]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.17
authorSasha Levin <sashal@kernel.org>
Sun, 10 Apr 2022 02:06:25 +0000 (22:06 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 10 Apr 2022 02:06:25 +0000 (22:06 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
194 files changed:
queue-5.17/ath11k-fix-frames-flush-failure-caused-by-deadlock.patch [new file with mode: 0644]
queue-5.17/ath11k-fix-kernel-panic-during-unload-load-ath11k-mo.patch [new file with mode: 0644]
queue-5.17/ath11k-mhi-use-mhi_sync_power_up.patch [new file with mode: 0644]
queue-5.17/ath11k-pci-fix-crash-on-suspend-if-board-file-is-not.patch [new file with mode: 0644]
queue-5.17/ath5k-fix-oob-in-ath5k_eeprom_read_pcal_info_5111.patch [new file with mode: 0644]
queue-5.17/bluetooth-fix-not-checking-for-valid-hdev-on-bt_dev_.patch [new file with mode: 0644]
queue-5.17/bluetooth-fix-null-ptr-deref-on-hci_sync_conn_comple.patch [new file with mode: 0644]
queue-5.17/bluetooth-fix-use-after-free-in-hci_send_acl.patch [new file with mode: 0644]
queue-5.17/bluetooth-hci_event-ignore-multiple-conn-complete-ev.patch [new file with mode: 0644]
queue-5.17/bluetooth-hci_sync-fix-compilation-warning.patch [new file with mode: 0644]
queue-5.17/bluetooth-hci_sync-fix-queuing-commands-when-hci_unr.patch [new file with mode: 0644]
queue-5.17/bluetooth-mediatek-fix-the-conflict-between-mtk-and-.patch [new file with mode: 0644]
queue-5.17/bluetooth-use-memset-avoid-memory-leaks.patch [new file with mode: 0644]
queue-5.17/bnxt_en-eliminate-unintended-link-toggle-during-fw-r.patch [new file with mode: 0644]
queue-5.17/bpf-make-dst_port-field-in-struct-bpf_sock-16-bit-wi.patch [new file with mode: 0644]
queue-5.17/can-etas_es58x-es58x_fd_rx_event_msg-initialize-rx_e.patch [new file with mode: 0644]
queue-5.17/can-isotp-set-default-value-for-n_as-to-50-micro-sec.patch [new file with mode: 0644]
queue-5.17/ceph-fix-inode-reference-leakage-in-ceph_get_snapdir.patch [new file with mode: 0644]
queue-5.17/ceph-fix-memory-leak-in-ceph_readdir-when-note_last_.patch [new file with mode: 0644]
queue-5.17/cfg80211-don-t-add-non-transmitted-bss-to-6ghz-scann.patch [new file with mode: 0644]
queue-5.17/clk-enforce-that-disjoints-limits-are-invalid.patch [new file with mode: 0644]
queue-5.17/clk-mediatek-fix-memory-leaks-on-probe.patch [new file with mode: 0644]
queue-5.17/clk-rockchip-drop-clk_set_rate_parent-from-dclk_vop-.patch [new file with mode: 0644]
queue-5.17/clk-si5341-fix-reported-clk_rate-when-output-divider.patch [new file with mode: 0644]
queue-5.17/clk-ti-preserve-node-in-ti_dt_clocks_register.patch [new file with mode: 0644]
queue-5.17/cpufreq-cppc-fix-performance-frequency-conversion.patch [new file with mode: 0644]
queue-5.17/dm-ioctl-prevent-potential-spectre-v1-gadget.patch [new file with mode: 0644]
queue-5.17/dm-requeue-io-if-mapping-table-not-yet-available.patch [new file with mode: 0644]
queue-5.17/drm-add-orientation-quirk-for-gpd-win-max.patch [new file with mode: 0644]
queue-5.17/drm-amd-amdgpu-amdgpu_cs-fix-refcount-leak-of-a-dma_.patch [new file with mode: 0644]
queue-5.17/drm-amd-display-add-signal-type-check-when-verify-st.patch [new file with mode: 0644]
queue-5.17/drm-amd-display-fix-memory-leak.patch [new file with mode: 0644]
queue-5.17/drm-amd-display-reset-lane-settings-after-each-phy-r.patch [new file with mode: 0644]
queue-5.17/drm-amd-display-use-psr-version-selected-during-set_.patch [new file with mode: 0644]
queue-5.17/drm-amdgpu-fix-an-error-message-in-rmmod.patch [new file with mode: 0644]
queue-5.17/drm-amdgpu-fix-recursive-locking-warning.patch [new file with mode: 0644]
queue-5.17/drm-amdkfd-don-t-take-process-mutex-for-svm-ioctls.patch [new file with mode: 0644]
queue-5.17/drm-amdkfd-enable-heavy-weight-tlb-flush-on-arcturus.patch [new file with mode: 0644]
queue-5.17/drm-amdkfd-ensure-mm-remain-valid-in-svm-deferred_li.patch [new file with mode: 0644]
queue-5.17/drm-amdkfd-make-crat-table-missing-message-informati.patch [new file with mode: 0644]
queue-5.17/drm-amdkfd-svm-range-restore-work-deadlock-when-proc.patch [new file with mode: 0644]
queue-5.17/drm-bridge-add-missing-pm_runtime_put_sync.patch [new file with mode: 0644]
queue-5.17/drm-edid-improve-non-desktop-quirk-logging.patch [new file with mode: 0644]
queue-5.17/drm-edid-remove-non_desktop-quirk-for-hpn-3515-and-l.patch [new file with mode: 0644]
queue-5.17/drm-msm-dsi-remove-spurious-irqf_oneshot-flag.patch [new file with mode: 0644]
queue-5.17/drm-sprd-check-the-platform_get_resource-return-valu.patch [new file with mode: 0644]
queue-5.17/drm-sprd-fix-potential-null-dereference.patch [new file with mode: 0644]
queue-5.17/drm-v3d-fix-missing-unlock.patch [new file with mode: 0644]
queue-5.17/habanalabs-fix-possible-memory-leak-in-mmu-dr-fini.patch [new file with mode: 0644]
queue-5.17/habanalabs-gaudi-handle-axi-errors-from-nic-engines.patch [new file with mode: 0644]
queue-5.17/habanalabs-reject-host-map-with-mmu-disabled.patch [new file with mode: 0644]
queue-5.17/hid-apple-report-magic-keyboard-2021-battery-over-us.patch [new file with mode: 0644]
queue-5.17/hid-apple-report-magic-keyboard-2021-with-fingerprin.patch [new file with mode: 0644]
queue-5.17/i40e-add-sending-commands-in-atomic-context.patch [new file with mode: 0644]
queue-5.17/iavf-stop-leaking-iavf_status-as-errno-values.patch [new file with mode: 0644]
queue-5.17/init-main.c-return-1-from-handled-__setup-functions.patch [new file with mode: 0644]
queue-5.17/iommu-arm-smmu-v3-fix-event-handling-soft-lockup.patch [new file with mode: 0644]
queue-5.17/ipv4-invalidate-neighbour-for-broadcast-address-upon.patch [new file with mode: 0644]
queue-5.17/ipv6-annotate-some-data-races-around-sk-sk_prot.patch [new file with mode: 0644]
queue-5.17/ipv6-make-mc_forwarding-atomic.patch [new file with mode: 0644]
queue-5.17/iwlwifi-fix-small-doc-mistake-for-iwl_fw_ini_addr_va.patch [new file with mode: 0644]
queue-5.17/iwlwifi-mei-fix-building-iwlmei.patch [new file with mode: 0644]
queue-5.17/iwlwifi-mvm-correctly-set-fragmented-ebs.patch [new file with mode: 0644]
queue-5.17/iwlwifi-mvm-move-only-to-an-enabled-channel.patch [new file with mode: 0644]
queue-5.17/jfs-prevent-null-deref-in-difree.patch [new file with mode: 0644]
queue-5.17/kvm-arm64-do-not-change-the-pmu-event-filter-after-a.patch [new file with mode: 0644]
queue-5.17/kvm-selftests-aarch64-fix-assert-in-gicv3_access_reg.patch [new file with mode: 0644]
queue-5.17/kvm-selftests-aarch64-fix-some-vgic-related-comments.patch [new file with mode: 0644]
queue-5.17/kvm-selftests-aarch64-fix-the-failure-check-in-kvm_s.patch [new file with mode: 0644]
queue-5.17/kvm-selftests-aarch64-pass-vgic_irq-guest-args-as-a-.patch [new file with mode: 0644]
queue-5.17/kvm-selftests-aarch64-use-a-tighter-assert-in-vgic_p.patch [new file with mode: 0644]
queue-5.17/kvm-svm-fix-kvm_cache_regs.h-inclusions-for-is_guest.patch [new file with mode: 0644]
queue-5.17/kvm-x86-emulator-emulate-rdpid-only-if-it-is-enabled.patch [new file with mode: 0644]
queue-5.17/kvm-x86-pmu-fix-and-isolate-tsx-specific-performance.patch [new file with mode: 0644]
queue-5.17/kvm-x86-pmu-use-different-raw-event-masks-for-amd-an.patch [new file with mode: 0644]
queue-5.17/kvm-x86-svm-clear-reserved-bits-written-to-perfevtse.patch [new file with mode: 0644]
queue-5.17/lib-kconfig.debug-add-arch-dependency-for-function_a.patch [new file with mode: 0644]
queue-5.17/lib-logic_iomem-correct-fallback-config-references.patch [new file with mode: 0644]
queue-5.17/libbpf-fix-accessing-syscall-arguments-on-powerpc.patch [new file with mode: 0644]
queue-5.17/libbpf-fix-accessing-the-first-syscall-argument-on-a.patch [new file with mode: 0644]
queue-5.17/libbpf-fix-accessing-the-first-syscall-argument-on-s.patch [new file with mode: 0644]
queue-5.17/libbpf-fix-build-issue-with-llvm-readelf.patch [new file with mode: 0644]
queue-5.17/macvtap-advertise-link-netns-via-netlink.patch [new file with mode: 0644]
queue-5.17/mctp-make-__mctp_dev_get-take-a-refcount-hold.patch [new file with mode: 0644]
queue-5.17/minix-fix-bug-when-opening-a-file-with-o_direct.patch [new file with mode: 0644]
queue-5.17/mips-fix-fortify-panic-when-copying-asm-exception-ha.patch [new file with mode: 0644]
queue-5.17/mips-ingenic-correct-unit-node-address.patch [new file with mode: 0644]
queue-5.17/mips-ralink-fix-a-refcount-leak-in-ill_acc_of_setup.patch [new file with mode: 0644]
queue-5.17/mlxsw-spectrum-guard-against-invalid-local-ports.patch [new file with mode: 0644]
queue-5.17/mm-fix-race-between-madv_free-reclaim-and-blkdev-dir.patch [new file with mode: 0644]
queue-5.17/mm-kfence-fix-objcgs-vector-allocation.patch [new file with mode: 0644]
queue-5.17/mt76-dma-initialize-skip_unmap-in-mt76_dma_rx_fill.patch [new file with mode: 0644]
queue-5.17/mt76-fix-monitor-mode-crash-with-sdio-driver.patch [new file with mode: 0644]
queue-5.17/mt76-mt7615-fix-assigning-negative-values-to-unsigne.patch [new file with mode: 0644]
queue-5.17/mt76-mt7915-fix-injected-mpdu-transmission-to-not-us.patch [new file with mode: 0644]
queue-5.17/mt76-mt7921-fix-crash-when-startup-fails.patch [new file with mode: 0644]
queue-5.17/net-account-alternate-interface-name-memory.patch [new file with mode: 0644]
queue-5.17/net-dsa-felix-fix-possible-null-pointer-dereference.patch [new file with mode: 0644]
queue-5.17/net-initialize-init_net-earlier.patch [new file with mode: 0644]
queue-5.17/net-limit-altnames-to-64k-total.patch [new file with mode: 0644]
queue-5.17/net-mlx5e-disable-tx-queues-before-registering-the-n.patch [new file with mode: 0644]
queue-5.17/net-mlx5e-remove-overzealous-validations-in-netlink-.patch [new file with mode: 0644]
queue-5.17/net-mlx5e-tc-hold-sample_attr-on-stack-instead-of-po.patch [new file with mode: 0644]
queue-5.17/net-sfp-add-2500base-x-quirk-for-lantech-sfp-module.patch [new file with mode: 0644]
queue-5.17/net-smc-correct-settings-of-rmb-window-update-limit.patch [new file with mode: 0644]
queue-5.17/net-smc-send-directly-when-tcp_cork-is-cleared.patch [new file with mode: 0644]
queue-5.17/netfilter-conntrack-revisit-gc-autotuning.patch [new file with mode: 0644]
queue-5.17/netlabel-fix-out-of-bounds-memory-accesses.patch [new file with mode: 0644]
queue-5.17/nfs-avoid-writeback-threads-getting-stuck-in-mempool.patch [new file with mode: 0644]
queue-5.17/nfs-nfsiod-should-not-block-forever-in-mempool_alloc.patch [new file with mode: 0644]
queue-5.17/nfs-swap-io-handling-is-slightly-different-for-o_dir.patch [new file with mode: 0644]
queue-5.17/nfs-swap-out-must-always-use-stable-writes.patch [new file with mode: 0644]
queue-5.17/nfsv4-protect-the-state-recovery-thread-against-dire.patch [new file with mode: 0644]
queue-5.17/nfsv4.2-fix-reference-count-leaks-in-_nfs42_proc_cop.patch [new file with mode: 0644]
queue-5.17/opp-expose-of-node-s-name-in-debugfs.patch [new file with mode: 0644]
queue-5.17/parisc-fix-cpu-affinity-for-lasi-wax-and-dino-chips.patch [new file with mode: 0644]
queue-5.17/parisc-fix-patch-code-locking-and-flushing.patch [new file with mode: 0644]
queue-5.17/pci-aardvark-fix-support-for-msi-interrupts.patch [new file with mode: 0644]
queue-5.17/pci-endpoint-fix-alignment-fault-error-in-copy-tests.patch [new file with mode: 0644]
queue-5.17/pci-endpoint-fix-misused-goto-label.patch [new file with mode: 0644]
queue-5.17/pci-pciehp-add-qualcomm-quirk-for-command-completed-.patch [new file with mode: 0644]
queue-5.17/phy-amlogic-meson8b-usb2-fix-shared-reset-control-us.patch [new file with mode: 0644]
queue-5.17/phy-amlogic-meson8b-usb2-use-dev_err_probe.patch [new file with mode: 0644]
queue-5.17/phy-amlogic-phy-meson-gxl-usb2-fix-shared-reset-cont.patch [new file with mode: 0644]
queue-5.17/platform-x86-hp-wmi-fix-0x05-error-code-reported-by-.patch [new file with mode: 0644]
queue-5.17/platform-x86-hp-wmi-fix-sw_tablet_mode-detection-met.patch [new file with mode: 0644]
queue-5.17/platform-x86-thinkpad_acpi-add-dual-fan-probe.patch [new file with mode: 0644]
queue-5.17/platform-x86-x86-android-tablets-depend-on-efi-and-s.patch [new file with mode: 0644]
queue-5.17/power-supply-axp20x_battery-properly-report-current-.patch [new file with mode: 0644]
queue-5.17/power-supply-axp288-charger-set-vhold-to-4.4v.patch [new file with mode: 0644]
queue-5.17/power-supply-axp288_charger-use-acpi_quirk_skip_acpi.patch [new file with mode: 0644]
queue-5.17/power-supply-axp288_fuel_gauge-use-acpi_quirk_skip_a.patch [new file with mode: 0644]
queue-5.17/powerpc-64e-tie-ppc_book3e_64-to-ppc_fsl_book3e.patch [new file with mode: 0644]
queue-5.17/powerpc-64s-hash-make-hash-faults-work-in-nmi-contex.patch [new file with mode: 0644]
queue-5.17/powerpc-code-patching-pre-map-patch-area.patch [new file with mode: 0644]
queue-5.17/powerpc-dts-t104xrdb-fix-phy-type-for-fman-4-5.patch [new file with mode: 0644]
queue-5.17/powerpc-secvar-fix-refcount-leak-in-format_show.patch [new file with mode: 0644]
queue-5.17/powerpc-set-crashkernel-offset-to-mid-of-rma-region.patch [new file with mode: 0644]
queue-5.17/powerpc-set_memory-avoid-spinlock-recursion-in-chang.patch [new file with mode: 0644]
queue-5.17/powerpc-xive-export-xive-ipi-information-for-online-.patch [new file with mode: 0644]
queue-5.17/ptp-replace-snprintf-with-sysfs_emit.patch [new file with mode: 0644]
queue-5.17/rdma-rtrs-clt-do-stop-and-failover-outside-reconnect.patch [new file with mode: 0644]
queue-5.17/ref_tracker-implement-use-after-free-detection.patch [new file with mode: 0644]
queue-5.17/riscv-fixed-misaligned-memory-access.-fixed-pointer-.patch [new file with mode: 0644]
queue-5.17/rtc-wm8350-handle-error-for-wm8350_register_irq.patch [new file with mode: 0644]
queue-5.17/rtw88-change-rtw_info-to-proper-message-level.patch [new file with mode: 0644]
queue-5.17/rtw89-fix-rcu-usage-in-rtw89_core_txq_push.patch [new file with mode: 0644]
queue-5.17/scsi-aha152x-fix-aha152x_setup-__setup-handler-retur.patch [new file with mode: 0644]
queue-5.17/scsi-bfa-replace-snprintf-with-sysfs_emit.patch [new file with mode: 0644]
queue-5.17/scsi-hisi_sas-free-irq-vectors-in-order-for-v3-hw.patch [new file with mode: 0644]
queue-5.17/scsi-hisi_sas-limit-users-changing-debugfs-bist-coun.patch [new file with mode: 0644]
queue-5.17/scsi-libfc-fix-use-after-free-in-fc_exch_abts_resp.patch [new file with mode: 0644]
queue-5.17/scsi-mpi3mr-fix-deadlock-while-canceling-the-fw-even.patch [new file with mode: 0644]
queue-5.17/scsi-mpi3mr-fix-memory-leaks.patch [new file with mode: 0644]
queue-5.17/scsi-mpi3mr-fix-reporting-of-actual-data-transfer-si.patch [new file with mode: 0644]
queue-5.17/scsi-mvsas-replace-snprintf-with-sysfs_emit.patch [new file with mode: 0644]
queue-5.17/scsi-pm8001-fix-memory-leak-in-pm8001_chip_fw_flash_.patch [new file with mode: 0644]
queue-5.17/scsi-pm8001-fix-pm8001_mpi_task_abort_resp.patch [new file with mode: 0644]
queue-5.17/scsi-pm8001-fix-pm80xx_pci_mem_copy-interface.patch [new file with mode: 0644]
queue-5.17/scsi-pm8001-fix-tag-leaks-on-error.patch [new file with mode: 0644]
queue-5.17/scsi-pm8001-fix-tag-values-handling.patch [new file with mode: 0644]
queue-5.17/scsi-pm8001-fix-task-leak-in-pm8001_send_abort_all.patch [new file with mode: 0644]
queue-5.17/scsi-scsi_debug-address-races-following-module-load.patch [new file with mode: 0644]
queue-5.17/scsi-smartpqi-fix-kdump-issue-when-controller-is-loc.patch [new file with mode: 0644]
queue-5.17/scsi-smartpqi-fix-rmmod-stack-trace.patch [new file with mode: 0644]
queue-5.17/selftests-net-add-tls-config-dependency-for-tls-self.patch [new file with mode: 0644]
queue-5.17/selftests-xsk-fix-bpf_res-cleanup-test.patch [new file with mode: 0644]
queue-5.17/serial-samsung_tty-do-not-unlock-port-lock-for-uart_.patch [new file with mode: 0644]
queue-5.17/series [new file with mode: 0644]
queue-5.17/staging-vchiq_arm-avoid-null-ptr-deref-in-vchiq_dump.patch [new file with mode: 0644]
queue-5.17/staging-vchiq_core-handle-null-result-of-find_servic.patch [new file with mode: 0644]
queue-5.17/staging-wfx-apply-the-necessary-sdio-quirks-for-the-.patch [new file with mode: 0644]
queue-5.17/staging-wfx-fix-an-error-handling-in-wfx_init_common.patch [new file with mode: 0644]
queue-5.17/sunrpc-fix-socket-waits-for-write-buffer-space.patch [new file with mode: 0644]
queue-5.17/sunrpc-remove-scheduling-boost-for-swapper-tasks.patch [new file with mode: 0644]
queue-5.17/sunrpc-xprt-async-tasks-mustn-t-block-waiting-for-me.patch [new file with mode: 0644]
queue-5.17/tcp-don-t-acquire-inet_listen_hashbucket-lock-with-d.patch [new file with mode: 0644]
queue-5.17/tuntap-add-sanity-checks-about-msg_controllen-in-sen.patch [new file with mode: 0644]
queue-5.17/um-fix-and-optimize-xor-select-template-for-config64.patch [new file with mode: 0644]
queue-5.17/usb-cdnsp-fix-cdnsp_decode_trb-function-to-properly-.patch [new file with mode: 0644]
queue-5.17/usb-dwc3-omap-fix-unbalanced-disables-for-smps10_out.patch [new file with mode: 0644]
queue-5.17/usb-dwc3-pci-set-the-swnode-from-inside-dwc3_pci_qui.patch [new file with mode: 0644]
queue-5.17/usb-ehci-add-pci-device-support-for-aspeed-platforms.patch [new file with mode: 0644]
queue-5.17/usb-gadget-tegra-xudc-do-not-program-sparam.patch [new file with mode: 0644]
queue-5.17/usb-gadget-tegra-xudc-fix-control-endpoint-s-definit.patch [new file with mode: 0644]
queue-5.17/vfio-pci-stub-vfio_pci_vga_rw-when-config_vfio_pci_v.patch [new file with mode: 0644]
queue-5.17/virtio_console-eliminate-anonymous-module_init-modul.patch [new file with mode: 0644]
queue-5.17/w1-w1_therm-fixes-w1_seq-for-ds28ea00-sensors.patch [new file with mode: 0644]
queue-5.17/x86-annotate-call_on_stack.patch [new file with mode: 0644]
queue-5.17/x86-kconfig-do-not-allow-config_x86_x32_abi-y-with-l.patch [new file with mode: 0644]
queue-5.17/x86-mce-work-around-an-erratum-on-fast-string-copy-i.patch [new file with mode: 0644]
queue-5.17/xen-delay-xen_hvm_init_time_ops-if-kdump-is-boot-on-.patch [new file with mode: 0644]
queue-5.17/xen-usb-harden-xen_hcd-against-malicious-backends.patch [new file with mode: 0644]
queue-5.17/xtensa-fix-dtc-warning-unit_address_format.patch [new file with mode: 0644]

diff --git a/queue-5.17/ath11k-fix-frames-flush-failure-caused-by-deadlock.patch b/queue-5.17/ath11k-fix-frames-flush-failure-caused-by-deadlock.patch
new file mode 100644 (file)
index 0000000..eb65fb0
--- /dev/null
@@ -0,0 +1,136 @@
+From 4e13bbd67901b2af197e7d93877db9461ce84155 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 16:45:45 +0800
+Subject: ath11k: Fix frames flush failure caused by deadlock
+
+From: Baochen Qiang <quic_bqiang@quicinc.com>
+
+[ Upstream commit 261b07519518bd14cb168b287b17e1d195f8d0c8 ]
+
+We are seeing below warnings:
+
+kernel: [25393.301506] ath11k_pci 0000:01:00.0: failed to flush mgmt transmit queue 0
+kernel: [25398.421509] ath11k_pci 0000:01:00.0: failed to flush mgmt transmit queue 0
+kernel: [25398.421831] ath11k_pci 0000:01:00.0: dropping mgmt frame for vdev 0, is_started 0
+
+this means ath11k fails to flush mgmt. frames because wmi_mgmt_tx_work
+has no chance to run in 5 seconds.
+
+By setting /proc/sys/kernel/hung_task_timeout_secs to 20 and increasing
+ATH11K_FLUSH_TIMEOUT to 50 we get below warnings:
+
+kernel: [  120.763160] INFO: task wpa_supplicant:924 blocked for more than 20 seconds.
+kernel: [  120.763169]       Not tainted 5.10.90 #12
+kernel: [  120.763177] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+kernel: [  120.763186] task:wpa_supplicant  state:D stack:    0 pid:  924 ppid:     1 flags:0x000043a0
+kernel: [  120.763201] Call Trace:
+kernel: [  120.763214]  __schedule+0x785/0x12fa
+kernel: [  120.763224]  ? lockdep_hardirqs_on_prepare+0xe2/0x1bb
+kernel: [  120.763242]  schedule+0x7e/0xa1
+kernel: [  120.763253]  schedule_timeout+0x98/0xfe
+kernel: [  120.763266]  ? run_local_timers+0x4a/0x4a
+kernel: [  120.763291]  ath11k_mac_flush_tx_complete+0x197/0x2b1 [ath11k 13c3a9bf37790f4ac8103b3decf7ab4008ac314a]
+kernel: [  120.763306]  ? init_wait_entry+0x2e/0x2e
+kernel: [  120.763343]  __ieee80211_flush_queues+0x167/0x21f [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.763378]  __ieee80211_recalc_idle+0x105/0x125 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.763411]  ieee80211_recalc_idle+0x14/0x27 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.763441]  ieee80211_free_chanctx+0x77/0xa2 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.763473]  __ieee80211_vif_release_channel+0x100/0x131 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.763540]  ieee80211_vif_release_channel+0x66/0x81 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.763572]  ieee80211_destroy_auth_data+0xa3/0xe6 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.763612]  ieee80211_mgd_deauth+0x178/0x29b [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.763654]  cfg80211_mlme_deauth+0x1a8/0x22c [cfg80211 8945aa5bc2af5f6972336665d8ad6f9c191ad5be]
+kernel: [  120.763697]  nl80211_deauthenticate+0xfa/0x123 [cfg80211 8945aa5bc2af5f6972336665d8ad6f9c191ad5be]
+kernel: [  120.763715]  genl_rcv_msg+0x392/0x3c2
+kernel: [  120.763750]  ? nl80211_associate+0x432/0x432 [cfg80211 8945aa5bc2af5f6972336665d8ad6f9c191ad5be]
+kernel: [  120.763782]  ? nl80211_associate+0x432/0x432 [cfg80211 8945aa5bc2af5f6972336665d8ad6f9c191ad5be]
+kernel: [  120.763802]  ? genl_rcv+0x36/0x36
+kernel: [  120.763814]  netlink_rcv_skb+0x89/0xf7
+kernel: [  120.763829]  genl_rcv+0x28/0x36
+kernel: [  120.763840]  netlink_unicast+0x179/0x24b
+kernel: [  120.763854]  netlink_sendmsg+0x393/0x401
+kernel: [  120.763872]  sock_sendmsg+0x72/0x76
+kernel: [  120.763886]  ____sys_sendmsg+0x170/0x1e6
+kernel: [  120.763897]  ? copy_msghdr_from_user+0x7a/0xa2
+kernel: [  120.763914]  ___sys_sendmsg+0x95/0xd1
+kernel: [  120.763940]  __sys_sendmsg+0x85/0xbf
+kernel: [  120.763956]  do_syscall_64+0x43/0x55
+kernel: [  120.763966]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
+kernel: [  120.763977] RIP: 0033:0x79089f3fcc83
+kernel: [  120.763986] RSP: 002b:00007ffe604f0508 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+kernel: [  120.763997] RAX: ffffffffffffffda RBX: 000059b40e987690 RCX: 000079089f3fcc83
+kernel: [  120.764006] RDX: 0000000000000000 RSI: 00007ffe604f0558 RDI: 0000000000000009
+kernel: [  120.764014] RBP: 00007ffe604f0540 R08: 0000000000000004 R09: 0000000000400000
+kernel: [  120.764023] R10: 00007ffe604f0638 R11: 0000000000000246 R12: 000059b40ea04980
+kernel: [  120.764032] R13: 00007ffe604f0638 R14: 000059b40e98c360 R15: 00007ffe604f0558
+...
+kernel: [  120.765230] INFO: task kworker/u32:26:4239 blocked for more than 20 seconds.
+kernel: [  120.765238]       Not tainted 5.10.90 #12
+kernel: [  120.765245] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+kernel: [  120.765253] task:kworker/u32:26  state:D stack:    0 pid: 4239 ppid:     2 flags:0x00004080
+kernel: [  120.765284] Workqueue: phy0 ieee80211_iface_work [mac80211]
+kernel: [  120.765295] Call Trace:
+kernel: [  120.765306]  __schedule+0x785/0x12fa
+kernel: [  120.765316]  ? find_held_lock+0x3d/0xb2
+kernel: [  120.765331]  schedule+0x7e/0xa1
+kernel: [  120.765340]  schedule_preempt_disabled+0x15/0x1e
+kernel: [  120.765349]  __mutex_lock_common+0x561/0xc0d
+kernel: [  120.765375]  ? ieee80211_sta_work+0x3e/0x1232 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.765390]  mutex_lock_nested+0x20/0x26
+kernel: [  120.765416]  ieee80211_sta_work+0x3e/0x1232 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.765430]  ? skb_dequeue+0x54/0x5e
+kernel: [  120.765456]  ? ieee80211_iface_work+0x7b/0x339 [mac80211 335da900954f1c5ea7f1613d92088ce83342042c]
+kernel: [  120.765485]  process_one_work+0x270/0x504
+kernel: [  120.765501]  worker_thread+0x215/0x376
+kernel: [  120.765514]  kthread+0x159/0x168
+kernel: [  120.765526]  ? pr_cont_work+0x5b/0x5b
+kernel: [  120.765536]  ? kthread_blkcg+0x31/0x31
+kernel: [  120.765550]  ret_from_fork+0x22/0x30
+...
+kernel: [  120.765867] Showing all locks held in the system:
+...
+kernel: [  120.766164] 5 locks held by wpa_supplicant/924:
+kernel: [  120.766172]  #0: ffffffffb1e63eb0 (cb_lock){++++}-{3:3}, at: genl_rcv+0x19/0x36
+kernel: [  120.766197]  #1: ffffffffb1e5b1c8 (rtnl_mutex){+.+.}-{3:3}, at: nl80211_pre_doit+0x2a/0x15c [cfg80211]
+kernel: [  120.766238]  #2: ffff99f08347cd08 (&wdev->mtx){+.+.}-{3:3}, at: nl80211_deauthenticate+0xde/0x123 [cfg80211]
+kernel: [  120.766279]  #3: ffff99f09df12a48 (&local->mtx){+.+.}-{3:3}, at: ieee80211_destroy_auth_data+0x9b/0xe6 [mac80211]
+kernel: [  120.766321]  #4: ffff99f09df12ce0 (&local->chanctx_mtx){+.+.}-{3:3}, at: ieee80211_vif_release_channel+0x5e/0x81 [mac80211]
+...
+kernel: [  120.766585] 3 locks held by kworker/u32:26/4239:
+kernel: [  120.766593]  #0: ffff99f04458f948 ((wq_completion)phy0){+.+.}-{0:0}, at: process_one_work+0x19a/0x504
+kernel: [  120.766621]  #1: ffffbad54b3cfe50 ((work_completion)(&sdata->work)){+.+.}-{0:0}, at: process_one_work+0x1c0/0x504
+kernel: [  120.766649]  #2: ffff99f08347cd08 (&wdev->mtx){+.+.}-{3:3}, at: ieee80211_sta_work+0x3e/0x1232 [mac80211]
+
+With above info the issue is clear: First wmi_mgmt_tx_work is inserted
+to local->workqueue after sdata->work inserted, then wpa_supplicant
+acquires wdev->mtx in nl80211_deauthenticate and finally calls
+ath11k_mac_op_flush where it waits all mgmt. frames to be sent out by
+wmi_mgmt_tx_work. Meanwhile, sdata->work is blocked by wdev->mtx in
+ieee80211_sta_work, as a result wmi_mgmt_tx_work has no chance to run.
+
+Change to use ab->workqueue instead of local->workqueue to fix this issue.
+
+Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220217084545.18844-1-quic_bqiang@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/mac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 08e33778f63b..28de877ad6c4 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -5574,7 +5574,7 @@ static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb,
+       skb_queue_tail(q, skb);
+       atomic_inc(&ar->num_pending_mgmt_tx);
+-      ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
++      queue_work(ar->ab->workqueue, &ar->wmi_mgmt_tx_work);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/ath11k-fix-kernel-panic-during-unload-load-ath11k-mo.patch b/queue-5.17/ath11k-fix-kernel-panic-during-unload-load-ath11k-mo.patch
new file mode 100644 (file)
index 0000000..b3f3acd
--- /dev/null
@@ -0,0 +1,65 @@
+From be1d0557215c1abf377528d8f2c8aa7036196f3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Jan 2022 14:49:33 +0530
+Subject: ath11k: fix kernel panic during unload/load ath11k modules
+
+From: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
+
+[ Upstream commit 22b59cb965f79ee1accf83172441c9ca0ecb632a ]
+
+Call netif_napi_del() from ath11k_ahb_free_ext_irq() to fix
+the following kernel panic when unload/load ath11k modules
+for few iterations.
+
+[  971.201365] Unable to handle kernel paging request at virtual address 6d97a208
+[  971.204227] pgd = 594c2919
+[  971.211478] [6d97a208] *pgd=00000000
+[  971.214120] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
+[  971.412024] CPU: 2 PID: 4435 Comm: insmod Not tainted 5.4.89 #0
+[  971.434256] Hardware name: Generic DT based system
+[  971.440165] PC is at napi_by_id+0x10/0x40
+[  971.445019] LR is at netif_napi_add+0x160/0x1dc
+
+[  971.743127] (napi_by_id) from [<807d89a0>] (netif_napi_add+0x160/0x1dc)
+[  971.751295] (netif_napi_add) from [<7f1209ac>] (ath11k_ahb_config_irq+0xf8/0x414 [ath11k_ahb])
+[  971.759164] (ath11k_ahb_config_irq [ath11k_ahb]) from [<7f12135c>] (ath11k_ahb_probe+0x40c/0x51c [ath11k_ahb])
+[  971.768567] (ath11k_ahb_probe [ath11k_ahb]) from [<80666864>] (platform_drv_probe+0x48/0x94)
+[  971.779670] (platform_drv_probe) from [<80664718>] (really_probe+0x1c8/0x450)
+[  971.789389] (really_probe) from [<80664cc4>] (driver_probe_device+0x15c/0x1b8)
+[  971.797547] (driver_probe_device) from [<80664f60>] (device_driver_attach+0x44/0x60)
+[  971.805795] (device_driver_attach) from [<806650a0>] (__driver_attach+0x124/0x140)
+[  971.814822] (__driver_attach) from [<80662adc>] (bus_for_each_dev+0x58/0xa4)
+[  971.823328] (bus_for_each_dev) from [<80663a2c>] (bus_add_driver+0xf0/0x1e8)
+[  971.831662] (bus_add_driver) from [<806658a4>] (driver_register+0xa8/0xf0)
+[  971.839822] (driver_register) from [<8030269c>] (do_one_initcall+0x78/0x1ac)
+[  971.847638] (do_one_initcall) from [<80392524>] (do_init_module+0x54/0x200)
+[  971.855968] (do_init_module) from [<803945b0>] (load_module+0x1e30/0x1ffc)
+[  971.864126] (load_module) from [<803948b0>] (sys_init_module+0x134/0x17c)
+[  971.871852] (sys_init_module) from [<80301000>] (ret_fast_syscall+0x0/0x50)
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.6.0.1-00760-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/1642583973-21599-1-git-send-email-quic_vnaralas@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
+index 3fb0aa000825..24bd0520926b 100644
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -391,6 +391,8 @@ static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
+               for (j = 0; j < irq_grp->num_irq; j++)
+                       free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
++
++              netif_napi_del(&irq_grp->napi);
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/ath11k-mhi-use-mhi_sync_power_up.patch b/queue-5.17/ath11k-mhi-use-mhi_sync_power_up.patch
new file mode 100644 (file)
index 0000000..99a3ed1
--- /dev/null
@@ -0,0 +1,87 @@
+From d71409d85633c53a0d7669a02a345ce9d7fdf501 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 11:01:17 +0200
+Subject: ath11k: mhi: use mhi_sync_power_up()
+
+From: Kalle Valo <quic_kvalo@quicinc.com>
+
+[ Upstream commit 3df6d74aedfdca919cca475d15dfdbc8b05c9e5d ]
+
+If amss.bin was missing ath11k would crash during 'rmmod ath11k_pci'. The
+reason for that was that we were using mhi_async_power_up() which does not
+check any errors. But mhi_sync_power_up() on the other hand does check for
+errors so let's use that to fix the crash.
+
+I was not able to find a reason why an async version was used.
+ath11k_mhi_start() (which enables state ATH11K_MHI_POWER_ON) is called from
+ath11k_hif_power_up(), which can sleep. So sync version should be safe to use
+here.
+
+[  145.569731] general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC KASAN PTI
+[  145.569789] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+[  145.569843] CPU: 2 PID: 1628 Comm: rmmod Kdump: loaded Tainted: G        W         5.16.0-wt-ath+ #567
+[  145.569898] Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0067.2021.0528.1339 05/28/2021
+[  145.569956] RIP: 0010:ath11k_hal_srng_access_begin+0xb5/0x2b0 [ath11k]
+[  145.570028] Code: df 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 ec 01 00 00 48 8b ab a8 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 ea 48 c1 ea 03 <0f> b6 14 02 48 89 e8 83 e0 07 83 c0 03 45 85 ed 75 48 38 d0 7c 08
+[  145.570089] RSP: 0018:ffffc900025d7ac0 EFLAGS: 00010246
+[  145.570144] RAX: dffffc0000000000 RBX: ffff88814fca2dd8 RCX: 1ffffffff50cb455
+[  145.570196] RDX: 0000000000000000 RSI: ffff88814fca2dd8 RDI: ffff88814fca2e80
+[  145.570252] RBP: 0000000000000000 R08: 0000000000000000 R09: ffffffffa8659497
+[  145.570329] R10: fffffbfff50cb292 R11: 0000000000000001 R12: ffff88814fca0000
+[  145.570410] R13: 0000000000000000 R14: ffff88814fca2798 R15: ffff88814fca2dd8
+[  145.570465] FS:  00007fa399988540(0000) GS:ffff888233e00000(0000) knlGS:0000000000000000
+[  145.570519] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  145.570571] CR2: 00007fa399b51421 CR3: 0000000137898002 CR4: 00000000003706e0
+[  145.570623] Call Trace:
+[  145.570675]  <TASK>
+[  145.570727]  ? ath11k_ce_tx_process_cb+0x34b/0x860 [ath11k]
+[  145.570797]  ath11k_ce_tx_process_cb+0x356/0x860 [ath11k]
+[  145.570864]  ? tasklet_init+0x150/0x150
+[  145.570919]  ? ath11k_ce_alloc_pipes+0x280/0x280 [ath11k]
+[  145.570986]  ? tasklet_clear_sched+0x42/0xe0
+[  145.571042]  ? tasklet_kill+0xe9/0x1b0
+[  145.571095]  ? tasklet_clear_sched+0xe0/0xe0
+[  145.571148]  ? irq_has_action+0x120/0x120
+[  145.571202]  ath11k_ce_cleanup_pipes+0x45a/0x580 [ath11k]
+[  145.571270]  ? ath11k_pci_stop+0x10e/0x170 [ath11k_pci]
+[  145.571345]  ath11k_core_stop+0x8a/0xc0 [ath11k]
+[  145.571434]  ath11k_core_deinit+0x9e/0x150 [ath11k]
+[  145.571499]  ath11k_pci_remove+0xd2/0x260 [ath11k_pci]
+[  145.571553]  pci_device_remove+0x9a/0x1c0
+[  145.571605]  __device_release_driver+0x332/0x660
+[  145.571659]  driver_detach+0x1e7/0x2c0
+[  145.571712]  bus_remove_driver+0xe2/0x2d0
+[  145.571772]  pci_unregister_driver+0x21/0x250
+[  145.571826]  __do_sys_delete_module+0x30a/0x4b0
+[  145.571879]  ? free_module+0xac0/0xac0
+[  145.571933]  ? lockdep_hardirqs_on_prepare.part.0+0x18c/0x370
+[  145.571986]  ? syscall_enter_from_user_mode+0x1d/0x50
+[  145.572039]  ? lockdep_hardirqs_on+0x79/0x100
+[  145.572097]  do_syscall_64+0x3b/0x90
+[  145.572153]  entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2
+
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220127090117.2024-2-kvalo@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/mhi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
+index cccaa348cf21..8b2143802816 100644
+--- a/drivers/net/wireless/ath/ath11k/mhi.c
++++ b/drivers/net/wireless/ath/ath11k/mhi.c
+@@ -561,7 +561,7 @@ static int ath11k_mhi_set_state(struct ath11k_pci *ab_pci,
+               ret = 0;
+               break;
+       case ATH11K_MHI_POWER_ON:
+-              ret = mhi_async_power_up(ab_pci->mhi_ctrl);
++              ret = mhi_sync_power_up(ab_pci->mhi_ctrl);
+               break;
+       case ATH11K_MHI_POWER_OFF:
+               mhi_power_down(ab_pci->mhi_ctrl, true);
+-- 
+2.35.1
+
diff --git a/queue-5.17/ath11k-pci-fix-crash-on-suspend-if-board-file-is-not.patch b/queue-5.17/ath11k-pci-fix-crash-on-suspend-if-board-file-is-not.patch
new file mode 100644 (file)
index 0000000..4f414f9
--- /dev/null
@@ -0,0 +1,94 @@
+From bfb400e3298d3251db3f2eaed993a6cc6a9100d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 11:01:16 +0200
+Subject: ath11k: pci: fix crash on suspend if board file is not found
+
+From: Kalle Valo <quic_kvalo@quicinc.com>
+
+[ Upstream commit b4f4c56459a5c744f7f066b9fc2b54ea995030c5 ]
+
+Mario reported that the kernel was crashing on suspend if ath11k was not able
+to find a board file:
+
+[  473.693286] PM: Suspending system (s2idle)
+[  473.693291] printk: Suspending console(s) (use no_console_suspend to debug)
+[  474.407787] BUG: unable to handle page fault for address: 0000000000002070
+[  474.407791] #PF: supervisor read access in kernel mode
+[  474.407794] #PF: error_code(0x0000) - not-present page
+[  474.407798] PGD 0 P4D 0
+[  474.407801] Oops: 0000 [#1] PREEMPT SMP NOPTI
+[  474.407805] CPU: 2 PID: 2350 Comm: kworker/u32:14 Tainted: G        W         5.16.0 #248
+[...]
+[  474.407868] Call Trace:
+[  474.407870]  <TASK>
+[  474.407874]  ? _raw_spin_lock_irqsave+0x2a/0x60
+[  474.407882]  ? lock_timer_base+0x72/0xa0
+[  474.407889]  ? _raw_spin_unlock_irqrestore+0x29/0x3d
+[  474.407892]  ? try_to_del_timer_sync+0x54/0x80
+[  474.407896]  ath11k_dp_rx_pktlog_stop+0x49/0xc0 [ath11k]
+[  474.407912]  ath11k_core_suspend+0x34/0x130 [ath11k]
+[  474.407923]  ath11k_pci_pm_suspend+0x1b/0x50 [ath11k_pci]
+[  474.407928]  pci_pm_suspend+0x7e/0x170
+[  474.407935]  ? pci_pm_freeze+0xc0/0xc0
+[  474.407939]  dpm_run_callback+0x4e/0x150
+[  474.407947]  __device_suspend+0x148/0x4c0
+[  474.407951]  async_suspend+0x20/0x90
+dmesg-efi-164255130401001:
+Oops#1 Part1
+[  474.407955]  async_run_entry_fn+0x33/0x120
+[  474.407959]  process_one_work+0x220/0x3f0
+[  474.407966]  worker_thread+0x4a/0x3d0
+[  474.407971]  kthread+0x17a/0x1a0
+[  474.407975]  ? process_one_work+0x3f0/0x3f0
+[  474.407979]  ? set_kthread_struct+0x40/0x40
+[  474.407983]  ret_from_fork+0x22/0x30
+[  474.407991]  </TASK>
+
+The issue here is that board file loading happens after ath11k_pci_probe()
+succesfully returns (ath11k initialisation happends asynchronously) and the
+suspend handler is still enabled, of course failing as ath11k is not properly
+initialised. Fix this by checking ATH11K_FLAG_QMI_FAIL during both suspend and
+resume.
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2
+
+Reported-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=215504
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220127090117.2024-1-kvalo@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/pci.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
+index de71ad594f34..903758751c99 100644
+--- a/drivers/net/wireless/ath/ath11k/pci.c
++++ b/drivers/net/wireless/ath/ath11k/pci.c
+@@ -1571,6 +1571,11 @@ static __maybe_unused int ath11k_pci_pm_suspend(struct device *dev)
+       struct ath11k_base *ab = dev_get_drvdata(dev);
+       int ret;
++      if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
++              ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot skipping pci suspend as qmi is not initialised\n");
++              return 0;
++      }
++
+       ret = ath11k_core_suspend(ab);
+       if (ret)
+               ath11k_warn(ab, "failed to suspend core: %d\n", ret);
+@@ -1583,6 +1588,11 @@ static __maybe_unused int ath11k_pci_pm_resume(struct device *dev)
+       struct ath11k_base *ab = dev_get_drvdata(dev);
+       int ret;
++      if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
++              ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot skipping pci resume as qmi is not initialised\n");
++              return 0;
++      }
++
+       ret = ath11k_core_resume(ab);
+       if (ret)
+               ath11k_warn(ab, "failed to resume core: %d\n", ret);
+-- 
+2.35.1
+
diff --git a/queue-5.17/ath5k-fix-oob-in-ath5k_eeprom_read_pcal_info_5111.patch b/queue-5.17/ath5k-fix-oob-in-ath5k_eeprom_read_pcal_info_5111.patch
new file mode 100644 (file)
index 0000000..dbf8c35
--- /dev/null
@@ -0,0 +1,87 @@
+From f65d99e024a9272b90192b7254608ba30a4c16ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Dec 2021 22:12:13 -0500
+Subject: ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111
+
+From: Zekun Shen <bruceshenzk@gmail.com>
+
+[ Upstream commit 564d4eceb97eaf381dd6ef6470b06377bb50c95a ]
+
+The bug was found during fuzzing. Stacktrace locates it in
+ath5k_eeprom_convert_pcal_info_5111.
+When none of the curve is selected in the loop, idx can go
+up to AR5K_EEPROM_N_PD_CURVES. The line makes pd out of bound.
+pd = &chinfo[pier].pd_curves[idx];
+
+There are many OOB writes using pd later in the code. So I
+added a sanity check for idx. Checks for other loops involving
+AR5K_EEPROM_N_PD_CURVES are not needed as the loop index is not
+used outside the loops.
+
+The patch is NOT tested with real device.
+
+The following is the fuzzing report
+
+BUG: KASAN: slab-out-of-bounds in ath5k_eeprom_read_pcal_info_5111+0x126a/0x1390 [ath5k]
+Write of size 1 at addr ffff8880174a4d60 by task modprobe/214
+
+CPU: 0 PID: 214 Comm: modprobe Not tainted 5.6.0 #1
+Call Trace:
+ dump_stack+0x76/0xa0
+ print_address_description.constprop.0+0x16/0x200
+ ? ath5k_eeprom_read_pcal_info_5111+0x126a/0x1390 [ath5k]
+ ? ath5k_eeprom_read_pcal_info_5111+0x126a/0x1390 [ath5k]
+ __kasan_report.cold+0x37/0x7c
+ ? ath5k_eeprom_read_pcal_info_5111+0x126a/0x1390 [ath5k]
+ kasan_report+0xe/0x20
+ ath5k_eeprom_read_pcal_info_5111+0x126a/0x1390 [ath5k]
+ ? apic_timer_interrupt+0xa/0x20
+ ? ath5k_eeprom_init_11a_pcal_freq+0xbc0/0xbc0 [ath5k]
+ ? ath5k_pci_eeprom_read+0x228/0x3c0 [ath5k]
+ ath5k_eeprom_init+0x2513/0x6290 [ath5k]
+ ? ath5k_eeprom_init_11a_pcal_freq+0xbc0/0xbc0 [ath5k]
+ ? usleep_range+0xb8/0x100
+ ? apic_timer_interrupt+0xa/0x20
+ ? ath5k_eeprom_read_pcal_info_2413+0x2f20/0x2f20 [ath5k]
+ ath5k_hw_init+0xb60/0x1970 [ath5k]
+ ath5k_init_ah+0x6fe/0x2530 [ath5k]
+ ? kasprintf+0xa6/0xe0
+ ? ath5k_stop+0x140/0x140 [ath5k]
+ ? _dev_notice+0xf6/0xf6
+ ? apic_timer_interrupt+0xa/0x20
+ ath5k_pci_probe.cold+0x29a/0x3d6 [ath5k]
+ ? ath5k_pci_eeprom_read+0x3c0/0x3c0 [ath5k]
+ ? mutex_lock+0x89/0xd0
+ ? ath5k_pci_eeprom_read+0x3c0/0x3c0 [ath5k]
+ local_pci_probe+0xd3/0x160
+ pci_device_probe+0x23f/0x3e0
+ ? pci_device_remove+0x280/0x280
+ ? pci_device_remove+0x280/0x280
+ really_probe+0x209/0x5d0
+
+Reported-by: Brendan Dolan-Gavitt <brendandg@nyu.edu>
+Signed-off-by: Zekun Shen <bruceshenzk@gmail.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/YckvDdj3mtCkDRIt@a-10-27-26-18.dynapool.vpn.nyu.edu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath5k/eeprom.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
+index 1fbc2c19848f..d444b3d70ba2 100644
+--- a/drivers/net/wireless/ath/ath5k/eeprom.c
++++ b/drivers/net/wireless/ath/ath5k/eeprom.c
+@@ -746,6 +746,9 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
+                       }
+               }
++              if (idx == AR5K_EEPROM_N_PD_CURVES)
++                      goto err_out;
++
+               ee->ee_pd_gains[mode] = 1;
+               pd = &chinfo[pier].pd_curves[idx];
+-- 
+2.35.1
+
diff --git a/queue-5.17/bluetooth-fix-not-checking-for-valid-hdev-on-bt_dev_.patch b/queue-5.17/bluetooth-fix-not-checking-for-valid-hdev-on-bt_dev_.patch
new file mode 100644 (file)
index 0000000..e1c28da
--- /dev/null
@@ -0,0 +1,57 @@
+From 651af7c2771e8a32576ab78bf4f83ceba71d1944 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Mar 2022 13:11:57 -0800
+Subject: Bluetooth: Fix not checking for valid hdev on
+ bt_dev_{info,warn,err,dbg}
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 9b392e0e0b6d026da5a62bb79a08f32e27af858e ]
+
+This fixes attemting to print hdev->name directly which causes them to
+print an error:
+
+kernel: read_version:367: (efault): sock 000000006a3008f2
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/bluetooth.h | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
+index a647e5fabdbd..2aa5e95808a5 100644
+--- a/include/net/bluetooth/bluetooth.h
++++ b/include/net/bluetooth/bluetooth.h
+@@ -204,19 +204,21 @@ void bt_err_ratelimited(const char *fmt, ...);
+ #define BT_DBG(fmt, ...)      pr_debug(fmt "\n", ##__VA_ARGS__)
+ #endif
++#define bt_dev_name(hdev) ((hdev) ? (hdev)->name : "null")
++
+ #define bt_dev_info(hdev, fmt, ...)                           \
+-      BT_INFO("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
++      BT_INFO("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ #define bt_dev_warn(hdev, fmt, ...)                           \
+-      BT_WARN("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
++      BT_WARN("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ #define bt_dev_err(hdev, fmt, ...)                            \
+-      BT_ERR("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
++      BT_ERR("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ #define bt_dev_dbg(hdev, fmt, ...)                            \
+-      BT_DBG("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
++      BT_DBG("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ #define bt_dev_warn_ratelimited(hdev, fmt, ...)                       \
+-      bt_warn_ratelimited("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
++      bt_warn_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ #define bt_dev_err_ratelimited(hdev, fmt, ...)                        \
+-      bt_err_ratelimited("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
++      bt_err_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ /* Connection and socket states */
+ enum {
+-- 
+2.35.1
+
diff --git a/queue-5.17/bluetooth-fix-null-ptr-deref-on-hci_sync_conn_comple.patch b/queue-5.17/bluetooth-fix-null-ptr-deref-on-hci_sync_conn_comple.patch
new file mode 100644 (file)
index 0000000..43c602a
--- /dev/null
@@ -0,0 +1,49 @@
+From a509858c432cd5f012b05b3662643633e34ec27b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jan 2022 17:44:02 +0100
+Subject: Bluetooth: fix null ptr deref on hci_sync_conn_complete_evt
+
+From: Soenke Huster <soenke.huster@eknoes.de>
+
+[ Upstream commit 3afee2118132e93e5f6fa636dfde86201a860ab3 ]
+
+This event is just specified for SCO and eSCO link types.
+On the reception of a HCI_Synchronous_Connection_Complete for a BDADDR
+of an existing LE connection, LE link type and a status that triggers the
+second case of the packet processing a NULL pointer dereference happens,
+as conn->link is NULL.
+
+Signed-off-by: Soenke Huster <soenke.huster@eknoes.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index a105b7317560..519f5906ee98 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4661,6 +4661,19 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
+       struct hci_ev_sync_conn_complete *ev = data;
+       struct hci_conn *conn;
++      switch (ev->link_type) {
++      case SCO_LINK:
++      case ESCO_LINK:
++              break;
++      default:
++              /* As per Core 5.3 Vol 4 Part E 7.7.35 (p.2219), Link_Type
++               * for HCI_Synchronous_Connection_Complete is limited to
++               * either SCO or eSCO
++               */
++              bt_dev_err(hdev, "Ignoring connect complete event for invalid link type");
++              return;
++      }
++
+       bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+       hci_dev_lock(hdev);
+-- 
+2.35.1
+
diff --git a/queue-5.17/bluetooth-fix-use-after-free-in-hci_send_acl.patch b/queue-5.17/bluetooth-fix-use-after-free-in-hci_send_acl.patch
new file mode 100644 (file)
index 0000000..f1dae2a
--- /dev/null
@@ -0,0 +1,134 @@
+From aaf739688514816ace84acac19c0da2aa92b6a8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Mar 2022 13:19:33 -0800
+Subject: Bluetooth: Fix use after free in hci_send_acl
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit f63d24baff787e13b723d86fe036f84bdbc35045 ]
+
+This fixes the following trace caused by receiving
+HCI_EV_DISCONN_PHY_LINK_COMPLETE which does call hci_conn_del without
+first checking if conn->type is in fact AMP_LINK and in case it is
+do properly cleanup upper layers with hci_disconn_cfm:
+
+ ==================================================================
+    BUG: KASAN: use-after-free in hci_send_acl+0xaba/0xc50
+    Read of size 8 at addr ffff88800e404818 by task bluetoothd/142
+
+    CPU: 0 PID: 142 Comm: bluetoothd Not tainted
+    5.17.0-rc5-00006-gda4022eeac1a #7
+    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+    rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+    Call Trace:
+     <TASK>
+     dump_stack_lvl+0x45/0x59
+     print_address_description.constprop.0+0x1f/0x150
+     kasan_report.cold+0x7f/0x11b
+     hci_send_acl+0xaba/0xc50
+     l2cap_do_send+0x23f/0x3d0
+     l2cap_chan_send+0xc06/0x2cc0
+     l2cap_sock_sendmsg+0x201/0x2b0
+     sock_sendmsg+0xdc/0x110
+     sock_write_iter+0x20f/0x370
+     do_iter_readv_writev+0x343/0x690
+     do_iter_write+0x132/0x640
+     vfs_writev+0x198/0x570
+     do_writev+0x202/0x280
+     do_syscall_64+0x38/0x90
+     entry_SYSCALL_64_after_hwframe+0x44/0xae
+    RSP: 002b:00007ffce8a099b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000014
+    Code: 0f 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3
+    0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 14 00 00 00 0f 05
+    <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10
+    RDX: 0000000000000001 RSI: 00007ffce8a099e0 RDI: 0000000000000015
+    RAX: ffffffffffffffda RBX: 00007ffce8a099e0 RCX: 00007f788fc3cf77
+    R10: 00007ffce8af7080 R11: 0000000000000246 R12: 000055e4ccf75580
+    RBP: 0000000000000015 R08: 0000000000000002 R09: 0000000000000001
+    </TASK>
+    R13: 000055e4ccf754a0 R14: 000055e4ccf75cd0 R15: 000055e4ccf4a6b0
+
+    Allocated by task 45:
+        kasan_save_stack+0x1e/0x40
+        __kasan_kmalloc+0x81/0xa0
+        hci_chan_create+0x9a/0x2f0
+        l2cap_conn_add.part.0+0x1a/0xdc0
+        l2cap_connect_cfm+0x236/0x1000
+        le_conn_complete_evt+0x15a7/0x1db0
+        hci_le_conn_complete_evt+0x226/0x2c0
+        hci_le_meta_evt+0x247/0x450
+        hci_event_packet+0x61b/0xe90
+        hci_rx_work+0x4d5/0xc50
+        process_one_work+0x8fb/0x15a0
+        worker_thread+0x576/0x1240
+        kthread+0x29d/0x340
+        ret_from_fork+0x1f/0x30
+
+    Freed by task 45:
+        kasan_save_stack+0x1e/0x40
+        kasan_set_track+0x21/0x30
+        kasan_set_free_info+0x20/0x30
+        __kasan_slab_free+0xfb/0x130
+        kfree+0xac/0x350
+        hci_conn_cleanup+0x101/0x6a0
+        hci_conn_del+0x27e/0x6c0
+        hci_disconn_phylink_complete_evt+0xe0/0x120
+        hci_event_packet+0x812/0xe90
+        hci_rx_work+0x4d5/0xc50
+        process_one_work+0x8fb/0x15a0
+        worker_thread+0x576/0x1240
+        kthread+0x29d/0x340
+        ret_from_fork+0x1f/0x30
+
+    The buggy address belongs to the object at ffff88800c0f0500
+    The buggy address is located 24 bytes inside of
+    which belongs to the cache kmalloc-128 of size 128
+    The buggy address belongs to the page:
+    128-byte region [ffff88800c0f0500, ffff88800c0f0580)
+    flags: 0x100000000000200(slab|node=0|zone=1)
+    page:00000000fe45cd86 refcount:1 mapcount:0
+    mapping:0000000000000000 index:0x0 pfn:0xc0f0
+    raw: 0000000000000000 0000000080100010 00000001ffffffff
+    0000000000000000
+    raw: 0100000000000200 ffffea00003a2c80 dead000000000004
+    ffff8880078418c0
+    page dumped because: kasan: bad access detected
+    ffff88800c0f0400: 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc
+    Memory state around the buggy address:
+    >ffff88800c0f0500: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+    ffff88800c0f0480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+    ffff88800c0f0580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+                                ^
+    ==================================================================
+    ffff88800c0f0600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+
+Reported-by: Sönke Huster <soenke.huster@eknoes.de>
+Tested-by: Sönke Huster <soenke.huster@eknoes.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 63b925921c87..d984777c9b58 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -5453,8 +5453,9 @@ static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, void *data,
+       hci_dev_lock(hdev);
+       hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
+-      if (hcon) {
++      if (hcon && hcon->type == AMP_LINK) {
+               hcon->state = BT_CLOSED;
++              hci_disconn_cfm(hcon, ev->reason);
+               hci_conn_del(hcon);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.17/bluetooth-hci_event-ignore-multiple-conn-complete-ev.patch b/queue-5.17/bluetooth-hci_event-ignore-multiple-conn-complete-ev.patch
new file mode 100644 (file)
index 0000000..e73308f
--- /dev/null
@@ -0,0 +1,169 @@
+From 6627e751fcb82a40734045d279ff3245641dc03b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jan 2022 15:06:24 +0100
+Subject: Bluetooth: hci_event: Ignore multiple conn complete events
+
+From: Soenke Huster <soenke.huster@eknoes.de>
+
+[ Upstream commit d5ebaa7c5f6f688959e8d40840b2249ede63b8ed ]
+
+When one of the three connection complete events is received multiple
+times for the same handle, the device is registered multiple times which
+leads to memory corruptions. Therefore, consequent events for a single
+connection are ignored.
+
+The conn->state can hold different values, therefore HCI_CONN_HANDLE_UNSET
+is introduced to identify new connections. To make sure the events do not
+contain this or another invalid handle HCI_CONN_HANDLE_MAX and checks
+are introduced.
+
+Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=215497
+Signed-off-by: Soenke Huster <soenke.huster@eknoes.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h |  3 ++
+ net/bluetooth/hci_conn.c         |  1 +
+ net/bluetooth/hci_event.c        | 63 ++++++++++++++++++++++++--------
+ 3 files changed, 52 insertions(+), 15 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index e336e9c1dda4..36d727f94ac2 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -294,6 +294,9 @@ struct adv_monitor {
+ #define HCI_MAX_SHORT_NAME_LENGTH     10
++#define HCI_CONN_HANDLE_UNSET         0xffff
++#define HCI_CONN_HANDLE_MAX           0x0eff
++
+ /* Min encryption key size to match with SMP */
+ #define HCI_MIN_ENC_KEY_SIZE          7
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 3bb2b3b6a1c9..84312c836549 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -691,6 +691,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
+       bacpy(&conn->dst, dst);
+       bacpy(&conn->src, &hdev->bdaddr);
++      conn->handle = HCI_CONN_HANDLE_UNSET;
+       conn->hdev  = hdev;
+       conn->type  = type;
+       conn->role  = role;
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 519f5906ee98..63b925921c87 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3068,6 +3068,11 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
+       struct hci_ev_conn_complete *ev = data;
+       struct hci_conn *conn;
++      if (__le16_to_cpu(ev->handle) > HCI_CONN_HANDLE_MAX) {
++              bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for invalid handle");
++              return;
++      }
++
+       bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+       hci_dev_lock(hdev);
+@@ -3106,6 +3111,17 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
+               }
+       }
++      /* The HCI_Connection_Complete event is only sent once per connection.
++       * Processing it more than once per connection can corrupt kernel memory.
++       *
++       * As the connection handle is set here for the first time, it indicates
++       * whether the connection is already set up.
++       */
++      if (conn->handle != HCI_CONN_HANDLE_UNSET) {
++              bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
++              goto unlock;
++      }
++
+       if (!ev->status) {
+               conn->handle = __le16_to_cpu(ev->handle);
+@@ -4674,6 +4690,11 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
+               return;
+       }
++      if (__le16_to_cpu(ev->handle) > HCI_CONN_HANDLE_MAX) {
++              bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete for invalid handle");
++              return;
++      }
++
+       bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+       hci_dev_lock(hdev);
+@@ -4697,23 +4718,19 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
+                       goto unlock;
+       }
++      /* The HCI_Synchronous_Connection_Complete event is only sent once per connection.
++       * Processing it more than once per connection can corrupt kernel memory.
++       *
++       * As the connection handle is set here for the first time, it indicates
++       * whether the connection is already set up.
++       */
++      if (conn->handle != HCI_CONN_HANDLE_UNSET) {
++              bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection");
++              goto unlock;
++      }
++
+       switch (ev->status) {
+       case 0x00:
+-              /* The synchronous connection complete event should only be
+-               * sent once per new connection. Receiving a successful
+-               * complete event when the connection status is already
+-               * BT_CONNECTED means that the device is misbehaving and sent
+-               * multiple complete event packets for the same new connection.
+-               *
+-               * Registering the device more than once can corrupt kernel
+-               * memory, hence upon detecting this invalid event, we report
+-               * an error and ignore the packet.
+-               */
+-              if (conn->state == BT_CONNECTED) {
+-                      bt_dev_err(hdev, "Ignoring connect complete event for existing connection");
+-                      goto unlock;
+-              }
+-
+               conn->handle = __le16_to_cpu(ev->handle);
+               conn->state  = BT_CONNECTED;
+               conn->type   = ev->link_type;
+@@ -5509,6 +5526,11 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
+       struct smp_irk *irk;
+       u8 addr_type;
++      if (handle > HCI_CONN_HANDLE_MAX) {
++              bt_dev_err(hdev, "Ignoring HCI_LE_Connection_Complete for invalid handle");
++              return;
++      }
++
+       hci_dev_lock(hdev);
+       /* All controllers implicitly stop advertising in the event of a
+@@ -5550,6 +5572,17 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
+               cancel_delayed_work(&conn->le_conn_timeout);
+       }
++      /* The HCI_LE_Connection_Complete event is only sent once per connection.
++       * Processing it more than once per connection can corrupt kernel memory.
++       *
++       * As the connection handle is set here for the first time, it indicates
++       * whether the connection is already set up.
++       */
++      if (conn->handle != HCI_CONN_HANDLE_UNSET) {
++              bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
++              goto unlock;
++      }
++
+       le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa);
+       /* Lookup the identity address from the stored connection
+-- 
+2.35.1
+
diff --git a/queue-5.17/bluetooth-hci_sync-fix-compilation-warning.patch b/queue-5.17/bluetooth-hci_sync-fix-compilation-warning.patch
new file mode 100644 (file)
index 0000000..9fc514d
--- /dev/null
@@ -0,0 +1,42 @@
+From af4ababf5b2d6ff4ce4358de6a8a1765d4825e1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jan 2022 21:21:45 -0800
+Subject: Bluetooth: hci_sync: Fix compilation warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 89a0b8b98f49ae34886e67624208c2898e1e4d7f ]
+
+This fixes the following warning:
+
+net/bluetooth/hci_sync.c:5143:5: warning: no previous prototype for
+‘hci_le_ext_create_conn_sync’ [-Wmissing-prototypes]
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 405d48c3e63e..48c837530a11 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5156,8 +5156,8 @@ static void set_ext_conn_params(struct hci_conn *conn,
+       p->max_ce_len = cpu_to_le16(0x0000);
+ }
+-int hci_le_ext_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
+-                              u8 own_addr_type)
++static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
++                                     struct hci_conn *conn, u8 own_addr_type)
+ {
+       struct hci_cp_le_ext_create_conn *cp;
+       struct hci_cp_le_ext_conn_param *p;
+-- 
+2.35.1
+
diff --git a/queue-5.17/bluetooth-hci_sync-fix-queuing-commands-when-hci_unr.patch b/queue-5.17/bluetooth-hci_sync-fix-queuing-commands-when-hci_unr.patch
new file mode 100644 (file)
index 0000000..8b69d81
--- /dev/null
@@ -0,0 +1,37 @@
+From 04b6561fc84dc8b1c98f4f2d6032a999ef784d49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 17:21:00 -0800
+Subject: Bluetooth: hci_sync: Fix queuing commands when HCI_UNREGISTER is set
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 0b94f2651f56b9e4aa5f012b0d7eb57308c773cf ]
+
+hci_cmd_sync_queue shall return an error if HCI_UNREGISTER flag has
+been set as that means hci_unregister_dev has been called so it will
+likely cause a uaf after the timeout as the hdev will be freed.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 48c837530a11..8f4c5698913d 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -379,6 +379,9 @@ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
+ {
+       struct hci_cmd_sync_work_entry *entry;
++      if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
++              return -ENODEV;
++
+       entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+       if (!entry)
+               return -ENOMEM;
+-- 
+2.35.1
+
diff --git a/queue-5.17/bluetooth-mediatek-fix-the-conflict-between-mtk-and-.patch b/queue-5.17/bluetooth-mediatek-fix-the-conflict-between-mtk-and-.patch
new file mode 100644 (file)
index 0000000..2e3e371
--- /dev/null
@@ -0,0 +1,99 @@
+From 4fc15215aeaf14c55921ec5fd505933bcbb8d5ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Feb 2022 02:17:41 +0800
+Subject: Bluetooth: mediatek: fix the conflict between mtk and msft vendor
+ event
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit e4412654e260842e1a94ffe0d4026e8a6fd34246 ]
+
+There is a conflict between MediaTek wmt event and msft vendor extension
+logic in the core layer since 145373cb1b1f ("Bluetooth: Add framework for
+Microsoft vendor extension") was introduced because we changed the type of
+mediatek wmt event to the type of msft vendor event in the driver.
+
+But the purpose we reported mediatek event to the core layer is for the
+diagnostic purpose with that we are able to see the full packet trace via
+monitoring socket with btmon. Thus, it is harmless we keep the original
+type of mediatek vendor event here to avoid breaking the msft extension
+function especially they can be supported by Mediatek chipset like MT7921
+, MT7922 devices and future devices.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btmtk.h     | 1 +
+ drivers/bluetooth/btmtksdio.c | 9 +--------
+ drivers/bluetooth/btusb.c     | 8 --------
+ 3 files changed, 2 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
+index 6e7b0c7567c0..0defa68bc2ce 100644
+--- a/drivers/bluetooth/btmtk.h
++++ b/drivers/bluetooth/btmtk.h
+@@ -5,6 +5,7 @@
+ #define FIRMWARE_MT7668               "mediatek/mt7668pr2h.bin"
+ #define FIRMWARE_MT7961               "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
++#define HCI_EV_WMT 0xe4
+ #define HCI_WMT_MAX_EVENT_SIZE                64
+ #define BTMTK_WMT_REG_READ 0x2
+diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
+index 9b868f187316..ecf29cfa7d79 100644
+--- a/drivers/bluetooth/btmtksdio.c
++++ b/drivers/bluetooth/btmtksdio.c
+@@ -370,13 +370,6 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
+       struct hci_event_hdr *hdr = (void *)skb->data;
+       int err;
+-      /* Fix up the vendor event id with 0xff for vendor specific instead
+-       * of 0xe4 so that event send via monitoring socket can be parsed
+-       * properly.
+-       */
+-      if (hdr->evt == 0xe4)
+-              hdr->evt = HCI_EV_VENDOR;
+-
+       /* When someone waits for the WMT event, the skb is being cloned
+        * and being processed the events from there then.
+        */
+@@ -392,7 +385,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
+       if (err < 0)
+               goto err_free_skb;
+-      if (hdr->evt == HCI_EV_VENDOR) {
++      if (hdr->evt == HCI_EV_WMT) {
+               if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
+                                      &bdev->tx_state)) {
+                       /* Barrier to sync with other CPUs */
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 2afbd87d77c9..42234d5f602d 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2254,7 +2254,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
+ {
+       struct hci_dev *hdev = urb->context;
+       struct btusb_data *data = hci_get_drvdata(hdev);
+-      struct hci_event_hdr *hdr;
+       struct sk_buff *skb;
+       int err;
+@@ -2274,13 +2273,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
+               hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
+               skb_put_data(skb, urb->transfer_buffer, urb->actual_length);
+-              hdr = (void *)skb->data;
+-              /* Fix up the vendor event id with 0xff for vendor specific
+-               * instead of 0xe4 so that event send via monitoring socket can
+-               * be parsed properly.
+-               */
+-              hdr->evt = 0xff;
+-
+               /* When someone waits for the WMT event, the skb is being cloned
+                * and being processed the events from there then.
+                */
+-- 
+2.35.1
+
diff --git a/queue-5.17/bluetooth-use-memset-avoid-memory-leaks.patch b/queue-5.17/bluetooth-use-memset-avoid-memory-leaks.patch
new file mode 100644 (file)
index 0000000..32fbed3
--- /dev/null
@@ -0,0 +1,35 @@
+From 1c499fa0582a95339ad89ba5ddcc0fd1e7a48c93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Feb 2022 07:41:52 +0000
+Subject: Bluetooth: use memset avoid memory leaks
+
+From: Minghao Chi (CGEL ZTE) <chi.minghao@zte.com.cn>
+
+[ Upstream commit d3715b2333e9a21692ba16ef8645eda584a9515d ]
+
+Use memset to initialize structs to prevent memory leaks
+in l2cap_ecred_connect
+
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Minghao Chi (CGEL ZTE) <chi.minghao@zte.com.cn>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index e817ff0607a0..8df99c07f272 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -1436,6 +1436,7 @@ static void l2cap_ecred_connect(struct l2cap_chan *chan)
+       l2cap_ecred_init(chan, 0);
++      memset(&data, 0, sizeof(data));
+       data.pdu.req.psm     = chan->psm;
+       data.pdu.req.mtu     = cpu_to_le16(chan->imtu);
+       data.pdu.req.mps     = cpu_to_le16(chan->mps);
+-- 
+2.35.1
+
diff --git a/queue-5.17/bnxt_en-eliminate-unintended-link-toggle-during-fw-r.patch b/queue-5.17/bnxt_en-eliminate-unintended-link-toggle-during-fw-r.patch
new file mode 100644 (file)
index 0000000..e47209f
--- /dev/null
@@ -0,0 +1,47 @@
+From 66993be51482ee46e0fe1d119cde9773b6e83dbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Mar 2022 03:54:39 -0500
+Subject: bnxt_en: Eliminate unintended link toggle during FW reset
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 7c492a2530c1f05441da541307c2534230dfd59b ]
+
+If the flow control settings have been changed, a subsequent FW reset
+may cause the ethernet link to toggle unnecessarily.  This link toggle
+will increase the down time by a few seconds.
+
+The problem is caused by bnxt_update_phy_setting() detecting a false
+mismatch in the flow control settings between the stored software
+settings and the current FW settings after the FW reset.  This mismatch
+is caused by the AUTONEG bit added to link_info->req_flow_ctrl in an
+inconsistent way in bnxt_set_pauseparam() in autoneg mode.  The AUTONEG
+bit should not be added to link_info->req_flow_ctrl.
+
+Reviewed-by: Colin Winegarden <colin.winegarden@broadcom.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+index 8aaa2335f848..f09b04556c32 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+@@ -2101,9 +2101,7 @@ static int bnxt_set_pauseparam(struct net_device *dev,
+               }
+               link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
+-              if (bp->hwrm_spec_code >= 0x10201)
+-                      link_info->req_flow_ctrl =
+-                              PORT_PHY_CFG_REQ_AUTO_PAUSE_AUTONEG_PAUSE;
++              link_info->req_flow_ctrl = 0;
+       } else {
+               /* when transition from auto pause to force pause,
+                * force a link change
+-- 
+2.35.1
+
diff --git a/queue-5.17/bpf-make-dst_port-field-in-struct-bpf_sock-16-bit-wi.patch b/queue-5.17/bpf-make-dst_port-field-in-struct-bpf_sock-16-bit-wi.patch
new file mode 100644 (file)
index 0000000..eb332b4
--- /dev/null
@@ -0,0 +1,94 @@
+From 1aba8d14c37ebc73590c52e19847de8e1db5b2da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Jan 2022 12:55:17 +0100
+Subject: bpf: Make dst_port field in struct bpf_sock 16-bit wide
+
+From: Jakub Sitnicki <jakub@cloudflare.com>
+
+[ Upstream commit 4421a582718ab81608d8486734c18083b822390d ]
+
+Menglong Dong reports that the documentation for the dst_port field in
+struct bpf_sock is inaccurate and confusing. From the BPF program PoV, the
+field is a zero-padded 16-bit integer in network byte order. The value
+appears to the BPF user as if laid out in memory as so:
+
+  offsetof(struct bpf_sock, dst_port) + 0  <port MSB>
+                                      + 8  <port LSB>
+                                      +16  0x00
+                                      +24  0x00
+
+32-, 16-, and 8-bit wide loads from the field are all allowed, but only if
+the offset into the field is 0.
+
+32-bit wide loads from dst_port are especially confusing. The loaded value,
+after converting to host byte order with bpf_ntohl(dst_port), contains the
+port number in the upper 16-bits.
+
+Remove the confusion by splitting the field into two 16-bit fields. For
+backward compatibility, allow 32-bit wide loads from offsetof(struct
+bpf_sock, dst_port).
+
+While at it, allow loads 8-bit loads at offset [0] and [1] from dst_port.
+
+Reported-by: Menglong Dong <imagedong@tencent.com>
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/r/20220130115518.213259-2-jakub@cloudflare.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/bpf.h |  3 ++-
+ net/core/filter.c        | 10 +++++++++-
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index 015bfec0dbfd..51b0f899424a 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -5500,7 +5500,8 @@ struct bpf_sock {
+       __u32 src_ip4;
+       __u32 src_ip6[4];
+       __u32 src_port;         /* host byte order */
+-      __u32 dst_port;         /* network byte order */
++      __be16 dst_port;        /* network byte order */
++      __u16 :16;              /* zero padding */
+       __u32 dst_ip4;
+       __u32 dst_ip6[4];
+       __u32 state;
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 9eb785842258..82fcb7533663 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -8033,6 +8033,7 @@ bool bpf_sock_is_valid_access(int off, int size, enum bpf_access_type type,
+                             struct bpf_insn_access_aux *info)
+ {
+       const int size_default = sizeof(__u32);
++      int field_size;
+       if (off < 0 || off >= sizeof(struct bpf_sock))
+               return false;
+@@ -8044,7 +8045,6 @@ bool bpf_sock_is_valid_access(int off, int size, enum bpf_access_type type,
+       case offsetof(struct bpf_sock, family):
+       case offsetof(struct bpf_sock, type):
+       case offsetof(struct bpf_sock, protocol):
+-      case offsetof(struct bpf_sock, dst_port):
+       case offsetof(struct bpf_sock, src_port):
+       case offsetof(struct bpf_sock, rx_queue_mapping):
+       case bpf_ctx_range(struct bpf_sock, src_ip4):
+@@ -8053,6 +8053,14 @@ bool bpf_sock_is_valid_access(int off, int size, enum bpf_access_type type,
+       case bpf_ctx_range_till(struct bpf_sock, dst_ip6[0], dst_ip6[3]):
+               bpf_ctx_record_field_size(info, size_default);
+               return bpf_ctx_narrow_access_ok(off, size, size_default);
++      case bpf_ctx_range(struct bpf_sock, dst_port):
++              field_size = size == size_default ?
++                      size_default : sizeof_field(struct bpf_sock, dst_port);
++              bpf_ctx_record_field_size(info, field_size);
++              return bpf_ctx_narrow_access_ok(off, size, field_size);
++      case offsetofend(struct bpf_sock, dst_port) ...
++           offsetof(struct bpf_sock, dst_ip4) - 1:
++              return false;
+       }
+       return size == size_default;
+-- 
+2.35.1
+
diff --git a/queue-5.17/can-etas_es58x-es58x_fd_rx_event_msg-initialize-rx_e.patch b/queue-5.17/can-etas_es58x-es58x_fd_rx_event_msg-initialize-rx_e.patch
new file mode 100644 (file)
index 0000000..f4bf10f
--- /dev/null
@@ -0,0 +1,64 @@
+From a1b1bb3b4485528e2769d6bb64b792031c20e43d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Mar 2022 19:13:02 +0900
+Subject: can: etas_es58x: es58x_fd_rx_event_msg(): initialize rx_event_msg
+ before calling es58x_check_msg_len()
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 7a8cd7c0ee823a1cc893ab3feaa23e4b602bfb9a ]
+
+Function es58x_fd_rx_event() invokes the es58x_check_msg_len() macro:
+
+|      ret = es58x_check_msg_len(es58x_dev->dev, *rx_event_msg, msg_len);
+
+While doing so, it dereferences an uninitialized
+variable: *rx_event_msg.
+
+This is actually harmless because es58x_check_msg_len() only uses
+preprocessor macros (sizeof() and __stringify()) on
+*rx_event_msg. c.f. [1].
+
+Nonetheless, this pattern is confusing so the lines are reordered to
+make sure that rx_event_msg is correctly initialized.
+
+This patch also fixes a false positive warning reported by cppcheck:
+
+| cppcheck possible warnings: (new ones prefixed by >>, may not be real problems)
+|
+|    In file included from drivers/net/can/usb/etas_es58x/es58x_fd.c:
+| >> drivers/net/can/usb/etas_es58x/es58x_fd.c:174:8: warning: Uninitialized variable: rx_event_msg [uninitvar]
+|     ret = es58x_check_msg_len(es58x_dev->dev, *rx_event_msg, msg_len);
+|           ^
+
+[1] https://elixir.bootlin.com/linux/v5.16/source/drivers/net/can/usb/etas_es58x/es58x_core.h#L467
+
+Link: https://lore.kernel.org/all/20220306101302.708783-1-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/etas_es58x/es58x_fd.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_fd.c b/drivers/net/can/usb/etas_es58x/es58x_fd.c
+index ec87126e1a7d..8ccda748fd08 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_fd.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_fd.c
+@@ -172,12 +172,11 @@ static int es58x_fd_rx_event_msg(struct net_device *netdev,
+       const struct es58x_fd_rx_event_msg *rx_event_msg;
+       int ret;
++      rx_event_msg = &es58x_fd_urb_cmd->rx_event_msg;
+       ret = es58x_check_msg_len(es58x_dev->dev, *rx_event_msg, msg_len);
+       if (ret)
+               return ret;
+-      rx_event_msg = &es58x_fd_urb_cmd->rx_event_msg;
+-
+       return es58x_rx_err_msg(netdev, rx_event_msg->error_code,
+                               rx_event_msg->event_code,
+                               get_unaligned_le64(&rx_event_msg->timestamp));
+-- 
+2.35.1
+
diff --git a/queue-5.17/can-isotp-set-default-value-for-n_as-to-50-micro-sec.patch b/queue-5.17/can-isotp-set-default-value-for-n_as-to-50-micro-sec.patch
new file mode 100644 (file)
index 0000000..8c55954
--- /dev/null
@@ -0,0 +1,138 @@
+From ef168cdcf6880a23d13a9ffe081e7ca4125e82f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Mar 2022 13:04:13 +0100
+Subject: can: isotp: set default value for N_As to 50 micro seconds
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 530e0d46c61314c59ecfdb8d3bcb87edbc0f85d3 ]
+
+The N_As value describes the time a CAN frame needs on the wire when
+transmitted by the CAN controller. Even very short CAN FD frames need
+arround 100 usecs (bitrate 1Mbit/s, data bitrate 8Mbit/s).
+
+Having N_As to be zero (the former default) leads to 'no CAN frame
+separation' when STmin is set to zero by the receiving node. This 'burst
+mode' should not be enabled by default as it could potentially dump a high
+number of CAN frames into the netdev queue from the soft hrtimer context.
+This does not affect the system stability but is just not nice and
+cooperative.
+
+With this N_As/frame_txtime value the 'burst mode' is disabled by default.
+
+As user space applications usually do not set the frame_txtime element
+of struct can_isotp_options the new in-kernel default is very likely
+overwritten with zero when the sockopt() CAN_ISOTP_OPTS is invoked.
+To make sure that a N_As value of zero is only set intentional the
+value '0' is now interpreted as 'do not change the current value'.
+When a frame_txtime of zero is required for testing purposes this
+CAN_ISOTP_FRAME_TXTIME_ZERO u32 value has to be set in frame_txtime.
+
+Link: https://lore.kernel.org/all/20220309120416.83514-2-socketcan@hartkopp.net
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/can/isotp.h | 28 ++++++++++++++++++++++------
+ net/can/isotp.c                | 12 +++++++++++-
+ 2 files changed, 33 insertions(+), 7 deletions(-)
+
+diff --git a/include/uapi/linux/can/isotp.h b/include/uapi/linux/can/isotp.h
+index c55935b64ccc..590f8aea2b6d 100644
+--- a/include/uapi/linux/can/isotp.h
++++ b/include/uapi/linux/can/isotp.h
+@@ -137,20 +137,16 @@ struct can_isotp_ll_options {
+ #define CAN_ISOTP_WAIT_TX_DONE        0x400   /* wait for tx completion */
+ #define CAN_ISOTP_SF_BROADCAST        0x800   /* 1-to-N functional addressing */
+-/* default values */
++/* protocol machine default values */
+ #define CAN_ISOTP_DEFAULT_FLAGS               0
+ #define CAN_ISOTP_DEFAULT_EXT_ADDRESS 0x00
+ #define CAN_ISOTP_DEFAULT_PAD_CONTENT 0xCC /* prevent bit-stuffing */
+-#define CAN_ISOTP_DEFAULT_FRAME_TXTIME        0
++#define CAN_ISOTP_DEFAULT_FRAME_TXTIME        50000 /* 50 micro seconds */
+ #define CAN_ISOTP_DEFAULT_RECV_BS     0
+ #define CAN_ISOTP_DEFAULT_RECV_STMIN  0x00
+ #define CAN_ISOTP_DEFAULT_RECV_WFTMAX 0
+-#define CAN_ISOTP_DEFAULT_LL_MTU      CAN_MTU
+-#define CAN_ISOTP_DEFAULT_LL_TX_DL    CAN_MAX_DLEN
+-#define CAN_ISOTP_DEFAULT_LL_TX_FLAGS 0
+-
+ /*
+  * Remark on CAN_ISOTP_DEFAULT_RECV_* values:
+  *
+@@ -162,4 +158,24 @@ struct can_isotp_ll_options {
+  * consistency and copied directly into the flow control (FC) frame.
+  */
++/* link layer default values => make use of Classical CAN frames */
++
++#define CAN_ISOTP_DEFAULT_LL_MTU      CAN_MTU
++#define CAN_ISOTP_DEFAULT_LL_TX_DL    CAN_MAX_DLEN
++#define CAN_ISOTP_DEFAULT_LL_TX_FLAGS 0
++
++/*
++ * The CAN_ISOTP_DEFAULT_FRAME_TXTIME has become a non-zero value as
++ * it only makes sense for isotp implementation tests to run without
++ * a N_As value. As user space applications usually do not set the
++ * frame_txtime element of struct can_isotp_options the new in-kernel
++ * default is very likely overwritten with zero when the sockopt()
++ * CAN_ISOTP_OPTS is invoked.
++ * To make sure that a N_As value of zero is only set intentional the
++ * value '0' is now interpreted as 'do not change the current value'.
++ * When a frame_txtime of zero is required for testing purposes this
++ * CAN_ISOTP_FRAME_TXTIME_ZERO u32 value has to be set in frame_txtime.
++ */
++#define CAN_ISOTP_FRAME_TXTIME_ZERO   0xFFFFFFFF
++
+ #endif /* !_UAPI_CAN_ISOTP_H */
+diff --git a/net/can/isotp.c b/net/can/isotp.c
+index a95d171b3a64..5bce7c66c121 100644
+--- a/net/can/isotp.c
++++ b/net/can/isotp.c
+@@ -141,6 +141,7 @@ struct isotp_sock {
+       struct can_isotp_options opt;
+       struct can_isotp_fc_options rxfc, txfc;
+       struct can_isotp_ll_options ll;
++      u32 frame_txtime;
+       u32 force_tx_stmin;
+       u32 force_rx_stmin;
+       struct tpcon rx, tx;
+@@ -360,7 +361,7 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
+               so->tx_gap = ktime_set(0, 0);
+               /* add transmission time for CAN frame N_As */
+-              so->tx_gap = ktime_add_ns(so->tx_gap, so->opt.frame_txtime);
++              so->tx_gap = ktime_add_ns(so->tx_gap, so->frame_txtime);
+               /* add waiting time for consecutive frames N_Cs */
+               if (so->opt.flags & CAN_ISOTP_FORCE_TXSTMIN)
+                       so->tx_gap = ktime_add_ns(so->tx_gap,
+@@ -1247,6 +1248,14 @@ static int isotp_setsockopt_locked(struct socket *sock, int level, int optname,
+               /* no separate rx_ext_address is given => use ext_address */
+               if (!(so->opt.flags & CAN_ISOTP_RX_EXT_ADDR))
+                       so->opt.rx_ext_address = so->opt.ext_address;
++
++              /* check for frame_txtime changes (0 => no changes) */
++              if (so->opt.frame_txtime) {
++                      if (so->opt.frame_txtime == CAN_ISOTP_FRAME_TXTIME_ZERO)
++                              so->frame_txtime = 0;
++                      else
++                              so->frame_txtime = so->opt.frame_txtime;
++              }
+               break;
+       case CAN_ISOTP_RECV_FC:
+@@ -1448,6 +1457,7 @@ static int isotp_init(struct sock *sk)
+       so->opt.rxpad_content = CAN_ISOTP_DEFAULT_PAD_CONTENT;
+       so->opt.txpad_content = CAN_ISOTP_DEFAULT_PAD_CONTENT;
+       so->opt.frame_txtime = CAN_ISOTP_DEFAULT_FRAME_TXTIME;
++      so->frame_txtime = CAN_ISOTP_DEFAULT_FRAME_TXTIME;
+       so->rxfc.bs = CAN_ISOTP_DEFAULT_RECV_BS;
+       so->rxfc.stmin = CAN_ISOTP_DEFAULT_RECV_STMIN;
+       so->rxfc.wftmax = CAN_ISOTP_DEFAULT_RECV_WFTMAX;
+-- 
+2.35.1
+
diff --git a/queue-5.17/ceph-fix-inode-reference-leakage-in-ceph_get_snapdir.patch b/queue-5.17/ceph-fix-inode-reference-leakage-in-ceph_get_snapdir.patch
new file mode 100644 (file)
index 0000000..df5c154
--- /dev/null
@@ -0,0 +1,59 @@
+From fd2236b0afd59956635332e7e7c07c66d5ef8988 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 14:51:53 +0800
+Subject: ceph: fix inode reference leakage in ceph_get_snapdir()
+
+From: Xiubo Li <xiubli@redhat.com>
+
+[ Upstream commit 322794d3355c33adcc4feace0045d85a8e4ed813 ]
+
+The ceph_get_inode() will search for or insert a new inode into the
+hash for the given vino, and return a reference to it. If new is
+non-NULL, its reference is consumed.
+
+We should release the reference when in error handing cases.
+
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/inode.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
+index ef4a980a7bf3..c092dce0485c 100644
+--- a/fs/ceph/inode.c
++++ b/fs/ceph/inode.c
+@@ -87,13 +87,13 @@ struct inode *ceph_get_snapdir(struct inode *parent)
+       if (!S_ISDIR(parent->i_mode)) {
+               pr_warn_once("bad snapdir parent type (mode=0%o)\n",
+                            parent->i_mode);
+-              return ERR_PTR(-ENOTDIR);
++              goto err;
+       }
+       if (!(inode->i_state & I_NEW) && !S_ISDIR(inode->i_mode)) {
+               pr_warn_once("bad snapdir inode type (mode=0%o)\n",
+                            inode->i_mode);
+-              return ERR_PTR(-ENOTDIR);
++              goto err;
+       }
+       inode->i_mode = parent->i_mode;
+@@ -113,6 +113,12 @@ struct inode *ceph_get_snapdir(struct inode *parent)
+       }
+       return inode;
++err:
++      if ((inode->i_state & I_NEW))
++              discard_new_inode(inode);
++      else
++              iput(inode);
++      return ERR_PTR(-ENOTDIR);
+ }
+ const struct inode_operations ceph_file_iops = {
+-- 
+2.35.1
+
diff --git a/queue-5.17/ceph-fix-memory-leak-in-ceph_readdir-when-note_last_.patch b/queue-5.17/ceph-fix-memory-leak-in-ceph_readdir-when-note_last_.patch
new file mode 100644 (file)
index 0000000..238ccb0
--- /dev/null
@@ -0,0 +1,54 @@
+From 050a8d0f7bc2e97942da015e256f62c1686238cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Mar 2022 19:52:59 +0800
+Subject: ceph: fix memory leak in ceph_readdir when note_last_dentry returns
+ error
+
+From: Xiubo Li <xiubli@redhat.com>
+
+[ Upstream commit f639d9867eea647005dc824e0e24f39ffc50d4e4 ]
+
+Reset the last_readdir at the same time, and add a comment explaining
+why we don't free last_readdir when dir_emit returns false.
+
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/dir.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
+index 133dbd9338e7..d91fa53e12b3 100644
+--- a/fs/ceph/dir.c
++++ b/fs/ceph/dir.c
+@@ -478,8 +478,11 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
+                                       2 : (fpos_off(rde->offset) + 1);
+                       err = note_last_dentry(dfi, rde->name, rde->name_len,
+                                              next_offset);
+-                      if (err)
++                      if (err) {
++                              ceph_mdsc_put_request(dfi->last_readdir);
++                              dfi->last_readdir = NULL;
+                               return err;
++                      }
+               } else if (req->r_reply_info.dir_end) {
+                       dfi->next_offset = 2;
+                       /* keep last name */
+@@ -520,6 +523,12 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
+               if (!dir_emit(ctx, rde->name, rde->name_len,
+                             ceph_present_ino(inode->i_sb, le64_to_cpu(rde->inode.in->ino)),
+                             le32_to_cpu(rde->inode.in->mode) >> 12)) {
++                      /*
++                       * NOTE: Here no need to put the 'dfi->last_readdir',
++                       * because when dir_emit stops us it's most likely
++                       * doesn't have enough memory, etc. So for next readdir
++                       * it will continue.
++                       */
+                       dout("filldir stopping us...\n");
+                       return 0;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.17/cfg80211-don-t-add-non-transmitted-bss-to-6ghz-scann.patch b/queue-5.17/cfg80211-don-t-add-non-transmitted-bss-to-6ghz-scann.patch
new file mode 100644 (file)
index 0000000..03c504b
--- /dev/null
@@ -0,0 +1,54 @@
+From 66fc2f4f1cf016d7aa86d2d518dbf63bd286f44c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Feb 2022 10:49:37 +0200
+Subject: cfg80211: don't add non transmitted BSS to 6GHz scanned channels
+
+From: Avraham Stern <avraham.stern@intel.com>
+
+[ Upstream commit 5666ee154f4696c011dfa8544aaf5591b6b87515 ]
+
+When adding 6GHz channels to scan request based on reported
+co-located APs, don't add channels that have only APs with
+"non-transmitted" BSSes if they only match the wildcard SSID since
+they will be found by probing the "transmitted" BSS.
+
+Signed-off-by: Avraham Stern <avraham.stern@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20220202104617.f6ddf099f934.I231e55885d3644f292d00dfe0f42653269f2559e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index b888522f133b..b2fdac96bab0 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -700,8 +700,12 @@ static bool cfg80211_find_ssid_match(struct cfg80211_colocated_ap *ap,
+       for (i = 0; i < request->n_ssids; i++) {
+               /* wildcard ssid in the scan request */
+-              if (!request->ssids[i].ssid_len)
++              if (!request->ssids[i].ssid_len) {
++                      if (ap->multi_bss && !ap->transmitted_bssid)
++                              continue;
++
+                       return true;
++              }
+               if (ap->ssid_len &&
+                   ap->ssid_len == request->ssids[i].ssid_len) {
+@@ -827,6 +831,9 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
+                   !cfg80211_find_ssid_match(ap, request))
+                       continue;
++              if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid)
++                      continue;
++
+               cfg80211_scan_req_add_chan(request, chan, true);
+               memcpy(scan_6ghz_params->bssid, ap->bssid, ETH_ALEN);
+               scan_6ghz_params->short_ssid = ap->short_ssid;
+-- 
+2.35.1
+
diff --git a/queue-5.17/clk-enforce-that-disjoints-limits-are-invalid.patch b/queue-5.17/clk-enforce-that-disjoints-limits-are-invalid.patch
new file mode 100644 (file)
index 0000000..af92e35
--- /dev/null
@@ -0,0 +1,103 @@
+From 57d0abc4ca50cce3657e6cfbc3f4a44cc122ebde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Feb 2022 15:35:25 +0100
+Subject: clk: Enforce that disjoints limits are invalid
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit 10c46f2ea914202482d19cf80dcc9c321c9ff59b ]
+
+If we were to have two users of the same clock, doing something like:
+
+clk_set_rate_range(user1, 1000, 2000);
+clk_set_rate_range(user2, 3000, 4000);
+
+The second call would fail with -EINVAL, preventing from getting in a
+situation where we end up with impossible limits.
+
+However, this is never explicitly checked against and enforced, and
+works by relying on an undocumented behaviour of clk_set_rate().
+
+Indeed, on the first clk_set_rate_range will make sure the current clock
+rate is within the new range, so it will be between 1000 and 2000Hz. On
+the second clk_set_rate_range(), it will consider (rightfully), that our
+current clock is outside of the 3000-4000Hz range, and will call
+clk_core_set_rate_nolock() to set it to 3000Hz.
+
+clk_core_set_rate_nolock() will then call clk_calc_new_rates() that will
+eventually check that our rate 3000Hz rate is outside the min 3000Hz max
+2000Hz range, will bail out, the error will propagate and we'll
+eventually return -EINVAL.
+
+This solely relies on the fact that clk_calc_new_rates(), and in
+particular clk_core_determine_round_nolock(), won't modify the new rate
+allowing the error to be reported. That assumption won't be true for all
+drivers, and most importantly we'll break that assumption in a later
+patch.
+
+It can also be argued that we shouldn't even reach the point where we're
+calling clk_core_set_rate_nolock().
+
+Let's make an explicit check for disjoints range before we're doing
+anything.
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://lore.kernel.org/r/20220225143534.405820-4-maxime@cerno.tech
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 01b64b962e76..2fdfce116087 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -632,6 +632,24 @@ static void clk_core_get_boundaries(struct clk_core *core,
+               *max_rate = min(*max_rate, clk_user->max_rate);
+ }
++static bool clk_core_check_boundaries(struct clk_core *core,
++                                    unsigned long min_rate,
++                                    unsigned long max_rate)
++{
++      struct clk *user;
++
++      lockdep_assert_held(&prepare_lock);
++
++      if (min_rate > core->max_rate || max_rate < core->min_rate)
++              return false;
++
++      hlist_for_each_entry(user, &core->clks, clks_node)
++              if (min_rate > user->max_rate || max_rate < user->min_rate)
++                      return false;
++
++      return true;
++}
++
+ void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
+                          unsigned long max_rate)
+ {
+@@ -2348,6 +2366,11 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
+       clk->min_rate = min;
+       clk->max_rate = max;
++      if (!clk_core_check_boundaries(clk->core, min, max)) {
++              ret = -EINVAL;
++              goto out;
++      }
++
+       rate = clk_core_get_rate_nolock(clk->core);
+       if (rate < min || rate > max) {
+               /*
+@@ -2376,6 +2399,7 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
+               }
+       }
++out:
+       if (clk->exclusive_count)
+               clk_core_rate_protect(clk->core);
+-- 
+2.35.1
+
diff --git a/queue-5.17/clk-mediatek-fix-memory-leaks-on-probe.patch b/queue-5.17/clk-mediatek-fix-memory-leaks-on-probe.patch
new file mode 100644 (file)
index 0000000..668669c
--- /dev/null
@@ -0,0 +1,91 @@
+From 85efa20b028f3135fb3dcc1d8d25fcaaa22c509a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Jan 2022 19:30:59 +0100
+Subject: clk: mediatek: Fix memory leaks on probe
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit 7a688c91d3fd54c53e7a9edd6052cdae98dd99d8 ]
+
+Handle the error branches to free memory where required.
+
+Addresses-Coverity-ID: 1491825 ("Resource leak")
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20220115183059.GA10809@elementary
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt8192.c | 36 +++++++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
+index cbc7c6dbe0f4..79ddb3cc0b98 100644
+--- a/drivers/clk/mediatek/clk-mt8192.c
++++ b/drivers/clk/mediatek/clk-mt8192.c
+@@ -1236,9 +1236,17 @@ static int clk_mt8192_infra_probe(struct platform_device *pdev)
+       r = mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), clk_data);
+       if (r)
+-              return r;
++              goto free_clk_data;
++
++      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++      if (r)
++              goto free_clk_data;
++
++      return r;
+-      return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++free_clk_data:
++      mtk_free_clk_data(clk_data);
++      return r;
+ }
+ static int clk_mt8192_peri_probe(struct platform_device *pdev)
+@@ -1253,9 +1261,17 @@ static int clk_mt8192_peri_probe(struct platform_device *pdev)
+       r = mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), clk_data);
+       if (r)
+-              return r;
++              goto free_clk_data;
++
++      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++      if (r)
++              goto free_clk_data;
+-      return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++      return r;
++
++free_clk_data:
++      mtk_free_clk_data(clk_data);
++      return r;
+ }
+ static int clk_mt8192_apmixed_probe(struct platform_device *pdev)
+@@ -1271,9 +1287,17 @@ static int clk_mt8192_apmixed_probe(struct platform_device *pdev)
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+       r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
+       if (r)
+-              return r;
++              goto free_clk_data;
+-      return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++      if (r)
++              goto free_clk_data;
++
++      return r;
++
++free_clk_data:
++      mtk_free_clk_data(clk_data);
++      return r;
+ }
+ static const struct of_device_id of_match_clk_mt8192[] = {
+-- 
+2.35.1
+
diff --git a/queue-5.17/clk-rockchip-drop-clk_set_rate_parent-from-dclk_vop-.patch b/queue-5.17/clk-rockchip-drop-clk_set_rate_parent-from-dclk_vop-.patch
new file mode 100644 (file)
index 0000000..ea8a1cf
--- /dev/null
@@ -0,0 +1,49 @@
+From 121f56d9c12a158638f9c8bd024687276d1923dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 15:55:46 +0100
+Subject: clk: rockchip: drop CLK_SET_RATE_PARENT from dclk_vop* on rk3568
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit ff3187eabb5ce478d15b6ed62eb286756adefac3 ]
+
+The pixel clocks dclk_vop[012] can be clocked from hpll, vpll, gpll or
+cpll. gpll and cpll also drive many other clocks, so changing the
+dclk_vop[012] clocks could change these other clocks as well. Drop
+CLK_SET_RATE_PARENT to fix that. With this change the VOP2 driver can
+only adjust the pixel clocks with the divider between the PLL and the
+dclk_vop[012] which means the user may have to adjust the PLL clock to a
+suitable rate using the assigned-clock-rate device tree property.
+
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Link: https://lore.kernel.org/r/20220126145549.617165-25-s.hauer@pengutronix.de
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/rockchip/clk-rk3568.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
+index 69a9e8069a48..604a367bc498 100644
+--- a/drivers/clk/rockchip/clk-rk3568.c
++++ b/drivers/clk/rockchip/clk-rk3568.c
+@@ -1038,13 +1038,13 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
+                       RK3568_CLKGATE_CON(20), 8, GFLAGS),
+       GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0,
+                       RK3568_CLKGATE_CON(20), 9, GFLAGS),
+-      COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
++      COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
+                       RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS,
+                       RK3568_CLKGATE_CON(20), 10, GFLAGS),
+-      COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
++      COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
+                       RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS,
+                       RK3568_CLKGATE_CON(20), 11, GFLAGS),
+-      COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0,
++      COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
+                       RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS,
+                       RK3568_CLKGATE_CON(20), 12, GFLAGS),
+       GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0,
+-- 
+2.35.1
+
diff --git a/queue-5.17/clk-si5341-fix-reported-clk_rate-when-output-divider.patch b/queue-5.17/clk-si5341-fix-reported-clk_rate-when-output-divider.patch
new file mode 100644 (file)
index 0000000..e80f655
--- /dev/null
@@ -0,0 +1,62 @@
+From 7d862336fd239742fd2f08ee4f9f2f1cff07f1a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Dec 2021 14:12:07 +0000
+Subject: clk: si5341: fix reported clk_rate when output divider is 2
+
+From: Adam Wujek <dev_public@wujek.eu>
+
+[ Upstream commit 2a8b539433e111c4de364237627ef219d2f6350a ]
+
+SI5341_OUT_CFG_RDIV_FORCE2 shall be checked first to distinguish whether
+a divider for a given output is set to 2 (SI5341_OUT_CFG_RDIV_FORCE2
+is set) or the output is disabled (SI5341_OUT_CFG_RDIV_FORCE2 not set,
+SI5341_OUT_R_REG is set 0).
+Before the change, divider set to 2 (SI5341_OUT_R_REG set to 0) was
+interpreted as output is disabled.
+
+Signed-off-by: Adam Wujek <dev_public@wujek.eu>
+Link: https://lore.kernel.org/r/20211203141125.2447520-1-dev_public@wujek.eu
+Reviewed-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index f7b41366666e..4de098b6b0d4 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -798,6 +798,15 @@ static unsigned long si5341_output_clk_recalc_rate(struct clk_hw *hw,
+       u32 r_divider;
+       u8 r[3];
++      err = regmap_read(output->data->regmap,
++                      SI5341_OUT_CONFIG(output), &val);
++      if (err < 0)
++              return err;
++
++      /* If SI5341_OUT_CFG_RDIV_FORCE2 is set, r_divider is 2 */
++      if (val & SI5341_OUT_CFG_RDIV_FORCE2)
++              return parent_rate / 2;
++
+       err = regmap_bulk_read(output->data->regmap,
+                       SI5341_OUT_R_REG(output), r, 3);
+       if (err < 0)
+@@ -814,13 +823,6 @@ static unsigned long si5341_output_clk_recalc_rate(struct clk_hw *hw,
+       r_divider += 1;
+       r_divider <<= 1;
+-      err = regmap_read(output->data->regmap,
+-                      SI5341_OUT_CONFIG(output), &val);
+-      if (err < 0)
+-              return err;
+-
+-      if (val & SI5341_OUT_CFG_RDIV_FORCE2)
+-              r_divider = 2;
+       return parent_rate / r_divider;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/clk-ti-preserve-node-in-ti_dt_clocks_register.patch b/queue-5.17/clk-ti-preserve-node-in-ti_dt_clocks_register.patch
new file mode 100644 (file)
index 0000000..90dc65c
--- /dev/null
@@ -0,0 +1,56 @@
+From 0dc220962c0eb6c589608f1b55cf1338b548187d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 09:14:43 +0200
+Subject: clk: ti: Preserve node in ti_dt_clocks_register()
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 80864594ff2ad002e2755daf97d46ff0c86faf1f ]
+
+In preparation for making use of the clock-output-names, we want to
+keep node around in ti_dt_clocks_register().
+
+This change should not needed as a fix currently.
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20220204071449.16762-3-tony@atomide.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/clk.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
+index 3da33c786d77..29eafab4353e 100644
+--- a/drivers/clk/ti/clk.c
++++ b/drivers/clk/ti/clk.c
+@@ -131,7 +131,7 @@ int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops)
+ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
+ {
+       struct ti_dt_clk *c;
+-      struct device_node *node, *parent;
++      struct device_node *node, *parent, *child;
+       struct clk *clk;
+       struct of_phandle_args clkspec;
+       char buf[64];
+@@ -171,10 +171,13 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
+               node = of_find_node_by_name(NULL, buf);
+               if (num_args && compat_mode) {
+                       parent = node;
+-                      node = of_get_child_by_name(parent, "clock");
+-                      if (!node)
+-                              node = of_get_child_by_name(parent, "clk");
+-                      of_node_put(parent);
++                      child = of_get_child_by_name(parent, "clock");
++                      if (!child)
++                              child = of_get_child_by_name(parent, "clk");
++                      if (child) {
++                              of_node_put(parent);
++                              node = child;
++                      }
+               }
+               clkspec.np = node;
+-- 
+2.35.1
+
diff --git a/queue-5.17/cpufreq-cppc-fix-performance-frequency-conversion.patch b/queue-5.17/cpufreq-cppc-fix-performance-frequency-conversion.patch
new file mode 100644 (file)
index 0000000..79d1fe6
--- /dev/null
@@ -0,0 +1,135 @@
+From c7cd1a9154a01b82d0d0d301561db4e3310b8cb7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Feb 2022 09:01:09 +0100
+Subject: cpufreq: CPPC: Fix performance/frequency conversion
+
+From: Pierre Gondois <Pierre.Gondois@arm.com>
+
+[ Upstream commit ec1c7ad47664f964c1101fe555b6fde0cb124b38 ]
+
+CPUfreq governors request CPU frequencies using information
+on current CPU usage. The CPPC driver converts them to
+performance requests. Frequency targets are computed as:
+       target_freq = (util / cpu_capacity) * max_freq
+target_freq is then clamped between [policy->min, policy->max].
+
+The CPPC driver converts performance values to frequencies
+(and vice-versa) using cppc_cpufreq_perf_to_khz() and
+cppc_cpufreq_khz_to_perf(). These functions both use two different
+factors depending on the range of the input value. For
+cppc_cpufreq_khz_to_perf():
+- (NOMINAL_PERF / NOMINAL_FREQ) or
+- (LOWEST_PERF / LOWEST_FREQ)
+and for cppc_cpufreq_perf_to_khz():
+- (NOMINAL_FREQ / NOMINAL_PERF) or
+- ((NOMINAL_PERF - LOWEST_FREQ) / (NOMINAL_PERF - LOWEST_PERF))
+
+This means:
+1- the functions are not inverse for some values:
+   (perf_to_khz(khz_to_perf(x)) != x)
+2- cppc_cpufreq_perf_to_khz(LOWEST_PERF) can sometimes give
+   a different value from LOWEST_FREQ due to integer approximation
+3- it is implied that performance and frequency are proportional
+   (NOMINAL_FREQ / NOMINAL_PERF) == (LOWEST_PERF / LOWEST_FREQ)
+
+This patch changes the conversion functions to an affine function.
+This fixes the 3 points above.
+
+Suggested-by: Lukasz Luba <lukasz.luba@arm.com>
+Suggested-by: Morten Rasmussen <morten.rasmussen@arm.com>
+Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cppc_cpufreq.c | 43 +++++++++++++++++-----------------
+ 1 file changed, 21 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
+index db17196266e4..82d370ae6a4a 100644
+--- a/drivers/cpufreq/cppc_cpufreq.c
++++ b/drivers/cpufreq/cppc_cpufreq.c
+@@ -303,52 +303,48 @@ static u64 cppc_get_dmi_max_khz(void)
+ /*
+  * If CPPC lowest_freq and nominal_freq registers are exposed then we can
+- * use them to convert perf to freq and vice versa
+- *
+- * If the perf/freq point lies between Nominal and Lowest, we can treat
+- * (Low perf, Low freq) and (Nom Perf, Nom freq) as 2D co-ordinates of a line
+- * and extrapolate the rest
+- * For perf/freq > Nominal, we use the ratio perf:freq at Nominal for conversion
++ * use them to convert perf to freq and vice versa. The conversion is
++ * extrapolated as an affine function passing by the 2 points:
++ *  - (Low perf, Low freq)
++ *  - (Nominal perf, Nominal perf)
+  */
+ static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu_data,
+                                            unsigned int perf)
+ {
+       struct cppc_perf_caps *caps = &cpu_data->perf_caps;
++      s64 retval, offset = 0;
+       static u64 max_khz;
+       u64 mul, div;
+       if (caps->lowest_freq && caps->nominal_freq) {
+-              if (perf >= caps->nominal_perf) {
+-                      mul = caps->nominal_freq;
+-                      div = caps->nominal_perf;
+-              } else {
+-                      mul = caps->nominal_freq - caps->lowest_freq;
+-                      div = caps->nominal_perf - caps->lowest_perf;
+-              }
++              mul = caps->nominal_freq - caps->lowest_freq;
++              div = caps->nominal_perf - caps->lowest_perf;
++              offset = caps->nominal_freq - div64_u64(caps->nominal_perf * mul, div);
+       } else {
+               if (!max_khz)
+                       max_khz = cppc_get_dmi_max_khz();
+               mul = max_khz;
+               div = caps->highest_perf;
+       }
+-      return (u64)perf * mul / div;
++
++      retval = offset + div64_u64(perf * mul, div);
++      if (retval >= 0)
++              return retval;
++      return 0;
+ }
+ static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu_data,
+                                            unsigned int freq)
+ {
+       struct cppc_perf_caps *caps = &cpu_data->perf_caps;
++      s64 retval, offset = 0;
+       static u64 max_khz;
+       u64  mul, div;
+       if (caps->lowest_freq && caps->nominal_freq) {
+-              if (freq >= caps->nominal_freq) {
+-                      mul = caps->nominal_perf;
+-                      div = caps->nominal_freq;
+-              } else {
+-                      mul = caps->lowest_perf;
+-                      div = caps->lowest_freq;
+-              }
++              mul = caps->nominal_perf - caps->lowest_perf;
++              div = caps->nominal_freq - caps->lowest_freq;
++              offset = caps->nominal_perf - div64_u64(caps->nominal_freq * mul, div);
+       } else {
+               if (!max_khz)
+                       max_khz = cppc_get_dmi_max_khz();
+@@ -356,7 +352,10 @@ static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu_data,
+               div = max_khz;
+       }
+-      return (u64)freq * mul / div;
++      retval = offset + div64_u64(freq * mul, div);
++      if (retval >= 0)
++              return retval;
++      return 0;
+ }
+ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
+-- 
+2.35.1
+
diff --git a/queue-5.17/dm-ioctl-prevent-potential-spectre-v1-gadget.patch b/queue-5.17/dm-ioctl-prevent-potential-spectre-v1-gadget.patch
new file mode 100644 (file)
index 0000000..f3ffc49
--- /dev/null
@@ -0,0 +1,44 @@
+From 3c4136a82fc9d849053a5d5300fee8d0e3c7f417 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Jan 2022 15:58:39 +0100
+Subject: dm ioctl: prevent potential spectre v1 gadget
+
+From: Jordy Zomer <jordy@jordyzomer.github.io>
+
+[ Upstream commit cd9c88da171a62c4b0f1c70e50c75845969fbc18 ]
+
+It appears like cmd could be a Spectre v1 gadget as it's supplied by a
+user and used as an array index. Prevent the contents of kernel memory
+from being leaked to userspace via speculative execution by using
+array_index_nospec.
+
+Signed-off-by: Jordy Zomer <jordy@pwning.systems>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-ioctl.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 21fe8652b095..901abd6dea41 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -18,6 +18,7 @@
+ #include <linux/dm-ioctl.h>
+ #include <linux/hdreg.h>
+ #include <linux/compat.h>
++#include <linux/nospec.h>
+ #include <linux/uaccess.h>
+ #include <linux/ima.h>
+@@ -1788,6 +1789,7 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
+       if (unlikely(cmd >= ARRAY_SIZE(_ioctls)))
+               return NULL;
++      cmd = array_index_nospec(cmd, ARRAY_SIZE(_ioctls));
+       *ioctl_flags = _ioctls[cmd].flags;
+       return _ioctls[cmd].fn;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/dm-requeue-io-if-mapping-table-not-yet-available.patch b/queue-5.17/dm-requeue-io-if-mapping-table-not-yet-available.patch
new file mode 100644 (file)
index 0000000..bd80d16
--- /dev/null
@@ -0,0 +1,70 @@
+From 9e2572a0cf4482e4d9101470f1f5d9c024f0b0cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Feb 2022 13:28:12 -0500
+Subject: dm: requeue IO if mapping table not yet available
+
+From: Mike Snitzer <snitzer@redhat.com>
+
+[ Upstream commit fa247089de9936a46e290d4724cb5f0b845600f5 ]
+
+Update both bio-based and request-based DM to requeue IO if the
+mapping table not available.
+
+This race of IO being submitted before the DM device ready is so
+narrow, yet possible for initial table load given that the DM device's
+request_queue is created prior, that it best to requeue IO to handle
+this unlikely case.
+
+Reported-by: Zhang Yi <yi.zhang@huawei.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-rq.c |  7 ++++++-
+ drivers/md/dm.c    | 11 +++--------
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 579ab6183d4d..dffeb47a9efb 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -499,8 +499,13 @@ static blk_status_t dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
+       if (unlikely(!ti)) {
+               int srcu_idx;
+-              struct dm_table *map = dm_get_live_table(md, &srcu_idx);
++              struct dm_table *map;
++              map = dm_get_live_table(md, &srcu_idx);
++              if (unlikely(!map)) {
++                      dm_put_live_table(md, srcu_idx);
++                      return BLK_STS_RESOURCE;
++              }
+               ti = dm_table_find_target(map, 0);
+               dm_put_live_table(md, srcu_idx);
+       }
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 394778d8bf54..dcb8d8fc7877 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1519,15 +1519,10 @@ static void dm_submit_bio(struct bio *bio)
+       struct dm_table *map;
+       map = dm_get_live_table(md, &srcu_idx);
+-      if (unlikely(!map)) {
+-              DMERR_LIMIT("%s: mapping table unavailable, erroring io",
+-                          dm_device_name(md));
+-              bio_io_error(bio);
+-              goto out;
+-      }
+-      /* If suspended, queue this IO for later */
+-      if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
++      /* If suspended, or map not yet available, queue this IO for later */
++      if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) ||
++          unlikely(!map)) {
+               if (bio->bi_opf & REQ_NOWAIT)
+                       bio_wouldblock_error(bio);
+               else if (bio->bi_opf & REQ_RAHEAD)
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-add-orientation-quirk-for-gpd-win-max.patch b/queue-5.17/drm-add-orientation-quirk-for-gpd-win-max.patch
new file mode 100644 (file)
index 0000000..ba4cbd5
--- /dev/null
@@ -0,0 +1,40 @@
+From 9636dd1828341d6fe5242a7e80e60090d9ca7090 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Dec 2021 23:22:00 +0100
+Subject: drm: Add orientation quirk for GPD Win Max
+
+From: Anisse Astier <anisse@astier.eu>
+
+[ Upstream commit 0b464ca3e0dd3cec65f28bc6d396d82f19080f69 ]
+
+Panel is 800x1280, but mounted on a laptop form factor, sideways.
+
+Signed-off-by: Anisse Astier <anisse@astier.eu>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211229222200.53128-3-anisse@astier.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index b910978d3e48..4e853acfd1e8 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -180,6 +180,12 @@ static const struct dmi_system_id orientation_data[] = {
+                 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"),
+               },
+               .driver_data = (void *)&lcd720x1280_rightside_up,
++      }, {    /* GPD Win Max */
++              .matches = {
++                DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
++                DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1619-01"),
++              },
++              .driver_data = (void *)&lcd800x1280_rightside_up,
+       }, {    /*
+                * GPD Pocket, note that the the DMI data is less generic then
+                * it seems, devices with a board-vendor of "AMI Corporation"
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amd-amdgpu-amdgpu_cs-fix-refcount-leak-of-a-dma_.patch b/queue-5.17/drm-amd-amdgpu-amdgpu_cs-fix-refcount-leak-of-a-dma_.patch
new file mode 100644 (file)
index 0000000..5f183bb
--- /dev/null
@@ -0,0 +1,46 @@
+From cd82cbaae60ff870e7e06deb47955d3bc2c5f9f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jan 2022 15:46:23 -0500
+Subject: drm/amd/amdgpu/amdgpu_cs: fix refcount leak of a dma_fence obj
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xin Xiong <xiongx18@fudan.edu.cn>
+
+[ Upstream commit dfced44f122c500004a48ecc8db516bb6a295a1b ]
+
+This issue takes place in an error path in
+amdgpu_cs_fence_to_handle_ioctl(). When `info->in.what` falls into
+default case, the function simply returns -EINVAL, forgetting to
+decrement the reference count of a dma_fence obj, which is bumped
+earlier by amdgpu_cs_get_fence(). This may result in reference count
+leaks.
+
+Fix it by decreasing the refcount of specific object before returning
+the error code.
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Xin Xiong <xiongx18@fudan.edu.cn>
+Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index 06d07502a1f6..a34be65c9eaa 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -1509,6 +1509,7 @@ int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data,
+               return 0;
+       default:
++              dma_fence_put(fence);
+               return -EINVAL;
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amd-display-add-signal-type-check-when-verify-st.patch b/queue-5.17/drm-amd-display-add-signal-type-check-when-verify-st.patch
new file mode 100644 (file)
index 0000000..f57314f
--- /dev/null
@@ -0,0 +1,47 @@
+From 522fc9a2d326e08ec4784dbf9ea90a91845fda33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Dec 2021 16:50:28 +0800
+Subject: drm/amd/display: Add signal type check when verify stream backends
+ same
+
+From: Dale Zhao <dale.zhao@amd.com>
+
+[ Upstream commit 047db281c026de5971cedb5bb486aa29bd16a39d ]
+
+[Why]
+For allow eDP hot-plug feature, the stream signal may change to VIRTUAL
+when plug-out and back to eDP when plug-in. OS will still setPathMode
+with same timing for each plugging, but eDP gets no stream update as we
+don't check signal type changing back as keeping it VIRTUAL. It's also
+unsafe for future cases that stream signal is switched with same timing.
+
+[How]
+Check stream signal type change include previous HDMI signal case.
+
+Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Wayne Lin <wayne.lin@amd.com>
+Signed-off-by: Dale Zhao <dale.zhao@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_resource.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+index 18757c158523..ac3071e38e4a 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+@@ -1640,6 +1640,9 @@ static bool are_stream_backends_same(
+       if (is_timing_changed(stream_a, stream_b))
+               return false;
++      if (stream_a->signal != stream_b->signal)
++              return false;
++
+       if (stream_a->dpms_off != stream_b->dpms_off)
+               return false;
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amd-display-fix-memory-leak.patch b/queue-5.17/drm-amd-display-fix-memory-leak.patch
new file mode 100644 (file)
index 0000000..f50890b
--- /dev/null
@@ -0,0 +1,271 @@
+From 477e66ab4f084086871981af00bc389bb17adcf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jan 2022 11:26:13 +0000
+Subject: drm/amd/display: Fix memory leak
+
+From: Yongzhi Liu <lyz_cs@pku.edu.cn>
+
+[ Upstream commit 5d5c6dba2b43e28845d7d7ed32a36802329a5f52 ]
+
+[why]
+Resource release is needed on the error handling path
+to prevent memory leak.
+
+[how]
+Fix this by adding kfree on the error handling path.
+
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Yongzhi Liu <lyz_cs@pku.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 80 ++++++++++++++-----
+ 1 file changed, 60 insertions(+), 20 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 26719efa5396..12d437d9a0e4 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
+@@ -227,8 +227,10 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -389,8 +391,10 @@ static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user((*(rd_buf + result)), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1359,8 +1363,10 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1376,8 +1382,10 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1546,8 +1554,10 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1563,8 +1573,10 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1731,8 +1743,10 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1748,8 +1762,10 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1912,8 +1928,10 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1929,8 +1947,10 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -2088,8 +2108,10 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -2105,8 +2127,10 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -2145,8 +2169,10 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -2162,8 +2188,10 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -2217,8 +2245,10 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -2234,8 +2264,10 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -2289,8 +2321,10 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -2306,8 +2340,10 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -3459,8 +3495,10 @@ static ssize_t dcc_en_bits_read(
+       dc->hwss.get_dcc_en_bits(dc, dcc_en_bits);
+       rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
+-      if (!rd_buf)
++      if (!rd_buf) {
++              kfree(dcc_en_bits);
+               return -ENOMEM;
++      }
+       for (i = 0; i < num_pipes; i++)
+               offset += snprintf(rd_buf + offset, rd_buf_size - offset,
+@@ -3473,8 +3511,10 @@ static ssize_t dcc_en_bits_read(
+               if (*pos >= rd_buf_size)
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+               *pos += 1;
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amd-display-reset-lane-settings-after-each-phy-r.patch b/queue-5.17/drm-amd-display-reset-lane-settings-after-each-phy-r.patch
new file mode 100644 (file)
index 0000000..700dcf2
--- /dev/null
@@ -0,0 +1,74 @@
+From a811400000523530e29f33d4fb0afa6962be00c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Feb 2022 13:59:02 -0500
+Subject: drm/amd/display: reset lane settings after each PHY repeater LT
+
+From: Sung Joon Kim <sungkim@amd.com>
+
+[ Upstream commit 3b853c316c9321e195414a6fb121d1c2d45b1e87 ]
+
+[why]
+In LTTPR non-transparent mode, we need
+to reset the cached lane settings before performing
+link training on the next PHY repeater. Otherwise,
+the cached lane settings will be used for the next
+clock recovery e.g. VS = MAX (3) which should not be
+the case according to the DP specs. We expect to use
+minimum lane settings on each clock recovery sequence.
+
+[how]
+Reset DPCD and HW lane settings on each repeater LT.
+Set training pattern to 0 for the repeater that failed LT
+at the proper place.
+
+Reviewed-by: Meenakshikumar Somasundaram <Meenakshikumar.Somasundaram@amd.com>
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Jasdeep Dhillon <jdhillon@amd.com>
+Signed-off-by: Sung Joon Kim <sungkim@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_link_dp.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+index 61b8f29a0c30..49d5271dcfdc 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+@@ -2378,22 +2378,27 @@ static enum link_training_result dp_perform_8b_10b_link_training(
+                               repeater_id--) {
+                       status = perform_clock_recovery_sequence(link, link_res, lt_settings, repeater_id);
+-                      if (status != LINK_TRAINING_SUCCESS)
++                      if (status != LINK_TRAINING_SUCCESS) {
++                              repeater_training_done(link, repeater_id);
+                               break;
++                      }
+                       status = perform_channel_equalization_sequence(link,
+                                       link_res,
+                                       lt_settings,
+                                       repeater_id);
++                      repeater_training_done(link, repeater_id);
++
+                       if (status != LINK_TRAINING_SUCCESS)
+                               break;
+-                      repeater_training_done(link, repeater_id);
++                      for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
++                              lt_settings->dpcd_lane_settings[lane].raw = 0;
++                              lt_settings->hw_lane_settings[lane].VOLTAGE_SWING = 0;
++                              lt_settings->hw_lane_settings[lane].PRE_EMPHASIS = 0;
++                      }
+               }
+-
+-              for (lane = 0; lane < (uint8_t)lt_settings->link_settings.lane_count; lane++)
+-                      lt_settings->dpcd_lane_settings[lane].raw = 0;
+       }
+       if (status == LINK_TRAINING_SUCCESS) {
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amd-display-use-psr-version-selected-during-set_.patch b/queue-5.17/drm-amd-display-use-psr-version-selected-during-set_.patch
new file mode 100644 (file)
index 0000000..60d0d68
--- /dev/null
@@ -0,0 +1,51 @@
+From 6748b03a0f9d207a5d4b29231295da3c46db45a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jan 2022 13:20:04 -0500
+Subject: drm/amd/display: Use PSR version selected during set_psr_caps
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit b80ddeb29d9df449f875f0b6f5de08d7537c02b8 ]
+
+[Why]
+If the DPCD caps specifies a PSR version newer than PSR_VERSION_1 then
+we fallback to using PSR_VERSION_1 in amdgpu_dm_set_psr_caps.
+
+This gets overriden with the raw DPCD value in amdgpu_dm_link_setup_psr,
+which can result in DMCUB hanging if we pass in an unsupported PSR
+version number.
+
+[How]
+Fix the hang by using link->psr_settings.psr_version directly during
+amdgpu_dm_link_setup_psr.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@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_psr.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+index c510638b4f99..a009fc654ac9 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+@@ -149,10 +149,8 @@ bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream)
+       link = stream->link;
+-      psr_config.psr_version = link->dpcd_caps.psr_caps.psr_version;
+-
+-      if (psr_config.psr_version > 0) {
+-              psr_config.psr_exit_link_training_required = 0x1;
++      if (link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED) {
++              psr_config.psr_version = link->psr_settings.psr_version;
+               psr_config.psr_frame_capture_indication_req = 0;
+               psr_config.psr_rfb_setup_time = 0x37;
+               psr_config.psr_sdp_transmit_line_num_deadline = 0x20;
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amdgpu-fix-an-error-message-in-rmmod.patch b/queue-5.17/drm-amdgpu-fix-an-error-message-in-rmmod.patch
new file mode 100644 (file)
index 0000000..a52536b
--- /dev/null
@@ -0,0 +1,47 @@
+From 4a68230098259e94bae8227560ac6e2b4cd1038b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 16:54:03 +0800
+Subject: drm/amdgpu: Fix an error message in rmmod
+
+From: Tianci.Yin <tianci.yin@amd.com>
+
+[ Upstream commit 7270e8957eb9aacf5914605d04865f3829a14bce ]
+
+[why]
+In rmmod procedure, kfd sends cp a dequeue request, but the
+request does not get response, then an error message "cp
+queue pipe 4 queue 0 preemption failed" printed.
+
+[how]
+Performing kfd suspending after disabling gfxoff can fix it.
+
+Acked-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
+Signed-off-by: Tianci.Yin <tianci.yin@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 | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index f18c698137a6..b87dca6d09fa 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2723,11 +2723,11 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
+               }
+       }
+-      amdgpu_amdkfd_suspend(adev, false);
+-
+       amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
+       amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
++      amdgpu_amdkfd_suspend(adev, false);
++
+       /* Workaroud for ASICs need to disable SMC first */
+       amdgpu_device_smu_fini_early(adev);
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amdgpu-fix-recursive-locking-warning.patch b/queue-5.17/drm-amdgpu-fix-recursive-locking-warning.patch
new file mode 100644 (file)
index 0000000..e34d24c
--- /dev/null
@@ -0,0 +1,141 @@
+From 63db2495f329e51b5c80e151905d926aabedfb7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Feb 2022 21:18:21 -0500
+Subject: drm/amdgpu: Fix recursive locking warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rajneesh Bhardwaj <rajneesh.bhardwaj@amd.com>
+
+[ Upstream commit 447c7997b62a5115ba4da846dcdee4fc12298a6a ]
+
+Noticed the below warning while running a pytorch workload on vega10
+GPUs. Change to trylock to avoid conflicts with already held reservation
+locks.
+
+[  +0.000003] WARNING: possible recursive locking detected
+[  +0.000003] 5.13.0-kfd-rajneesh #1030 Not tainted
+[  +0.000004] --------------------------------------------
+[  +0.000002] python/4822 is trying to acquire lock:
+[  +0.000004] ffff932cd9a259f8 (reservation_ww_class_mutex){+.+.}-{3:3},
+at: amdgpu_bo_release_notify+0xc4/0x160 [amdgpu]
+[  +0.000203]
+              but task is already holding lock:
+[  +0.000003] ffff932cbb7181f8 (reservation_ww_class_mutex){+.+.}-{3:3},
+at: ttm_eu_reserve_buffers+0x270/0x470 [ttm]
+[  +0.000017]
+              other info that might help us debug this:
+[  +0.000002]  Possible unsafe locking scenario:
+
+[  +0.000003]        CPU0
+[  +0.000002]        ----
+[  +0.000002]   lock(reservation_ww_class_mutex);
+[  +0.000004]   lock(reservation_ww_class_mutex);
+[  +0.000003]
+               *** DEADLOCK ***
+
+[  +0.000002]  May be due to missing lock nesting notation
+
+[  +0.000003] 7 locks held by python/4822:
+[  +0.000003]  #0: ffff932c4ac028d0 (&process->mutex){+.+.}-{3:3}, at:
+kfd_ioctl_map_memory_to_gpu+0x10b/0x320 [amdgpu]
+[  +0.000232]  #1: ffff932c55e830a8 (&info->lock#2){+.+.}-{3:3}, at:
+amdgpu_amdkfd_gpuvm_map_memory_to_gpu+0x64/0xf60 [amdgpu]
+[  +0.000241]  #2: ffff932cc45b5e68 (&(*mem)->lock){+.+.}-{3:3}, at:
+amdgpu_amdkfd_gpuvm_map_memory_to_gpu+0xdf/0xf60 [amdgpu]
+[  +0.000236]  #3: ffffb2b35606fd28
+(reservation_ww_class_acquire){+.+.}-{0:0}, at:
+amdgpu_amdkfd_gpuvm_map_memory_to_gpu+0x232/0xf60 [amdgpu]
+[  +0.000235]  #4: ffff932cbb7181f8
+(reservation_ww_class_mutex){+.+.}-{3:3}, at:
+ttm_eu_reserve_buffers+0x270/0x470 [ttm]
+[  +0.000015]  #5: ffffffffc045f700 (*(sspp++)){....}-{0:0}, at:
+drm_dev_enter+0x5/0xa0 [drm]
+[  +0.000038]  #6: ffff932c52da7078 (&vm->eviction_lock){+.+.}-{3:3},
+at: amdgpu_vm_bo_update_mapping+0xd5/0x4f0 [amdgpu]
+[  +0.000195]
+              stack backtrace:
+[  +0.000003] CPU: 11 PID: 4822 Comm: python Not tainted
+5.13.0-kfd-rajneesh #1030
+[  +0.000005] Hardware name: GIGABYTE MZ01-CE0-00/MZ01-CE0-00, BIOS F02
+08/29/2018
+[  +0.000003] Call Trace:
+[  +0.000003]  dump_stack+0x6d/0x89
+[  +0.000010]  __lock_acquire+0xb93/0x1a90
+[  +0.000009]  lock_acquire+0x25d/0x2d0
+[  +0.000005]  ? amdgpu_bo_release_notify+0xc4/0x160 [amdgpu]
+[  +0.000184]  ? lock_is_held_type+0xa2/0x110
+[  +0.000006]  ? amdgpu_bo_release_notify+0xc4/0x160 [amdgpu]
+[  +0.000184]  __ww_mutex_lock.constprop.17+0xca/0x1060
+[  +0.000007]  ? amdgpu_bo_release_notify+0xc4/0x160 [amdgpu]
+[  +0.000183]  ? lock_release+0x13f/0x270
+[  +0.000005]  ? lock_is_held_type+0xa2/0x110
+[  +0.000006]  ? amdgpu_bo_release_notify+0xc4/0x160 [amdgpu]
+[  +0.000183]  amdgpu_bo_release_notify+0xc4/0x160 [amdgpu]
+[  +0.000185]  ttm_bo_release+0x4c6/0x580 [ttm]
+[  +0.000010]  amdgpu_bo_unref+0x1a/0x30 [amdgpu]
+[  +0.000183]  amdgpu_vm_free_table+0x76/0xa0 [amdgpu]
+[  +0.000189]  amdgpu_vm_free_pts+0xb8/0xf0 [amdgpu]
+[  +0.000189]  amdgpu_vm_update_ptes+0x411/0x770 [amdgpu]
+[  +0.000191]  amdgpu_vm_bo_update_mapping+0x324/0x4f0 [amdgpu]
+[  +0.000191]  amdgpu_vm_bo_update+0x251/0x610 [amdgpu]
+[  +0.000191]  update_gpuvm_pte+0xcc/0x290 [amdgpu]
+[  +0.000229]  ? amdgpu_vm_bo_map+0xd7/0x130 [amdgpu]
+[  +0.000190]  amdgpu_amdkfd_gpuvm_map_memory_to_gpu+0x912/0xf60
+[amdgpu]
+[  +0.000234]  kfd_ioctl_map_memory_to_gpu+0x182/0x320 [amdgpu]
+[  +0.000218]  kfd_ioctl+0x2b9/0x600 [amdgpu]
+[  +0.000216]  ? kfd_ioctl_unmap_memory_from_gpu+0x270/0x270 [amdgpu]
+[  +0.000216]  ? lock_release+0x13f/0x270
+[  +0.000006]  ? __fget_files+0x107/0x1e0
+[  +0.000007]  __x64_sys_ioctl+0x8b/0xd0
+[  +0.000007]  do_syscall_64+0x36/0x70
+[  +0.000004]  entry_SYSCALL_64_after_hwframe+0x44/0xae
+[  +0.000007] RIP: 0033:0x7fbff90a7317
+[  +0.000004] 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
+[  +0.000005] RSP: 002b:00007fbe301fe648 EFLAGS: 00000246 ORIG_RAX:
+0000000000000010
+[  +0.000006] RAX: ffffffffffffffda RBX: 00007fbcc402d820 RCX:
+00007fbff90a7317
+[  +0.000003] RDX: 00007fbe301fe690 RSI: 00000000c0184b18 RDI:
+0000000000000004
+[  +0.000003] RBP: 00007fbe301fe690 R08: 0000000000000000 R09:
+00007fbcc402d880
+[  +0.000003] R10: 0000000002001000 R11: 0000000000000246 R12:
+00000000c0184b18
+[  +0.000003] R13: 0000000000000004 R14: 00007fbf689593a0 R15:
+00007fbcc402d820
+
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Felix Kuehling <Felix.Kuehling@amd.com>
+Cc: Alex Deucher <Alexander.Deucher@amd.com>
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Signed-off-by: Rajneesh Bhardwaj <rajneesh.bhardwaj@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_object.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index 5661b82d84d4..dda53fe30975 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -1303,7 +1303,8 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
+           !(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE))
+               return;
+-      dma_resv_lock(bo->base.resv, NULL);
++      if (WARN_ON_ONCE(!dma_resv_trylock(bo->base.resv)))
++              return;
+       r = amdgpu_fill_buffer(abo, AMDGPU_POISON, bo->base.resv, &fence);
+       if (!WARN_ON(r)) {
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amdkfd-don-t-take-process-mutex-for-svm-ioctls.patch b/queue-5.17/drm-amdkfd-don-t-take-process-mutex-for-svm-ioctls.patch
new file mode 100644 (file)
index 0000000..2aef1f6
--- /dev/null
@@ -0,0 +1,55 @@
+From d651f28ddebb66f369d3a3850e0a229656c4a099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jan 2022 16:40:44 -0500
+Subject: drm/amdkfd: Don't take process mutex for svm ioctls
+
+From: Philip Yang <Philip.Yang@amd.com>
+
+[ Upstream commit ac7c48c0cce00d03b3c95fddcccb0a45257e33e3 ]
+
+SVM ioctls take proper svms->lock to handle race conditions, don't need
+take process mutex to serialize ioctls. This also fixes circular locking
+warning:
+
+WARNING: possible circular locking dependency detected
+
+  Possible unsafe locking scenario:
+
+        CPU0                    CPU1
+        ----                    ----
+   lock((work_completion)(&svms->deferred_list_work));
+                                lock(&process->mutex);
+                     lock((work_completion)(&svms->deferred_list_work));
+   lock(&process->mutex);
+
+   *** DEADLOCK ***
+
+Signed-off-by: Philip Yang <Philip.Yang@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/amdkfd/kfd_chardev.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+index 337953af7c2f..70122978bdd0 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+@@ -1846,13 +1846,9 @@ static int kfd_ioctl_svm(struct file *filep, struct kfd_process *p, void *data)
+       if (!args->start_addr || !args->size)
+               return -EINVAL;
+-      mutex_lock(&p->mutex);
+-
+       r = svm_ioctl(p, args->op, args->start_addr, args->size, args->nattr,
+                     args->attrs);
+-      mutex_unlock(&p->mutex);
+-
+       return r;
+ }
+ #else
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amdkfd-enable-heavy-weight-tlb-flush-on-arcturus.patch b/queue-5.17/drm-amdkfd-enable-heavy-weight-tlb-flush-on-arcturus.patch
new file mode 100644 (file)
index 0000000..7cdc762
--- /dev/null
@@ -0,0 +1,77 @@
+From ea44dfd5d435ce72d2b28aba65439cd7d0c4d239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jan 2022 10:57:54 -0500
+Subject: drm/amdkfd: enable heavy-weight TLB flush on Arcturus
+
+From: Eric Huang <jinhuieric.huang@amd.com>
+
+[ Upstream commit f61c40c0757a79bcf744314df606c2bc8ae6a729 ]
+
+SDMA FW fixes the hang issue for adding heavy-weight TLB
+flush on Arcturus, so we can enable it.
+
+Signed-off-by: Eric Huang <jinhuieric.huang@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |  6 ------
+ drivers/gpu/drm/amd/amdkfd/kfd_chardev.c         | 10 ++++++++--
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index f9bab963a948..5df387c4d7fb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -1813,12 +1813,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
+                               true);
+       ret = unreserve_bo_and_vms(&ctx, false, false);
+-      /* Only apply no TLB flush on Aldebaran to
+-       * workaround regressions on other Asics.
+-       */
+-      if (table_freed && (adev->asic_type != CHIP_ALDEBARAN))
+-              *table_freed = true;
+-
+       goto out;
+ out_unreserve:
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+index 4bfc0c8ab764..337953af7c2f 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+@@ -1416,6 +1416,12 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
+       return ret;
+ }
++static bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev) {
++      return KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2) ||
++             (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) &&
++              dev->adev->sdma.instance[0].fw_version >= 18);
++}
++
+ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
+                                       struct kfd_process *p, void *data)
+ {
+@@ -1503,7 +1509,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
+       }
+       /* Flush TLBs after waiting for the page table updates to complete */
+-      if (table_freed) {
++      if (table_freed || !kfd_flush_tlb_after_unmap(dev)) {
+               for (i = 0; i < args->n_devices; i++) {
+                       peer = kfd_device_by_id(devices_arr[i]);
+                       if (WARN_ON_ONCE(!peer))
+@@ -1603,7 +1609,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
+       }
+       mutex_unlock(&p->mutex);
+-      if (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2)) {
++      if (kfd_flush_tlb_after_unmap(dev)) {
+               err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev,
+                               (struct kgd_mem *) mem, true);
+               if (err) {
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amdkfd-ensure-mm-remain-valid-in-svm-deferred_li.patch b/queue-5.17/drm-amdkfd-ensure-mm-remain-valid-in-svm-deferred_li.patch
new file mode 100644 (file)
index 0000000..4ff326c
--- /dev/null
@@ -0,0 +1,141 @@
+From 022cfb318cbe47688aa1348d418801e506302763 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jan 2022 12:15:24 -0500
+Subject: drm/amdkfd: Ensure mm remain valid in svm deferred_list work
+
+From: Philip Yang <Philip.Yang@amd.com>
+
+[ Upstream commit 367c9b0f1b8750a704070e7ae85234d591290434 ]
+
+svm_deferred_list work should continue to handle deferred_range_list
+which maybe split to child range to avoid child range leak, and remove
+ranges mmu interval notifier to avoid mm mm_count leak. So taking mm
+reference when adding range to deferred list, to ensure mm is valid in
+the scheduled deferred_list_work, and drop the mm referrence after range
+is handled.
+
+Signed-off-by: Philip Yang <Philip.Yang@amd.com>
+Reported-by: Ruili Ji <ruili.ji@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/amdkfd/kfd_svm.c | 62 ++++++++++++++++------------
+ 1 file changed, 36 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+index f2805ba74c80..225affcddbc1 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+@@ -1985,10 +1985,9 @@ svm_range_update_notifier_and_interval_tree(struct mm_struct *mm,
+ }
+ static void
+-svm_range_handle_list_op(struct svm_range_list *svms, struct svm_range *prange)
++svm_range_handle_list_op(struct svm_range_list *svms, struct svm_range *prange,
++                       struct mm_struct *mm)
+ {
+-      struct mm_struct *mm = prange->work_item.mm;
+-
+       switch (prange->work_item.op) {
+       case SVM_OP_NULL:
+               pr_debug("NULL OP 0x%p prange 0x%p [0x%lx 0x%lx]\n",
+@@ -2071,34 +2070,41 @@ static void svm_range_deferred_list_work(struct work_struct *work)
+       pr_debug("enter svms 0x%p\n", svms);
+       p = container_of(svms, struct kfd_process, svms);
+-      /* Avoid mm is gone when inserting mmu notifier */
+-      mm = get_task_mm(p->lead_thread);
+-      if (!mm) {
+-              pr_debug("svms 0x%p process mm gone\n", svms);
+-              return;
+-      }
+-retry:
+-      mmap_write_lock(mm);
+-
+-      /* Checking for the need to drain retry faults must be inside
+-       * mmap write lock to serialize with munmap notifiers.
+-       */
+-      if (unlikely(atomic_read(&svms->drain_pagefaults))) {
+-              mmap_write_unlock(mm);
+-              svm_range_drain_retry_fault(svms);
+-              goto retry;
+-      }
+       spin_lock(&svms->deferred_list_lock);
+       while (!list_empty(&svms->deferred_range_list)) {
+               prange = list_first_entry(&svms->deferred_range_list,
+                                         struct svm_range, deferred_list);
+-              list_del_init(&prange->deferred_list);
+               spin_unlock(&svms->deferred_list_lock);
+               pr_debug("prange 0x%p [0x%lx 0x%lx] op %d\n", prange,
+                        prange->start, prange->last, prange->work_item.op);
++              mm = prange->work_item.mm;
++retry:
++              mmap_write_lock(mm);
++
++              /* Checking for the need to drain retry faults must be inside
++               * mmap write lock to serialize with munmap notifiers.
++               */
++              if (unlikely(atomic_read(&svms->drain_pagefaults))) {
++                      mmap_write_unlock(mm);
++                      svm_range_drain_retry_fault(svms);
++                      goto retry;
++              }
++
++              /* Remove from deferred_list must be inside mmap write lock, for
++               * two race cases:
++               * 1. unmap_from_cpu may change work_item.op and add the range
++               *    to deferred_list again, cause use after free bug.
++               * 2. svm_range_list_lock_and_flush_work may hold mmap write
++               *    lock and continue because deferred_list is empty, but
++               *    deferred_list work is actually waiting for mmap lock.
++               */
++              spin_lock(&svms->deferred_list_lock);
++              list_del_init(&prange->deferred_list);
++              spin_unlock(&svms->deferred_list_lock);
++
+               mutex_lock(&svms->lock);
+               mutex_lock(&prange->migrate_mutex);
+               while (!list_empty(&prange->child_list)) {
+@@ -2109,19 +2115,20 @@ static void svm_range_deferred_list_work(struct work_struct *work)
+                       pr_debug("child prange 0x%p op %d\n", pchild,
+                                pchild->work_item.op);
+                       list_del_init(&pchild->child_list);
+-                      svm_range_handle_list_op(svms, pchild);
++                      svm_range_handle_list_op(svms, pchild, mm);
+               }
+               mutex_unlock(&prange->migrate_mutex);
+-              svm_range_handle_list_op(svms, prange);
++              svm_range_handle_list_op(svms, prange, mm);
+               mutex_unlock(&svms->lock);
++              mmap_write_unlock(mm);
++
++              /* Pairs with mmget in svm_range_add_list_work */
++              mmput(mm);
+               spin_lock(&svms->deferred_list_lock);
+       }
+       spin_unlock(&svms->deferred_list_lock);
+-
+-      mmap_write_unlock(mm);
+-      mmput(mm);
+       pr_debug("exit svms 0x%p\n", svms);
+ }
+@@ -2139,6 +2146,9 @@ svm_range_add_list_work(struct svm_range_list *svms, struct svm_range *prange,
+                       prange->work_item.op = op;
+       } else {
+               prange->work_item.op = op;
++
++              /* Pairs with mmput in deferred_list_work */
++              mmget(mm);
+               prange->work_item.mm = mm;
+               list_add_tail(&prange->deferred_list,
+                             &prange->svms->deferred_range_list);
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amdkfd-make-crat-table-missing-message-informati.patch b/queue-5.17/drm-amdkfd-make-crat-table-missing-message-informati.patch
new file mode 100644 (file)
index 0000000..64579a5
--- /dev/null
@@ -0,0 +1,38 @@
+From 18a6cbe7a031d1515b582b654c0bad481df3cd8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Feb 2022 15:40:12 -0500
+Subject: drm/amdkfd: make CRAT table missing message informational only
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 9dff13f9edf755a15f6507874185a3290c1ae8bb ]
+
+The driver has a fallback so make the message informational
+rather than a warning. The driver has a fallback if the
+Component Resource Association Table (CRAT) is missing, so
+make this informational now.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1906
+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/amdkfd/kfd_crat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+index 9624bbe8b501..281def1c6c08 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+@@ -1567,7 +1567,7 @@ int kfd_create_crat_image_acpi(void **crat_image, size_t *size)
+       /* Fetch the CRAT table from ACPI */
+       status = acpi_get_table(CRAT_SIGNATURE, 0, &crat_table);
+       if (status == AE_NOT_FOUND) {
+-              pr_warn("CRAT table not found\n");
++              pr_info("CRAT table not found\n");
+               return -ENODATA;
+       } else if (ACPI_FAILURE(status)) {
+               const char *err = acpi_format_exception(status);
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-amdkfd-svm-range-restore-work-deadlock-when-proc.patch b/queue-5.17/drm-amdkfd-svm-range-restore-work-deadlock-when-proc.patch
new file mode 100644 (file)
index 0000000..a384b8f
--- /dev/null
@@ -0,0 +1,106 @@
+From fbcf86bdc06d9f0015fa05269b96d573b87818b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jan 2022 11:50:50 -0500
+Subject: drm/amdkfd: svm range restore work deadlock when process exit
+
+From: Philip Yang <Philip.Yang@amd.com>
+
+[ Upstream commit 6225bb3a88d22594aacea2485dc28ca12d596721 ]
+
+kfd_process_notifier_release flush svm_range_restore_work
+which calls svm_range_list_lock_and_flush_work to flush deferred_list
+work, but if deferred_list work mmput release the last user, it will
+call exit_mmap -> notifier_release, it is deadlock with below backtrace.
+
+Move flush svm_range_restore_work to kfd_process_wq_release to avoid
+deadlock. Then svm_range_restore_work take task->mm ref to avoid mm is
+gone while validating and mapping ranges to GPU.
+
+Workqueue: events svm_range_deferred_list_work [amdgpu]
+Call Trace:
+ wait_for_completion+0x94/0x100
+ __flush_work+0x12a/0x1e0
+ __cancel_work_timer+0x10e/0x190
+ cancel_delayed_work_sync+0x13/0x20
+ kfd_process_notifier_release+0x98/0x2a0 [amdgpu]
+ __mmu_notifier_release+0x74/0x1f0
+ exit_mmap+0x170/0x200
+ mmput+0x5d/0x130
+ svm_range_deferred_list_work+0x104/0x230 [amdgpu]
+ process_one_work+0x220/0x3c0
+
+Signed-off-by: Philip Yang <Philip.Yang@amd.com>
+Reported-by: Ruili Ji <ruili.ji@amd.com>
+Tested-by: Ruili Ji <ruili.ji@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/amdkfd/kfd_process.c |  1 -
+ drivers/gpu/drm/amd/amdkfd/kfd_svm.c     | 15 +++++++++------
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index d1145da5348f..74f162887d3b 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -1150,7 +1150,6 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
+       cancel_delayed_work_sync(&p->eviction_work);
+       cancel_delayed_work_sync(&p->restore_work);
+-      cancel_delayed_work_sync(&p->svms.restore_work);
+       mutex_lock(&p->mutex);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+index 225affcddbc1..1cf9041c9727 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+@@ -1643,13 +1643,14 @@ static void svm_range_restore_work(struct work_struct *work)
+       pr_debug("restore svm ranges\n");
+-      /* kfd_process_notifier_release destroys this worker thread. So during
+-       * the lifetime of this thread, kfd_process and mm will be valid.
+-       */
+       p = container_of(svms, struct kfd_process, svms);
+-      mm = p->mm;
+-      if (!mm)
++
++      /* Keep mm reference when svm_range_validate_and_map ranges */
++      mm = get_task_mm(p->lead_thread);
++      if (!mm) {
++              pr_debug("svms 0x%p process mm gone\n", svms);
+               return;
++      }
+       svm_range_list_lock_and_flush_work(svms, mm);
+       mutex_lock(&svms->lock);
+@@ -1703,6 +1704,7 @@ static void svm_range_restore_work(struct work_struct *work)
+ out_reschedule:
+       mutex_unlock(&svms->lock);
+       mmap_write_unlock(mm);
++      mmput(mm);
+       /* If validation failed, reschedule another attempt */
+       if (evicted_ranges) {
+@@ -2840,6 +2842,8 @@ void svm_range_list_fini(struct kfd_process *p)
+       pr_debug("pasid 0x%x svms 0x%p\n", p->pasid, &p->svms);
++      cancel_delayed_work_sync(&p->svms.restore_work);
++
+       /* Ensure list work is finished before process is destroyed */
+       flush_work(&p->svms.deferred_list_work);
+@@ -2850,7 +2854,6 @@ void svm_range_list_fini(struct kfd_process *p)
+       atomic_inc(&p->svms.drain_pagefaults);
+       svm_range_drain_retry_fault(&p->svms);
+-
+       list_for_each_entry_safe(prange, next, &p->svms.list, list) {
+               svm_range_unlink(prange);
+               svm_range_remove_notifier(prange);
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-bridge-add-missing-pm_runtime_put_sync.patch b/queue-5.17/drm-bridge-add-missing-pm_runtime_put_sync.patch
new file mode 100644 (file)
index 0000000..c57ea9a
--- /dev/null
@@ -0,0 +1,77 @@
+From b1a69b6a88b140cc902e7fa9ec28697d0350e90e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jan 2022 23:20:35 -0800
+Subject: drm/bridge: Add missing pm_runtime_put_sync
+
+From: Yongzhi Liu <lyz_cs@pku.edu.cn>
+
+[ Upstream commit 46f47807738441e354873546dde0b000106c068a ]
+
+pm_runtime_get_sync() will increase the rumtime PM counter
+even when 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. Besides, a matching decrement is needed
+on the error handling path to keep the counter balanced.
+
+Signed-off-by: Yongzhi Liu <lyz_cs@pku.edu.cn>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/1643008835-73961-1-git-send-email-lyz_cs@pku.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/nwl-dsi.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
+index 6e484d836cfe..691039aba87f 100644
+--- a/drivers/gpu/drm/bridge/nwl-dsi.c
++++ b/drivers/gpu/drm/bridge/nwl-dsi.c
+@@ -861,18 +861,19 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
+       memcpy(&dsi->mode, adjusted_mode, sizeof(dsi->mode));
+       drm_mode_debug_printmodeline(adjusted_mode);
+-      pm_runtime_get_sync(dev);
++      if (pm_runtime_resume_and_get(dev) < 0)
++              return;
+       if (clk_prepare_enable(dsi->lcdif_clk) < 0)
+-              return;
++              goto runtime_put;
+       if (clk_prepare_enable(dsi->core_clk) < 0)
+-              return;
++              goto runtime_put;
+       /* Step 1 from DSI reset-out instructions */
+       ret = reset_control_deassert(dsi->rst_pclk);
+       if (ret < 0) {
+               DRM_DEV_ERROR(dev, "Failed to deassert PCLK: %d\n", ret);
+-              return;
++              goto runtime_put;
+       }
+       /* Step 2 from DSI reset-out instructions */
+@@ -882,13 +883,18 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
+       ret = reset_control_deassert(dsi->rst_esc);
+       if (ret < 0) {
+               DRM_DEV_ERROR(dev, "Failed to deassert ESC: %d\n", ret);
+-              return;
++              goto runtime_put;
+       }
+       ret = reset_control_deassert(dsi->rst_byte);
+       if (ret < 0) {
+               DRM_DEV_ERROR(dev, "Failed to deassert BYTE: %d\n", ret);
+-              return;
++              goto runtime_put;
+       }
++
++      return;
++
++runtime_put:
++      pm_runtime_put_sync(dev);
+ }
+ static void
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-edid-improve-non-desktop-quirk-logging.patch b/queue-5.17/drm-edid-improve-non-desktop-quirk-logging.patch
new file mode 100644 (file)
index 0000000..535dd3a
--- /dev/null
@@ -0,0 +1,73 @@
+From b67f46ac3d097718b3dd05bde2dce9dde580e4f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Dec 2021 12:10:51 +0200
+Subject: drm/edid: improve non-desktop quirk logging
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit ce99534e978d4a36787dbe5e5c57749d12e6bf4a ]
+
+Improve non-desktop quirk logging if the EDID indicates non-desktop. If
+both are set, note about redundant quirk. If there's no quirk but the
+EDID indicates non-desktop, don't log non-desktop is set to 0.
+
+Cc: Philipp Zabel <philipp.zabel@gmail.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Reviewed-by: Philipp Zabel <philipp.zabel@gmail.com>
+Tested-by: Philipp Zabel <philipp.zabel@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211228101051.317989-1-jani.nikula@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_edid.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
+index a71b82668a98..83e5c115e754 100644
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -5325,17 +5325,13 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
+       info->width_mm = edid->width_cm * 10;
+       info->height_mm = edid->height_cm * 10;
+-      info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
+-
+       drm_get_monitor_range(connector, edid);
+-      DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
+-
+       if (edid->revision < 3)
+-              return quirks;
++              goto out;
+       if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
+-              return quirks;
++              goto out;
+       info->color_formats |= DRM_COLOR_FORMAT_RGB444;
+       drm_parse_cea_ext(connector, edid);
+@@ -5356,7 +5352,7 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
+       /* Only defined for 1.4 with digital displays */
+       if (edid->revision < 4)
+-              return quirks;
++              goto out;
+       switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
+       case DRM_EDID_DIGITAL_DEPTH_6:
+@@ -5393,6 +5389,13 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
+       drm_update_mso(connector, edid);
++out:
++      if (quirks & EDID_QUIRK_NON_DESKTOP) {
++              drm_dbg_kms(connector->dev, "Non-desktop display%s\n",
++                          info->non_desktop ? " (redundant quirk)" : "");
++              info->non_desktop = true;
++      }
++
+       return quirks;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-edid-remove-non_desktop-quirk-for-hpn-3515-and-l.patch b/queue-5.17/drm-edid-remove-non_desktop-quirk-for-hpn-3515-and-l.patch
new file mode 100644 (file)
index 0000000..f9a031e
--- /dev/null
@@ -0,0 +1,43 @@
+From bfa5776dc6150da13dcbd4a42cf7da8c10d4c7ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jan 2022 11:16:53 +0100
+Subject: drm/edid: remove non_desktop quirk for HPN-3515 and LEN-B800.
+
+From: Philipp Zabel <philipp.zabel@gmail.com>
+
+[ Upstream commit 50dc95d561a2552b0d76a9f91b38005195bf2974 ]
+
+Now that there is support for the Microsoft VSDB for HMDs, remove the
+non-desktop quirk for two devices that are verified to contain it in
+their EDID: HPN-3515 and LEN-B800.
+Presumably most of the other Windows Mixed Reality headsets contain it
+as well, but there are ACR-7FCE and SEC-5194 devices without it.
+
+Tested with LEN-B800.
+
+Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220123101653.147333-2-philipp.zabel@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_edid.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
+index b8f5419e514a..a71b82668a98 100644
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -212,9 +212,7 @@ static const struct edid_quirk {
+       /* Windows Mixed Reality Headsets */
+       EDID_QUIRK('A', 'C', 'R', 0x7fce, EDID_QUIRK_NON_DESKTOP),
+-      EDID_QUIRK('H', 'P', 'N', 0x3515, EDID_QUIRK_NON_DESKTOP),
+       EDID_QUIRK('L', 'E', 'N', 0x0408, EDID_QUIRK_NON_DESKTOP),
+-      EDID_QUIRK('L', 'E', 'N', 0xb800, EDID_QUIRK_NON_DESKTOP),
+       EDID_QUIRK('F', 'U', 'J', 0x1970, EDID_QUIRK_NON_DESKTOP),
+       EDID_QUIRK('D', 'E', 'L', 0x7fce, EDID_QUIRK_NON_DESKTOP),
+       EDID_QUIRK('S', 'E', 'C', 0x144a, EDID_QUIRK_NON_DESKTOP),
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-msm-dsi-remove-spurious-irqf_oneshot-flag.patch b/queue-5.17/drm-msm-dsi-remove-spurious-irqf_oneshot-flag.patch
new file mode 100644 (file)
index 0000000..63b0a84
--- /dev/null
@@ -0,0 +1,49 @@
+From 8c15ee36772334386df91116ac20c5eb69a487d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Feb 2022 17:47:32 +0000
+Subject: drm/msm/dsi: Remove spurious IRQF_ONESHOT flag
+
+From: Daniel Thompson <daniel.thompson@linaro.org>
+
+[ Upstream commit 24b176d8827d167ac3b379317f60c0985f6e95aa ]
+
+Quoting the header comments, IRQF_ONESHOT is "Used by threaded interrupts
+which need to keep the irq line disabled until the threaded handler has
+been run.". When applied to an interrupt that doesn't request a threaded
+irq then IRQF_ONESHOT has a lesser known (undocumented?) side effect,
+which it to disable the forced threading of irqs (and for "normal" kernels
+it is a nop). In this case I can find no evidence that suppressing forced
+threading is intentional. Had it been intentional then a driver must adopt
+the raw_spinlock API in order to avoid deadlocks on PREEMPT_RT kernels
+(and avoid calling any kernel API that uses regular spinlocks).
+
+Fix this by removing the spurious additional flag.
+
+This change is required for my Snapdragon 7cx Gen2 tablet to boot-to-GUI
+with PREEMPT_RT enabled.
+
+Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20220201174734.196718-2-daniel.thompson@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
+index 6b3ced4aaaf5..3a3f53f0c8ae 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
+@@ -1877,7 +1877,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
+       /* do not autoenable, will be enabled later */
+       ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq,
+-                      IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
++                      IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN,
+                       "dsi_isr", msm_host);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to request IRQ%u: %d\n",
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-sprd-check-the-platform_get_resource-return-valu.patch b/queue-5.17/drm-sprd-check-the-platform_get_resource-return-valu.patch
new file mode 100644 (file)
index 0000000..22a22af
--- /dev/null
@@ -0,0 +1,62 @@
+From 654a0d2fb5476e0ffc6af0f78377b5638bbcb1cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Dec 2021 21:37:00 +0800
+Subject: drm/sprd: check the platform_get_resource() return value
+
+From: Kevin Tang <kevin3.tang@gmail.com>
+
+[ Upstream commit 73792e6e66be1225837cc1a40f1e39b1d077751c ]
+
+platform_get_resource() may fail and return NULL, so check it's value
+before using it.
+
+Reported-by: Zou Wei <zou_wei@huawei.com>
+Signed-off-by: Kevin Tang <kevin3.tang@gmail.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/all/20220117084156.9338-1-kevin3.tang@gmail.com
+
+v1 -> v2:
+- new patch
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/sprd/sprd_dpu.c | 5 +++++
+ drivers/gpu/drm/sprd/sprd_dsi.c | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/gpu/drm/sprd/sprd_dpu.c b/drivers/gpu/drm/sprd/sprd_dpu.c
+index 06a3414ee43a..1637203ea103 100644
+--- a/drivers/gpu/drm/sprd/sprd_dpu.c
++++ b/drivers/gpu/drm/sprd/sprd_dpu.c
+@@ -790,6 +790,11 @@ static int sprd_dpu_context_init(struct sprd_dpu *dpu,
+       int ret;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!res) {
++              dev_err(dev, "failed to get I/O resource\n");
++              return -EINVAL;
++      }
++
+       ctx->base = devm_ioremap(dev, res->start, resource_size(res));
+       if (!ctx->base) {
+               dev_err(dev, "failed to map dpu registers\n");
+diff --git a/drivers/gpu/drm/sprd/sprd_dsi.c b/drivers/gpu/drm/sprd/sprd_dsi.c
+index 911b3cddc264..12b67a5d5923 100644
+--- a/drivers/gpu/drm/sprd/sprd_dsi.c
++++ b/drivers/gpu/drm/sprd/sprd_dsi.c
+@@ -907,6 +907,11 @@ static int sprd_dsi_context_init(struct sprd_dsi *dsi,
+       struct resource *res;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!res) {
++              dev_err(dev, "failed to get I/O resource\n");
++              return -EINVAL;
++      }
++
+       ctx->base = devm_ioremap(dev, res->start, resource_size(res));
+       if (!ctx->base) {
+               drm_err(dsi->drm, "failed to map dsi host registers\n");
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-sprd-fix-potential-null-dereference.patch b/queue-5.17/drm-sprd-fix-potential-null-dereference.patch
new file mode 100644 (file)
index 0000000..adef26e
--- /dev/null
@@ -0,0 +1,43 @@
+From 5d460ad73e1ec83b9a426b66cf5ed775bee9ad51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Jan 2022 23:55:47 +0800
+Subject: drm/sprd: fix potential NULL dereference
+
+From: Kevin Tang <kevin3.tang@gmail.com>
+
+[ Upstream commit 8668658aebb0a19d877d5a81c004baf716c4aaa6 ]
+
+'drm' could be null in sprd_drm_shutdown, and drm_warn maybe dereference
+it, remove this warning log.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Kevin Tang <kevin3.tang@gmail.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/all/20220117084044.9210-1-kevin3.tang@gmail.com
+
+v1 -> v2:
+- Split checking platform_get_resource() return value to a separate patch
+- Use dev_warn() instead of removing the warning log
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/sprd/sprd_drm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/sprd/sprd_drm.c b/drivers/gpu/drm/sprd/sprd_drm.c
+index a077e2d4d721..af2be97d5ed0 100644
+--- a/drivers/gpu/drm/sprd/sprd_drm.c
++++ b/drivers/gpu/drm/sprd/sprd_drm.c
+@@ -155,7 +155,7 @@ static void sprd_drm_shutdown(struct platform_device *pdev)
+       struct drm_device *drm = platform_get_drvdata(pdev);
+       if (!drm) {
+-              drm_warn(drm, "drm device is not available, no shutdown\n");
++              dev_warn(&pdev->dev, "drm device is not available, no shutdown\n");
+               return;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.17/drm-v3d-fix-missing-unlock.patch b/queue-5.17/drm-v3d-fix-missing-unlock.patch
new file mode 100644 (file)
index 0000000..c19571b
--- /dev/null
@@ -0,0 +1,68 @@
+From b160491b10407d562dddc9c97a4fc12e18d3d590 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jan 2022 05:41:02 -0800
+Subject: drm/v3d: fix missing unlock
+
+From: Yongzhi Liu <lyz_cs@pku.edu.cn>
+
+[ Upstream commit e57c1a3bd5e8e0c7181f65ae55581f0236a8f284 ]
+
+[why]
+Unlock is needed on the error handling path to prevent dead lock.
+v3d_submit_cl_ioctl and v3d_submit_csd_ioctl is missing unlock.
+
+[how]
+Fix this by changing goto target on the error handling path. So
+changing the goto to target an error handling path
+that includes drm_gem_unlock reservations.
+
+Signed-off-by: Yongzhi Liu <lyz_cs@pku.edu.cn>
+Reviewed-by: Melissa Wen <mwen@igalia.com>
+Signed-off-by: Melissa Wen <melissa.srw@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/1643377262-109975-1-git-send-email-lyz_cs@pku.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/v3d/v3d_gem.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
+index c7ed2e1cbab6..92bc0faee84f 100644
+--- a/drivers/gpu/drm/v3d/v3d_gem.c
++++ b/drivers/gpu/drm/v3d/v3d_gem.c
+@@ -798,7 +798,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
+               if (!render->base.perfmon) {
+                       ret = -ENOENT;
+-                      goto fail;
++                      goto fail_perfmon;
+               }
+       }
+@@ -847,6 +847,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
+ fail_unreserve:
+       mutex_unlock(&v3d->sched_lock);
++fail_perfmon:
+       drm_gem_unlock_reservations(last_job->bo,
+                                   last_job->bo_count, &acquire_ctx);
+ fail:
+@@ -1027,7 +1028,7 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
+                                                    args->perfmon_id);
+               if (!job->base.perfmon) {
+                       ret = -ENOENT;
+-                      goto fail;
++                      goto fail_perfmon;
+               }
+       }
+@@ -1056,6 +1057,7 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
+ fail_unreserve:
+       mutex_unlock(&v3d->sched_lock);
++fail_perfmon:
+       drm_gem_unlock_reservations(clean_job->bo, clean_job->bo_count,
+                                   &acquire_ctx);
+ fail:
+-- 
+2.35.1
+
diff --git a/queue-5.17/habanalabs-fix-possible-memory-leak-in-mmu-dr-fini.patch b/queue-5.17/habanalabs-fix-possible-memory-leak-in-mmu-dr-fini.patch
new file mode 100644 (file)
index 0000000..d75711e
--- /dev/null
@@ -0,0 +1,38 @@
+From 9e7359825b5441662cacc8b252d4fbffb7222c53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jan 2022 09:48:27 +0200
+Subject: habanalabs: fix possible memory leak in MMU DR fini
+
+From: Ohad Sharabi <osharabi@habana.ai>
+
+[ Upstream commit eb85eec858c1a5c11d3a0bff403f6440b05b40dc ]
+
+This patch fixes what seems to be copy paste error.
+
+We will have a memory leak if the host-resident shadow is NULL (which
+will likely happen as the DR and HR are not dependent).
+
+Signed-off-by: Ohad Sharabi <osharabi@habana.ai>
+Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/habanalabs/common/mmu/mmu_v1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/misc/habanalabs/common/mmu/mmu_v1.c b/drivers/misc/habanalabs/common/mmu/mmu_v1.c
+index 6134b6ae7615..3cadef97817d 100644
+--- a/drivers/misc/habanalabs/common/mmu/mmu_v1.c
++++ b/drivers/misc/habanalabs/common/mmu/mmu_v1.c
+@@ -467,7 +467,7 @@ static void hl_mmu_v1_fini(struct hl_device *hdev)
+ {
+       /* MMU H/W fini was already done in device hw_fini() */
+-      if (!ZERO_OR_NULL_PTR(hdev->mmu_priv.hr.mmu_shadow_hop0)) {
++      if (!ZERO_OR_NULL_PTR(hdev->mmu_priv.dr.mmu_shadow_hop0)) {
+               kvfree(hdev->mmu_priv.dr.mmu_shadow_hop0);
+               gen_pool_destroy(hdev->mmu_priv.dr.mmu_pgt_pool);
+-- 
+2.35.1
+
diff --git a/queue-5.17/habanalabs-gaudi-handle-axi-errors-from-nic-engines.patch b/queue-5.17/habanalabs-gaudi-handle-axi-errors-from-nic-engines.patch
new file mode 100644 (file)
index 0000000..3ac5b81
--- /dev/null
@@ -0,0 +1,95 @@
+From 33abe74797b3258ce7536de1453b8dd042d25d86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 16:07:03 +0200
+Subject: habanalabs/gaudi: handle axi errors from NIC engines
+
+From: Oded Gabbay <ogabbay@kernel.org>
+
+[ Upstream commit 26ef1c000bc21a192618c9ec651dd36ba63ca00c ]
+
+Various AXI errors can occur in the NIC engines and are reported to
+the driver by the f/w. Add code to print the errors and ack them to
+the f/w.
+
+Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/habanalabs/gaudi/gaudi.c | 48 +++++++++++++++++++++++++++
+ 1 file changed, 48 insertions(+)
+
+diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
+index 013c6da2e3ca..b4dacea80151 100644
+--- a/drivers/misc/habanalabs/gaudi/gaudi.c
++++ b/drivers/misc/habanalabs/gaudi/gaudi.c
+@@ -7819,6 +7819,48 @@ static void gaudi_print_fw_alive_info(struct hl_device *hdev,
+               fw_alive->thread_id, fw_alive->uptime_seconds);
+ }
++static void gaudi_print_nic_axi_irq_info(struct hl_device *hdev, u16 event_type,
++                                              void *data)
++{
++      char desc[64] = "", *type;
++      struct eq_nic_sei_event *eq_nic_sei = data;
++      u16 nic_id = event_type - GAUDI_EVENT_NIC_SEI_0;
++
++      switch (eq_nic_sei->axi_error_cause) {
++      case RXB:
++              type = "RXB";
++              break;
++      case RXE:
++              type = "RXE";
++              break;
++      case TXS:
++              type = "TXS";
++              break;
++      case TXE:
++              type = "TXE";
++              break;
++      case QPC_RESP:
++              type = "QPC_RESP";
++              break;
++      case NON_AXI_ERR:
++              type = "NON_AXI_ERR";
++              break;
++      case TMR:
++              type = "TMR";
++              break;
++      default:
++              dev_err(hdev->dev, "unknown NIC AXI cause %d\n",
++                      eq_nic_sei->axi_error_cause);
++              type = "N/A";
++              break;
++      }
++
++      snprintf(desc, sizeof(desc), "NIC%d_%s%d", nic_id, type,
++                      eq_nic_sei->id);
++      dev_err_ratelimited(hdev->dev, "Received H/W interrupt %d [\"%s\"]\n",
++              event_type, desc);
++}
++
+ static int gaudi_non_hard_reset_late_init(struct hl_device *hdev)
+ {
+       /* GAUDI doesn't support any reset except hard-reset */
+@@ -8066,6 +8108,7 @@ static void gaudi_handle_eqe(struct hl_device *hdev,
+                               struct hl_eq_entry *eq_entry)
+ {
+       struct gaudi_device *gaudi = hdev->asic_specific;
++      u64 data = le64_to_cpu(eq_entry->data[0]);
+       u32 ctl = le32_to_cpu(eq_entry->hdr.ctl);
+       u32 fw_fatal_err_flag = 0;
+       u16 event_type = ((ctl & EQ_CTL_EVENT_TYPE_MASK)
+@@ -8263,6 +8306,11 @@ static void gaudi_handle_eqe(struct hl_device *hdev,
+               hl_fw_unmask_irq(hdev, event_type);
+               break;
++      case GAUDI_EVENT_NIC_SEI_0 ... GAUDI_EVENT_NIC_SEI_4:
++              gaudi_print_nic_axi_irq_info(hdev, event_type, &data);
++              hl_fw_unmask_irq(hdev, event_type);
++              break;
++
+       case GAUDI_EVENT_DMA_IF_SEI_0 ... GAUDI_EVENT_DMA_IF_SEI_3:
+               gaudi_print_irq_info(hdev, event_type, false);
+               gaudi_print_sm_sei_info(hdev, event_type,
+-- 
+2.35.1
+
diff --git a/queue-5.17/habanalabs-reject-host-map-with-mmu-disabled.patch b/queue-5.17/habanalabs-reject-host-map-with-mmu-disabled.patch
new file mode 100644 (file)
index 0000000..62e0dc5
--- /dev/null
@@ -0,0 +1,90 @@
+From b6d75a4e62503c0dc8cf88e3812a187c21bdb9bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jan 2022 12:16:53 +0200
+Subject: habanalabs: reject host map with mmu disabled
+
+From: Oded Gabbay <ogabbay@kernel.org>
+
+[ Upstream commit 9a79e3e4a3637c07352d9723b825490a1b04391f ]
+
+This is not something we can do a workaround. It is clearly an error
+and we should notify the user that it is an error.
+
+Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/habanalabs/common/memory.c | 30 +++++++++----------------
+ 1 file changed, 11 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c
+index c1eefaebacb6..bcc6e547e071 100644
+--- a/drivers/misc/habanalabs/common/memory.c
++++ b/drivers/misc/habanalabs/common/memory.c
+@@ -1967,16 +1967,15 @@ static int export_dmabuf_from_handle(struct hl_ctx *ctx, u64 handle, int flags,
+ static int mem_ioctl_no_mmu(struct hl_fpriv *hpriv, union hl_mem_args *args)
+ {
+       struct hl_device *hdev = hpriv->hdev;
+-      struct hl_ctx *ctx = hpriv->ctx;
+       u64 block_handle, device_addr = 0;
++      struct hl_ctx *ctx = hpriv->ctx;
+       u32 handle = 0, block_size;
+-      int rc, dmabuf_fd = -EBADF;
++      int rc;
+       switch (args->in.op) {
+       case HL_MEM_OP_ALLOC:
+               if (args->in.alloc.mem_size == 0) {
+-                      dev_err(hdev->dev,
+-                              "alloc size must be larger than 0\n");
++                      dev_err(hdev->dev, "alloc size must be larger than 0\n");
+                       rc = -EINVAL;
+                       goto out;
+               }
+@@ -1997,15 +1996,14 @@ static int mem_ioctl_no_mmu(struct hl_fpriv *hpriv, union hl_mem_args *args)
+       case HL_MEM_OP_MAP:
+               if (args->in.flags & HL_MEM_USERPTR) {
+-                      device_addr = args->in.map_host.host_virt_addr;
+-                      rc = 0;
++                      dev_err(hdev->dev, "Failed to map host memory when MMU is disabled\n");
++                      rc = -EPERM;
+               } else {
+-                      rc = get_paddr_from_handle(ctx, &args->in,
+-                                                      &device_addr);
++                      rc = get_paddr_from_handle(ctx, &args->in, &device_addr);
++                      memset(args, 0, sizeof(*args));
++                      args->out.device_virt_addr = device_addr;
+               }
+-              memset(args, 0, sizeof(*args));
+-              args->out.device_virt_addr = device_addr;
+               break;
+       case HL_MEM_OP_UNMAP:
+@@ -2013,20 +2011,14 @@ static int mem_ioctl_no_mmu(struct hl_fpriv *hpriv, union hl_mem_args *args)
+               break;
+       case HL_MEM_OP_MAP_BLOCK:
+-              rc = map_block(hdev, args->in.map_block.block_addr,
+-                              &block_handle, &block_size);
++              rc = map_block(hdev, args->in.map_block.block_addr, &block_handle, &block_size);
+               args->out.block_handle = block_handle;
+               args->out.block_size = block_size;
+               break;
+       case HL_MEM_OP_EXPORT_DMABUF_FD:
+-              rc = export_dmabuf_from_addr(ctx,
+-                              args->in.export_dmabuf_fd.handle,
+-                              args->in.export_dmabuf_fd.mem_size,
+-                              args->in.flags,
+-                              &dmabuf_fd);
+-              memset(args, 0, sizeof(*args));
+-              args->out.fd = dmabuf_fd;
++              dev_err(hdev->dev, "Failed to export dma-buf object when MMU is disabled\n");
++              rc = -EPERM;
+               break;
+       default:
+-- 
+2.35.1
+
diff --git a/queue-5.17/hid-apple-report-magic-keyboard-2021-battery-over-us.patch b/queue-5.17/hid-apple-report-magic-keyboard-2021-battery-over-us.patch
new file mode 100644 (file)
index 0000000..7d91086
--- /dev/null
@@ -0,0 +1,47 @@
+From c2b85d92eac5df0493995cc6e3fa4acca93d8578 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Feb 2022 19:50:09 +0100
+Subject: HID: apple: Report Magic Keyboard 2021 battery over USB
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit 8ae5c16c9d421d43f32f66d2308031f1bd3f9336 ]
+
+Like the Apple Magic Keyboard 2015, when connected over USB, the 2021
+version registers 2 different interfaces. One of them is used to report
+the battery level.
+
+However, unlike when connected over Bluetooth, the battery level is not
+reported automatically and it is required to fetch it manually.
+
+Add the APPLE_RDESC_BATTERY quirk to fix the battery report descriptor
+and manually fetch the battery level.
+
+Tested with the ANSI, ISO and JIS variants of the keyboard.
+
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-apple.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index 7dc89dc6b0f0..18de4ccb0fb2 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -748,7 +748,7 @@ static const struct hid_device_id apple_devices[] = {
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
+               .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
+-              .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
++              .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
+-- 
+2.35.1
+
diff --git a/queue-5.17/hid-apple-report-magic-keyboard-2021-with-fingerprin.patch b/queue-5.17/hid-apple-report-magic-keyboard-2021-with-fingerprin.patch
new file mode 100644 (file)
index 0000000..59743c8
--- /dev/null
@@ -0,0 +1,53 @@
+From c0c9d3a231c27681186fa861114ba7f7761b6dbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Feb 2022 19:55:30 +0100
+Subject: HID: apple: Report Magic Keyboard 2021 with fingerprint reader
+ battery over USB
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit cbfcfbfc384890a062a5d0cc4792df094a6cc7a8 ]
+
+Like the Apple Magic Keyboard 2015, when connected over USB, the 2021
+version with fingerprint reader registers 2 different interfaces. One of
+them is used to report the battery level.
+
+However, unlike when connected over Bluetooth, the battery level is not
+reported automatically and it is required to fetch it manually.
+
+Add the APPLE_RDESC_BATTERY quirk to fix the battery report descriptor
+and manually fetch the battery level.
+
+Tested with the ANSI variant of the keyboard with and without numpad.
+
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-apple.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index 18de4ccb0fb2..590376d776a1 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -752,11 +752,11 @@ static const struct hid_device_id apple_devices[] = {
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
+-              .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
++              .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
+-              .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
++              .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+-- 
+2.35.1
+
diff --git a/queue-5.17/i40e-add-sending-commands-in-atomic-context.patch b/queue-5.17/i40e-add-sending-commands-in-atomic-context.patch
new file mode 100644 (file)
index 0000000..24e40e2
--- /dev/null
@@ -0,0 +1,93 @@
+From ecec3473ca9f1ee4aeb96d479d5ff0a6436de305 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jan 2022 13:19:28 +0000
+Subject: i40e: Add sending commands in atomic context
+
+From: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+
+[ Upstream commit 59b3d7350ff35c939b8e173eb2eecac80a5ee046 ]
+
+Change functions:
+- i40e_aq_add_macvlan
+- i40e_aq_remove_macvlan
+- i40e_aq_delete_element
+- i40e_aq_add_vsi
+- i40e_aq_update_vsi_params
+to explicitly use i40e_asq_send_command_atomic(..., true)
+instead of i40e_asq_send_command, as they use mutexes and do some
+work in an atomic context.
+Without this change setting vlan via netdev will fail with
+call trace cased by bug "BUG: scheduling while atomic".
+
+Signed-off-by: Witold Fijalkowski <witoldx.fijalkowski@intel.com>
+Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Tested-by: Gurucharan G <gurucharanx.g@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_common.c | 21 +++++++++++--------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
+index 9ddeb015eb7e..e830987a8c6d 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
+@@ -1899,8 +1899,9 @@ i40e_status i40e_aq_add_vsi(struct i40e_hw *hw,
+       desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+-      status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
+-                                  sizeof(vsi_ctx->info), cmd_details);
++      status = i40e_asq_send_command_atomic(hw, &desc, &vsi_ctx->info,
++                                            sizeof(vsi_ctx->info),
++                                            cmd_details, true);
+       if (status)
+               goto aq_add_vsi_exit;
+@@ -2287,8 +2288,9 @@ i40e_status i40e_aq_update_vsi_params(struct i40e_hw *hw,
+       desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+-      status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
+-                                  sizeof(vsi_ctx->info), cmd_details);
++      status = i40e_asq_send_command_atomic(hw, &desc, &vsi_ctx->info,
++                                            sizeof(vsi_ctx->info),
++                                            cmd_details, true);
+       vsi_ctx->vsis_allocated = le16_to_cpu(resp->vsi_used);
+       vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
+@@ -2673,8 +2675,8 @@ i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
+       if (buf_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
+-      status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
+-                                     cmd_details);
++      status = i40e_asq_send_command_atomic(hw, &desc, mv_list, buf_size,
++                                            cmd_details, true);
+       return status;
+ }
+@@ -2715,8 +2717,8 @@ i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
+       if (buf_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
+-      status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
+-                                     cmd_details);
++      status = i40e_asq_send_command_atomic(hw, &desc, mv_list, buf_size,
++                                            cmd_details, true);
+       return status;
+ }
+@@ -3868,7 +3870,8 @@ i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
+       cmd->seid = cpu_to_le16(seid);
+-      status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
++      status = i40e_asq_send_command_atomic(hw, &desc, NULL, 0,
++                                            cmd_details, true);
+       return status;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/iavf-stop-leaking-iavf_status-as-errno-values.patch b/queue-5.17/iavf-stop-leaking-iavf_status-as-errno-values.patch
new file mode 100644 (file)
index 0000000..32ce427
--- /dev/null
@@ -0,0 +1,367 @@
+From e76fbfbc6a0870ef1d62e91baa335a108c8eee76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 15:16:29 +0100
+Subject: iavf: stop leaking iavf_status as "errno" values
+
+From: Mateusz Palczewski <mateusz.palczewski@intel.com>
+
+[ Upstream commit bae569d01a1f4929ce28093be80bbbbacbf1b127 ]
+
+Several functions in the iAVF core files take status values of the enum
+iavf_status and convert them into integer values. This leads to
+confusion as functions return both Linux errno values and status codes
+intermixed. Reporting status codes as if they were "errno" values can
+lead to confusion when reviewing error logs. Additionally, it can lead
+to unexpected behavior if a return value is not interpreted properly.
+
+Fix this by introducing iavf_status_to_errno, a switch that explicitly
+converts from the status codes into an appropriate error value. Also
+introduce a virtchnl_status_to_errno function for the one case where we
+were returning both virtchnl status codes and iavf_status codes in the
+same function.
+
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h        |   5 +-
+ drivers/net/ethernet/intel/iavf/iavf_main.c   | 173 +++++++++++++++---
+ .../net/ethernet/intel/iavf/iavf_virtchnl.c   |  18 +-
+ 3 files changed, 157 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 4babe4705a55..358a9b3031d5 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -44,6 +44,9 @@
+ #define DEFAULT_DEBUG_LEVEL_SHIFT 3
+ #define PFX "iavf: "
++int iavf_status_to_errno(enum iavf_status status);
++int virtchnl_status_to_errno(enum virtchnl_status_code v_status);
++
+ /* VSI state flags shared with common code */
+ enum iavf_vsi_state_t {
+       __IAVF_VSI_DOWN,
+@@ -515,7 +518,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter);
+ void iavf_del_vlans(struct iavf_adapter *adapter);
+ void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags);
+ void iavf_request_stats(struct iavf_adapter *adapter);
+-void iavf_request_reset(struct iavf_adapter *adapter);
++int iavf_request_reset(struct iavf_adapter *adapter);
+ void iavf_get_hena(struct iavf_adapter *adapter);
+ void iavf_set_hena(struct iavf_adapter *adapter);
+ void iavf_set_rss_key(struct iavf_adapter *adapter);
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 0e178a0a59c5..d10e9a8e8011 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -51,6 +51,113 @@ MODULE_LICENSE("GPL v2");
+ static const struct net_device_ops iavf_netdev_ops;
+ struct workqueue_struct *iavf_wq;
++int iavf_status_to_errno(enum iavf_status status)
++{
++      switch (status) {
++      case IAVF_SUCCESS:
++              return 0;
++      case IAVF_ERR_PARAM:
++      case IAVF_ERR_MAC_TYPE:
++      case IAVF_ERR_INVALID_MAC_ADDR:
++      case IAVF_ERR_INVALID_LINK_SETTINGS:
++      case IAVF_ERR_INVALID_PD_ID:
++      case IAVF_ERR_INVALID_QP_ID:
++      case IAVF_ERR_INVALID_CQ_ID:
++      case IAVF_ERR_INVALID_CEQ_ID:
++      case IAVF_ERR_INVALID_AEQ_ID:
++      case IAVF_ERR_INVALID_SIZE:
++      case IAVF_ERR_INVALID_ARP_INDEX:
++      case IAVF_ERR_INVALID_FPM_FUNC_ID:
++      case IAVF_ERR_QP_INVALID_MSG_SIZE:
++      case IAVF_ERR_INVALID_FRAG_COUNT:
++      case IAVF_ERR_INVALID_ALIGNMENT:
++      case IAVF_ERR_INVALID_PUSH_PAGE_INDEX:
++      case IAVF_ERR_INVALID_IMM_DATA_SIZE:
++      case IAVF_ERR_INVALID_VF_ID:
++      case IAVF_ERR_INVALID_HMCFN_ID:
++      case IAVF_ERR_INVALID_PBLE_INDEX:
++      case IAVF_ERR_INVALID_SD_INDEX:
++      case IAVF_ERR_INVALID_PAGE_DESC_INDEX:
++      case IAVF_ERR_INVALID_SD_TYPE:
++      case IAVF_ERR_INVALID_HMC_OBJ_INDEX:
++      case IAVF_ERR_INVALID_HMC_OBJ_COUNT:
++      case IAVF_ERR_INVALID_SRQ_ARM_LIMIT:
++              return -EINVAL;
++      case IAVF_ERR_NVM:
++      case IAVF_ERR_NVM_CHECKSUM:
++      case IAVF_ERR_PHY:
++      case IAVF_ERR_CONFIG:
++      case IAVF_ERR_UNKNOWN_PHY:
++      case IAVF_ERR_LINK_SETUP:
++      case IAVF_ERR_ADAPTER_STOPPED:
++      case IAVF_ERR_MASTER_REQUESTS_PENDING:
++      case IAVF_ERR_AUTONEG_NOT_COMPLETE:
++      case IAVF_ERR_RESET_FAILED:
++      case IAVF_ERR_BAD_PTR:
++      case IAVF_ERR_SWFW_SYNC:
++      case IAVF_ERR_QP_TOOMANY_WRS_POSTED:
++      case IAVF_ERR_QUEUE_EMPTY:
++      case IAVF_ERR_FLUSHED_QUEUE:
++      case IAVF_ERR_OPCODE_MISMATCH:
++      case IAVF_ERR_CQP_COMPL_ERROR:
++      case IAVF_ERR_BACKING_PAGE_ERROR:
++      case IAVF_ERR_NO_PBLCHUNKS_AVAILABLE:
++      case IAVF_ERR_MEMCPY_FAILED:
++      case IAVF_ERR_SRQ_ENABLED:
++      case IAVF_ERR_ADMIN_QUEUE_ERROR:
++      case IAVF_ERR_ADMIN_QUEUE_FULL:
++      case IAVF_ERR_BAD_IWARP_CQE:
++      case IAVF_ERR_NVM_BLANK_MODE:
++      case IAVF_ERR_PE_DOORBELL_NOT_ENABLED:
++      case IAVF_ERR_DIAG_TEST_FAILED:
++      case IAVF_ERR_FIRMWARE_API_VERSION:
++      case IAVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
++              return -EIO;
++      case IAVF_ERR_DEVICE_NOT_SUPPORTED:
++              return -ENODEV;
++      case IAVF_ERR_NO_AVAILABLE_VSI:
++      case IAVF_ERR_RING_FULL:
++              return -ENOSPC;
++      case IAVF_ERR_NO_MEMORY:
++              return -ENOMEM;
++      case IAVF_ERR_TIMEOUT:
++      case IAVF_ERR_ADMIN_QUEUE_TIMEOUT:
++              return -ETIMEDOUT;
++      case IAVF_ERR_NOT_IMPLEMENTED:
++      case IAVF_NOT_SUPPORTED:
++              return -EOPNOTSUPP;
++      case IAVF_ERR_ADMIN_QUEUE_NO_WORK:
++              return -EALREADY;
++      case IAVF_ERR_NOT_READY:
++              return -EBUSY;
++      case IAVF_ERR_BUF_TOO_SHORT:
++              return -EMSGSIZE;
++      }
++
++      return -EIO;
++}
++
++int virtchnl_status_to_errno(enum virtchnl_status_code v_status)
++{
++      switch (v_status) {
++      case VIRTCHNL_STATUS_SUCCESS:
++              return 0;
++      case VIRTCHNL_STATUS_ERR_PARAM:
++      case VIRTCHNL_STATUS_ERR_INVALID_VF_ID:
++              return -EINVAL;
++      case VIRTCHNL_STATUS_ERR_NO_MEMORY:
++              return -ENOMEM;
++      case VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH:
++      case VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR:
++      case VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR:
++              return -EIO;
++      case VIRTCHNL_STATUS_ERR_NOT_SUPPORTED:
++              return -EOPNOTSUPP;
++      }
++
++      return -EIO;
++}
++
+ /**
+  * iavf_pdev_to_adapter - go from pci_dev to adapter
+  * @pdev: pci_dev pointer
+@@ -1421,7 +1528,7 @@ static int iavf_config_rss_aq(struct iavf_adapter *adapter)
+       struct iavf_aqc_get_set_rss_key_data *rss_key =
+               (struct iavf_aqc_get_set_rss_key_data *)adapter->rss_key;
+       struct iavf_hw *hw = &adapter->hw;
+-      int ret = 0;
++      enum iavf_status status;
+       if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
+               /* bail because we already have a command pending */
+@@ -1430,24 +1537,25 @@ static int iavf_config_rss_aq(struct iavf_adapter *adapter)
+               return -EBUSY;
+       }
+-      ret = iavf_aq_set_rss_key(hw, adapter->vsi.id, rss_key);
+-      if (ret) {
++      status = iavf_aq_set_rss_key(hw, adapter->vsi.id, rss_key);
++      if (status) {
+               dev_err(&adapter->pdev->dev, "Cannot set RSS key, err %s aq_err %s\n",
+-                      iavf_stat_str(hw, ret),
++                      iavf_stat_str(hw, status),
+                       iavf_aq_str(hw, hw->aq.asq_last_status));
+-              return ret;
++              return iavf_status_to_errno(status);
+       }
+-      ret = iavf_aq_set_rss_lut(hw, adapter->vsi.id, false,
+-                                adapter->rss_lut, adapter->rss_lut_size);
+-      if (ret) {
++      status = iavf_aq_set_rss_lut(hw, adapter->vsi.id, false,
++                                   adapter->rss_lut, adapter->rss_lut_size);
++      if (status) {
+               dev_err(&adapter->pdev->dev, "Cannot set RSS lut, err %s aq_err %s\n",
+-                      iavf_stat_str(hw, ret),
++                      iavf_stat_str(hw, status),
+                       iavf_aq_str(hw, hw->aq.asq_last_status));
++              return iavf_status_to_errno(status);
+       }
+-      return ret;
++      return 0;
+ }
+@@ -2003,23 +2111,24 @@ static void iavf_startup(struct iavf_adapter *adapter)
+ {
+       struct pci_dev *pdev = adapter->pdev;
+       struct iavf_hw *hw = &adapter->hw;
+-      int err;
++      enum iavf_status status;
++      int ret;
+       WARN_ON(adapter->state != __IAVF_STARTUP);
+       /* driver loaded, probe complete */
+       adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED;
+       adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
+-      err = iavf_set_mac_type(hw);
+-      if (err) {
+-              dev_err(&pdev->dev, "Failed to set MAC type (%d)\n", err);
++      status = iavf_set_mac_type(hw);
++      if (status) {
++              dev_err(&pdev->dev, "Failed to set MAC type (%d)\n", status);
+               goto err;
+       }
+-      err = iavf_check_reset_complete(hw);
+-      if (err) {
++      ret = iavf_check_reset_complete(hw);
++      if (ret) {
+               dev_info(&pdev->dev, "Device is still in reset (%d), retrying\n",
+-                       err);
++                       ret);
+               goto err;
+       }
+       hw->aq.num_arq_entries = IAVF_AQ_LEN;
+@@ -2027,14 +2136,15 @@ static void iavf_startup(struct iavf_adapter *adapter)
+       hw->aq.arq_buf_size = IAVF_MAX_AQ_BUF_SIZE;
+       hw->aq.asq_buf_size = IAVF_MAX_AQ_BUF_SIZE;
+-      err = iavf_init_adminq(hw);
+-      if (err) {
+-              dev_err(&pdev->dev, "Failed to init Admin Queue (%d)\n", err);
++      status = iavf_init_adminq(hw);
++      if (status) {
++              dev_err(&pdev->dev, "Failed to init Admin Queue (%d)\n",
++                      status);
+               goto err;
+       }
+-      err = iavf_send_api_ver(adapter);
+-      if (err) {
+-              dev_err(&pdev->dev, "Unable to send to PF (%d)\n", err);
++      ret = iavf_send_api_ver(adapter);
++      if (ret) {
++              dev_err(&pdev->dev, "Unable to send to PF (%d)\n", ret);
+               iavf_shutdown_adminq(hw);
+               goto err;
+       }
+@@ -2070,7 +2180,7 @@ static void iavf_init_version_check(struct iavf_adapter *adapter)
+       /* aq msg sent, awaiting reply */
+       err = iavf_verify_api_ver(adapter);
+       if (err) {
+-              if (err == IAVF_ERR_ADMIN_QUEUE_NO_WORK)
++              if (err == -EALREADY)
+                       err = iavf_send_api_ver(adapter);
+               else
+                       dev_err(&pdev->dev, "Unsupported PF API version %d.%d, expected %d.%d\n",
+@@ -2171,11 +2281,11 @@ static void iavf_init_get_resources(struct iavf_adapter *adapter)
+               }
+       }
+       err = iavf_get_vf_config(adapter);
+-      if (err == IAVF_ERR_ADMIN_QUEUE_NO_WORK) {
++      if (err == -EALREADY) {
+               err = iavf_send_vf_config_msg(adapter);
+               goto err_alloc;
+-      } else if (err == IAVF_ERR_PARAM) {
+-              /* We only get ERR_PARAM if the device is in a very bad
++      } else if (err == -EINVAL) {
++              /* We only get -EINVAL if the device is in a very bad
+                * state or if we've been disabled for previous bad
+                * behavior. Either way, we're done now.
+                */
+@@ -2626,6 +2736,7 @@ static void iavf_reset_task(struct work_struct *work)
+       struct iavf_hw *hw = &adapter->hw;
+       struct iavf_mac_filter *f, *ftmp;
+       struct iavf_cloud_filter *cf;
++      enum iavf_status status;
+       u32 reg_val;
+       int i = 0, err;
+       bool running;
+@@ -2727,10 +2838,12 @@ static void iavf_reset_task(struct work_struct *work)
+       /* kill and reinit the admin queue */
+       iavf_shutdown_adminq(hw);
+       adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+-      err = iavf_init_adminq(hw);
+-      if (err)
++      status = iavf_init_adminq(hw);
++      if (status) {
+               dev_info(&adapter->pdev->dev, "Failed to init adminq: %d\n",
+-                       err);
++                       status);
++              goto reset_err;
++      }
+       adapter->aq_required = 0;
+       if ((adapter->flags & IAVF_FLAG_REINIT_MSIX_NEEDED) ||
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+index 5263cefe46f5..b8c5837f8b50 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+@@ -22,17 +22,17 @@ static int iavf_send_pf_msg(struct iavf_adapter *adapter,
+                           enum virtchnl_ops op, u8 *msg, u16 len)
+ {
+       struct iavf_hw *hw = &adapter->hw;
+-      enum iavf_status err;
++      enum iavf_status status;
+       if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
+               return 0; /* nothing to see here, move along */
+-      err = iavf_aq_send_msg_to_pf(hw, op, 0, msg, len, NULL);
+-      if (err)
+-              dev_dbg(&adapter->pdev->dev, "Unable to send opcode %d to PF, err %s, aq_err %s\n",
+-                      op, iavf_stat_str(hw, err),
++      status = iavf_aq_send_msg_to_pf(hw, op, 0, msg, len, NULL);
++      if (status)
++              dev_dbg(&adapter->pdev->dev, "Unable to send opcode %d to PF, status %s, aq_err %s\n",
++                      op, iavf_stat_str(hw, status),
+                       iavf_aq_str(hw, hw->aq.asq_last_status));
+-      return err;
++      return iavf_status_to_errno(status);
+ }
+ /**
+@@ -1827,11 +1827,13 @@ void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter)
+  *
+  * Request that the PF reset this VF. No response is expected.
+  **/
+-void iavf_request_reset(struct iavf_adapter *adapter)
++int iavf_request_reset(struct iavf_adapter *adapter)
+ {
++      int err;
+       /* Don't check CURRENT_OP - this is always higher priority */
+-      iavf_send_pf_msg(adapter, VIRTCHNL_OP_RESET_VF, NULL, 0);
++      err = iavf_send_pf_msg(adapter, VIRTCHNL_OP_RESET_VF, NULL, 0);
+       adapter->current_op = VIRTCHNL_OP_UNKNOWN;
++      return err;
+ }
+ /**
+-- 
+2.35.1
+
diff --git a/queue-5.17/init-main.c-return-1-from-handled-__setup-functions.patch b/queue-5.17/init-main.c-return-1-from-handled-__setup-functions.patch
new file mode 100644 (file)
index 0000000..2287893
--- /dev/null
@@ -0,0 +1,57 @@
+From 82b10d8a6be6a32bef6b9470368af73cc5e06da7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 16:06:14 -0700
+Subject: init/main.c: return 1 from handled __setup() functions
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit f9a40b0890658330c83c95511f9d6b396610defc ]
+
+initcall_blacklist() should return 1 to indicate that it handled its
+cmdline arguments.
+
+set_debug_rodata() should return 1 to indicate that it handled its
+cmdline arguments.  Print a warning if the option string is invalid.
+
+This prevents these strings from being added to the 'init' program's
+environment as they are not init arguments/parameters.
+
+Link: https://lkml.kernel.org/r/20220221050901.23985-1-rdunlap@infradead.org
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: Igor Zhbanov <i.zhbanov@omprussia.ru>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ init/main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/init/main.c b/init/main.c
+index ada50f5a15e4..9a5097b2251a 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -1192,7 +1192,7 @@ static int __init initcall_blacklist(char *str)
+               }
+       } while (str_entry);
+-      return 0;
++      return 1;
+ }
+ static bool __init_or_module initcall_blacklisted(initcall_t fn)
+@@ -1454,7 +1454,9 @@ static noinline void __init kernel_init_freeable(void);
+ bool rodata_enabled __ro_after_init = true;
+ static int __init set_debug_rodata(char *str)
+ {
+-      return strtobool(str, &rodata_enabled);
++      if (strtobool(str, &rodata_enabled))
++              pr_warn("Invalid option string for rodata: '%s'\n", str);
++      return 1;
+ }
+ __setup("rodata=", set_debug_rodata);
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.17/iommu-arm-smmu-v3-fix-event-handling-soft-lockup.patch b/queue-5.17/iommu-arm-smmu-v3-fix-event-handling-soft-lockup.patch
new file mode 100644 (file)
index 0000000..5e2b291
--- /dev/null
@@ -0,0 +1,55 @@
+From af296bc96b147d7999f3dbc2ec850983604d7bac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Jan 2022 07:07:54 +0000
+Subject: iommu/arm-smmu-v3: fix event handling soft lockup
+
+From: Zhou Guanghui <zhouguanghui1@huawei.com>
+
+[ Upstream commit 30de2b541af98179780054836b48825fcfba4408 ]
+
+During event processing, events are read from the event queue one
+by one until the queue is empty.If the master device continuously
+requests address access at the same time and the SMMU generates
+events, the cyclic processing of the event takes a long time and
+softlockup warnings may be reported.
+
+arm-smmu-v3 arm-smmu-v3.34.auto: event 0x0a received:
+arm-smmu-v3 arm-smmu-v3.34.auto:       0x00007f220000280a
+arm-smmu-v3 arm-smmu-v3.34.auto:       0x000010000000007e
+arm-smmu-v3 arm-smmu-v3.34.auto:       0x00000000034e8670
+watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [irq/268-arm-smm:247]
+Call trace:
+ _dev_info+0x7c/0xa0
+ arm_smmu_evtq_thread+0x1c0/0x230
+ irq_thread_fn+0x30/0x80
+ irq_thread+0x128/0x210
+ kthread+0x134/0x138
+ ret_from_fork+0x10/0x1c
+Kernel panic - not syncing: softlockup: hung tasks
+
+Fix this by calling cond_resched() after the event information is
+printed.
+
+Signed-off-by: Zhou Guanghui <zhouguanghui1@huawei.com>
+Link: https://lore.kernel.org/r/20220119070754.26528-1-zhouguanghui1@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index 6dc6d8b6b368..f60381cdf1c4 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -1558,6 +1558,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
+                               dev_info(smmu->dev, "\t0x%016llx\n",
+                                        (unsigned long long)evt[i]);
++                      cond_resched();
+               }
+               /*
+-- 
+2.35.1
+
diff --git a/queue-5.17/ipv4-invalidate-neighbour-for-broadcast-address-upon.patch b/queue-5.17/ipv4-invalidate-neighbour-for-broadcast-address-upon.patch
new file mode 100644 (file)
index 0000000..6e79439
--- /dev/null
@@ -0,0 +1,118 @@
+From 37f8c4ef56de1c5b6da00cb467fca77c68e02f48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Feb 2022 17:45:19 +0200
+Subject: ipv4: Invalidate neighbour for broadcast address upon address
+ addition
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 0c51e12e218f20b7d976158fdc18019627326f7a ]
+
+In case user space sends a packet destined to a broadcast address when a
+matching broadcast route is not configured, the kernel will create a
+unicast neighbour entry that will never be resolved [1].
+
+When the broadcast route is configured, the unicast neighbour entry will
+not be invalidated and continue to linger, resulting in packets being
+dropped.
+
+Solve this by invalidating unresolved neighbour entries for broadcast
+addresses after routes for these addresses are internally configured by
+the kernel. This allows the kernel to create a broadcast neighbour entry
+following the next route lookup.
+
+Another possible solution that is more generic but also more complex is
+to have the ARP code register a listener to the FIB notification chain
+and invalidate matching neighbour entries upon the addition of broadcast
+routes.
+
+It is also possible to wave off the issue as a user space problem, but
+it seems a bit excessive to expect user space to be that intimately
+familiar with the inner workings of the FIB/neighbour kernel code.
+
+[1] https://lore.kernel.org/netdev/55a04a8f-56f3-f73c-2aea-2195923f09d1@huawei.com/
+
+Reported-by: Wang Hai <wanghai38@huawei.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Tested-by: Wang Hai <wanghai38@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/arp.h       | 1 +
+ net/ipv4/arp.c          | 9 +++++++--
+ net/ipv4/fib_frontend.c | 5 ++++-
+ 3 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/arp.h b/include/net/arp.h
+index 031374ac2f22..d7ef4ec71dfe 100644
+--- a/include/net/arp.h
++++ b/include/net/arp.h
+@@ -65,6 +65,7 @@ void arp_send(int type, int ptype, __be32 dest_ip,
+             const unsigned char *src_hw, const unsigned char *th);
+ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir);
+ void arp_ifdown(struct net_device *dev);
++int arp_invalidate(struct net_device *dev, __be32 ip, bool force);
+ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
+                          struct net_device *dev, __be32 src_ip,
+diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
+index 4db0325f6e1a..dc28f0588e54 100644
+--- a/net/ipv4/arp.c
++++ b/net/ipv4/arp.c
+@@ -1116,13 +1116,18 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
+       return err;
+ }
+-static int arp_invalidate(struct net_device *dev, __be32 ip)
++int arp_invalidate(struct net_device *dev, __be32 ip, bool force)
+ {
+       struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
+       int err = -ENXIO;
+       struct neigh_table *tbl = &arp_tbl;
+       if (neigh) {
++              if ((neigh->nud_state & NUD_VALID) && !force) {
++                      neigh_release(neigh);
++                      return 0;
++              }
++
+               if (neigh->nud_state & ~NUD_NOARP)
+                       err = neigh_update(neigh, NULL, NUD_FAILED,
+                                          NEIGH_UPDATE_F_OVERRIDE|
+@@ -1169,7 +1174,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
+               if (!dev)
+                       return -EINVAL;
+       }
+-      return arp_invalidate(dev, ip);
++      return arp_invalidate(dev, ip, true);
+ }
+ /*
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index 85117b45216d..89a5a4875595 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -1115,9 +1115,11 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
+               return;
+       /* Add broadcast address, if it is explicitly assigned. */
+-      if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF))
++      if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) {
+               fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32,
+                         prim, 0);
++              arp_invalidate(dev, ifa->ifa_broadcast, false);
++      }
+       if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) &&
+           (prefix != addr || ifa->ifa_prefixlen < 32)) {
+@@ -1131,6 +1133,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
+               if (ifa->ifa_prefixlen < 31) {
+                       fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix | ~mask,
+                                 32, prim, 0);
++                      arp_invalidate(dev, prefix | ~mask, false);
+               }
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/ipv6-annotate-some-data-races-around-sk-sk_prot.patch b/queue-5.17/ipv6-annotate-some-data-races-around-sk-sk_prot.patch
new file mode 100644 (file)
index 0000000..45590f8
--- /dev/null
@@ -0,0 +1,170 @@
+From b1073fe8310654d5ca31c21d96fa0f0036f00752 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 15:48:41 -0800
+Subject: ipv6: annotate some data-races around sk->sk_prot
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 086d49058cd8471046ae9927524708820f5fd1c7 ]
+
+IPv6 has this hack changing sk->sk_prot when an IPv6 socket
+is 'converted' to an IPv4 one with IPV6_ADDRFORM option.
+
+This operation is only performed for TCP and UDP, knowing
+their 'struct proto' for the two network families are populated
+in the same way, and can not disappear while a reader
+might use and dereference sk->sk_prot.
+
+If we think about it all reads of sk->sk_prot while
+either socket lock or RTNL is not acquired should be using READ_ONCE().
+
+Also note that other layers like MPTCP, XFRM, CHELSIO_TLS also
+write over sk->sk_prot.
+
+BUG: KCSAN: data-race in inet6_recvmsg / ipv6_setsockopt
+
+write to 0xffff8881386f7aa8 of 8 bytes by task 26932 on cpu 0:
+ do_ipv6_setsockopt net/ipv6/ipv6_sockglue.c:492 [inline]
+ ipv6_setsockopt+0x3758/0x3910 net/ipv6/ipv6_sockglue.c:1019
+ udpv6_setsockopt+0x85/0x90 net/ipv6/udp.c:1649
+ sock_common_setsockopt+0x5d/0x70 net/core/sock.c:3489
+ __sys_setsockopt+0x209/0x2a0 net/socket.c:2180
+ __do_sys_setsockopt net/socket.c:2191 [inline]
+ __se_sys_setsockopt net/socket.c:2188 [inline]
+ __x64_sys_setsockopt+0x62/0x70 net/socket.c:2188
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+read to 0xffff8881386f7aa8 of 8 bytes by task 26911 on cpu 1:
+ inet6_recvmsg+0x7a/0x210 net/ipv6/af_inet6.c:659
+ ____sys_recvmsg+0x16c/0x320
+ ___sys_recvmsg net/socket.c:2674 [inline]
+ do_recvmmsg+0x3f5/0xae0 net/socket.c:2768
+ __sys_recvmmsg net/socket.c:2847 [inline]
+ __do_sys_recvmmsg net/socket.c:2870 [inline]
+ __se_sys_recvmmsg net/socket.c:2863 [inline]
+ __x64_sys_recvmmsg+0xde/0x160 net/socket.c:2863
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+value changed: 0xffffffff85e0e980 -> 0xffffffff85e01580
+
+Reported by Kernel Concurrency Sanitizer on:
+CPU: 1 PID: 26911 Comm: syz-executor.3 Not tainted 5.17.0-rc2-syzkaller-00316-g0457e5153e0e-dirty #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/af_inet6.c      | 24 ++++++++++++++++++------
+ net/ipv6/ipv6_sockglue.c |  6 ++++--
+ 2 files changed, 22 insertions(+), 8 deletions(-)
+
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 8fe7900f1949..7d7b7523d126 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -441,11 +441,14 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ {
+       struct sock *sk = sock->sk;
+       u32 flags = BIND_WITH_LOCK;
++      const struct proto *prot;
+       int err = 0;
++      /* IPV6_ADDRFORM can change sk->sk_prot under us. */
++      prot = READ_ONCE(sk->sk_prot);
+       /* If the socket has its own bind function then use it. */
+-      if (sk->sk_prot->bind)
+-              return sk->sk_prot->bind(sk, uaddr, addr_len);
++      if (prot->bind)
++              return prot->bind(sk, uaddr, addr_len);
+       if (addr_len < SIN6_LEN_RFC2133)
+               return -EINVAL;
+@@ -555,6 +558,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+       void __user *argp = (void __user *)arg;
+       struct sock *sk = sock->sk;
+       struct net *net = sock_net(sk);
++      const struct proto *prot;
+       switch (cmd) {
+       case SIOCADDRT:
+@@ -572,9 +576,11 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+       case SIOCSIFDSTADDR:
+               return addrconf_set_dstaddr(net, argp);
+       default:
+-              if (!sk->sk_prot->ioctl)
++              /* IPV6_ADDRFORM can change sk->sk_prot under us. */
++              prot = READ_ONCE(sk->sk_prot);
++              if (!prot->ioctl)
+                       return -ENOIOCTLCMD;
+-              return sk->sk_prot->ioctl(sk, cmd, arg);
++              return prot->ioctl(sk, cmd, arg);
+       }
+       /*NOTREACHED*/
+       return 0;
+@@ -636,11 +642,14 @@ INDIRECT_CALLABLE_DECLARE(int udpv6_sendmsg(struct sock *, struct msghdr *,
+ int inet6_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ {
+       struct sock *sk = sock->sk;
++      const struct proto *prot;
+       if (unlikely(inet_send_prepare(sk)))
+               return -EAGAIN;
+-      return INDIRECT_CALL_2(sk->sk_prot->sendmsg, tcp_sendmsg, udpv6_sendmsg,
++      /* IPV6_ADDRFORM can change sk->sk_prot under us. */
++      prot = READ_ONCE(sk->sk_prot);
++      return INDIRECT_CALL_2(prot->sendmsg, tcp_sendmsg, udpv6_sendmsg,
+                              sk, msg, size);
+ }
+@@ -650,13 +659,16 @@ int inet6_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
+                 int flags)
+ {
+       struct sock *sk = sock->sk;
++      const struct proto *prot;
+       int addr_len = 0;
+       int err;
+       if (likely(!(flags & MSG_ERRQUEUE)))
+               sock_rps_record_flow(sk);
+-      err = INDIRECT_CALL_2(sk->sk_prot->recvmsg, tcp_recvmsg, udpv6_recvmsg,
++      /* IPV6_ADDRFORM can change sk->sk_prot under us. */
++      prot = READ_ONCE(sk->sk_prot);
++      err = INDIRECT_CALL_2(prot->recvmsg, tcp_recvmsg, udpv6_recvmsg,
+                             sk, msg, size, flags & MSG_DONTWAIT,
+                             flags & ~MSG_DONTWAIT, &addr_len);
+       if (err >= 0)
+diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
+index a733803a710c..222f6bf220ba 100644
+--- a/net/ipv6/ipv6_sockglue.c
++++ b/net/ipv6/ipv6_sockglue.c
+@@ -475,7 +475,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
+                               sock_prot_inuse_add(net, sk->sk_prot, -1);
+                               sock_prot_inuse_add(net, &tcp_prot, 1);
+-                              sk->sk_prot = &tcp_prot;
++                              /* Paired with READ_ONCE(sk->sk_prot) in net/ipv6/af_inet6.c */
++                              WRITE_ONCE(sk->sk_prot, &tcp_prot);
+                               icsk->icsk_af_ops = &ipv4_specific;
+                               sk->sk_socket->ops = &inet_stream_ops;
+                               sk->sk_family = PF_INET;
+@@ -489,7 +490,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
+                               sock_prot_inuse_add(net, sk->sk_prot, -1);
+                               sock_prot_inuse_add(net, prot, 1);
+-                              sk->sk_prot = prot;
++                              /* Paired with READ_ONCE(sk->sk_prot) in net/ipv6/af_inet6.c */
++                              WRITE_ONCE(sk->sk_prot, prot);
+                               sk->sk_socket->ops = &inet_dgram_ops;
+                               sk->sk_family = PF_INET;
+                       }
+-- 
+2.35.1
+
diff --git a/queue-5.17/ipv6-make-mc_forwarding-atomic.patch b/queue-5.17/ipv6-make-mc_forwarding-atomic.patch
new file mode 100644 (file)
index 0000000..0c4a1e1
--- /dev/null
@@ -0,0 +1,127 @@
+From 116b9dc4ad682be6fe208db23994b62fe0b847a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 12:15:45 -0800
+Subject: ipv6: make mc_forwarding atomic
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 145c7a793838add5e004e7d49a67654dc7eba147 ]
+
+This fixes minor data-races in ip6_mc_input() and
+batadv_mcast_mla_rtr_flags_softif_get_ipv6()
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/ipv6.h       | 2 +-
+ net/batman-adv/multicast.c | 2 +-
+ net/ipv6/addrconf.c        | 4 ++--
+ net/ipv6/ip6_input.c       | 2 +-
+ net/ipv6/ip6mr.c           | 8 ++++----
+ 5 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
+index a59d25f19385..b8641dc0ee66 100644
+--- a/include/linux/ipv6.h
++++ b/include/linux/ipv6.h
+@@ -51,7 +51,7 @@ struct ipv6_devconf {
+       __s32           use_optimistic;
+ #endif
+ #ifdef CONFIG_IPV6_MROUTE
+-      __s32           mc_forwarding;
++      atomic_t        mc_forwarding;
+ #endif
+       __s32           disable_ipv6;
+       __s32           drop_unicast_in_l2_multicast;
+diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
+index f4004cf0ff6f..9f311fddfaf9 100644
+--- a/net/batman-adv/multicast.c
++++ b/net/batman-adv/multicast.c
+@@ -134,7 +134,7 @@ static u8 batadv_mcast_mla_rtr_flags_softif_get_ipv6(struct net_device *dev)
+ {
+       struct inet6_dev *in6_dev = __in6_dev_get(dev);
+-      if (in6_dev && in6_dev->cnf.mc_forwarding)
++      if (in6_dev && atomic_read(&in6_dev->cnf.mc_forwarding))
+               return BATADV_NO_FLAGS;
+       else
+               return BATADV_MCAST_WANT_NO_RTR6;
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index f908e2fd30b2..4df84013c4e6 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -554,7 +554,7 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
+ #ifdef CONFIG_IPV6_MROUTE
+       if ((all || type == NETCONFA_MC_FORWARDING) &&
+           nla_put_s32(skb, NETCONFA_MC_FORWARDING,
+-                      devconf->mc_forwarding) < 0)
++                      atomic_read(&devconf->mc_forwarding)) < 0)
+               goto nla_put_failure;
+ #endif
+       if ((all || type == NETCONFA_PROXY_NEIGH) &&
+@@ -5539,7 +5539,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
+       array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic;
+ #endif
+ #ifdef CONFIG_IPV6_MROUTE
+-      array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
++      array[DEVCONF_MC_FORWARDING] = atomic_read(&cnf->mc_forwarding);
+ #endif
+       array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
+       array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
+diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
+index 80256717868e..d4b1e2c5aa76 100644
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -508,7 +508,7 @@ int ip6_mc_input(struct sk_buff *skb)
+       /*
+        *      IPv6 multicast router mode is now supported ;)
+        */
+-      if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
++      if (atomic_read(&dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding) &&
+           !(ipv6_addr_type(&hdr->daddr) &
+             (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
+           likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
+diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
+index 8a2db926b5eb..e3c884678dbe 100644
+--- a/net/ipv6/ip6mr.c
++++ b/net/ipv6/ip6mr.c
+@@ -734,7 +734,7 @@ static int mif6_delete(struct mr_table *mrt, int vifi, int notify,
+       in6_dev = __in6_dev_get(dev);
+       if (in6_dev) {
+-              in6_dev->cnf.mc_forwarding--;
++              atomic_dec(&in6_dev->cnf.mc_forwarding);
+               inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
+                                            NETCONFA_MC_FORWARDING,
+                                            dev->ifindex, &in6_dev->cnf);
+@@ -902,7 +902,7 @@ static int mif6_add(struct net *net, struct mr_table *mrt,
+       in6_dev = __in6_dev_get(dev);
+       if (in6_dev) {
+-              in6_dev->cnf.mc_forwarding++;
++              atomic_inc(&in6_dev->cnf.mc_forwarding);
+               inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
+                                            NETCONFA_MC_FORWARDING,
+                                            dev->ifindex, &in6_dev->cnf);
+@@ -1553,7 +1553,7 @@ static int ip6mr_sk_init(struct mr_table *mrt, struct sock *sk)
+       } else {
+               rcu_assign_pointer(mrt->mroute_sk, sk);
+               sock_set_flag(sk, SOCK_RCU_FREE);
+-              net->ipv6.devconf_all->mc_forwarding++;
++              atomic_inc(&net->ipv6.devconf_all->mc_forwarding);
+       }
+       write_unlock_bh(&mrt_lock);
+@@ -1586,7 +1586,7 @@ int ip6mr_sk_done(struct sock *sk)
+                        * so the RCU grace period before sk freeing
+                        * is guaranteed by sk_destruct()
+                        */
+-                      net->ipv6.devconf_all->mc_forwarding--;
++                      atomic_dec(&net->ipv6.devconf_all->mc_forwarding);
+                       write_unlock_bh(&mrt_lock);
+                       inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
+                                                    NETCONFA_MC_FORWARDING,
+-- 
+2.35.1
+
diff --git a/queue-5.17/iwlwifi-fix-small-doc-mistake-for-iwl_fw_ini_addr_va.patch b/queue-5.17/iwlwifi-fix-small-doc-mistake-for-iwl_fw_ini_addr_va.patch
new file mode 100644 (file)
index 0000000..c5864c9
--- /dev/null
@@ -0,0 +1,48 @@
+From 78e10af9fa25570c090c5f00b6e6a940f4cf7282 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Feb 2022 11:21:40 +0200
+Subject: iwlwifi: fix small doc mistake for iwl_fw_ini_addr_val
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+[ Upstream commit 3009c797c4b3840495e8f48d8d07f48d2ddfed80 ]
+
+There was a small copy and paste mistake in the doc declaration of
+iwl_fw_ini_addr_val.  Fix it.
+
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20220205112029.aeec71c397b3.I0ba3234419eb8c8c7512a2ca531a6dbb55046cf7@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
+index 456b7eaac570..061fe6cc6cf5 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2018-2021 Intel Corporation
++ * Copyright (C) 2018-2022 Intel Corporation
+  */
+ #ifndef __iwl_fw_dbg_tlv_h__
+ #define __iwl_fw_dbg_tlv_h__
+@@ -249,11 +249,10 @@ struct iwl_fw_ini_hcmd_tlv {
+ } __packed; /* FW_TLV_DEBUG_HCMD_API_S_VER_1 */
+ /**
+-* struct iwl_fw_ini_conf_tlv - preset configuration TLV
++* struct iwl_fw_ini_addr_val - Address and value to set it to
+ *
+ * @address: the base address
+ * @value: value to set at address
+-
+ */
+ struct iwl_fw_ini_addr_val {
+       __le32 address;
+-- 
+2.35.1
+
diff --git a/queue-5.17/iwlwifi-mei-fix-building-iwlmei.patch b/queue-5.17/iwlwifi-mei-fix-building-iwlmei.patch
new file mode 100644 (file)
index 0000000..7862680
--- /dev/null
@@ -0,0 +1,44 @@
+From 7a99dcb6945a2461c72816a2c344baf44ee3d537 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Mar 2022 19:36:03 +0100
+Subject: iwlwifi: mei: fix building iwlmei
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 066291bec0c55315e568ead501bebdefcb8453d2 ]
+
+Building iwlmei without CONFIG_CFG80211 causes a link-time warning:
+
+ld.lld: error: undefined symbol: ieee80211_hdrlen
+>>> referenced by net.c
+>>>               net/wireless/intel/iwlwifi/mei/net.o:(iwl_mei_tx_copy_to_csme) in archive drivers/built-in.a
+
+Add an explicit dependency to avoid this. In theory it should not
+be needed here, but it also seems pointless to allow IWLMEI
+for configurations without CFG80211.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Emmanuel Grumbach <Emmanuel.grumbach@intel.com>
+Acked-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220316183617.1470631-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig b/drivers/net/wireless/intel/iwlwifi/Kconfig
+index 85e704283755..a647a406b87b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/Kconfig
++++ b/drivers/net/wireless/intel/iwlwifi/Kconfig
+@@ -139,6 +139,7 @@ config IWLMEI
+       tristate "Intel Management Engine communication over WLAN"
+       depends on INTEL_MEI
+       depends on PM
++      depends on CFG80211
+       help
+         Enables the iwlmei kernel module.
+-- 
+2.35.1
+
diff --git a/queue-5.17/iwlwifi-mvm-correctly-set-fragmented-ebs.patch b/queue-5.17/iwlwifi-mvm-correctly-set-fragmented-ebs.patch
new file mode 100644 (file)
index 0000000..b082750
--- /dev/null
@@ -0,0 +1,42 @@
+From 62d0a19970f967504b6077754c3912989d0c8ea0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 12:25:00 +0200
+Subject: iwlwifi: mvm: Correctly set fragmented EBS
+
+From: Ilan Peer <ilan.peer@intel.com>
+
+[ Upstream commit d8d4dd26b9e0469baf5017f0544d852fd4e3fb6d ]
+
+Currently, fragmented EBS was set for a channel only if the 'hb_type'
+was set to fragmented or balanced scan. However, 'hb_type' is set only
+in case of CDB, and thus fragmented EBS is never set for a channel for
+non-CDB devices. Fix it.
+
+Signed-off-by: Ilan Peer <ilan.peer@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20220204122220.a6165ac9b9d5.I654eafa62fd647030ae6d4f07f32c96c3171decb@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+index 5f92a09db374..4cd507cb412d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+@@ -1893,7 +1893,10 @@ static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm,
+                       IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
+       /* set fragmented ebs for fragmented scan on HB channels */
+-      if (iwl_mvm_is_scan_fragmented(params->hb_type))
++      if ((!iwl_mvm_is_cdb_supported(mvm) &&
++           iwl_mvm_is_scan_fragmented(params->type)) ||
++          (iwl_mvm_is_cdb_supported(mvm) &&
++           iwl_mvm_is_scan_fragmented(params->hb_type)))
+               flags |= IWL_SCAN_CHANNEL_FLAG_EBS_FRAG;
+       return flags;
+-- 
+2.35.1
+
diff --git a/queue-5.17/iwlwifi-mvm-move-only-to-an-enabled-channel.patch b/queue-5.17/iwlwifi-mvm-move-only-to-an-enabled-channel.patch
new file mode 100644 (file)
index 0000000..be29a57
--- /dev/null
@@ -0,0 +1,80 @@
+From 57a0836458a61ddd8f9e30c8d3a4a20668eec6a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 18:22:33 +0200
+Subject: iwlwifi: mvm: move only to an enabled channel
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit e04135c07755d001b5cde61048c69a7cc84bb94b ]
+
+During disassociation we're decreasing the phy's ref count.
+If the ref count becomes 0, we're configuring the phy ctxt
+to the default channel (the lowest channel which the device
+can operate on). Currently we're not checking whether the
+the default channel is enabled or not. Fix it by configuring
+the phy ctxt to the lowest channel which is enabled.
+
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20220210181930.03f281b6a6bc.I5b63d43ec41996d599e6f37ec3f32e878b3e405e@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 31 +++++++++++++------
+ 1 file changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+index 9af40b0fa37a..a6e6673bf4ee 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2022 Intel Corporation
+  * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
+  * Copyright (C) 2017 Intel Deutschland GmbH
+  */
+@@ -349,18 +349,31 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
+        * otherwise we might not be able to reuse this phy.
+        */
+       if (ctxt->ref == 0) {
+-              struct ieee80211_channel *chan;
++              struct ieee80211_channel *chan = NULL;
+               struct cfg80211_chan_def chandef;
+-              struct ieee80211_supported_band *sband = NULL;
+-              enum nl80211_band band = NL80211_BAND_2GHZ;
++              struct ieee80211_supported_band *sband;
++              enum nl80211_band band;
++              int channel;
+-              while (!sband && band < NUM_NL80211_BANDS)
+-                      sband = mvm->hw->wiphy->bands[band++];
++              for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
++                      sband = mvm->hw->wiphy->bands[band];
+-              if (WARN_ON(!sband))
+-                      return;
++                      if (!sband)
++                              continue;
++
++                      for (channel = 0; channel < sband->n_channels; channel++)
++                              if (!(sband->channels[channel].flags &
++                                              IEEE80211_CHAN_DISABLED)) {
++                                      chan = &sband->channels[channel];
++                                      break;
++                              }
+-              chan = &sband->channels[0];
++                      if (chan)
++                              break;
++              }
++
++              if (WARN_ON(!chan))
++                      return;
+               cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
+               iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
+-- 
+2.35.1
+
diff --git a/queue-5.17/jfs-prevent-null-deref-in-difree.patch b/queue-5.17/jfs-prevent-null-deref-in-difree.patch
new file mode 100644 (file)
index 0000000..7c2e9af
--- /dev/null
@@ -0,0 +1,48 @@
+From ea8a221cb67965e207e6e51e6a93552732e1299b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Mar 2022 21:59:17 +0800
+Subject: jfs: prevent NULL deref in diFree
+
+From: Haimin Zhang <tcs_kernel@tencent.com>
+
+[ Upstream commit a53046291020ec41e09181396c1e829287b48d47 ]
+
+Add validation check for JFS_IP(ipimap)->i_imap to prevent a NULL deref
+in diFree since diFree uses it without do any validations.
+When function jfs_mount calls diMount to initialize fileset inode
+allocation map, it can fail and JFS_IP(ipimap)->i_imap won't be
+initialized. Then it calls diFreeSpecial to close fileset inode allocation
+map inode and it will flow into jfs_evict_inode. Function jfs_evict_inode
+just validates JFS_SBI(inode->i_sb)->ipimap, then calls diFree. diFree use
+JFS_IP(ipimap)->i_imap directly, then it will cause a NULL deref.
+
+Reported-by: TCS Robot <tcs_robot@tencent.com>
+Signed-off-by: Haimin Zhang <tcs_kernel@tencent.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/inode.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
+index 57ab424c05ff..072821b50ab9 100644
+--- a/fs/jfs/inode.c
++++ b/fs/jfs/inode.c
+@@ -146,12 +146,13 @@ void jfs_evict_inode(struct inode *inode)
+               dquot_initialize(inode);
+               if (JFS_IP(inode)->fileset == FILESYSTEM_I) {
++                      struct inode *ipimap = JFS_SBI(inode->i_sb)->ipimap;
+                       truncate_inode_pages_final(&inode->i_data);
+                       if (test_cflag(COMMIT_Freewmap, inode))
+                               jfs_free_zero_link(inode);
+-                      if (JFS_SBI(inode->i_sb)->ipimap)
++                      if (ipimap && JFS_IP(ipimap)->i_imap)
+                               diFree(inode);
+                       /*
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-arm64-do-not-change-the-pmu-event-filter-after-a.patch b/queue-5.17/kvm-arm64-do-not-change-the-pmu-event-filter-after-a.patch
new file mode 100644 (file)
index 0000000..77e60c0
--- /dev/null
@@ -0,0 +1,164 @@
+From 53be503634a50b2005fd56ddd90b26b46d46d41f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 16:17:54 +0000
+Subject: KVM: arm64: Do not change the PMU event filter after a VCPU has run
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 5177fe91e4cf78a659aada2c9cf712db4d788481 ]
+
+Userspace can specify which events a guest is allowed to use with the
+KVM_ARM_VCPU_PMU_V3_FILTER attribute. The list of allowed events can be
+identified by a guest from reading the PMCEID{0,1}_EL0 registers.
+
+Changing the PMU event filter after a VCPU has run can cause reads of the
+registers performed before the filter is changed to return different values
+than reads performed with the new event filter in place. The architecture
+defines the two registers as read-only, and this behaviour contradicts
+that.
+
+Keep track when the first VCPU has run and deny changes to the PMU event
+filter to prevent this from happening.
+
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+[ Alexandru E: Added commit message, updated ioctl documentation ]
+Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220127161759.53553-2-alexandru.elisei@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/virt/kvm/devices/vcpu.rst |  2 +-
+ arch/arm64/include/asm/kvm_host.h       |  1 +
+ arch/arm64/kvm/arm.c                    |  4 +++
+ arch/arm64/kvm/pmu-emul.c               | 33 +++++++++++++++----------
+ 4 files changed, 26 insertions(+), 14 deletions(-)
+
+diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
+index 60a29972d3f1..d063aaee5bb7 100644
+--- a/Documentation/virt/kvm/devices/vcpu.rst
++++ b/Documentation/virt/kvm/devices/vcpu.rst
+@@ -70,7 +70,7 @@ irqchip.
+        -ENODEV  PMUv3 not supported or GIC not initialized
+        -ENXIO   PMUv3 not properly configured or in-kernel irqchip not
+                 configured as required prior to calling this attribute
+-       -EBUSY   PMUv3 already initialized
++       -EBUSY   PMUv3 already initialized or a VCPU has already run
+        -EINVAL  Invalid filter range
+        =======  ======================================================
+diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
+index 031e3a2537fc..8234626a945a 100644
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -136,6 +136,7 @@ struct kvm_arch {
+       /* Memory Tagging Extension enabled for the guest */
+       bool mte_enabled;
++      bool ran_once;
+ };
+ struct kvm_vcpu_fault_info {
+diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
+index 4dca6ffd03d4..85a2a75f4498 100644
+--- a/arch/arm64/kvm/arm.c
++++ b/arch/arm64/kvm/arm.c
+@@ -634,6 +634,10 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
+       if (kvm_vm_is_protected(kvm))
+               kvm_call_hyp_nvhe(__pkvm_vcpu_init_traps, vcpu);
++      mutex_lock(&kvm->lock);
++      kvm->arch.ran_once = true;
++      mutex_unlock(&kvm->lock);
++
+       return ret;
+ }
+diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
+index fbcfd4ec6f92..bc771bc1a041 100644
+--- a/arch/arm64/kvm/pmu-emul.c
++++ b/arch/arm64/kvm/pmu-emul.c
+@@ -924,6 +924,8 @@ static bool pmu_irq_is_valid(struct kvm *kvm, int irq)
+ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+ {
++      struct kvm *kvm = vcpu->kvm;
++
+       if (!kvm_vcpu_has_pmu(vcpu))
+               return -ENODEV;
+@@ -941,7 +943,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+               int __user *uaddr = (int __user *)(long)attr->addr;
+               int irq;
+-              if (!irqchip_in_kernel(vcpu->kvm))
++              if (!irqchip_in_kernel(kvm))
+                       return -EINVAL;
+               if (get_user(irq, uaddr))
+@@ -951,7 +953,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+               if (!(irq_is_ppi(irq) || irq_is_spi(irq)))
+                       return -EINVAL;
+-              if (!pmu_irq_is_valid(vcpu->kvm, irq))
++              if (!pmu_irq_is_valid(kvm, irq))
+                       return -EINVAL;
+               if (kvm_arm_pmu_irq_initialized(vcpu))
+@@ -966,7 +968,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+               struct kvm_pmu_event_filter filter;
+               int nr_events;
+-              nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1;
++              nr_events = kvm_pmu_event_mask(kvm) + 1;
+               uaddr = (struct kvm_pmu_event_filter __user *)(long)attr->addr;
+@@ -978,12 +980,17 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+                    filter.action != KVM_PMU_EVENT_DENY))
+                       return -EINVAL;
+-              mutex_lock(&vcpu->kvm->lock);
++              mutex_lock(&kvm->lock);
++
++              if (kvm->arch.ran_once) {
++                      mutex_unlock(&kvm->lock);
++                      return -EBUSY;
++              }
+-              if (!vcpu->kvm->arch.pmu_filter) {
+-                      vcpu->kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
+-                      if (!vcpu->kvm->arch.pmu_filter) {
+-                              mutex_unlock(&vcpu->kvm->lock);
++              if (!kvm->arch.pmu_filter) {
++                      kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
++                      if (!kvm->arch.pmu_filter) {
++                              mutex_unlock(&kvm->lock);
+                               return -ENOMEM;
+                       }
+@@ -994,17 +1001,17 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+                        * events, the default is to allow.
+                        */
+                       if (filter.action == KVM_PMU_EVENT_ALLOW)
+-                              bitmap_zero(vcpu->kvm->arch.pmu_filter, nr_events);
++                              bitmap_zero(kvm->arch.pmu_filter, nr_events);
+                       else
+-                              bitmap_fill(vcpu->kvm->arch.pmu_filter, nr_events);
++                              bitmap_fill(kvm->arch.pmu_filter, nr_events);
+               }
+               if (filter.action == KVM_PMU_EVENT_ALLOW)
+-                      bitmap_set(vcpu->kvm->arch.pmu_filter, filter.base_event, filter.nevents);
++                      bitmap_set(kvm->arch.pmu_filter, filter.base_event, filter.nevents);
+               else
+-                      bitmap_clear(vcpu->kvm->arch.pmu_filter, filter.base_event, filter.nevents);
++                      bitmap_clear(kvm->arch.pmu_filter, filter.base_event, filter.nevents);
+-              mutex_unlock(&vcpu->kvm->lock);
++              mutex_unlock(&kvm->lock);
+               return 0;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-selftests-aarch64-fix-assert-in-gicv3_access_reg.patch b/queue-5.17/kvm-selftests-aarch64-fix-assert-in-gicv3_access_reg.patch
new file mode 100644 (file)
index 0000000..3c4f099
--- /dev/null
@@ -0,0 +1,40 @@
+From 023d91a7a46368246342a5f28d853d920c27fda6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 19:08:54 -0800
+Subject: kvm: selftests: aarch64: fix assert in gicv3_access_reg
+
+From: Ricardo Koller <ricarkol@google.com>
+
+[ Upstream commit cc94d47ce16d4147d546e47c8248e8bd12ba5fe5 ]
+
+The val argument in gicv3_access_reg can have any value when used for a
+read, not necessarily 0.  Fix the assert by checking val only for
+writes.
+
+Signed-off-by: Ricardo Koller <ricarkol@google.com>
+Reported-by: Reiji Watanabe <reijiw@google.com>
+Cc: Andrew Jones <drjones@redhat.com>
+Reviewed-by: Andrew Jones <drjones@redhat.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220127030858.3269036-2-ricarkol@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/lib/aarch64/gic_v3.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c
+index 00f613c0583c..e4945fe66620 100644
+--- a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c
++++ b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c
+@@ -159,7 +159,7 @@ static void gicv3_access_reg(uint32_t intid, uint64_t offset,
+       uint32_t cpu_or_dist;
+       GUEST_ASSERT(bits_per_field <= reg_bits);
+-      GUEST_ASSERT(*val < (1U << bits_per_field));
++      GUEST_ASSERT(!write || *val < (1U << bits_per_field));
+       /* Some registers like IROUTER are 64 bit long. Those are currently not
+        * supported by readl nor writel, so just asserting here until then.
+        */
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-selftests-aarch64-fix-some-vgic-related-comments.patch b/queue-5.17/kvm-selftests-aarch64-fix-some-vgic-related-comments.patch
new file mode 100644 (file)
index 0000000..c4298a9
--- /dev/null
@@ -0,0 +1,121 @@
+From fec836bbee544637ca5b1304380e5d801422a6af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 19:08:57 -0800
+Subject: kvm: selftests: aarch64: fix some vgic related comments
+
+From: Ricardo Koller <ricarkol@google.com>
+
+[ Upstream commit a5cd38fd9c47b23abc6df08d6ee6a71b39038185 ]
+
+Fix the formatting of some comments and the wording of one of them (in
+gicv3_access_reg).
+
+Signed-off-by: Ricardo Koller <ricarkol@google.com>
+Reported-by: Reiji Watanabe <reijiw@google.com>
+Cc: Andrew Jones <drjones@redhat.com>
+Reviewed-by: Andrew Jones <drjones@redhat.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220127030858.3269036-5-ricarkol@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 12 ++++++++----
+ tools/testing/selftests/kvm/lib/aarch64/gic_v3.c | 10 ++++++----
+ tools/testing/selftests/kvm/lib/aarch64/vgic.c   |  3 ++-
+ 3 files changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+index 48e43e24d240..554ca649d470 100644
+--- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
++++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+@@ -306,7 +306,8 @@ static void guest_restore_active(struct test_args *args,
+       uint32_t prio, intid, ap1r;
+       int i;
+-      /* Set the priorities of the first (KVM_NUM_PRIOS - 1) IRQs
++      /*
++       * Set the priorities of the first (KVM_NUM_PRIOS - 1) IRQs
+        * in descending order, so intid+1 can preempt intid.
+        */
+       for (i = 0, prio = (num - 1) * 8; i < num; i++, prio -= 8) {
+@@ -315,7 +316,8 @@ static void guest_restore_active(struct test_args *args,
+               gic_set_priority(intid, prio);
+       }
+-      /* In a real migration, KVM would restore all GIC state before running
++      /*
++       * In a real migration, KVM would restore all GIC state before running
+        * guest code.
+        */
+       for (i = 0; i < num; i++) {
+@@ -503,7 +505,8 @@ static void guest_code(struct test_args *args)
+               test_injection_failure(args, f);
+       }
+-      /* Restore the active state of IRQs. This would happen when live
++      /*
++       * Restore the active state of IRQs. This would happen when live
+        * migrating IRQs in the middle of being handled.
+        */
+       for_each_supported_activate_fn(args, set_active_fns, f)
+@@ -844,7 +847,8 @@ int main(int argc, char **argv)
+               }
+       }
+-      /* If the user just specified nr_irqs and/or gic_version, then run all
++      /*
++       * If the user just specified nr_irqs and/or gic_version, then run all
+        * combinations.
+        */
+       if (default_args) {
+diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c
+index e4945fe66620..263bf3ed8fd5 100644
+--- a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c
++++ b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c
+@@ -19,7 +19,7 @@ struct gicv3_data {
+       unsigned int nr_spis;
+ };
+-#define sgi_base_from_redist(redist_base)     (redist_base + SZ_64K)
++#define sgi_base_from_redist(redist_base)     (redist_base + SZ_64K)
+ #define DIST_BIT                              (1U << 31)
+ enum gicv3_intid_range {
+@@ -105,7 +105,8 @@ static void gicv3_set_eoi_split(bool split)
+ {
+       uint32_t val;
+-      /* All other fields are read-only, so no need to read CTLR first. In
++      /*
++       * All other fields are read-only, so no need to read CTLR first. In
+        * fact, the kernel does the same.
+        */
+       val = split ? (1U << 1) : 0;
+@@ -160,8 +161,9 @@ static void gicv3_access_reg(uint32_t intid, uint64_t offset,
+       GUEST_ASSERT(bits_per_field <= reg_bits);
+       GUEST_ASSERT(!write || *val < (1U << bits_per_field));
+-      /* Some registers like IROUTER are 64 bit long. Those are currently not
+-       * supported by readl nor writel, so just asserting here until then.
++      /*
++       * This function does not support 64 bit accesses. Just asserting here
++       * until we implement readq/writeq.
+        */
+       GUEST_ASSERT(reg_bits == 32);
+diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
+index f5cd0c536d85..7c876ccf9294 100644
+--- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
++++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
+@@ -152,7 +152,8 @@ static void vgic_poke_irq(int gic_fd, uint32_t intid,
+               attr += SZ_64K;
+       }
+-      /* All calls will succeed, even with invalid intid's, as long as the
++      /*
++       * All calls will succeed, even with invalid intid's, as long as the
+        * addr part of the attr is within 32 bits (checked above). An invalid
+        * intid will just make the read/writes point to above the intended
+        * register space (i.e., ICPENDR after ISPENDR).
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-selftests-aarch64-fix-the-failure-check-in-kvm_s.patch b/queue-5.17/kvm-selftests-aarch64-fix-the-failure-check-in-kvm_s.patch
new file mode 100644 (file)
index 0000000..f9c67cb
--- /dev/null
@@ -0,0 +1,47 @@
+From 65903cf6897dc53536dd2c0fe35c68475d9b706b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 19:08:56 -0800
+Subject: kvm: selftests: aarch64: fix the failure check in
+ kvm_set_gsi_routing_irqchip_check
+
+From: Ricardo Koller <ricarkol@google.com>
+
+[ Upstream commit 5b7898648f02083012900e48d063e51ccbdad165 ]
+
+kvm_set_gsi_routing_irqchip_check(expect_failure=true) is used to check
+the error code returned by the kernel when trying to setup an invalid
+gsi routing table. The ioctl fails if "pin >= KVM_IRQCHIP_NUM_PINS", so
+kvm_set_gsi_routing_irqchip_check() should test the error only when
+"intid >= KVM_IRQCHIP_NUM_PINS+32". The issue is that the test check is
+"intid >= KVM_IRQCHIP_NUM_PINS", so for a case like "intid =
+KVM_IRQCHIP_NUM_PINS" the test wrongly assumes that the kernel will
+return an error.  Fix this by using the right check.
+
+Signed-off-by: Ricardo Koller <ricarkol@google.com>
+Reported-by: Reiji Watanabe <reijiw@google.com>
+Cc: Andrew Jones <drjones@redhat.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220127030858.3269036-4-ricarkol@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/aarch64/vgic_irq.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+index 7f3afee5cc00..48e43e24d240 100644
+--- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
++++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+@@ -573,8 +573,8 @@ static void kvm_set_gsi_routing_irqchip_check(struct kvm_vm *vm,
+               kvm_gsi_routing_write(vm, routing);
+       } else {
+               ret = _kvm_gsi_routing_write(vm, routing);
+-              /* The kernel only checks for KVM_IRQCHIP_NUM_PINS. */
+-              if (intid >= KVM_IRQCHIP_NUM_PINS)
++              /* The kernel only checks e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS */
++              if (((uint64_t)intid + num - 1 - MIN_SPI) >= KVM_IRQCHIP_NUM_PINS)
+                       TEST_ASSERT(ret != 0 && errno == EINVAL,
+                               "Bad intid %u did not cause KVM_SET_GSI_ROUTING "
+                               "error: rc: %i errno: %i", intid, ret, errno);
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-selftests-aarch64-pass-vgic_irq-guest-args-as-a-.patch b/queue-5.17/kvm-selftests-aarch64-pass-vgic_irq-guest-args-as-a-.patch
new file mode 100644 (file)
index 0000000..a5b2ca3
--- /dev/null
@@ -0,0 +1,108 @@
+From a81667bbb4ae91341bf32c39eb1dd6763e70a3b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 19:08:55 -0800
+Subject: kvm: selftests: aarch64: pass vgic_irq guest args as a pointer
+
+From: Ricardo Koller <ricarkol@google.com>
+
+[ Upstream commit 11024a7a0ac26dd31ddfa0f6590e158bdf9ab858 ]
+
+The guest in vgic_irq gets its arguments in a struct. This struct used
+to fit nicely in a single register so vcpu_args_set() was able to pass
+it by value by setting x0 with it. Unfortunately, this args struct grew
+after some commits and some guest args became random (specically
+kvm_supports_irqfd).
+
+Fix this by passing the guest args as a pointer (after allocating some
+guest memory for it).
+
+Signed-off-by: Ricardo Koller <ricarkol@google.com>
+Reported-by: Reiji Watanabe <reijiw@google.com>
+Cc: Andrew Jones <drjones@redhat.com>
+Reviewed-by: Andrew Jones <drjones@redhat.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220127030858.3269036-3-ricarkol@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../testing/selftests/kvm/aarch64/vgic_irq.c  | 29 ++++++++++---------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+index 7eca97799917..7f3afee5cc00 100644
+--- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
++++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+@@ -472,10 +472,10 @@ static void test_restore_active(struct test_args *args, struct kvm_inject_desc *
+               guest_restore_active(args, MIN_SPI, 4, f->cmd);
+ }
+-static void guest_code(struct test_args args)
++static void guest_code(struct test_args *args)
+ {
+-      uint32_t i, nr_irqs = args.nr_irqs;
+-      bool level_sensitive = args.level_sensitive;
++      uint32_t i, nr_irqs = args->nr_irqs;
++      bool level_sensitive = args->level_sensitive;
+       struct kvm_inject_desc *f, *inject_fns;
+       gic_init(GIC_V3, 1, dist, redist);
+@@ -484,11 +484,11 @@ static void guest_code(struct test_args args)
+               gic_irq_enable(i);
+       for (i = MIN_SPI; i < nr_irqs; i++)
+-              gic_irq_set_config(i, !args.level_sensitive);
++              gic_irq_set_config(i, !level_sensitive);
+-      gic_set_eoi_split(args.eoi_split);
++      gic_set_eoi_split(args->eoi_split);
+-      reset_priorities(&args);
++      reset_priorities(args);
+       gic_set_priority_mask(CPU_PRIO_MASK);
+       inject_fns  = level_sensitive ? inject_level_fns
+@@ -497,17 +497,17 @@ static void guest_code(struct test_args args)
+       local_irq_enable();
+       /* Start the tests. */
+-      for_each_supported_inject_fn(&args, inject_fns, f) {
+-              test_injection(&args, f);
+-              test_preemption(&args, f);
+-              test_injection_failure(&args, f);
++      for_each_supported_inject_fn(args, inject_fns, f) {
++              test_injection(args, f);
++              test_preemption(args, f);
++              test_injection_failure(args, f);
+       }
+       /* Restore the active state of IRQs. This would happen when live
+        * migrating IRQs in the middle of being handled.
+        */
+-      for_each_supported_activate_fn(&args, set_active_fns, f)
+-              test_restore_active(&args, f);
++      for_each_supported_activate_fn(args, set_active_fns, f)
++              test_restore_active(args, f);
+       GUEST_DONE();
+ }
+@@ -739,6 +739,7 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
+       int gic_fd;
+       struct kvm_vm *vm;
+       struct kvm_inject_args inject_args;
++      vm_vaddr_t args_gva;
+       struct test_args args = {
+               .nr_irqs = nr_irqs,
+@@ -757,7 +758,9 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
+       vcpu_init_descriptor_tables(vm, VCPU_ID);
+       /* Setup the guest args page (so it gets the args). */
+-      vcpu_args_set(vm, 0, 1, args);
++      args_gva = vm_vaddr_alloc_page(vm);
++      memcpy(addr_gva2hva(vm, args_gva), &args, sizeof(args));
++      vcpu_args_set(vm, 0, 1, args_gva);
+       gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
+                       GICD_BASE_GPA, GICR_BASE_GPA);
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-selftests-aarch64-use-a-tighter-assert-in-vgic_p.patch b/queue-5.17/kvm-selftests-aarch64-use-a-tighter-assert-in-vgic_p.patch
new file mode 100644 (file)
index 0000000..4db6bec
--- /dev/null
@@ -0,0 +1,51 @@
+From 2b4e607a95fd760749d44899765b5cd865d622f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 19:08:58 -0800
+Subject: kvm: selftests: aarch64: use a tighter assert in vgic_poke_irq()
+
+From: Ricardo Koller <ricarkol@google.com>
+
+[ Upstream commit b53de63a89244c196d8a2ea76b6754e3fdb4b626 ]
+
+vgic_poke_irq() checks that the attr argument passed to the vgic device
+ioctl is sane. Make this check tighter by moving it to after the last
+attr update.
+
+Signed-off-by: Ricardo Koller <ricarkol@google.com>
+Reported-by: Reiji Watanabe <reijiw@google.com>
+Cc: Andrew Jones <drjones@redhat.com>
+Reviewed-by: Andrew Jones <drjones@redhat.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220127030858.3269036-6-ricarkol@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/lib/aarch64/vgic.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
+index 7c876ccf9294..5d45046c1b80 100644
+--- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
++++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
+@@ -140,9 +140,6 @@ static void vgic_poke_irq(int gic_fd, uint32_t intid,
+       uint64_t val;
+       bool intid_is_private = INTID_IS_SGI(intid) || INTID_IS_PPI(intid);
+-      /* Check that the addr part of the attr is within 32 bits. */
+-      assert(attr <= KVM_DEV_ARM_VGIC_OFFSET_MASK);
+-
+       uint32_t group = intid_is_private ? KVM_DEV_ARM_VGIC_GRP_REDIST_REGS
+                                         : KVM_DEV_ARM_VGIC_GRP_DIST_REGS;
+@@ -152,6 +149,9 @@ static void vgic_poke_irq(int gic_fd, uint32_t intid,
+               attr += SZ_64K;
+       }
++      /* Check that the addr part of the attr is within 32 bits. */
++      assert((attr & ~KVM_DEV_ARM_VGIC_OFFSET_MASK) == 0);
++
+       /*
+        * All calls will succeed, even with invalid intid's, as long as the
+        * addr part of the attr is within 32 bits (checked above). An invalid
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-svm-fix-kvm_cache_regs.h-inclusions-for-is_guest.patch b/queue-5.17/kvm-svm-fix-kvm_cache_regs.h-inclusions-for-is_guest.patch
new file mode 100644 (file)
index 0000000..c3a3bc5
--- /dev/null
@@ -0,0 +1,56 @@
+From 03c6b7bf918805e7c24766db2e8229d9cf3f6a3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 08:10:32 -0800
+Subject: KVM: SVM: Fix kvm_cache_regs.h inclusions for is_guest_mode()
+
+From: Peter Gonda <pgonda@google.com>
+
+[ Upstream commit 4a9e7b9ea252842bc8b14d495706ac6317fafd5d ]
+
+Include kvm_cache_regs.h to pick up the definition of is_guest_mode(),
+which is referenced by nested_svm_virtualize_tpr() in svm.h. Remove
+include from svm_onhpyerv.c which was done only because of lack of
+include in svm.h.
+
+Fixes: 883b0a91f41ab ("KVM: SVM: Move Nested SVM Implementation to nested.c")
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Sean Christopherson <seanjc@google.com>
+Cc: kvm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Peter Gonda <pgonda@google.com>
+Message-Id: <20220304161032.2270688-1-pgonda@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/svm/svm.h          | 2 ++
+ arch/x86/kvm/svm/svm_onhyperv.c | 1 -
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
+index fa98d6844728..86bcfed6599e 100644
+--- a/arch/x86/kvm/svm/svm.h
++++ b/arch/x86/kvm/svm/svm.h
+@@ -22,6 +22,8 @@
+ #include <asm/svm.h>
+ #include <asm/sev-common.h>
++#include "kvm_cache_regs.h"
++
+ #define __sme_page_pa(x) __sme_set(page_to_pfn(x) << PAGE_SHIFT)
+ #define       IOPM_SIZE PAGE_SIZE * 3
+diff --git a/arch/x86/kvm/svm/svm_onhyperv.c b/arch/x86/kvm/svm/svm_onhyperv.c
+index 98aa981c04ec..8cdc62c74a96 100644
+--- a/arch/x86/kvm/svm/svm_onhyperv.c
++++ b/arch/x86/kvm/svm/svm_onhyperv.c
+@@ -4,7 +4,6 @@
+  */
+ #include <linux/kvm_host.h>
+-#include "kvm_cache_regs.h"
+ #include <asm/mshyperv.h>
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-x86-emulator-emulate-rdpid-only-if-it-is-enabled.patch b/queue-5.17/kvm-x86-emulator-emulate-rdpid-only-if-it-is-enabled.patch
new file mode 100644 (file)
index 0000000..cb31092
--- /dev/null
@@ -0,0 +1,81 @@
+From 656cae7b1df4a26ecc239cacc9caccc3bc6cd2a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 21:15:14 +0800
+Subject: KVM: x86/emulator: Emulate RDPID only if it is enabled in guest
+
+From: Hou Wenlong <houwenlong.hwl@antgroup.com>
+
+[ Upstream commit a836839cbfe60dc434c5476a7429cf2bae36415d ]
+
+When RDTSCP is supported but RDPID is not supported in host,
+RDPID emulation is available. However, __kvm_get_msr() would
+only fail when RDTSCP/RDPID both are disabled in guest, so
+the emulator wouldn't inject a #UD when RDPID is disabled but
+RDTSCP is enabled in guest.
+
+Fixes: fb6d4d340e05 ("KVM: x86: emulate RDPID")
+Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com>
+Message-Id: <1dfd46ae5b76d3ed87bde3154d51c64ea64c99c1.1646226788.git.houwenlong.hwl@antgroup.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/emulate.c     | 4 +++-
+ arch/x86/kvm/kvm_emulate.h | 1 +
+ arch/x86/kvm/x86.c         | 6 ++++++
+ 3 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index 02d061a06aa1..de9d8a27387c 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -3523,8 +3523,10 @@ static int em_rdpid(struct x86_emulate_ctxt *ctxt)
+ {
+       u64 tsc_aux = 0;
+-      if (ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux))
++      if (!ctxt->ops->guest_has_rdpid(ctxt))
+               return emulate_ud(ctxt);
++
++      ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux);
+       ctxt->dst.val = tsc_aux;
+       return X86EMUL_CONTINUE;
+ }
+diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
+index 39eded2426ff..a2a7654d8ace 100644
+--- a/arch/x86/kvm/kvm_emulate.h
++++ b/arch/x86/kvm/kvm_emulate.h
+@@ -226,6 +226,7 @@ struct x86_emulate_ops {
+       bool (*guest_has_long_mode)(struct x86_emulate_ctxt *ctxt);
+       bool (*guest_has_movbe)(struct x86_emulate_ctxt *ctxt);
+       bool (*guest_has_fxsr)(struct x86_emulate_ctxt *ctxt);
++      bool (*guest_has_rdpid)(struct x86_emulate_ctxt *ctxt);
+       void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 9b6166348c94..c81ec70197fb 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -7675,6 +7675,11 @@ static bool emulator_guest_has_fxsr(struct x86_emulate_ctxt *ctxt)
+       return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_FXSR);
+ }
++static bool emulator_guest_has_rdpid(struct x86_emulate_ctxt *ctxt)
++{
++      return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_RDPID);
++}
++
+ static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
+ {
+       return kvm_register_read_raw(emul_to_vcpu(ctxt), reg);
+@@ -7757,6 +7762,7 @@ static const struct x86_emulate_ops emulate_ops = {
+       .guest_has_long_mode = emulator_guest_has_long_mode,
+       .guest_has_movbe     = emulator_guest_has_movbe,
+       .guest_has_fxsr      = emulator_guest_has_fxsr,
++      .guest_has_rdpid     = emulator_guest_has_rdpid,
+       .set_nmi_mask        = emulator_set_nmi_mask,
+       .get_hflags          = emulator_get_hflags,
+       .exiting_smm         = emulator_exiting_smm,
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-x86-pmu-fix-and-isolate-tsx-specific-performance.patch b/queue-5.17/kvm-x86-pmu-fix-and-isolate-tsx-specific-performance.patch
new file mode 100644 (file)
index 0000000..516d38e
--- /dev/null
@@ -0,0 +1,131 @@
+From 781c239781e02f1783f86b84d0121b80864f7da4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Mar 2022 16:42:57 +0800
+Subject: KVM: x86/pmu: Fix and isolate TSX-specific performance event logic
+
+From: Like Xu <likexu@tencent.com>
+
+[ Upstream commit e644896f5106aa3f6d7e8c7adf2e4dc0fce53555 ]
+
+HSW_IN_TX* bits are used in generic code which are not supported on
+AMD. Worse, these bits overlap with AMD EventSelect[11:8] and hence
+using HSW_IN_TX* bits unconditionally in generic code is resulting in
+unintentional pmu behavior on AMD. For example, if EventSelect[11:8]
+is 0x2, pmc_reprogram_counter() wrongly assumes that
+HSW_IN_TX_CHECKPOINTED is set and thus forces sampling period to be 0.
+
+Also per the SDM, both bits 32 and 33 "may only be set if the processor
+supports HLE or RTM" and for "IN_TXCP (bit 33): this bit may only be set
+for IA32_PERFEVTSEL2."
+
+Opportunistically eliminate code redundancy, because if the HSW_IN_TX*
+bit is set in pmc->eventsel, it is already set in attr.config.
+
+Reported-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Reported-by: Jim Mattson <jmattson@google.com>
+Fixes: 103af0a98788 ("perf, kvm: Support the in_tx/in_tx_cp modifiers in KVM arch perfmon emulation v5")
+Co-developed-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Signed-off-by: Like Xu <likexu@tencent.com>
+Message-Id: <20220309084257.88931-1-likexu@tencent.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/pmu.c           | 15 +++++----------
+ arch/x86/kvm/vmx/pmu_intel.c | 13 ++++++++++---
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
+index 902b6d700215..eca39f56c231 100644
+--- a/arch/x86/kvm/pmu.c
++++ b/arch/x86/kvm/pmu.c
+@@ -96,8 +96,7 @@ static void kvm_perf_overflow(struct perf_event *perf_event,
+ static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
+                                 u64 config, bool exclude_user,
+-                                bool exclude_kernel, bool intr,
+-                                bool in_tx, bool in_tx_cp)
++                                bool exclude_kernel, bool intr)
+ {
+       struct perf_event *event;
+       struct perf_event_attr attr = {
+@@ -116,16 +115,14 @@ static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
+       attr.sample_period = get_sample_period(pmc, pmc->counter);
+-      if (in_tx)
+-              attr.config |= HSW_IN_TX;
+-      if (in_tx_cp) {
++      if ((attr.config & HSW_IN_TX_CHECKPOINTED) &&
++          guest_cpuid_is_intel(pmc->vcpu)) {
+               /*
+                * HSW_IN_TX_CHECKPOINTED is not supported with nonzero
+                * period. Just clear the sample period so at least
+                * allocating the counter doesn't fail.
+                */
+               attr.sample_period = 0;
+-              attr.config |= HSW_IN_TX_CHECKPOINTED;
+       }
+       event = perf_event_create_kernel_counter(&attr, -1, current,
+@@ -233,9 +230,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
+       pmc_reprogram_counter(pmc, type, config,
+                             !(eventsel & ARCH_PERFMON_EVENTSEL_USR),
+                             !(eventsel & ARCH_PERFMON_EVENTSEL_OS),
+-                            eventsel & ARCH_PERFMON_EVENTSEL_INT,
+-                            (eventsel & HSW_IN_TX),
+-                            (eventsel & HSW_IN_TX_CHECKPOINTED));
++                            eventsel & ARCH_PERFMON_EVENTSEL_INT);
+ }
+ EXPORT_SYMBOL_GPL(reprogram_gp_counter);
+@@ -271,7 +266,7 @@ void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int idx)
+                             kvm_x86_ops.pmu_ops->pmc_perf_hw_id(pmc),
+                             !(en_field & 0x2), /* exclude user */
+                             !(en_field & 0x1), /* exclude kernel */
+-                            pmi, false, false);
++                            pmi);
+ }
+ EXPORT_SYMBOL_GPL(reprogram_fixed_counter);
+diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
+index 8ba12294a7c5..5fa3870b8988 100644
+--- a/arch/x86/kvm/vmx/pmu_intel.c
++++ b/arch/x86/kvm/vmx/pmu_intel.c
+@@ -389,6 +389,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+       struct kvm_pmc *pmc;
+       u32 msr = msr_info->index;
+       u64 data = msr_info->data;
++      u64 reserved_bits;
+       switch (msr) {
+       case MSR_CORE_PERF_FIXED_CTR_CTRL:
+@@ -443,7 +444,11 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+               } else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
+                       if (data == pmc->eventsel)
+                               return 0;
+-                      if (!(data & pmu->reserved_bits)) {
++                      reserved_bits = pmu->reserved_bits;
++                      if ((pmc->idx == 2) &&
++                          (pmu->raw_event_mask & HSW_IN_TX_CHECKPOINTED))
++                              reserved_bits ^= HSW_IN_TX_CHECKPOINTED;
++                      if (!(data & reserved_bits)) {
+                               reprogram_gp_counter(pmc, data);
+                               return 0;
+                       }
+@@ -534,8 +539,10 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
+       entry = kvm_find_cpuid_entry(vcpu, 7, 0);
+       if (entry &&
+           (boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
+-          (entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM)))
+-              pmu->reserved_bits ^= HSW_IN_TX|HSW_IN_TX_CHECKPOINTED;
++          (entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM))) {
++              pmu->reserved_bits ^= HSW_IN_TX;
++              pmu->raw_event_mask |= (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
++      }
+       bitmap_set(pmu->all_valid_pmc_idx,
+               0, pmu->nr_arch_gp_counters);
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-x86-pmu-use-different-raw-event-masks-for-amd-an.patch b/queue-5.17/kvm-x86-pmu-use-different-raw-event-masks-for-amd-an.patch
new file mode 100644 (file)
index 0000000..e56d78d
--- /dev/null
@@ -0,0 +1,89 @@
+From 89960e9fc202b3d75c3105f59e885b614a5a7587 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Mar 2022 17:24:52 -0800
+Subject: KVM: x86/pmu: Use different raw event masks for AMD and Intel
+
+From: Jim Mattson <jmattson@google.com>
+
+[ Upstream commit 95b065bf5c431c06c68056a03a5853b660640ecc ]
+
+The third nybble of AMD's event select overlaps with Intel's IN_TX and
+IN_TXCP bits. Therefore, we can't use AMD64_RAW_EVENT_MASK on Intel
+platforms that support TSX.
+
+Declare a raw_event_mask in the kvm_pmu structure, initialize it in
+the vendor-specific pmu_refresh() functions, and use that mask for
+PERF_TYPE_RAW configurations in reprogram_gp_counter().
+
+Fixes: 710c47651431 ("KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW")
+Signed-off-by: Jim Mattson <jmattson@google.com>
+Message-Id: <20220308012452.3468611-1-jmattson@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/kvm_host.h | 1 +
+ arch/x86/kvm/pmu.c              | 3 ++-
+ arch/x86/kvm/svm/pmu.c          | 1 +
+ arch/x86/kvm/vmx/pmu_intel.c    | 1 +
+ 4 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
+index ec9830d2aabf..17b4e1808b8e 100644
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -509,6 +509,7 @@ struct kvm_pmu {
+       u64 global_ctrl_mask;
+       u64 global_ovf_ctrl_mask;
+       u64 reserved_bits;
++      u64 raw_event_mask;
+       u8 version;
+       struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
+       struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED];
+diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
+index b1a02993782b..902b6d700215 100644
+--- a/arch/x86/kvm/pmu.c
++++ b/arch/x86/kvm/pmu.c
+@@ -185,6 +185,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
+       u32 type = PERF_TYPE_RAW;
+       struct kvm *kvm = pmc->vcpu->kvm;
+       struct kvm_pmu_event_filter *filter;
++      struct kvm_pmu *pmu = vcpu_to_pmu(pmc->vcpu);
+       bool allow_event = true;
+       if (eventsel & ARCH_PERFMON_EVENTSEL_PIN_CONTROL)
+@@ -221,7 +222,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
+       }
+       if (type == PERF_TYPE_RAW)
+-              config = eventsel & AMD64_RAW_EVENT_MASK;
++              config = eventsel & pmu->raw_event_mask;
+       if (pmc->current_config == eventsel && pmc_resume_counter(pmc))
+               return;
+diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c
+index 5aa45f13b16d..7cc664b4472a 100644
+--- a/arch/x86/kvm/svm/pmu.c
++++ b/arch/x86/kvm/svm/pmu.c
+@@ -284,6 +284,7 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
+       pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1;
+       pmu->reserved_bits = 0xfffffff000280000ull;
++      pmu->raw_event_mask = AMD64_RAW_EVENT_MASK;
+       pmu->version = 1;
+       /* not applicable to AMD; but clean them to prevent any fall out */
+       pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
+diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
+index 466d18fc0c5d..8ba12294a7c5 100644
+--- a/arch/x86/kvm/vmx/pmu_intel.c
++++ b/arch/x86/kvm/vmx/pmu_intel.c
+@@ -485,6 +485,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
+       pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
+       pmu->version = 0;
+       pmu->reserved_bits = 0xffffffff00200000ull;
++      pmu->raw_event_mask = X86_RAW_EVENT_MASK;
+       entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
+       if (!entry || !enable_pmu)
+-- 
+2.35.1
+
diff --git a/queue-5.17/kvm-x86-svm-clear-reserved-bits-written-to-perfevtse.patch b/queue-5.17/kvm-x86-svm-clear-reserved-bits-written-to-perfevtse.patch
new file mode 100644 (file)
index 0000000..5e77b0e
--- /dev/null
@@ -0,0 +1,74 @@
+From 024678864896d6dba6cb55ea9ac32dd1ce0ae682 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Feb 2022 15:41:31 -0800
+Subject: KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs
+
+From: Jim Mattson <jmattson@google.com>
+
+[ Upstream commit 9b026073db2f1ad0e4d8b61c83316c8497981037 ]
+
+AMD EPYC CPUs never raise a #GP for a WRMSR to a PerfEvtSeln MSR. Some
+reserved bits are cleared, and some are not. Specifically, on
+Zen3/Milan, bits 19 and 42 are not cleared.
+
+When emulating such a WRMSR, KVM should not synthesize a #GP,
+regardless of which bits are set. However, undocumented bits should
+not be passed through to the hardware MSR. So, rather than checking
+for reserved bits and synthesizing a #GP, just clear the reserved
+bits.
+
+This may seem pedantic, but since KVM currently does not support the
+"Host/Guest Only" bits (41:40), it is necessary to clear these bits
+rather than synthesizing #GP, because some popular guests (e.g Linux)
+will set the "Host Only" bit even on CPUs that don't support
+EFER.SVME, and they don't expect a #GP.
+
+For example,
+
+root@Ubuntu1804:~# perf stat -e r26 -a sleep 1
+
+ Performance counter stats for 'system wide':
+
+                 0      r26
+
+       1.001070977 seconds time elapsed
+
+Feb 23 03:59:58 Ubuntu1804 kernel: [  405.379957] unchecked MSR access error: WRMSR to 0xc0010200 (tried to write 0x0000020000130026) at rIP: 0xffffffff9b276a28 (native_write_msr+0x8/0x30)
+Feb 23 03:59:58 Ubuntu1804 kernel: [  405.379958] Call Trace:
+Feb 23 03:59:58 Ubuntu1804 kernel: [  405.379963]  amd_pmu_disable_event+0x27/0x90
+
+Fixes: ca724305a2b0 ("KVM: x86/vPMU: Implement AMD vPMU code for KVM")
+Reported-by: Lotus Fenn <lotusf@google.com>
+Signed-off-by: Jim Mattson <jmattson@google.com>
+Reviewed-by: Like Xu <likexu@tencent.com>
+Reviewed-by: David Dunn <daviddunn@google.com>
+Message-Id: <20220226234131.2167175-1-jmattson@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/svm/pmu.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c
+index 7cc664b4472a..ba40b7fced5a 100644
+--- a/arch/x86/kvm/svm/pmu.c
++++ b/arch/x86/kvm/svm/pmu.c
+@@ -262,12 +262,10 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+       /* MSR_EVNTSELn */
+       pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL);
+       if (pmc) {
+-              if (data == pmc->eventsel)
+-                      return 0;
+-              if (!(data & pmu->reserved_bits)) {
++              data &= ~pmu->reserved_bits;
++              if (data != pmc->eventsel)
+                       reprogram_gp_counter(pmc, data);
+-                      return 0;
+-              }
++              return 0;
+       }
+       return 1;
+-- 
+2.35.1
+
diff --git a/queue-5.17/lib-kconfig.debug-add-arch-dependency-for-function_a.patch b/queue-5.17/lib-kconfig.debug-add-arch-dependency-for-function_a.patch
new file mode 100644 (file)
index 0000000..b60ac6d
--- /dev/null
@@ -0,0 +1,52 @@
+From d7fe010ca435e28c3335fc67f33ac906bcaccc43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 16:05:50 -0700
+Subject: lib/Kconfig.debug: add ARCH dependency for FUNCTION_ALIGN option
+
+From: Feng Tang <feng.tang@intel.com>
+
+[ Upstream commit 1bf18da62106225dbc47aab41efee2aeb99caccd ]
+
+0Day robots reported there is compiling issue for 'csky' ARCH when
+CONFIG_DEBUG_FORCE_DATA_SECTION_ALIGNED is enabled [1]:
+
+All errors (new ones prefixed by >>):
+
+   {standard input}: Assembler messages:
+>> {standard input}:2277: Error: pcrel offset for branch to .LS000B too far (0x3c)
+
+Which was discussed in [2].  And as there is no solution for csky yet, add
+some dependency for this config to limit it to several ARCHs which have no
+compiling issue so far.
+
+[1]. https://lore.kernel.org/lkml/202202271612.W32UJAj2-lkp@intel.com/
+[2]. https://www.spinics.net/lists/linux-kbuild/msg30298.html
+
+Link: https://lkml.kernel.org/r/20220304021100.GN4548@shbuild999.sh.intel.com
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Feng Tang <feng.tang@intel.com>
+Cc: Guo Ren <guoren@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/Kconfig.debug | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 14b89aa37c5c..440fd666c16d 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -416,7 +416,8 @@ config SECTION_MISMATCH_WARN_ONLY
+         If unsure, say Y.
+ config DEBUG_FORCE_FUNCTION_ALIGN_64B
+-      bool "Force all function address 64B aligned" if EXPERT
++      bool "Force all function address 64B aligned"
++      depends on EXPERT && (X86_64 || ARM64 || PPC32 || PPC64 || ARC)
+       help
+         There are cases that a commit from one domain changes the function
+         address alignment of other domains, and cause magic performance
+-- 
+2.35.1
+
diff --git a/queue-5.17/lib-logic_iomem-correct-fallback-config-references.patch b/queue-5.17/lib-logic_iomem-correct-fallback-config-references.patch
new file mode 100644 (file)
index 0000000..5570f3a
--- /dev/null
@@ -0,0 +1,66 @@
+From 0eed17aae0f16417cb8d24bb2508aeb22c57b9ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jan 2022 16:40:15 +0100
+Subject: lib/logic_iomem: correct fallback config references
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 2a6852cb8ff0c8c1363cac648d68489343813212 ]
+
+Due to some renaming, we ended up with the "indirect iomem"
+naming in Kconfig, following INDIRECT_PIO. However, clearly
+I missed following through on that in the ifdefs, but so far
+INDIRECT_IOMEM_FALLBACK isn't used by any architecture.
+
+Reported-by: Lukas Bulwahn <lukas.bulwahn@gmail.com>
+Fixes: ca2e334232b6 ("lib: add iomem emulation (logic_iomem)")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/logic_iomem.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/lib/logic_iomem.c b/lib/logic_iomem.c
+index 8c3365f26e51..b247d412ddef 100644
+--- a/lib/logic_iomem.c
++++ b/lib/logic_iomem.c
+@@ -68,7 +68,7 @@ int logic_iomem_add_region(struct resource *resource,
+ }
+ EXPORT_SYMBOL(logic_iomem_add_region);
+-#ifndef CONFIG_LOGIC_IOMEM_FALLBACK
++#ifndef CONFIG_INDIRECT_IOMEM_FALLBACK
+ static void __iomem *real_ioremap(phys_addr_t offset, size_t size)
+ {
+       WARN(1, "invalid ioremap(0x%llx, 0x%zx)\n",
+@@ -81,7 +81,7 @@ static void real_iounmap(volatile void __iomem *addr)
+       WARN(1, "invalid iounmap for addr 0x%llx\n",
+            (unsigned long long)(uintptr_t __force)addr);
+ }
+-#endif /* CONFIG_LOGIC_IOMEM_FALLBACK */
++#endif /* CONFIG_INDIRECT_IOMEM_FALLBACK */
+ void __iomem *ioremap(phys_addr_t offset, size_t size)
+ {
+@@ -168,7 +168,7 @@ void iounmap(volatile void __iomem *addr)
+ }
+ EXPORT_SYMBOL(iounmap);
+-#ifndef CONFIG_LOGIC_IOMEM_FALLBACK
++#ifndef CONFIG_INDIRECT_IOMEM_FALLBACK
+ #define MAKE_FALLBACK(op, sz)                                                 \
+ static u##sz real_raw_read ## op(const volatile void __iomem *addr)   \
+ {                                                                     \
+@@ -213,7 +213,7 @@ static void real_memcpy_toio(volatile void __iomem *addr, const void *buffer,
+       WARN(1, "Invalid memcpy_toio at address 0x%llx\n",
+            (unsigned long long)(uintptr_t __force)addr);
+ }
+-#endif /* CONFIG_LOGIC_IOMEM_FALLBACK */
++#endif /* CONFIG_INDIRECT_IOMEM_FALLBACK */
+ #define MAKE_OP(op, sz)                                               \
+ u##sz __raw_read ## op(const volatile void __iomem *addr)             \
+-- 
+2.35.1
+
diff --git a/queue-5.17/libbpf-fix-accessing-syscall-arguments-on-powerpc.patch b/queue-5.17/libbpf-fix-accessing-syscall-arguments-on-powerpc.patch
new file mode 100644 (file)
index 0000000..4887b2b
--- /dev/null
@@ -0,0 +1,39 @@
+From bb3e8149bf93b180164bf49931b30d10beb6a894 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Feb 2022 03:17:39 +0100
+Subject: libbpf: Fix accessing syscall arguments on powerpc
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+[ Upstream commit f07f1503469b11b739892d50c836992ffbe026ee ]
+
+powerpc does not select ARCH_HAS_SYSCALL_WRAPPER, so its syscall
+handlers take "unpacked" syscall arguments. Indicate this to libbpf
+using PT_REGS_SYSCALL_REGS macro.
+
+Reported-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Tested-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
+Link: https://lore.kernel.org/bpf/20220209021745.2215452-5-iii@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/bpf_tracing.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
+index e1b505606882..41f5f3149875 100644
+--- a/tools/lib/bpf/bpf_tracing.h
++++ b/tools/lib/bpf/bpf_tracing.h
+@@ -178,6 +178,8 @@
+ #define __PT_RC_REG gpr[3]
+ #define __PT_SP_REG sp
+ #define __PT_IP_REG nip
++/* powerpc does not select ARCH_HAS_SYSCALL_WRAPPER. */
++#define PT_REGS_SYSCALL_REGS(ctx) ctx
+ #elif defined(bpf_target_sparc)
+-- 
+2.35.1
+
diff --git a/queue-5.17/libbpf-fix-accessing-the-first-syscall-argument-on-a.patch b/queue-5.17/libbpf-fix-accessing-the-first-syscall-argument-on-a.patch
new file mode 100644 (file)
index 0000000..68b909c
--- /dev/null
@@ -0,0 +1,53 @@
+From 5fcc9911ce3fd71960896cee8cbeb9f445a4829e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Feb 2022 03:17:44 +0100
+Subject: libbpf: Fix accessing the first syscall argument on arm64
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+[ Upstream commit fbca4a2f649730b67488a8b36140ce4d2cf13c63 ]
+
+On arm64, the first syscall argument should be accessed via orig_x0
+(see arch/arm64/include/asm/syscall.h). Currently regs[0] is used
+instead, leading to bpf_syscall_macro test failure.
+
+orig_x0 cannot be added to struct user_pt_regs, since its layout is a
+part of the ABI. Therefore provide access to it only through
+PT_REGS_PARM1_CORE_SYSCALL() by using a struct pt_regs flavor.
+
+Reported-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20220209021745.2215452-10-iii@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/bpf_tracing.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
+index 41f5f3149875..bed07c35b8de 100644
+--- a/tools/lib/bpf/bpf_tracing.h
++++ b/tools/lib/bpf/bpf_tracing.h
+@@ -140,6 +140,10 @@
+ #elif defined(bpf_target_arm64)
++struct pt_regs___arm64 {
++      unsigned long orig_x0;
++};
++
+ /* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
+ #define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x))
+ #define __PT_PARM1_REG regs[0]
+@@ -152,6 +156,8 @@
+ #define __PT_RC_REG regs[0]
+ #define __PT_SP_REG sp
+ #define __PT_IP_REG pc
++#define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma("GCC error \"use PT_REGS_PARM1_CORE_SYSCALL() instead\""); 0l; })
++#define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ((const struct pt_regs___arm64 *)(x), orig_x0)
+ #elif defined(bpf_target_mips)
+-- 
+2.35.1
+
diff --git a/queue-5.17/libbpf-fix-accessing-the-first-syscall-argument-on-s.patch b/queue-5.17/libbpf-fix-accessing-the-first-syscall-argument-on-s.patch
new file mode 100644 (file)
index 0000000..b8bd3a8
--- /dev/null
@@ -0,0 +1,53 @@
+From e182937f0c52a82922cdd19efa77502e9a8531c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Feb 2022 03:17:45 +0100
+Subject: libbpf: Fix accessing the first syscall argument on s390
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+[ Upstream commit 1f22a6f9f9a0f50218a11a0554709fd34a821fa3 ]
+
+On s390, the first syscall argument should be accessed via orig_gpr2
+(see arch/s390/include/asm/syscall.h). Currently gpr[2] is used
+instead, leading to bpf_syscall_macro test failure.
+
+orig_gpr2 cannot be added to user_pt_regs, since its layout is a part
+of the ABI. Therefore provide access to it only through
+PT_REGS_PARM1_CORE_SYSCALL() by using a struct pt_regs flavor.
+
+Reported-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20220209021745.2215452-11-iii@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/bpf_tracing.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
+index bed07c35b8de..122d79c8f4b4 100644
+--- a/tools/lib/bpf/bpf_tracing.h
++++ b/tools/lib/bpf/bpf_tracing.h
+@@ -112,6 +112,10 @@
+ #elif defined(bpf_target_s390)
++struct pt_regs___s390 {
++      unsigned long orig_gpr2;
++};
++
+ /* s390 provides user_pt_regs instead of struct pt_regs to userspace */
+ #define __PT_REGS_CAST(x) ((const user_pt_regs *)(x))
+ #define __PT_PARM1_REG gprs[2]
+@@ -124,6 +128,8 @@
+ #define __PT_RC_REG gprs[2]
+ #define __PT_SP_REG gprs[15]
+ #define __PT_IP_REG psw.addr
++#define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma("GCC error \"use PT_REGS_PARM1_CORE_SYSCALL() instead\""); 0l; })
++#define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ((const struct pt_regs___s390 *)(x), orig_gpr2)
+ #elif defined(bpf_target_arm)
+-- 
+2.35.1
+
diff --git a/queue-5.17/libbpf-fix-build-issue-with-llvm-readelf.patch b/queue-5.17/libbpf-fix-build-issue-with-llvm-readelf.patch
new file mode 100644 (file)
index 0000000..559f03e
--- /dev/null
@@ -0,0 +1,97 @@
+From 1b06fc0fabca67ecffaac34f099c5f652ebb4b0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 13:43:55 -0800
+Subject: libbpf: Fix build issue with llvm-readelf
+
+From: Yonghong Song <yhs@fb.com>
+
+[ Upstream commit 0908a66ad1124c1634c33847ac662106f7f2c198 ]
+
+There are cases where clang compiler is packaged in a way
+readelf is a symbolic link to llvm-readelf. In such cases,
+llvm-readelf will be used instead of default binutils readelf,
+and the following error will appear during libbpf build:
+
+  Warning: Num of global symbols in
+   /home/yhs/work/bpf-next/tools/testing/selftests/bpf/tools/build/libbpf/sharedobjs/libbpf-in.o (367)
+   does NOT match with num of versioned symbols in
+   /home/yhs/work/bpf-next/tools/testing/selftests/bpf/tools/build/libbpf/libbpf.so libbpf.map (383).
+   Please make sure all LIBBPF_API symbols are versioned in libbpf.map.
+  --- /home/yhs/work/bpf-next/tools/testing/selftests/bpf/tools/build/libbpf/libbpf_global_syms.tmp ...
+  +++ /home/yhs/work/bpf-next/tools/testing/selftests/bpf/tools/build/libbpf/libbpf_versioned_syms.tmp ...
+  @@ -324,6 +324,22 @@
+   btf__str_by_offset
+   btf__type_by_id
+   btf__type_cnt
+  +LIBBPF_0.0.1
+  +LIBBPF_0.0.2
+  +LIBBPF_0.0.3
+  +LIBBPF_0.0.4
+  +LIBBPF_0.0.5
+  +LIBBPF_0.0.6
+  +LIBBPF_0.0.7
+  +LIBBPF_0.0.8
+  +LIBBPF_0.0.9
+  +LIBBPF_0.1.0
+  +LIBBPF_0.2.0
+  +LIBBPF_0.3.0
+  +LIBBPF_0.4.0
+  +LIBBPF_0.5.0
+  +LIBBPF_0.6.0
+  +LIBBPF_0.7.0
+   libbpf_attach_type_by_name
+   libbpf_find_kernel_btf
+   libbpf_find_vmlinux_btf_id
+  make[2]: *** [Makefile:184: check_abi] Error 1
+  make[1]: *** [Makefile:140: all] Error 2
+
+The above failure is due to different printouts for some ABS
+versioned symbols. For example, with the same libbpf.so,
+  $ /bin/readelf --dyn-syms --wide tools/lib/bpf/libbpf.so | grep "LIBBPF" | grep ABS
+     134: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS LIBBPF_0.5.0
+     202: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS LIBBPF_0.6.0
+     ...
+  $ /opt/llvm/bin/readelf --dyn-syms --wide tools/lib/bpf/libbpf.so | grep "LIBBPF" | grep ABS
+     134: 0000000000000000     0 OBJECT  GLOBAL DEFAULT   ABS LIBBPF_0.5.0@@LIBBPF_0.5.0
+     202: 0000000000000000     0 OBJECT  GLOBAL DEFAULT   ABS LIBBPF_0.6.0@@LIBBPF_0.6.0
+     ...
+The binutils readelf doesn't print out the symbol LIBBPF_* version and llvm-readelf does.
+Such a difference caused libbpf build failure with llvm-readelf.
+
+The proposed fix filters out all ABS symbols as they are not part of the comparison.
+This works for both binutils readelf and llvm-readelf.
+
+Reported-by: Delyan Kratunov <delyank@fb.com>
+Signed-off-by: Yonghong Song <yhs@fb.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20220204214355.502108-1-yhs@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/Makefile | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
+index f947b61b2107..b8b37fe76006 100644
+--- a/tools/lib/bpf/Makefile
++++ b/tools/lib/bpf/Makefile
+@@ -131,7 +131,7 @@ GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \
+                          sort -u | wc -l)
+ VERSIONED_SYM_COUNT = $(shell readelf --dyn-syms --wide $(OUTPUT)libbpf.so | \
+                             sed 's/\[.*\]//' | \
+-                            awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}' | \
++                            awk '/GLOBAL/ && /DEFAULT/ && !/UND|ABS/ {print $$NF}' | \
+                             grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l)
+ CMD_TARGETS = $(LIB_TARGET) $(PC_FILE)
+@@ -194,7 +194,7 @@ check_abi: $(OUTPUT)libbpf.so $(VERSION_SCRIPT)
+                   sort -u > $(OUTPUT)libbpf_global_syms.tmp;           \
+               readelf --dyn-syms --wide $(OUTPUT)libbpf.so |           \
+                   sed 's/\[.*\]//' |                                   \
+-                  awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}'|  \
++                  awk '/GLOBAL/ && /DEFAULT/ && !/UND|ABS/ {print $$NF}'|  \
+                   grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 |             \
+                   sort -u > $(OUTPUT)libbpf_versioned_syms.tmp;        \
+               diff -u $(OUTPUT)libbpf_global_syms.tmp                  \
+-- 
+2.35.1
+
diff --git a/queue-5.17/macvtap-advertise-link-netns-via-netlink.patch b/queue-5.17/macvtap-advertise-link-netns-via-netlink.patch
new file mode 100644 (file)
index 0000000..7e8f42b
--- /dev/null
@@ -0,0 +1,68 @@
+From 237eee74fd47141a4f5952e8399d3b864d9c3396 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Feb 2022 01:32:40 +0100
+Subject: macvtap: advertise link netns via netlink
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sven Eckelmann <sven@narfation.org>
+
+[ Upstream commit a02192151b7dbf855084c38dca380d77c7658353 ]
+
+Assign rtnl_link_ops->get_link_net() callback so that IFLA_LINK_NETNSID is
+added to rtnetlink messages. This fixes iproute2 which otherwise resolved
+the link interface to an interface in the wrong namespace.
+
+Test commands:
+
+  ip netns add nst
+  ip link add dummy0 type dummy
+  ip link add link macvtap0 link dummy0 type macvtap
+  ip link set macvtap0 netns nst
+  ip -netns nst link show macvtap0
+
+Before:
+
+  10: macvtap0@gre0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 500
+      link/ether 5e:8f:ae:1d:60:50 brd ff:ff:ff:ff:ff:ff
+
+After:
+
+  10: macvtap0@if2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 500
+      link/ether 5e:8f:ae:1d:60:50 brd ff:ff:ff:ff:ff:ff link-netnsid 0
+
+Reported-by: Leonardo Mörlein <freifunk@irrelefant.net>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Link: https://lore.kernel.org/r/20220228003240.1337426-1-sven@narfation.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvtap.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
+index 6b12902a803f..cecf8c63096c 100644
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -133,11 +133,17 @@ static void macvtap_setup(struct net_device *dev)
+       dev->tx_queue_len = TUN_READQ_SIZE;
+ }
++static struct net *macvtap_link_net(const struct net_device *dev)
++{
++      return dev_net(macvlan_dev_real_dev(dev));
++}
++
+ static struct rtnl_link_ops macvtap_link_ops __read_mostly = {
+       .kind           = "macvtap",
+       .setup          = macvtap_setup,
+       .newlink        = macvtap_newlink,
+       .dellink        = macvtap_dellink,
++      .get_link_net   = macvtap_link_net,
+       .priv_size      = sizeof(struct macvtap_dev),
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.17/mctp-make-__mctp_dev_get-take-a-refcount-hold.patch b/queue-5.17/mctp-make-__mctp_dev_get-take-a-refcount-hold.patch
new file mode 100644 (file)
index 0000000..6568a6c
--- /dev/null
@@ -0,0 +1,139 @@
+From 95f9d44572ce31a7f6be437f4df575e10a66a2a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Feb 2022 12:17:38 +0800
+Subject: mctp: make __mctp_dev_get() take a refcount hold
+
+From: Matt Johnston <matt@codeconstruct.com.au>
+
+[ Upstream commit dc121c0084910db985cf1c8ba6fce5d8c307cc02 ]
+
+Previously there was a race that could allow the mctp_dev refcount
+to hit zero:
+
+rcu_read_lock();
+mdev = __mctp_dev_get(dev);
+// mctp_unregister() happens here, mdev->refs hits zero
+mctp_dev_hold(dev);
+rcu_read_unlock();
+
+Now we make __mctp_dev_get() take the hold itself. It is safe to test
+against the zero refcount because __mctp_dev_get() is called holding
+rcu_read_lock and mctp_dev uses kfree_rcu().
+
+Reported-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mctp/device.c     | 21 ++++++++++++++++++---
+ net/mctp/route.c      |  5 ++++-
+ net/mctp/test/utils.c |  1 -
+ 3 files changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/net/mctp/device.c b/net/mctp/device.c
+index ef2755f82f87..f86ef6d751bd 100644
+--- a/net/mctp/device.c
++++ b/net/mctp/device.c
+@@ -24,12 +24,25 @@ struct mctp_dump_cb {
+       size_t a_idx;
+ };
+-/* unlocked: caller must hold rcu_read_lock */
++/* unlocked: caller must hold rcu_read_lock.
++ * Returned mctp_dev has its refcount incremented, or NULL if unset.
++ */
+ struct mctp_dev *__mctp_dev_get(const struct net_device *dev)
+ {
+-      return rcu_dereference(dev->mctp_ptr);
++      struct mctp_dev *mdev = rcu_dereference(dev->mctp_ptr);
++
++      /* RCU guarantees that any mdev is still live.
++       * Zero refcount implies a pending free, return NULL.
++       */
++      if (mdev)
++              if (!refcount_inc_not_zero(&mdev->refs))
++                      return NULL;
++      return mdev;
+ }
++/* Returned mctp_dev does not have refcount incremented. The returned pointer
++ * remains live while rtnl_lock is held, as that prevents mctp_unregister()
++ */
+ struct mctp_dev *mctp_dev_get_rtnl(const struct net_device *dev)
+ {
+       return rtnl_dereference(dev->mctp_ptr);
+@@ -123,6 +136,7 @@ static int mctp_dump_addrinfo(struct sk_buff *skb, struct netlink_callback *cb)
+                               if (mdev) {
+                                       rc = mctp_dump_dev_addrinfo(mdev,
+                                                                   skb, cb);
++                                      mctp_dev_put(mdev);
+                                       // Error indicates full buffer, this
+                                       // callback will get retried.
+                                       if (rc < 0)
+@@ -297,7 +311,7 @@ void mctp_dev_hold(struct mctp_dev *mdev)
+ void mctp_dev_put(struct mctp_dev *mdev)
+ {
+-      if (refcount_dec_and_test(&mdev->refs)) {
++      if (mdev && refcount_dec_and_test(&mdev->refs)) {
+               dev_put(mdev->dev);
+               kfree_rcu(mdev, rcu);
+       }
+@@ -369,6 +383,7 @@ static size_t mctp_get_link_af_size(const struct net_device *dev,
+       if (!mdev)
+               return 0;
+       ret = nla_total_size(4); /* IFLA_MCTP_NET */
++      mctp_dev_put(mdev);
+       return ret;
+ }
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index e52cef750500..05fbd318eb98 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -786,7 +786,7 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt,
+ {
+       struct mctp_sock *msk = container_of(sk, struct mctp_sock, sk);
+       struct mctp_skb_cb *cb = mctp_cb(skb);
+-      struct mctp_route tmp_rt;
++      struct mctp_route tmp_rt = {0};
+       struct mctp_sk_key *key;
+       struct net_device *dev;
+       struct mctp_hdr *hdr;
+@@ -892,6 +892,7 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt,
+               mctp_route_release(rt);
+       dev_put(dev);
++      mctp_dev_put(tmp_rt.dev);
+       return rc;
+@@ -1057,11 +1058,13 @@ static int mctp_pkttype_receive(struct sk_buff *skb, struct net_device *dev,
+       rt->output(rt, skb);
+       mctp_route_release(rt);
++      mctp_dev_put(mdev);
+       return NET_RX_SUCCESS;
+ err_drop:
+       kfree_skb(skb);
++      mctp_dev_put(mdev);
+       return NET_RX_DROP;
+ }
+diff --git a/net/mctp/test/utils.c b/net/mctp/test/utils.c
+index 7b7918702592..e03ba66bbe18 100644
+--- a/net/mctp/test/utils.c
++++ b/net/mctp/test/utils.c
+@@ -54,7 +54,6 @@ struct mctp_test_dev *mctp_test_create_dev(void)
+       rcu_read_lock();
+       dev->mdev = __mctp_dev_get(ndev);
+-      mctp_dev_hold(dev->mdev);
+       rcu_read_unlock();
+       return dev;
+-- 
+2.35.1
+
diff --git a/queue-5.17/minix-fix-bug-when-opening-a-file-with-o_direct.patch b/queue-5.17/minix-fix-bug-when-opening-a-file-with-o_direct.patch
new file mode 100644 (file)
index 0000000..6486cfd
--- /dev/null
@@ -0,0 +1,48 @@
+From 14158e17aeeeb5435a8ec02328bd49ee1f8f35dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 16:06:23 -0700
+Subject: minix: fix bug when opening a file with O_DIRECT
+
+From: Qinghua Jin <qhjin.dev@gmail.com>
+
+[ Upstream commit 9ce3c0d26c42d279b6c378a03cd6a61d828f19ca ]
+
+Testcase:
+1. create a minix file system and mount it
+2. open a file on the file system with O_RDWR|O_CREAT|O_TRUNC|O_DIRECT
+3. open fails with -EINVAL but leaves an empty file behind. All other
+   open() failures don't leave the failed open files behind.
+
+It is hard to check the direct_IO op before creating the inode.  Just as
+ext4 and btrfs do, this patch will resolve the issue by allowing to
+create the file with O_DIRECT but returning error when writing the file.
+
+Link: https://lkml.kernel.org/r/20220107133626.413379-1-qhjin.dev@gmail.com
+Signed-off-by: Qinghua Jin <qhjin.dev@gmail.com>
+Reported-by: Colin Ian King <colin.king@intel.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/minix/inode.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/minix/inode.c b/fs/minix/inode.c
+index a71f1cf894b9..d4bd94234ef7 100644
+--- a/fs/minix/inode.c
++++ b/fs/minix/inode.c
+@@ -447,7 +447,8 @@ static const struct address_space_operations minix_aops = {
+       .writepage = minix_writepage,
+       .write_begin = minix_write_begin,
+       .write_end = generic_write_end,
+-      .bmap = minix_bmap
++      .bmap = minix_bmap,
++      .direct_IO = noop_direct_IO
+ };
+ static const struct inode_operations minix_symlink_inode_operations = {
+-- 
+2.35.1
+
diff --git a/queue-5.17/mips-fix-fortify-panic-when-copying-asm-exception-ha.patch b/queue-5.17/mips-fix-fortify-panic-when-copying-asm-exception-ha.patch
new file mode 100644 (file)
index 0000000..e83399a
--- /dev/null
@@ -0,0 +1,99 @@
+From d60e7d9719f5aca0e3a7b2c422b49d1f600f7120 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 01:30:23 +0000
+Subject: MIPS: fix fortify panic when copying asm exception handlers
+
+From: Alexander Lobakin <alobakin@pm.me>
+
+[ Upstream commit d17b66417308996e7e64b270a3c7f3c1fbd4cfc8 ]
+
+With KCFLAGS="-O3", I was able to trigger a fortify-source
+memcpy() overflow panic on set_vi_srs_handler().
+Although O3 level is not supported in the mainline, under some
+conditions that may've happened with any optimization settings,
+it's just a matter of inlining luck. The panic itself is correct,
+more precisely, 50/50 false-positive and not at the same time.
+From the one side, no real overflow happens. Exception handler
+defined in asm just gets copied to some reserved places in the
+memory.
+But the reason behind is that C code refers to that exception
+handler declares it as `char`, i.e. something of 1 byte length.
+It's obvious that the asm function itself is way more than 1 byte,
+so fortify logics thought we are going to past the symbol declared.
+The standard way to refer to asm symbols from C code which is not
+supposed to be called from C is to declare them as
+`extern const u8[]`. This is fully correct from any point of view,
+as any code itself is just a bunch of bytes (including 0 as it is
+for syms like _stext/_etext/etc.), and the exact size is not known
+at the moment of compilation.
+Adjust the type of the except_vec_vi_*() and related variables.
+Make set_handler() take `const` as a second argument to avoid
+cast-away warnings and give a little more room for optimization.
+
+Signed-off-by: Alexander Lobakin <alobakin@pm.me>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/include/asm/setup.h |  2 +-
+ arch/mips/kernel/traps.c      | 22 +++++++++++-----------
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h
+index bb36a400203d..8c56b862fd9c 100644
+--- a/arch/mips/include/asm/setup.h
++++ b/arch/mips/include/asm/setup.h
+@@ -16,7 +16,7 @@ static inline void setup_8250_early_printk_port(unsigned long base,
+       unsigned int reg_shift, unsigned int timeout) {}
+ #endif
+-extern void set_handler(unsigned long offset, void *addr, unsigned long len);
++void set_handler(unsigned long offset, const void *addr, unsigned long len);
+ extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
+ typedef void (*vi_handler_t)(void);
+diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
+index a486486b2355..246c6a6b0261 100644
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -2091,19 +2091,19 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
+                * If no shadow set is selected then use the default handler
+                * that does normal register saving and standard interrupt exit
+                */
+-              extern char except_vec_vi, except_vec_vi_lui;
+-              extern char except_vec_vi_ori, except_vec_vi_end;
+-              extern char rollback_except_vec_vi;
+-              char *vec_start = using_rollback_handler() ?
+-                      &rollback_except_vec_vi : &except_vec_vi;
++              extern const u8 except_vec_vi[], except_vec_vi_lui[];
++              extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
++              extern const u8 rollback_except_vec_vi[];
++              const u8 *vec_start = using_rollback_handler() ?
++                                    rollback_except_vec_vi : except_vec_vi;
+ #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
+-              const int lui_offset = &except_vec_vi_lui - vec_start + 2;
+-              const int ori_offset = &except_vec_vi_ori - vec_start + 2;
++              const int lui_offset = except_vec_vi_lui - vec_start + 2;
++              const int ori_offset = except_vec_vi_ori - vec_start + 2;
+ #else
+-              const int lui_offset = &except_vec_vi_lui - vec_start;
+-              const int ori_offset = &except_vec_vi_ori - vec_start;
++              const int lui_offset = except_vec_vi_lui - vec_start;
++              const int ori_offset = except_vec_vi_ori - vec_start;
+ #endif
+-              const int handler_len = &except_vec_vi_end - vec_start;
++              const int handler_len = except_vec_vi_end - vec_start;
+               if (handler_len > VECTORSPACING) {
+                       /*
+@@ -2311,7 +2311,7 @@ void per_cpu_trap_init(bool is_boot_cpu)
+ }
+ /* Install CPU exception handler */
+-void set_handler(unsigned long offset, void *addr, unsigned long size)
++void set_handler(unsigned long offset, const void *addr, unsigned long size)
+ {
+ #ifdef CONFIG_CPU_MICROMIPS
+       memcpy((void *)(ebase + offset), ((unsigned char *)addr - 1), size);
+-- 
+2.35.1
+
diff --git a/queue-5.17/mips-ingenic-correct-unit-node-address.patch b/queue-5.17/mips-ingenic-correct-unit-node-address.patch
new file mode 100644 (file)
index 0000000..5dd7f15
--- /dev/null
@@ -0,0 +1,37 @@
+From 9ffdb0188dc32b1bb8209bc16a19ab8c718c418b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Mar 2022 12:52:59 +0100
+Subject: MIPS: ingenic: correct unit node address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit 8931ddd8d6a55fcefb20f44a38ba42bb746f0b62 ]
+
+Unit node addresses should not have leading 0x:
+
+  Warning (unit_address_format): /nemc@13410000/efuse@d0/eth-mac-addr@0x22: unit name should not have leading "0x"
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Reviewed-by: Paul Cercueil <paul@crapouillou.net>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/boot/dts/ingenic/jz4780.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi
+index 3f9ea47a10cd..b998301f179c 100644
+--- a/arch/mips/boot/dts/ingenic/jz4780.dtsi
++++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi
+@@ -510,7 +510,7 @@
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+-                      eth0_addr: eth-mac-addr@0x22 {
++                      eth0_addr: eth-mac-addr@22 {
+                               reg = <0x22 0x6>;
+                       };
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.17/mips-ralink-fix-a-refcount-leak-in-ill_acc_of_setup.patch b/queue-5.17/mips-ralink-fix-a-refcount-leak-in-ill_acc_of_setup.patch
new file mode 100644 (file)
index 0000000..5c4ea50
--- /dev/null
@@ -0,0 +1,33 @@
+From 9f7210fc8e0ea01e670cf15c62bb378ad0aef061 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Feb 2022 15:35:37 +0800
+Subject: mips: ralink: fix a refcount leak in ill_acc_of_setup()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 4a0a1436053b17e50b7c88858fb0824326641793 ]
+
+of_node_put(np) needs to be called when pdev == NULL.
+
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/ralink/ill_acc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c
+index 115a69fc20ca..f395ae218470 100644
+--- a/arch/mips/ralink/ill_acc.c
++++ b/arch/mips/ralink/ill_acc.c
+@@ -61,6 +61,7 @@ static int __init ill_acc_of_setup(void)
+       pdev = of_find_device_by_node(np);
+       if (!pdev) {
+               pr_err("%pOFn: failed to lookup pdev\n", np);
++              of_node_put(np);
+               return -EINVAL;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.17/mlxsw-spectrum-guard-against-invalid-local-ports.patch b/queue-5.17/mlxsw-spectrum-guard-against-invalid-local-ports.patch
new file mode 100644 (file)
index 0000000..d32b268
--- /dev/null
@@ -0,0 +1,114 @@
+From 29f4cd58c1fa7b564d09bf689cf8942ec8a79cd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 11:02:25 +0200
+Subject: mlxsw: spectrum: Guard against invalid local ports
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit bcdfd615f83b4bd04678109bf18022d1476e4bbf ]
+
+When processing events generated by the device's firmware, the driver
+protects itself from events reported for non-existent local ports, but
+not for the CPU port (local port 0), which exists, but does not have all
+the fields as any local port.
+
+This can result in a NULL pointer dereference when trying access
+'struct mlxsw_sp_port' fields which are not initialized for CPU port.
+
+Commit 63b08b1f6834 ("mlxsw: spectrum: Protect driver from buggy firmware")
+already handled such issue by bailing early when processing a PUDE event
+reported for the CPU port.
+
+Generalize the approach by moving the check to a common function and
+making use of it in all relevant places.
+
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum.c           | 4 +---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum.h           | 7 +++++++
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c       | 3 +--
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 3 +--
+ 4 files changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+index aa411dec62f0..eb1319d63613 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+@@ -2148,13 +2148,11 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
+       struct mlxsw_sp *mlxsw_sp = priv;
+       struct mlxsw_sp_port *mlxsw_sp_port;
+       enum mlxsw_reg_pude_oper_status status;
+-      unsigned int max_ports;
+       u16 local_port;
+-      max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
+       local_port = mlxsw_reg_pude_local_port_get(pude_pl);
+-      if (WARN_ON_ONCE(!local_port || local_port >= max_ports))
++      if (WARN_ON_ONCE(!mlxsw_sp_local_port_is_valid(mlxsw_sp, local_port)))
+               return;
+       mlxsw_sp_port = mlxsw_sp->ports[local_port];
+       if (!mlxsw_sp_port)
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+index bb2442e1f705..30942b6ffcf9 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+@@ -481,6 +481,13 @@ int
+ mlxsw_sp_port_vlan_classification_set(struct mlxsw_sp_port *mlxsw_sp_port,
+                                     bool is_8021ad_tagged,
+                                     bool is_8021q_tagged);
++static inline bool
++mlxsw_sp_local_port_is_valid(struct mlxsw_sp *mlxsw_sp, u16 local_port)
++{
++      unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
++
++      return local_port < max_ports && local_port;
++}
+ /* spectrum_buffers.c */
+ struct mlxsw_sp_hdroom_prio {
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+index 0ff163fbc775..35422e64d89f 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+@@ -568,12 +568,11 @@ void mlxsw_sp1_ptp_got_timestamp(struct mlxsw_sp *mlxsw_sp, bool ingress,
+                                u8 domain_number, u16 sequence_id,
+                                u64 timestamp)
+ {
+-      unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
+       struct mlxsw_sp_port *mlxsw_sp_port;
+       struct mlxsw_sp1_ptp_key key;
+       u8 types;
+-      if (WARN_ON_ONCE(local_port >= max_ports))
++      if (WARN_ON_ONCE(!mlxsw_sp_local_port_is_valid(mlxsw_sp, local_port)))
+               return;
+       mlxsw_sp_port = mlxsw_sp->ports[local_port];
+       if (!mlxsw_sp_port)
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+index 65c1724c63b0..bffdb41fc4ed 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+@@ -2616,7 +2616,6 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
+                                           char *sfn_pl, int rec_index,
+                                           bool adding)
+ {
+-      unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
+       struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
+       struct mlxsw_sp_bridge_device *bridge_device;
+       struct mlxsw_sp_bridge_port *bridge_port;
+@@ -2630,7 +2629,7 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
+       mlxsw_reg_sfn_mac_unpack(sfn_pl, rec_index, mac, &fid, &local_port);
+-      if (WARN_ON_ONCE(local_port >= max_ports))
++      if (WARN_ON_ONCE(!mlxsw_sp_local_port_is_valid(mlxsw_sp, local_port)))
+               return;
+       mlxsw_sp_port = mlxsw_sp->ports[local_port];
+       if (!mlxsw_sp_port) {
+-- 
+2.35.1
+
diff --git a/queue-5.17/mm-fix-race-between-madv_free-reclaim-and-blkdev-dir.patch b/queue-5.17/mm-fix-race-between-madv_free-reclaim-and-blkdev-dir.patch
new file mode 100644 (file)
index 0000000..ef4d2d5
--- /dev/null
@@ -0,0 +1,463 @@
+From 9336510e6d8589d31986ac8591d6a58ac232017b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Apr 2022 16:14:25 -0300
+Subject: mm: fix race between MADV_FREE reclaim and blkdev direct IO read
+
+From: Mauricio Faria de Oliveira <mfo@canonical.com>
+
+commit 6c8e2a256915a223f6289f651d6b926cd7135c9e upstream.
+
+Problem:
+=======
+
+Userspace might read the zero-page instead of actual data from a direct IO
+read on a block device if the buffers have been called madvise(MADV_FREE)
+on earlier (this is discussed below) due to a race between page reclaim on
+MADV_FREE and blkdev direct IO read.
+
+- Race condition:
+  ==============
+
+During page reclaim, the MADV_FREE page check in try_to_unmap_one() checks
+if the page is not dirty, then discards its rmap PTE(s) (vs.  remap back
+if the page is dirty).
+
+However, after try_to_unmap_one() returns to shrink_page_list(), it might
+keep the page _anyway_ if page_ref_freeze() fails (it expects exactly
+_one_ page reference, from the isolation for page reclaim).
+
+Well, blkdev_direct_IO() gets references for all pages, and on READ
+operations it only sets them dirty _later_.
+
+So, if MADV_FREE'd pages (i.e., not dirty) are used as buffers for direct
+IO read from block devices, and page reclaim happens during
+__blkdev_direct_IO[_simple]() exactly AFTER bio_iov_iter_get_pages()
+returns, but BEFORE the pages are set dirty, the situation happens.
+
+The direct IO read eventually completes.  Now, when userspace reads the
+buffers, the PTE is no longer there and the page fault handler
+do_anonymous_page() services that with the zero-page, NOT the data!
+
+A synthetic reproducer is provided.
+
+- Page faults:
+  ===========
+
+If page reclaim happens BEFORE bio_iov_iter_get_pages() the issue doesn't
+happen, because that faults-in all pages as writeable, so
+do_anonymous_page() sets up a new page/rmap/PTE, and that is used by
+direct IO.  The userspace reads don't fault as the PTE is there (thus
+zero-page is not used/setup).
+
+But if page reclaim happens AFTER it / BEFORE setting pages dirty, the PTE
+is no longer there; the subsequent page faults can't help:
+
+The data-read from the block device probably won't generate faults due to
+DMA (no MMU) but even in the case it wouldn't use DMA, that happens on
+different virtual addresses (not user-mapped addresses) because `struct
+bio_vec` stores `struct page` to figure addresses out (which are different
+from user-mapped addresses) for the read.
+
+Thus userspace reads (to user-mapped addresses) still fault, then
+do_anonymous_page() gets another `struct page` that would address/ map to
+other memory than the `struct page` used by `struct bio_vec` for the read.
+(The original `struct page` is not available, since it wasn't freed, as
+page_ref_freeze() failed due to more page refs.  And even if it were
+available, its data cannot be trusted anymore.)
+
+Solution:
+========
+
+One solution is to check for the expected page reference count in
+try_to_unmap_one().
+
+There should be one reference from the isolation (that is also checked in
+shrink_page_list() with page_ref_freeze()) plus one or more references
+from page mapping(s) (put in discard: label).  Further references mean
+that rmap/PTE cannot be unmapped/nuked.
+
+(Note: there might be more than one reference from mapping due to
+fork()/clone() without CLONE_VM, which use the same `struct page` for
+references, until the copy-on-write page gets copied.)
+
+So, additional page references (e.g., from direct IO read) now prevent the
+rmap/PTE from being unmapped/dropped; similarly to the page is not freed
+per shrink_page_list()/page_ref_freeze()).
+
+- Races and Barriers:
+  ==================
+
+The new check in try_to_unmap_one() should be safe in races with
+bio_iov_iter_get_pages() in get_user_pages() fast and slow paths, as it's
+done under the PTE lock.
+
+The fast path doesn't take the lock, but it checks if the PTE has changed
+and if so, it drops the reference and leaves the page for the slow path
+(which does take that lock).
+
+The fast path requires synchronization w/ full memory barrier: it writes
+the page reference count first then it reads the PTE later, while
+try_to_unmap() writes PTE first then it reads page refcount.
+
+And a second barrier is needed, as the page dirty flag should not be read
+before the page reference count (as in __remove_mapping()).  (This can be
+a load memory barrier only; no writes are involved.)
+
+Call stack/comments:
+
+- try_to_unmap_one()
+  - page_vma_mapped_walk()
+    - map_pte()                        # see pte_offset_map_lock():
+        pte_offset_map()
+        spin_lock()
+
+  - ptep_get_and_clear()       # write PTE
+  - smp_mb()                   # (new barrier) GUP fast path
+  - page_ref_count()           # (new check) read refcount
+
+  - page_vma_mapped_walk_done()        # see pte_unmap_unlock():
+      pte_unmap()
+      spin_unlock()
+
+- bio_iov_iter_get_pages()
+  - __bio_iov_iter_get_pages()
+    - iov_iter_get_pages()
+      - get_user_pages_fast()
+        - internal_get_user_pages_fast()
+
+          # fast path
+          - lockless_pages_from_mm()
+            - gup_{pgd,p4d,pud,pmd,pte}_range()
+                ptep = pte_offset_map()                # not _lock()
+                pte = ptep_get_lockless(ptep)
+
+                page = pte_page(pte)
+                try_grab_compound_head(page)   # inc refcount
+                                               # (RMW/barrier
+                                               #  on success)
+
+                if (pte_val(pte) != pte_val(*ptep)) # read PTE
+                        put_compound_head(page) # dec refcount
+                                               # go slow path
+
+          # slow path
+          - __gup_longterm_unlocked()
+            - get_user_pages_unlocked()
+              - __get_user_pages_locked()
+                - __get_user_pages()
+                  - follow_{page,p4d,pud,pmd}_mask()
+                    - follow_page_pte()
+                        ptep = pte_offset_map_lock()
+                        pte = *ptep
+                        page = vm_normal_page(pte)
+                        try_grab_page(page)    # inc refcount
+                        pte_unmap_unlock()
+
+- Huge Pages:
+  ==========
+
+Regarding transparent hugepages, that logic shouldn't change, as MADV_FREE
+(aka lazyfree) pages are PageAnon() && !PageSwapBacked()
+(madvise_free_pte_range() -> mark_page_lazyfree() -> lru_lazyfree_fn())
+thus should reach shrink_page_list() -> split_huge_page_to_list() before
+try_to_unmap[_one](), so it deals with normal pages only.
+
+(And in case unlikely/TTU_SPLIT_HUGE_PMD/split_huge_pmd_address() happens,
+which should not or be rare, the page refcount should be greater than
+mapcount: the head page is referenced by tail pages.  That also prevents
+checking the head `page` then incorrectly call page_remove_rmap(subpage)
+for a tail page, that isn't even in the shrink_page_list()'s page_list (an
+effect of split huge pmd/pmvw), as it might happen today in this unlikely
+scenario.)
+
+MADV_FREE'd buffers:
+===================
+
+So, back to the "if MADV_FREE pages are used as buffers" note.  The case
+is arguable, and subject to multiple interpretations.
+
+The madvise(2) manual page on the MADV_FREE advice value says:
+
+1) 'After a successful MADV_FREE ... data will be lost when
+   the kernel frees the pages.'
+2) 'the free operation will be canceled if the caller writes
+   into the page' / 'subsequent writes ... will succeed and
+   then [the] kernel cannot free those dirtied pages'
+3) 'If there is no subsequent write, the kernel can free the
+   pages at any time.'
+
+Thoughts, questions, considerations... respectively:
+
+1) Since the kernel didn't actually free the page (page_ref_freeze()
+   failed), should the data not have been lost? (on userspace read.)
+2) Should writes performed by the direct IO read be able to cancel
+   the free operation?
+   - Should the direct IO read be considered as 'the caller' too,
+     as it's been requested by 'the caller'?
+   - Should the bio technique to dirty pages on return to userspace
+     (bio_check_pages_dirty() is called/used by __blkdev_direct_IO())
+     be considered in another/special way here?
+3) Should an upcoming write from a previously requested direct IO
+   read be considered as a subsequent write, so the kernel should
+   not free the pages? (as it's known at the time of page reclaim.)
+
+And lastly:
+
+Technically, the last point would seem a reasonable consideration and
+balance, as the madvise(2) manual page apparently (and fairly) seem to
+assume that 'writes' are memory access from the userspace process (not
+explicitly considering writes from the kernel or its corner cases; again,
+fairly)..  plus the kernel fix implementation for the corner case of the
+largely 'non-atomic write' encompassed by a direct IO read operation, is
+relatively simple; and it helps.
+
+Reproducer:
+==========
+
+@ test.c (simplified, but works)
+
+       #define _GNU_SOURCE
+       #include <fcntl.h>
+       #include <stdio.h>
+       #include <unistd.h>
+       #include <sys/mman.h>
+
+       int main() {
+               int fd, i;
+               char *buf;
+
+               fd = open(DEV, O_RDONLY | O_DIRECT);
+
+               buf = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
+                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+               for (i = 0; i < BUF_SIZE; i += PAGE_SIZE)
+                       buf[i] = 1; // init to non-zero
+
+               madvise(buf, BUF_SIZE, MADV_FREE);
+
+               read(fd, buf, BUF_SIZE);
+
+               for (i = 0; i < BUF_SIZE; i += PAGE_SIZE)
+                       printf("%p: 0x%x\n", &buf[i], buf[i]);
+
+               return 0;
+       }
+
+@ block/fops.c (formerly fs/block_dev.c)
+
+       +#include <linux/swap.h>
+       ...
+       ... __blkdev_direct_IO[_simple](...)
+       {
+       ...
+       +       if (!strcmp(current->comm, "good"))
+       +               shrink_all_memory(ULONG_MAX);
+       +
+               ret = bio_iov_iter_get_pages(...);
+       +
+       +       if (!strcmp(current->comm, "bad"))
+       +               shrink_all_memory(ULONG_MAX);
+       ...
+       }
+
+@ shell
+
+        # NUM_PAGES=4
+        # PAGE_SIZE=$(getconf PAGE_SIZE)
+
+        # yes | dd of=test.img bs=${PAGE_SIZE} count=${NUM_PAGES}
+        # DEV=$(losetup -f --show test.img)
+
+        # gcc -DDEV=\"$DEV\" \
+              -DBUF_SIZE=$((PAGE_SIZE * NUM_PAGES)) \
+              -DPAGE_SIZE=${PAGE_SIZE} \
+               test.c -o test
+
+        # od -tx1 $DEV
+        0000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a
+        *
+        0040000
+
+        # mv test good
+        # ./good
+        0x7f7c10418000: 0x79
+        0x7f7c10419000: 0x79
+        0x7f7c1041a000: 0x79
+        0x7f7c1041b000: 0x79
+
+        # mv good bad
+        # ./bad
+        0x7fa1b8050000: 0x0
+        0x7fa1b8051000: 0x0
+        0x7fa1b8052000: 0x0
+        0x7fa1b8053000: 0x0
+
+Note: the issue is consistent on v5.17-rc3, but it's intermittent with the
+support of MADV_FREE on v4.5 (60%-70% error; needs swap).  [wrap
+do_direct_IO() in do_blockdev_direct_IO() @ fs/direct-io.c].
+
+- v5.17-rc3:
+
+        # for i in {1..1000}; do ./good; done \
+            | cut -d: -f2 | sort | uniq -c
+           4000  0x79
+
+        # mv good bad
+        # for i in {1..1000}; do ./bad; done \
+            | cut -d: -f2 | sort | uniq -c
+           4000  0x0
+
+        # free | grep Swap
+        Swap:             0           0           0
+
+- v4.5:
+
+        # for i in {1..1000}; do ./good; done \
+            | cut -d: -f2 | sort | uniq -c
+           4000  0x79
+
+        # mv good bad
+        # for i in {1..1000}; do ./bad; done \
+            | cut -d: -f2 | sort | uniq -c
+           2702  0x0
+           1298  0x79
+
+        # swapoff -av
+        swapoff /swap
+
+        # for i in {1..1000}; do ./bad; done \
+            | cut -d: -f2 | sort | uniq -c
+           4000  0x79
+
+Ceph/TCMalloc:
+=============
+
+For documentation purposes, the use case driving the analysis/fix is Ceph
+on Ubuntu 18.04, as the TCMalloc library there still uses MADV_FREE to
+release unused memory to the system from the mmap'ed page heap (might be
+committed back/used again; it's not munmap'ed.) - PageHeap::DecommitSpan()
+-> TCMalloc_SystemRelease() -> madvise() - PageHeap::CommitSpan() ->
+TCMalloc_SystemCommit() -> do nothing.
+
+Note: TCMalloc switched back to MADV_DONTNEED a few commits after the
+release in Ubuntu 18.04 (google-perftools/gperftools 2.5), so the issue
+just 'disappeared' on Ceph on later Ubuntu releases but is still present
+in the kernel, and can be hit by other use cases.
+
+The observed issue seems to be the old Ceph bug #22464 [1], where checksum
+mismatches are observed (and instrumentation with buffer dumps shows
+zero-pages read from mmap'ed/MADV_FREE'd page ranges).
+
+The issue in Ceph was reasonably deemed a kernel bug (comment #50) and
+mostly worked around with a retry mechanism, but other parts of Ceph could
+still hit that (rocksdb).  Anyway, it's less likely to be hit again as
+TCMalloc switched out of MADV_FREE by default.
+
+(Some kernel versions/reports from the Ceph bug, and relation with
+the MADV_FREE introduction/changes; TCMalloc versions not checked.)
+- 4.4 good
+- 4.5 (madv_free: introduction)
+- 4.9 bad
+- 4.10 good? maybe a swapless system
+- 4.12 (madv_free: no longer free instantly on swapless systems)
+- 4.13 bad
+
+[1] https://tracker.ceph.com/issues/22464
+
+Thanks:
+======
+
+Several people contributed to analysis/discussions/tests/reproducers in
+the first stages when drilling down on ceph/tcmalloc/linux kernel:
+
+- Dan Hill
+- Dan Streetman
+- Dongdong Tao
+- Gavin Guo
+- Gerald Yang
+- Heitor Alves de Siqueira
+- Ioanna Alifieraki
+- Jay Vosburgh
+- Matthew Ruffell
+- Ponnuvel Palaniyappan
+
+Reviews, suggestions, corrections, comments:
+
+- Minchan Kim
+- Yu Zhao
+- Huang, Ying
+- John Hubbard
+- Christoph Hellwig
+
+[mfo@canonical.com: v4]
+  Link: https://lkml.kernel.org/r/20220209202659.183418-1-mfo@canonical.comLink: https://lkml.kernel.org/r/20220131230255.789059-1-mfo@canonical.com
+
+Fixes: 802a3a92ad7a ("mm: reclaim MADV_FREE pages")
+Signed-off-by: Mauricio Faria de Oliveira <mfo@canonical.com>
+Reviewed-by: "Huang, Ying" <ying.huang@intel.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Yu Zhao <yuzhao@google.com>
+Cc: Yang Shi <shy828301@gmail.com>
+Cc: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Dan Hill <daniel.hill@canonical.com>
+Cc: Dan Streetman <dan.streetman@canonical.com>
+Cc: Dongdong Tao <dongdong.tao@canonical.com>
+Cc: Gavin Guo <gavin.guo@canonical.com>
+Cc: Gerald Yang <gerald.yang@canonical.com>
+Cc: Heitor Alves de Siqueira <halves@canonical.com>
+Cc: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
+Cc: Jay Vosburgh <jay.vosburgh@canonical.com>
+Cc: Matthew Ruffell <matthew.ruffell@canonical.com>
+Cc: Ponnuvel Palaniyappan <ponnuvel.palaniyappan@canonical.com>
+Cc: <stable@vger.kernel.org>
+Cc: Christoph Hellwig <hch@infradead.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[mfo: backport: replace folio/test_flag with page/flag equivalents;
+ real Fixes: 854e9ed09ded ("mm: support madvise(MADV_FREE)") in v4.]
+Signed-off-by: Mauricio Faria de Oliveira <mfo@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/rmap.c | 25 ++++++++++++++++++++++++-
+ 1 file changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/mm/rmap.c b/mm/rmap.c
+index 6a1e8c7f6213..9e27f9f038d3 100644
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -1599,7 +1599,30 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
+                       /* MADV_FREE page check */
+                       if (!PageSwapBacked(page)) {
+-                              if (!PageDirty(page)) {
++                              int ref_count, map_count;
++
++                              /*
++                               * Synchronize with gup_pte_range():
++                               * - clear PTE; barrier; read refcount
++                               * - inc refcount; barrier; read PTE
++                               */
++                              smp_mb();
++
++                              ref_count = page_ref_count(page);
++                              map_count = page_mapcount(page);
++
++                              /*
++                               * Order reads for page refcount and dirty flag
++                               * (see comments in __remove_mapping()).
++                               */
++                              smp_rmb();
++
++                              /*
++                               * The only page refs must be one from isolation
++                               * plus the rmap(s) (dropped by discard:).
++                               */
++                              if (ref_count == 1 + map_count &&
++                                  !PageDirty(page)) {
+                                       /* Invalidate as we cleared the pte */
+                                       mmu_notifier_invalidate_range(mm,
+                                               address, address + PAGE_SIZE);
+-- 
+2.35.1
+
diff --git a/queue-5.17/mm-kfence-fix-objcgs-vector-allocation.patch b/queue-5.17/mm-kfence-fix-objcgs-vector-allocation.patch
new file mode 100644 (file)
index 0000000..4eadcd6
--- /dev/null
@@ -0,0 +1,87 @@
+From 306b81e801090b449a5a4ef1b7918f0fdfcfbf07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Apr 2022 11:28:36 -0700
+Subject: mm: kfence: fix objcgs vector allocation
+
+From: Muchun Song <songmuchun@bytedance.com>
+
+[ Upstream commit 8f0b36497303487d5a32c75789c77859cc2ee895 ]
+
+If the kfence object is allocated to be used for objects vector, then
+this slot of the pool eventually being occupied permanently since the
+vector is never freed.  The solutions could be (1) freeing vector when
+the kfence object is freed or (2) allocating all vectors statically.
+
+Since the memory consumption of object vectors is low, it is better to
+chose (2) to fix the issue and it is also can reduce overhead of vectors
+allocating in the future.
+
+Link: https://lkml.kernel.org/r/20220328132843.16624-1-songmuchun@bytedance.com
+Fixes: d3fb45f370d9 ("mm, kfence: insert KFENCE hooks for SLAB")
+Signed-off-by: Muchun Song <songmuchun@bytedance.com>
+Reviewed-by: Marco Elver <elver@google.com>
+Reviewed-by: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Xiongchun Duan <duanxiongchun@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/kfence/core.c   | 11 ++++++++++-
+ mm/kfence/kfence.h |  3 +++
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/mm/kfence/core.c b/mm/kfence/core.c
+index 13128fa13062..d4c7978cd75e 100644
+--- a/mm/kfence/core.c
++++ b/mm/kfence/core.c
+@@ -555,6 +555,8 @@ static bool __init kfence_init_pool(void)
+        * enters __slab_free() slow-path.
+        */
+       for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
++              struct slab *slab = page_slab(&pages[i]);
++
+               if (!i || (i % 2))
+                       continue;
+@@ -562,7 +564,11 @@ static bool __init kfence_init_pool(void)
+               if (WARN_ON(compound_head(&pages[i]) != &pages[i]))
+                       goto err;
+-              __SetPageSlab(&pages[i]);
++              __folio_set_slab(slab_folio(slab));
++#ifdef CONFIG_MEMCG
++              slab->memcg_data = (unsigned long)&kfence_metadata[i / 2 - 1].objcg |
++                                 MEMCG_DATA_OBJCGS;
++#endif
+       }
+       /*
+@@ -938,6 +944,9 @@ void __kfence_free(void *addr)
+ {
+       struct kfence_metadata *meta = addr_to_metadata((unsigned long)addr);
++#ifdef CONFIG_MEMCG
++      KFENCE_WARN_ON(meta->objcg);
++#endif
+       /*
+        * If the objects of the cache are SLAB_TYPESAFE_BY_RCU, defer freeing
+        * the object, as the object page may be recycled for other-typed
+diff --git a/mm/kfence/kfence.h b/mm/kfence/kfence.h
+index 2a2d5de9d379..9a6c4b1b12a8 100644
+--- a/mm/kfence/kfence.h
++++ b/mm/kfence/kfence.h
+@@ -89,6 +89,9 @@ struct kfence_metadata {
+       struct kfence_track free_track;
+       /* For updating alloc_covered on frees. */
+       u32 alloc_stack_hash;
++#ifdef CONFIG_MEMCG
++      struct obj_cgroup *objcg;
++#endif
+ };
+ extern struct kfence_metadata kfence_metadata[CONFIG_KFENCE_NUM_OBJECTS];
+-- 
+2.35.1
+
diff --git a/queue-5.17/mt76-dma-initialize-skip_unmap-in-mt76_dma_rx_fill.patch b/queue-5.17/mt76-dma-initialize-skip_unmap-in-mt76_dma_rx_fill.patch
new file mode 100644 (file)
index 0000000..3de044a
--- /dev/null
@@ -0,0 +1,89 @@
+From 01d100d88e9f8f3f3632d5970f1c38c440324a49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Feb 2022 12:29:55 +0100
+Subject: mt76: dma: initialize skip_unmap in mt76_dma_rx_fill
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 577298ec55dfc8b9aece54520f0258c3f93a6573 ]
+
+Even if it is only a false-positive since skip_buf0/skip_buf1 are only
+used in mt76_dma_tx_cleanup_idx routine, initialize skip_unmap in
+mt76_dma_rx_fill in order to fix the following UBSAN report:
+
+[   13.924906] UBSAN: invalid-load in linux-5.15.0/drivers/net/wireless/mediatek/mt76/dma.c:162:13
+[   13.924909] load of value 225 is not a valid value for type '_Bool'
+[   13.924912] CPU: 9 PID: 672 Comm: systemd-udevd Not tainted 5.15.0-18-generic #18-Ubuntu
+[   13.924914] Hardware name: LENOVO 21A0000CMX/21A0000CMX, BIOS R1MET43W (1.13 ) 11/05/2021
+[   13.924915] Call Trace:
+[   13.924917]  <TASK>
+[   13.924920]  show_stack+0x52/0x58
+[   13.924925]  dump_stack_lvl+0x4a/0x5f
+[   13.924931]  dump_stack+0x10/0x12
+[   13.924932]  ubsan_epilogue+0x9/0x45
+[   13.924934]  __ubsan_handle_load_invalid_value.cold+0x44/0x49
+[   13.924935]  ? __iommu_dma_map+0x84/0xf0
+[   13.924939]  mt76_dma_add_buf.constprop.0.cold+0x23/0x85 [mt76]
+[   13.924949]  mt76_dma_rx_fill.isra.0+0x102/0x1f0 [mt76]
+[   13.924954]  mt76_dma_init+0xc9/0x150 [mt76]
+[   13.924959]  ? mt7921_dma_enable+0x110/0x110 [mt7921e]
+[   13.924966]  mt7921_dma_init+0x1e3/0x260 [mt7921e]
+[   13.924970]  mt7921_register_device+0x29d/0x510 [mt7921e]
+[   13.924975]  mt7921_pci_probe.part.0+0x17f/0x1b0 [mt7921e]
+[   13.924980]  mt7921_pci_probe+0x43/0x60 [mt7921e]
+[   13.924984]  local_pci_probe+0x4b/0x90
+[   13.924987]  pci_device_probe+0x115/0x1f0
+[   13.924989]  really_probe+0x21e/0x420
+[   13.924992]  __driver_probe_device+0x115/0x190
+[   13.924994]  driver_probe_device+0x23/0xc0
+[   13.924996]  __driver_attach+0xbd/0x1d0
+[   13.924998]  ? __device_attach_driver+0x110/0x110
+[   13.924999]  bus_for_each_dev+0x7e/0xc0
+[   13.925001]  driver_attach+0x1e/0x20
+[   13.925003]  bus_add_driver+0x135/0x200
+[   13.925005]  driver_register+0x95/0xf0
+[   13.925008]  ? 0xffffffffc0766000
+[   13.925010]  __pci_register_driver+0x68/0x70
+[   13.925011]  mt7921_pci_driver_init+0x23/0x1000 [mt7921e]
+[   13.925015]  do_one_initcall+0x48/0x1d0
+[   13.925019]  ? kmem_cache_alloc_trace+0x19e/0x2e0
+[   13.925022]  do_init_module+0x62/0x280
+[   13.925025]  load_module+0xac9/0xbb0
+[   13.925027]  __do_sys_finit_module+0xbf/0x120
+[   13.925029]  __x64_sys_finit_module+0x18/0x20
+[   13.925030]  do_syscall_64+0x5c/0xc0
+[   13.925033]  ? do_syscall_64+0x69/0xc0
+[   13.925034]  ? sysvec_reschedule_ipi+0x78/0xe0
+[   13.925036]  ? asm_sysvec_reschedule_ipi+0xa/0x20
+[   13.925039]  entry_SYSCALL_64_after_hwframe+0x44/0xae
+[   13.925040] RIP: 0033:0x7fbf2b90f94d
+[   13.925045] RSP: 002b:00007ffe2ec7e5d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
+[   13.925047] RAX: ffffffffffffffda RBX: 000056106b0634e0 RCX: 00007fbf2b90f94d
+[   13.925048] RDX: 0000000000000000 RSI: 00007fbf2baa3441 RDI: 0000000000000013
+[   13.925049] RBP: 0000000000020000 R08: 0000000000000000 R09: 0000000000000002
+[   13.925050] R10: 0000000000000013 R11: 0000000000000246 R12: 00007fbf2baa3441
+[   13.925051] R13: 000056106b062620 R14: 000056106b0610c0 R15: 000056106b0640d0
+[   13.925053]  </TASK>
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/dma.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
+index 3a9af8931c35..3d644925a4e0 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -465,6 +465,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+               qbuf.addr = addr + offset;
+               qbuf.len = len - offset;
++              qbuf.skip_unmap = false;
+               mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, NULL);
+               frames++;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.17/mt76-fix-monitor-mode-crash-with-sdio-driver.patch b/queue-5.17/mt76-fix-monitor-mode-crash-with-sdio-driver.patch
new file mode 100644 (file)
index 0000000..708531a
--- /dev/null
@@ -0,0 +1,55 @@
+From f932d413f0b5019c4ecacea71c70c9ce7736d73d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 22:54:05 +0800
+Subject: mt76: fix monitor mode crash with sdio driver
+
+From: Deren Wu <deren.wu@mediatek.com>
+
+[ Upstream commit 123bc712b1de0805f9d683687e17b1ec2aba0b68 ]
+
+mt7921s driver may receive frames with fragment buffers. If there is a
+CTS packet received in monitor mode, the payload is 10 bytes only and
+need 6 bytes header padding after RXD buffer. However, only RXD in the
+first linear buffer, if we pull buffer size RXD-size+6 bytes with
+skb_pull(), that would trigger "BUG_ON(skb->len < skb->data_len)" in
+__skb_pull().
+
+To avoid the nonlinear buffer issue, enlarge the RXD size from 128 to
+256 to make sure all MCU operation in linear buffer.
+
+[   52.007562] kernel BUG at include/linux/skbuff.h:2313!
+[   52.007578] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
+[   52.007987] pc : skb_pull+0x48/0x4c
+[   52.008015] lr : mt7921_queue_rx_skb+0x494/0x890 [mt7921_common]
+[   52.008361] Call trace:
+[   52.008377]  skb_pull+0x48/0x4c
+[   52.008400]  mt76s_net_worker+0x134/0x1b0 [mt76_sdio 35339a92c6eb7d4bbcc806a1d22f56365565135c]
+[   52.008431]  __mt76_worker_fn+0xe8/0x170 [mt76 ef716597d11a77150bc07e3fdd68eeb0f9b56917]
+[   52.008449]  kthread+0x148/0x3ac
+[   52.008466]  ret_from_fork+0x10/0x30
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index 1f6f7a44d3f0..5197fcb06649 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -19,7 +19,7 @@
+ #define MT_MCU_RING_SIZE      32
+ #define MT_RX_BUF_SIZE                2048
+-#define MT_SKB_HEAD_LEN               128
++#define MT_SKB_HEAD_LEN               256
+ #define MT_MAX_NON_AQL_PKT    16
+ #define MT_TXQ_FREE_THR               32
+-- 
+2.35.1
+
diff --git a/queue-5.17/mt76-mt7615-fix-assigning-negative-values-to-unsigne.patch b/queue-5.17/mt76-mt7615-fix-assigning-negative-values-to-unsigne.patch
new file mode 100644 (file)
index 0000000..764ce22
--- /dev/null
@@ -0,0 +1,41 @@
+From 54f57798ad4d268a5693d8ff23914b720d77fdb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Feb 2022 09:58:21 +0800
+Subject: mt76: mt7615: Fix assigning negative values to unsigned variable
+
+From: Yang Li <yang.lee@linux.alibaba.com>
+
+[ Upstream commit 9273ffcc9a11942bd586bb42584337ef3962b692 ]
+
+Smatch reports the following:
+drivers/net/wireless/mediatek/mt76/mt7615/mac.c:1865
+mt7615_mac_adjust_sensitivity() warn: assigning (-110) to unsigned
+variable 'def_th'
+drivers/net/wireless/mediatek/mt76/mt7615/mac.c:1865
+mt7615_mac_adjust_sensitivity() warn: assigning (-98) to unsigned
+variable 'def_th'
+
+Reported-by: Abaci Robot <abaci@linux.alibaba.com>
+Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+index ba31bb7caaf9..5d69e77814c9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+@@ -1841,7 +1841,7 @@ mt7615_mac_adjust_sensitivity(struct mt7615_phy *phy,
+       struct mt7615_dev *dev = phy->dev;
+       int false_cca = ofdm ? phy->false_cca_ofdm : phy->false_cca_cck;
+       bool ext_phy = phy != &dev->phy;
+-      u16 def_th = ofdm ? -98 : -110;
++      s16 def_th = ofdm ? -98 : -110;
+       bool update = false;
+       s8 *sensitivity;
+       int signal;
+-- 
+2.35.1
+
diff --git a/queue-5.17/mt76-mt7915-fix-injected-mpdu-transmission-to-not-us.patch b/queue-5.17/mt76-mt7915-fix-injected-mpdu-transmission-to-not-us.patch
new file mode 100644 (file)
index 0000000..96b083b
--- /dev/null
@@ -0,0 +1,48 @@
+From 5b69c7a3466266370d93562daf4bfae7db5d53dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 16:47:30 +0100
+Subject: mt76: mt7915: fix injected MPDU transmission to not use HW A-MSDU
+
+From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
+
+[ Upstream commit 28225a6ef80ebf46c46e5fbd5b1ee231a0b2b5b7 ]
+
+Before, the hardware would be allowed to transmit injected 802.11 MPDUs
+as A-MSDU. This resulted in corrupted frames being transmitted. Now,
+injected MPDUs are transmitted as-is, without A-MSDU.
+
+The fix was verified with frame injection on MT7915 hardware, both with
+and without the injected frame being encrypted.
+
+If the hardware cannot do A-MSDU aggregation on MPDUs, this problem
+would also be present in the TX path where mac80211 does the 802.11
+encapsulation. However, I have not observed any such problem when
+disabling IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD to force that mode.
+Therefore this fix is isolated to injected frames only.
+
+The same A-MSDU logic is also present in the mt7921 driver, so it is
+likely that this fix should be applied there too. I do not have access
+to mt7921 hardware so I have not been able to test that.
+
+Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index db267642924d..e4c300aa1526 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -1085,6 +1085,7 @@ mt7915_mac_write_txwi_80211(struct mt7915_dev *dev, __le32 *txwi,
+               val = MT_TXD3_SN_VALID |
+                     FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
+               txwi[3] |= cpu_to_le32(val);
++              txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU);
+       }
+       val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
+-- 
+2.35.1
+
diff --git a/queue-5.17/mt76-mt7921-fix-crash-when-startup-fails.patch b/queue-5.17/mt76-mt7921-fix-crash-when-startup-fails.patch
new file mode 100644 (file)
index 0000000..705df6c
--- /dev/null
@@ -0,0 +1,41 @@
+From 9a781625870166bef43f5bfd9e63056733b919ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jan 2022 11:08:14 -0800
+Subject: mt76: mt7921: fix crash when startup fails.
+
+From: Ben Greear <greearb@candelatech.com>
+
+[ Upstream commit 827e7799c61b978fbc2cc9dac66cb62401b2b3f0 ]
+
+If the nic fails to start, it is possible that the
+reset_work has already been scheduled.  Ensure the
+work item is canceled so we do not have use-after-free
+crash in case cleanup is called before the work item
+is executed.
+
+This fixes crash on my x86_64 apu2 when mt7921k radio
+fails to work.  Radio still fails, but OS does not
+crash.
+
+Signed-off-by: Ben Greear <greearb@candelatech.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+index 7a8d2596c226..4abb7a6e775a 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -273,6 +273,7 @@ static void mt7921_stop(struct ieee80211_hw *hw)
+       cancel_delayed_work_sync(&dev->pm.ps_work);
+       cancel_work_sync(&dev->pm.wake_work);
++      cancel_work_sync(&dev->reset_work);
+       mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
+       mt7921_mutex_acquire(dev);
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-account-alternate-interface-name-memory.patch b/queue-5.17/net-account-alternate-interface-name-memory.patch
new file mode 100644 (file)
index 0000000..d13d488
--- /dev/null
@@ -0,0 +1,35 @@
+From cdc902a52158442d581d3e774f7e9d01024bab81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Mar 2022 10:29:13 -0800
+Subject: net: account alternate interface name memory
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 5d26cff5bdbebdf98ba48217c078ff102536f134 ]
+
+George reports that altnames can eat up kernel memory.
+We should charge that memory appropriately.
+
+Reported-by: George Shuklin <george.shuklin@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnetlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index 2fb8eb6791e8..9c9ad3d4b766 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -3658,7 +3658,7 @@ static int rtnl_alt_ifname(int cmd, struct net_device *dev, struct nlattr *attr,
+       if (err)
+               return err;
+-      alt_ifname = nla_strdup(attr, GFP_KERNEL);
++      alt_ifname = nla_strdup(attr, GFP_KERNEL_ACCOUNT);
+       if (!alt_ifname)
+               return -ENOMEM;
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-dsa-felix-fix-possible-null-pointer-dereference.patch b/queue-5.17/net-dsa-felix-fix-possible-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..8174521
--- /dev/null
@@ -0,0 +1,42 @@
+From bc2a5dd5a967bcb828e3c1ce4689aff0caa8a3ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Mar 2022 09:08:00 +0000
+Subject: net: dsa: felix: fix possible NULL pointer dereference
+
+From: Zheng Yongjun <zhengyongjun3@huawei.com>
+
+[ Upstream commit 866b7a278cdb51eb158cd8513bc7438fc857804a ]
+
+As the possible failure of the allocation, kzalloc() may return NULL
+pointer.
+Therefore, it should be better to check the 'sgi' in order to prevent
+the dereference of NULL pointer.
+
+Fixes: 23ae3a7877718 ("net: dsa: felix: add stream gate settings for psfp").
+Signed-off-by: Zheng Yongjun <zhengyongjun3@huawei.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://lore.kernel.org/r/20220329090800.130106-1-zhengyongjun3@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/felix_vsc9959.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
+index 33f0ceae381d..2875b5250856 100644
+--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
+@@ -1940,6 +1940,10 @@ static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port,
+               case FLOW_ACTION_GATE:
+                       size = struct_size(sgi, entries, a->gate.num_entries);
+                       sgi = kzalloc(size, GFP_KERNEL);
++                      if (!sgi) {
++                              ret = -ENOMEM;
++                              goto err;
++                      }
+                       vsc9959_psfp_parse_gate(a, sgi);
+                       ret = vsc9959_psfp_sgi_table_add(ocelot, sgi);
+                       if (ret) {
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-initialize-init_net-earlier.patch b/queue-5.17/net-initialize-init_net-earlier.patch
new file mode 100644 (file)
index 0000000..f6b5ab9
--- /dev/null
@@ -0,0 +1,152 @@
+From 61e4536e0b1cc90f5047ab67f483c1c4d9b939fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Feb 2022 09:01:25 -0800
+Subject: net: initialize init_net earlier
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9c1be1935fb68b2413796cdc03d019b8cf35ab51 ]
+
+While testing a patch that will follow later
+("net: add netns refcount tracker to struct nsproxy")
+I found that devtmpfs_init() was called before init_net
+was initialized.
+
+This is a bug, because devtmpfs_setup() calls
+ksys_unshare(CLONE_NEWNS);
+
+This has the effect of increasing init_net refcount,
+which will be later overwritten to 1, as part of setup_net(&init_net)
+
+We had too many prior patches [1] trying to work around the root cause.
+
+Really, make sure init_net is in BSS section, and that net_ns_init()
+is called earlier at boot time.
+
+Note that another patch ("vfs: add netns refcount tracker
+to struct fs_context") also will need net_ns_init() being called
+before vfs_caches_init()
+
+As a bonus, this patch saves around 4KB in .data section.
+
+[1]
+
+f8c46cb39079 ("netns: do not call pernet ops for not yet set up init_net namespace")
+b5082df8019a ("net: Initialise init_net.count to 1")
+734b65417b24 ("net: Statically initialize init_net.dev_base_head")
+
+v2: fixed a build error reported by kernel build bots (CONFIG_NET=n)
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/net_namespace.h |  6 ++++++
+ init/main.c                 |  2 ++
+ net/core/dev.c              |  3 +--
+ net/core/net_namespace.c    | 17 +++++------------
+ 4 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
+index 5b61c462e534..374cc7b260fc 100644
+--- a/include/net/net_namespace.h
++++ b/include/net/net_namespace.h
+@@ -513,4 +513,10 @@ static inline void fnhe_genid_bump(struct net *net)
+       atomic_inc(&net->fnhe_genid);
+ }
++#ifdef CONFIG_NET
++void net_ns_init(void);
++#else
++static inline void net_ns_init(void) {}
++#endif
++
+ #endif /* __NET_NET_NAMESPACE_H */
+diff --git a/init/main.c b/init/main.c
+index 65fa2e41a9c0..ada50f5a15e4 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -99,6 +99,7 @@
+ #include <linux/kcsan.h>
+ #include <linux/init_syscalls.h>
+ #include <linux/stackdepot.h>
++#include <net/net_namespace.h>
+ #include <asm/io.h>
+ #include <asm/bugs.h>
+@@ -1116,6 +1117,7 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
+       key_init();
+       security_init();
+       dbg_late_init();
++      net_ns_init();
+       vfs_caches_init();
+       pagecache_init();
+       signals_init();
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 1baab07820f6..91cf709c98b3 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -10732,8 +10732,7 @@ static int __net_init netdev_init(struct net *net)
+       BUILD_BUG_ON(GRO_HASH_BUCKETS >
+                    8 * sizeof_field(struct napi_struct, gro_bitmask));
+-      if (net != &init_net)
+-              INIT_LIST_HEAD(&net->dev_base_head);
++      INIT_LIST_HEAD(&net->dev_base_head);
+       net->dev_name_head = netdev_create_hash();
+       if (net->dev_name_head == NULL)
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index a5b5bb99c644..212e65add951 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -44,13 +44,7 @@ EXPORT_SYMBOL_GPL(net_rwsem);
+ static struct key_tag init_net_key_domain = { .usage = REFCOUNT_INIT(1) };
+ #endif
+-struct net init_net = {
+-      .ns.count       = REFCOUNT_INIT(1),
+-      .dev_base_head  = LIST_HEAD_INIT(init_net.dev_base_head),
+-#ifdef CONFIG_KEYS
+-      .key_domain     = &init_net_key_domain,
+-#endif
+-};
++struct net init_net;
+ EXPORT_SYMBOL(init_net);
+ static bool init_net_initialized;
+@@ -1084,7 +1078,7 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
+       rtnl_set_sk_err(net, RTNLGRP_NSID, err);
+ }
+-static int __init net_ns_init(void)
++void __init net_ns_init(void)
+ {
+       struct net_generic *ng;
+@@ -1105,6 +1099,9 @@ static int __init net_ns_init(void)
+       rcu_assign_pointer(init_net.gen, ng);
++#ifdef CONFIG_KEYS
++      init_net.key_domain = &init_net_key_domain;
++#endif
+       down_write(&pernet_ops_rwsem);
+       if (setup_net(&init_net, &init_user_ns))
+               panic("Could not setup the initial network namespace");
+@@ -1119,12 +1116,8 @@ static int __init net_ns_init(void)
+                     RTNL_FLAG_DOIT_UNLOCKED);
+       rtnl_register(PF_UNSPEC, RTM_GETNSID, rtnl_net_getid, rtnl_net_dumpid,
+                     RTNL_FLAG_DOIT_UNLOCKED);
+-
+-      return 0;
+ }
+-pure_initcall(net_ns_init);
+-
+ static void free_exit_list(struct pernet_operations *ops, struct list_head *net_exit_list)
+ {
+       ops_pre_exit_list(ops, net_exit_list);
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-limit-altnames-to-64k-total.patch b/queue-5.17/net-limit-altnames-to-64k-total.patch
new file mode 100644 (file)
index 0000000..29984ce
--- /dev/null
@@ -0,0 +1,57 @@
+From 1b2dcd2ee90eaeb13adf9432f39c8ad91c023f35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Mar 2022 10:29:14 -0800
+Subject: net: limit altnames to 64k total
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 155fb43b70b5fce341347a77d1af2765d1e8fbb8 ]
+
+Property list (altname is a link "property") is wrapped
+in a nlattr. nlattrs length is 16bit so practically
+speaking the list of properties can't be longer than
+that, otherwise user space would have to interpret
+broken netlink messages.
+
+Prevent the problem from occurring by checking the length
+of the property list before adding new entries.
+
+Reported-by: George Shuklin <george.shuklin@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnetlink.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index 9c9ad3d4b766..43b995e935cd 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -3652,12 +3652,23 @@ static int rtnl_alt_ifname(int cmd, struct net_device *dev, struct nlattr *attr,
+                          bool *changed, struct netlink_ext_ack *extack)
+ {
+       char *alt_ifname;
++      size_t size;
+       int err;
+       err = nla_validate(attr, attr->nla_len, IFLA_MAX, ifla_policy, extack);
+       if (err)
+               return err;
++      if (cmd == RTM_NEWLINKPROP) {
++              size = rtnl_prop_list_size(dev);
++              size += nla_total_size(ALTIFNAMSIZ);
++              if (size >= U16_MAX) {
++                      NL_SET_ERR_MSG(extack,
++                                     "effective property list too long");
++                      return -EINVAL;
++              }
++      }
++
+       alt_ifname = nla_strdup(attr, GFP_KERNEL_ACCOUNT);
+       if (!alt_ifname)
+               return -ENOMEM;
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-mlx5e-disable-tx-queues-before-registering-the-n.patch b/queue-5.17/net-mlx5e-disable-tx-queues-before-registering-the-n.patch
new file mode 100644 (file)
index 0000000..b6fb6f2
--- /dev/null
@@ -0,0 +1,38 @@
+From fc30fe17650fba1126e9c7e8b07befde6281a4ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 12:52:48 +0200
+Subject: net/mlx5e: Disable TX queues before registering the netdev
+
+From: Maxim Mikityanskiy <maximmi@nvidia.com>
+
+[ Upstream commit d08c6e2a4d0308a7922d7ef3b1b3af45d4096aad ]
+
+Normally, the queues are disabled when the channels are deactivated, and
+enabled when the channels are activated. However, on register, the
+channels are not active, but the queues are enabled by default. This
+change fixes it, preventing mlx5e_xmit from running when the channels
+are deactivated in the beginning.
+
+Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 3667f5ef5990..169e3524bb1c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -5345,6 +5345,7 @@ mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *prof
+       }
+       netif_carrier_off(netdev);
++      netif_tx_disable(netdev);
+       dev_net_set(netdev, mlx5_core_net(mdev));
+       return netdev;
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-mlx5e-remove-overzealous-validations-in-netlink-.patch b/queue-5.17/net-mlx5e-remove-overzealous-validations-in-netlink-.patch
new file mode 100644 (file)
index 0000000..6a30266
--- /dev/null
@@ -0,0 +1,68 @@
+From e09fa5db0ec98a3932bdfba584f83ed14e71d87f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 16:28:23 +0200
+Subject: net/mlx5e: Remove overzealous validations in netlink EEPROM query
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 970adfb76095fa719778d70a6b86030d2feb88dd ]
+
+Unlike the legacy EEPROM callbacks, when using the netlink EEPROM query
+(get_module_eeprom_by_page) the driver should not try to validate the
+query parameters, but just perform the read requested by the userspace.
+
+Recent discussion in the mailing list:
+https://lore.kernel.org/netdev/20220120093051.70845141@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net/
+
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/port.c    | 23 -------------------
+ 1 file changed, 23 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
+index 7b16a1188aab..fd79860de723 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
+@@ -433,35 +433,12 @@ int mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev,
+                                    struct mlx5_module_eeprom_query_params *params,
+                                    u8 *data)
+ {
+-      u8 module_id;
+       int err;
+       err = mlx5_query_module_num(dev, &params->module_number);
+       if (err)
+               return err;
+-      err = mlx5_query_module_id(dev, params->module_number, &module_id);
+-      if (err)
+-              return err;
+-
+-      switch (module_id) {
+-      case MLX5_MODULE_ID_SFP:
+-              if (params->page > 0)
+-                      return -EINVAL;
+-              break;
+-      case MLX5_MODULE_ID_QSFP:
+-      case MLX5_MODULE_ID_QSFP28:
+-      case MLX5_MODULE_ID_QSFP_PLUS:
+-              if (params->page > 3)
+-                      return -EINVAL;
+-              break;
+-      case MLX5_MODULE_ID_DSFP:
+-              break;
+-      default:
+-              mlx5_core_err(dev, "Module ID not recognized: 0x%x\n", module_id);
+-              return -EINVAL;
+-      }
+-
+       if (params->i2c_address != MLX5_I2C_ADDR_HIGH &&
+           params->i2c_address != MLX5_I2C_ADDR_LOW) {
+               mlx5_core_err(dev, "I2C address not recognized: 0x%x\n", params->i2c_address);
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-mlx5e-tc-hold-sample_attr-on-stack-instead-of-po.patch b/queue-5.17/net-mlx5e-tc-hold-sample_attr-on-stack-instead-of-po.patch
new file mode 100644 (file)
index 0000000..1380632
--- /dev/null
@@ -0,0 +1,156 @@
+From a50c83f7f16bdd1faf5192ce7f2879f27627cbbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Dec 2021 15:10:35 +0200
+Subject: net/mlx5e: TC, Hold sample_attr on stack instead of pointer
+
+From: Roi Dayan <roid@nvidia.com>
+
+[ Upstream commit eeed226ed110ed40598e60e29b66643012277be7 ]
+
+In later commit we are going to instantiate multiple attr instances
+for flow instead of single attr.
+Parsing TC sample allocates a new memory but there is no symmetric
+cleanup in the infrastructure.
+To avoid asymmetric alloc/free use sample_attr as part of the flow attr
+and not allocated and held as a pointer.
+This will avoid a cleanup leak when sample action is not on the first
+attr.
+
+Signed-off-by: Roi Dayan <roid@nvidia.com>
+Reviewed-by: Oz Shlomo <ozsh@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en/tc/act/sample.c |  7 +------
+ drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c | 10 +++++-----
+ drivers/net/ethernet/mellanox/mlx5/core/en_tc.c        |  1 -
+ drivers/net/ethernet/mellanox/mlx5/core/en_tc.h        |  2 +-
+ .../net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |  6 +++---
+ 5 files changed, 10 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/sample.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/sample.c
+index 6699bdf5cf01..b895c378cfaf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/sample.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/sample.c
+@@ -27,11 +27,7 @@ tc_act_parse_sample(struct mlx5e_tc_act_parse_state *parse_state,
+                   struct mlx5e_priv *priv,
+                   struct mlx5_flow_attr *attr)
+ {
+-      struct mlx5e_sample_attr *sample_attr;
+-
+-      sample_attr = kzalloc(sizeof(*attr->sample_attr), GFP_KERNEL);
+-      if (!sample_attr)
+-              return -ENOMEM;
++      struct mlx5e_sample_attr *sample_attr = &attr->sample_attr;
+       sample_attr->rate = act->sample.rate;
+       sample_attr->group_num = act->sample.psample_group->group_num;
+@@ -39,7 +35,6 @@ tc_act_parse_sample(struct mlx5e_tc_act_parse_state *parse_state,
+       if (act->sample.truncate)
+               sample_attr->trunc_size = act->sample.trunc_size;
+-      attr->sample_attr = sample_attr;
+       flow_flag_set(parse_state->flow, SAMPLE);
+       return 0;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
+index ff4b4f8a5a9d..0faaf9a4b531 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
+@@ -513,7 +513,7 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample,
+       sample_flow = kzalloc(sizeof(*sample_flow), GFP_KERNEL);
+       if (!sample_flow)
+               return ERR_PTR(-ENOMEM);
+-      sample_attr = attr->sample_attr;
++      sample_attr = &attr->sample_attr;
+       sample_attr->sample_flow = sample_flow;
+       /* For NICs with reg_c_preserve support or decap action, use
+@@ -546,6 +546,7 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample,
+               err = PTR_ERR(sample_flow->sampler);
+               goto err_sampler;
+       }
++      sample_attr->sampler_id = sample_flow->sampler->sampler_id;
+       /* Create an id mapping reg_c0 value to sample object. */
+       restore_obj.type = MLX5_MAPPED_OBJ_SAMPLE;
+@@ -585,8 +586,7 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample,
+       pre_attr->outer_match_level = attr->outer_match_level;
+       pre_attr->chain = attr->chain;
+       pre_attr->prio = attr->prio;
+-      pre_attr->sample_attr = attr->sample_attr;
+-      sample_attr->sampler_id = sample_flow->sampler->sampler_id;
++      pre_attr->sample_attr = *sample_attr;
+       pre_esw_attr = pre_attr->esw_attr;
+       pre_esw_attr->in_mdev = esw_attr->in_mdev;
+       pre_esw_attr->in_rep = esw_attr->in_rep;
+@@ -633,11 +633,11 @@ mlx5e_tc_sample_unoffload(struct mlx5e_tc_psample *tc_psample,
+        * will hit fw syndromes.
+        */
+       esw = tc_psample->esw;
+-      sample_flow = attr->sample_attr->sample_flow;
++      sample_flow = attr->sample_attr.sample_flow;
+       mlx5_eswitch_del_offloaded_rule(esw, sample_flow->pre_rule, sample_flow->pre_attr);
+       sample_restore_put(tc_psample, sample_flow->restore);
+-      mapping_remove(esw->offloads.reg_c0_obj_pool, attr->sample_attr->restore_obj_id);
++      mapping_remove(esw->offloads.reg_c0_obj_pool, attr->sample_attr.restore_obj_id);
+       sampler_put(tc_psample, sample_flow->sampler);
+       if (sample_flow->post_act_handle)
+               mlx5e_tc_post_act_del(tc_psample->post_act, sample_flow->post_act_handle);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index b27532a9301e..7e5c00349ccf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -1634,7 +1634,6 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
+       if (flow_flag_test(flow, L3_TO_L2_DECAP))
+               mlx5e_detach_decap(priv, flow);
+-      kfree(attr->sample_attr);
+       kvfree(attr->esw_attr->rx_tun_attr);
+       kvfree(attr->parse_attr);
+       kfree(flow->attr);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+index 5ffae9b13066..2f09e34db9ff 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+@@ -71,7 +71,7 @@ struct mlx5_flow_attr {
+       struct mlx5_fc *counter;
+       struct mlx5_modify_hdr *modify_hdr;
+       struct mlx5_ct_attr ct_attr;
+-      struct mlx5e_sample_attr *sample_attr;
++      struct mlx5e_sample_attr sample_attr;
+       struct mlx5e_tc_flow_parse_attr *parse_attr;
+       u32 chain;
+       u16 prio;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index cfcd72bad9af..e7e7b4b0dcdb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -201,12 +201,12 @@ esw_cleanup_decap_indir(struct mlx5_eswitch *esw,
+ static int
+ esw_setup_sampler_dest(struct mlx5_flow_destination *dest,
+                      struct mlx5_flow_act *flow_act,
+-                     struct mlx5_flow_attr *attr,
++                     u32 sampler_id,
+                      int i)
+ {
+       flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
+       dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER;
+-      dest[i].sampler_id = attr->sample_attr->sampler_id;
++      dest[i].sampler_id = sampler_id;
+       return 0;
+ }
+@@ -466,7 +466,7 @@ esw_setup_dests(struct mlx5_flow_destination *dest,
+               attr->flags |= MLX5_ESW_ATTR_FLAG_SRC_REWRITE;
+       if (attr->flags & MLX5_ESW_ATTR_FLAG_SAMPLE) {
+-              esw_setup_sampler_dest(dest, flow_act, attr, *i);
++              esw_setup_sampler_dest(dest, flow_act, attr->sample_attr.sampler_id, *i);
+               (*i)++;
+       } else if (attr->dest_ft) {
+               esw_setup_ft_dest(dest, flow_act, esw, attr, spec, *i);
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-sfp-add-2500base-x-quirk-for-lantech-sfp-module.patch b/queue-5.17/net-sfp-add-2500base-x-quirk-for-lantech-sfp-module.patch
new file mode 100644 (file)
index 0000000..5f05a3d
--- /dev/null
@@ -0,0 +1,53 @@
+From c49dbe29501f6d4aa321baea4d80efffb92d4ec4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Mar 2022 21:50:14 +0100
+Subject: net: sfp: add 2500base-X quirk for Lantech SFP module
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit 00eec9fe4f3b9588b4bfa8ef9dd0aae96407d5d7 ]
+
+The Lantech 8330-262D-E module is 2500base-X capable, but it reports the
+nominal bitrate as 2500MBd instead of 3125MBd. Add a quirk for the
+module.
+
+The following in an EEPROM dump of such a SFP with the serial number
+redacted:
+
+00: 03 04 07 00 00 00 01 20 40 0c 05 01 19 00 00 00    ???...? @????...
+10: 1e 0f 00 00 4c 61 6e 74 65 63 68 20 20 20 20 20    ??..Lantech
+20: 20 20 20 20 00 00 00 00 38 33 33 30 2d 32 36 32        ....8330-262
+30: 44 2d 45 20 20 20 20 20 56 31 2e 30 03 52 00 cb    D-E     V1.0?R.?
+40: 00 1a 00 00 46 43 XX XX XX XX XX XX XX XX XX XX    .?..FCXXXXXXXXXX
+50: 20 20 20 20 32 32 30 32 31 34 20 20 68 b0 01 98        220214  h???
+60: 45 58 54 52 45 4d 45 4c 59 20 43 4f 4d 50 41 54    EXTREMELY COMPAT
+70: 49 42 4c 45 20 20 20 20 20 20 20 20 20 20 20 20    IBLE
+
+Signed-off-by: Michael Walle <michael@walle.cc>
+Link: https://lore.kernel.org/r/20220312205014.4154907-1-michael@walle.cc
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/sfp-bus.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
+index c1512c9925a6..15aa5ac1ff49 100644
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -74,6 +74,12 @@ static const struct sfp_quirk sfp_quirks[] = {
+               .vendor = "HUAWEI",
+               .part = "MA5671A",
+               .modes = sfp_quirk_2500basex,
++      }, {
++              // Lantech 8330-262D-E can operate at 2500base-X, but
++              // incorrectly report 2500MBd NRZ in their EEPROM
++              .vendor = "Lantech",
++              .part = "8330-262D-E",
++              .modes = sfp_quirk_2500basex,
+       }, {
+               .vendor = "UBNT",
+               .part = "UF-INSTANT",
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-smc-correct-settings-of-rmb-window-update-limit.patch b/queue-5.17/net-smc-correct-settings-of-rmb-window-update-limit.patch
new file mode 100644 (file)
index 0000000..93c5e6e
--- /dev/null
@@ -0,0 +1,52 @@
+From 65c81abded7584b06402efa0e25af9778ed02182 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Mar 2022 17:44:00 +0800
+Subject: net/smc: correct settings of RMB window update limit
+
+From: Dust Li <dust.li@linux.alibaba.com>
+
+[ Upstream commit 6bf536eb5c8ca011d1ff57b5c5f7c57ceac06a37 ]
+
+rmbe_update_limit is used to limit announcing receive
+window updating too frequently. RFC7609 request a minimal
+increase in the window size of 10% of the receive buffer
+space. But current implementation used:
+
+  min_t(int, rmbe_size / 10, SOCK_MIN_SNDBUF / 2)
+
+and SOCK_MIN_SNDBUF / 2 == 2304 Bytes, which is almost
+always less then 10% of the receive buffer space.
+
+This causes the receiver always sending CDC message to
+update its consumer cursor when it consumes more then 2K
+of data. And as a result, we may encounter something like
+"TCP silly window syndrome" when sending 2.5~8K message.
+
+This patch fixes this using max(rmbe_size / 10, SOCK_MIN_SNDBUF / 2).
+
+With this patch and SMC autocorking enabled, qperf 2K/4K/8K
+tcp_bw test shows 45%/75%/40% increase in throughput respectively.
+
+Signed-off-by: Dust Li <dust.li@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/smc_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
+index be7d704976ff..f40f6ed0fbdb 100644
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -1989,7 +1989,7 @@ static struct smc_buf_desc *smc_buf_get_slot(int compressed_bufsize,
+  */
+ static inline int smc_rmb_wnd_update_limit(int rmbe_size)
+ {
+-      return min_t(int, rmbe_size / 10, SOCK_MIN_SNDBUF / 2);
++      return max_t(int, rmbe_size / 10, SOCK_MIN_SNDBUF / 2);
+ }
+ /* map an rmb buf to a link */
+-- 
+2.35.1
+
diff --git a/queue-5.17/net-smc-send-directly-when-tcp_cork-is-cleared.patch b/queue-5.17/net-smc-send-directly-when-tcp_cork-is-cleared.patch
new file mode 100644 (file)
index 0000000..9bd9da3
--- /dev/null
@@ -0,0 +1,111 @@
+From db782a142b7f4bb625fba0d26a7028ffa16225b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jan 2022 02:02:55 +0800
+Subject: net/smc: Send directly when TCP_CORK is cleared
+
+From: Tony Lu <tonylu@linux.alibaba.com>
+
+[ Upstream commit ea785a1a573b390a150010b3c5b81e1ccd8c98a8 ]
+
+According to the man page of TCP_CORK [1], if set, don't send out
+partial frames. All queued partial frames are sent when option is
+cleared again.
+
+When applications call setsockopt to disable TCP_CORK, this call is
+protected by lock_sock(), and tries to mod_delayed_work() to 0, in order
+to send pending data right now. However, the delayed work smc_tx_work is
+also protected by lock_sock(). There introduces lock contention for
+sending data.
+
+To fix it, send pending data directly which acts like TCP, without
+lock_sock() protected in the context of setsockopt (already lock_sock()ed),
+and cancel unnecessary dealyed work, which is protected by lock.
+
+[1] https://linux.die.net/man/7/tcp
+
+Signed-off-by: Tony Lu <tonylu@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c |  4 ++--
+ net/smc/smc_tx.c | 25 +++++++++++++++----------
+ net/smc/smc_tx.h |  1 +
+ 3 files changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 284befa90967..67fc72047c9c 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -2636,8 +2636,8 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
+                   sk->sk_state != SMC_CLOSED) {
+                       if (!val) {
+                               SMC_STAT_INC(smc, cork_cnt);
+-                              mod_delayed_work(smc->conn.lgr->tx_wq,
+-                                               &smc->conn.tx_work, 0);
++                              smc_tx_pending(&smc->conn);
++                              cancel_delayed_work(&smc->conn.tx_work);
+                       }
+               }
+               break;
+diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
+index be241d53020f..7b0b6e24582f 100644
+--- a/net/smc/smc_tx.c
++++ b/net/smc/smc_tx.c
+@@ -597,27 +597,32 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
+       return rc;
+ }
+-/* Wakeup sndbuf consumers from process context
+- * since there is more data to transmit
+- */
+-void smc_tx_work(struct work_struct *work)
++void smc_tx_pending(struct smc_connection *conn)
+ {
+-      struct smc_connection *conn = container_of(to_delayed_work(work),
+-                                                 struct smc_connection,
+-                                                 tx_work);
+       struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
+       int rc;
+-      lock_sock(&smc->sk);
+       if (smc->sk.sk_err)
+-              goto out;
++              return;
+       rc = smc_tx_sndbuf_nonempty(conn);
+       if (!rc && conn->local_rx_ctrl.prod_flags.write_blocked &&
+           !atomic_read(&conn->bytes_to_rcv))
+               conn->local_rx_ctrl.prod_flags.write_blocked = 0;
++}
++
++/* Wakeup sndbuf consumers from process context
++ * since there is more data to transmit
++ */
++void smc_tx_work(struct work_struct *work)
++{
++      struct smc_connection *conn = container_of(to_delayed_work(work),
++                                                 struct smc_connection,
++                                                 tx_work);
++      struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
+-out:
++      lock_sock(&smc->sk);
++      smc_tx_pending(conn);
+       release_sock(&smc->sk);
+ }
+diff --git a/net/smc/smc_tx.h b/net/smc/smc_tx.h
+index 07e6ad76224a..a59f370b8b43 100644
+--- a/net/smc/smc_tx.h
++++ b/net/smc/smc_tx.h
+@@ -27,6 +27,7 @@ static inline int smc_tx_prepared_sends(struct smc_connection *conn)
+       return smc_curs_diff(conn->sndbuf_desc->len, &sent, &prep);
+ }
++void smc_tx_pending(struct smc_connection *conn);
+ void smc_tx_work(struct work_struct *work);
+ void smc_tx_init(struct smc_sock *smc);
+ int smc_tx_sendmsg(struct smc_sock *smc, struct msghdr *msg, size_t len);
+-- 
+2.35.1
+
diff --git a/queue-5.17/netfilter-conntrack-revisit-gc-autotuning.patch b/queue-5.17/netfilter-conntrack-revisit-gc-autotuning.patch
new file mode 100644 (file)
index 0000000..00de6b7
--- /dev/null
@@ -0,0 +1,208 @@
+From 3f8d34ec4e75c83ad4f9d0daeeae49674f4b7f40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Feb 2022 16:43:05 +0100
+Subject: netfilter: conntrack: revisit gc autotuning
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 2cfadb761d3d0219412fd8150faea60c7e863833 ]
+
+as of commit 4608fdfc07e1
+("netfilter: conntrack: collect all entries in one cycle")
+conntrack gc was changed to run every 2 minutes.
+
+On systems where conntrack hash table is set to large value, most evictions
+happen from gc worker rather than the packet path due to hash table
+distribution.
+
+This causes netlink event overflows when events are collected.
+
+This change collects average expiry of scanned entries and
+reschedules to the average remaining value, within 1 to 60 second interval.
+
+To avoid event overflows, reschedule after each bucket and add a
+limit for both run time and number of evictions per run.
+
+If more entries have to be evicted, reschedule and restart 1 jiffy
+into the future.
+
+Reported-by: Karel Rericha <karel@maxtel.cz>
+Cc: Shmulik Ladkani <shmulik.ladkani@gmail.com>
+Cc: Eyal Birger <eyal.birger@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_core.c | 85 ++++++++++++++++++++++++-------
+ 1 file changed, 68 insertions(+), 17 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index bf1e17c678f1..7552e1e9fd62 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -67,6 +67,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_hash);
+ struct conntrack_gc_work {
+       struct delayed_work     dwork;
+       u32                     next_bucket;
++      u32                     avg_timeout;
++      u32                     start_time;
+       bool                    exiting;
+       bool                    early_drop;
+ };
+@@ -78,8 +80,19 @@ static __read_mostly bool nf_conntrack_locks_all;
+ /* serialize hash resizes and nf_ct_iterate_cleanup */
+ static DEFINE_MUTEX(nf_conntrack_mutex);
+-#define GC_SCAN_INTERVAL      (120u * HZ)
++#define GC_SCAN_INTERVAL_MAX  (60ul * HZ)
++#define GC_SCAN_INTERVAL_MIN  (1ul * HZ)
++
++/* clamp timeouts to this value (TCP unacked) */
++#define GC_SCAN_INTERVAL_CLAMP        (300ul * HZ)
++
++/* large initial bias so that we don't scan often just because we have
++ * three entries with a 1s timeout.
++ */
++#define GC_SCAN_INTERVAL_INIT INT_MAX
++
+ #define GC_SCAN_MAX_DURATION  msecs_to_jiffies(10)
++#define GC_SCAN_EXPIRED_MAX   (64000u / HZ)
+ #define MIN_CHAINLEN  8u
+ #define MAX_CHAINLEN  (32u - MIN_CHAINLEN)
+@@ -1421,16 +1434,28 @@ static bool gc_worker_can_early_drop(const struct nf_conn *ct)
+ static void gc_worker(struct work_struct *work)
+ {
+-      unsigned long end_time = jiffies + GC_SCAN_MAX_DURATION;
+       unsigned int i, hashsz, nf_conntrack_max95 = 0;
+-      unsigned long next_run = GC_SCAN_INTERVAL;
++      u32 end_time, start_time = nfct_time_stamp;
+       struct conntrack_gc_work *gc_work;
++      unsigned int expired_count = 0;
++      unsigned long next_run;
++      s32 delta_time;
++
+       gc_work = container_of(work, struct conntrack_gc_work, dwork.work);
+       i = gc_work->next_bucket;
+       if (gc_work->early_drop)
+               nf_conntrack_max95 = nf_conntrack_max / 100u * 95u;
++      if (i == 0) {
++              gc_work->avg_timeout = GC_SCAN_INTERVAL_INIT;
++              gc_work->start_time = start_time;
++      }
++
++      next_run = gc_work->avg_timeout;
++
++      end_time = start_time + GC_SCAN_MAX_DURATION;
++
+       do {
+               struct nf_conntrack_tuple_hash *h;
+               struct hlist_nulls_head *ct_hash;
+@@ -1447,6 +1472,7 @@ static void gc_worker(struct work_struct *work)
+               hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[i], hnnode) {
+                       struct nf_conntrack_net *cnet;
++                      unsigned long expires;
+                       struct net *net;
+                       tmp = nf_ct_tuplehash_to_ctrack(h);
+@@ -1456,11 +1482,29 @@ static void gc_worker(struct work_struct *work)
+                               continue;
+                       }
++                      if (expired_count > GC_SCAN_EXPIRED_MAX) {
++                              rcu_read_unlock();
++
++                              gc_work->next_bucket = i;
++                              gc_work->avg_timeout = next_run;
++
++                              delta_time = nfct_time_stamp - gc_work->start_time;
++
++                              /* re-sched immediately if total cycle time is exceeded */
++                              next_run = delta_time < (s32)GC_SCAN_INTERVAL_MAX;
++                              goto early_exit;
++                      }
++
+                       if (nf_ct_is_expired(tmp)) {
+                               nf_ct_gc_expired(tmp);
++                              expired_count++;
+                               continue;
+                       }
++                      expires = clamp(nf_ct_expires(tmp), GC_SCAN_INTERVAL_MIN, GC_SCAN_INTERVAL_CLAMP);
++                      next_run += expires;
++                      next_run /= 2u;
++
+                       if (nf_conntrack_max95 == 0 || gc_worker_skip_ct(tmp))
+                               continue;
+@@ -1478,8 +1522,10 @@ static void gc_worker(struct work_struct *work)
+                               continue;
+                       }
+-                      if (gc_worker_can_early_drop(tmp))
++                      if (gc_worker_can_early_drop(tmp)) {
+                               nf_ct_kill(tmp);
++                              expired_count++;
++                      }
+                       nf_ct_put(tmp);
+               }
+@@ -1492,33 +1538,38 @@ static void gc_worker(struct work_struct *work)
+               cond_resched();
+               i++;
+-              if (time_after(jiffies, end_time) && i < hashsz) {
++              delta_time = nfct_time_stamp - end_time;
++              if (delta_time > 0 && i < hashsz) {
++                      gc_work->avg_timeout = next_run;
+                       gc_work->next_bucket = i;
+                       next_run = 0;
+-                      break;
++                      goto early_exit;
+               }
+       } while (i < hashsz);
++      gc_work->next_bucket = 0;
++
++      next_run = clamp(next_run, GC_SCAN_INTERVAL_MIN, GC_SCAN_INTERVAL_MAX);
++
++      delta_time = max_t(s32, nfct_time_stamp - gc_work->start_time, 1);
++      if (next_run > (unsigned long)delta_time)
++              next_run -= delta_time;
++      else
++              next_run = 1;
++
++early_exit:
+       if (gc_work->exiting)
+               return;
+-      /*
+-       * Eviction will normally happen from the packet path, and not
+-       * from this gc worker.
+-       *
+-       * This worker is only here to reap expired entries when system went
+-       * idle after a busy period.
+-       */
+-      if (next_run) {
++      if (next_run)
+               gc_work->early_drop = false;
+-              gc_work->next_bucket = 0;
+-      }
++
+       queue_delayed_work(system_power_efficient_wq, &gc_work->dwork, next_run);
+ }
+ static void conntrack_gc_work_init(struct conntrack_gc_work *gc_work)
+ {
+-      INIT_DEFERRABLE_WORK(&gc_work->dwork, gc_worker);
++      INIT_DELAYED_WORK(&gc_work->dwork, gc_worker);
+       gc_work->exiting = false;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/netlabel-fix-out-of-bounds-memory-accesses.patch b/queue-5.17/netlabel-fix-out-of-bounds-memory-accesses.patch
new file mode 100644 (file)
index 0000000..0699ab2
--- /dev/null
@@ -0,0 +1,70 @@
+From 39bc16799cb034f1d61ebe11fd4b641cf1480e88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Mar 2022 14:35:08 +0800
+Subject: netlabel: fix out-of-bounds memory accesses
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit f22881de730ebd472e15bcc2c0d1d46e36a87b9c ]
+
+In calipso_map_cat_ntoh(), in the for loop, if the return value of
+netlbl_bitmap_walk() is equal to (net_clen_bits - 1), when
+netlbl_bitmap_walk() is called next time, out-of-bounds memory accesses
+of bitmap[byte_offset] occurs.
+
+The bug was found during fuzzing. The following is the fuzzing report
+ BUG: KASAN: slab-out-of-bounds in netlbl_bitmap_walk+0x3c/0xd0
+ Read of size 1 at addr ffffff8107bf6f70 by task err_OH/252
+
+ CPU: 7 PID: 252 Comm: err_OH Not tainted 5.17.0-rc7+ #17
+ Hardware name: linux,dummy-virt (DT)
+ Call trace:
+  dump_backtrace+0x21c/0x230
+  show_stack+0x1c/0x60
+  dump_stack_lvl+0x64/0x7c
+  print_address_description.constprop.0+0x70/0x2d0
+  __kasan_report+0x158/0x16c
+  kasan_report+0x74/0x120
+  __asan_load1+0x80/0xa0
+  netlbl_bitmap_walk+0x3c/0xd0
+  calipso_opt_getattr+0x1a8/0x230
+  calipso_sock_getattr+0x218/0x340
+  calipso_sock_getattr+0x44/0x60
+  netlbl_sock_getattr+0x44/0x80
+  selinux_netlbl_socket_setsockopt+0x138/0x170
+  selinux_socket_setsockopt+0x4c/0x60
+  security_socket_setsockopt+0x4c/0x90
+  __sys_setsockopt+0xbc/0x2b0
+  __arm64_sys_setsockopt+0x6c/0x84
+  invoke_syscall+0x64/0x190
+  el0_svc_common.constprop.0+0x88/0x200
+  do_el0_svc+0x88/0xa0
+  el0_svc+0x128/0x1b0
+  el0t_64_sync_handler+0x9c/0x120
+  el0t_64_sync+0x16c/0x170
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Acked-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_kapi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
+index beb0e573266d..54c083003947 100644
+--- a/net/netlabel/netlabel_kapi.c
++++ b/net/netlabel/netlabel_kapi.c
+@@ -885,6 +885,8 @@ int netlbl_bitmap_walk(const unsigned char *bitmap, u32 bitmap_len,
+       unsigned char bitmask;
+       unsigned char byte;
++      if (offset >= bitmap_len)
++              return -1;
+       byte_offset = offset / 8;
+       byte = bitmap[byte_offset];
+       bit_spot = offset;
+-- 
+2.35.1
+
diff --git a/queue-5.17/nfs-avoid-writeback-threads-getting-stuck-in-mempool.patch b/queue-5.17/nfs-avoid-writeback-threads-getting-stuck-in-mempool.patch
new file mode 100644 (file)
index 0000000..ad69d1b
--- /dev/null
@@ -0,0 +1,80 @@
+From 1ead968017fb32eb7d6731a94b342d9636298abf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Mar 2022 13:48:36 -0400
+Subject: NFS: Avoid writeback threads getting stuck in mempool_alloc()
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 0bae835b63c53f86cdc524f5962e39409585b22c ]
+
+In a low memory situation, allow the NFS writeback code to fail without
+getting stuck in infinite loops in mempool_alloc().
+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/pagelist.c | 10 +++++-----
+ fs/nfs/write.c    | 10 ++++++++--
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
+index 815d63080245..9157dd19b8b4 100644
+--- a/fs/nfs/pagelist.c
++++ b/fs/nfs/pagelist.c
+@@ -90,10 +90,10 @@ void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos)
+       }
+ }
+-static inline struct nfs_page *
+-nfs_page_alloc(void)
++static inline struct nfs_page *nfs_page_alloc(void)
+ {
+-      struct nfs_page *p = kmem_cache_zalloc(nfs_page_cachep, GFP_KERNEL);
++      struct nfs_page *p =
++              kmem_cache_zalloc(nfs_page_cachep, nfs_io_gfp_mask());
+       if (p)
+               INIT_LIST_HEAD(&p->wb_list);
+       return p;
+@@ -892,7 +892,7 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
+       struct nfs_commit_info cinfo;
+       struct nfs_page_array *pg_array = &hdr->page_array;
+       unsigned int pagecount, pageused;
+-      gfp_t gfp_flags = GFP_KERNEL;
++      gfp_t gfp_flags = nfs_io_gfp_mask();
+       pagecount = nfs_page_array_len(mirror->pg_base, mirror->pg_count);
+       pg_array->npages = pagecount;
+@@ -979,7 +979,7 @@ nfs_pageio_alloc_mirrors(struct nfs_pageio_descriptor *desc,
+       desc->pg_mirrors_dynamic = NULL;
+       if (mirror_count == 1)
+               return desc->pg_mirrors_static;
+-      ret = kmalloc_array(mirror_count, sizeof(*ret), GFP_KERNEL);
++      ret = kmalloc_array(mirror_count, sizeof(*ret), nfs_io_gfp_mask());
+       if (ret != NULL) {
+               for (i = 0; i < mirror_count; i++)
+                       nfs_pageio_mirror_init(&ret[i], desc->pg_bsize);
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index d0b9083bbfb5..938850303099 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -94,9 +94,15 @@ EXPORT_SYMBOL_GPL(nfs_commit_free);
+ static struct nfs_pgio_header *nfs_writehdr_alloc(void)
+ {
+-      struct nfs_pgio_header *p = mempool_alloc(nfs_wdata_mempool, GFP_KERNEL);
++      struct nfs_pgio_header *p;
+-      memset(p, 0, sizeof(*p));
++      p = kmem_cache_zalloc(nfs_wdata_cachep, nfs_io_gfp_mask());
++      if (!p) {
++              p = mempool_alloc(nfs_wdata_mempool, GFP_NOWAIT);
++              if (!p)
++                      return NULL;
++              memset(p, 0, sizeof(*p));
++      }
+       p->rw_mode = FMODE_WRITE;
+       return p;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/nfs-nfsiod-should-not-block-forever-in-mempool_alloc.patch b/queue-5.17/nfs-nfsiod-should-not-block-forever-in-mempool_alloc.patch
new file mode 100644 (file)
index 0000000..c71e4b2
--- /dev/null
@@ -0,0 +1,135 @@
+From 4d02da896992d4c7ea4d627e243e8c7c0a8f0d16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Mar 2022 12:34:19 -0400
+Subject: NFS: nfsiod should not block forever in mempool_alloc()
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 515dcdcd48736576c6f5c197814da6f81c60a21e ]
+
+The concern is that since nfsiod is sometimes required to kick off a
+commit, it can get locked up waiting forever in mempool_alloc() instead
+of failing gracefully and leaving the commit until later.
+
+Try to allocate from the slab first, with GFP_KERNEL | __GFP_NORETRY,
+then fall back to a non-blocking attempt to allocate from the memory
+pool.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/internal.h      |  7 +++++++
+ fs/nfs/pnfs_nfs.c      |  8 ++++++--
+ fs/nfs/write.c         | 24 +++++++++---------------
+ include/linux/nfs_fs.h |  2 +-
+ 4 files changed, 23 insertions(+), 18 deletions(-)
+
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index 2de7c56a1fbe..db9f611e8efd 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -573,6 +573,13 @@ nfs_write_match_verf(const struct nfs_writeverf *verf,
+               !nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier);
+ }
++static inline gfp_t nfs_io_gfp_mask(void)
++{
++      if (current->flags & PF_WQ_WORKER)
++              return GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
++      return GFP_KERNEL;
++}
++
+ /* unlink.c */
+ extern struct rpc_task *
+ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
+diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
+index 316f68f96e57..657c242a18ff 100644
+--- a/fs/nfs/pnfs_nfs.c
++++ b/fs/nfs/pnfs_nfs.c
+@@ -419,7 +419,7 @@ static struct nfs_commit_data *
+ pnfs_bucket_fetch_commitdata(struct pnfs_commit_bucket *bucket,
+                            struct nfs_commit_info *cinfo)
+ {
+-      struct nfs_commit_data *data = nfs_commitdata_alloc(false);
++      struct nfs_commit_data *data = nfs_commitdata_alloc();
+       if (!data)
+               return NULL;
+@@ -515,7 +515,11 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
+       unsigned int nreq = 0;
+       if (!list_empty(mds_pages)) {
+-              data = nfs_commitdata_alloc(true);
++              data = nfs_commitdata_alloc();
++              if (!data) {
++                      nfs_retry_commit(mds_pages, NULL, cinfo, -1);
++                      return -ENOMEM;
++              }
+               data->ds_commit_index = -1;
+               list_splice_init(mds_pages, &data->pages);
+               list_add_tail(&data->list, &list);
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index 60693ab6a032..d0b9083bbfb5 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -70,27 +70,17 @@ static mempool_t *nfs_wdata_mempool;
+ static struct kmem_cache *nfs_cdata_cachep;
+ static mempool_t *nfs_commit_mempool;
+-struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail)
++struct nfs_commit_data *nfs_commitdata_alloc(void)
+ {
+       struct nfs_commit_data *p;
+-      if (never_fail)
+-              p = mempool_alloc(nfs_commit_mempool, GFP_NOIO);
+-      else {
+-              /* It is OK to do some reclaim, not no safe to wait
+-               * for anything to be returned to the pool.
+-               * mempool_alloc() cannot handle that particular combination,
+-               * so we need two separate attempts.
+-               */
++      p = kmem_cache_zalloc(nfs_cdata_cachep, nfs_io_gfp_mask());
++      if (!p) {
+               p = mempool_alloc(nfs_commit_mempool, GFP_NOWAIT);
+-              if (!p)
+-                      p = kmem_cache_alloc(nfs_cdata_cachep, GFP_NOIO |
+-                                           __GFP_NOWARN | __GFP_NORETRY);
+               if (!p)
+                       return NULL;
++              memset(p, 0, sizeof(*p));
+       }
+-
+-      memset(p, 0, sizeof(*p));
+       INIT_LIST_HEAD(&p->pages);
+       return p;
+ }
+@@ -1826,7 +1816,11 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
+       if (list_empty(head))
+               return 0;
+-      data = nfs_commitdata_alloc(true);
++      data = nfs_commitdata_alloc();
++      if (!data) {
++              nfs_retry_commit(head, NULL, cinfo, -1);
++              return -ENOMEM;
++      }
+       /* Set up the argument struct */
+       nfs_init_commit(data, head, NULL, cinfo);
+diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
+index 161e4f5ea7a0..c9d3dc79d587 100644
+--- a/include/linux/nfs_fs.h
++++ b/include/linux/nfs_fs.h
+@@ -585,7 +585,7 @@ extern int nfs_wb_all(struct inode *inode);
+ extern int nfs_wb_page(struct inode *inode, struct page *page);
+ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
+ extern int  nfs_commit_inode(struct inode *, int);
+-extern struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail);
++extern struct nfs_commit_data *nfs_commitdata_alloc(void);
+ extern void nfs_commit_free(struct nfs_commit_data *data);
+ bool nfs_commit_end(struct nfs_mds_commit_info *cinfo);
+-- 
+2.35.1
+
diff --git a/queue-5.17/nfs-swap-io-handling-is-slightly-different-for-o_dir.patch b/queue-5.17/nfs-swap-io-handling-is-slightly-different-for-o_dir.patch
new file mode 100644 (file)
index 0000000..aee06c8
--- /dev/null
@@ -0,0 +1,183 @@
+From cdf68c43c65f978928daa952b2030f4d26196a76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Mar 2022 10:41:44 +1100
+Subject: NFS: swap IO handling is slightly different for O_DIRECT IO
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit 64158668ac8b31626a8ce48db4cad08496eb8340 ]
+
+1/ Taking the i_rwsem for swap IO triggers lockdep warnings regarding
+   possible deadlocks with "fs_reclaim".  These deadlocks could, I believe,
+   eventuate if a buffered read on the swapfile was attempted.
+
+   We don't need coherence with the page cache for a swap file, and
+   buffered writes are forbidden anyway.  There is no other need for
+   i_rwsem during direct IO.  So never take it for swap_rw()
+
+2/ generic_write_checks() explicitly forbids writes to swap, and
+   performs checks that are not needed for swap.  So bypass it
+   for swap_rw().
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/direct.c        | 42 ++++++++++++++++++++++++++++--------------
+ fs/nfs/file.c          |  4 ++--
+ include/linux/nfs_fs.h |  8 ++++----
+ 3 files changed, 34 insertions(+), 20 deletions(-)
+
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index eabfdab543c8..04aaf39a05cb 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -173,8 +173,8 @@ ssize_t nfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
+       VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE);
+       if (iov_iter_rw(iter) == READ)
+-              return nfs_file_direct_read(iocb, iter);
+-      return nfs_file_direct_write(iocb, iter);
++              return nfs_file_direct_read(iocb, iter, true);
++      return nfs_file_direct_write(iocb, iter, true);
+ }
+ static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
+@@ -425,6 +425,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
+  * nfs_file_direct_read - file direct read operation for NFS files
+  * @iocb: target I/O control block
+  * @iter: vector of user buffers into which to read data
++ * @swap: flag indicating this is swap IO, not O_DIRECT IO
+  *
+  * We use this function for direct reads instead of calling
+  * generic_file_aio_read() in order to avoid gfar's check to see if
+@@ -440,7 +441,8 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
+  * client must read the updated atime from the server back into its
+  * cache.
+  */
+-ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
++ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
++                           bool swap)
+ {
+       struct file *file = iocb->ki_filp;
+       struct address_space *mapping = file->f_mapping;
+@@ -482,12 +484,14 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
+       if (iter_is_iovec(iter))
+               dreq->flags = NFS_ODIRECT_SHOULD_DIRTY;
+-      nfs_start_io_direct(inode);
++      if (!swap)
++              nfs_start_io_direct(inode);
+       NFS_I(inode)->read_io += count;
+       requested = nfs_direct_read_schedule_iovec(dreq, iter, iocb->ki_pos);
+-      nfs_end_io_direct(inode);
++      if (!swap)
++              nfs_end_io_direct(inode);
+       if (requested > 0) {
+               result = nfs_direct_wait(dreq);
+@@ -876,6 +880,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
+  * nfs_file_direct_write - file direct write operation for NFS files
+  * @iocb: target I/O control block
+  * @iter: vector of user buffers from which to write data
++ * @swap: flag indicating this is swap IO, not O_DIRECT IO
+  *
+  * We use this function for direct writes instead of calling
+  * generic_file_aio_write() in order to avoid taking the inode
+@@ -892,7 +897,8 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
+  * Note that O_APPEND is not supported for NFS direct writes, as there
+  * is no atomic O_APPEND write facility in the NFS protocol.
+  */
+-ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
++ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
++                            bool swap)
+ {
+       ssize_t result, requested;
+       size_t count;
+@@ -906,7 +912,11 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
+       dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
+               file, iov_iter_count(iter), (long long) iocb->ki_pos);
+-      result = generic_write_checks(iocb, iter);
++      if (swap)
++              /* bypass generic checks */
++              result =  iov_iter_count(iter);
++      else
++              result = generic_write_checks(iocb, iter);
+       if (result <= 0)
+               return result;
+       count = result;
+@@ -937,16 +947,20 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
+               dreq->iocb = iocb;
+       pnfs_init_ds_commit_info_ops(&dreq->ds_cinfo, inode);
+-      nfs_start_io_direct(inode);
++      if (swap) {
++              requested = nfs_direct_write_schedule_iovec(dreq, iter, pos);
++      } else {
++              nfs_start_io_direct(inode);
+-      requested = nfs_direct_write_schedule_iovec(dreq, iter, pos);
++              requested = nfs_direct_write_schedule_iovec(dreq, iter, pos);
+-      if (mapping->nrpages) {
+-              invalidate_inode_pages2_range(mapping,
+-                                            pos >> PAGE_SHIFT, end);
+-      }
++              if (mapping->nrpages) {
++                      invalidate_inode_pages2_range(mapping,
++                                                    pos >> PAGE_SHIFT, end);
++              }
+-      nfs_end_io_direct(inode);
++              nfs_end_io_direct(inode);
++      }
+       if (requested > 0) {
+               result = nfs_direct_wait(dreq);
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c
+index 76d76acbc594..d8583f57ff99 100644
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -162,7 +162,7 @@ nfs_file_read(struct kiocb *iocb, struct iov_iter *to)
+       ssize_t result;
+       if (iocb->ki_flags & IOCB_DIRECT)
+-              return nfs_file_direct_read(iocb, to);
++              return nfs_file_direct_read(iocb, to, false);
+       dprintk("NFS: read(%pD2, %zu@%lu)\n",
+               iocb->ki_filp,
+@@ -619,7 +619,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
+               return result;
+       if (iocb->ki_flags & IOCB_DIRECT)
+-              return nfs_file_direct_write(iocb, from);
++              return nfs_file_direct_write(iocb, from, false);
+       dprintk("NFS: write(%pD2, %zu@%Ld)\n",
+               file, iov_iter_count(from), (long long) iocb->ki_pos);
+diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
+index 68f81d8d36de..161e4f5ea7a0 100644
+--- a/include/linux/nfs_fs.h
++++ b/include/linux/nfs_fs.h
+@@ -513,10 +513,10 @@ static inline const struct cred *nfs_file_cred(struct file *file)
+  * linux/fs/nfs/direct.c
+  */
+ extern ssize_t nfs_direct_IO(struct kiocb *, struct iov_iter *);
+-extern ssize_t nfs_file_direct_read(struct kiocb *iocb,
+-                      struct iov_iter *iter);
+-extern ssize_t nfs_file_direct_write(struct kiocb *iocb,
+-                      struct iov_iter *iter);
++ssize_t nfs_file_direct_read(struct kiocb *iocb,
++                           struct iov_iter *iter, bool swap);
++ssize_t nfs_file_direct_write(struct kiocb *iocb,
++                            struct iov_iter *iter, bool swap);
+ /*
+  * linux/fs/nfs/dir.c
+-- 
+2.35.1
+
diff --git a/queue-5.17/nfs-swap-out-must-always-use-stable-writes.patch b/queue-5.17/nfs-swap-out-must-always-use-stable-writes.patch
new file mode 100644 (file)
index 0000000..8a3489b
--- /dev/null
@@ -0,0 +1,71 @@
+From d2142c51a5df16500f3ec0b06612d87e1a273973 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Mar 2022 10:41:44 +1100
+Subject: NFS: swap-out must always use STABLE writes.
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit c265de257f558a05c1859ee9e3fed04883b9ec0e ]
+
+The commit handling code is not safe against memory-pressure deadlocks
+when writing to swap.  In particular, nfs_commitdata_alloc() blocks
+indefinitely waiting for memory, and this can consume all available
+workqueue threads.
+
+swap-out most likely uses STABLE writes anyway as COND_STABLE indicates
+that a stable write should be used if the write fits in a single
+request, and it normally does.  However if we ever swap with a small
+wsize, or gather unusually large numbers of pages for a single write,
+this might change.
+
+For safety, make it explicit in the code that direct writes used for swap
+must always use FLUSH_STABLE.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/direct.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index 04aaf39a05cb..11c566d8769f 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -794,7 +794,7 @@ static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = {
+  */
+ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
+                                              struct iov_iter *iter,
+-                                             loff_t pos)
++                                             loff_t pos, int ioflags)
+ {
+       struct nfs_pageio_descriptor desc;
+       struct inode *inode = dreq->inode;
+@@ -802,7 +802,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
+       size_t requested_bytes = 0;
+       size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE);
+-      nfs_pageio_init_write(&desc, inode, FLUSH_COND_STABLE, false,
++      nfs_pageio_init_write(&desc, inode, ioflags, false,
+                             &nfs_direct_write_completion_ops);
+       desc.pg_dreq = dreq;
+       get_dreq(dreq);
+@@ -948,11 +948,13 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
+       pnfs_init_ds_commit_info_ops(&dreq->ds_cinfo, inode);
+       if (swap) {
+-              requested = nfs_direct_write_schedule_iovec(dreq, iter, pos);
++              requested = nfs_direct_write_schedule_iovec(dreq, iter, pos,
++                                                          FLUSH_STABLE);
+       } else {
+               nfs_start_io_direct(inode);
+-              requested = nfs_direct_write_schedule_iovec(dreq, iter, pos);
++              requested = nfs_direct_write_schedule_iovec(dreq, iter, pos,
++                                                          FLUSH_COND_STABLE);
+               if (mapping->nrpages) {
+                       invalidate_inode_pages2_range(mapping,
+-- 
+2.35.1
+
diff --git a/queue-5.17/nfsv4-protect-the-state-recovery-thread-against-dire.patch b/queue-5.17/nfsv4-protect-the-state-recovery-thread-against-dire.patch
new file mode 100644 (file)
index 0000000..f9e253a
--- /dev/null
@@ -0,0 +1,76 @@
+From 0d31335384a8b31ae703c7f785caae7007ae28a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Jan 2022 13:32:45 -0500
+Subject: NFSv4: Protect the state recovery thread against direct reclaim
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 3e17898aca293a24dae757a440a50aa63ca29671 ]
+
+If memory allocation triggers a direct reclaim from the state recovery
+thread, then we can deadlock. Use memalloc_nofs_save/restore to ensure
+that doesn't happen.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4state.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index f5a62c0d999b..0f4818627ef0 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -49,6 +49,7 @@
+ #include <linux/workqueue.h>
+ #include <linux/bitops.h>
+ #include <linux/jiffies.h>
++#include <linux/sched/mm.h>
+ #include <linux/sunrpc/clnt.h>
+@@ -2560,9 +2561,17 @@ static void nfs4_layoutreturn_any_run(struct nfs_client *clp)
+ static void nfs4_state_manager(struct nfs_client *clp)
+ {
++      unsigned int memflags;
+       int status = 0;
+       const char *section = "", *section_sep = "";
++      /*
++       * State recovery can deadlock if the direct reclaim code tries
++       * start NFS writeback. So ensure memory allocations are all
++       * GFP_NOFS.
++       */
++      memflags = memalloc_nofs_save();
++
+       /* Ensure exclusive access to NFSv4 state */
+       do {
+               trace_nfs4_state_mgr(clp);
+@@ -2657,6 +2666,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
+                       clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
+               }
++              memalloc_nofs_restore(memflags);
+               nfs4_end_drain_session(clp);
+               nfs4_clear_state_manager_bit(clp);
+@@ -2674,6 +2684,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
+                       return;
+               if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
+                       return;
++              memflags = memalloc_nofs_save();
+       } while (refcount_read(&clp->cl_count) > 1 && !signalled());
+       goto out_drain;
+@@ -2686,6 +2697,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
+                       clp->cl_hostname, -status);
+       ssleep(1);
+ out_drain:
++      memalloc_nofs_restore(memflags);
+       nfs4_end_drain_session(clp);
+       nfs4_clear_state_manager_bit(clp);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/nfsv4.2-fix-reference-count-leaks-in-_nfs42_proc_cop.patch b/queue-5.17/nfsv4.2-fix-reference-count-leaks-in-_nfs42_proc_cop.patch
new file mode 100644 (file)
index 0000000..10de61f
--- /dev/null
@@ -0,0 +1,66 @@
+From ce9e22312d809dfb85c5abaa8f8f465e84b4da5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 21:10:45 +0800
+Subject: NFSv4.2: fix reference count leaks in _nfs42_proc_copy_notify()
+
+From: Xin Xiong <xiongx18@fudan.edu.cn>
+
+[ Upstream commit b7f114edd54326f730a754547e7cfb197b5bc132 ]
+
+[You don't often get email from xiongx18@fudan.edu.cn. Learn why this is important at http://aka.ms/LearnAboutSenderIdentification.]
+
+The reference counting issue happens in two error paths in the
+function _nfs42_proc_copy_notify(). In both error paths, the function
+simply returns the error code and forgets to balance the refcount of
+object `ctx`, bumped by get_nfs_open_context() earlier, which may
+cause refcount leaks.
+
+Fix it by balancing refcount of the `ctx` object before the function
+returns in both error paths.
+
+Signed-off-by: Xin Xiong <xiongx18@fudan.edu.cn>
+Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42proc.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index 32129446beca..ca878d021fab 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -591,8 +591,10 @@ static int _nfs42_proc_copy_notify(struct file *src, struct file *dst,
+       ctx = get_nfs_open_context(nfs_file_open_context(src));
+       l_ctx = nfs_get_lock_context(ctx);
+-      if (IS_ERR(l_ctx))
+-              return PTR_ERR(l_ctx);
++      if (IS_ERR(l_ctx)) {
++              status = PTR_ERR(l_ctx);
++              goto out;
++      }
+       status = nfs4_set_rw_stateid(&args->cna_src_stateid, ctx, l_ctx,
+                                    FMODE_READ);
+@@ -600,7 +602,7 @@ static int _nfs42_proc_copy_notify(struct file *src, struct file *dst,
+       if (status) {
+               if (status == -EAGAIN)
+                       status = -NFS4ERR_BAD_STATEID;
+-              return status;
++              goto out;
+       }
+       status = nfs4_call_sync(src_server->client, src_server, &msg,
+@@ -609,6 +611,7 @@ static int _nfs42_proc_copy_notify(struct file *src, struct file *dst,
+       if (status == -ENOTSUPP)
+               src_server->caps &= ~NFS_CAP_COPY_NOTIFY;
++out:
+       put_nfs_open_context(nfs_file_open_context(src));
+       return status;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/opp-expose-of-node-s-name-in-debugfs.patch b/queue-5.17/opp-expose-of-node-s-name-in-debugfs.patch
new file mode 100644 (file)
index 0000000..9767077
--- /dev/null
@@ -0,0 +1,67 @@
+From 731f81776e46de092f85a9dc5c33aaf99e92cf50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 14:37:53 +0530
+Subject: opp: Expose of-node's name in debugfs
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit 021dbecabc93b1610b5db989d52a94e0c6671136 ]
+
+It is difficult to find which OPPs are active at the moment, specially
+if there are multiple OPPs with same frequency available in the device
+tree (controlled by supported hardware feature).
+
+Expose name of the DT node to find out the exact OPP.
+
+While at it, also expose level field.
+
+Reported-by: Leo Yan <leo.yan@linaro.org>
+Tested-by: Leo Yan <leo.yan@linaro.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/opp/debugfs.c | 5 +++++
+ drivers/opp/opp.h     | 1 +
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
+index 596c185b5dda..b5f2f9f39392 100644
+--- a/drivers/opp/debugfs.c
++++ b/drivers/opp/debugfs.c
+@@ -10,6 +10,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/device.h>
+ #include <linux/err.h>
++#include <linux/of.h>
+ #include <linux/init.h>
+ #include <linux/limits.h>
+ #include <linux/slab.h>
+@@ -131,9 +132,13 @@ void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
+       debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend);
+       debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate);
+       debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate);
++      debugfs_create_u32("level", S_IRUGO, d, &opp->level);
+       debugfs_create_ulong("clock_latency_ns", S_IRUGO, d,
+                            &opp->clock_latency_ns);
++      opp->of_name = of_node_full_name(opp->np);
++      debugfs_create_str("of_name", S_IRUGO, d, (char **)&opp->of_name);
++
+       opp_debug_create_supplies(opp, opp_table, d);
+       opp_debug_create_bw(opp, opp_table, d);
+diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
+index 407c3bfe51d9..45e3a55239a1 100644
+--- a/drivers/opp/opp.h
++++ b/drivers/opp/opp.h
+@@ -96,6 +96,7 @@ struct dev_pm_opp {
+ #ifdef CONFIG_DEBUG_FS
+       struct dentry *dentry;
++      const char *of_name;
+ #endif
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.17/parisc-fix-cpu-affinity-for-lasi-wax-and-dino-chips.patch b/queue-5.17/parisc-fix-cpu-affinity-for-lasi-wax-and-dino-chips.patch
new file mode 100644 (file)
index 0000000..2e3df54
--- /dev/null
@@ -0,0 +1,232 @@
+From e95282072cde7de45629d3872fb7d302ca47f09f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Mar 2022 15:46:26 +0200
+Subject: parisc: Fix CPU affinity for Lasi, WAX and Dino chips
+
+From: Helge Deller <deller@gmx.de>
+
+[ Upstream commit 939fc856676c266c3bc347c1c1661872a3725c0f ]
+
+Add the missing logic to allow Lasi, WAX and Dino to set the
+CPU affinity. This fixes IRQ migration to other CPUs when a
+CPU is shutdown which currently holds the IRQs for one of those
+chips.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/parisc/dino.c | 41 +++++++++++++++++++++++++++++++++--------
+ drivers/parisc/gsc.c  | 31 +++++++++++++++++++++++++++++++
+ drivers/parisc/gsc.h  |  1 +
+ drivers/parisc/lasi.c |  7 +++----
+ drivers/parisc/wax.c  |  7 +++----
+ 5 files changed, 71 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
+index 952a92504df6..e33036281327 100644
+--- a/drivers/parisc/dino.c
++++ b/drivers/parisc/dino.c
+@@ -142,9 +142,8 @@ struct dino_device
+ {
+       struct pci_hba_data     hba;    /* 'C' inheritance - must be first */
+       spinlock_t              dinosaur_pen;
+-      unsigned long           txn_addr; /* EIR addr to generate interrupt */ 
+-      u32                     txn_data; /* EIR data assign to each dino */ 
+       u32                     imr;      /* IRQ's which are enabled */ 
++      struct gsc_irq          gsc_irq;
+       int                     global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */
+ #ifdef DINO_DEBUG
+       unsigned int            dino_irr0; /* save most recent IRQ line stat */
+@@ -339,14 +338,43 @@ static void dino_unmask_irq(struct irq_data *d)
+       if (tmp & DINO_MASK_IRQ(local_irq)) {
+               DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n",
+                               __func__, tmp);
+-              gsc_writel(dino_dev->txn_data, dino_dev->txn_addr);
++              gsc_writel(dino_dev->gsc_irq.txn_data, dino_dev->gsc_irq.txn_addr);
+       }
+ }
++#ifdef CONFIG_SMP
++static int dino_set_affinity_irq(struct irq_data *d, const struct cpumask *dest,
++                              bool force)
++{
++      struct dino_device *dino_dev = irq_data_get_irq_chip_data(d);
++      struct cpumask tmask;
++      int cpu_irq;
++      u32 eim;
++
++      if (!cpumask_and(&tmask, dest, cpu_online_mask))
++              return -EINVAL;
++
++      cpu_irq = cpu_check_affinity(d, &tmask);
++      if (cpu_irq < 0)
++              return cpu_irq;
++
++      dino_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq);
++      eim = ((u32) dino_dev->gsc_irq.txn_addr) | dino_dev->gsc_irq.txn_data;
++      __raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0);
++
++      irq_data_update_effective_affinity(d, &tmask);
++
++      return IRQ_SET_MASK_OK;
++}
++#endif
++
+ static struct irq_chip dino_interrupt_type = {
+       .name           = "GSC-PCI",
+       .irq_unmask     = dino_unmask_irq,
+       .irq_mask       = dino_mask_irq,
++#ifdef CONFIG_SMP
++      .irq_set_affinity = dino_set_affinity_irq,
++#endif
+ };
+@@ -806,7 +834,6 @@ static int __init dino_common_init(struct parisc_device *dev,
+ {
+       int status;
+       u32 eim;
+-      struct gsc_irq gsc_irq;
+       struct resource *res;
+       pcibios_register_hba(&dino_dev->hba);
+@@ -821,10 +848,8 @@ static int __init dino_common_init(struct parisc_device *dev,
+       **   still only has 11 IRQ input lines - just map some of them
+       **   to a different processor.
+       */
+-      dev->irq = gsc_alloc_irq(&gsc_irq);
+-      dino_dev->txn_addr = gsc_irq.txn_addr;
+-      dino_dev->txn_data = gsc_irq.txn_data;
+-      eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
++      dev->irq = gsc_alloc_irq(&dino_dev->gsc_irq);
++      eim = ((u32) dino_dev->gsc_irq.txn_addr) | dino_dev->gsc_irq.txn_data;
+       /* 
+       ** Dino needs a PA "IRQ" to get a processor's attention.
+diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
+index ed9371acf37e..ec175ae99873 100644
+--- a/drivers/parisc/gsc.c
++++ b/drivers/parisc/gsc.c
+@@ -135,10 +135,41 @@ static void gsc_asic_unmask_irq(struct irq_data *d)
+        */
+ }
++#ifdef CONFIG_SMP
++static int gsc_set_affinity_irq(struct irq_data *d, const struct cpumask *dest,
++                              bool force)
++{
++      struct gsc_asic *gsc_dev = irq_data_get_irq_chip_data(d);
++      struct cpumask tmask;
++      int cpu_irq;
++
++      if (!cpumask_and(&tmask, dest, cpu_online_mask))
++              return -EINVAL;
++
++      cpu_irq = cpu_check_affinity(d, &tmask);
++      if (cpu_irq < 0)
++              return cpu_irq;
++
++      gsc_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq);
++      gsc_dev->eim = ((u32) gsc_dev->gsc_irq.txn_addr) | gsc_dev->gsc_irq.txn_data;
++
++      /* switch IRQ's for devices below LASI/WAX to other CPU */
++      gsc_writel(gsc_dev->eim, gsc_dev->hpa + OFFSET_IAR);
++
++      irq_data_update_effective_affinity(d, &tmask);
++
++      return IRQ_SET_MASK_OK;
++}
++#endif
++
++
+ static struct irq_chip gsc_asic_interrupt_type = {
+       .name           =       "GSC-ASIC",
+       .irq_unmask     =       gsc_asic_unmask_irq,
+       .irq_mask       =       gsc_asic_mask_irq,
++#ifdef CONFIG_SMP
++      .irq_set_affinity =     gsc_set_affinity_irq,
++#endif
+ };
+ int gsc_assign_irq(struct irq_chip *type, void *data)
+diff --git a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h
+index 86abad3fa215..73cbd0bb1975 100644
+--- a/drivers/parisc/gsc.h
++++ b/drivers/parisc/gsc.h
+@@ -31,6 +31,7 @@ struct gsc_asic {
+       int version;
+       int type;
+       int eim;
++      struct gsc_irq gsc_irq;
+       int global_irq[32];
+ };
+diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
+index 4e4fd12c2112..6ef621adb63a 100644
+--- a/drivers/parisc/lasi.c
++++ b/drivers/parisc/lasi.c
+@@ -163,7 +163,6 @@ static int __init lasi_init_chip(struct parisc_device *dev)
+ {
+       extern void (*chassis_power_off)(void);
+       struct gsc_asic *lasi;
+-      struct gsc_irq gsc_irq;
+       int ret;
+       lasi = kzalloc(sizeof(*lasi), GFP_KERNEL);
+@@ -185,7 +184,7 @@ static int __init lasi_init_chip(struct parisc_device *dev)
+       lasi_init_irq(lasi);
+       /* the IRQ lasi should use */
+-      dev->irq = gsc_alloc_irq(&gsc_irq);
++      dev->irq = gsc_alloc_irq(&lasi->gsc_irq);
+       if (dev->irq < 0) {
+               printk(KERN_ERR "%s(): cannot get GSC irq\n",
+                               __func__);
+@@ -193,9 +192,9 @@ static int __init lasi_init_chip(struct parisc_device *dev)
+               return -EBUSY;
+       }
+-      lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
++      lasi->eim = ((u32) lasi->gsc_irq.txn_addr) | lasi->gsc_irq.txn_data;
+-      ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi);
++      ret = request_irq(lasi->gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi);
+       if (ret < 0) {
+               kfree(lasi);
+               return ret;
+diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c
+index 5b6df1516235..73a2b01f8d9c 100644
+--- a/drivers/parisc/wax.c
++++ b/drivers/parisc/wax.c
+@@ -68,7 +68,6 @@ static int __init wax_init_chip(struct parisc_device *dev)
+ {
+       struct gsc_asic *wax;
+       struct parisc_device *parent;
+-      struct gsc_irq gsc_irq;
+       int ret;
+       wax = kzalloc(sizeof(*wax), GFP_KERNEL);
+@@ -85,7 +84,7 @@ static int __init wax_init_chip(struct parisc_device *dev)
+       wax_init_irq(wax);
+       /* the IRQ wax should use */
+-      dev->irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ);
++      dev->irq = gsc_claim_irq(&wax->gsc_irq, WAX_GSC_IRQ);
+       if (dev->irq < 0) {
+               printk(KERN_ERR "%s(): cannot get GSC irq\n",
+                               __func__);
+@@ -93,9 +92,9 @@ static int __init wax_init_chip(struct parisc_device *dev)
+               return -EBUSY;
+       }
+-      wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
++      wax->eim = ((u32) wax->gsc_irq.txn_addr) | wax->gsc_irq.txn_data;
+-      ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "wax", wax);
++      ret = request_irq(wax->gsc_irq.irq, gsc_asic_intr, 0, "wax", wax);
+       if (ret < 0) {
+               kfree(wax);
+               return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.17/parisc-fix-patch-code-locking-and-flushing.patch b/queue-5.17/parisc-fix-patch-code-locking-and-flushing.patch
new file mode 100644 (file)
index 0000000..8d1895c
--- /dev/null
@@ -0,0 +1,97 @@
+From 29e80eea04c2d79e46dd5e64e8fcb00281d57d15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Mar 2022 18:54:36 +0000
+Subject: parisc: Fix patch code locking and flushing
+
+From: John David Anglin <dave.anglin@bell.net>
+
+[ Upstream commit a9fe7fa7d874a536e0540469f314772c054a0323 ]
+
+This change fixes the following:
+
+1) The flags variable is not initialized. Always use raw_spin_lock_irqsave
+and raw_spin_unlock_irqrestore to serialize patching.
+
+2) flush_kernel_vmap_range is primarily intended for DMA flushes. Since
+__patch_text_multiple is often called with interrupts disabled, it is
+better to directly call flush_kernel_dcache_range_asm and
+flush_kernel_icache_range_asm. This avoids an extra call.
+
+3) The final call to flush_icache_range is unnecessary.
+
+Signed-off-by: John David Anglin <dave.anglin@bell.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/kernel/patch.c | 25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/arch/parisc/kernel/patch.c b/arch/parisc/kernel/patch.c
+index 80a0ab372802..e59574f65e64 100644
+--- a/arch/parisc/kernel/patch.c
++++ b/arch/parisc/kernel/patch.c
+@@ -40,10 +40,7 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags,
+       *need_unmap = 1;
+       set_fixmap(fixmap, page_to_phys(page));
+-      if (flags)
+-              raw_spin_lock_irqsave(&patch_lock, *flags);
+-      else
+-              __acquire(&patch_lock);
++      raw_spin_lock_irqsave(&patch_lock, *flags);
+       return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
+ }
+@@ -52,10 +49,7 @@ static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
+ {
+       clear_fixmap(fixmap);
+-      if (flags)
+-              raw_spin_unlock_irqrestore(&patch_lock, *flags);
+-      else
+-              __release(&patch_lock);
++      raw_spin_unlock_irqrestore(&patch_lock, *flags);
+ }
+ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
+@@ -67,8 +61,9 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
+       int mapped;
+       /* Make sure we don't have any aliases in cache */
+-      flush_kernel_vmap_range(addr, len);
+-      flush_icache_range(start, end);
++      flush_kernel_dcache_range_asm(start, end);
++      flush_kernel_icache_range_asm(start, end);
++      flush_tlb_kernel_range(start, end);
+       p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags, &mapped);
+@@ -81,8 +76,10 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
+                        * We're crossing a page boundary, so
+                        * need to remap
+                        */
+-                      flush_kernel_vmap_range((void *)fixmap,
+-                                              (p-fixmap) * sizeof(*p));
++                      flush_kernel_dcache_range_asm((unsigned long)fixmap,
++                                                    (unsigned long)p);
++                      flush_tlb_kernel_range((unsigned long)fixmap,
++                                             (unsigned long)p);
+                       if (mapped)
+                               patch_unmap(FIX_TEXT_POKE0, &flags);
+                       p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags,
+@@ -90,10 +87,10 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
+               }
+       }
+-      flush_kernel_vmap_range((void *)fixmap, (p-fixmap) * sizeof(*p));
++      flush_kernel_dcache_range_asm((unsigned long)fixmap, (unsigned long)p);
++      flush_tlb_kernel_range((unsigned long)fixmap, (unsigned long)p);
+       if (mapped)
+               patch_unmap(FIX_TEXT_POKE0, &flags);
+-      flush_icache_range(start, end);
+ }
+ void __kprobes __patch_text(void *addr, u32 insn)
+-- 
+2.35.1
+
diff --git a/queue-5.17/pci-aardvark-fix-support-for-msi-interrupts.patch b/queue-5.17/pci-aardvark-fix-support-for-msi-interrupts.patch
new file mode 100644 (file)
index 0000000..cd5112d
--- /dev/null
@@ -0,0 +1,84 @@
+From 660fe808b2dbe815588e374e190dd3e200c27d77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jan 2022 02:49:58 +0100
+Subject: PCI: aardvark: Fix support for MSI interrupts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit b0b0b8b897f8e12b2368e868bd7cdc5742d5c5a9 ]
+
+Aardvark hardware supports Multi-MSI and MSI_FLAG_MULTI_PCI_MSI is already
+set for the MSI chip. But when allocating MSI interrupt numbers for
+Multi-MSI, the numbers need to be properly aligned, otherwise endpoint
+devices send MSI interrupt with incorrect numbers.
+
+Fix this issue by using function bitmap_find_free_region() instead of
+bitmap_find_next_zero_area().
+
+To ensure that aligned MSI interrupt numbers are used by endpoint devices,
+we cannot use Linux virtual irq numbers (as they are random and not
+properly aligned). Instead we need to use the aligned hwirq numbers.
+
+This change fixes receiving MSI interrupts on Armada 3720 boards and
+allows using NVMe disks which use Multi-MSI feature with 3 interrupts.
+
+Without this NVMe disks freeze booting as linux nvme-core.c is waiting
+60s for an interrupt.
+
+Link: https://lore.kernel.org/r/20220110015018.26359-4-kabel@kernel.org
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pci-aardvark.c | 16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
+index 82e2c618d532..15348be1a8aa 100644
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -1186,7 +1186,7 @@ static void advk_msi_irq_compose_msi_msg(struct irq_data *data,
+       msg->address_lo = lower_32_bits(msi_msg);
+       msg->address_hi = upper_32_bits(msi_msg);
+-      msg->data = data->irq;
++      msg->data = data->hwirq;
+ }
+ static int advk_msi_set_affinity(struct irq_data *irq_data,
+@@ -1203,15 +1203,11 @@ static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
+       int hwirq, i;
+       mutex_lock(&pcie->msi_used_lock);
+-      hwirq = bitmap_find_next_zero_area(pcie->msi_used, MSI_IRQ_NUM,
+-                                         0, nr_irqs, 0);
+-      if (hwirq >= MSI_IRQ_NUM) {
+-              mutex_unlock(&pcie->msi_used_lock);
+-              return -ENOSPC;
+-      }
+-
+-      bitmap_set(pcie->msi_used, hwirq, nr_irqs);
++      hwirq = bitmap_find_free_region(pcie->msi_used, MSI_IRQ_NUM,
++                                      order_base_2(nr_irqs));
+       mutex_unlock(&pcie->msi_used_lock);
++      if (hwirq < 0)
++              return -ENOSPC;
+       for (i = 0; i < nr_irqs; i++)
+               irq_domain_set_info(domain, virq + i, hwirq + i,
+@@ -1229,7 +1225,7 @@ static void advk_msi_irq_domain_free(struct irq_domain *domain,
+       struct advk_pcie *pcie = domain->host_data;
+       mutex_lock(&pcie->msi_used_lock);
+-      bitmap_clear(pcie->msi_used, d->hwirq, nr_irqs);
++      bitmap_release_region(pcie->msi_used, d->hwirq, order_base_2(nr_irqs));
+       mutex_unlock(&pcie->msi_used_lock);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/pci-endpoint-fix-alignment-fault-error-in-copy-tests.patch b/queue-5.17/pci-endpoint-fix-alignment-fault-error-in-copy-tests.patch
new file mode 100644 (file)
index 0000000..23eb28f
--- /dev/null
@@ -0,0 +1,92 @@
+From 2bd857f049627a9d68d3f020a00694422da5983a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Dec 2021 17:47:08 +0800
+Subject: PCI: endpoint: Fix alignment fault error in copy tests
+
+From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
+
+[ Upstream commit 829cc0e2ea2d61fb6c54bc3f8a17f86c56e11864 ]
+
+The copy test uses the memcpy() to copy data between IO memory spaces.
+This can trigger an alignment fault error (pasted the error logs below)
+because memcpy() may use unaligned accesses on a mapped memory that is
+just IO, which does not support unaligned memory accesses.
+
+Fix it by using the correct memcpy API to copy from/to IO memory.
+
+Alignment fault error logs:
+   Unable to handle kernel paging request at virtual address ffff8000101cd3c1
+   Mem abort info:
+     ESR = 0x96000021
+     EC = 0x25: DABT (current EL), IL = 32 bits
+     SET = 0, FnV = 0
+     EA = 0, S1PTW = 0
+     FSC = 0x21: alignment fault
+   Data abort info:
+     ISV = 0, ISS = 0x00000021
+     CM = 0, WnR = 0
+   swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000081773000
+   [ffff8000101cd3c1] pgd=1000000082410003, p4d=1000000082410003, pud=1000000082411003, pmd=1000000082412003, pte=0068004000001f13
+   Internal error: Oops: 96000021 [#1] PREEMPT SMP
+   Modules linked in:
+   CPU: 0 PID: 6 Comm: kworker/0:0H Not tainted 5.15.0-rc1-next-20210914-dirty #2
+   Hardware name: LS1012A RDB Board (DT)
+   Workqueue: kpcitest pci_epf_test_cmd_handler
+   pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+   pc : __memcpy+0x168/0x230
+   lr : pci_epf_test_cmd_handler+0x6f0/0xa68
+   sp : ffff80001003bce0
+   x29: ffff80001003bce0 x28: ffff800010135000 x27: ffff8000101e5000
+   x26: ffff8000101cd000 x25: ffff6cda941cf6c8 x24: 0000000000000000
+   x23: ffff6cda863f2000 x22: ffff6cda9096c800 x21: ffff800010135000
+   x20: ffff6cda941cf680 x19: ffffaf39fd999000 x18: 0000000000000000
+   x17: 0000000000000000 x16: 0000000000000000 x15: ffffaf39fd2b6000
+   x14: 0000000000000000 x13: 15f5c8fa2f984d57 x12: 604d132b60275454
+   x11: 065cee5e5fb428b6 x10: aae662eb17d0cf3e x9 : 1d97c9a1b4ddef37
+   x8 : 7541b65edebf928c x7 : e71937c4fc595de0 x6 : b8a0e09562430d1c
+   x5 : ffff8000101e5401 x4 : ffff8000101cd401 x3 : ffff8000101e5380
+   x2 : fffffffffffffff1 x1 : ffff8000101cd3c0 x0 : ffff8000101e5000
+   Call trace:
+    __memcpy+0x168/0x230
+    process_one_work+0x1ec/0x370
+    worker_thread+0x44/0x478
+    kthread+0x154/0x160
+    ret_from_fork+0x10/0x20
+   Code: a984346c a9c4342c f1010042 54fffee8 (a97c3c8e)
+   ---[ end trace 568c28c7b6336335 ]---
+
+Link: https://lore.kernel.org/r/20211217094708.28678-1-Zhiqiang.Hou@nxp.com
+Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 90d84d3bc868..c7e45633beaf 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -285,7 +285,17 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
+               if (ret)
+                       dev_err(dev, "Data transfer failed\n");
+       } else {
+-              memcpy(dst_addr, src_addr, reg->size);
++              void *buf;
++
++              buf = kzalloc(reg->size, GFP_KERNEL);
++              if (!buf) {
++                      ret = -ENOMEM;
++                      goto err_map_addr;
++              }
++
++              memcpy_fromio(buf, src_addr, reg->size);
++              memcpy_toio(dst_addr, buf, reg->size);
++              kfree(buf);
+       }
+       ktime_get_ts64(&end);
+       pci_epf_test_print_rate("COPY", reg->size, &start, &end, use_dma);
+-- 
+2.35.1
+
diff --git a/queue-5.17/pci-endpoint-fix-misused-goto-label.patch b/queue-5.17/pci-endpoint-fix-misused-goto-label.patch
new file mode 100644 (file)
index 0000000..9bb9ae8
--- /dev/null
@@ -0,0 +1,36 @@
+From 8433f5cff0d98e50f511b14a7c4e879ac76ec113 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jan 2022 15:48:23 +0800
+Subject: PCI: endpoint: Fix misused goto label
+
+From: Li Chen <lchen@ambarella.com>
+
+[ Upstream commit bf8d87c076f55b8b4dfdb6bc6c6b6dc0c2ccb487 ]
+
+Fix a misused goto label jump since that can result in a memory leak.
+
+Link: https://lore.kernel.org/r/17e7b9b9ee6.c6d9c6a02564.4545388417402742326@zohomail.com
+Signed-off-by: Li Chen <lchen@ambarella.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index c7e45633beaf..5b833f00e980 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -451,7 +451,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
+               if (!epf_test->dma_supported) {
+                       dev_err(dev, "Cannot transfer data using DMA\n");
+                       ret = -EINVAL;
+-                      goto err_map_addr;
++                      goto err_dma_map;
+               }
+               src_phys_addr = dma_map_single(dma_dev, buf, reg->size,
+-- 
+2.35.1
+
diff --git a/queue-5.17/pci-pciehp-add-qualcomm-quirk-for-command-completed-.patch b/queue-5.17/pci-pciehp-add-qualcomm-quirk-for-command-completed-.patch
new file mode 100644 (file)
index 0000000..c50e0da
--- /dev/null
@@ -0,0 +1,44 @@
+From f3eab120373c507d20759611c8f156f3154b79ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 20:20:03 +0530
+Subject: PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 9f72d4757cbe4d1ed669192f6d23817c9e437c4b ]
+
+The Qualcomm PCI bridge device (Device ID 0x0110) found in chipsets such as
+SM8450 does not set the Command Completed bit unless writes to the Slot
+Command register change "Control" bits.
+
+This results in timeouts like below:
+
+  pcieport 0001:00:00.0: pciehp: Timeout on hotplug command 0x03c0 (issued 2020 msec ago)
+
+Add the device to the Command Completed quirk to mark commands "completed"
+immediately unless they change the "Control" bits.
+
+Link: https://lore.kernel.org/r/20220210145003.135907-1-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/pciehp_hpc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index 85dce560831a..040ae076ec0e 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -1086,6 +1086,8 @@ static void quirk_cmd_compl(struct pci_dev *pdev)
+ }
+ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+                             PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
++DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0110,
++                            PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
+ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0400,
+                             PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
+ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0401,
+-- 
+2.35.1
+
diff --git a/queue-5.17/phy-amlogic-meson8b-usb2-fix-shared-reset-control-us.patch b/queue-5.17/phy-amlogic-meson8b-usb2-fix-shared-reset-control-us.patch
new file mode 100644 (file)
index 0000000..839255b
--- /dev/null
@@ -0,0 +1,68 @@
+From 193fcfe4444ef2e2d802d82fc707dc80a47e02e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jan 2022 10:52:55 +0100
+Subject: phy: amlogic: meson8b-usb2: fix shared reset control use
+
+From: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+
+[ Upstream commit 6f1dedf089ab1a4f03ea7aadc3c4a99885b4b4a0 ]
+
+Use reset_control_rearm() call if an error occurs in case
+phy_meson8b_usb2_power_on() fails after reset() has been called, or in
+case phy_meson8b_usb2_power_off() is called i.e the resource is no longer
+used and the reset line may be triggered again by other devices.
+
+reset_control_rearm() keeps use of triggered_count sane in the reset
+framework, use of reset_control_reset() on shared reset line should
+be balanced with reset_control_rearm().
+
+Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+Reported-by: Jerome Brunet <jbrunet@baylibre.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Acked-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20220111095255.176141-4-aouledameur@baylibre.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/amlogic/phy-meson8b-usb2.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
+index 77e7e9b1428c..dd96763911b8 100644
+--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
++++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
+@@ -154,6 +154,7 @@ static int phy_meson8b_usb2_power_on(struct phy *phy)
+       ret = clk_prepare_enable(priv->clk_usb_general);
+       if (ret) {
+               dev_err(&phy->dev, "Failed to enable USB general clock\n");
++              reset_control_rearm(priv->reset);
+               return ret;
+       }
+@@ -161,6 +162,7 @@ static int phy_meson8b_usb2_power_on(struct phy *phy)
+       if (ret) {
+               dev_err(&phy->dev, "Failed to enable USB DDR clock\n");
+               clk_disable_unprepare(priv->clk_usb_general);
++              reset_control_rearm(priv->reset);
+               return ret;
+       }
+@@ -199,6 +201,7 @@ static int phy_meson8b_usb2_power_on(struct phy *phy)
+                               dev_warn(&phy->dev, "USB ID detect failed!\n");
+                               clk_disable_unprepare(priv->clk_usb);
+                               clk_disable_unprepare(priv->clk_usb_general);
++                              reset_control_rearm(priv->reset);
+                               return -EINVAL;
+                       }
+               }
+@@ -218,6 +221,7 @@ static int phy_meson8b_usb2_power_off(struct phy *phy)
+       clk_disable_unprepare(priv->clk_usb);
+       clk_disable_unprepare(priv->clk_usb_general);
++      reset_control_rearm(priv->reset);
+       /* power off the PHY by putting it into reset mode */
+       regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET,
+-- 
+2.35.1
+
diff --git a/queue-5.17/phy-amlogic-meson8b-usb2-use-dev_err_probe.patch b/queue-5.17/phy-amlogic-meson8b-usb2-use-dev_err_probe.patch
new file mode 100644 (file)
index 0000000..4ae3e1b
--- /dev/null
@@ -0,0 +1,42 @@
+From cfdb1eb94e4442f500ef9009c6ccd552ef0745f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jan 2022 10:52:54 +0100
+Subject: phy: amlogic: meson8b-usb2: Use dev_err_probe()
+
+From: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+
+[ Upstream commit 6466ba1898d415b527e1013bd8551a6fdfece94c ]
+
+Use the existing dev_err_probe() helper instead of open-coding the same
+operation.
+
+Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+Reported-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Acked-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20220111095255.176141-3-aouledameur@baylibre.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/amlogic/phy-meson8b-usb2.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
+index cf10bed40528..77e7e9b1428c 100644
+--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
++++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
+@@ -265,8 +265,9 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
+               return PTR_ERR(priv->clk_usb);
+       priv->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+-      if (PTR_ERR(priv->reset) == -EPROBE_DEFER)
+-              return PTR_ERR(priv->reset);
++      if (IS_ERR(priv->reset))
++              return dev_err_probe(&pdev->dev, PTR_ERR(priv->reset),
++                                   "Failed to get the reset line");
+       priv->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node, -1);
+       if (priv->dr_mode == USB_DR_MODE_UNKNOWN) {
+-- 
+2.35.1
+
diff --git a/queue-5.17/phy-amlogic-phy-meson-gxl-usb2-fix-shared-reset-cont.patch b/queue-5.17/phy-amlogic-phy-meson-gxl-usb2-fix-shared-reset-cont.patch
new file mode 100644 (file)
index 0000000..756435b
--- /dev/null
@@ -0,0 +1,57 @@
+From 22a801fe5daae0c8ebd23eab054d3801c63964df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jan 2022 10:52:53 +0100
+Subject: phy: amlogic: phy-meson-gxl-usb2: fix shared reset controller use
+
+From: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+
+[ Upstream commit 2f87727130ce17ffefecd0895eeebf22d5a36f6f ]
+
+Use reset_control_rearm() call if an error occurs in case
+phy_meson_gxl_usb2_init() fails after reset() has been called ; or in case
+phy_meson_gxl_usb2_exit() is called i.e the resource is no longer used
+and the reset line may be triggered again by other devices.
+
+reset_control_rearm() keeps use of triggered_count sane in the reset
+framework. Therefore, use of reset_control_reset() on shared reset line
+should be balanced with reset_control_rearm().
+
+Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+Reported-by: Jerome Brunet <jbrunet@baylibre.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Acked-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20220111095255.176141-2-aouledameur@baylibre.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb2.c b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
+index 2b3c0d730f20..db17c3448bfe 100644
+--- a/drivers/phy/amlogic/phy-meson-gxl-usb2.c
++++ b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
+@@ -114,8 +114,10 @@ static int phy_meson_gxl_usb2_init(struct phy *phy)
+               return ret;
+       ret = clk_prepare_enable(priv->clk);
+-      if (ret)
++      if (ret) {
++              reset_control_rearm(priv->reset);
+               return ret;
++      }
+       return 0;
+ }
+@@ -125,6 +127,7 @@ static int phy_meson_gxl_usb2_exit(struct phy *phy)
+       struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
+       clk_disable_unprepare(priv->clk);
++      reset_control_rearm(priv->reset);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/platform-x86-hp-wmi-fix-0x05-error-code-reported-by-.patch b/queue-5.17/platform-x86-hp-wmi-fix-0x05-error-code-reported-by-.patch
new file mode 100644 (file)
index 0000000..8caac3f
--- /dev/null
@@ -0,0 +1,153 @@
+From 228d11dda1c63386ffb641ca489a5e79502edfec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Mar 2022 15:08:52 -0600
+Subject: platform/x86: hp-wmi: Fix 0x05 error code reported by several WMI
+ calls
+
+From: Jorge Lopez <jorge.lopez2@hp.com>
+
+[ Upstream commit be9d73e64957bbd31ee9a0d11adc0f720974c558 ]
+
+Several WMI queries leverage hp_wmi_read_int function to read their
+data. hp_wmi_read_int function was corrected in a previous patch.
+Now, this function invokes hp_wmi_perform_query with input parameter
+of size zero and the output buffer of size 4.
+
+WMI commands calling hp_wmi_perform_query with input buffer size value
+of zero are listed below.
+
+HPWMI_DISPLAY_QUERY
+HPWMI_HDDTEMP_QUERY
+HPWMI_ALS_QUERY
+HPWMI_HARDWARE_QUERY
+HPWMI_WIRELESS_QUERY
+HPWMI_BIOS_QUERY
+HPWMI_FEATURE_QUERY
+HPWMI_HOTKEY_QUERY
+HPWMI_FEATURE2_QUERY
+HPWMI_WIRELESS2_QUERY
+HPWMI_POSTCODEERROR_QUERY
+HPWMI_THERMAL_PROFILE_QUERY
+HPWMI_FAN_SPEED_MAX_GET_QUERY
+
+Invoking those WMI commands with an input buffer size greater
+than zero will cause error 0x05 to be returned.
+
+All WMI commands executed by the driver were reviewed and changes
+were made to ensure the expected input and output buffer size match
+the WMI specification.
+
+Changes were validated on a HP ZBook Workstation notebook,
+HP EliteBook x360, and HP EliteBook 850 G8.  Additional
+validation was included in the test process to ensure no other
+commands were incorrectly handled.
+
+Signed-off-by: Jorge Lopez <jorge.lopez2@hp.com>
+Link: https://lore.kernel.org/r/20220310210853.28367-4-jorge.lopez2@hp.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/hp-wmi.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index f822ef6eb93c..88f0bfd6ecf1 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -330,7 +330,7 @@ static int hp_wmi_get_fan_speed(int fan)
+       char fan_data[4] = { fan, 0, 0, 0 };
+       int ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_GET_QUERY, HPWMI_GM,
+-                                     &fan_data, sizeof(fan_data),
++                                     &fan_data, sizeof(char),
+                                      sizeof(fan_data));
+       if (ret != 0)
+@@ -399,7 +399,7 @@ static int omen_thermal_profile_set(int mode)
+               return -EINVAL;
+       ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM,
+-                                 &buffer, sizeof(buffer), sizeof(buffer));
++                                 &buffer, sizeof(buffer), 0);
+       if (ret)
+               return ret < 0 ? ret : -EINVAL;
+@@ -436,7 +436,7 @@ static int hp_wmi_fan_speed_max_set(int enabled)
+       int ret;
+       ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_SET_QUERY, HPWMI_GM,
+-                                 &enabled, sizeof(enabled), sizeof(enabled));
++                                 &enabled, sizeof(enabled), 0);
+       if (ret)
+               return ret < 0 ? ret : -EINVAL;
+@@ -449,7 +449,7 @@ static int hp_wmi_fan_speed_max_get(void)
+       int val = 0, ret;
+       ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM,
+-                                 &val, sizeof(val), sizeof(val));
++                                 &val, 0, sizeof(val));
+       if (ret)
+               return ret < 0 ? ret : -EINVAL;
+@@ -461,7 +461,7 @@ static int __init hp_wmi_bios_2008_later(void)
+ {
+       int state = 0;
+       int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state,
+-                                     sizeof(state), sizeof(state));
++                                     0, sizeof(state));
+       if (!ret)
+               return 1;
+@@ -472,7 +472,7 @@ static int __init hp_wmi_bios_2009_later(void)
+ {
+       u8 state[128];
+       int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
+-                                     sizeof(state), sizeof(state));
++                                     0, sizeof(state));
+       if (!ret)
+               return 1;
+@@ -550,7 +550,7 @@ static int hp_wmi_rfkill2_refresh(void)
+       int err, i;
+       err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
+-                                 sizeof(state), sizeof(state));
++                                 0, sizeof(state));
+       if (err)
+               return err;
+@@ -639,7 +639,7 @@ static ssize_t als_store(struct device *dev, struct device_attribute *attr,
+               return ret;
+       ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp,
+-                                     sizeof(tmp), sizeof(tmp));
++                                     sizeof(tmp), 0);
+       if (ret)
+               return ret < 0 ? ret : -EINVAL;
+@@ -660,9 +660,9 @@ static ssize_t postcode_store(struct device *dev, struct device_attribute *attr,
+       if (clear == false)
+               return -EINVAL;
+-      /* Clear the POST error code. It is kept until until cleared. */
++      /* Clear the POST error code. It is kept until cleared. */
+       ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, HPWMI_WRITE, &tmp,
+-                                     sizeof(tmp), sizeof(tmp));
++                                     sizeof(tmp), 0);
+       if (ret)
+               return ret < 0 ? ret : -EINVAL;
+@@ -952,7 +952,7 @@ static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
+       int err, i;
+       err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
+-                                 sizeof(state), sizeof(state));
++                                 0, sizeof(state));
+       if (err)
+               return err < 0 ? err : -EINVAL;
+-- 
+2.35.1
+
diff --git a/queue-5.17/platform-x86-hp-wmi-fix-sw_tablet_mode-detection-met.patch b/queue-5.17/platform-x86-hp-wmi-fix-sw_tablet_mode-detection-met.patch
new file mode 100644 (file)
index 0000000..5cc0977
--- /dev/null
@@ -0,0 +1,197 @@
+From fcff105aba5f956d4cc1623ea46607bfef889520 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Mar 2022 15:08:51 -0600
+Subject: platform/x86: hp-wmi: Fix SW_TABLET_MODE detection method
+
+From: Jorge Lopez <jorge.lopez2@hp.com>
+
+[ Upstream commit 520ee4ea1cc60251a6e3c911cf0336278aa52634 ]
+
+The purpose of this patch is to introduce a fix and removal of the
+current hack when determining tablet mode status.
+
+Determining the tablet mode status requires reading Byte 0 bit 2 as
+reported by HPWMI_HARDWARE_QUERY.  The investigation identified the
+failure was rooted in two areas: HPWMI_HARDWARE_QUERY failure (0x05)
+and reading Byte 0, bit 2 only to determine the table mode status.
+HPWMI_HARDWARE_QUERY WMI failure also rendered the dock state value
+invalid.
+
+The latest changes use SMBIOS Type 3 (chassis type) and WMI Command
+0x40 (device_mode_status) information to determine if the device is
+in tablet mode or not.
+
+hp_wmi_hw_state function was split into two functions;
+hp_wmi_get_dock_state and hp_wmi_get_tablet_mode.  The new functions
+separate how dock_state and tablet_mode is handled in a cleaner
+manner.
+
+All changes were validated on a HP ZBook Workstation notebook,
+HP EliteBook x360, and HP EliteBook 850 G8.
+
+Signed-off-by: Jorge Lopez <jorge.lopez2@hp.com>
+Link: https://lore.kernel.org/r/20220310210853.28367-3-jorge.lopez2@hp.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/hp-wmi.c | 71 +++++++++++++++++++++++++----------
+ 1 file changed, 52 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index 48a46466f086..f822ef6eb93c 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -35,10 +35,6 @@ MODULE_LICENSE("GPL");
+ MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
+ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
+-static int enable_tablet_mode_sw = -1;
+-module_param(enable_tablet_mode_sw, int, 0444);
+-MODULE_PARM_DESC(enable_tablet_mode_sw, "Enable SW_TABLET_MODE reporting (-1=auto, 0=no, 1=yes)");
+-
+ #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
+ #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
+ #define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95
+@@ -107,6 +103,7 @@ enum hp_wmi_commandtype {
+       HPWMI_FEATURE2_QUERY            = 0x0d,
+       HPWMI_WIRELESS2_QUERY           = 0x1b,
+       HPWMI_POSTCODEERROR_QUERY       = 0x2a,
++      HPWMI_SYSTEM_DEVICE_MODE        = 0x40,
+       HPWMI_THERMAL_PROFILE_QUERY     = 0x4c,
+ };
+@@ -217,6 +214,19 @@ struct rfkill2_device {
+ static int rfkill2_count;
+ static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
++/*
++ * Chassis Types values were obtained from SMBIOS reference
++ * specification version 3.00. A complete list of system enclosures
++ * and chassis types is available on Table 17.
++ */
++static const char * const tablet_chassis_types[] = {
++      "30", /* Tablet*/
++      "31", /* Convertible */
++      "32"  /* Detachable */
++};
++
++#define DEVICE_MODE_TABLET    0x06
++
+ /* map output size to the corresponding WMI method id */
+ static inline int encode_outsize_for_pvsz(int outsize)
+ {
+@@ -345,14 +355,39 @@ static int hp_wmi_read_int(int query)
+       return val;
+ }
+-static int hp_wmi_hw_state(int mask)
++static int hp_wmi_get_dock_state(void)
+ {
+       int state = hp_wmi_read_int(HPWMI_HARDWARE_QUERY);
+       if (state < 0)
+               return state;
+-      return !!(state & mask);
++      return !!(state & HPWMI_DOCK_MASK);
++}
++
++static int hp_wmi_get_tablet_mode(void)
++{
++      char system_device_mode[4] = { 0 };
++      const char *chassis_type;
++      bool tablet_found;
++      int ret;
++
++      chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
++      if (!chassis_type)
++              return -ENODEV;
++
++      tablet_found = match_string(tablet_chassis_types,
++                                  ARRAY_SIZE(tablet_chassis_types),
++                                  chassis_type) >= 0;
++      if (!tablet_found)
++              return -ENODEV;
++
++      ret = hp_wmi_perform_query(HPWMI_SYSTEM_DEVICE_MODE, HPWMI_READ,
++                                 system_device_mode, 0, sizeof(system_device_mode));
++      if (ret < 0)
++              return ret;
++
++      return system_device_mode[0] == DEVICE_MODE_TABLET;
+ }
+ static int omen_thermal_profile_set(int mode)
+@@ -568,7 +603,7 @@ static ssize_t als_show(struct device *dev, struct device_attribute *attr,
+ static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+ {
+-      int value = hp_wmi_hw_state(HPWMI_DOCK_MASK);
++      int value = hp_wmi_get_dock_state();
+       if (value < 0)
+               return value;
+       return sprintf(buf, "%d\n", value);
+@@ -577,7 +612,7 @@ static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
+ static ssize_t tablet_show(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+ {
+-      int value = hp_wmi_hw_state(HPWMI_TABLET_MASK);
++      int value = hp_wmi_get_tablet_mode();
+       if (value < 0)
+               return value;
+       return sprintf(buf, "%d\n", value);
+@@ -699,10 +734,10 @@ static void hp_wmi_notify(u32 value, void *context)
+       case HPWMI_DOCK_EVENT:
+               if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
+                       input_report_switch(hp_wmi_input_dev, SW_DOCK,
+-                                          hp_wmi_hw_state(HPWMI_DOCK_MASK));
++                                          hp_wmi_get_dock_state());
+               if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
+                       input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
+-                                          hp_wmi_hw_state(HPWMI_TABLET_MASK));
++                                          hp_wmi_get_tablet_mode());
+               input_sync(hp_wmi_input_dev);
+               break;
+       case HPWMI_PARK_HDD:
+@@ -780,19 +815,17 @@ static int __init hp_wmi_input_setup(void)
+       __set_bit(EV_SW, hp_wmi_input_dev->evbit);
+       /* Dock */
+-      val = hp_wmi_hw_state(HPWMI_DOCK_MASK);
++      val = hp_wmi_get_dock_state();
+       if (!(val < 0)) {
+               __set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
+               input_report_switch(hp_wmi_input_dev, SW_DOCK, val);
+       }
+       /* Tablet mode */
+-      if (enable_tablet_mode_sw > 0) {
+-              val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
+-              if (val >= 0) {
+-                      __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
+-                      input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
+-              }
++      val = hp_wmi_get_tablet_mode();
++      if (!(val < 0)) {
++              __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
++              input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
+       }
+       err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
+@@ -1227,10 +1260,10 @@ static int hp_wmi_resume_handler(struct device *device)
+       if (hp_wmi_input_dev) {
+               if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
+                       input_report_switch(hp_wmi_input_dev, SW_DOCK,
+-                                          hp_wmi_hw_state(HPWMI_DOCK_MASK));
++                                          hp_wmi_get_dock_state());
+               if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
+                       input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
+-                                          hp_wmi_hw_state(HPWMI_TABLET_MASK));
++                                          hp_wmi_get_tablet_mode());
+               input_sync(hp_wmi_input_dev);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.17/platform-x86-thinkpad_acpi-add-dual-fan-probe.patch b/queue-5.17/platform-x86-thinkpad_acpi-add-dual-fan-probe.patch
new file mode 100644 (file)
index 0000000..fcfccea
--- /dev/null
@@ -0,0 +1,81 @@
+From 8df67e3dbf141e129ebe81fce78766c7e2901d0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Feb 2022 13:51:37 -0500
+Subject: platform/x86: thinkpad_acpi: Add dual fan probe
+
+From: Mark Pearson <markpearson@lenovo.com>
+
+[ Upstream commit bf779aaf56ea23864e39e9862b3b3a8436236e07 ]
+
+Instead of having quirks for systems that have a second fan it would
+be nice to detect this setup.
+Unfortunately, confirmed by the Lenovo FW team, there is no way to
+retrieve this information from the EC or BIOS. Recommendation was to
+attempt to read the fan and if successful then assume a 2nd fan is
+present.
+
+The fans are also supposed to spin up on boot for some time, so in
+theory we could check for a speed > 0. In testing this seems to hold
+true but as I couldn't test on all platforms I've avoided implementing
+this. It also breaks for the corner case where you load the module
+once the fans are idle.
+
+Tested on P1G4, P1G3, X1C9 and T14 (no fans) and it works correctly.
+For the platforms with dual fans where it was confirmed to work I have
+removed the quirks. Potentially this could be done for all platforms
+but I've left untested platforms in for now. On these platforms the
+fans will be enabled and then detected - so no impact.
+
+Signed-off-by: Mark Pearson <markpearson@lenovo.com>
+Link: https://lore.kernel.org/r/20220222185137.4325-1-markpearson@lenovo.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/thinkpad_acpi.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 3424b080db77..3fb8cda31eb9 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -8699,10 +8699,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
+       TPACPI_Q_LNV3('N', '2', 'N', TPACPI_FAN_2CTL),  /* P53 / P73 */
+       TPACPI_Q_LNV3('N', '2', 'E', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (1st gen) */
+       TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (2nd gen) */
+-      TPACPI_Q_LNV3('N', '2', 'V', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (3nd gen) */
+-      TPACPI_Q_LNV3('N', '4', '0', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (4nd gen) */
+       TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL),  /* P15 (1st gen) / P15v (1st gen) */
+-      TPACPI_Q_LNV3('N', '3', '2', TPACPI_FAN_2CTL),  /* X1 Carbon (9th gen) */
+       TPACPI_Q_LNV3('N', '3', '7', TPACPI_FAN_2CTL),  /* T15g (2nd gen) */
+       TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */
+ };
+@@ -8746,6 +8743,9 @@ static int __init fan_init(struct ibm_init_struct *iibm)
+                * ThinkPad ECs supports the fan control register */
+               if (likely(acpi_ec_read(fan_status_offset,
+                                       &fan_control_initial_status))) {
++                      int res;
++                      unsigned int speed;
++
+                       fan_status_access_mode = TPACPI_FAN_RD_TPEC;
+                       if (quirks & TPACPI_FAN_Q1)
+                               fan_quirk1_setup();
+@@ -8758,6 +8758,15 @@ static int __init fan_init(struct ibm_init_struct *iibm)
+                               tp_features.second_fan_ctl = 1;
+                               pr_info("secondary fan control enabled\n");
+                       }
++                      /* Try and probe the 2nd fan */
++                      res = fan2_get_speed(&speed);
++                      if (res >= 0) {
++                              /* It responded - so let's assume it's there */
++                              tp_features.second_fan = 1;
++                              tp_features.second_fan_ctl = 1;
++                              pr_info("secondary fan control detected & enabled\n");
++                      }
++
+               } else {
+                       pr_err("ThinkPad ACPI EC access misbehaving, fan status and control unavailable\n");
+                       return -ENODEV;
+-- 
+2.35.1
+
diff --git a/queue-5.17/platform-x86-x86-android-tablets-depend-on-efi-and-s.patch b/queue-5.17/platform-x86-x86-android-tablets-depend-on-efi-and-s.patch
new file mode 100644 (file)
index 0000000..255b4ba
--- /dev/null
@@ -0,0 +1,39 @@
+From b228e7a5ef7a53774249e809b50f58f1f203d0fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Mar 2022 16:29:42 +0100
+Subject: platform/x86: x86-android-tablets: Depend on EFI and SPI
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 1e8aa2aa1274953e8e595f0630436744597d0d64 ]
+
+The recently added support for Lenovo Yoga Tablet 2 tablets uses
+symbols from EFI and SPI add "depends on EFI && SPI" to the
+X86_ANDROID_TABLETS Kconfig entry.
+
+Reported-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Randy Dunlap <rdunlap@infradead.org>
+Tested-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://lore.kernel.org/r/20220308152942.262130-1-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
+index 24deeeb29af2..53abd553b842 100644
+--- a/drivers/platform/x86/Kconfig
++++ b/drivers/platform/x86/Kconfig
+@@ -1027,7 +1027,7 @@ config TOUCHSCREEN_DMI
+ config X86_ANDROID_TABLETS
+       tristate "X86 Android tablet support"
+-      depends on I2C && SERIAL_DEV_BUS && ACPI && GPIOLIB
++      depends on I2C && SPI && SERIAL_DEV_BUS && ACPI && EFI && GPIOLIB
+       help
+         X86 tablets which ship with Android as (part of) the factory image
+         typically have various problems with their DSDTs. The factory kernels
+-- 
+2.35.1
+
diff --git a/queue-5.17/power-supply-axp20x_battery-properly-report-current-.patch b/queue-5.17/power-supply-axp20x_battery-properly-report-current-.patch
new file mode 100644 (file)
index 0000000..4e3c2a4
--- /dev/null
@@ -0,0 +1,63 @@
+From a4ad35bd615099006add686d08ddf19df4597e70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jan 2022 11:47:27 +0300
+Subject: power: supply: axp20x_battery: properly report current when
+ discharging
+
+From: Evgeny Boger <boger@wirenboard.com>
+
+[ Upstream commit d4f408cdcd26921c1268cb8dcbe8ffb6faf837f3 ]
+
+As stated in [1], negative current values are used for discharging
+batteries.
+
+AXP PMICs internally have two different ADC channels for shunt current
+measurement: one used during charging and one during discharging.
+The values reported by these ADCs are unsigned.
+While the driver properly selects ADC channel to get the data from,
+it doesn't apply negative sign when reporting discharging current.
+
+[1] Documentation/ABI/testing/sysfs-class-power
+
+Signed-off-by: Evgeny Boger <boger@wirenboard.com>
+Acked-by: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/axp20x_battery.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
+index 5d197141f476..9106077c0dbb 100644
+--- a/drivers/power/supply/axp20x_battery.c
++++ b/drivers/power/supply/axp20x_battery.c
+@@ -186,7 +186,6 @@ static int axp20x_battery_get_prop(struct power_supply *psy,
+                                  union power_supply_propval *val)
+ {
+       struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
+-      struct iio_channel *chan;
+       int ret = 0, reg, val1;
+       switch (psp) {
+@@ -266,12 +265,12 @@ static int axp20x_battery_get_prop(struct power_supply *psy,
+               if (ret)
+                       return ret;
+-              if (reg & AXP20X_PWR_STATUS_BAT_CHARGING)
+-                      chan = axp20x_batt->batt_chrg_i;
+-              else
+-                      chan = axp20x_batt->batt_dischrg_i;
+-
+-              ret = iio_read_channel_processed(chan, &val->intval);
++              if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
++                      ret = iio_read_channel_processed(axp20x_batt->batt_chrg_i, &val->intval);
++              } else {
++                      ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i, &val1);
++                      val->intval = -val1;
++              }
+               if (ret)
+                       return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.17/power-supply-axp288-charger-set-vhold-to-4.4v.patch b/queue-5.17/power-supply-axp288-charger-set-vhold-to-4.4v.patch
new file mode 100644 (file)
index 0000000..279ac3f
--- /dev/null
@@ -0,0 +1,85 @@
+From e65e064aae84d8e45a29ca9715b451cb0aa600f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Feb 2022 13:51:47 +0100
+Subject: power: supply: axp288-charger: Set Vhold to 4.4V
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 5ac121b81b4051e7fc83d5b3456a5e499d5bd147 ]
+
+The AXP288's recommended and factory default Vhold value (minimum
+input voltage below which the input current draw will be reduced)
+is 4.4V. This lines up with other charger IC's such as the TI
+bq2419x/bq2429x series which use 4.36V or 4.44V.
+
+For some reason some BIOS-es initialize Vhold to 4.6V or even 4.7V
+which combined with the typical voltage drop over typically low
+wire gauge micro-USB cables leads to the input-current getting
+capped below 1A (with a 2A capable dedicated charger) based on Vhold.
+
+This leads to slow charging, or even to the device slowly discharging
+if the device is in heavy use.
+
+As the Linux AXP288 drivers use the builtin BC1.2 charger detection
+and send the input-current-limit according to the detected charger
+there really is no reason not to use the recommended 4.4V Vhold.
+
+Set Vhold to 4.4V to fix the slow charging issue on various devices.
+
+There is one exception, the special-case of the HP X2 2-in-1s which
+combine this BC1.2 capable PMIC with a Type-C port and a 5V/3A factory
+provided charger with a Type-C plug which does not do BC1.2. These
+have their input-current-limit hardcoded to 3A (like under Windows)
+and use a higher Vhold on purpose to limit the current when used
+with other chargers. To avoid touching Vhold on these HP X2 laptops
+the code setting Vhold is added to an else branch of the if checking
+for these models.
+
+Note this also fixes the sofar unused VBUS_ISPOUT_VHOLD_SET_MASK
+define, which was wrong.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/axp288_charger.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/supply/axp288_charger.c b/drivers/power/supply/axp288_charger.c
+index ec41f6cd3f93..c498e62ab4e2 100644
+--- a/drivers/power/supply/axp288_charger.c
++++ b/drivers/power/supply/axp288_charger.c
+@@ -42,11 +42,11 @@
+ #define VBUS_ISPOUT_CUR_LIM_1500MA    0x1     /* 1500mA */
+ #define VBUS_ISPOUT_CUR_LIM_2000MA    0x2     /* 2000mA */
+ #define VBUS_ISPOUT_CUR_NO_LIM                0x3     /* 2500mA */
+-#define VBUS_ISPOUT_VHOLD_SET_MASK    0x31
++#define VBUS_ISPOUT_VHOLD_SET_MASK    0x38
+ #define VBUS_ISPOUT_VHOLD_SET_BIT_POS 0x3
+ #define VBUS_ISPOUT_VHOLD_SET_OFFSET  4000    /* 4000mV */
+ #define VBUS_ISPOUT_VHOLD_SET_LSB_RES 100     /* 100mV */
+-#define VBUS_ISPOUT_VHOLD_SET_4300MV  0x3     /* 4300mV */
++#define VBUS_ISPOUT_VHOLD_SET_4400MV  0x4     /* 4400mV */
+ #define VBUS_ISPOUT_VBUS_PATH_DIS     BIT(7)
+ #define CHRG_CCCV_CC_MASK             0xf             /* 4 bits */
+@@ -769,6 +769,16 @@ static int charger_init_hw_regs(struct axp288_chrg_info *info)
+               ret = axp288_charger_vbus_path_select(info, true);
+               if (ret < 0)
+                       return ret;
++      } else {
++              /* Set Vhold to the factory default / recommended 4.4V */
++              val = VBUS_ISPOUT_VHOLD_SET_4400MV << VBUS_ISPOUT_VHOLD_SET_BIT_POS;
++              ret = regmap_update_bits(info->regmap, AXP20X_VBUS_IPSOUT_MGMT,
++                                       VBUS_ISPOUT_VHOLD_SET_MASK, val);
++              if (ret < 0) {
++                      dev_err(&info->pdev->dev, "register(%x) write error(%d)\n",
++                              AXP20X_VBUS_IPSOUT_MGMT, ret);
++                      return ret;
++              }
+       }
+       /* Read current charge voltage and current limit */
+-- 
+2.35.1
+
diff --git a/queue-5.17/power-supply-axp288_charger-use-acpi_quirk_skip_acpi.patch b/queue-5.17/power-supply-axp288_charger-use-acpi_quirk_skip_acpi.patch
new file mode 100644 (file)
index 0000000..fa72ca0
--- /dev/null
@@ -0,0 +1,66 @@
+From d922321d4457bb71d5187fd121954b8f4f2f7ada Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 23:28:04 +0100
+Subject: power: supply: axp288_charger: Use
+ acpi_quirk_skip_acpi_ac_and_battery()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 00d0566614b7bb7b226cb5a6895b0180ffe6915a ]
+
+Normally the native AXP288 fg/charger drivers are preferred but one some
+devices the ACPI drivers should be used instead.
+
+The ACPI battery/ac drivers use the acpi_quirk_skip_acpi_ac_and_battery()
+helper to determine if they should skip loading because native fuel-gauge/
+charger drivers like the AXP288 drivers will be used.
+
+The new acpi_quirk_skip_acpi_ac_and_battery() helper includes a list of
+exceptions for boards where the ACPI drivers should be used instead.
+
+Use this new helper to avoid loading on such boards. Note this requires
+adding a Kconfig dependency on ACPI, this is not a problem because ACPI
+should be enabled on all boards with an AXP288 PMIC anyways.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/Kconfig          | 2 +-
+ drivers/power/supply/axp288_charger.c | 7 +++++++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
+index b366e2fd8e97..d7534f12e9ef 100644
+--- a/drivers/power/supply/Kconfig
++++ b/drivers/power/supply/Kconfig
+@@ -351,7 +351,7 @@ config AXP20X_POWER
+ config AXP288_CHARGER
+       tristate "X-Powers AXP288 Charger"
+-      depends on MFD_AXP20X && EXTCON_AXP288 && IOSF_MBI
++      depends on MFD_AXP20X && EXTCON_AXP288 && IOSF_MBI && ACPI
+       help
+         Say yes here to have support X-Power AXP288 power management IC (PMIC)
+         integrated charger.
+diff --git a/drivers/power/supply/axp288_charger.c b/drivers/power/supply/axp288_charger.c
+index c498e62ab4e2..19746e658a6a 100644
+--- a/drivers/power/supply/axp288_charger.c
++++ b/drivers/power/supply/axp288_charger.c
+@@ -838,6 +838,13 @@ static int axp288_charger_probe(struct platform_device *pdev)
+       struct power_supply_config charger_cfg = {};
+       unsigned int val;
++      /*
++       * Normally the native AXP288 fg/charger drivers are preferred but
++       * on some devices the ACPI drivers should be used instead.
++       */
++      if (!acpi_quirk_skip_acpi_ac_and_battery())
++              return -ENODEV;
++
+       /*
+        * On some devices the fuelgauge and charger parts of the axp288 are
+        * not used, check that the fuelgauge is enabled (CC_CTRL != 0).
+-- 
+2.35.1
+
diff --git a/queue-5.17/power-supply-axp288_fuel_gauge-use-acpi_quirk_skip_a.patch b/queue-5.17/power-supply-axp288_fuel_gauge-use-acpi_quirk_skip_a.patch
new file mode 100644 (file)
index 0000000..58411cb
--- /dev/null
@@ -0,0 +1,87 @@
+From 29b1b059aa0cd1381bc3eb914d9e3cf82b17f25f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 23:28:05 +0100
+Subject: power: supply: axp288_fuel_gauge: Use
+ acpi_quirk_skip_acpi_ac_and_battery()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit da365db704d290fb4dc4cdbd41f60b0ecec1cc03 ]
+
+Normally the native AXP288 fg/charger drivers are preferred but one some
+devices the ACPI drivers should be used instead.
+
+The ACPI battery/ac drivers use the acpi_quirk_skip_acpi_ac_and_battery()
+helper to determine if they should skip loading because native fuel-gauge/
+charger drivers like the AXP288 drivers will be used.
+
+The new acpi_quirk_skip_acpi_ac_and_battery() helper includes a list of
+exceptions for boards where the ACPI drivers should be used instead.
+
+Use this new helper to avoid loading on such boards. Note this requires
+adding a Kconfig dependency on ACPI, this is not a problem because ACPI
+should be enabled on all boards with an AXP288 PMIC anyways.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/Kconfig             |  2 +-
+ drivers/power/supply/axp288_fuel_gauge.c | 14 ++++++++------
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
+index d7534f12e9ef..5e4a69352811 100644
+--- a/drivers/power/supply/Kconfig
++++ b/drivers/power/supply/Kconfig
+@@ -358,7 +358,7 @@ config AXP288_CHARGER
+ config AXP288_FUEL_GAUGE
+       tristate "X-Powers AXP288 Fuel Gauge"
+-      depends on MFD_AXP20X && IIO && IOSF_MBI
++      depends on MFD_AXP20X && IIO && IOSF_MBI && ACPI
+       help
+         Say yes here to have support for X-Power power management IC (PMIC)
+         Fuel Gauge. The device provides battery statistics and status
+diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c
+index c1da217fdb0e..ce8ffd0a41b5 100644
+--- a/drivers/power/supply/axp288_fuel_gauge.c
++++ b/drivers/power/supply/axp288_fuel_gauge.c
+@@ -9,6 +9,7 @@
+  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  */
++#include <linux/acpi.h>
+ #include <linux/dmi.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -560,12 +561,6 @@ static const struct dmi_system_id axp288_no_battery_list[] = {
+                       DMI_EXACT_MATCH(DMI_BIOS_VERSION, "1.000"),
+               },
+       },
+-      {
+-              /* ECS EF20EA */
+-              .matches = {
+-                      DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
+-              },
+-      },
+       {
+               /* Intel Cherry Trail Compute Stick, Windows version */
+               .matches = {
+@@ -624,6 +619,13 @@ static int axp288_fuel_gauge_probe(struct platform_device *pdev)
+       };
+       unsigned int val;
++      /*
++       * Normally the native AXP288 fg/charger drivers are preferred but
++       * on some devices the ACPI drivers should be used instead.
++       */
++      if (!acpi_quirk_skip_acpi_ac_and_battery())
++              return -ENODEV;
++
+       if (dmi_check_system(axp288_no_battery_list))
+               return -ENODEV;
+-- 
+2.35.1
+
diff --git a/queue-5.17/powerpc-64e-tie-ppc_book3e_64-to-ppc_fsl_book3e.patch b/queue-5.17/powerpc-64e-tie-ppc_book3e_64-to-ppc_fsl_book3e.patch
new file mode 100644 (file)
index 0000000..6f37fa2
--- /dev/null
@@ -0,0 +1,60 @@
+From 54f8b673b00476cd4dc8874d7dfe37340675279b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 17:12:22 +1100
+Subject: powerpc/64e: Tie PPC_BOOK3E_64 to PPC_FSL_BOOK3E
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 1a76e520ee1831a81dabf8a9a58c6453f700026e ]
+
+Since the IBM A2 CPU support was removed, see commit
+fb5a515704d7 ("powerpc: Remove platforms/wsp and associated pieces"),
+the only 64-bit Book3E CPUs we support are Freescale (NXP) ones.
+
+However our Kconfig still allows configurating a kernel that has 64-bit
+Book3E support, but no Freescale CPU support enabled. Such a kernel
+would never boot, it doesn't know about any CPUs.
+
+It also causes build errors, as reported by lkp, because
+PPC_BARRIER_NOSPEC is not enabled in such a configuration:
+
+  powerpc64-linux-ld: arch/powerpc/net/bpf_jit_comp64.o:(.toc+0x0):
+  undefined reference to `powerpc_security_features'
+
+To fix this, force PPC_FSL_BOOK3E to be selected whenever we are
+building a 64-bit Book3E kernel.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
+Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220304061222.2478720-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/Kconfig.cputype | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
+index 87bc1929ee5a..e2e1fec91c6e 100644
+--- a/arch/powerpc/platforms/Kconfig.cputype
++++ b/arch/powerpc/platforms/Kconfig.cputype
+@@ -107,6 +107,7 @@ config PPC_BOOK3S_64
+ config PPC_BOOK3E_64
+       bool "Embedded processors"
++      select PPC_FSL_BOOK3E
+       select PPC_FPU # Make it a choice ?
+       select PPC_SMP_MUXED_IPI
+       select PPC_DOORBELL
+@@ -295,7 +296,7 @@ config FSL_BOOKE
+ config PPC_FSL_BOOK3E
+       bool
+       select ARCH_SUPPORTS_HUGETLBFS if PHYS_64BIT || PPC64
+-      select FSL_EMB_PERFMON
++      imply FSL_EMB_PERFMON
+       select PPC_SMP_MUXED_IPI
+       select PPC_DOORBELL
+       select PPC_KUEP
+-- 
+2.35.1
+
diff --git a/queue-5.17/powerpc-64s-hash-make-hash-faults-work-in-nmi-contex.patch b/queue-5.17/powerpc-64s-hash-make-hash-faults-work-in-nmi-contex.patch
new file mode 100644 (file)
index 0000000..9d5d53a
--- /dev/null
@@ -0,0 +1,231 @@
+From d4461096a8a8a700fcd816548938e781e65ac732 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 13:53:48 +1000
+Subject: powerpc/64s/hash: Make hash faults work in NMI context
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 8b91cee5eadd2021f55e6775f2d50bd56d00c217 ]
+
+Hash faults are not resoved in NMI context, instead causing the access
+to fail. This is done because perf interrupts can get backtraces
+including walking the user stack, and taking a hash fault on those could
+deadlock on the HPTE lock if the perf interrupt hits while the same HPTE
+lock is being held by the hash fault code. The user-access for the stack
+walking will notice the access failed and deal with that in the perf
+code.
+
+The reason to allow perf interrupts in is to better profile hash faults.
+
+The problem with this is any hash fault on a kernel access that happens
+in NMI context will crash, because kernel accesses must not fail.
+
+Hard lockups, system reset, machine checks that access vmalloc space
+including modules and including stack backtracing and symbol lookup in
+modules, per-cpu data, etc could all run into this problem.
+
+Fix this by disallowing perf interrupts in the hash fault code (the
+direct hash fault is covered by MSR[EE]=0 so the PMI disable just needs
+to extend to the preload case). This simplifies the tricky logic in hash
+faults and perf, at the cost of reduced profiling of hash faults.
+
+perf can still latch addresses when interrupts are disabled, it just
+won't get the stack trace at that point, so it would still find hot
+spots, just sometimes with confusing stack chains.
+
+An alternative could be to allow perf interrupts here but always do the
+slowpath stack walk if we are in nmi context, but that slows down all
+perf interrupt stack walking on hash though and it does not remove as
+much tricky code.
+
+Reported-by: Laurent Dufour <ldufour@linux.ibm.com>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Tested-by: Laurent Dufour <ldufour@linux.ibm.com>
+Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220204035348.545435-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/interrupt.h  |  2 +-
+ arch/powerpc/mm/book3s64/hash_utils.c | 54 ++++-----------------------
+ arch/powerpc/perf/callchain.h         |  9 +----
+ arch/powerpc/perf/callchain_64.c      | 27 --------------
+ 4 files changed, 10 insertions(+), 82 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
+index fc28f46d2f9d..5404f7abbcf8 100644
+--- a/arch/powerpc/include/asm/interrupt.h
++++ b/arch/powerpc/include/asm/interrupt.h
+@@ -612,7 +612,7 @@ DECLARE_INTERRUPT_HANDLER_RAW(do_slb_fault);
+ DECLARE_INTERRUPT_HANDLER(do_bad_segment_interrupt);
+ /* hash_utils.c */
+-DECLARE_INTERRUPT_HANDLER_RAW(do_hash_fault);
++DECLARE_INTERRUPT_HANDLER(do_hash_fault);
+ /* fault.c */
+ DECLARE_INTERRUPT_HANDLER(do_page_fault);
+diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
+index 7abf82a698d3..985cabdd7f67 100644
+--- a/arch/powerpc/mm/book3s64/hash_utils.c
++++ b/arch/powerpc/mm/book3s64/hash_utils.c
+@@ -1621,8 +1621,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
+ }
+ EXPORT_SYMBOL_GPL(hash_page);
+-DECLARE_INTERRUPT_HANDLER(__do_hash_fault);
+-DEFINE_INTERRUPT_HANDLER(__do_hash_fault)
++DEFINE_INTERRUPT_HANDLER(do_hash_fault)
+ {
+       unsigned long ea = regs->dar;
+       unsigned long dsisr = regs->dsisr;
+@@ -1681,35 +1680,6 @@ DEFINE_INTERRUPT_HANDLER(__do_hash_fault)
+       }
+ }
+-/*
+- * The _RAW interrupt entry checks for the in_nmi() case before
+- * running the full handler.
+- */
+-DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault)
+-{
+-      /*
+-       * If we are in an "NMI" (e.g., an interrupt when soft-disabled), then
+-       * don't call hash_page, just fail the fault. This is required to
+-       * prevent re-entrancy problems in the hash code, namely perf
+-       * interrupts hitting while something holds H_PAGE_BUSY, and taking a
+-       * hash fault. See the comment in hash_preload().
+-       *
+-       * We come here as a result of a DSI at a point where we don't want
+-       * to call hash_page, such as when we are accessing memory (possibly
+-       * user memory) inside a PMU interrupt that occurred while interrupts
+-       * were soft-disabled.  We want to invoke the exception handler for
+-       * the access, or panic if there isn't a handler.
+-       */
+-      if (unlikely(in_nmi())) {
+-              do_bad_page_fault_segv(regs);
+-              return 0;
+-      }
+-
+-      __do_hash_fault(regs);
+-
+-      return 0;
+-}
+-
+ #ifdef CONFIG_PPC_MM_SLICES
+ static bool should_hash_preload(struct mm_struct *mm, unsigned long ea)
+ {
+@@ -1776,26 +1746,18 @@ static void hash_preload(struct mm_struct *mm, pte_t *ptep, unsigned long ea,
+ #endif /* CONFIG_PPC_64K_PAGES */
+       /*
+-       * __hash_page_* must run with interrupts off, as it sets the
+-       * H_PAGE_BUSY bit. It's possible for perf interrupts to hit at any
+-       * time and may take a hash fault reading the user stack, see
+-       * read_user_stack_slow() in the powerpc/perf code.
+-       *
+-       * If that takes a hash fault on the same page as we lock here, it
+-       * will bail out when seeing H_PAGE_BUSY set, and retry the access
+-       * leading to an infinite loop.
++       * __hash_page_* must run with interrupts off, including PMI interrupts
++       * off, as it sets the H_PAGE_BUSY bit.
+        *
+-       * Disabling interrupts here does not prevent perf interrupts, but it
+-       * will prevent them taking hash faults (see the NMI test in
+-       * do_hash_page), then read_user_stack's copy_from_user_nofault will
+-       * fail and perf will fall back to read_user_stack_slow(), which
+-       * walks the Linux page tables.
++       * It's otherwise possible for perf interrupts to hit at any time and
++       * may take a hash fault reading the user stack, which could take a
++       * hash miss and deadlock on the same H_PAGE_BUSY bit.
+        *
+        * Interrupts must also be off for the duration of the
+        * mm_is_thread_local test and update, to prevent preempt running the
+        * mm on another CPU (XXX: this may be racy vs kthread_use_mm).
+        */
+-      local_irq_save(flags);
++      powerpc_local_irq_pmu_save(flags);
+       /* Is that local to this CPU ? */
+       if (mm_is_thread_local(mm))
+@@ -1820,7 +1782,7 @@ static void hash_preload(struct mm_struct *mm, pte_t *ptep, unsigned long ea,
+                                  mm_ctx_user_psize(&mm->context),
+                                  pte_val(*ptep));
+-      local_irq_restore(flags);
++      powerpc_local_irq_pmu_restore(flags);
+ }
+ /*
+diff --git a/arch/powerpc/perf/callchain.h b/arch/powerpc/perf/callchain.h
+index d6fa6e25234f..19a8d051ddf1 100644
+--- a/arch/powerpc/perf/callchain.h
++++ b/arch/powerpc/perf/callchain.h
+@@ -2,7 +2,6 @@
+ #ifndef _POWERPC_PERF_CALLCHAIN_H
+ #define _POWERPC_PERF_CALLCHAIN_H
+-int read_user_stack_slow(const void __user *ptr, void *buf, int nb);
+ void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
+                           struct pt_regs *regs);
+ void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
+@@ -26,17 +25,11 @@ static inline int __read_user_stack(const void __user *ptr, void *ret,
+                                   size_t size)
+ {
+       unsigned long addr = (unsigned long)ptr;
+-      int rc;
+       if (addr > TASK_SIZE - size || (addr & (size - 1)))
+               return -EFAULT;
+-      rc = copy_from_user_nofault(ret, ptr, size);
+-
+-      if (IS_ENABLED(CONFIG_PPC64) && !radix_enabled() && rc)
+-              return read_user_stack_slow(ptr, ret, size);
+-
+-      return rc;
++      return copy_from_user_nofault(ret, ptr, size);
+ }
+ #endif /* _POWERPC_PERF_CALLCHAIN_H */
+diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c
+index 8d0df4226328..488e8a21a11e 100644
+--- a/arch/powerpc/perf/callchain_64.c
++++ b/arch/powerpc/perf/callchain_64.c
+@@ -18,33 +18,6 @@
+ #include "callchain.h"
+-/*
+- * On 64-bit we don't want to invoke hash_page on user addresses from
+- * interrupt context, so if the access faults, we read the page tables
+- * to find which page (if any) is mapped and access it directly. Radix
+- * has no need for this so it doesn't use read_user_stack_slow.
+- */
+-int read_user_stack_slow(const void __user *ptr, void *buf, int nb)
+-{
+-
+-      unsigned long addr = (unsigned long) ptr;
+-      unsigned long offset;
+-      struct page *page;
+-      void *kaddr;
+-
+-      if (get_user_page_fast_only(addr, FOLL_WRITE, &page)) {
+-              kaddr = page_address(page);
+-
+-              /* align address to page boundary */
+-              offset = addr & ~PAGE_MASK;
+-
+-              memcpy(buf, kaddr + offset, nb);
+-              put_page(page);
+-              return 0;
+-      }
+-      return -EFAULT;
+-}
+-
+ static int read_user_stack_64(const unsigned long __user *ptr, unsigned long *ret)
+ {
+       return __read_user_stack(ptr, ret, sizeof(*ret));
+-- 
+2.35.1
+
diff --git a/queue-5.17/powerpc-code-patching-pre-map-patch-area.patch b/queue-5.17/powerpc-code-patching-pre-map-patch-area.patch
new file mode 100644 (file)
index 0000000..a737897
--- /dev/null
@@ -0,0 +1,99 @@
+From 039c4b541a8da823781f3b2a7acb29170aa90bfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 12:58:21 +1100
+Subject: powerpc/code-patching: Pre-map patch area
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 591b4b268435f00d2f0b81f786c2c7bd5ef66416 ]
+
+Paul reported a warning with DEBUG_ATOMIC_SLEEP=y:
+
+  BUG: sleeping function called from invalid context at include/linux/sched/mm.h:256
+  in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 1, name: swapper/0
+  preempt_count: 0, expected: 0
+  ...
+  Call Trace:
+    dump_stack_lvl+0xa0/0xec (unreliable)
+    __might_resched+0x2f4/0x310
+    kmem_cache_alloc+0x220/0x4b0
+    __pud_alloc+0x74/0x1d0
+    hash__map_kernel_page+0x2cc/0x390
+    do_patch_instruction+0x134/0x4a0
+    arch_jump_label_transform+0x64/0x78
+    __jump_label_update+0x148/0x180
+    static_key_enable_cpuslocked+0xd0/0x120
+    static_key_enable+0x30/0x50
+    check_kvm_guest+0x60/0x88
+    pSeries_smp_probe+0x54/0xb0
+    smp_prepare_cpus+0x3e0/0x430
+    kernel_init_freeable+0x20c/0x43c
+    kernel_init+0x30/0x1a0
+    ret_from_kernel_thread+0x5c/0x64
+
+Peter pointed out that this is because do_patch_instruction() has
+disabled interrupts, but then map_patch_area() calls map_kernel_page()
+then hash__map_kernel_page() which does a sleeping memory allocation.
+
+We only see the warning in KVM guests with SMT enabled, which is not
+particularly common, or on other platforms if CONFIG_KPROBES is
+disabled, also not common. The reason we don't see it in most
+configurations is that another path that happens to have interrupts
+enabled has allocated the required page tables for us, eg. there's a
+path in kprobes init that does that. That's just pure luck though.
+
+As Christophe suggested, the simplest solution is to do a dummy
+map/unmap when we initialise the patching, so that any required page
+table levels are pre-allocated before the first call to
+do_patch_instruction(). This works because the unmap doesn't free any
+page tables that were allocated by the map, it just clears the PTE,
+leaving the page table levels there for the next map.
+
+Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Debugged-by: Peter Zijlstra <peterz@infradead.org>
+Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220223015821.473097-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/lib/code-patching.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
+index 906d43463366..00c68e7fb11e 100644
+--- a/arch/powerpc/lib/code-patching.c
++++ b/arch/powerpc/lib/code-patching.c
+@@ -43,9 +43,14 @@ int raw_patch_instruction(u32 *addr, ppc_inst_t instr)
+ #ifdef CONFIG_STRICT_KERNEL_RWX
+ static DEFINE_PER_CPU(struct vm_struct *, text_poke_area);
++static int map_patch_area(void *addr, unsigned long text_poke_addr);
++static void unmap_patch_area(unsigned long addr);
++
+ static int text_area_cpu_up(unsigned int cpu)
+ {
+       struct vm_struct *area;
++      unsigned long addr;
++      int err;
+       area = get_vm_area(PAGE_SIZE, VM_ALLOC);
+       if (!area) {
+@@ -53,6 +58,15 @@ static int text_area_cpu_up(unsigned int cpu)
+                       cpu);
+               return -1;
+       }
++
++      // Map/unmap the area to ensure all page tables are pre-allocated
++      addr = (unsigned long)area->addr;
++      err = map_patch_area(empty_zero_page, addr);
++      if (err)
++              return err;
++
++      unmap_patch_area(addr);
++
+       this_cpu_write(text_poke_area, area);
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.17/powerpc-dts-t104xrdb-fix-phy-type-for-fman-4-5.patch b/queue-5.17/powerpc-dts-t104xrdb-fix-phy-type-for-fman-4-5.patch
new file mode 100644 (file)
index 0000000..3b28191
--- /dev/null
@@ -0,0 +1,47 @@
+From 07a8ff4c393af33b882a2d70c095cfb1939a5f66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Dec 2021 18:11:21 +0300
+Subject: powerpc: dts: t104xrdb: fix phy type for FMAN 4/5
+
+From: Maxim Kiselev <bigunclemax@gmail.com>
+
+[ Upstream commit 17846485dff91acce1ad47b508b633dffc32e838 ]
+
+T1040RDB has two RTL8211E-VB phys which requires setting
+of internal delays for correct work.
+
+Changing the phy-connection-type property to `rgmii-id`
+will fix this issue.
+
+Signed-off-by: Maxim Kiselev <bigunclemax@gmail.com>
+Reviewed-by: Maxim Kochetkov <fido_max@inbox.ru>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20211230151123.1258321-1-bigunclemax@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/boot/dts/fsl/t104xrdb.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
+index 099a598c74c0..bfe1ed5be337 100644
+--- a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
++++ b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
+@@ -139,12 +139,12 @@
+               fman@400000 {
+                       ethernet@e6000 {
+                               phy-handle = <&phy_rgmii_0>;
+-                              phy-connection-type = "rgmii";
++                              phy-connection-type = "rgmii-id";
+                       };
+                       ethernet@e8000 {
+                               phy-handle = <&phy_rgmii_1>;
+-                              phy-connection-type = "rgmii";
++                              phy-connection-type = "rgmii-id";
+                       };
+                       mdio0: mdio@fc000 {
+-- 
+2.35.1
+
diff --git a/queue-5.17/powerpc-secvar-fix-refcount-leak-in-format_show.patch b/queue-5.17/powerpc-secvar-fix-refcount-leak-in-format_show.patch
new file mode 100644 (file)
index 0000000..62cd87b
--- /dev/null
@@ -0,0 +1,49 @@
+From 036d9339216fb9ee599dd502f2c55ee732666f1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 10:19:59 +0800
+Subject: powerpc/secvar: fix refcount leak in format_show()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit d601fd24e6964967f115f036a840f4f28488f63f ]
+
+Refcount leak will happen when format_show returns failure in multiple
+cases. Unified management of of_node_put can fix this problem.
+
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220302021959.10959-1-hbh25y@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/secvar-sysfs.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/kernel/secvar-sysfs.c b/arch/powerpc/kernel/secvar-sysfs.c
+index a0a78aba2083..1ee4640a2641 100644
+--- a/arch/powerpc/kernel/secvar-sysfs.c
++++ b/arch/powerpc/kernel/secvar-sysfs.c
+@@ -26,15 +26,18 @@ static ssize_t format_show(struct kobject *kobj, struct kobj_attribute *attr,
+       const char *format;
+       node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend");
+-      if (!of_device_is_available(node))
+-              return -ENODEV;
++      if (!of_device_is_available(node)) {
++              rc = -ENODEV;
++              goto out;
++      }
+       rc = of_property_read_string(node, "format", &format);
+       if (rc)
+-              return rc;
++              goto out;
+       rc = sprintf(buf, "%s\n", format);
++out:
+       of_node_put(node);
+       return rc;
+-- 
+2.35.1
+
diff --git a/queue-5.17/powerpc-set-crashkernel-offset-to-mid-of-rma-region.patch b/queue-5.17/powerpc-set-crashkernel-offset-to-mid-of-rma-region.patch
new file mode 100644 (file)
index 0000000..cf0da7e
--- /dev/null
@@ -0,0 +1,90 @@
+From c006a7952437fb3696a85d53ea269a078b669096 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 14:26:01 +0530
+Subject: powerpc: Set crashkernel offset to mid of RMA region
+
+From: Sourabh Jain <sourabhjain@linux.ibm.com>
+
+[ Upstream commit 7c5ed82b800d8615cdda00729e7b62e5899f0b13 ]
+
+On large config LPARs (having 192 and more cores), Linux fails to boot
+due to insufficient memory in the first memblock. It is due to the
+memory reservation for the crash kernel which starts at 128MB offset of
+the first memblock. This memory reservation for the crash kernel doesn't
+leave enough space in the first memblock to accommodate other essential
+system resources.
+
+The crash kernel start address was set to 128MB offset by default to
+ensure that the crash kernel get some memory below the RMA region which
+is used to be of size 256MB. But given that the RMA region size can be
+512MB or more, setting the crash kernel offset to mid of RMA size will
+leave enough space for the kernel to allocate memory for other system
+resources.
+
+Since the above crash kernel offset change is only applicable to the LPAR
+platform, the LPAR feature detection is pushed before the crash kernel
+reservation. The rest of LPAR specific initialization will still
+be done during pseries_probe_fw_features as usual.
+
+This patch is dependent on changes to paca allocation for boot CPU. It
+expect boot CPU to discover 1T segment support which is introduced by
+the patch posted here:
+https://lists.ozlabs.org/pipermail/linuxppc-dev/2022-January/239175.html
+
+Reported-by: Abdul haleem <abdhalee@linux.vnet.ibm.com>
+Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220204085601.107257-1-sourabhjain@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/rtas.c |  6 ++++++
+ arch/powerpc/kexec/core.c  | 15 +++++++++++----
+ 2 files changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index 733e6ef36758..1f42aabbbab3 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -1313,6 +1313,12 @@ int __init early_init_dt_scan_rtas(unsigned long node,
+       entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
+       sizep  = of_get_flat_dt_prop(node, "rtas-size", NULL);
++#ifdef CONFIG_PPC64
++      /* need this feature to decide the crashkernel offset */
++      if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL))
++              powerpc_firmware_features |= FW_FEATURE_LPAR;
++#endif
++
+       if (basep && entryp && sizep) {
+               rtas.base = *basep;
+               rtas.entry = *entryp;
+diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
+index 8b68d9f91a03..abf5897ae88c 100644
+--- a/arch/powerpc/kexec/core.c
++++ b/arch/powerpc/kexec/core.c
+@@ -134,11 +134,18 @@ void __init reserve_crashkernel(void)
+       if (!crashk_res.start) {
+ #ifdef CONFIG_PPC64
+               /*
+-               * On 64bit we split the RMO in half but cap it at half of
+-               * a small SLB (128MB) since the crash kernel needs to place
+-               * itself and some stacks to be in the first segment.
++               * On the LPAR platform place the crash kernel to mid of
++               * RMA size (512MB or more) to ensure the crash kernel
++               * gets enough space to place itself and some stack to be
++               * in the first segment. At the same time normal kernel
++               * also get enough space to allocate memory for essential
++               * system resource in the first segment. Keep the crash
++               * kernel starts at 128MB offset on other platforms.
+                */
+-              crashk_res.start = min(0x8000000ULL, (ppc64_rma_size / 2));
++              if (firmware_has_feature(FW_FEATURE_LPAR))
++                      crashk_res.start = ppc64_rma_size / 2;
++              else
++                      crashk_res.start = min(0x8000000ULL, (ppc64_rma_size / 2));
+ #else
+               crashk_res.start = KDUMP_KERNELBASE;
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.17/powerpc-set_memory-avoid-spinlock-recursion-in-chang.patch b/queue-5.17/powerpc-set_memory-avoid-spinlock-recursion-in-chang.patch
new file mode 100644 (file)
index 0000000..4f6ffb1
--- /dev/null
@@ -0,0 +1,139 @@
+From 4b1cbd4f98a5176389fcec01e20249fadc1ca732 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Dec 2021 11:07:33 +0000
+Subject: powerpc/set_memory: Avoid spinlock recursion in change_page_attr()
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit a4c182ecf33584b9b2d1aa9dad073014a504c01f ]
+
+Commit 1f9ad21c3b38 ("powerpc/mm: Implement set_memory() routines")
+included a spin_lock() to change_page_attr() in order to
+safely perform the three step operations. But then
+commit 9f7853d7609d ("powerpc/mm: Fix set_memory_*() against
+concurrent accesses") modify it to use pte_update() and do
+the operation safely against concurrent access.
+
+In the meantime, Maxime reported some spinlock recursion.
+
+[   15.351649] BUG: spinlock recursion on CPU#0, kworker/0:2/217
+[   15.357540]  lock: init_mm+0x3c/0x420, .magic: dead4ead, .owner: kworker/0:2/217, .owner_cpu: 0
+[   15.366563] CPU: 0 PID: 217 Comm: kworker/0:2 Not tainted 5.15.0+ #523
+[   15.373350] Workqueue: events do_free_init
+[   15.377615] Call Trace:
+[   15.380232] [e4105ac0] [800946a4] do_raw_spin_lock+0xf8/0x120 (unreliable)
+[   15.387340] [e4105ae0] [8001f4ec] change_page_attr+0x40/0x1d4
+[   15.393413] [e4105b10] [801424e0] __apply_to_page_range+0x164/0x310
+[   15.400009] [e4105b60] [80169620] free_pcp_prepare+0x1e4/0x4a0
+[   15.406045] [e4105ba0] [8016c5a0] free_unref_page+0x40/0x2b8
+[   15.411979] [e4105be0] [8018724c] kasan_depopulate_vmalloc_pte+0x6c/0x94
+[   15.418989] [e4105c00] [801424e0] __apply_to_page_range+0x164/0x310
+[   15.425451] [e4105c50] [80187834] kasan_release_vmalloc+0xbc/0x134
+[   15.431898] [e4105c70] [8015f7a8] __purge_vmap_area_lazy+0x4e4/0xdd8
+[   15.438560] [e4105d30] [80160d10] _vm_unmap_aliases.part.0+0x17c/0x24c
+[   15.445283] [e4105d60] [801642d0] __vunmap+0x2f0/0x5c8
+[   15.450684] [e4105db0] [800e32d0] do_free_init+0x68/0x94
+[   15.456181] [e4105dd0] [8005d094] process_one_work+0x4bc/0x7b8
+[   15.462283] [e4105e90] [8005d614] worker_thread+0x284/0x6e8
+[   15.468227] [e4105f00] [8006aaec] kthread+0x1f0/0x210
+[   15.473489] [e4105f40] [80017148] ret_from_kernel_thread+0x14/0x1c
+
+Remove the read / modify / write sequence to make the operation atomic
+and remove the spin_lock() in change_page_attr().
+
+To do the operation atomically, we can't use pte modification helpers
+anymore. Because all platforms have different combination of bits, it
+is not easy to use those bits directly. But all have the
+_PAGE_KERNEL_{RO/ROX/RW/RWX} set of flags. All we need it to compare
+two sets to know which bits are set or cleared.
+
+For instance, by comparing _PAGE_KERNEL_ROX and _PAGE_KERNEL_RO you
+know which bit gets cleared and which bit get set when changing exec
+permission.
+
+Reported-by: Maxime Bizon <mbizon@freebox.fr>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/all/20211212112152.GA27070@sakura/
+Link: https://lore.kernel.org/r/43c3c76a1175ae6dc1a3d3b5c3f7ecb48f683eea.1640344012.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/pageattr.c | 32 +++++++++++++-------------------
+ 1 file changed, 13 insertions(+), 19 deletions(-)
+
+diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c
+index 3bb9d168e3b3..85753e32a4de 100644
+--- a/arch/powerpc/mm/pageattr.c
++++ b/arch/powerpc/mm/pageattr.c
+@@ -15,12 +15,14 @@
+ #include <asm/pgtable.h>
++static pte_basic_t pte_update_delta(pte_t *ptep, unsigned long addr,
++                                  unsigned long old, unsigned long new)
++{
++      return pte_update(&init_mm, addr, ptep, old & ~new, new & ~old, 0);
++}
++
+ /*
+- * Updates the attributes of a page in three steps:
+- *
+- * 1. take the page_table_lock
+- * 2. install the new entry with the updated attributes
+- * 3. flush the TLB
++ * Updates the attributes of a page atomically.
+  *
+  * This sequence is safe against concurrent updates, and also allows updating the
+  * attributes of a page currently being executed or accessed.
+@@ -28,25 +30,21 @@
+ static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
+ {
+       long action = (long)data;
+-      pte_t pte;
+-      spin_lock(&init_mm.page_table_lock);
+-
+-      pte = ptep_get(ptep);
+-
+-      /* modify the PTE bits as desired, then apply */
++      /* modify the PTE bits as desired */
+       switch (action) {
+       case SET_MEMORY_RO:
+-              pte = pte_wrprotect(pte);
++              /* Don't clear DIRTY bit */
++              pte_update_delta(ptep, addr, _PAGE_KERNEL_RW & ~_PAGE_DIRTY, _PAGE_KERNEL_RO);
+               break;
+       case SET_MEMORY_RW:
+-              pte = pte_mkwrite(pte_mkdirty(pte));
++              pte_update_delta(ptep, addr, _PAGE_KERNEL_RO, _PAGE_KERNEL_RW);
+               break;
+       case SET_MEMORY_NX:
+-              pte = pte_exprotect(pte);
++              pte_update_delta(ptep, addr, _PAGE_KERNEL_ROX, _PAGE_KERNEL_RO);
+               break;
+       case SET_MEMORY_X:
+-              pte = pte_mkexec(pte);
++              pte_update_delta(ptep, addr, _PAGE_KERNEL_RO, _PAGE_KERNEL_ROX);
+               break;
+       case SET_MEMORY_NP:
+               pte_update(&init_mm, addr, ptep, _PAGE_PRESENT, 0, 0);
+@@ -59,16 +57,12 @@ static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
+               break;
+       }
+-      pte_update(&init_mm, addr, ptep, ~0UL, pte_val(pte), 0);
+-
+       /* See ptesync comment in radix__set_pte_at() */
+       if (radix_enabled())
+               asm volatile("ptesync": : :"memory");
+       flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+-      spin_unlock(&init_mm.page_table_lock);
+-
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/powerpc-xive-export-xive-ipi-information-for-online-.patch b/queue-5.17/powerpc-xive-export-xive-ipi-information-for-online-.patch
new file mode 100644 (file)
index 0000000..afc0935
--- /dev/null
@@ -0,0 +1,45 @@
+From a29e25da93d0556329aa9ca353cae4855cd8c3d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jan 2022 16:33:53 +0530
+Subject: powerpc/xive: Export XIVE IPI information for online-only processors.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sachin Sant <sachinp@linux.ibm.com>
+
+[ Upstream commit 279d1a72c0f8021520f68ddb0a1346ff9ba1ea8c ]
+
+Cédric pointed out that XIVE IPI information exported via sysfs
+(debug/powerpc/xive) display empty lines for processors which are
+not online.
+
+Switch to using for_each_online_cpu() so that information is
+displayed for online-only processors.
+
+Reported-by: Cédric Le Goater <clg@kaod.org>
+Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
+Reviewed-by: Cédric Le Goater <clg@kaod.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/164146703333.19039.10920919226094771665.sendpatchset@MacBook-Pro.local
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/sysdev/xive/common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
+index 89c86f32aff8..bb5bda6b2357 100644
+--- a/arch/powerpc/sysdev/xive/common.c
++++ b/arch/powerpc/sysdev/xive/common.c
+@@ -1791,7 +1791,7 @@ static int xive_ipi_debug_show(struct seq_file *m, void *private)
+       if (xive_ops->debug_show)
+               xive_ops->debug_show(m, private);
+-      for_each_possible_cpu(cpu)
++      for_each_online_cpu(cpu)
+               xive_debug_show_ipi(m, cpu);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/ptp-replace-snprintf-with-sysfs_emit.patch b/queue-5.17/ptp-replace-snprintf-with-sysfs_emit.patch
new file mode 100644 (file)
index 0000000..29cdb59
--- /dev/null
@@ -0,0 +1,52 @@
+From c6cfa6d17440e7f960e8f7d9185c81d0568689c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 08:02:36 +0800
+Subject: ptp: replace snprintf with sysfs_emit
+
+From: Yang Guang <yang.guang5@zte.com.cn>
+
+[ Upstream commit e2cf07654efb0fd7bbcb475c6f74be7b5755a8fd ]
+
+coccinelle report:
+./drivers/ptp/ptp_sysfs.c:17:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/ptp/ptp_sysfs.c:390:8-16:
+WARNING: use scnprintf or sprintf
+
+Use sysfs_emit instead of scnprintf or sprintf makes more sense.
+
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Yang Guang <yang.guang5@zte.com.cn>
+Signed-off-by: David Yang <davidcomponentone@gmail.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_sysfs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c
+index 41b92dc2f011..9233bfedeb17 100644
+--- a/drivers/ptp/ptp_sysfs.c
++++ b/drivers/ptp/ptp_sysfs.c
+@@ -14,7 +14,7 @@ static ssize_t clock_name_show(struct device *dev,
+                              struct device_attribute *attr, char *page)
+ {
+       struct ptp_clock *ptp = dev_get_drvdata(dev);
+-      return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name);
++      return sysfs_emit(page, "%s\n", ptp->info->name);
+ }
+ static DEVICE_ATTR_RO(clock_name);
+@@ -387,7 +387,7 @@ static ssize_t ptp_pin_show(struct device *dev, struct device_attribute *attr,
+       mutex_unlock(&ptp->pincfg_mux);
+-      return snprintf(page, PAGE_SIZE, "%u %u\n", func, chan);
++      return sysfs_emit(page, "%u %u\n", func, chan);
+ }
+ static ssize_t ptp_pin_store(struct device *dev, struct device_attribute *attr,
+-- 
+2.35.1
+
diff --git a/queue-5.17/rdma-rtrs-clt-do-stop-and-failover-outside-reconnect.patch b/queue-5.17/rdma-rtrs-clt-do-stop-and-failover-outside-reconnect.patch
new file mode 100644 (file)
index 0000000..87ec3da
--- /dev/null
@@ -0,0 +1,149 @@
+From c0c12ab14691a5494624694fb47752466b9ec6cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jan 2022 16:47:53 +0100
+Subject: RDMA/rtrs-clt: Do stop and failover outside reconnect work.
+
+From: Jack Wang <jinpu.wang@ionos.com>
+
+[ Upstream commit c1289d5d8502d62e5bc50ff066c9d6daabfc3264 ]
+
+We can't do instant reconnect, not to DDoS server, but we should stop and
+failover earlier, so there is less service interruption.
+
+To avoid deadlock, as error_recovery is called from different callback
+like rdma event or hb error handler, add a new err recovery_work.
+
+Link: https://lore.kernel.org/r/20220114154753.983568-6-haris.iqbal@ionos.com
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Reviewed-by: Aleksei Marov <aleksei.marov@ionos.com>
+Reviewed-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 40 ++++++++++++++------------
+ drivers/infiniband/ulp/rtrs/rtrs-clt.h |  1 +
+ 2 files changed, 23 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index 759b85f03331..df4d06d4d183 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -297,6 +297,7 @@ static bool rtrs_clt_change_state_from_to(struct rtrs_clt_path *clt_path,
+       return changed;
+ }
++static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_path *clt_path);
+ static void rtrs_rdma_error_recovery(struct rtrs_clt_con *con)
+ {
+       struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+@@ -304,16 +305,7 @@ static void rtrs_rdma_error_recovery(struct rtrs_clt_con *con)
+       if (rtrs_clt_change_state_from_to(clt_path,
+                                          RTRS_CLT_CONNECTED,
+                                          RTRS_CLT_RECONNECTING)) {
+-              struct rtrs_clt_sess *clt = clt_path->clt;
+-              unsigned int delay_ms;
+-
+-              /*
+-               * Normal scenario, reconnect if we were successfully connected
+-               */
+-              delay_ms = clt->reconnect_delay_sec * 1000;
+-              queue_delayed_work(rtrs_wq, &clt_path->reconnect_dwork,
+-                                 msecs_to_jiffies(delay_ms +
+-                                                  prandom_u32() % RTRS_RECONNECT_SEED));
++              queue_work(rtrs_wq, &clt_path->err_recovery_work);
+       } else {
+               /*
+                * Error can happen just on establishing new connection,
+@@ -1511,6 +1503,22 @@ static void rtrs_clt_init_hb(struct rtrs_clt_path *clt_path)
+ static void rtrs_clt_reconnect_work(struct work_struct *work);
+ static void rtrs_clt_close_work(struct work_struct *work);
++static void rtrs_clt_err_recovery_work(struct work_struct *work)
++{
++      struct rtrs_clt_path *clt_path;
++      struct rtrs_clt_sess *clt;
++      int delay_ms;
++
++      clt_path = container_of(work, struct rtrs_clt_path, err_recovery_work);
++      clt = clt_path->clt;
++      delay_ms = clt->reconnect_delay_sec * 1000;
++      rtrs_clt_stop_and_destroy_conns(clt_path);
++      queue_delayed_work(rtrs_wq, &clt_path->reconnect_dwork,
++                         msecs_to_jiffies(delay_ms +
++                                          prandom_u32() %
++                                          RTRS_RECONNECT_SEED));
++}
++
+ static struct rtrs_clt_path *alloc_path(struct rtrs_clt_sess *clt,
+                                       const struct rtrs_addr *path,
+                                       size_t con_num, u32 nr_poll_queues)
+@@ -1562,6 +1570,7 @@ static struct rtrs_clt_path *alloc_path(struct rtrs_clt_sess *clt,
+       clt_path->state = RTRS_CLT_CONNECTING;
+       atomic_set(&clt_path->connected_cnt, 0);
+       INIT_WORK(&clt_path->close_work, rtrs_clt_close_work);
++      INIT_WORK(&clt_path->err_recovery_work, rtrs_clt_err_recovery_work);
+       INIT_DELAYED_WORK(&clt_path->reconnect_dwork, rtrs_clt_reconnect_work);
+       rtrs_clt_init_hb(clt_path);
+@@ -2326,6 +2335,7 @@ static void rtrs_clt_close_work(struct work_struct *work)
+       clt_path = container_of(work, struct rtrs_clt_path, close_work);
++      cancel_work_sync(&clt_path->err_recovery_work);
+       cancel_delayed_work_sync(&clt_path->reconnect_dwork);
+       rtrs_clt_stop_and_destroy_conns(clt_path);
+       rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_CLOSED, NULL);
+@@ -2638,7 +2648,6 @@ static void rtrs_clt_reconnect_work(struct work_struct *work)
+ {
+       struct rtrs_clt_path *clt_path;
+       struct rtrs_clt_sess *clt;
+-      unsigned int delay_ms;
+       int err;
+       clt_path = container_of(to_delayed_work(work), struct rtrs_clt_path,
+@@ -2655,8 +2664,6 @@ static void rtrs_clt_reconnect_work(struct work_struct *work)
+       }
+       clt_path->reconnect_attempts++;
+-      /* Stop everything */
+-      rtrs_clt_stop_and_destroy_conns(clt_path);
+       msleep(RTRS_RECONNECT_BACKOFF);
+       if (rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_CONNECTING, NULL)) {
+               err = init_path(clt_path);
+@@ -2669,11 +2676,7 @@ static void rtrs_clt_reconnect_work(struct work_struct *work)
+ reconnect_again:
+       if (rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_RECONNECTING, NULL)) {
+               clt_path->stats->reconnects.fail_cnt++;
+-              delay_ms = clt->reconnect_delay_sec * 1000;
+-              queue_delayed_work(rtrs_wq, &clt_path->reconnect_dwork,
+-                                 msecs_to_jiffies(delay_ms +
+-                                                  prandom_u32() %
+-                                                  RTRS_RECONNECT_SEED));
++              queue_work(rtrs_wq, &clt_path->err_recovery_work);
+       }
+ }
+@@ -2908,6 +2911,7 @@ int rtrs_clt_reconnect_from_sysfs(struct rtrs_clt_path *clt_path)
+                                                &old_state);
+       if (changed) {
+               clt_path->reconnect_attempts = 0;
++              rtrs_clt_stop_and_destroy_conns(clt_path);
+               queue_delayed_work(rtrs_wq, &clt_path->reconnect_dwork, 0);
+       }
+       if (changed || old_state == RTRS_CLT_RECONNECTING) {
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.h b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
+index d1b18a154ae0..f848c0392d98 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
+@@ -134,6 +134,7 @@ struct rtrs_clt_path {
+       struct rtrs_clt_io_req  *reqs;
+       struct delayed_work     reconnect_dwork;
+       struct work_struct      close_work;
++      struct work_struct      err_recovery_work;
+       unsigned int            reconnect_attempts;
+       bool                    established;
+       struct rtrs_rbuf        *rbufs;
+-- 
+2.35.1
+
diff --git a/queue-5.17/ref_tracker-implement-use-after-free-detection.patch b/queue-5.17/ref_tracker-implement-use-after-free-detection.patch
new file mode 100644 (file)
index 0000000..5fba50d
--- /dev/null
@@ -0,0 +1,78 @@
+From c4c25399934101f9665e35f6218dc9e1c58ab652 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 14:42:35 -0800
+Subject: ref_tracker: implement use-after-free detection
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e3ececfe668facd87d920b608349a32607060e66 ]
+
+Whenever ref_tracker_dir_init() is called, mark the struct ref_tracker_dir
+as dead.
+
+Test the dead status from ref_tracker_alloc() and ref_tracker_free()
+
+This should detect buggy dev_put()/dev_hold() happening too late
+in netdevice dismantle process.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/ref_tracker.h | 2 ++
+ lib/ref_tracker.c           | 5 +++++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h
+index 60f3453be23e..a443abda937d 100644
+--- a/include/linux/ref_tracker.h
++++ b/include/linux/ref_tracker.h
+@@ -13,6 +13,7 @@ struct ref_tracker_dir {
+       spinlock_t              lock;
+       unsigned int            quarantine_avail;
+       refcount_t              untracked;
++      bool                    dead;
+       struct list_head        list; /* List of active trackers */
+       struct list_head        quarantine; /* List of dead trackers */
+ #endif
+@@ -26,6 +27,7 @@ static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
+       INIT_LIST_HEAD(&dir->quarantine);
+       spin_lock_init(&dir->lock);
+       dir->quarantine_avail = quarantine_count;
++      dir->dead = false;
+       refcount_set(&dir->untracked, 1);
+       stack_depot_init();
+ }
+diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
+index a6789c0c626b..32ff6bd497f8 100644
+--- a/lib/ref_tracker.c
++++ b/lib/ref_tracker.c
+@@ -20,6 +20,7 @@ void ref_tracker_dir_exit(struct ref_tracker_dir *dir)
+       unsigned long flags;
+       bool leak = false;
++      dir->dead = true;
+       spin_lock_irqsave(&dir->lock, flags);
+       list_for_each_entry_safe(tracker, n, &dir->quarantine, head) {
+               list_del(&tracker->head);
+@@ -72,6 +73,8 @@ int ref_tracker_alloc(struct ref_tracker_dir *dir,
+       gfp_t gfp_mask = gfp;
+       unsigned long flags;
++      WARN_ON_ONCE(dir->dead);
++
+       if (gfp & __GFP_DIRECT_RECLAIM)
+               gfp_mask |= __GFP_NOFAIL;
+       *trackerp = tracker = kzalloc(sizeof(*tracker), gfp_mask);
+@@ -100,6 +103,8 @@ int ref_tracker_free(struct ref_tracker_dir *dir,
+       unsigned int nr_entries;
+       unsigned long flags;
++      WARN_ON_ONCE(dir->dead);
++
+       if (!tracker) {
+               refcount_dec(&dir->untracked);
+               return -EEXIST;
+-- 
+2.35.1
+
diff --git a/queue-5.17/riscv-fixed-misaligned-memory-access.-fixed-pointer-.patch b/queue-5.17/riscv-fixed-misaligned-memory-access.-fixed-pointer-.patch
new file mode 100644 (file)
index 0000000..661c267
--- /dev/null
@@ -0,0 +1,421 @@
+From 8f8542d7cf2ce7e2d2bc23d148c7bd6a4ac4b805 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Mar 2022 20:03:21 -0500
+Subject: riscv: Fixed misaligned memory access. Fixed pointer comparison.
+
+From: Michael T. Kloos <michael@michaelkloos.com>
+
+[ Upstream commit 9d1f0ec9f71780e69ceb9d91697600c747d6e02e ]
+
+Rewrote the RISC-V memmove() assembly implementation.  The
+previous implementation did not check memory alignment and it
+compared 2 pointers with a signed comparison.  The misaligned
+memory access would cause the kernel to crash on systems that
+did not emulate it in firmware and did not support it in hardware.
+Firmware emulation is slow and may not exist.  The RISC-V spec
+does not guarantee that support for misaligned memory accesses
+will exist.  It should not be depended on.
+
+This patch now checks for XLEN granularity of co-alignment between
+the pointers.  Failing that, copying is done by loading from the 2
+contiguous and naturally aligned XLEN memory locations containing
+the overlapping XLEN sized data to be copied.  The data is shifted
+into the correct place and binary or'ed together on each
+iteration.  The result is then stored into the corresponding
+naturally aligned XLEN sized location in the destination.  For
+unaligned data at the terminations of the regions to be copied
+or for copies less than (2 * XLEN) in size, byte copy is used.
+
+This patch also now uses unsigned comparison for the pointers and
+migrates to the newer assembler annotations from the now deprecated
+ones.
+
+Signed-off-by: Michael T. Kloos <michael@michaelkloos.com>
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/lib/memmove.S | 368 +++++++++++++++++++++++++++++++++------
+ 1 file changed, 310 insertions(+), 58 deletions(-)
+
+diff --git a/arch/riscv/lib/memmove.S b/arch/riscv/lib/memmove.S
+index 07d1d2152ba5..e0609e1f0864 100644
+--- a/arch/riscv/lib/memmove.S
++++ b/arch/riscv/lib/memmove.S
+@@ -1,64 +1,316 @@
+-/* SPDX-License-Identifier: GPL-2.0 */
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2022 Michael T. Kloos <michael@michaelkloos.com>
++ */
+ #include <linux/linkage.h>
+ #include <asm/asm.h>
+-ENTRY(__memmove)
+-WEAK(memmove)
+-        move    t0, a0
+-        move    t1, a1
+-
+-        beq     a0, a1, exit_memcpy
+-        beqz    a2, exit_memcpy
+-        srli    t2, a2, 0x2
+-
+-        slt     t3, a0, a1
+-        beqz    t3, do_reverse
+-
+-        andi    a2, a2, 0x3
+-        li      t4, 1
+-        beqz    t2, byte_copy
+-
+-word_copy:
+-        lw      t3, 0(a1)
+-        addi    t2, t2, -1
+-        addi    a1, a1, 4
+-        sw      t3, 0(a0)
+-        addi    a0, a0, 4
+-        bnez    t2, word_copy
+-        beqz    a2, exit_memcpy
+-        j       byte_copy
+-
+-do_reverse:
+-        add     a0, a0, a2
+-        add     a1, a1, a2
+-        andi    a2, a2, 0x3
+-        li      t4, -1
+-        beqz    t2, reverse_byte_copy
+-
+-reverse_word_copy:
+-        addi    a1, a1, -4
+-        addi    t2, t2, -1
+-        lw      t3, 0(a1)
+-        addi    a0, a0, -4
+-        sw      t3, 0(a0)
+-        bnez    t2, reverse_word_copy
+-        beqz    a2, exit_memcpy
+-
+-reverse_byte_copy:
+-        addi    a0, a0, -1
+-        addi    a1, a1, -1
++SYM_FUNC_START(__memmove)
++SYM_FUNC_START_WEAK(memmove)
++      /*
++       * Returns
++       *   a0 - dest
++       *
++       * Parameters
++       *   a0 - Inclusive first byte of dest
++       *   a1 - Inclusive first byte of src
++       *   a2 - Length of copy n
++       *
++       * Because the return matches the parameter register a0,
++       * we will not clobber or modify that register.
++       *
++       * Note: This currently only works on little-endian.
++       * To port to big-endian, reverse the direction of shifts
++       * in the 2 misaligned fixup copy loops.
++       */
++      /* Return if nothing to do */
++      beq a0, a1, return_from_memmove
++      beqz a2, return_from_memmove
++
++      /*
++       * Register Uses
++       *      Forward Copy: a1 - Index counter of src
++       *      Reverse Copy: a4 - Index counter of src
++       *      Forward Copy: t3 - Index counter of dest
++       *      Reverse Copy: t4 - Index counter of dest
++       *   Both Copy Modes: t5 - Inclusive first multibyte/aligned of dest
++       *   Both Copy Modes: t6 - Non-Inclusive last multibyte/aligned of dest
++       *   Both Copy Modes: t0 - Link / Temporary for load-store
++       *   Both Copy Modes: t1 - Temporary for load-store
++       *   Both Copy Modes: t2 - Temporary for load-store
++       *   Both Copy Modes: a5 - dest to src alignment offset
++       *   Both Copy Modes: a6 - Shift ammount
++       *   Both Copy Modes: a7 - Inverse Shift ammount
++       *   Both Copy Modes: a2 - Alternate breakpoint for unrolled loops
++       */
++
++      /*
++       * Solve for some register values now.
++       * Byte copy does not need t5 or t6.
++       */
++      mv   t3, a0
++      add  t4, a0, a2
++      add  a4, a1, a2
++
++      /*
++       * Byte copy if copying less than (2 * SZREG) bytes. This can
++       * cause problems with the bulk copy implementation and is
++       * small enough not to bother.
++       */
++      andi t0, a2, -(2 * SZREG)
++      beqz t0, byte_copy
++
++      /*
++       * Now solve for t5 and t6.
++       */
++      andi t5, t3, -SZREG
++      andi t6, t4, -SZREG
++      /*
++       * If dest(Register t3) rounded down to the nearest naturally
++       * aligned SZREG address, does not equal dest, then add SZREG
++       * to find the low-bound of SZREG alignment in the dest memory
++       * region.  Note that this could overshoot the dest memory
++       * region if n is less than SZREG.  This is one reason why
++       * we always byte copy if n is less than SZREG.
++       * Otherwise, dest is already naturally aligned to SZREG.
++       */
++      beq  t5, t3, 1f
++              addi t5, t5, SZREG
++      1:
++
++      /*
++       * If the dest and src are co-aligned to SZREG, then there is
++       * no need for the full rigmarole of a full misaligned fixup copy.
++       * Instead, do a simpler co-aligned copy.
++       */
++      xor  t0, a0, a1
++      andi t1, t0, (SZREG - 1)
++      beqz t1, coaligned_copy
++      /* Fall through to misaligned fixup copy */
++
++misaligned_fixup_copy:
++      bltu a1, a0, misaligned_fixup_copy_reverse
++
++misaligned_fixup_copy_forward:
++      jal  t0, byte_copy_until_aligned_forward
++
++      andi a5, a1, (SZREG - 1) /* Find the alignment offset of src (a1) */
++      slli a6, a5, 3 /* Multiply by 8 to convert that to bits to shift */
++      sub  a5, a1, t3 /* Find the difference between src and dest */
++      andi a1, a1, -SZREG /* Align the src pointer */
++      addi a2, t6, SZREG /* The other breakpoint for the unrolled loop*/
++
++      /*
++       * Compute The Inverse Shift
++       * a7 = XLEN - a6 = XLEN + -a6
++       * 2s complement negation to find the negative: -a6 = ~a6 + 1
++       * Add that to XLEN.  XLEN = SZREG * 8.
++       */
++      not  a7, a6
++      addi a7, a7, (SZREG * 8 + 1)
++
++      /*
++       * Fix Misalignment Copy Loop - Forward
++       * load_val0 = load_ptr[0];
++       * do {
++       *      load_val1 = load_ptr[1];
++       *      store_ptr += 2;
++       *      store_ptr[0 - 2] = (load_val0 >> {a6}) | (load_val1 << {a7});
++       *
++       *      if (store_ptr == {a2})
++       *              break;
++       *
++       *      load_val0 = load_ptr[2];
++       *      load_ptr += 2;
++       *      store_ptr[1 - 2] = (load_val1 >> {a6}) | (load_val0 << {a7});
++       *
++       * } while (store_ptr != store_ptr_end);
++       * store_ptr = store_ptr_end;
++       */
++
++      REG_L t0, (0 * SZREG)(a1)
++      1:
++      REG_L t1, (1 * SZREG)(a1)
++      addi  t3, t3, (2 * SZREG)
++      srl   t0, t0, a6
++      sll   t2, t1, a7
++      or    t2, t0, t2
++      REG_S t2, ((0 * SZREG) - (2 * SZREG))(t3)
++
++      beq   t3, a2, 2f
++
++      REG_L t0, (2 * SZREG)(a1)
++      addi  a1, a1, (2 * SZREG)
++      srl   t1, t1, a6
++      sll   t2, t0, a7
++      or    t2, t1, t2
++      REG_S t2, ((1 * SZREG) - (2 * SZREG))(t3)
++
++      bne   t3, t6, 1b
++      2:
++      mv    t3, t6 /* Fix the dest pointer in case the loop was broken */
++
++      add  a1, t3, a5 /* Restore the src pointer */
++      j byte_copy_forward /* Copy any remaining bytes */
++
++misaligned_fixup_copy_reverse:
++      jal  t0, byte_copy_until_aligned_reverse
++
++      andi a5, a4, (SZREG - 1) /* Find the alignment offset of src (a4) */
++      slli a6, a5, 3 /* Multiply by 8 to convert that to bits to shift */
++      sub  a5, a4, t4 /* Find the difference between src and dest */
++      andi a4, a4, -SZREG /* Align the src pointer */
++      addi a2, t5, -SZREG /* The other breakpoint for the unrolled loop*/
++
++      /*
++       * Compute The Inverse Shift
++       * a7 = XLEN - a6 = XLEN + -a6
++       * 2s complement negation to find the negative: -a6 = ~a6 + 1
++       * Add that to XLEN.  XLEN = SZREG * 8.
++       */
++      not  a7, a6
++      addi a7, a7, (SZREG * 8 + 1)
++
++      /*
++       * Fix Misalignment Copy Loop - Reverse
++       * load_val1 = load_ptr[0];
++       * do {
++       *      load_val0 = load_ptr[-1];
++       *      store_ptr -= 2;
++       *      store_ptr[1] = (load_val0 >> {a6}) | (load_val1 << {a7});
++       *
++       *      if (store_ptr == {a2})
++       *              break;
++       *
++       *      load_val1 = load_ptr[-2];
++       *      load_ptr -= 2;
++       *      store_ptr[0] = (load_val1 >> {a6}) | (load_val0 << {a7});
++       *
++       * } while (store_ptr != store_ptr_end);
++       * store_ptr = store_ptr_end;
++       */
++
++      REG_L t1, ( 0 * SZREG)(a4)
++      1:
++      REG_L t0, (-1 * SZREG)(a4)
++      addi  t4, t4, (-2 * SZREG)
++      sll   t1, t1, a7
++      srl   t2, t0, a6
++      or    t2, t1, t2
++      REG_S t2, ( 1 * SZREG)(t4)
++
++      beq   t4, a2, 2f
++
++      REG_L t1, (-2 * SZREG)(a4)
++      addi  a4, a4, (-2 * SZREG)
++      sll   t0, t0, a7
++      srl   t2, t1, a6
++      or    t2, t0, t2
++      REG_S t2, ( 0 * SZREG)(t4)
++
++      bne   t4, t5, 1b
++      2:
++      mv    t4, t5 /* Fix the dest pointer in case the loop was broken */
++
++      add  a4, t4, a5 /* Restore the src pointer */
++      j byte_copy_reverse /* Copy any remaining bytes */
++
++/*
++ * Simple copy loops for SZREG co-aligned memory locations.
++ * These also make calls to do byte copies for any unaligned
++ * data at their terminations.
++ */
++coaligned_copy:
++      bltu a1, a0, coaligned_copy_reverse
++
++coaligned_copy_forward:
++      jal t0, byte_copy_until_aligned_forward
++
++      1:
++      REG_L t1, ( 0 * SZREG)(a1)
++      addi  a1, a1, SZREG
++      addi  t3, t3, SZREG
++      REG_S t1, (-1 * SZREG)(t3)
++      bne   t3, t6, 1b
++
++      j byte_copy_forward /* Copy any remaining bytes */
++
++coaligned_copy_reverse:
++      jal t0, byte_copy_until_aligned_reverse
++
++      1:
++      REG_L t1, (-1 * SZREG)(a4)
++      addi  a4, a4, -SZREG
++      addi  t4, t4, -SZREG
++      REG_S t1, ( 0 * SZREG)(t4)
++      bne   t4, t5, 1b
++
++      j byte_copy_reverse /* Copy any remaining bytes */
++
++/*
++ * These are basically sub-functions within the function.  They
++ * are used to byte copy until the dest pointer is in alignment.
++ * At which point, a bulk copy method can be used by the
++ * calling code.  These work on the same registers as the bulk
++ * copy loops.  Therefore, the register values can be picked
++ * up from where they were left and we avoid code duplication
++ * without any overhead except the call in and return jumps.
++ */
++byte_copy_until_aligned_forward:
++      beq  t3, t5, 2f
++      1:
++      lb   t1,  0(a1)
++      addi a1, a1, 1
++      addi t3, t3, 1
++      sb   t1, -1(t3)
++      bne  t3, t5, 1b
++      2:
++      jalr zero, 0x0(t0) /* Return to multibyte copy loop */
++
++byte_copy_until_aligned_reverse:
++      beq  t4, t6, 2f
++      1:
++      lb   t1, -1(a4)
++      addi a4, a4, -1
++      addi t4, t4, -1
++      sb   t1,  0(t4)
++      bne  t4, t6, 1b
++      2:
++      jalr zero, 0x0(t0) /* Return to multibyte copy loop */
++
++/*
++ * Simple byte copy loops.
++ * These will byte copy until they reach the end of data to copy.
++ * At that point, they will call to return from memmove.
++ */
+ byte_copy:
+-        lb      t3, 0(a1)
+-        addi    a2, a2, -1
+-        sb      t3, 0(a0)
+-        add     a1, a1, t4
+-        add     a0, a0, t4
+-        bnez    a2, byte_copy
+-
+-exit_memcpy:
+-        move a0, t0
+-        move a1, t1
+-        ret
+-END(__memmove)
++      bltu a1, a0, byte_copy_reverse
++
++byte_copy_forward:
++      beq  t3, t4, 2f
++      1:
++      lb   t1,  0(a1)
++      addi a1, a1, 1
++      addi t3, t3, 1
++      sb   t1, -1(t3)
++      bne  t3, t4, 1b
++      2:
++      ret
++
++byte_copy_reverse:
++      beq  t4, t3, 2f
++      1:
++      lb   t1, -1(a4)
++      addi a4, a4, -1
++      addi t4, t4, -1
++      sb   t1,  0(t4)
++      bne  t4, t3, 1b
++      2:
++
++return_from_memmove:
++      ret
++
++SYM_FUNC_END(memmove)
++SYM_FUNC_END(__memmove)
+-- 
+2.35.1
+
diff --git a/queue-5.17/rtc-wm8350-handle-error-for-wm8350_register_irq.patch b/queue-5.17/rtc-wm8350-handle-error-for-wm8350_register_irq.patch
new file mode 100644 (file)
index 0000000..47b6579
--- /dev/null
@@ -0,0 +1,55 @@
+From e83076c953cdb784f762f7566bfca4af13edf406 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Mar 2022 16:50:30 +0800
+Subject: rtc: wm8350: Handle error for wm8350_register_irq
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 43f0269b6b89c1eec4ef83c48035608f4dcdd886 ]
+
+As the potential failure of the wm8350_register_irq(),
+it should be better to check it and return error if fails.
+Also, it need not free 'wm_rtc->rtc' since it will be freed
+automatically.
+
+Fixes: 077eaf5b40ec ("rtc: rtc-wm8350: add support for WM8350 RTC")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20220303085030.291793-1-jiasheng@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-wm8350.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
+index 2018614f258f..6eaa9321c074 100644
+--- a/drivers/rtc/rtc-wm8350.c
++++ b/drivers/rtc/rtc-wm8350.c
+@@ -432,14 +432,21 @@ static int wm8350_rtc_probe(struct platform_device *pdev)
+               return ret;
+       }
+-      wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC,
++      ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC,
+                           wm8350_rtc_update_handler, 0,
+                           "RTC Seconds", wm8350);
++      if (ret)
++              return ret;
++
+       wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
+-      wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM,
++      ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM,
+                           wm8350_rtc_alarm_handler, 0,
+                           "RTC Alarm", wm8350);
++      if (ret) {
++              wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
++              return ret;
++      }
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/rtw88-change-rtw_info-to-proper-message-level.patch b/queue-5.17/rtw88-change-rtw_info-to-proper-message-level.patch
new file mode 100644 (file)
index 0000000..b23dc57
--- /dev/null
@@ -0,0 +1,206 @@
+From 099c6b29f287ba9c1a502c8ae883430ad596f245 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Feb 2022 11:55:27 +0800
+Subject: rtw88: change rtw_info() to proper message level
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit a0061be4e54b52e5e4ff179c3f817107ddbb2830 ]
+
+Larry reported funny log entries [1] when he used rtl8821ce. These
+messages are not harmless, but not useful for users, so change them to
+rtw_dbg() level. By the way, I review all rtw_info() and change others
+to rtw_warn().
+
+[1] https://lore.kernel.org/linux-wireless/c356d5ae-a7b3-3065-1121-64c446e70333@lwfinger.net/
+
+Reported-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220218035527.9835-1-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/debug.c    | 2 +-
+ drivers/net/wireless/realtek/rtw88/debug.h    | 1 +
+ drivers/net/wireless/realtek/rtw88/fw.c       | 2 +-
+ drivers/net/wireless/realtek/rtw88/mac80211.c | 8 ++++----
+ drivers/net/wireless/realtek/rtw88/main.c     | 8 ++++----
+ drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 +-
+ drivers/net/wireless/realtek/rtw88/rtw8822b.c | 4 ++--
+ drivers/net/wireless/realtek/rtw88/rtw8822c.c | 4 ++--
+ drivers/net/wireless/realtek/rtw88/sar.c      | 8 ++++----
+ 9 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
+index e429428232c1..e7e9f17df96a 100644
+--- a/drivers/net/wireless/realtek/rtw88/debug.c
++++ b/drivers/net/wireless/realtek/rtw88/debug.c
+@@ -390,7 +390,7 @@ static ssize_t rtw_debugfs_set_h2c(struct file *filp,
+                    &param[0], &param[1], &param[2], &param[3],
+                    &param[4], &param[5], &param[6], &param[7]);
+       if (num != 8) {
+-              rtw_info(rtwdev, "invalid H2C command format for debug\n");
++              rtw_warn(rtwdev, "invalid H2C command format for debug\n");
+               return -EINVAL;
+       }
+diff --git a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h
+index 61f8369fe2d6..066792dd96af 100644
+--- a/drivers/net/wireless/realtek/rtw88/debug.h
++++ b/drivers/net/wireless/realtek/rtw88/debug.h
+@@ -23,6 +23,7 @@ enum rtw_debug_mask {
+       RTW_DBG_PATH_DIV        = 0x00004000,
+       RTW_DBG_ADAPTIVITY      = 0x00008000,
+       RTW_DBG_HW_SCAN         = 0x00010000,
++      RTW_DBG_STATE           = 0x00020000,
+       RTW_DBG_ALL             = 0xffffffff
+ };
+diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
+index 4c8e5ea5d069..db90d75a8633 100644
+--- a/drivers/net/wireless/realtek/rtw88/fw.c
++++ b/drivers/net/wireless/realtek/rtw88/fw.c
+@@ -2131,7 +2131,7 @@ void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb)
+       rtw_hw_scan_complete(rtwdev, vif, aborted);
+       if (aborted)
+-              rtw_info(rtwdev, "HW scan aborted with code: %d\n", rc);
++              rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, "HW scan aborted with code: %d\n", rc);
+ }
+ void rtw_store_op_chan(struct rtw_dev *rtwdev)
+diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
+index 647d2662955b..5cdc54c9a9aa 100644
+--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
+@@ -208,7 +208,7 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
+       mutex_unlock(&rtwdev->mutex);
+-      rtw_info(rtwdev, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
++      rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
+       return 0;
+ }
+@@ -219,7 +219,7 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
+       struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+       u32 config = 0;
+-      rtw_info(rtwdev, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
++      rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
+       mutex_lock(&rtwdev->mutex);
+@@ -245,8 +245,8 @@ static int rtw_ops_change_interface(struct ieee80211_hw *hw,
+ {
+       struct rtw_dev *rtwdev = hw->priv;
+-      rtw_info(rtwdev, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n",
+-               vif->addr, vif->type, type, vif->p2p, p2p);
++      rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n",
++              vif->addr, vif->type, type, vif->p2p, p2p);
+       rtw_ops_remove_interface(hw, vif);
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
+index 39c223a2e3e2..b00200f81db7 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.c
++++ b/drivers/net/wireless/realtek/rtw88/main.c
+@@ -314,8 +314,8 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
+       rtwdev->sta_cnt++;
+       rtwdev->beacon_loss = false;
+-      rtw_info(rtwdev, "sta %pM joined with macid %d\n",
+-               sta->addr, si->mac_id);
++      rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %pM joined with macid %d\n",
++              sta->addr, si->mac_id);
+       return 0;
+ }
+@@ -336,8 +336,8 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
+       kfree(si->mask);
+       rtwdev->sta_cnt--;
+-      rtw_info(rtwdev, "sta %pM with macid %d left\n",
+-               sta->addr, si->mac_id);
++      rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %pM with macid %d left\n",
++              sta->addr, si->mac_id);
+ }
+ struct rtw_fwcd_hdr {
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+index db078df63f85..80d4761796b1 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+@@ -499,7 +499,7 @@ static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx)
+       }
+       if (lna_idx >= lna_gain_table_size) {
+-              rtw_info(rtwdev, "incorrect lna index (%d)\n", lna_idx);
++              rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx);
+               return -120;
+       }
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+index dd4fbb82750d..a23806b69b0f 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+@@ -1012,12 +1012,12 @@ static int rtw8822b_set_antenna(struct rtw_dev *rtwdev,
+               antenna_tx, antenna_rx);
+       if (!rtw8822b_check_rf_path(antenna_tx)) {
+-              rtw_info(rtwdev, "unsupported tx path 0x%x\n", antenna_tx);
++              rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx);
+               return -EINVAL;
+       }
+       if (!rtw8822b_check_rf_path(antenna_rx)) {
+-              rtw_info(rtwdev, "unsupported rx path 0x%x\n", antenna_rx);
++              rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx);
+               return -EINVAL;
+       }
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+index 35c46e5209de..ddf4d1a23e60 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+@@ -2798,7 +2798,7 @@ static int rtw8822c_set_antenna(struct rtw_dev *rtwdev,
+       case BB_PATH_AB:
+               break;
+       default:
+-              rtw_info(rtwdev, "unsupported tx path 0x%x\n", antenna_tx);
++              rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx);
+               return -EINVAL;
+       }
+@@ -2808,7 +2808,7 @@ static int rtw8822c_set_antenna(struct rtw_dev *rtwdev,
+       case BB_PATH_AB:
+               break;
+       default:
+-              rtw_info(rtwdev, "unsupported rx path 0x%x\n", antenna_rx);
++              rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx);
+               return -EINVAL;
+       }
+diff --git a/drivers/net/wireless/realtek/rtw88/sar.c b/drivers/net/wireless/realtek/rtw88/sar.c
+index 3383726c4d90..c472f1502b82 100644
+--- a/drivers/net/wireless/realtek/rtw88/sar.c
++++ b/drivers/net/wireless/realtek/rtw88/sar.c
+@@ -91,10 +91,10 @@ int rtw_set_sar_specs(struct rtw_dev *rtwdev,
+                       return -EINVAL;
+               power = sar->sub_specs[i].power;
+-              rtw_info(rtwdev, "On freq %u to %u, set SAR %d in 1/%lu dBm\n",
+-                       rtw_common_sar_freq_ranges[idx].start_freq,
+-                       rtw_common_sar_freq_ranges[idx].end_freq,
+-                       power, BIT(RTW_COMMON_SAR_FCT));
++              rtw_dbg(rtwdev, RTW_DBG_REGD, "On freq %u to %u, set SAR %d in 1/%lu dBm\n",
++                      rtw_common_sar_freq_ranges[idx].start_freq,
++                      rtw_common_sar_freq_ranges[idx].end_freq,
++                      power, BIT(RTW_COMMON_SAR_FCT));
+               for (j = 0; j < RTW_RF_PATH_MAX; j++) {
+                       for (k = 0; k < RTW_RATE_SECTION_MAX; k++) {
+-- 
+2.35.1
+
diff --git a/queue-5.17/rtw89-fix-rcu-usage-in-rtw89_core_txq_push.patch b/queue-5.17/rtw89-fix-rcu-usage-in-rtw89_core_txq_push.patch
new file mode 100644 (file)
index 0000000..657aa5b
--- /dev/null
@@ -0,0 +1,116 @@
+From 8b5980b545a030b5c25cf3fd0a6d9c351108be56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Feb 2022 20:37:51 +0100
+Subject: rtw89: fix RCU usage in rtw89_core_txq_push()
+
+From: Jiri Kosina <jkosina@suse.cz>
+
+[ Upstream commit f3d825a35920714fb7f73e4d4f36ea2328860660 ]
+
+ieee80211_tx_h_select_key() is performing a series of RCU dereferences,
+but rtw89_core_txq_push() is calling it (via ieee80211_tx_dequeue_ni())
+without RCU read-side lock held; fix that.
+
+This addresses the splat below.
+
+ =============================
+ WARNING: suspicious RCU usage
+ 5.17.0-rc4-00003-gccad664b7f14 #3 Tainted: G            E
+ -----------------------------
+ net/mac80211/tx.c:593 suspicious rcu_dereference_check() usage!
+
+ other info that might help us debug this:
+
+ rcu_scheduler_active = 2, debug_locks = 1
+ 2 locks held by kworker/u33:0/184:
+  #0: ffff9c0b14811d38 ((wq_completion)rtw89_tx_wq){+.+.}-{0:0}, at: process_one_work+0x258/0x660
+  #1: ffffb97380cf3e78 ((work_completion)(&rtwdev->txq_work)){+.+.}-{0:0}, at: process_one_work+0x258/0x660
+
+ stack backtrace:
+ CPU: 8 PID: 184 Comm: kworker/u33:0 Tainted: G            E     5.17.0-rc4-00003-gccad664b7f14 #3 473b49ab0e7c2d6af2900c756bfd04efd7a9de13
+ Hardware name: LENOVO 20UJS2B905/20UJS2B905, BIOS R1CET63W(1.32 ) 04/09/2021
+ Workqueue: rtw89_tx_wq rtw89_core_txq_work [rtw89_core]
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x58/0x71
+  ieee80211_tx_h_select_key+0x2c0/0x530 [mac80211 911c23e2351c0ae60b597a67b1204a5ea955e365]
+  ieee80211_tx_dequeue+0x1a7/0x1260 [mac80211 911c23e2351c0ae60b597a67b1204a5ea955e365]
+  rtw89_core_txq_work+0x1a6/0x420 [rtw89_core b39ba493f2e517ad75e0f8187ecc24edf58bbbea]
+  process_one_work+0x2d8/0x660
+  worker_thread+0x39/0x3e0
+  ? process_one_work+0x660/0x660
+  kthread+0xe5/0x110
+  ? kthread_complete_and_exit+0x20/0x20
+  ret_from_fork+0x22/0x30
+  </TASK>
+
+ =============================
+ WARNING: suspicious RCU usage
+ 5.17.0-rc4-00003-gccad664b7f14 #3 Tainted: G            E
+ -----------------------------
+ net/mac80211/tx.c:607 suspicious rcu_dereference_check() usage!
+
+ other info that might help us debug this:
+
+ rcu_scheduler_active = 2, debug_locks = 1
+ 2 locks held by kworker/u33:0/184:
+  #0: ffff9c0b14811d38 ((wq_completion)rtw89_tx_wq){+.+.}-{0:0}, at: process_one_work+0x258/0x660
+  #1: ffffb97380cf3e78 ((work_completion)(&rtwdev->txq_work)){+.+.}-{0:0}, at: process_one_work+0x258/0x660
+
+ stack backtrace:
+ CPU: 8 PID: 184 Comm: kworker/u33:0 Tainted: G            E     5.17.0-rc4-00003-gccad664b7f14 #3 473b49ab0e7c2d6af2900c756bfd04efd7a9de13
+ Hardware name: LENOVO 20UJS2B905/20UJS2B905, BIOS R1CET63W(1.32 ) 04/09/2021
+ Workqueue: rtw89_tx_wq rtw89_core_txq_work [rtw89_core]
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x58/0x71
+  ieee80211_tx_h_select_key+0x464/0x530 [mac80211 911c23e2351c0ae60b597a67b1204a5ea955e365]
+  ieee80211_tx_dequeue+0x1a7/0x1260 [mac80211 911c23e2351c0ae60b597a67b1204a5ea955e365]
+  rtw89_core_txq_work+0x1a6/0x420 [rtw89_core b39ba493f2e517ad75e0f8187ecc24edf58bbbea]
+  process_one_work+0x2d8/0x660
+  worker_thread+0x39/0x3e0
+  ? process_one_work+0x660/0x660
+  kthread+0xe5/0x110
+  ? kthread_complete_and_exit+0x20/0x20
+  ret_from_fork+0x22/0x30
+  </TASK>
+
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/nycvar.YFH.7.76.2202152037000.11721@cbobk.fhfr.pm
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/core.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
+index a0737eea9f81..9632e7f218dd 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.c
++++ b/drivers/net/wireless/realtek/rtw89/core.c
+@@ -1509,11 +1509,12 @@ static void rtw89_core_txq_push(struct rtw89_dev *rtwdev,
+       unsigned long i;
+       int ret;
++      rcu_read_lock();
+       for (i = 0; i < frame_cnt; i++) {
+               skb = ieee80211_tx_dequeue_ni(rtwdev->hw, txq);
+               if (!skb) {
+                       rtw89_debug(rtwdev, RTW89_DBG_TXRX, "dequeue a NULL skb\n");
+-                      return;
++                      goto out;
+               }
+               rtw89_core_txq_check_agg(rtwdev, rtwtxq, skb);
+               ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, NULL);
+@@ -1523,6 +1524,8 @@ static void rtw89_core_txq_push(struct rtw89_dev *rtwdev,
+                       break;
+               }
+       }
++out:
++      rcu_read_unlock();
+ }
+ static u32 rtw89_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 tid)
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-aha152x-fix-aha152x_setup-__setup-handler-retur.patch b/queue-5.17/scsi-aha152x-fix-aha152x_setup-__setup-handler-retur.patch
new file mode 100644 (file)
index 0000000..425370e
--- /dev/null
@@ -0,0 +1,52 @@
+From 40307f16d6d275cecc3671c9fb6f5029e2f85d41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Feb 2022 16:06:23 -0800
+Subject: scsi: aha152x: Fix aha152x_setup() __setup handler return value
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit cc8294ec4738d25e2bb2d71f7d82a9bf7f4a157b ]
+
+__setup() handlers should return 1 if the command line option is handled
+and 0 if not (or maybe never return 0; doing so just pollutes init's
+environment with strings that are not init arguments/parameters).
+
+Return 1 from aha152x_setup() to indicate that the boot option has been
+handled.
+
+Link: lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru
+Link: https://lore.kernel.org/r/20220223000623.5920-1-rdunlap@infradead.org
+Cc: "Juergen E. Fischer" <fischer@norbit.de>
+Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
+Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
+Reported-by: Igor Zhbanov <i.zhbanov@omprussia.ru>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/aha152x.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
+index d17880b57d17..2449b4215b32 100644
+--- a/drivers/scsi/aha152x.c
++++ b/drivers/scsi/aha152x.c
+@@ -3375,13 +3375,11 @@ static int __init aha152x_setup(char *str)
+       setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 1;
+       setup[setup_count].delay       = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;
+       setup[setup_count].ext_trans   = ints[0] >= 8 ? ints[8] : 0;
+-      if (ints[0] > 8) {                                                /*}*/
++      if (ints[0] > 8)
+               printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
+                      "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");
+-      } else {
++      else
+               setup_count++;
+-              return 0;
+-      }
+       return 1;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-bfa-replace-snprintf-with-sysfs_emit.patch b/queue-5.17/scsi-bfa-replace-snprintf-with-sysfs_emit.patch
new file mode 100644 (file)
index 0000000..52806e1
--- /dev/null
@@ -0,0 +1,169 @@
+From 5b556d47e8cbf89855f800243ea55b7292cc6b13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 08:03:46 +0800
+Subject: scsi: bfa: Replace snprintf() with sysfs_emit()
+
+From: Yang Guang <yang.guang5@zte.com.cn>
+
+[ Upstream commit 2245ea91fd3a04cafbe2f54911432a8657528c3b ]
+
+coccinelle report:
+./drivers/scsi/bfa/bfad_attr.c:908:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:860:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:888:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:853:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:808:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:728:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:822:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:927:9-17:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:900:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:874:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:714:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/bfa/bfad_attr.c:839:8-16:
+WARNING: use scnprintf or sprintf
+
+Use sysfs_emit() instead of scnprintf() or sprintf().
+
+Link: https://lore.kernel.org/r/def83ff75faec64ba592b867a8499b1367bae303.1643181468.git.yang.guang5@zte.com.cn
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Yang Guang <yang.guang5@zte.com.cn>
+Signed-off-by: David Yang <davidcomponentone@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/bfa/bfad_attr.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
+index f46989bd083c..5a85401e9e2d 100644
+--- a/drivers/scsi/bfa/bfad_attr.c
++++ b/drivers/scsi/bfa/bfad_attr.c
+@@ -711,7 +711,7 @@ bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
+       char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
+       bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
+-      return snprintf(buf, PAGE_SIZE, "%s\n", serial_num);
++      return sysfs_emit(buf, "%s\n", serial_num);
+ }
+ static ssize_t
+@@ -725,7 +725,7 @@ bfad_im_model_show(struct device *dev, struct device_attribute *attr,
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
+       bfa_get_adapter_model(&bfad->bfa, model);
+-      return snprintf(buf, PAGE_SIZE, "%s\n", model);
++      return sysfs_emit(buf, "%s\n", model);
+ }
+ static ssize_t
+@@ -805,7 +805,7 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
+               snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
+                       "Invalid Model");
+-      return snprintf(buf, PAGE_SIZE, "%s\n", model_descr);
++      return sysfs_emit(buf, "%s\n", model_descr);
+ }
+ static ssize_t
+@@ -819,7 +819,7 @@ bfad_im_node_name_show(struct device *dev, struct device_attribute *attr,
+       u64        nwwn;
+       nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port);
+-      return snprintf(buf, PAGE_SIZE, "0x%llx\n", cpu_to_be64(nwwn));
++      return sysfs_emit(buf, "0x%llx\n", cpu_to_be64(nwwn));
+ }
+ static ssize_t
+@@ -836,7 +836,7 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
+       bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
+       strlcpy(symname, port_attr.port_cfg.sym_name.symname,
+                       BFA_SYMNAME_MAXLEN);
+-      return snprintf(buf, PAGE_SIZE, "%s\n", symname);
++      return sysfs_emit(buf, "%s\n", symname);
+ }
+ static ssize_t
+@@ -850,14 +850,14 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
+       char hw_ver[BFA_VERSION_LEN];
+       bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
+-      return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver);
++      return sysfs_emit(buf, "%s\n", hw_ver);
+ }
+ static ssize_t
+ bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr,
+                               char *buf)
+ {
+-      return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION);
++      return sysfs_emit(buf, "%s\n", BFAD_DRIVER_VERSION);
+ }
+ static ssize_t
+@@ -871,7 +871,7 @@ bfad_im_optionrom_version_show(struct device *dev,
+       char optrom_ver[BFA_VERSION_LEN];
+       bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
+-      return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver);
++      return sysfs_emit(buf, "%s\n", optrom_ver);
+ }
+ static ssize_t
+@@ -885,7 +885,7 @@ bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
+       char fw_ver[BFA_VERSION_LEN];
+       bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
+-      return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver);
++      return sysfs_emit(buf, "%s\n", fw_ver);
+ }
+ static ssize_t
+@@ -897,7 +897,7 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
+                       (struct bfad_im_port_s *) shost->hostdata[0];
+       struct bfad_s *bfad = im_port->bfad;
+-      return snprintf(buf, PAGE_SIZE, "%d\n",
++      return sysfs_emit(buf, "%d\n",
+                       bfa_get_nports(&bfad->bfa));
+ }
+@@ -905,7 +905,7 @@ static ssize_t
+ bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr,
+                               char *buf)
+ {
+-      return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME);
++      return sysfs_emit(buf, "%s\n", BFAD_DRIVER_NAME);
+ }
+ static ssize_t
+@@ -924,14 +924,14 @@ bfad_im_num_of_discovered_ports_show(struct device *dev,
+       rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s),
+                        GFP_ATOMIC);
+       if (rports == NULL)
+-              return snprintf(buf, PAGE_SIZE, "Failed\n");
++              return sysfs_emit(buf, "Failed\n");
+       spin_lock_irqsave(&bfad->bfad_lock, flags);
+       bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
+       spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+       kfree(rports);
+-      return snprintf(buf, PAGE_SIZE, "%d\n", nrports);
++      return sysfs_emit(buf, "%d\n", nrports);
+ }
+ static          DEVICE_ATTR(serial_number, S_IRUGO,
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-hisi_sas-free-irq-vectors-in-order-for-v3-hw.patch b/queue-5.17/scsi-hisi_sas-free-irq-vectors-in-order-for-v3-hw.patch
new file mode 100644 (file)
index 0000000..fd8fee2
--- /dev/null
@@ -0,0 +1,109 @@
+From bbf02a0027111c35be978e4f59477cf573d3de74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 19:51:26 +0800
+Subject: scsi: hisi_sas: Free irq vectors in order for v3 HW
+
+From: Qi Liu <liuqi115@huawei.com>
+
+[ Upstream commit 554fb72ee34f4732c7f694f56c3c6e67790352a0 ]
+
+If the driver probe fails to request the channel IRQ or fatal IRQ, the
+driver will free the IRQ vectors before freeing the IRQs in free_irq(),
+and this will cause a kernel BUG like this:
+
+------------[ cut here ]------------
+kernel BUG at drivers/pci/msi.c:369!
+Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
+Call trace:
+   free_msi_irqs+0x118/0x13c
+   pci_disable_msi+0xfc/0x120
+   pci_free_irq_vectors+0x24/0x3c
+   hisi_sas_v3_probe+0x360/0x9d0 [hisi_sas_v3_hw]
+   local_pci_probe+0x44/0xb0
+   work_for_cpu_fn+0x20/0x34
+   process_one_work+0x1d0/0x340
+   worker_thread+0x2e0/0x460
+   kthread+0x180/0x190
+   ret_from_fork+0x10/0x20
+---[ end trace b88990335b610c11 ]---
+
+So we use devm_add_action() to control the order in which we free the
+vectors.
+
+Link: https://lore.kernel.org/r/1645703489-87194-4-git-send-email-john.garry@huawei.com
+Signed-off-by: Qi Liu <liuqi115@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 70173389f6eb..104ef772b512 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2398,17 +2398,25 @@ static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p)
+       return IRQ_WAKE_THREAD;
+ }
++static void hisi_sas_v3_free_vectors(void *data)
++{
++      struct pci_dev *pdev = data;
++
++      pci_free_irq_vectors(pdev);
++}
++
+ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
+ {
+       int vectors;
+       int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi;
+       struct Scsi_Host *shost = hisi_hba->shost;
++      struct pci_dev *pdev = hisi_hba->pci_dev;
+       struct irq_affinity desc = {
+               .pre_vectors = BASE_VECTORS_V3_HW,
+       };
+       min_msi = MIN_AFFINE_VECTORS_V3_HW;
+-      vectors = pci_alloc_irq_vectors_affinity(hisi_hba->pci_dev,
++      vectors = pci_alloc_irq_vectors_affinity(pdev,
+                                                min_msi, max_msi,
+                                                PCI_IRQ_MSI |
+                                                PCI_IRQ_AFFINITY,
+@@ -2420,6 +2428,7 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
+       hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
+       shost->nr_hw_queues = hisi_hba->cq_nvecs;
++      devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
+       return 0;
+ }
+@@ -4769,7 +4778,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       rc = scsi_add_host(shost, dev);
+       if (rc)
+-              goto err_out_free_irq_vectors;
++              goto err_out_debugfs;
+       rc = sas_register_ha(sha);
+       if (rc)
+@@ -4800,8 +4809,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       sas_unregister_ha(sha);
+ err_out_register_ha:
+       scsi_remove_host(shost);
+-err_out_free_irq_vectors:
+-      pci_free_irq_vectors(pdev);
+ err_out_debugfs:
+       debugfs_exit_v3_hw(hisi_hba);
+ err_out_ha:
+@@ -4825,7 +4832,6 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba)
+               devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq);
+       }
+-      pci_free_irq_vectors(pdev);
+ }
+ static void hisi_sas_v3_remove(struct pci_dev *pdev)
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-hisi_sas-limit-users-changing-debugfs-bist-coun.patch b/queue-5.17/scsi-hisi_sas-limit-users-changing-debugfs-bist-coun.patch
new file mode 100644 (file)
index 0000000..ccdcaeb
--- /dev/null
@@ -0,0 +1,95 @@
+From 5fe5059b74c9f24e75bd11a22e6edba1076bc57d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 19:51:28 +0800
+Subject: scsi: hisi_sas: Limit users changing debugfs BIST count value
+
+From: Xiang Chen <chenxiang66@hisilicon.com>
+
+[ Upstream commit 286ce4c65fbdf5eb9d4d5f4e4997c4e32bf1b073 ]
+
+Add a file operation for "cnt" file under bist directory, so users can only
+read "cnt" or clear "cnt" to zero, but cannot randomly modify.
+
+Link: https://lore.kernel.org/r/1645703489-87194-6-git-send-email-john.garry@huawei.com
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: Qi Liu <liuqi115@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 52 +++++++++++++++++++++++++-
+ 1 file changed, 50 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 104ef772b512..52089538e9de 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -3976,6 +3976,54 @@ static const struct file_operations debugfs_bist_phy_v3_hw_fops = {
+       .owner = THIS_MODULE,
+ };
++static ssize_t debugfs_bist_cnt_v3_hw_write(struct file *filp,
++                                      const char __user *buf,
++                                      size_t count, loff_t *ppos)
++{
++      struct seq_file *m = filp->private_data;
++      struct hisi_hba *hisi_hba = m->private;
++      unsigned int cnt;
++      int val;
++
++      if (hisi_hba->debugfs_bist_enable)
++              return -EPERM;
++
++      val = kstrtouint_from_user(buf, count, 0, &cnt);
++      if (val)
++              return val;
++
++      if (cnt)
++              return -EINVAL;
++
++      hisi_hba->debugfs_bist_cnt = 0;
++      return count;
++}
++
++static int debugfs_bist_cnt_v3_hw_show(struct seq_file *s, void *p)
++{
++      struct hisi_hba *hisi_hba = s->private;
++
++      seq_printf(s, "%u\n", hisi_hba->debugfs_bist_cnt);
++
++      return 0;
++}
++
++static int debugfs_bist_cnt_v3_hw_open(struct inode *inode,
++                                        struct file *filp)
++{
++      return single_open(filp, debugfs_bist_cnt_v3_hw_show,
++                         inode->i_private);
++}
++
++static const struct file_operations debugfs_bist_cnt_v3_hw_ops = {
++      .open = debugfs_bist_cnt_v3_hw_open,
++      .read = seq_read,
++      .write = debugfs_bist_cnt_v3_hw_write,
++      .llseek = seq_lseek,
++      .release = single_release,
++      .owner = THIS_MODULE,
++};
++
+ static const struct {
+       int             value;
+       char            *name;
+@@ -4613,8 +4661,8 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba)
+       debugfs_create_file("phy_id", 0600, hisi_hba->debugfs_bist_dentry,
+                           hisi_hba, &debugfs_bist_phy_v3_hw_fops);
+-      debugfs_create_u32("cnt", 0600, hisi_hba->debugfs_bist_dentry,
+-                         &hisi_hba->debugfs_bist_cnt);
++      debugfs_create_file("cnt", 0600, hisi_hba->debugfs_bist_dentry,
++                          hisi_hba, &debugfs_bist_cnt_v3_hw_ops);
+       debugfs_create_file("loopback_mode", 0600,
+                           hisi_hba->debugfs_bist_dentry,
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-libfc-fix-use-after-free-in-fc_exch_abts_resp.patch b/queue-5.17/scsi-libfc-fix-use-after-free-in-fc_exch_abts_resp.patch
new file mode 100644 (file)
index 0000000..99b6884
--- /dev/null
@@ -0,0 +1,39 @@
+From aa25e73b0e67d5358c72db49ee8b8b6733163f05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Mar 2022 09:51:15 +0800
+Subject: scsi: libfc: Fix use after free in fc_exch_abts_resp()
+
+From: Jianglei Nie <niejianglei2021@163.com>
+
+[ Upstream commit 271add11994ba1a334859069367e04d2be2ebdd4 ]
+
+fc_exch_release(ep) will decrease the ep's reference count. When the
+reference count reaches zero, it is freed. But ep is still used in the
+following code, which will lead to a use after free.
+
+Return after the fc_exch_release() call to avoid use after free.
+
+Link: https://lore.kernel.org/r/20220303015115.459778-1-niejianglei2021@163.com
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Jianglei Nie <niejianglei2021@163.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/libfc/fc_exch.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
+index 841000445b9a..aa223db4cf53 100644
+--- a/drivers/scsi/libfc/fc_exch.c
++++ b/drivers/scsi/libfc/fc_exch.c
+@@ -1701,6 +1701,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
+       if (cancel_delayed_work_sync(&ep->timeout_work)) {
+               FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n");
+               fc_exch_release(ep);    /* release from pending timer hold */
++              return;
+       }
+       spin_lock_bh(&ep->ex_lock);
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-mpi3mr-fix-deadlock-while-canceling-the-fw-even.patch b/queue-5.17/scsi-mpi3mr-fix-deadlock-while-canceling-the-fw-even.patch
new file mode 100644 (file)
index 0000000..adeb3f1
--- /dev/null
@@ -0,0 +1,247 @@
+From 426e8b6e3ff234c800a0f85e898ba51da4b1f062 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 15:28:09 +0530
+Subject: scsi: mpi3mr: Fix deadlock while canceling the fw event
+
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+
+[ Upstream commit 580e6742205efe6b0bfa5a6a6079f509d99168e0 ]
+
+During controller reset, the driver tries to flush all the pending firmware
+event works from worker queue that are queued prior to the reset. However,
+if any work is waiting for device addition/removal operation to be
+completed at the SML, then a deadlock is observed. This is due to the
+controller reset waiting for the device addition/removal to be completed
+and the device/addition removal is waiting for the controller reset to be
+completed.
+
+To limit this deadlock, continue with the controller reset handling without
+canceling the work which is waiting for device addition/removal operation
+to complete at SML.
+
+Link: https://lore.kernel.org/r/20220210095817.22828-2-sreekanth.reddy@broadcom.com
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr.h    |   4 ++
+ drivers/scsi/mpi3mr/mpi3mr_fw.c |   2 +-
+ drivers/scsi/mpi3mr/mpi3mr_os.c | 106 ++++++++++++++++++++++++++------
+ 3 files changed, 91 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
+index fc4eaf6d1e47..d892ade421bf 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr.h
++++ b/drivers/scsi/mpi3mr/mpi3mr.h
+@@ -866,6 +866,8 @@ struct mpi3mr_ioc {
+  * @send_ack: Event acknowledgment required or not
+  * @process_evt: Bottomhalf processing required or not
+  * @evt_ctx: Event context to send in Ack
++ * @pending_at_sml: waiting for device add/remove API to complete
++ * @discard: discard this event
+  * @ref_count: kref count
+  * @event_data: Actual MPI3 event data
+  */
+@@ -877,6 +879,8 @@ struct mpi3mr_fwevt {
+       bool send_ack;
+       bool process_evt;
+       u32 evt_ctx;
++      bool pending_at_sml;
++      bool discard;
+       struct kref ref_count;
+       char event_data[0] __aligned(4);
+ };
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
+index 15bdc21ead66..7193b983ee3b 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
+@@ -4353,8 +4353,8 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
+       memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
+       memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
+       memset(mrioc->evtack_cmds_bitmap, 0, mrioc->evtack_cmds_bitmap_sz);
+-      mpi3mr_cleanup_fwevt_list(mrioc);
+       mpi3mr_flush_host_io(mrioc);
++      mpi3mr_cleanup_fwevt_list(mrioc);
+       mpi3mr_invalidate_devhandles(mrioc);
+       if (mrioc->prepare_for_reset) {
+               mrioc->prepare_for_reset = 0;
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
+index 284117da9086..d205354be63a 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
+@@ -285,6 +285,35 @@ static struct mpi3mr_fwevt *mpi3mr_dequeue_fwevt(
+       return fwevt;
+ }
++/**
++ * mpi3mr_cancel_work - cancel firmware event
++ * @fwevt: fwevt object which needs to be canceled
++ *
++ * Return: Nothing.
++ */
++static void mpi3mr_cancel_work(struct mpi3mr_fwevt *fwevt)
++{
++      /*
++       * Wait on the fwevt to complete. If this returns 1, then
++       * the event was never executed.
++       *
++       * If it did execute, we wait for it to finish, and the put will
++       * happen from mpi3mr_process_fwevt()
++       */
++      if (cancel_work_sync(&fwevt->work)) {
++              /*
++               * Put fwevt reference count after
++               * dequeuing it from worker queue
++               */
++              mpi3mr_fwevt_put(fwevt);
++              /*
++               * Put fwevt reference count to neutralize
++               * kref_init increment
++               */
++              mpi3mr_fwevt_put(fwevt);
++      }
++}
++
+ /**
+  * mpi3mr_cleanup_fwevt_list - Cleanup firmware event list
+  * @mrioc: Adapter instance reference
+@@ -302,28 +331,25 @@ void mpi3mr_cleanup_fwevt_list(struct mpi3mr_ioc *mrioc)
+           !mrioc->fwevt_worker_thread)
+               return;
+-      while ((fwevt = mpi3mr_dequeue_fwevt(mrioc)) ||
+-          (fwevt = mrioc->current_event)) {
++      while ((fwevt = mpi3mr_dequeue_fwevt(mrioc)))
++              mpi3mr_cancel_work(fwevt);
++
++      if (mrioc->current_event) {
++              fwevt = mrioc->current_event;
+               /*
+-               * Wait on the fwevt to complete. If this returns 1, then
+-               * the event was never executed, and we need a put for the
+-               * reference the work had on the fwevt.
+-               *
+-               * If it did execute, we wait for it to finish, and the put will
+-               * happen from mpi3mr_process_fwevt()
++               * Don't call cancel_work_sync() API for the
++               * fwevt work if the controller reset is
++               * get called as part of processing the
++               * same fwevt work (or) when worker thread is
++               * waiting for device add/remove APIs to complete.
++               * Otherwise we will see deadlock.
+                */
+-              if (cancel_work_sync(&fwevt->work)) {
+-                      /*
+-                       * Put fwevt reference count after
+-                       * dequeuing it from worker queue
+-                       */
+-                      mpi3mr_fwevt_put(fwevt);
+-                      /*
+-                       * Put fwevt reference count to neutralize
+-                       * kref_init increment
+-                       */
+-                      mpi3mr_fwevt_put(fwevt);
++              if (current_work() == &fwevt->work || fwevt->pending_at_sml) {
++                      fwevt->discard = 1;
++                      return;
+               }
++
++              mpi3mr_cancel_work(fwevt);
+       }
+ }
+@@ -690,6 +716,24 @@ static struct mpi3mr_tgt_dev  *__mpi3mr_get_tgtdev_from_tgtpriv(
+       return tgtdev;
+ }
++/**
++ * mpi3mr_print_device_event_notice - print notice related to post processing of
++ *                                    device event after controller reset.
++ *
++ * @mrioc: Adapter instance reference
++ * @device_add: true for device add event and false for device removal event
++ *
++ * Return: None.
++ */
++static void mpi3mr_print_device_event_notice(struct mpi3mr_ioc *mrioc,
++      bool device_add)
++{
++      ioc_notice(mrioc, "Device %s was in progress before the reset and\n",
++          (device_add ? "addition" : "removal"));
++      ioc_notice(mrioc, "completed after reset, verify whether the exposed devices\n");
++      ioc_notice(mrioc, "are matched with attached devices for correctness\n");
++}
++
+ /**
+  * mpi3mr_remove_tgtdev_from_host - Remove dev from upper layers
+  * @mrioc: Adapter instance reference
+@@ -714,8 +758,17 @@ static void mpi3mr_remove_tgtdev_from_host(struct mpi3mr_ioc *mrioc,
+       }
+       if (tgtdev->starget) {
++              if (mrioc->current_event)
++                      mrioc->current_event->pending_at_sml = 1;
+               scsi_remove_target(&tgtdev->starget->dev);
+               tgtdev->host_exposed = 0;
++              if (mrioc->current_event) {
++                      mrioc->current_event->pending_at_sml = 0;
++                      if (mrioc->current_event->discard) {
++                              mpi3mr_print_device_event_notice(mrioc, false);
++                              return;
++                      }
++              }
+       }
+       ioc_info(mrioc, "%s :Removed handle(0x%04x), wwid(0x%016llx)\n",
+           __func__, tgtdev->dev_handle, (unsigned long long)tgtdev->wwid);
+@@ -749,11 +802,20 @@ static int mpi3mr_report_tgtdev_to_host(struct mpi3mr_ioc *mrioc,
+       }
+       if (!tgtdev->host_exposed && !mrioc->reset_in_progress) {
+               tgtdev->host_exposed = 1;
++              if (mrioc->current_event)
++                      mrioc->current_event->pending_at_sml = 1;
+               scsi_scan_target(&mrioc->shost->shost_gendev, 0,
+                   tgtdev->perst_id,
+                   SCAN_WILD_CARD, SCSI_SCAN_INITIAL);
+               if (!tgtdev->starget)
+                       tgtdev->host_exposed = 0;
++              if (mrioc->current_event) {
++                      mrioc->current_event->pending_at_sml = 0;
++                      if (mrioc->current_event->discard) {
++                              mpi3mr_print_device_event_notice(mrioc, true);
++                              goto out;
++                      }
++              }
+       }
+ out:
+       if (tgtdev)
+@@ -1193,6 +1255,8 @@ static void mpi3mr_sastopochg_evt_bh(struct mpi3mr_ioc *mrioc,
+       mpi3mr_sastopochg_evt_debug(mrioc, event_data);
+       for (i = 0; i < event_data->num_entries; i++) {
++              if (fwevt->discard)
++                      return;
+               handle = le16_to_cpu(event_data->phy_entry[i].attached_dev_handle);
+               if (!handle)
+                       continue;
+@@ -1324,6 +1388,8 @@ static void mpi3mr_pcietopochg_evt_bh(struct mpi3mr_ioc *mrioc,
+       mpi3mr_pcietopochg_evt_debug(mrioc, event_data);
+       for (i = 0; i < event_data->num_entries; i++) {
++              if (fwevt->discard)
++                      return;
+               handle =
+                   le16_to_cpu(event_data->port_entry[i].attached_dev_handle);
+               if (!handle)
+@@ -1362,8 +1428,8 @@ static void mpi3mr_pcietopochg_evt_bh(struct mpi3mr_ioc *mrioc,
+ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
+       struct mpi3mr_fwevt *fwevt)
+ {
+-      mrioc->current_event = fwevt;
+       mpi3mr_fwevt_del_from_list(mrioc, fwevt);
++      mrioc->current_event = fwevt;
+       if (mrioc->stop_drv_processing)
+               goto out;
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-mpi3mr-fix-memory-leaks.patch b/queue-5.17/scsi-mpi3mr-fix-memory-leaks.patch
new file mode 100644 (file)
index 0000000..4aa3097
--- /dev/null
@@ -0,0 +1,36 @@
+From c32acb0ea9299a931d80d9ad470cad71dd5e5582 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 15:28:16 +0530
+Subject: scsi: mpi3mr: Fix memory leaks
+
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+
+[ Upstream commit d44b5fefb22e139408ae12b864da1ecb9ad9d1d2 ]
+
+Fix memory leaks related to operational reply queue's memory segments which
+are not getting freed while unloading the driver.
+
+Link: https://lore.kernel.org/r/20220210095817.22828-9-sreekanth.reddy@broadcom.com
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_fw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
+index 7193b983ee3b..e44868230197 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
+@@ -1520,7 +1520,7 @@ static void mpi3mr_free_op_req_q_segments(struct mpi3mr_ioc *mrioc, u16 q_idx)
+                           MPI3MR_MAX_SEG_LIST_SIZE,
+                           mrioc->req_qinfo[q_idx].q_segment_list,
+                           mrioc->req_qinfo[q_idx].q_segment_list_dma);
+-                      mrioc->op_reply_qinfo[q_idx].q_segment_list = NULL;
++                      mrioc->req_qinfo[q_idx].q_segment_list = NULL;
+               }
+       } else
+               size = mrioc->req_qinfo[q_idx].segment_qd *
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-mpi3mr-fix-reporting-of-actual-data-transfer-si.patch b/queue-5.17/scsi-mpi3mr-fix-reporting-of-actual-data-transfer-si.patch
new file mode 100644 (file)
index 0000000..4b67efc
--- /dev/null
@@ -0,0 +1,37 @@
+From 01e7a4039d810e6c0d49461f247ff9fcca274224 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 15:28:14 +0530
+Subject: scsi: mpi3mr: Fix reporting of actual data transfer size
+
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+
+[ Upstream commit 9992246127246a27cc7184f05cce6f62ac48f84e ]
+
+The driver is missing to set the residual size while completing an
+I/O. Ensure proper data transfer size is reported to the kernel on I/O
+completion based on the transfer length reported by the firmware.
+
+Link: https://lore.kernel.org/r/20220210095817.22828-7-sreekanth.reddy@broadcom.com
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_os.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
+index d205354be63a..f7893de35b26 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
+@@ -2617,6 +2617,8 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc,
+               scmd->result = DID_OK << 16;
+               goto out_success;
+       }
++
++      scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_count);
+       if (ioc_status == MPI3_IOCSTATUS_SCSI_DATA_UNDERRUN &&
+           xfer_count == 0 && (scsi_status == MPI3_SCSI_STATUS_BUSY ||
+           scsi_status == MPI3_SCSI_STATUS_RESERVATION_CONFLICT ||
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-mvsas-replace-snprintf-with-sysfs_emit.patch b/queue-5.17/scsi-mvsas-replace-snprintf-with-sysfs_emit.patch
new file mode 100644 (file)
index 0000000..a6722c5
--- /dev/null
@@ -0,0 +1,52 @@
+From fb1c80c3b690a201253ce68340248867255750be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 08:00:59 +0800
+Subject: scsi: mvsas: Replace snprintf() with sysfs_emit()
+
+From: Yang Guang <yang.guang5@zte.com.cn>
+
+[ Upstream commit 0ad3867b0f13e45cfee5a1298bfd40eef096116c ]
+
+coccinelle report:
+./drivers/scsi/mvsas/mv_init.c:699:8-16:
+WARNING: use scnprintf or sprintf
+./drivers/scsi/mvsas/mv_init.c:747:8-16:
+WARNING: use scnprintf or sprintf
+
+Use sysfs_emit() instead of scnprintf() or sprintf().
+
+Link: https://lore.kernel.org/r/c1711f7cf251730a8ceb5bdfc313bf85662b3395.1643182948.git.yang.guang5@zte.com.cn
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Yang Guang <yang.guang5@zte.com.cn>
+Signed-off-by: David Yang <davidcomponentone@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mvsas/mv_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
+index dcae2d4464f9..44df7c03aab8 100644
+--- a/drivers/scsi/mvsas/mv_init.c
++++ b/drivers/scsi/mvsas/mv_init.c
+@@ -696,7 +696,7 @@ static struct pci_driver mvs_pci_driver = {
+ static ssize_t driver_version_show(struct device *cdev,
+                                  struct device_attribute *attr, char *buffer)
+ {
+-      return snprintf(buffer, PAGE_SIZE, "%s\n", DRV_VERSION);
++      return sysfs_emit(buffer, "%s\n", DRV_VERSION);
+ }
+ static DEVICE_ATTR_RO(driver_version);
+@@ -744,7 +744,7 @@ static ssize_t interrupt_coalescing_store(struct device *cdev,
+ static ssize_t interrupt_coalescing_show(struct device *cdev,
+                                        struct device_attribute *attr, char *buffer)
+ {
+-      return snprintf(buffer, PAGE_SIZE, "%d\n", interrupt_coalescing);
++      return sysfs_emit(buffer, "%d\n", interrupt_coalescing);
+ }
+ static DEVICE_ATTR_RW(interrupt_coalescing);
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-pm8001-fix-memory-leak-in-pm8001_chip_fw_flash_.patch b/queue-5.17/scsi-pm8001-fix-memory-leak-in-pm8001_chip_fw_flash_.patch
new file mode 100644 (file)
index 0000000..592f015
--- /dev/null
@@ -0,0 +1,41 @@
+From 5e76b0c76e4ba3f137fc9f1dd8ce6cad12692110 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Feb 2022 12:18:01 +0900
+Subject: scsi: pm8001: Fix memory leak in pm8001_chip_fw_flash_update_req()
+
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+
+[ Upstream commit f792a3629f4c4aa4c3703d66b43ce1edcc3ec09a ]
+
+In pm8001_chip_fw_flash_update_build(), if
+pm8001_chip_fw_flash_update_build() fails, the struct fw_control_ex
+allocated must be freed.
+
+Link: https://lore.kernel.org/r/20220220031810.738362-23-damien.lemoal@opensource.wdc.com
+Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/pm8001/pm8001_hwi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
+index ccc7f53ddbd6..27ead825c2bb 100644
+--- a/drivers/scsi/pm8001/pm8001_hwi.c
++++ b/drivers/scsi/pm8001/pm8001_hwi.c
+@@ -4880,8 +4880,10 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
+       ccb->ccb_tag = tag;
+       rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
+               tag);
+-      if (rc)
++      if (rc) {
++              kfree(fw_control_context);
+               pm8001_tag_free(pm8001_ha, tag);
++      }
+       return rc;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-pm8001-fix-pm8001_mpi_task_abort_resp.patch b/queue-5.17/scsi-pm8001-fix-pm8001_mpi_task_abort_resp.patch
new file mode 100644 (file)
index 0000000..60d400a
--- /dev/null
@@ -0,0 +1,46 @@
+From 6f92c35779e2fa9f6773ae583724be27f8788a8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Feb 2022 12:17:57 +0900
+Subject: scsi: pm8001: Fix pm8001_mpi_task_abort_resp()
+
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+
+[ Upstream commit 7e6b7e740addcea450041b5be8e42f0a4ceece0f ]
+
+The call to pm8001_ccb_task_free() at the end of
+pm8001_mpi_task_abort_resp() already frees the ccb tag. So when the device
+NCQ_ABORT_ALL_FLAG is set, the tag should not be freed again.  Also change
+the hardcoded 0xBFFFFFFF value to ~NCQ_ABORT_ALL_FLAG as it ought to be.
+
+Link: https://lore.kernel.org/r/20220220031810.738362-19-damien.lemoal@opensource.wdc.com
+Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/pm8001/pm8001_hwi.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
+index d853e8d0195a..4f4a9dcb6a1e 100644
+--- a/drivers/scsi/pm8001/pm8001_hwi.c
++++ b/drivers/scsi/pm8001/pm8001_hwi.c
+@@ -3706,12 +3706,11 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+       mb();
+       if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) {
+-              pm8001_tag_free(pm8001_ha, tag);
+               sas_free_task(t);
+-              /* clear the flag */
+-              pm8001_dev->id &= 0xBFFFFFFF;
+-      } else
++              pm8001_dev->id &= ~NCQ_ABORT_ALL_FLAG;
++      } else {
+               t->task_done(t);
++      }
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-pm8001-fix-pm80xx_pci_mem_copy-interface.patch b/queue-5.17/scsi-pm8001-fix-pm80xx_pci_mem_copy-interface.patch
new file mode 100644 (file)
index 0000000..3872bcc
--- /dev/null
@@ -0,0 +1,61 @@
+From da3a4d473dca9d5d851995a909a58646cf905539 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Feb 2022 12:17:44 +0900
+Subject: scsi: pm8001: Fix pm80xx_pci_mem_copy() interface
+
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+
+[ Upstream commit 3762d8f6edcdb03994c919f9487fd6d336c06561 ]
+
+The declaration of the local variable destination1 in pm80xx_pci_mem_copy()
+as a pointer to a u32 results in the sparse warning:
+
+warning: incorrect type in assignment (different base types)
+    expected unsigned int [usertype]
+    got restricted __le32 [usertype]
+
+Furthermore, the destination" argument of pm80xx_pci_mem_copy() is wrongly
+declared with the const attribute.
+
+Fix both problems by changing the type of the "destination" argument to
+"__le32 *" and use this argument directly inside the pm80xx_pci_mem_copy()
+function, thus removing the need for the destination1 local variable.
+
+Link: https://lore.kernel.org/r/20220220031810.738362-6-damien.lemoal@opensource.wdc.com
+Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/pm8001/pm80xx_hwi.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
+index 908dbac20b48..9a0d65ac0174 100644
+--- a/drivers/scsi/pm8001/pm80xx_hwi.c
++++ b/drivers/scsi/pm8001/pm80xx_hwi.c
+@@ -67,18 +67,16 @@ int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shift_value)
+ }
+ static void pm80xx_pci_mem_copy(struct pm8001_hba_info  *pm8001_ha, u32 soffset,
+-                              const void *destination,
++                              __le32 *destination,
+                               u32 dw_count, u32 bus_base_number)
+ {
+       u32 index, value, offset;
+-      u32 *destination1;
+-      destination1 = (u32 *)destination;
+-      for (index = 0; index < dw_count; index += 4, destination1++) {
++      for (index = 0; index < dw_count; index += 4, destination++) {
+               offset = (soffset + index);
+               if (offset < (64 * 1024)) {
+                       value = pm8001_cr32(pm8001_ha, bus_base_number, offset);
+-                      *destination1 =  cpu_to_le32(value);
++                      *destination = cpu_to_le32(value);
+               }
+       }
+       return;
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-pm8001-fix-tag-leaks-on-error.patch b/queue-5.17/scsi-pm8001-fix-tag-leaks-on-error.patch
new file mode 100644 (file)
index 0000000..5e4ec29
--- /dev/null
@@ -0,0 +1,102 @@
+From 4089b61b1137de6e1abe3135c7a65cc17556614c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Feb 2022 12:18:00 +0900
+Subject: scsi: pm8001: Fix tag leaks on error
+
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+
+[ Upstream commit 4c8f04b1905cd4b776d0b720463c091545478ef7 ]
+
+In pm8001_chip_set_dev_state_req(), pm8001_chip_fw_flash_update_req(),
+pm80xx_chip_phy_ctl_req() and pm8001_chip_reg_dev_req() add missing calls
+to pm8001_tag_free() to free the allocated tag when pm8001_mpi_build_cmd()
+fails.
+
+Similarly, in pm8001_exec_internal_task_abort(), if the chip ->task_abort
+method fails, the tag allocated for the abort request task must be
+freed. Add the missing call to pm8001_tag_free().
+
+Link: https://lore.kernel.org/r/20220220031810.738362-22-damien.lemoal@opensource.wdc.com
+Reviewed-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/pm8001/pm8001_hwi.c | 9 +++++++++
+ drivers/scsi/pm8001/pm8001_sas.c | 2 +-
+ drivers/scsi/pm8001/pm80xx_hwi.c | 9 +++++++--
+ 3 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
+index 5ec429cf1e20..ccc7f53ddbd6 100644
+--- a/drivers/scsi/pm8001/pm8001_hwi.c
++++ b/drivers/scsi/pm8001/pm8001_hwi.c
+@@ -4465,6 +4465,9 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
+               SAS_ADDR_SIZE);
+       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+                       sizeof(payload), 0);
++      if (rc)
++              pm8001_tag_free(pm8001_ha, tag);
++
+       return rc;
+ }
+@@ -4877,6 +4880,9 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
+       ccb->ccb_tag = tag;
+       rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
+               tag);
++      if (rc)
++              pm8001_tag_free(pm8001_ha, tag);
++
+       return rc;
+ }
+@@ -4981,6 +4987,9 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
+       payload.nds = cpu_to_le32(state);
+       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+                       sizeof(payload), 0);
++      if (rc)
++              pm8001_tag_free(pm8001_ha, tag);
++
+       return rc;
+ }
+diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
+index c1f871561b32..b68c8400ca15 100644
+--- a/drivers/scsi/pm8001/pm8001_sas.c
++++ b/drivers/scsi/pm8001/pm8001_sas.c
+@@ -847,10 +847,10 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
+               res = PM8001_CHIP_DISP->task_abort(pm8001_ha,
+                       pm8001_dev, flag, task_tag, ccb_tag);
+-
+               if (res) {
+                       del_timer(&task->slow_task->timer);
+                       pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n");
++                      pm8001_tag_free(pm8001_ha, ccb_tag);
+                       goto ex_err;
+               }
+               wait_for_completion(&task->slow_task->completion);
+diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
+index 728190b26924..55163469030d 100644
+--- a/drivers/scsi/pm8001/pm80xx_hwi.c
++++ b/drivers/scsi/pm8001/pm80xx_hwi.c
+@@ -4920,8 +4920,13 @@ static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
+       payload.tag = cpu_to_le32(tag);
+       payload.phyop_phyid =
+               cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
+-      return pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+-                      sizeof(payload), 0);
++
++      rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
++                                sizeof(payload), 0);
++      if (rc)
++              pm8001_tag_free(pm8001_ha, tag);
++
++      return rc;
+ }
+ static u32 pm80xx_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha)
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-pm8001-fix-tag-values-handling.patch b/queue-5.17/scsi-pm8001-fix-tag-values-handling.patch
new file mode 100644 (file)
index 0000000..350c2b6
--- /dev/null
@@ -0,0 +1,310 @@
+From eb7b791736efc76924de3f2db8160cfb2970d9ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Feb 2022 12:17:58 +0900
+Subject: scsi: pm8001: Fix tag values handling
+
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+
+[ Upstream commit 7fb23a785ba38dea907323a039123f231195b297 ]
+
+The function pm8001_tag_alloc() determines free tags using the function
+find_first_zero_bit() which can return 0 when the first bit of the bitmap
+being inspected is 0. As such, tag 0 is a valid tag value that should not
+be dismissed as invalid. Fix the functions pm8001_work_fn(),
+mpi_sata_completion(), pm8001_mpi_task_abort_resp() and
+pm8001_open_reject_retry() to not dismiss 0 tags as invalid.
+
+The value 0xffffffff is used for invalid tags for unused ccb information
+structures. Add the macro definition PM8001_INVALID_TAG to define this
+value.
+
+Link: https://lore.kernel.org/r/20220220031810.738362-20-damien.lemoal@opensource.wdc.com
+Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/pm8001/pm8001_hwi.c  | 52 +++++++++++--------------------
+ drivers/scsi/pm8001/pm8001_init.c |  3 +-
+ drivers/scsi/pm8001/pm8001_sas.c  | 13 ++++----
+ drivers/scsi/pm8001/pm8001_sas.h  |  2 ++
+ drivers/scsi/pm8001/pm80xx_hwi.c  |  5 ---
+ 5 files changed, 28 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
+index 4f4a9dcb6a1e..d244231e62f9 100644
+--- a/drivers/scsi/pm8001/pm8001_hwi.c
++++ b/drivers/scsi/pm8001/pm8001_hwi.c
+@@ -1522,7 +1522,6 @@ void pm8001_work_fn(struct work_struct *work)
+       case IO_XFER_ERROR_BREAK:
+       {       /* This one stashes the sas_task instead */
+               struct sas_task *t = (struct sas_task *)pm8001_dev;
+-              u32 tag;
+               struct pm8001_ccb_info *ccb;
+               struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
+               unsigned long flags, flags1;
+@@ -1544,8 +1543,8 @@ void pm8001_work_fn(struct work_struct *work)
+               /* Search for a possible ccb that matches the task */
+               for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
+                       ccb = &pm8001_ha->ccb_info[i];
+-                      tag = ccb->ccb_tag;
+-                      if ((tag != 0xFFFFFFFF) && (ccb->task == t))
++                      if ((ccb->ccb_tag != PM8001_INVALID_TAG) &&
++                          (ccb->task == t))
+                               break;
+               }
+               if (!ccb) {
+@@ -1567,11 +1566,11 @@ void pm8001_work_fn(struct work_struct *work)
+                       spin_unlock_irqrestore(&t->task_state_lock, flags1);
+                       pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
+                                  t, pw->handler, ts->resp, ts->stat);
+-                      pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
++                      pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
+                       spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+               } else {
+                       spin_unlock_irqrestore(&t->task_state_lock, flags1);
+-                      pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
++                      pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
+                       mb();/* in order to force CPU ordering */
+                       spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+                       t->task_done(t);
+@@ -1580,7 +1579,6 @@ void pm8001_work_fn(struct work_struct *work)
+       case IO_XFER_OPEN_RETRY_TIMEOUT:
+       {       /* This one stashes the sas_task instead */
+               struct sas_task *t = (struct sas_task *)pm8001_dev;
+-              u32 tag;
+               struct pm8001_ccb_info *ccb;
+               struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
+               unsigned long flags, flags1;
+@@ -1614,8 +1612,8 @@ void pm8001_work_fn(struct work_struct *work)
+               /* Search for a possible ccb that matches the task */
+               for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
+                       ccb = &pm8001_ha->ccb_info[i];
+-                      tag = ccb->ccb_tag;
+-                      if ((tag != 0xFFFFFFFF) && (ccb->task == t))
++                      if ((ccb->ccb_tag != PM8001_INVALID_TAG) &&
++                          (ccb->task == t))
+                               break;
+               }
+               if (!ccb) {
+@@ -1686,19 +1684,13 @@ void pm8001_work_fn(struct work_struct *work)
+               struct task_status_struct *ts;
+               struct sas_task *task;
+               int i;
+-              u32 tag, device_id;
++              u32 device_id;
+               for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
+                       ccb = &pm8001_ha->ccb_info[i];
+                       task = ccb->task;
+                       ts = &task->task_status;
+-                      tag = ccb->ccb_tag;
+-                      /* check if tag is NULL */
+-                      if (!tag) {
+-                              pm8001_dbg(pm8001_ha, FAIL,
+-                                      "tag Null\n");
+-                              continue;
+-                      }
++
+                       if (task != NULL) {
+                               dev = task->dev;
+                               if (!dev) {
+@@ -1707,10 +1699,11 @@ void pm8001_work_fn(struct work_struct *work)
+                                       continue;
+                               }
+                               /*complete sas task and update to top layer */
+-                              pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
++                              pm8001_ccb_task_free(pm8001_ha, task, ccb,
++                                                   ccb->ccb_tag);
+                               ts->resp = SAS_TASK_COMPLETE;
+                               task->task_done(task);
+-                      } else if (tag != 0xFFFFFFFF) {
++                      } else if (ccb->ccb_tag != PM8001_INVALID_TAG) {
+                               /* complete the internal commands/non-sas task */
+                               pm8001_dev = ccb->device;
+                               if (pm8001_dev->dcompletion) {
+@@ -1718,7 +1711,7 @@ void pm8001_work_fn(struct work_struct *work)
+                                       pm8001_dev->dcompletion = NULL;
+                               }
+                               complete(pm8001_ha->nvmd_completion);
+-                              pm8001_tag_free(pm8001_ha, tag);
++                              pm8001_tag_free(pm8001_ha, ccb->ccb_tag);
+                       }
+               }
+               /* Deregister all the device ids  */
+@@ -2316,11 +2309,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
+       param = le32_to_cpu(psataPayload->param);
+       tag = le32_to_cpu(psataPayload->tag);
+-      if (!tag) {
+-              pm8001_dbg(pm8001_ha, FAIL, "tag null\n");
+-              return;
+-      }
+-
+       ccb = &pm8001_ha->ccb_info[tag];
+       t = ccb->task;
+       pm8001_dev = ccb->device;
+@@ -3056,7 +3044,7 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha,
+                  device_id, pds, nds, status);
+       complete(pm8001_dev->setds_completion);
+       ccb->task = NULL;
+-      ccb->ccb_tag = 0xFFFFFFFF;
++      ccb->ccb_tag = PM8001_INVALID_TAG;
+       pm8001_tag_free(pm8001_ha, tag);
+ }
+@@ -3074,7 +3062,7 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+                               dlen_status);
+       }
+       ccb->task = NULL;
+-      ccb->ccb_tag = 0xFFFFFFFF;
++      ccb->ccb_tag = PM8001_INVALID_TAG;
+       pm8001_tag_free(pm8001_ha, tag);
+ }
+@@ -3101,7 +3089,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+                * freed by requesting path anywhere.
+                */
+               ccb->task = NULL;
+-              ccb->ccb_tag = 0xFFFFFFFF;
++              ccb->ccb_tag = PM8001_INVALID_TAG;
+               pm8001_tag_free(pm8001_ha, tag);
+               return;
+       }
+@@ -3147,7 +3135,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+       complete(pm8001_ha->nvmd_completion);
+       pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n");
+       ccb->task = NULL;
+-      ccb->ccb_tag = 0xFFFFFFFF;
++      ccb->ccb_tag = PM8001_INVALID_TAG;
+       pm8001_tag_free(pm8001_ha, tag);
+ }
+@@ -3560,7 +3548,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+       }
+       complete(pm8001_dev->dcompletion);
+       ccb->task = NULL;
+-      ccb->ccb_tag = 0xFFFFFFFF;
++      ccb->ccb_tag = PM8001_INVALID_TAG;
+       pm8001_tag_free(pm8001_ha, htag);
+       return 0;
+ }
+@@ -3632,7 +3620,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
+       }
+       kfree(ccb->fw_control_context);
+       ccb->task = NULL;
+-      ccb->ccb_tag = 0xFFFFFFFF;
++      ccb->ccb_tag = PM8001_INVALID_TAG;
+       pm8001_tag_free(pm8001_ha, tag);
+       complete(pm8001_ha->nvmd_completion);
+       return 0;
+@@ -3668,10 +3656,6 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+       status = le32_to_cpu(pPayload->status);
+       tag = le32_to_cpu(pPayload->tag);
+-      if (!tag) {
+-              pm8001_dbg(pm8001_ha, FAIL, " TAG NULL. RETURNING !!!\n");
+-              return -1;
+-      }
+       scp = le32_to_cpu(pPayload->scp);
+       ccb = &pm8001_ha->ccb_info[tag];
+diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
+index d8a2121cb8d9..d2a2593f669d 100644
+--- a/drivers/scsi/pm8001/pm8001_init.c
++++ b/drivers/scsi/pm8001/pm8001_init.c
+@@ -1216,10 +1216,11 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
+                       goto err_out;
+               }
+               pm8001_ha->ccb_info[i].task = NULL;
+-              pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff;
++              pm8001_ha->ccb_info[i].ccb_tag = PM8001_INVALID_TAG;
+               pm8001_ha->ccb_info[i].device = NULL;
+               ++pm8001_ha->tags_num;
+       }
++
+       return 0;
+ err_out_noccb:
+diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
+index 32edda3e55c6..c1f871561b32 100644
+--- a/drivers/scsi/pm8001/pm8001_sas.c
++++ b/drivers/scsi/pm8001/pm8001_sas.c
+@@ -567,7 +567,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
+       task->lldd_task = NULL;
+       ccb->task = NULL;
+-      ccb->ccb_tag = 0xFFFFFFFF;
++      ccb->ccb_tag = PM8001_INVALID_TAG;
+       ccb->open_retry = 0;
+       pm8001_tag_free(pm8001_ha, ccb_idx);
+ }
+@@ -952,9 +952,11 @@ void pm8001_open_reject_retry(
+               struct task_status_struct *ts;
+               struct pm8001_device *pm8001_dev;
+               unsigned long flags1;
+-              u32 tag;
+               struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[i];
++              if (ccb->ccb_tag == PM8001_INVALID_TAG)
++                      continue;
++
+               pm8001_dev = ccb->device;
+               if (!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED))
+                       continue;
+@@ -966,9 +968,6 @@ void pm8001_open_reject_retry(
+                               continue;
+               } else if (pm8001_dev != device_to_close)
+                       continue;
+-              tag = ccb->ccb_tag;
+-              if (!tag || (tag == 0xFFFFFFFF))
+-                      continue;
+               task = ccb->task;
+               if (!task || !task->task_done)
+                       continue;
+@@ -989,11 +988,11 @@ void pm8001_open_reject_retry(
+                               & SAS_TASK_STATE_ABORTED))) {
+                       spin_unlock_irqrestore(&task->task_state_lock,
+                               flags1);
+-                      pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
++                      pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
+               } else {
+                       spin_unlock_irqrestore(&task->task_state_lock,
+                               flags1);
+-                      pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
++                      pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
+                       mb();/* in order to force CPU ordering */
+                       spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+                       task->task_done(task);
+diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
+index a17da1cebce1..1791cdf30276 100644
+--- a/drivers/scsi/pm8001/pm8001_sas.h
++++ b/drivers/scsi/pm8001/pm8001_sas.h
+@@ -738,6 +738,8 @@ void pm8001_free_dev(struct pm8001_device *pm8001_dev);
+ /* ctl shared API */
+ extern const struct attribute_group *pm8001_host_groups[];
++#define PM8001_INVALID_TAG    ((u32)-1)
++
+ static inline void
+ pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
+                       struct sas_task *task, struct pm8001_ccb_info *ccb,
+diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
+index 9a0d65ac0174..728190b26924 100644
+--- a/drivers/scsi/pm8001/pm80xx_hwi.c
++++ b/drivers/scsi/pm8001/pm80xx_hwi.c
+@@ -2404,11 +2404,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
+       param = le32_to_cpu(psataPayload->param);
+       tag = le32_to_cpu(psataPayload->tag);
+-      if (!tag) {
+-              pm8001_dbg(pm8001_ha, FAIL, "tag null\n");
+-              return;
+-      }
+-
+       ccb = &pm8001_ha->ccb_info[tag];
+       t = ccb->task;
+       pm8001_dev = ccb->device;
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-pm8001-fix-task-leak-in-pm8001_send_abort_all.patch b/queue-5.17/scsi-pm8001-fix-task-leak-in-pm8001_send_abort_all.patch
new file mode 100644 (file)
index 0000000..28142a3
--- /dev/null
@@ -0,0 +1,60 @@
+From aa6cfb94996ca02a4ae78f8555c87e2af16a6d0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Feb 2022 12:17:59 +0900
+Subject: scsi: pm8001: Fix task leak in pm8001_send_abort_all()
+
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+
+[ Upstream commit f90a74892f3acf0cdec5844e90fc8686ca13e7d7 ]
+
+In pm8001_send_abort_all(), make sure to free the allocated sas task
+if pm8001_tag_alloc() or pm8001_mpi_build_cmd() fail.
+
+Link: https://lore.kernel.org/r/20220220031810.738362-21-damien.lemoal@opensource.wdc.com
+Reviewed-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/pm8001/pm8001_hwi.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
+index d244231e62f9..5ec429cf1e20 100644
+--- a/drivers/scsi/pm8001/pm8001_hwi.c
++++ b/drivers/scsi/pm8001/pm8001_hwi.c
+@@ -1765,7 +1765,6 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
+       }
+       task = sas_alloc_slow_task(GFP_ATOMIC);
+-
+       if (!task) {
+               pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task\n");
+               return;
+@@ -1774,8 +1773,10 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
+       task->task_done = pm8001_task_done;
+       res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
+-      if (res)
++      if (res) {
++              sas_free_task(task);
+               return;
++      }
+       ccb = &pm8001_ha->ccb_info[ccb_tag];
+       ccb->device = pm8001_ha_dev;
+@@ -1792,8 +1793,10 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
+       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
+                       sizeof(task_abort), 0);
+-      if (ret)
++      if (ret) {
++              sas_free_task(task);
+               pm8001_tag_free(pm8001_ha, ccb_tag);
++      }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-scsi_debug-address-races-following-module-load.patch b/queue-5.17/scsi-scsi_debug-address-races-following-module-load.patch
new file mode 100644 (file)
index 0000000..b515f0e
--- /dev/null
@@ -0,0 +1,491 @@
+From be5e65338a564a1cb149ff10be808b2103c1df9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jan 2022 20:28:45 -0500
+Subject: scsi: scsi_debug: Address races following module load
+
+From: Douglas Gilbert <dgilbert@interlog.com>
+
+[ Upstream commit 2aad3cd8537033cd34f70294a23f54623ffe9c1b ]
+
+When scsi_debug is loaded as a module with many (simulated) hosts, targets,
+and devices (LUs), modprobe can take a long time to return.  Only a small
+amount of this time is spent in the scsi_debug_init(); the rest is other
+parts of the kernel reacting to to the appearance of new storage
+devices. As soon as scsi_debug_init() has completed the user space may call
+'rmmod scsi_debug' and this was found to cause race problems as outlined
+here:
+
+    https://bugzilla.kernel.org/show_bug.cgi?id=212337
+
+To reliably generate this race a sysfs parameter called rm_all_hosts was
+added and the code was strengthened in this area. The main change was to
+make the count of scsi_debug hosts present an atomic.  Then it was found
+that the handling of the existing add_host parameter needed the same
+strengthening. Further: 'echo -9999 >
+/sys/bus/pseudo/drivers/scsi_debug/add_host has the same effect as
+rm_all_hosts so rm_all_hosts was not needed.
+
+To inhibit a race between two invocations of writes to add_host, a mutex
+was added. Also address a possible race when rmmod is called but LUs are
+still being added.
+
+The logic to remove (all) hosts is rather crude: it works backwards down a
+linked lists of hosts. Any pending requests are terminated with
+DID_NO_CONNECT as are any new requests. In the case where not all hosts are
+being removed, the ones that remain may have lost requests as just
+outlined. The lowest numbered host (id) hosts will remain.
+
+Cc: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20220109012853.301953-2-dgilbert@interlog.com
+Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_debug.c | 197 ++++++++++++++++++++++++++++----------
+ 1 file changed, 146 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 2104973a35cd..24f3905f054f 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -33,6 +33,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/crc-t10dif.h>
+ #include <linux/spinlock.h>
++#include <linux/mutex.h>
+ #include <linux/interrupt.h>
+ #include <linux/atomic.h>
+ #include <linux/hrtimer.h>
+@@ -730,7 +731,9 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEM_P1 + 1] = {
+           {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+ };
+-static int sdebug_num_hosts;
++static atomic_t sdebug_num_hosts;
++static DEFINE_MUTEX(add_host_mutex);
++
+ static int sdebug_add_host = DEF_NUM_HOST;  /* in sysfs this is relative */
+ static int sdebug_ato = DEF_ATO;
+ static int sdebug_cdb_len = DEF_CDB_LEN;
+@@ -777,6 +780,7 @@ static int sdebug_uuid_ctl = DEF_UUID_CTL;
+ static bool sdebug_random = DEF_RANDOM;
+ static bool sdebug_per_host_store = DEF_PER_HOST_STORE;
+ static bool sdebug_removable = DEF_REMOVABLE;
++static bool sdebug_deflect_incoming;
+ static bool sdebug_clustering;
+ static bool sdebug_host_lock = DEF_HOST_LOCK;
+ static bool sdebug_strict = DEF_STRICT;
+@@ -5026,6 +5030,10 @@ static int scsi_debug_slave_configure(struct scsi_device *sdp)
+                      sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+       if (sdp->host->max_cmd_len != SDEBUG_MAX_CMD_LEN)
+               sdp->host->max_cmd_len = SDEBUG_MAX_CMD_LEN;
++      if (smp_load_acquire(&sdebug_deflect_incoming)) {
++              pr_info("Exit early due to deflect_incoming\n");
++              return 1;
++      }
+       if (devip == NULL) {
+               devip = find_build_dev_info(sdp);
+               if (devip == NULL)
+@@ -5111,7 +5119,7 @@ static bool stop_queued_cmnd(struct scsi_cmnd *cmnd)
+ }
+ /* Deletes (stops) timers or work queues of all queued commands */
+-static void stop_all_queued(void)
++static void stop_all_queued(bool done_with_no_conn)
+ {
+       unsigned long iflags;
+       int j, k;
+@@ -5120,13 +5128,15 @@ static void stop_all_queued(void)
+       struct sdebug_queued_cmd *sqcp;
+       struct sdebug_dev_info *devip;
+       struct sdebug_defer *sd_dp;
++      struct scsi_cmnd *scp;
+       for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) {
+               spin_lock_irqsave(&sqp->qc_lock, iflags);
+               for (k = 0; k < SDEBUG_CANQUEUE; ++k) {
+                       if (test_bit(k, sqp->in_use_bm)) {
+                               sqcp = &sqp->qc_arr[k];
+-                              if (sqcp->a_cmnd == NULL)
++                              scp = sqcp->a_cmnd;
++                              if (!scp)
+                                       continue;
+                               devip = (struct sdebug_dev_info *)
+                                       sqcp->a_cmnd->device->hostdata;
+@@ -5141,6 +5151,10 @@ static void stop_all_queued(void)
+                                       l_defer_t = SDEB_DEFER_NONE;
+                               spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+                               stop_qc_helper(sd_dp, l_defer_t);
++                              if (done_with_no_conn && l_defer_t != SDEB_DEFER_NONE) {
++                                      scp->result = DID_NO_CONNECT << 16;
++                                      scsi_done(scp);
++                              }
+                               clear_bit(k, sqp->in_use_bm);
+                               spin_lock_irqsave(&sqp->qc_lock, iflags);
+                       }
+@@ -5283,7 +5297,7 @@ static int scsi_debug_host_reset(struct scsi_cmnd *SCpnt)
+               }
+       }
+       spin_unlock(&sdebug_host_list_lock);
+-      stop_all_queued();
++      stop_all_queued(false);
+       if (SDEBUG_OPT_RESET_NOISE & sdebug_opts)
+               sdev_printk(KERN_INFO, SCpnt->device,
+                           "%s: %d device(s) found\n", __func__, k);
+@@ -5343,13 +5357,50 @@ static void sdebug_build_parts(unsigned char *ramp, unsigned long store_size)
+       }
+ }
+-static void block_unblock_all_queues(bool block)
++static void sdeb_block_all_queues(void)
++{
++      int j;
++      struct sdebug_queue *sqp;
++
++      for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp)
++              atomic_set(&sqp->blocked, (int)true);
++}
++
++static void sdeb_unblock_all_queues(void)
+ {
+       int j;
+       struct sdebug_queue *sqp;
+       for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp)
+-              atomic_set(&sqp->blocked, (int)block);
++              atomic_set(&sqp->blocked, (int)false);
++}
++
++static void
++sdeb_add_n_hosts(int num_hosts)
++{
++      if (num_hosts < 1)
++              return;
++      do {
++              bool found;
++              unsigned long idx;
++              struct sdeb_store_info *sip;
++              bool want_phs = (sdebug_fake_rw == 0) && sdebug_per_host_store;
++
++              found = false;
++              if (want_phs) {
++                      xa_for_each_marked(per_store_ap, idx, sip, SDEB_XA_NOT_IN_USE) {
++                              sdeb_most_recent_idx = (int)idx;
++                              found = true;
++                              break;
++                      }
++                      if (found)      /* re-use case */
++                              sdebug_add_host_helper((int)idx);
++                      else
++                              sdebug_do_add_host(true /* make new store */);
++              } else {
++                      sdebug_do_add_host(false);
++              }
++      } while (--num_hosts);
+ }
+ /* Adjust (by rounding down) the sdebug_cmnd_count so abs(every_nth)-1
+@@ -5362,10 +5413,10 @@ static void tweak_cmnd_count(void)
+       modulo = abs(sdebug_every_nth);
+       if (modulo < 2)
+               return;
+-      block_unblock_all_queues(true);
++      sdeb_block_all_queues();
+       count = atomic_read(&sdebug_cmnd_count);
+       atomic_set(&sdebug_cmnd_count, (count / modulo) * modulo);
+-      block_unblock_all_queues(false);
++      sdeb_unblock_all_queues();
+ }
+ static void clear_queue_stats(void)
+@@ -5383,6 +5434,15 @@ static bool inject_on_this_cmd(void)
+       return (atomic_read(&sdebug_cmnd_count) % abs(sdebug_every_nth)) == 0;
+ }
++static int process_deflect_incoming(struct scsi_cmnd *scp)
++{
++      u8 opcode = scp->cmnd[0];
++
++      if (opcode == SYNCHRONIZE_CACHE || opcode == SYNCHRONIZE_CACHE_16)
++              return 0;
++      return DID_NO_CONNECT << 16;
++}
++
+ #define INCLUSIVE_TIMING_MAX_NS 1000000               /* 1 millisecond */
+ /* Complete the processing of the thread that queued a SCSI command to this
+@@ -5392,8 +5452,7 @@ static bool inject_on_this_cmd(void)
+  */
+ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
+                        int scsi_result,
+-                       int (*pfp)(struct scsi_cmnd *,
+-                                  struct sdebug_dev_info *),
++                       int (*pfp)(struct scsi_cmnd *, struct sdebug_dev_info *),
+                        int delta_jiff, int ndelay)
+ {
+       bool new_sd_dp;
+@@ -5414,13 +5473,27 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
+       }
+       sdp = cmnd->device;
+-      if (delta_jiff == 0)
++      if (delta_jiff == 0) {
++              sqp = get_queue(cmnd);
++              if (atomic_read(&sqp->blocked)) {
++                      if (smp_load_acquire(&sdebug_deflect_incoming))
++                              return process_deflect_incoming(cmnd);
++                      else
++                              return SCSI_MLQUEUE_HOST_BUSY;
++              }
+               goto respond_in_thread;
++      }
+       sqp = get_queue(cmnd);
+       spin_lock_irqsave(&sqp->qc_lock, iflags);
+       if (unlikely(atomic_read(&sqp->blocked))) {
+               spin_unlock_irqrestore(&sqp->qc_lock, iflags);
++              if (smp_load_acquire(&sdebug_deflect_incoming)) {
++                      scsi_result = process_deflect_incoming(cmnd);
++                      goto respond_in_thread;
++              }
++              if (sdebug_verbose)
++                      pr_info("blocked --> SCSI_MLQUEUE_HOST_BUSY\n");
+               return SCSI_MLQUEUE_HOST_BUSY;
+       }
+       num_in_q = atomic_read(&devip->num_in_q);
+@@ -5616,8 +5689,12 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
+ respond_in_thread:    /* call back to mid-layer using invocation thread */
+       cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0;
+       cmnd->result &= ~SDEG_RES_IMMED_MASK;
+-      if (cmnd->result == 0 && scsi_result != 0)
++      if (cmnd->result == 0 && scsi_result != 0) {
+               cmnd->result = scsi_result;
++              if (sdebug_verbose)
++                      pr_info("respond_in_thread: tag=0x%x, scp->result=0x%x\n",
++                              blk_mq_unique_tag(scsi_cmd_to_rq(cmnd)), scsi_result);
++      }
+       scsi_done(cmnd);
+       return 0;
+ }
+@@ -5900,7 +5977,7 @@ static ssize_t delay_store(struct device_driver *ddp, const char *buf,
+                       int j, k;
+                       struct sdebug_queue *sqp;
+-                      block_unblock_all_queues(true);
++                      sdeb_block_all_queues();
+                       for (j = 0, sqp = sdebug_q_arr; j < submit_queues;
+                            ++j, ++sqp) {
+                               k = find_first_bit(sqp->in_use_bm,
+@@ -5914,7 +5991,7 @@ static ssize_t delay_store(struct device_driver *ddp, const char *buf,
+                               sdebug_jdelay = jdelay;
+                               sdebug_ndelay = 0;
+                       }
+-                      block_unblock_all_queues(false);
++                      sdeb_unblock_all_queues();
+               }
+               return res;
+       }
+@@ -5940,7 +6017,7 @@ static ssize_t ndelay_store(struct device_driver *ddp, const char *buf,
+                       int j, k;
+                       struct sdebug_queue *sqp;
+-                      block_unblock_all_queues(true);
++                      sdeb_block_all_queues();
+                       for (j = 0, sqp = sdebug_q_arr; j < submit_queues;
+                            ++j, ++sqp) {
+                               k = find_first_bit(sqp->in_use_bm,
+@@ -5955,7 +6032,7 @@ static ssize_t ndelay_store(struct device_driver *ddp, const char *buf,
+                               sdebug_jdelay = ndelay  ? JDELAY_OVERRIDDEN
+                                                       : DEF_JDELAY;
+                       }
+-                      block_unblock_all_queues(false);
++                      sdeb_unblock_all_queues();
+               }
+               return res;
+       }
+@@ -6269,7 +6346,7 @@ static ssize_t max_queue_store(struct device_driver *ddp, const char *buf,
+       if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n > 0) &&
+           (n <= SDEBUG_CANQUEUE) &&
+           (sdebug_host_max_queue == 0)) {
+-              block_unblock_all_queues(true);
++              sdeb_block_all_queues();
+               k = 0;
+               for (j = 0, sqp = sdebug_q_arr; j < submit_queues;
+                    ++j, ++sqp) {
+@@ -6284,7 +6361,7 @@ static ssize_t max_queue_store(struct device_driver *ddp, const char *buf,
+                       atomic_set(&retired_max_queue, k + 1);
+               else
+                       atomic_set(&retired_max_queue, 0);
+-              block_unblock_all_queues(false);
++              sdeb_unblock_all_queues();
+               return count;
+       }
+       return -EINVAL;
+@@ -6356,43 +6433,48 @@ static DRIVER_ATTR_RW(virtual_gb);
+ static ssize_t add_host_show(struct device_driver *ddp, char *buf)
+ {
+       /* absolute number of hosts currently active is what is shown */
+-      return scnprintf(buf, PAGE_SIZE, "%d\n", sdebug_num_hosts);
++      return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&sdebug_num_hosts));
+ }
++/*
++ * Accept positive and negative values. Hex values (only positive) may be prefixed by '0x'.
++ * To remove all hosts use a large negative number (e.g. -9999). The value 0 does nothing.
++ * Returns -EBUSY if another add_host sysfs invocation is active.
++ */
+ static ssize_t add_host_store(struct device_driver *ddp, const char *buf,
+                             size_t count)
+ {
+-      bool found;
+-      unsigned long idx;
+-      struct sdeb_store_info *sip;
+-      bool want_phs = (sdebug_fake_rw == 0) && sdebug_per_host_store;
+       int delta_hosts;
+-      if (sscanf(buf, "%d", &delta_hosts) != 1)
++      if (count == 0 || kstrtoint(buf, 0, &delta_hosts))
+               return -EINVAL;
++      if (sdebug_verbose)
++              pr_info("prior num_hosts=%d, num_to_add=%d\n",
++                      atomic_read(&sdebug_num_hosts), delta_hosts);
++      if (delta_hosts == 0)
++              return count;
++      if (mutex_trylock(&add_host_mutex) == 0)
++              return -EBUSY;
+       if (delta_hosts > 0) {
+-              do {
+-                      found = false;
+-                      if (want_phs) {
+-                              xa_for_each_marked(per_store_ap, idx, sip,
+-                                                 SDEB_XA_NOT_IN_USE) {
+-                                      sdeb_most_recent_idx = (int)idx;
+-                                      found = true;
+-                                      break;
+-                              }
+-                              if (found)      /* re-use case */
+-                                      sdebug_add_host_helper((int)idx);
+-                              else
+-                                      sdebug_do_add_host(true);
+-                      } else {
+-                              sdebug_do_add_host(false);
+-                      }
+-              } while (--delta_hosts);
++              sdeb_add_n_hosts(delta_hosts);
+       } else if (delta_hosts < 0) {
++              smp_store_release(&sdebug_deflect_incoming, true);
++              sdeb_block_all_queues();
++              if (delta_hosts >= atomic_read(&sdebug_num_hosts))
++                      stop_all_queued(true);
+               do {
++                      if (atomic_read(&sdebug_num_hosts) < 1) {
++                              free_all_queued();
++                              break;
++                      }
+                       sdebug_do_remove_host(false);
+               } while (++delta_hosts);
++              sdeb_unblock_all_queues();
++              smp_store_release(&sdebug_deflect_incoming, false);
+       }
++      mutex_unlock(&add_host_mutex);
++      if (sdebug_verbose)
++              pr_info("post num_hosts=%d\n", atomic_read(&sdebug_num_hosts));
+       return count;
+ }
+ static DRIVER_ATTR_RW(add_host);
+@@ -6902,6 +6984,10 @@ static int __init scsi_debug_init(void)
+       sdebug_add_host = 0;
+       for (k = 0; k < hosts_to_add; k++) {
++              if (smp_load_acquire(&sdebug_deflect_incoming)) {
++                      pr_info("exit early as sdebug_deflect_incoming is set\n");
++                      return 0;
++              }
+               if (want_store && k == 0) {
+                       ret = sdebug_add_host_helper(idx);
+                       if (ret < 0) {
+@@ -6919,8 +7005,12 @@ static int __init scsi_debug_init(void)
+               }
+       }
+       if (sdebug_verbose)
+-              pr_info("built %d host(s)\n", sdebug_num_hosts);
++              pr_info("built %d host(s)\n", atomic_read(&sdebug_num_hosts));
++      /*
++       * Even though all the hosts have been established, due to async device (LU) scanning
++       * by the scsi mid-level, there may still be devices (LUs) being set up.
++       */
+       return 0;
+ bus_unreg:
+@@ -6936,12 +7026,17 @@ static int __init scsi_debug_init(void)
+ static void __exit scsi_debug_exit(void)
+ {
+-      int k = sdebug_num_hosts;
++      int k;
+-      stop_all_queued();
+-      for (; k; k--)
++      /* Possible race with LUs still being set up; stop them asap */
++      sdeb_block_all_queues();
++      smp_store_release(&sdebug_deflect_incoming, true);
++      stop_all_queued(false);
++      for (k = 0; atomic_read(&sdebug_num_hosts) > 0; k++)
+               sdebug_do_remove_host(true);
+       free_all_queued();
++      if (sdebug_verbose)
++              pr_info("removed %d hosts\n", k);
+       driver_unregister(&sdebug_driverfs_driver);
+       bus_unregister(&pseudo_lld_bus);
+       root_device_unregister(pseudo_primary);
+@@ -7111,13 +7206,13 @@ static int sdebug_add_host_helper(int per_host_idx)
+       sdbg_host->dev.bus = &pseudo_lld_bus;
+       sdbg_host->dev.parent = pseudo_primary;
+       sdbg_host->dev.release = &sdebug_release_adapter;
+-      dev_set_name(&sdbg_host->dev, "adapter%d", sdebug_num_hosts);
++      dev_set_name(&sdbg_host->dev, "adapter%d", atomic_read(&sdebug_num_hosts));
+       error = device_register(&sdbg_host->dev);
+       if (error)
+               goto clean;
+-      ++sdebug_num_hosts;
++      atomic_inc(&sdebug_num_hosts);
+       return 0;
+ clean:
+@@ -7181,7 +7276,7 @@ static void sdebug_do_remove_host(bool the_end)
+               return;
+       device_unregister(&sdbg_host->dev);
+-      --sdebug_num_hosts;
++      atomic_dec(&sdebug_num_hosts);
+ }
+ static int sdebug_change_qdepth(struct scsi_device *sdev, int qdepth)
+@@ -7189,10 +7284,10 @@ static int sdebug_change_qdepth(struct scsi_device *sdev, int qdepth)
+       int num_in_q = 0;
+       struct sdebug_dev_info *devip;
+-      block_unblock_all_queues(true);
++      sdeb_block_all_queues();
+       devip = (struct sdebug_dev_info *)sdev->hostdata;
+       if (NULL == devip) {
+-              block_unblock_all_queues(false);
++              sdeb_unblock_all_queues();
+               return  -ENODEV;
+       }
+       num_in_q = atomic_read(&devip->num_in_q);
+@@ -7211,7 +7306,7 @@ static int sdebug_change_qdepth(struct scsi_device *sdev, int qdepth)
+               sdev_printk(KERN_INFO, sdev, "%s: qdepth=%d, num_in_q=%d\n",
+                           __func__, qdepth, num_in_q);
+       }
+-      block_unblock_all_queues(false);
++      sdeb_unblock_all_queues();
+       return sdev->queue_depth;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-smartpqi-fix-kdump-issue-when-controller-is-loc.patch b/queue-5.17/scsi-smartpqi-fix-kdump-issue-when-controller-is-loc.patch
new file mode 100644 (file)
index 0000000..6460290
--- /dev/null
@@ -0,0 +1,100 @@
+From c419777b2f728d092829f71660e22bac7b03160d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Feb 2022 15:48:43 -0600
+Subject: scsi: smartpqi: Fix kdump issue when controller is locked up
+
+From: Mahesh Rajashekhara <mahesh.rajashekhara@microchip.com>
+
+[ Upstream commit 3ada501d602abf02353445c03bb3258146445d90 ]
+
+Avoid dropping into shell if the controller is in locked up state.
+
+Driver issues SIS soft reset to bring back the controller to SIS mode while
+OS boots into kdump mode.
+
+If the controller is in lockup state, SIS soft reset does not work.
+
+Since the controller lockup code has not been cleared, driver considers the
+firmware is no longer up and running. Driver returns back an error code to
+OS and the kdump fails.
+
+Link: https://lore.kernel.org/r/164375212337.440833.11955356190354940369.stgit@brunhilda.pdev.net
+Reviewed-by: Kevin Barnett <kevin.barnett@microchip.com>
+Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
+Reviewed-by: Scott Teel <scott.teel@microchip.com>
+Signed-off-by: Mahesh Rajashekhara <mahesh.rajashekhara@microchip.com>
+Signed-off-by: Don Brace <don.brace@microchip.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 39 ++++++++++++++++-----------
+ 1 file changed, 23 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 2db9f874cc51..f3749e508673 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -7855,6 +7855,21 @@ static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info)
+       return pqi_revert_to_sis_mode(ctrl_info);
+ }
++static void pqi_perform_lockup_action(void)
++{
++      switch (pqi_lockup_action) {
++      case PANIC:
++              panic("FATAL: Smart Family Controller lockup detected");
++              break;
++      case REBOOT:
++              emergency_restart();
++              break;
++      case NONE:
++      default:
++              break;
++      }
++}
++
+ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
+ {
+       int rc;
+@@ -7879,8 +7894,15 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
+        * commands.
+        */
+       rc = sis_wait_for_ctrl_ready(ctrl_info);
+-      if (rc)
++      if (rc) {
++              if (reset_devices) {
++                      dev_err(&ctrl_info->pci_dev->dev,
++                              "kdump init failed with error %d\n", rc);
++                      pqi_lockup_action = REBOOT;
++                      pqi_perform_lockup_action();
++              }
+               return rc;
++      }
+       /*
+        * Get the controller properties.  This allows us to determine
+@@ -8605,21 +8627,6 @@ static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info, unsigned int de
+       return pqi_ctrl_init_resume(ctrl_info);
+ }
+-static void pqi_perform_lockup_action(void)
+-{
+-      switch (pqi_lockup_action) {
+-      case PANIC:
+-              panic("FATAL: Smart Family Controller lockup detected");
+-              break;
+-      case REBOOT:
+-              emergency_restart();
+-              break;
+-      case NONE:
+-      default:
+-              break;
+-      }
+-}
+-
+ static struct pqi_raid_error_info pqi_ctrl_offline_raid_error_info = {
+       .data_out_result = PQI_DATA_IN_OUT_HARDWARE_ERROR,
+       .status = SAM_STAT_CHECK_CONDITION,
+-- 
+2.35.1
+
diff --git a/queue-5.17/scsi-smartpqi-fix-rmmod-stack-trace.patch b/queue-5.17/scsi-smartpqi-fix-rmmod-stack-trace.patch
new file mode 100644 (file)
index 0000000..8ab510c
--- /dev/null
@@ -0,0 +1,51 @@
+From a295e94e2603cfd31a5a9b495e868475a47bbd13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Feb 2022 15:47:53 -0600
+Subject: scsi: smartpqi: Fix rmmod stack trace
+
+From: Don Brace <don.brace@microchip.com>
+
+[ Upstream commit c4ff687d25c05919382a759503bd3821689f4e2f ]
+
+Prevent "BUG: scheduling while atomic: rmmod" stack trace.
+
+Stop setting spin_locks before calling OS functions to remove devices.
+
+Link: https://lore.kernel.org/r/164375207296.440833.4996145011193819683.stgit@brunhilda.pdev.net
+Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
+Reviewed-by: Scott Teel <scott.teel@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 | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index f0897d587454..2db9f874cc51 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -2513,17 +2513,15 @@ static void pqi_remove_all_scsi_devices(struct pqi_ctrl_info *ctrl_info)
+       struct pqi_scsi_dev *device;
+       struct pqi_scsi_dev *next;
+-      spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+-
+       list_for_each_entry_safe(device, next, &ctrl_info->scsi_device_list,
+               scsi_device_list_entry) {
+               if (pqi_is_device_added(device))
+                       pqi_remove_device(ctrl_info, device);
++              spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+               list_del(&device->scsi_device_list_entry);
+               pqi_free_device(device);
++              spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+       }
+-
+-      spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+ }
+ static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info)
+-- 
+2.35.1
+
diff --git a/queue-5.17/selftests-net-add-tls-config-dependency-for-tls-self.patch b/queue-5.17/selftests-net-add-tls-config-dependency-for-tls-self.patch
new file mode 100644 (file)
index 0000000..a7ad378
--- /dev/null
@@ -0,0 +1,35 @@
+From 95fff4a9e0444c5b5dcdb82b2559bc94d031494c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Mar 2022 19:16:50 +0530
+Subject: selftests: net: Add tls config dependency for tls selftests
+
+From: Naresh Kamboju <naresh.kamboju@linaro.org>
+
+[ Upstream commit d9142e1cf3bbdaf21337767114ecab26fe702d47 ]
+
+selftest net tls test cases need TLS=m without this the test hangs.
+Enabling config TLS solves this problem and runs to complete.
+  - CONFIG_TLS=m
+
+Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Signed-off-by: Naresh Kamboju <naresh.kamboju@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/config | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config
+index ead7963b9bf0..cecb921a0dbf 100644
+--- a/tools/testing/selftests/net/config
++++ b/tools/testing/selftests/net/config
+@@ -43,5 +43,6 @@ CONFIG_NET_ACT_TUNNEL_KEY=m
+ CONFIG_NET_ACT_MIRRED=m
+ CONFIG_BAREUDP=m
+ CONFIG_IPV6_IOAM6_LWTUNNEL=y
++CONFIG_TLS=m
+ CONFIG_CRYPTO_SM4=y
+ CONFIG_AMT=m
+-- 
+2.35.1
+
diff --git a/queue-5.17/selftests-xsk-fix-bpf_res-cleanup-test.patch b/queue-5.17/selftests-xsk-fix-bpf_res-cleanup-test.patch
new file mode 100644 (file)
index 0000000..45e5df0
--- /dev/null
@@ -0,0 +1,225 @@
+From 89a9845dd09d77f7c88add4f5ae53ddc68a20d24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 09:29:45 +0100
+Subject: selftests, xsk: Fix bpf_res cleanup test
+
+From: Magnus Karlsson <magnus.karlsson@intel.com>
+
+[ Upstream commit 3b22523bca02b0d5618c08b93d8fd1fb578e1cc3 ]
+
+After commit 710ad98c363a ("veth: Do not record rx queue hint in veth_xmit"),
+veth no longer receives traffic on the same queue as it was sent on. This
+breaks the bpf_res test for the AF_XDP selftests as the socket tied to
+queue 1 will not receive traffic anymore.
+
+Modify the test so that two sockets are tied to queue id 0 using a shared
+umem instead. When killing the first socket enter the second socket into
+the xskmap so that traffic will flow to it. This will still test that the
+resources are not cleaned up until after the second socket dies, without
+having to rely on veth supporting rx_queue hints.
+
+Reported-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20220125082945.26179-1-magnus.karlsson@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/xdpxceiver.c | 80 +++++++++++++++---------
+ tools/testing/selftests/bpf/xdpxceiver.h |  2 +-
+ 2 files changed, 50 insertions(+), 32 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c
+index ffa5502ad95e..5f8296d29e77 100644
+--- a/tools/testing/selftests/bpf/xdpxceiver.c
++++ b/tools/testing/selftests/bpf/xdpxceiver.c
+@@ -266,22 +266,24 @@ static int xsk_configure_umem(struct xsk_umem_info *umem, void *buffer, u64 size
+ }
+ static int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_info *umem,
+-                              struct ifobject *ifobject, u32 qid)
++                              struct ifobject *ifobject, bool shared)
+ {
+-      struct xsk_socket_config cfg;
++      struct xsk_socket_config cfg = {};
+       struct xsk_ring_cons *rxr;
+       struct xsk_ring_prod *txr;
+       xsk->umem = umem;
+       cfg.rx_size = xsk->rxqsize;
+       cfg.tx_size = XSK_RING_PROD__DEFAULT_NUM_DESCS;
+-      cfg.libbpf_flags = 0;
++      cfg.libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD;
+       cfg.xdp_flags = ifobject->xdp_flags;
+       cfg.bind_flags = ifobject->bind_flags;
++      if (shared)
++              cfg.bind_flags |= XDP_SHARED_UMEM;
+       txr = ifobject->tx_on ? &xsk->tx : NULL;
+       rxr = ifobject->rx_on ? &xsk->rx : NULL;
+-      return xsk_socket__create(&xsk->xsk, ifobject->ifname, qid, umem->umem, rxr, txr, &cfg);
++      return xsk_socket__create(&xsk->xsk, ifobject->ifname, 0, umem->umem, rxr, txr, &cfg);
+ }
+ static struct option long_options[] = {
+@@ -387,7 +389,6 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
+       for (i = 0; i < MAX_INTERFACES; i++) {
+               struct ifobject *ifobj = i ? ifobj_rx : ifobj_tx;
+-              ifobj->umem = &ifobj->umem_arr[0];
+               ifobj->xsk = &ifobj->xsk_arr[0];
+               ifobj->use_poll = false;
+               ifobj->pacing_on = true;
+@@ -401,11 +402,12 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
+                       ifobj->tx_on = false;
+               }
++              memset(ifobj->umem, 0, sizeof(*ifobj->umem));
++              ifobj->umem->num_frames = DEFAULT_UMEM_BUFFERS;
++              ifobj->umem->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
++
+               for (j = 0; j < MAX_SOCKETS; j++) {
+-                      memset(&ifobj->umem_arr[j], 0, sizeof(ifobj->umem_arr[j]));
+                       memset(&ifobj->xsk_arr[j], 0, sizeof(ifobj->xsk_arr[j]));
+-                      ifobj->umem_arr[j].num_frames = DEFAULT_UMEM_BUFFERS;
+-                      ifobj->umem_arr[j].frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
+                       ifobj->xsk_arr[j].rxqsize = XSK_RING_CONS__DEFAULT_NUM_DESCS;
+               }
+       }
+@@ -950,7 +952,10 @@ static void tx_stats_validate(struct ifobject *ifobject)
+ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
+ {
++      u64 umem_sz = ifobject->umem->num_frames * ifobject->umem->frame_size;
+       int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
++      int ret, ifindex;
++      void *bufs;
+       u32 i;
+       ifobject->ns_fd = switch_namespace(ifobject->nsname);
+@@ -958,23 +963,20 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
+       if (ifobject->umem->unaligned_mode)
+               mmap_flags |= MAP_HUGETLB;
+-      for (i = 0; i < test->nb_sockets; i++) {
+-              u64 umem_sz = ifobject->umem->num_frames * ifobject->umem->frame_size;
+-              u32 ctr = 0;
+-              void *bufs;
+-              int ret;
++      bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
++      if (bufs == MAP_FAILED)
++              exit_with_error(errno);
+-              bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
+-              if (bufs == MAP_FAILED)
+-                      exit_with_error(errno);
++      ret = xsk_configure_umem(ifobject->umem, bufs, umem_sz);
++      if (ret)
++              exit_with_error(-ret);
+-              ret = xsk_configure_umem(&ifobject->umem_arr[i], bufs, umem_sz);
+-              if (ret)
+-                      exit_with_error(-ret);
++      for (i = 0; i < test->nb_sockets; i++) {
++              u32 ctr = 0;
+               while (ctr++ < SOCK_RECONF_CTR) {
+-                      ret = xsk_configure_socket(&ifobject->xsk_arr[i], &ifobject->umem_arr[i],
+-                                                 ifobject, i);
++                      ret = xsk_configure_socket(&ifobject->xsk_arr[i], ifobject->umem,
++                                                 ifobject, !!i);
+                       if (!ret)
+                               break;
+@@ -985,8 +987,22 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
+               }
+       }
+-      ifobject->umem = &ifobject->umem_arr[0];
+       ifobject->xsk = &ifobject->xsk_arr[0];
++
++      if (!ifobject->rx_on)
++              return;
++
++      ifindex = if_nametoindex(ifobject->ifname);
++      if (!ifindex)
++              exit_with_error(errno);
++
++      ret = xsk_setup_xdp_prog(ifindex, &ifobject->xsk_map_fd);
++      if (ret)
++              exit_with_error(-ret);
++
++      ret = xsk_socket__update_xskmap(ifobject->xsk->xsk, ifobject->xsk_map_fd);
++      if (ret)
++              exit_with_error(-ret);
+ }
+ static void testapp_cleanup_xsk_res(struct ifobject *ifobj)
+@@ -1142,14 +1158,16 @@ static void testapp_bidi(struct test_spec *test)
+ static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj_rx)
+ {
++      int ret;
++
+       xsk_socket__delete(ifobj_tx->xsk->xsk);
+-      xsk_umem__delete(ifobj_tx->umem->umem);
+       xsk_socket__delete(ifobj_rx->xsk->xsk);
+-      xsk_umem__delete(ifobj_rx->umem->umem);
+-      ifobj_tx->umem = &ifobj_tx->umem_arr[1];
+       ifobj_tx->xsk = &ifobj_tx->xsk_arr[1];
+-      ifobj_rx->umem = &ifobj_rx->umem_arr[1];
+       ifobj_rx->xsk = &ifobj_rx->xsk_arr[1];
++
++      ret = xsk_socket__update_xskmap(ifobj_rx->xsk->xsk, ifobj_rx->xsk_map_fd);
++      if (ret)
++              exit_with_error(-ret);
+ }
+ static void testapp_bpf_res(struct test_spec *test)
+@@ -1408,13 +1426,13 @@ static struct ifobject *ifobject_create(void)
+       if (!ifobj->xsk_arr)
+               goto out_xsk_arr;
+-      ifobj->umem_arr = calloc(MAX_SOCKETS, sizeof(*ifobj->umem_arr));
+-      if (!ifobj->umem_arr)
+-              goto out_umem_arr;
++      ifobj->umem = calloc(1, sizeof(*ifobj->umem));
++      if (!ifobj->umem)
++              goto out_umem;
+       return ifobj;
+-out_umem_arr:
++out_umem:
+       free(ifobj->xsk_arr);
+ out_xsk_arr:
+       free(ifobj);
+@@ -1423,7 +1441,7 @@ static struct ifobject *ifobject_create(void)
+ static void ifobject_delete(struct ifobject *ifobj)
+ {
+-      free(ifobj->umem_arr);
++      free(ifobj->umem);
+       free(ifobj->xsk_arr);
+       free(ifobj);
+ }
+diff --git a/tools/testing/selftests/bpf/xdpxceiver.h b/tools/testing/selftests/bpf/xdpxceiver.h
+index 2f705f44b748..62a3e6388632 100644
+--- a/tools/testing/selftests/bpf/xdpxceiver.h
++++ b/tools/testing/selftests/bpf/xdpxceiver.h
+@@ -125,10 +125,10 @@ struct ifobject {
+       struct xsk_socket_info *xsk;
+       struct xsk_socket_info *xsk_arr;
+       struct xsk_umem_info *umem;
+-      struct xsk_umem_info *umem_arr;
+       thread_func_t func_ptr;
+       struct pkt_stream *pkt_stream;
+       int ns_fd;
++      int xsk_map_fd;
+       u32 dst_ip;
+       u32 src_ip;
+       u32 xdp_flags;
+-- 
+2.35.1
+
diff --git a/queue-5.17/serial-samsung_tty-do-not-unlock-port-lock-for-uart_.patch b/queue-5.17/serial-samsung_tty-do-not-unlock-port-lock-for-uart_.patch
new file mode 100644 (file)
index 0000000..a1cd92a
--- /dev/null
@@ -0,0 +1,53 @@
+From b5ebcac6bb2edc15e6a35f25878c99c3e6b26404 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Mar 2022 12:51:53 +0100
+Subject: serial: samsung_tty: do not unlock port->lock for uart_write_wakeup()
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+[ Upstream commit 988c7c00691008ea1daaa1235680a0da49dab4e8 ]
+
+The commit c15c3747ee32 (serial: samsung: fix potential soft lockup
+during uart write) added an unlock of port->lock before
+uart_write_wakeup() and a lock after it. It was always problematic to
+write data from tty_ldisc_ops::write_wakeup and it was even documented
+that way. We fixed the line disciplines to conform to this recently.
+So if there is still a missed one, we should fix them instead of this
+workaround.
+
+On the top of that, s3c24xx_serial_tx_dma_complete() in this driver
+still holds the port->lock while calling uart_write_wakeup().
+
+So revert the wrap added by the commit above.
+
+Cc: Thomas Abraham <thomas.abraham@linaro.org>
+Cc: Kyungmin Park <kyungmin.park@samsung.com>
+Cc: Hyeonkook Kim <hk619.kim@samsung.com>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20220308115153.4225-1-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/samsung_tty.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
+index d002a4e48ed9..0d94a7cb275e 100644
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -921,11 +921,8 @@ static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
+               return;
+       }
+-      if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
+-              spin_unlock(&port->lock);
++      if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+-              spin_lock(&port->lock);
+-      }
+       if (uart_circ_empty(xmit))
+               s3c24xx_serial_stop_tx(port);
+-- 
+2.35.1
+
diff --git a/queue-5.17/series b/queue-5.17/series
new file mode 100644 (file)
index 0000000..ccd82ca
--- /dev/null
@@ -0,0 +1,193 @@
+lib-logic_iomem-correct-fallback-config-references.patch
+um-fix-and-optimize-xor-select-template-for-config64.patch
+rtc-wm8350-handle-error-for-wm8350_register_irq.patch
+net-dsa-felix-fix-possible-null-pointer-dereference.patch
+mm-kfence-fix-objcgs-vector-allocation.patch
+kvm-x86-pmu-use-different-raw-event-masks-for-amd-an.patch
+kvm-svm-fix-kvm_cache_regs.h-inclusions-for-is_guest.patch
+kvm-x86-svm-clear-reserved-bits-written-to-perfevtse.patch
+kvm-x86-pmu-fix-and-isolate-tsx-specific-performance.patch
+kvm-x86-emulator-emulate-rdpid-only-if-it-is-enabled.patch
+drm-add-orientation-quirk-for-gpd-win-max.patch
+bluetooth-hci_sync-fix-compilation-warning.patch
+ath5k-fix-oob-in-ath5k_eeprom_read_pcal_info_5111.patch
+bluetooth-fix-null-ptr-deref-on-hci_sync_conn_comple.patch
+drm-amd-display-add-signal-type-check-when-verify-st.patch
+drm-amdkfd-enable-heavy-weight-tlb-flush-on-arcturus.patch
+drm-edid-remove-non_desktop-quirk-for-hpn-3515-and-l.patch
+drm-edid-improve-non-desktop-quirk-logging.patch
+bluetooth-hci_event-ignore-multiple-conn-complete-ev.patch
+scsi-scsi_debug-address-races-following-module-load.patch
+drm-amd-amdgpu-amdgpu_cs-fix-refcount-leak-of-a-dma_.patch
+drm-amd-display-fix-memory-leak.patch
+drm-amd-display-use-psr-version-selected-during-set_.patch
+usb-gadget-tegra-xudc-do-not-program-sparam.patch
+usb-gadget-tegra-xudc-fix-control-endpoint-s-definit.patch
+usb-cdnsp-fix-cdnsp_decode_trb-function-to-properly-.patch
+ptp-replace-snprintf-with-sysfs_emit.patch
+bluetooth-hci_sync-fix-queuing-commands-when-hci_unr.patch
+selftests-xsk-fix-bpf_res-cleanup-test.patch
+net-mlx5e-tc-hold-sample_attr-on-stack-instead-of-po.patch
+drm-amdkfd-don-t-take-process-mutex-for-svm-ioctls.patch
+drm-amdkfd-ensure-mm-remain-valid-in-svm-deferred_li.patch
+drm-amdkfd-svm-range-restore-work-deadlock-when-proc.patch
+drm-amdgpu-fix-an-error-message-in-rmmod.patch
+mlxsw-spectrum-guard-against-invalid-local-ports.patch
+rdma-rtrs-clt-do-stop-and-failover-outside-reconnect.patch
+powerpc-xive-export-xive-ipi-information-for-online-.patch
+powerpc-dts-t104xrdb-fix-phy-type-for-fman-4-5.patch
+ath11k-fix-kernel-panic-during-unload-load-ath11k-mo.patch
+ath11k-pci-fix-crash-on-suspend-if-board-file-is-not.patch
+ath11k-mhi-use-mhi_sync_power_up.patch
+net-smc-send-directly-when-tcp_cork-is-cleared.patch
+drm-bridge-add-missing-pm_runtime_put_sync.patch
+bpf-make-dst_port-field-in-struct-bpf_sock-16-bit-wi.patch
+scsi-mvsas-replace-snprintf-with-sysfs_emit.patch
+scsi-bfa-replace-snprintf-with-sysfs_emit.patch
+drm-v3d-fix-missing-unlock.patch
+power-supply-axp20x_battery-properly-report-current-.patch
+mt76-mt7921-fix-crash-when-startup-fails.patch
+mt76-dma-initialize-skip_unmap-in-mt76_dma_rx_fill.patch
+i40e-add-sending-commands-in-atomic-context.patch
+cfg80211-don-t-add-non-transmitted-bss-to-6ghz-scann.patch
+libbpf-fix-build-issue-with-llvm-readelf.patch
+ipv6-make-mc_forwarding-atomic.patch
+ref_tracker-implement-use-after-free-detection.patch
+net-initialize-init_net-earlier.patch
+powerpc-set-crashkernel-offset-to-mid-of-rma-region.patch
+drm-amdgpu-fix-recursive-locking-warning.patch
+scsi-smartpqi-fix-rmmod-stack-trace.patch
+scsi-smartpqi-fix-kdump-issue-when-controller-is-loc.patch
+pci-aardvark-fix-support-for-msi-interrupts.patch
+kvm-selftests-aarch64-fix-assert-in-gicv3_access_reg.patch
+kvm-selftests-aarch64-pass-vgic_irq-guest-args-as-a-.patch
+kvm-selftests-aarch64-fix-the-failure-check-in-kvm_s.patch
+kvm-selftests-aarch64-fix-some-vgic-related-comments.patch
+kvm-selftests-aarch64-use-a-tighter-assert-in-vgic_p.patch
+iommu-arm-smmu-v3-fix-event-handling-soft-lockup.patch
+usb-ehci-add-pci-device-support-for-aspeed-platforms.patch
+kvm-arm64-do-not-change-the-pmu-event-filter-after-a.patch
+libbpf-fix-accessing-syscall-arguments-on-powerpc.patch
+libbpf-fix-accessing-the-first-syscall-argument-on-a.patch
+libbpf-fix-accessing-the-first-syscall-argument-on-s.patch
+pci-endpoint-fix-alignment-fault-error-in-copy-tests.patch
+tcp-don-t-acquire-inet_listen_hashbucket-lock-with-d.patch
+pci-pciehp-add-qualcomm-quirk-for-command-completed-.patch
+scsi-mpi3mr-fix-deadlock-while-canceling-the-fw-even.patch
+scsi-mpi3mr-fix-reporting-of-actual-data-transfer-si.patch
+scsi-mpi3mr-fix-memory-leaks.patch
+powerpc-set_memory-avoid-spinlock-recursion-in-chang.patch
+power-supply-axp288-charger-set-vhold-to-4.4v.patch
+drm-sprd-fix-potential-null-dereference.patch
+drm-sprd-check-the-platform_get_resource-return-valu.patch
+drm-amd-display-reset-lane-settings-after-each-phy-r.patch
+net-mlx5e-disable-tx-queues-before-registering-the-n.patch
+hid-apple-report-magic-keyboard-2021-battery-over-us.patch
+hid-apple-report-magic-keyboard-2021-with-fingerprin.patch
+usb-dwc3-pci-set-the-swnode-from-inside-dwc3_pci_qui.patch
+iwlwifi-mvm-correctly-set-fragmented-ebs.patch
+iwlwifi-fix-small-doc-mistake-for-iwl_fw_ini_addr_va.patch
+iwlwifi-mvm-move-only-to-an-enabled-channel.patch
+ipv6-annotate-some-data-races-around-sk-sk_prot.patch
+drm-msm-dsi-remove-spurious-irqf_oneshot-flag.patch
+x86-mce-work-around-an-erratum-on-fast-string-copy-i.patch
+rtw89-fix-rcu-usage-in-rtw89_core_txq_push.patch
+ath11k-fix-frames-flush-failure-caused-by-deadlock.patch
+ipv4-invalidate-neighbour-for-broadcast-address-upon.patch
+rtw88-change-rtw_info-to-proper-message-level.patch
+dm-ioctl-prevent-potential-spectre-v1-gadget.patch
+dm-requeue-io-if-mapping-table-not-yet-available.patch
+drm-amdkfd-make-crat-table-missing-message-informati.patch
+vfio-pci-stub-vfio_pci_vga_rw-when-config_vfio_pci_v.patch
+scsi-pm8001-fix-pm80xx_pci_mem_copy-interface.patch
+scsi-pm8001-fix-pm8001_mpi_task_abort_resp.patch
+scsi-pm8001-fix-tag-values-handling.patch
+scsi-pm8001-fix-task-leak-in-pm8001_send_abort_all.patch
+scsi-pm8001-fix-tag-leaks-on-error.patch
+scsi-pm8001-fix-memory-leak-in-pm8001_chip_fw_flash_.patch
+mt76-mt7915-fix-injected-mpdu-transmission-to-not-us.patch
+mctp-make-__mctp_dev_get-take-a-refcount-hold.patch
+powerpc-64s-hash-make-hash-faults-work-in-nmi-contex.patch
+mt76-mt7615-fix-assigning-negative-values-to-unsigne.patch
+power-supply-axp288_charger-use-acpi_quirk_skip_acpi.patch
+power-supply-axp288_fuel_gauge-use-acpi_quirk_skip_a.patch
+scsi-aha152x-fix-aha152x_setup-__setup-handler-retur.patch
+scsi-hisi_sas-free-irq-vectors-in-order-for-v3-hw.patch
+scsi-hisi_sas-limit-users-changing-debugfs-bist-coun.patch
+net-smc-correct-settings-of-rmb-window-update-limit.patch
+mips-ralink-fix-a-refcount-leak-in-ill_acc_of_setup.patch
+iavf-stop-leaking-iavf_status-as-errno-values.patch
+macvtap-advertise-link-netns-via-netlink.patch
+platform-x86-thinkpad_acpi-add-dual-fan-probe.patch
+tuntap-add-sanity-checks-about-msg_controllen-in-sen.patch
+bluetooth-mediatek-fix-the-conflict-between-mtk-and-.patch
+bluetooth-fix-not-checking-for-valid-hdev-on-bt_dev_.patch
+bluetooth-use-memset-avoid-memory-leaks.patch
+bnxt_en-eliminate-unintended-link-toggle-during-fw-r.patch
+pci-endpoint-fix-misused-goto-label.patch
+mips-fix-fortify-panic-when-copying-asm-exception-ha.patch
+powerpc-code-patching-pre-map-patch-area.patch
+powerpc-64e-tie-ppc_book3e_64-to-ppc_fsl_book3e.patch
+powerpc-secvar-fix-refcount-leak-in-format_show.patch
+scsi-libfc-fix-use-after-free-in-fc_exch_abts_resp.patch
+platform-x86-x86-android-tablets-depend-on-efi-and-s.patch
+can-isotp-set-default-value-for-n_as-to-50-micro-sec.patch
+can-etas_es58x-es58x_fd_rx_event_msg-initialize-rx_e.patch
+riscv-fixed-misaligned-memory-access.-fixed-pointer-.patch
+net-account-alternate-interface-name-memory.patch
+net-limit-altnames-to-64k-total.patch
+net-mlx5e-remove-overzealous-validations-in-netlink-.patch
+platform-x86-hp-wmi-fix-sw_tablet_mode-detection-met.patch
+platform-x86-hp-wmi-fix-0x05-error-code-reported-by-.patch
+net-sfp-add-2500base-x-quirk-for-lantech-sfp-module.patch
+usb-dwc3-omap-fix-unbalanced-disables-for-smps10_out.patch
+xen-usb-harden-xen_hcd-against-malicious-backends.patch
+mt76-fix-monitor-mode-crash-with-sdio-driver.patch
+xtensa-fix-dtc-warning-unit_address_format.patch
+iwlwifi-mei-fix-building-iwlmei.patch
+mips-ingenic-correct-unit-node-address.patch
+bluetooth-fix-use-after-free-in-hci_send_acl.patch
+netfilter-conntrack-revisit-gc-autotuning.patch
+netlabel-fix-out-of-bounds-memory-accesses.patch
+ceph-fix-inode-reference-leakage-in-ceph_get_snapdir.patch
+ceph-fix-memory-leak-in-ceph_readdir-when-note_last_.patch
+lib-kconfig.debug-add-arch-dependency-for-function_a.patch
+init-main.c-return-1-from-handled-__setup-functions.patch
+minix-fix-bug-when-opening-a-file-with-o_direct.patch
+clk-si5341-fix-reported-clk_rate-when-output-divider.patch
+clk-mediatek-fix-memory-leaks-on-probe.patch
+staging-vchiq_arm-avoid-null-ptr-deref-in-vchiq_dump.patch
+staging-vchiq_core-handle-null-result-of-find_servic.patch
+phy-amlogic-phy-meson-gxl-usb2-fix-shared-reset-cont.patch
+phy-amlogic-meson8b-usb2-use-dev_err_probe.patch
+phy-amlogic-meson8b-usb2-fix-shared-reset-control-us.patch
+clk-rockchip-drop-clk_set_rate_parent-from-dclk_vop-.patch
+cpufreq-cppc-fix-performance-frequency-conversion.patch
+opp-expose-of-node-s-name-in-debugfs.patch
+staging-wfx-apply-the-necessary-sdio-quirks-for-the-.patch
+staging-wfx-fix-an-error-handling-in-wfx_init_common.patch
+w1-w1_therm-fixes-w1_seq-for-ds28ea00-sensors.patch
+nfsv4.2-fix-reference-count-leaks-in-_nfs42_proc_cop.patch
+nfsv4-protect-the-state-recovery-thread-against-dire.patch
+habanalabs-fix-possible-memory-leak-in-mmu-dr-fini.patch
+habanalabs-reject-host-map-with-mmu-disabled.patch
+habanalabs-gaudi-handle-axi-errors-from-nic-engines.patch
+xen-delay-xen_hvm_init_time_ops-if-kdump-is-boot-on-.patch
+clk-ti-preserve-node-in-ti_dt_clocks_register.patch
+clk-enforce-that-disjoints-limits-are-invalid.patch
+sunrpc-xprt-async-tasks-mustn-t-block-waiting-for-me.patch
+sunrpc-remove-scheduling-boost-for-swapper-tasks.patch
+nfs-swap-io-handling-is-slightly-different-for-o_dir.patch
+nfs-swap-out-must-always-use-stable-writes.patch
+x86-annotate-call_on_stack.patch
+x86-kconfig-do-not-allow-config_x86_x32_abi-y-with-l.patch
+serial-samsung_tty-do-not-unlock-port-lock-for-uart_.patch
+virtio_console-eliminate-anonymous-module_init-modul.patch
+jfs-prevent-null-deref-in-difree.patch
+sunrpc-fix-socket-waits-for-write-buffer-space.patch
+nfs-nfsiod-should-not-block-forever-in-mempool_alloc.patch
+nfs-avoid-writeback-threads-getting-stuck-in-mempool.patch
+selftests-net-add-tls-config-dependency-for-tls-self.patch
+parisc-fix-cpu-affinity-for-lasi-wax-and-dino-chips.patch
+parisc-fix-patch-code-locking-and-flushing.patch
+mm-fix-race-between-madv_free-reclaim-and-blkdev-dir.patch
diff --git a/queue-5.17/staging-vchiq_arm-avoid-null-ptr-deref-in-vchiq_dump.patch b/queue-5.17/staging-vchiq_arm-avoid-null-ptr-deref-in-vchiq_dump.patch
new file mode 100644 (file)
index 0000000..ec48239
--- /dev/null
@@ -0,0 +1,39 @@
+From b282ce8ff98799d27f9cd4252a8839bc68be5642 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jan 2022 21:02:21 +0100
+Subject: staging: vchiq_arm: Avoid NULL ptr deref in
+ vchiq_dump_platform_instances
+
+From: Stefan Wahren <stefan.wahren@i2se.com>
+
+[ Upstream commit aa899e686d442c63d50f4d369cc02dbbf0941cb0 ]
+
+vchiq_get_state() can return a NULL pointer. So handle this cases and
+avoid a NULL pointer derefence in vchiq_dump_platform_instances.
+
+Reviewed-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Link: https://lore.kernel.org/r/1642968143-19281-17-git-send-email-stefan.wahren@i2se.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+index 3a2e4582db8e..a3e3c9f9aa18 100644
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -1209,6 +1209,9 @@ int vchiq_dump_platform_instances(void *dump_context)
+       int len;
+       int i;
++      if (!state)
++              return -ENOTCONN;
++
+       /*
+        * There is no list of instances, so instead scan all services,
+        * marking those that have been dumped.
+-- 
+2.35.1
+
diff --git a/queue-5.17/staging-vchiq_core-handle-null-result-of-find_servic.patch b/queue-5.17/staging-vchiq_core-handle-null-result-of-find_servic.patch
new file mode 100644 (file)
index 0000000..112fe66
--- /dev/null
@@ -0,0 +1,48 @@
+From eb3aa0ef6bebadfe1ef070c273464578f76f3498 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jan 2022 21:02:22 +0100
+Subject: staging: vchiq_core: handle NULL result of find_service_by_handle
+
+From: Stefan Wahren <stefan.wahren@i2se.com>
+
+[ Upstream commit ca225857faf237234d2fffe5d1919467dfadd822 ]
+
+In case of an invalid handle the function find_servive_by_handle
+returns NULL. So take care of this and avoid a NULL pointer dereference.
+
+Reviewed-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Link: https://lore.kernel.org/r/1642968143-19281-18-git-send-email-stefan.wahren@i2se.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/vc04_services/interface/vchiq_arm/vchiq_core.c  | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+index 7fe20d4b7ba2..b7295236671c 100644
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+@@ -2306,6 +2306,9 @@ void vchiq_msg_queue_push(unsigned int handle, struct vchiq_header *header)
+       struct vchiq_service *service = find_service_by_handle(handle);
+       int pos;
++      if (!service)
++              return;
++
+       while (service->msg_queue_write == service->msg_queue_read +
+               VCHIQ_MAX_SLOTS) {
+               if (wait_for_completion_interruptible(&service->msg_queue_pop))
+@@ -2326,6 +2329,9 @@ struct vchiq_header *vchiq_msg_hold(unsigned int handle)
+       struct vchiq_header *header;
+       int pos;
++      if (!service)
++              return NULL;
++
+       if (service->msg_queue_write == service->msg_queue_read)
+               return NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.17/staging-wfx-apply-the-necessary-sdio-quirks-for-the-.patch b/queue-5.17/staging-wfx-apply-the-necessary-sdio-quirks-for-the-.patch
new file mode 100644 (file)
index 0000000..125c95b
--- /dev/null
@@ -0,0 +1,63 @@
+From 383705029b7ee949dca275cb507f788d22c3c59e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Feb 2022 10:31:12 +0100
+Subject: staging: wfx: apply the necessary SDIO quirks for the Silabs WF200
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jérôme Pouiller <jerome.pouiller@silabs.com>
+
+[ Upstream commit 96e0cbca1cb96e9d3deac3051aa816e13082f3fd ]
+
+Until now, the SDIO quirks are applied directly from the driver.
+However, it is better to apply the quirks before driver probing. So,
+this patch relocate the quirks in the MMC framework.
+
+Note that the WF200 has no valid SDIO VID/PID. Therefore, we match DT
+rather than on the SDIO VID/PID.
+
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
+Link: https://lore.kernel.org/r/20220216093112.92469-3-Jerome.Pouiller@silabs.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/quirks.h      | 5 +++++
+ drivers/staging/wfx/bus_sdio.c | 3 ---
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
+index 20f568727277..f879dc63d936 100644
+--- a/drivers/mmc/core/quirks.h
++++ b/drivers/mmc/core/quirks.h
+@@ -149,6 +149,11 @@ static const struct mmc_fixup __maybe_unused sdio_fixup_methods[] = {
+ static const struct mmc_fixup __maybe_unused sdio_card_init_methods[] = {
+       SDIO_FIXUP_COMPATIBLE("ti,wl1251", wl1251_quirk, 0),
++      SDIO_FIXUP_COMPATIBLE("silabs,wf200", add_quirk,
++                            MMC_QUIRK_BROKEN_BYTE_MODE_512 |
++                            MMC_QUIRK_LENIENT_FN0 |
++                            MMC_QUIRK_BLKSZ_FOR_BYTE_MODE),
++
+       END_FIXUP
+ };
+diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/staging/wfx/bus_sdio.c
+index a670176ba06f..0612f8a7c085 100644
+--- a/drivers/staging/wfx/bus_sdio.c
++++ b/drivers/staging/wfx/bus_sdio.c
+@@ -207,9 +207,6 @@ static int wfx_sdio_probe(struct sdio_func *func,
+       bus->func = func;
+       sdio_set_drvdata(func, bus);
+-      func->card->quirks |= MMC_QUIRK_LENIENT_FN0 |
+-                            MMC_QUIRK_BLKSZ_FOR_BYTE_MODE |
+-                            MMC_QUIRK_BROKEN_BYTE_MODE_512;
+       sdio_claim_host(func);
+       ret = sdio_enable_func(func);
+-- 
+2.35.1
+
diff --git a/queue-5.17/staging-wfx-fix-an-error-handling-in-wfx_init_common.patch b/queue-5.17/staging-wfx-fix-an-error-handling-in-wfx_init_common.patch
new file mode 100644 (file)
index 0000000..50f398a
--- /dev/null
@@ -0,0 +1,56 @@
+From 8d14482c21ce493312258404cbe94ac6cd63ecd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Feb 2022 21:59:45 +0800
+Subject: staging: wfx: fix an error handling in wfx_init_common()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiaoke Wang <xkernel.wang@foxmail.com>
+
+[ Upstream commit 60f1d3c92dc1ef1026e5b917a329a7fa947da036 ]
+
+One error handler of wfx_init_common() return without calling
+ieee80211_free_hw(hw), which may result in memory leak. And I add
+one err label to unify the error handler, which is useful for the
+subsequent changes.
+
+Suggested-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
+Signed-off-by: Xiaoke Wang <xkernel.wang@foxmail.com>
+Link: https://lore.kernel.org/r/tencent_24A24A3EFF61206ECCC4B94B1C5C1454E108@qq.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/wfx/main.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c
+index 858d778cc589..e3999e95ce85 100644
+--- a/drivers/staging/wfx/main.c
++++ b/drivers/staging/wfx/main.c
+@@ -322,7 +322,8 @@ struct wfx_dev *wfx_init_common(struct device *dev,
+       wdev->pdata.gpio_wakeup = devm_gpiod_get_optional(dev, "wakeup",
+                                                         GPIOD_OUT_LOW);
+       if (IS_ERR(wdev->pdata.gpio_wakeup))
+-              return NULL;
++              goto err;
++
+       if (wdev->pdata.gpio_wakeup)
+               gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup");
+@@ -341,6 +342,10 @@ struct wfx_dev *wfx_init_common(struct device *dev,
+               return NULL;
+       return wdev;
++
++err:
++      ieee80211_free_hw(hw);
++      return NULL;
+ }
+ int wfx_probe(struct wfx_dev *wdev)
+-- 
+2.35.1
+
diff --git a/queue-5.17/sunrpc-fix-socket-waits-for-write-buffer-space.patch b/queue-5.17/sunrpc-fix-socket-waits-for-write-buffer-space.patch
new file mode 100644 (file)
index 0000000..45f4e86
--- /dev/null
@@ -0,0 +1,128 @@
+From ed73eca6586851be138642982957365389b5c309 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Mar 2022 21:02:10 -0400
+Subject: SUNRPC: Fix socket waits for write buffer space
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 7496b59f588dd52886fdbac7633608097543a0a5 ]
+
+The socket layer requires that we use the socket lock to protect changes
+to the sock->sk_write_pending field and others.
+
+Reported-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/xprtsock.c | 54 +++++++++++++++++++++++++++++++------------
+ 1 file changed, 39 insertions(+), 15 deletions(-)
+
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index 11eab0f0333b..5eb05c2dd6d6 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -763,12 +763,12 @@ xs_stream_start_connect(struct sock_xprt *transport)
+ /**
+  * xs_nospace - handle transmit was incomplete
+  * @req: pointer to RPC request
++ * @transport: pointer to struct sock_xprt
+  *
+  */
+-static int xs_nospace(struct rpc_rqst *req)
++static int xs_nospace(struct rpc_rqst *req, struct sock_xprt *transport)
+ {
+-      struct rpc_xprt *xprt = req->rq_xprt;
+-      struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
++      struct rpc_xprt *xprt = &transport->xprt;
+       struct sock *sk = transport->inet;
+       int ret = -EAGAIN;
+@@ -779,25 +779,49 @@ static int xs_nospace(struct rpc_rqst *req)
+       /* Don't race with disconnect */
+       if (xprt_connected(xprt)) {
++              struct socket_wq *wq;
++
++              rcu_read_lock();
++              wq = rcu_dereference(sk->sk_wq);
++              set_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags);
++              rcu_read_unlock();
++
+               /* wait for more buffer space */
++              set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+               sk->sk_write_pending++;
+               xprt_wait_for_buffer_space(xprt);
+       } else
+               ret = -ENOTCONN;
+       spin_unlock(&xprt->transport_lock);
++      return ret;
++}
+-      /* Race breaker in case memory is freed before above code is called */
+-      if (ret == -EAGAIN) {
+-              struct socket_wq *wq;
++static int xs_sock_nospace(struct rpc_rqst *req)
++{
++      struct sock_xprt *transport =
++              container_of(req->rq_xprt, struct sock_xprt, xprt);
++      struct sock *sk = transport->inet;
++      int ret = -EAGAIN;
+-              rcu_read_lock();
+-              wq = rcu_dereference(sk->sk_wq);
+-              set_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags);
+-              rcu_read_unlock();
++      lock_sock(sk);
++      if (!sock_writeable(sk))
++              ret = xs_nospace(req, transport);
++      release_sock(sk);
++      return ret;
++}
+-              sk->sk_write_space(sk);
+-      }
++static int xs_stream_nospace(struct rpc_rqst *req)
++{
++      struct sock_xprt *transport =
++              container_of(req->rq_xprt, struct sock_xprt, xprt);
++      struct sock *sk = transport->inet;
++      int ret = -EAGAIN;
++
++      lock_sock(sk);
++      if (!sk_stream_memory_free(sk))
++              ret = xs_nospace(req, transport);
++      release_sock(sk);
+       return ret;
+ }
+@@ -887,7 +911,7 @@ static int xs_local_send_request(struct rpc_rqst *req)
+       case -ENOBUFS:
+               break;
+       case -EAGAIN:
+-              status = xs_nospace(req);
++              status = xs_stream_nospace(req);
+               break;
+       default:
+               dprintk("RPC:       sendmsg returned unrecognized error %d\n",
+@@ -963,7 +987,7 @@ static int xs_udp_send_request(struct rpc_rqst *req)
+               /* Should we call xs_close() here? */
+               break;
+       case -EAGAIN:
+-              status = xs_nospace(req);
++              status = xs_sock_nospace(req);
+               break;
+       case -ENETUNREACH:
+       case -ENOBUFS:
+@@ -1083,7 +1107,7 @@ static int xs_tcp_send_request(struct rpc_rqst *req)
+               /* Should we call xs_close() here? */
+               break;
+       case -EAGAIN:
+-              status = xs_nospace(req);
++              status = xs_stream_nospace(req);
+               break;
+       case -ECONNRESET:
+       case -ECONNREFUSED:
+-- 
+2.35.1
+
diff --git a/queue-5.17/sunrpc-remove-scheduling-boost-for-swapper-tasks.patch b/queue-5.17/sunrpc-remove-scheduling-boost-for-swapper-tasks.patch
new file mode 100644 (file)
index 0000000..6a3fb6d
--- /dev/null
@@ -0,0 +1,79 @@
+From 375f5e6246d7fad6b988781248fc9e84edf67937 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Mar 2022 10:41:44 +1100
+Subject: SUNRPC: remove scheduling boost for "SWAPPER" tasks.
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit a80a8461868905823609be97f91776a26befe839 ]
+
+Currently, tasks marked as "swapper" tasks get put to the front of
+non-priority rpc_queues, and are sorted earlier than non-swapper tasks on
+the transport's ->xmit_queue.
+
+This is pointless as currently *all* tasks for a mount that has swap
+enabled on *any* file are marked as "swapper" tasks.  So the net result
+is that the non-priority rpc_queues are reverse-ordered (LIFO).
+
+This scheduling boost is not necessary to avoid deadlocks, and hurts
+fairness, so remove it.  If there were a need to expedite some requests,
+the tk_priority mechanism is a more appropriate tool.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/sched.c |  7 -------
+ net/sunrpc/xprt.c  | 11 -----------
+ 2 files changed, 18 deletions(-)
+
+diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
+index ae295844ac55..9020cedb7c95 100644
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -186,11 +186,6 @@ static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue,
+ /*
+  * Add new request to wait queue.
+- *
+- * Swapper tasks always get inserted at the head of the queue.
+- * This should avoid many nasty memory deadlocks and hopefully
+- * improve overall performance.
+- * Everyone else gets appended to the queue to ensure proper FIFO behavior.
+  */
+ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
+               struct rpc_task *task,
+@@ -199,8 +194,6 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
+       INIT_LIST_HEAD(&task->u.tk_wait.timer_list);
+       if (RPC_IS_PRIORITY(queue))
+               __rpc_add_wait_queue_priority(queue, task, queue_priority);
+-      else if (RPC_IS_SWAPPER(task))
+-              list_add(&task->u.tk_wait.list, &queue->tasks[0]);
+       else
+               list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]);
+       task->tk_waitqueue = queue;
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+index 75acde97d748..b1bb466bbdda 100644
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -1354,17 +1354,6 @@ xprt_request_enqueue_transmit(struct rpc_task *task)
+                               INIT_LIST_HEAD(&req->rq_xmit2);
+                               goto out;
+                       }
+-              } else if (RPC_IS_SWAPPER(task)) {
+-                      list_for_each_entry(pos, &xprt->xmit_queue, rq_xmit) {
+-                              if (pos->rq_cong || pos->rq_bytes_sent)
+-                                      continue;
+-                              if (RPC_IS_SWAPPER(pos->rq_task))
+-                                      continue;
+-                              /* Note: req is added _before_ pos */
+-                              list_add_tail(&req->rq_xmit, &pos->rq_xmit);
+-                              INIT_LIST_HEAD(&req->rq_xmit2);
+-                              goto out;
+-                      }
+               } else if (!req->rq_seqno) {
+                       list_for_each_entry(pos, &xprt->xmit_queue, rq_xmit) {
+                               if (pos->rq_task->tk_owner != task->tk_owner)
+-- 
+2.35.1
+
diff --git a/queue-5.17/sunrpc-xprt-async-tasks-mustn-t-block-waiting-for-me.patch b/queue-5.17/sunrpc-xprt-async-tasks-mustn-t-block-waiting-for-me.patch
new file mode 100644 (file)
index 0000000..8497993
--- /dev/null
@@ -0,0 +1,67 @@
+From 403b3e77edbb4d5f1d9c3134b55a9240ba01aa33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Mar 2022 10:41:44 +1100
+Subject: SUNRPC/xprt: async tasks mustn't block waiting for memory
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit a721035477fb5fb8abc738fbe410b07c12af3dc5 ]
+
+When memory is short, new worker threads cannot be created and we depend
+on the minimum one rpciod thread to be able to handle everything.  So it
+must not block waiting for memory.
+
+xprt_dynamic_alloc_slot can block indefinitely.  This can tie up all
+workqueue threads and NFS can deadlock.  So when called from a
+workqueue, set __GFP_NORETRY.
+
+The rdma alloc_slot already does not block.  However it sets the error
+to -EAGAIN suggesting this will trigger a sleep.  It does not.  As we
+can see in call_reserveresult(), only -ENOMEM causes a sleep.  -EAGAIN
+causes immediate retry.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/xprt.c               | 5 ++++-
+ net/sunrpc/xprtrdma/transport.c | 2 +-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+index 396a74974f60..75acde97d748 100644
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -1690,12 +1690,15 @@ static bool xprt_throttle_congested(struct rpc_xprt *xprt, struct rpc_task *task
+ static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt)
+ {
+       struct rpc_rqst *req = ERR_PTR(-EAGAIN);
++      gfp_t gfp_mask = GFP_KERNEL;
+       if (xprt->num_reqs >= xprt->max_reqs)
+               goto out;
+       ++xprt->num_reqs;
+       spin_unlock(&xprt->reserve_lock);
+-      req = kzalloc(sizeof(struct rpc_rqst), GFP_NOFS);
++      if (current->flags & PF_WQ_WORKER)
++              gfp_mask |= __GFP_NORETRY | __GFP_NOWARN;
++      req = kzalloc(sizeof(*req), gfp_mask);
+       spin_lock(&xprt->reserve_lock);
+       if (req != NULL)
+               goto out;
+diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
+index ff78a296fa81..6b7e10e5a141 100644
+--- a/net/sunrpc/xprtrdma/transport.c
++++ b/net/sunrpc/xprtrdma/transport.c
+@@ -521,7 +521,7 @@ xprt_rdma_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task)
+       return;
+ out_sleep:
+-      task->tk_status = -EAGAIN;
++      task->tk_status = -ENOMEM;
+       xprt_add_backlog(xprt, task);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/tcp-don-t-acquire-inet_listen_hashbucket-lock-with-d.patch b/queue-5.17/tcp-don-t-acquire-inet_listen_hashbucket-lock-with-d.patch
new file mode 100644 (file)
index 0000000..29622dc
--- /dev/null
@@ -0,0 +1,173 @@
+From 5036c9db2866249607d41184804bd415fa270639 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Feb 2022 19:56:57 +0100
+Subject: tcp: Don't acquire inet_listen_hashbucket::lock with disabled BH.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 4f9bf2a2f5aacf988e6d5e56b961ba45c5a25248 ]
+
+Commit
+   9652dc2eb9e40 ("tcp: relax listening_hash operations")
+
+removed the need to disable bottom half while acquiring
+listening_hash.lock. There are still two callers left which disable
+bottom half before the lock is acquired.
+
+On PREEMPT_RT the softirqs are preemptible and local_bh_disable() acts
+as a lock to ensure that resources, that are protected by disabling
+bottom halves, remain protected.
+This leads to a circular locking dependency if the lock acquired with
+disabled bottom halves is also acquired with enabled bottom halves
+followed by disabling bottom halves. This is the reverse locking order.
+It has been observed with inet_listen_hashbucket::lock:
+
+local_bh_disable() + spin_lock(&ilb->lock):
+  inet_listen()
+    inet_csk_listen_start()
+      sk->sk_prot->hash() := inet_hash()
+       local_bh_disable()
+       __inet_hash()
+         spin_lock(&ilb->lock);
+           acquire(&ilb->lock);
+
+Reverse order: spin_lock(&ilb2->lock) + local_bh_disable():
+  tcp_seq_next()
+    listening_get_next()
+      spin_lock(&ilb2->lock);
+       acquire(&ilb2->lock);
+
+  tcp4_seq_show()
+    get_tcp4_sock()
+      sock_i_ino()
+       read_lock_bh(&sk->sk_callback_lock);
+         acquire(softirq_ctrl) // <---- whoops
+         acquire(&sk->sk_callback_lock)
+
+Drop local_bh_disable() around __inet_hash() which acquires
+listening_hash->lock. Split inet_unhash() and acquire the
+listen_hashbucket lock without disabling bottom halves; the inet_ehash
+lock with disabled bottom halves.
+
+Reported-by: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://lkml.kernel.org/r/12d6f9879a97cd56c09fb53dee343cbb14f7f1f7.camel@gmx.de
+Link: https://lkml.kernel.org/r/X9CheYjuXWc75Spa@hirez.programming.kicks-ass.net
+Link: https://lore.kernel.org/r/YgQOebeZ10eNx1W6@linutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/inet_hashtables.c  | 53 ++++++++++++++++++++++---------------
+ net/ipv6/inet6_hashtables.c |  5 +---
+ 2 files changed, 33 insertions(+), 25 deletions(-)
+
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 30ab717ff1b8..17440840a791 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -637,7 +637,9 @@ int __inet_hash(struct sock *sk, struct sock *osk)
+       int err = 0;
+       if (sk->sk_state != TCP_LISTEN) {
++              local_bh_disable();
+               inet_ehash_nolisten(sk, osk, NULL);
++              local_bh_enable();
+               return 0;
+       }
+       WARN_ON(!sk_unhashed(sk));
+@@ -669,45 +671,54 @@ int inet_hash(struct sock *sk)
+ {
+       int err = 0;
+-      if (sk->sk_state != TCP_CLOSE) {
+-              local_bh_disable();
++      if (sk->sk_state != TCP_CLOSE)
+               err = __inet_hash(sk, NULL);
+-              local_bh_enable();
+-      }
+       return err;
+ }
+ EXPORT_SYMBOL_GPL(inet_hash);
+-void inet_unhash(struct sock *sk)
++static void __inet_unhash(struct sock *sk, struct inet_listen_hashbucket *ilb)
+ {
+-      struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
+-      struct inet_listen_hashbucket *ilb = NULL;
+-      spinlock_t *lock;
+-
+       if (sk_unhashed(sk))
+               return;
+-      if (sk->sk_state == TCP_LISTEN) {
+-              ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
+-              lock = &ilb->lock;
+-      } else {
+-              lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
+-      }
+-      spin_lock_bh(lock);
+-      if (sk_unhashed(sk))
+-              goto unlock;
+-
+       if (rcu_access_pointer(sk->sk_reuseport_cb))
+               reuseport_stop_listen_sock(sk);
+       if (ilb) {
++              struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
++
+               inet_unhash2(hashinfo, sk);
+               ilb->count--;
+       }
+       __sk_nulls_del_node_init_rcu(sk);
+       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+-unlock:
+-      spin_unlock_bh(lock);
++}
++
++void inet_unhash(struct sock *sk)
++{
++      struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
++
++      if (sk_unhashed(sk))
++              return;
++
++      if (sk->sk_state == TCP_LISTEN) {
++              struct inet_listen_hashbucket *ilb;
++
++              ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
++              /* Don't disable bottom halves while acquiring the lock to
++               * avoid circular locking dependency on PREEMPT_RT.
++               */
++              spin_lock(&ilb->lock);
++              __inet_unhash(sk, ilb);
++              spin_unlock(&ilb->lock);
++      } else {
++              spinlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
++
++              spin_lock_bh(lock);
++              __inet_unhash(sk, NULL);
++              spin_unlock_bh(lock);
++      }
+ }
+ EXPORT_SYMBOL_GPL(inet_unhash);
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index 4514444e96c8..4740afecf7c6 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -333,11 +333,8 @@ int inet6_hash(struct sock *sk)
+ {
+       int err = 0;
+-      if (sk->sk_state != TCP_CLOSE) {
+-              local_bh_disable();
++      if (sk->sk_state != TCP_CLOSE)
+               err = __inet_hash(sk, NULL);
+-              local_bh_enable();
+-      }
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/tuntap-add-sanity-checks-about-msg_controllen-in-sen.patch b/queue-5.17/tuntap-add-sanity-checks-about-msg_controllen-in-sen.patch
new file mode 100644 (file)
index 0000000..10ec9f4
--- /dev/null
@@ -0,0 +1,71 @@
+From 9e15bbb77f2b4fa9848eb62bebd96efe75e5aa92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Mar 2022 10:24:40 +0800
+Subject: tuntap: add sanity checks about msg_controllen in sendmsg
+
+From: Harold Huang <baymaxhuang@gmail.com>
+
+[ Upstream commit 74a335a07a17d131b9263bfdbdcb5e40673ca9ca ]
+
+In patch [1], tun_msg_ctl was added to allow pass batched xdp buffers to
+tun_sendmsg. Although we donot use msg_controllen in this path, we should
+check msg_controllen to make sure the caller pass a valid msg_ctl.
+
+[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fe8dd45bb7556246c6b76277b1ba4296c91c2505
+
+Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
+Suggested-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Harold Huang <baymaxhuang@gmail.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Link: https://lore.kernel.org/r/20220303022441.383865-1-baymaxhuang@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tap.c   | 3 ++-
+ drivers/net/tun.c   | 3 ++-
+ drivers/vhost/net.c | 1 +
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/tap.c b/drivers/net/tap.c
+index 8e3a28ba6b28..ba2ef5437e16 100644
+--- a/drivers/net/tap.c
++++ b/drivers/net/tap.c
+@@ -1198,7 +1198,8 @@ static int tap_sendmsg(struct socket *sock, struct msghdr *m,
+       struct xdp_buff *xdp;
+       int i;
+-      if (ctl && (ctl->type == TUN_MSG_PTR)) {
++      if (m->msg_controllen == sizeof(struct tun_msg_ctl) &&
++          ctl && ctl->type == TUN_MSG_PTR) {
+               for (i = 0; i < ctl->num; i++) {
+                       xdp = &((struct xdp_buff *)ctl->ptr)[i];
+                       tap_get_user_xdp(q, xdp);
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index fed85447701a..de999e0fedbc 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2489,7 +2489,8 @@ static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
+       if (!tun)
+               return -EBADFD;
+-      if (ctl && (ctl->type == TUN_MSG_PTR)) {
++      if (m->msg_controllen == sizeof(struct tun_msg_ctl) &&
++          ctl && ctl->type == TUN_MSG_PTR) {
+               struct tun_page tpage;
+               int n = ctl->num;
+               int flush = 0;
+diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
+index 28ef323882fb..792ab5f23647 100644
+--- a/drivers/vhost/net.c
++++ b/drivers/vhost/net.c
+@@ -473,6 +473,7 @@ static void vhost_tx_batch(struct vhost_net *net,
+               goto signal_used;
+       msghdr->msg_control = &ctl;
++      msghdr->msg_controllen = sizeof(ctl);
+       err = sock->ops->sendmsg(sock, msghdr, 0);
+       if (unlikely(err < 0)) {
+               vq_err(&nvq->vq, "Fail to batch sending packets\n");
+-- 
+2.35.1
+
diff --git a/queue-5.17/um-fix-and-optimize-xor-select-template-for-config64.patch b/queue-5.17/um-fix-and-optimize-xor-select-template-for-config64.patch
new file mode 100644 (file)
index 0000000..d656f1d
--- /dev/null
@@ -0,0 +1,56 @@
+From f8bccfa5289dffc705f385bd38c48e0984d48855 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jan 2022 20:05:06 +0000
+Subject: um: fix and optimize xor select template for CONFIG64 and timetravel
+ mode
+
+From: Benjamin Beichler <benjamin.beichler@uni-rostock.de>
+
+[ Upstream commit e3a33af812c611d99756e2ec61e9d7068d466bdf ]
+
+Due to dropped inclusion of asm-generic/xor.h, xor_block_8regs symbol is
+missing with CONFIG64 and break compilation, as the asm/xor_64.h also did
+not include it. The patch recreate the logic from arch/x86, which check
+whether AVX is available and add fallbacks for 32bit and 64bit config of
+um.
+
+A very minor additional "fix" is, the return of the macro parameter
+instead of NULL, as this is the original intent of the macro, but
+this does not change the actual behavior.
+
+Fixes: c0ecca6604b8 ("um: enable the use of optimized xor routines in UML")
+Signed-off-by: Benjamin Beichler <benjamin.beichler@uni-rostock.de>
+Acked-By: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/include/asm/xor.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/um/include/asm/xor.h b/arch/um/include/asm/xor.h
+index f512704a9ec7..22b39de73c24 100644
+--- a/arch/um/include/asm/xor.h
++++ b/arch/um/include/asm/xor.h
+@@ -4,8 +4,10 @@
+ #ifdef CONFIG_64BIT
+ #undef CONFIG_X86_32
++#define TT_CPU_INF_XOR_DEFAULT (AVX_SELECT(&xor_block_sse_pf64))
+ #else
+ #define CONFIG_X86_32 1
++#define TT_CPU_INF_XOR_DEFAULT (AVX_SELECT(&xor_block_8regs))
+ #endif
+ #include <asm/cpufeature.h>
+@@ -16,7 +18,7 @@
+ #undef XOR_SELECT_TEMPLATE
+ /* pick an arbitrary one - measuring isn't possible with inf-cpu */
+ #define XOR_SELECT_TEMPLATE(x)        \
+-      (time_travel_mode == TT_MODE_INFCPU ? &xor_block_8regs : NULL)
++      (time_travel_mode == TT_MODE_INFCPU ? TT_CPU_INF_XOR_DEFAULT : x))
+ #endif
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.17/usb-cdnsp-fix-cdnsp_decode_trb-function-to-properly-.patch b/queue-5.17/usb-cdnsp-fix-cdnsp_decode_trb-function-to-properly-.patch
new file mode 100644 (file)
index 0000000..63cee94
--- /dev/null
@@ -0,0 +1,393 @@
+From a2af677af4bb7b6fd0d37bac1ed5bef4cd653291 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jan 2022 06:32:37 +0100
+Subject: usb: cdnsp: fix cdnsp_decode_trb function to properly handle ret
+ value
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+[ Upstream commit 03db9289b5ab59437e42a111a34545a7cedb5190 ]
+
+Variable ret in function cdnsp_decode_trb is initialized but not
+used. To fix this compiler warning patch adds checking whether the
+data buffer has not been overflowed.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Link: https://lore.kernel.org/r/20220112053237.14309-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/cdns3/cdnsp-debug.h | 305 ++++++++++++++++----------------
+ 1 file changed, 154 insertions(+), 151 deletions(-)
+
+diff --git a/drivers/usb/cdns3/cdnsp-debug.h b/drivers/usb/cdns3/cdnsp-debug.h
+index a8776df2d4e0..f0ca865cce2a 100644
+--- a/drivers/usb/cdns3/cdnsp-debug.h
++++ b/drivers/usb/cdns3/cdnsp-debug.h
+@@ -182,208 +182,211 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
+       int ep_id = TRB_TO_EP_INDEX(field3) - 1;
+       int type = TRB_FIELD_TO_TYPE(field3);
+       unsigned int ep_num;
+-      int ret = 0;
++      int ret;
+       u32 temp;
+       ep_num = DIV_ROUND_UP(ep_id, 2);
+       switch (type) {
+       case TRB_LINK:
+-              ret += snprintf(str, size,
+-                              "LINK %08x%08x intr %ld type '%s' flags %c:%c:%c:%c",
+-                              field1, field0, GET_INTR_TARGET(field2),
+-                              cdnsp_trb_type_string(type),
+-                              field3 & TRB_IOC ? 'I' : 'i',
+-                              field3 & TRB_CHAIN ? 'C' : 'c',
+-                              field3 & TRB_TC ? 'T' : 't',
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "LINK %08x%08x intr %ld type '%s' flags %c:%c:%c:%c",
++                             field1, field0, GET_INTR_TARGET(field2),
++                             cdnsp_trb_type_string(type),
++                             field3 & TRB_IOC ? 'I' : 'i',
++                             field3 & TRB_CHAIN ? 'C' : 'c',
++                             field3 & TRB_TC ? 'T' : 't',
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_TRANSFER:
+       case TRB_COMPLETION:
+       case TRB_PORT_STATUS:
+       case TRB_HC_EVENT:
+-              ret += snprintf(str, size,
+-                              "ep%d%s(%d) type '%s' TRB %08x%08x status '%s'"
+-                              " len %ld slot %ld flags %c:%c",
+-                              ep_num, ep_id % 2 ? "out" : "in",
+-                              TRB_TO_EP_INDEX(field3),
+-                              cdnsp_trb_type_string(type), field1, field0,
+-                              cdnsp_trb_comp_code_string(GET_COMP_CODE(field2)),
+-                              EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3),
+-                              field3 & EVENT_DATA ? 'E' : 'e',
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "ep%d%s(%d) type '%s' TRB %08x%08x status '%s'"
++                             " len %ld slot %ld flags %c:%c",
++                             ep_num, ep_id % 2 ? "out" : "in",
++                             TRB_TO_EP_INDEX(field3),
++                             cdnsp_trb_type_string(type), field1, field0,
++                             cdnsp_trb_comp_code_string(GET_COMP_CODE(field2)),
++                             EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3),
++                             field3 & EVENT_DATA ? 'E' : 'e',
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_MFINDEX_WRAP:
+-              ret += snprintf(str, size, "%s: flags %c",
+-                              cdnsp_trb_type_string(type),
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size, "%s: flags %c",
++                             cdnsp_trb_type_string(type),
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_SETUP:
+-              ret += snprintf(str, size,
+-                              "type '%s' bRequestType %02x bRequest %02x "
+-                              "wValue %02x%02x wIndex %02x%02x wLength %d "
+-                              "length %ld TD size %ld intr %ld Setup ID %ld "
+-                              "flags %c:%c:%c",
+-                              cdnsp_trb_type_string(type),
+-                              field0 & 0xff,
+-                              (field0 & 0xff00) >> 8,
+-                              (field0 & 0xff000000) >> 24,
+-                              (field0 & 0xff0000) >> 16,
+-                              (field1 & 0xff00) >> 8,
+-                              field1 & 0xff,
+-                              (field1 & 0xff000000) >> 16 |
+-                              (field1 & 0xff0000) >> 16,
+-                              TRB_LEN(field2), GET_TD_SIZE(field2),
+-                              GET_INTR_TARGET(field2),
+-                              TRB_SETUPID_TO_TYPE(field3),
+-                              field3 & TRB_IDT ? 'D' : 'd',
+-                              field3 & TRB_IOC ? 'I' : 'i',
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "type '%s' bRequestType %02x bRequest %02x "
++                             "wValue %02x%02x wIndex %02x%02x wLength %d "
++                             "length %ld TD size %ld intr %ld Setup ID %ld "
++                             "flags %c:%c:%c",
++                             cdnsp_trb_type_string(type),
++                             field0 & 0xff,
++                             (field0 & 0xff00) >> 8,
++                             (field0 & 0xff000000) >> 24,
++                             (field0 & 0xff0000) >> 16,
++                             (field1 & 0xff00) >> 8,
++                             field1 & 0xff,
++                             (field1 & 0xff000000) >> 16 |
++                             (field1 & 0xff0000) >> 16,
++                             TRB_LEN(field2), GET_TD_SIZE(field2),
++                             GET_INTR_TARGET(field2),
++                             TRB_SETUPID_TO_TYPE(field3),
++                             field3 & TRB_IDT ? 'D' : 'd',
++                             field3 & TRB_IOC ? 'I' : 'i',
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_DATA:
+-              ret += snprintf(str, size,
+-                              "type '%s' Buffer %08x%08x length %ld TD size %ld "
+-                              "intr %ld flags %c:%c:%c:%c:%c:%c:%c",
+-                              cdnsp_trb_type_string(type),
+-                              field1, field0, TRB_LEN(field2),
+-                              GET_TD_SIZE(field2),
+-                              GET_INTR_TARGET(field2),
+-                              field3 & TRB_IDT ? 'D' : 'i',
+-                              field3 & TRB_IOC ? 'I' : 'i',
+-                              field3 & TRB_CHAIN ? 'C' : 'c',
+-                              field3 & TRB_NO_SNOOP ? 'S' : 's',
+-                              field3 & TRB_ISP ? 'I' : 'i',
+-                              field3 & TRB_ENT ? 'E' : 'e',
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "type '%s' Buffer %08x%08x length %ld TD size %ld "
++                             "intr %ld flags %c:%c:%c:%c:%c:%c:%c",
++                             cdnsp_trb_type_string(type),
++                             field1, field0, TRB_LEN(field2),
++                             GET_TD_SIZE(field2),
++                             GET_INTR_TARGET(field2),
++                             field3 & TRB_IDT ? 'D' : 'i',
++                             field3 & TRB_IOC ? 'I' : 'i',
++                             field3 & TRB_CHAIN ? 'C' : 'c',
++                             field3 & TRB_NO_SNOOP ? 'S' : 's',
++                             field3 & TRB_ISP ? 'I' : 'i',
++                             field3 & TRB_ENT ? 'E' : 'e',
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_STATUS:
+-              ret += snprintf(str, size,
+-                              "Buffer %08x%08x length %ld TD size %ld intr"
+-                              "%ld type '%s' flags %c:%c:%c:%c",
+-                              field1, field0, TRB_LEN(field2),
+-                              GET_TD_SIZE(field2),
+-                              GET_INTR_TARGET(field2),
+-                              cdnsp_trb_type_string(type),
+-                              field3 & TRB_IOC ? 'I' : 'i',
+-                              field3 & TRB_CHAIN ? 'C' : 'c',
+-                              field3 & TRB_ENT ? 'E' : 'e',
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "Buffer %08x%08x length %ld TD size %ld intr"
++                             "%ld type '%s' flags %c:%c:%c:%c",
++                             field1, field0, TRB_LEN(field2),
++                             GET_TD_SIZE(field2),
++                             GET_INTR_TARGET(field2),
++                             cdnsp_trb_type_string(type),
++                             field3 & TRB_IOC ? 'I' : 'i',
++                             field3 & TRB_CHAIN ? 'C' : 'c',
++                             field3 & TRB_ENT ? 'E' : 'e',
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_NORMAL:
+       case TRB_ISOC:
+       case TRB_EVENT_DATA:
+       case TRB_TR_NOOP:
+-              ret += snprintf(str, size,
+-                              "type '%s' Buffer %08x%08x length %ld "
+-                              "TD size %ld intr %ld "
+-                              "flags %c:%c:%c:%c:%c:%c:%c:%c:%c",
+-                              cdnsp_trb_type_string(type),
+-                              field1, field0, TRB_LEN(field2),
+-                              GET_TD_SIZE(field2),
+-                              GET_INTR_TARGET(field2),
+-                              field3 & TRB_BEI ? 'B' : 'b',
+-                              field3 & TRB_IDT ? 'T' : 't',
+-                              field3 & TRB_IOC ? 'I' : 'i',
+-                              field3 & TRB_CHAIN ? 'C' : 'c',
+-                              field3 & TRB_NO_SNOOP ? 'S' : 's',
+-                              field3 & TRB_ISP ? 'I' : 'i',
+-                              field3 & TRB_ENT ? 'E' : 'e',
+-                              field3 & TRB_CYCLE ? 'C' : 'c',
+-                              !(field3 & TRB_EVENT_INVALIDATE) ? 'V' : 'v');
++              ret = snprintf(str, size,
++                             "type '%s' Buffer %08x%08x length %ld "
++                             "TD size %ld intr %ld "
++                             "flags %c:%c:%c:%c:%c:%c:%c:%c:%c",
++                             cdnsp_trb_type_string(type),
++                             field1, field0, TRB_LEN(field2),
++                             GET_TD_SIZE(field2),
++                             GET_INTR_TARGET(field2),
++                             field3 & TRB_BEI ? 'B' : 'b',
++                             field3 & TRB_IDT ? 'T' : 't',
++                             field3 & TRB_IOC ? 'I' : 'i',
++                             field3 & TRB_CHAIN ? 'C' : 'c',
++                             field3 & TRB_NO_SNOOP ? 'S' : 's',
++                             field3 & TRB_ISP ? 'I' : 'i',
++                             field3 & TRB_ENT ? 'E' : 'e',
++                             field3 & TRB_CYCLE ? 'C' : 'c',
++                             !(field3 & TRB_EVENT_INVALIDATE) ? 'V' : 'v');
+               break;
+       case TRB_CMD_NOOP:
+       case TRB_ENABLE_SLOT:
+-              ret += snprintf(str, size, "%s: flags %c",
+-                              cdnsp_trb_type_string(type),
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size, "%s: flags %c",
++                             cdnsp_trb_type_string(type),
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_DISABLE_SLOT:
+-              ret += snprintf(str, size, "%s: slot %ld flags %c",
+-                              cdnsp_trb_type_string(type),
+-                              TRB_TO_SLOT_ID(field3),
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size, "%s: slot %ld flags %c",
++                             cdnsp_trb_type_string(type),
++                             TRB_TO_SLOT_ID(field3),
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_ADDR_DEV:
+-              ret += snprintf(str, size,
+-                              "%s: ctx %08x%08x slot %ld flags %c:%c",
+-                              cdnsp_trb_type_string(type), field1, field0,
+-                              TRB_TO_SLOT_ID(field3),
+-                              field3 & TRB_BSR ? 'B' : 'b',
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "%s: ctx %08x%08x slot %ld flags %c:%c",
++                             cdnsp_trb_type_string(type), field1, field0,
++                             TRB_TO_SLOT_ID(field3),
++                             field3 & TRB_BSR ? 'B' : 'b',
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_CONFIG_EP:
+-              ret += snprintf(str, size,
+-                              "%s: ctx %08x%08x slot %ld flags %c:%c",
+-                              cdnsp_trb_type_string(type), field1, field0,
+-                              TRB_TO_SLOT_ID(field3),
+-                              field3 & TRB_DC ? 'D' : 'd',
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "%s: ctx %08x%08x slot %ld flags %c:%c",
++                             cdnsp_trb_type_string(type), field1, field0,
++                             TRB_TO_SLOT_ID(field3),
++                             field3 & TRB_DC ? 'D' : 'd',
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_EVAL_CONTEXT:
+-              ret += snprintf(str, size,
+-                              "%s: ctx %08x%08x slot %ld flags %c",
+-                              cdnsp_trb_type_string(type), field1, field0,
+-                              TRB_TO_SLOT_ID(field3),
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "%s: ctx %08x%08x slot %ld flags %c",
++                             cdnsp_trb_type_string(type), field1, field0,
++                             TRB_TO_SLOT_ID(field3),
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_RESET_EP:
+       case TRB_HALT_ENDPOINT:
+       case TRB_FLUSH_ENDPOINT:
+-              ret += snprintf(str, size,
+-                              "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c",
+-                              cdnsp_trb_type_string(type),
+-                              ep_num, ep_id % 2 ? "out" : "in",
+-                              TRB_TO_EP_INDEX(field3), field1, field0,
+-                              TRB_TO_SLOT_ID(field3),
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c",
++                             cdnsp_trb_type_string(type),
++                             ep_num, ep_id % 2 ? "out" : "in",
++                             TRB_TO_EP_INDEX(field3), field1, field0,
++                             TRB_TO_SLOT_ID(field3),
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_STOP_RING:
+-              ret += snprintf(str, size,
+-                              "%s: ep%d%s(%d) slot %ld sp %d flags %c",
+-                              cdnsp_trb_type_string(type),
+-                              ep_num, ep_id % 2 ? "out" : "in",
+-                              TRB_TO_EP_INDEX(field3),
+-                              TRB_TO_SLOT_ID(field3),
+-                              TRB_TO_SUSPEND_PORT(field3),
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "%s: ep%d%s(%d) slot %ld sp %d flags %c",
++                             cdnsp_trb_type_string(type),
++                             ep_num, ep_id % 2 ? "out" : "in",
++                             TRB_TO_EP_INDEX(field3),
++                             TRB_TO_SLOT_ID(field3),
++                             TRB_TO_SUSPEND_PORT(field3),
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_SET_DEQ:
+-              ret += snprintf(str, size,
+-                              "%s: ep%d%s(%d) deq %08x%08x stream %ld slot %ld  flags %c",
+-                              cdnsp_trb_type_string(type),
+-                              ep_num, ep_id % 2 ? "out" : "in",
+-                              TRB_TO_EP_INDEX(field3), field1, field0,
+-                              TRB_TO_STREAM_ID(field2),
+-                              TRB_TO_SLOT_ID(field3),
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size,
++                             "%s: ep%d%s(%d) deq %08x%08x stream %ld slot %ld  flags %c",
++                             cdnsp_trb_type_string(type),
++                             ep_num, ep_id % 2 ? "out" : "in",
++                             TRB_TO_EP_INDEX(field3), field1, field0,
++                             TRB_TO_STREAM_ID(field2),
++                             TRB_TO_SLOT_ID(field3),
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_RESET_DEV:
+-              ret += snprintf(str, size, "%s: slot %ld flags %c",
+-                              cdnsp_trb_type_string(type),
+-                              TRB_TO_SLOT_ID(field3),
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              ret = snprintf(str, size, "%s: slot %ld flags %c",
++                             cdnsp_trb_type_string(type),
++                             TRB_TO_SLOT_ID(field3),
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_ENDPOINT_NRDY:
+-              temp  = TRB_TO_HOST_STREAM(field2);
+-
+-              ret += snprintf(str, size,
+-                              "%s: ep%d%s(%d) H_SID %x%s%s D_SID %lx flags %c:%c",
+-                              cdnsp_trb_type_string(type),
+-                              ep_num, ep_id % 2 ? "out" : "in",
+-                              TRB_TO_EP_INDEX(field3), temp,
+-                              temp == STREAM_PRIME_ACK ? "(PRIME)" : "",
+-                              temp == STREAM_REJECTED ? "(REJECTED)" : "",
+-                              TRB_TO_DEV_STREAM(field0),
+-                              field3 & TRB_STAT ? 'S' : 's',
+-                              field3 & TRB_CYCLE ? 'C' : 'c');
++              temp = TRB_TO_HOST_STREAM(field2);
++
++              ret = snprintf(str, size,
++                             "%s: ep%d%s(%d) H_SID %x%s%s D_SID %lx flags %c:%c",
++                             cdnsp_trb_type_string(type),
++                             ep_num, ep_id % 2 ? "out" : "in",
++                             TRB_TO_EP_INDEX(field3), temp,
++                             temp == STREAM_PRIME_ACK ? "(PRIME)" : "",
++                             temp == STREAM_REJECTED ? "(REJECTED)" : "",
++                             TRB_TO_DEV_STREAM(field0),
++                             field3 & TRB_STAT ? 'S' : 's',
++                             field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       default:
+-              ret += snprintf(str, size,
+-                              "type '%s' -> raw %08x %08x %08x %08x",
+-                              cdnsp_trb_type_string(type),
+-                              field0, field1, field2, field3);
++              ret = snprintf(str, size,
++                             "type '%s' -> raw %08x %08x %08x %08x",
++                             cdnsp_trb_type_string(type),
++                             field0, field1, field2, field3);
+       }
++      if (ret >= size)
++              pr_info("CDNSP: buffer overflowed.\n");
++
+       return str;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.17/usb-dwc3-omap-fix-unbalanced-disables-for-smps10_out.patch b/queue-5.17/usb-dwc3-omap-fix-unbalanced-disables-for-smps10_out.patch
new file mode 100644 (file)
index 0000000..f7ad794
--- /dev/null
@@ -0,0 +1,75 @@
+From 1705a4c937053a5544cda8889c09c2d328acdf1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Mar 2022 14:03:37 +0100
+Subject: usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on
+ omap5evm
+
+From: H. Nikolaus Schaller <hns@goldelico.com>
+
+[ Upstream commit ac01df343e5a6c6bcead2ed421af1fde30f73e7e ]
+
+Usually, the vbus_regulator (smps10 on omap5evm) boots up disabled.
+
+Hence calling regulator_disable() indirectly through dwc3_omap_set_mailbox()
+during probe leads to:
+
+[   10.332764] WARNING: CPU: 0 PID: 1628 at drivers/regulator/core.c:2853 _regulator_disable+0x40/0x164
+[   10.351919] unbalanced disables for smps10_out1
+[   10.361298] Modules linked in: dwc3_omap(+) clk_twl6040 at24 gpio_twl6040 palmas_gpadc palmas_pwrbutton
+industrialio snd_soc_omap_mcbsp(+) snd_soc_ti_sdma display_connector ti_tpd12s015 drm leds_gpio
+drm_panel_orientation_quirks ip_tables x_tables ipv6 autofs4
+[   10.387818] CPU: 0 PID: 1628 Comm: systemd-udevd Not tainted 5.17.0-rc1-letux-lpae+ #8139
+[   10.405129] Hardware name: Generic OMAP5 (Flattened Device Tree)
+[   10.411455]  unwind_backtrace from show_stack+0x10/0x14
+[   10.416970]  show_stack from dump_stack_lvl+0x40/0x4c
+[   10.422313]  dump_stack_lvl from __warn+0xb8/0x170
+[   10.427377]  __warn from warn_slowpath_fmt+0x70/0x9c
+[   10.432595]  warn_slowpath_fmt from _regulator_disable+0x40/0x164
+[   10.439037]  _regulator_disable from regulator_disable+0x30/0x64
+[   10.445382]  regulator_disable from dwc3_omap_set_mailbox+0x8c/0xf0 [dwc3_omap]
+[   10.453116]  dwc3_omap_set_mailbox [dwc3_omap] from dwc3_omap_probe+0x2b8/0x394 [dwc3_omap]
+[   10.467021]  dwc3_omap_probe [dwc3_omap] from platform_probe+0x58/0xa8
+[   10.481762]  platform_probe from really_probe+0x168/0x2fc
+[   10.481782]  really_probe from __driver_probe_device+0xc4/0xd8
+[   10.481782]  __driver_probe_device from driver_probe_device+0x24/0xa4
+[   10.503762]  driver_probe_device from __driver_attach+0xc4/0xd8
+[   10.510018]  __driver_attach from bus_for_each_dev+0x64/0xa0
+[   10.516001]  bus_for_each_dev from bus_add_driver+0x148/0x1a4
+[   10.524880]  bus_add_driver from driver_register+0xb4/0xf8
+[   10.530678]  driver_register from do_one_initcall+0x90/0x1c4
+[   10.536661]  do_one_initcall from do_init_module+0x4c/0x200
+[   10.536683]  do_init_module from load_module+0x13dc/0x1910
+[   10.551159]  load_module from sys_finit_module+0xc8/0xd8
+[   10.561319]  sys_finit_module from __sys_trace_return+0x0/0x18
+[   10.561336] Exception stack(0xc344bfa8 to 0xc344bff0)
+[   10.561341] bfa0:                   b6fb5778 b6fab8d8 00000007 b6ecfbb8 00000000 b6ed0398
+[   10.561341] bfc0: b6fb5778 b6fab8d8 855c0500 0000017b 00020000 b6f9a3cc 00000000 b6fb5778
+[   10.595500] bfe0: bede18f8 bede18e8 b6ec9aeb b6dda1c2
+[   10.601345] ---[ end trace 0000000000000000 ]---
+
+Fix this unnecessary warning by checking if the regulator is enabled.
+
+Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
+Link: https://lore.kernel.org/r/af3b750dc2265d875deaabcf5f80098c9645da45.1646744616.git.hns@goldelico.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/dwc3-omap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
+index e196673f5c64..efaf0db595f4 100644
+--- a/drivers/usb/dwc3/dwc3-omap.c
++++ b/drivers/usb/dwc3/dwc3-omap.c
+@@ -242,7 +242,7 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
+               break;
+       case OMAP_DWC3_ID_FLOAT:
+-              if (omap->vbus_reg)
++              if (omap->vbus_reg && regulator_is_enabled(omap->vbus_reg))
+                       regulator_disable(omap->vbus_reg);
+               val = dwc3_omap_read_utmi_ctrl(omap);
+               val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG;
+-- 
+2.35.1
+
diff --git a/queue-5.17/usb-dwc3-pci-set-the-swnode-from-inside-dwc3_pci_qui.patch b/queue-5.17/usb-dwc3-pci-set-the-swnode-from-inside-dwc3_pci_qui.patch
new file mode 100644 (file)
index 0000000..23710d7
--- /dev/null
@@ -0,0 +1,61 @@
+From 551fdc597ab5b8fb782957b0b8b37cba1ffd75c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Feb 2022 14:05:18 +0100
+Subject: usb: dwc3: pci: Set the swnode from inside dwc3_pci_quirks()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit e285cb403994419e997749c9a52b9370884ae0c8 ]
+
+The quirk handling may need to set some different properties
+which means using a different swnode, move the setting of the swnode
+to inside dwc3_pci_quirks() so that the quirk handling can choose
+a different swnode.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20220213130524.18748-4-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/dwc3-pci.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
+index 06d0e88ec8af..4d9608cc55f7 100644
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -185,7 +185,8 @@ static const struct software_node dwc3_pci_amd_mr_swnode = {
+       .properties = dwc3_pci_mr_properties,
+ };
+-static int dwc3_pci_quirks(struct dwc3_pci *dwc)
++static int dwc3_pci_quirks(struct dwc3_pci *dwc,
++                         const struct software_node *swnode)
+ {
+       struct pci_dev                  *pdev = dwc->pci;
+@@ -242,7 +243,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc)
+               }
+       }
+-      return 0;
++      return device_add_software_node(&dwc->dwc3->dev, swnode);
+ }
+ #ifdef CONFIG_PM
+@@ -307,11 +308,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+       dwc->dwc3->dev.parent = dev;
+       ACPI_COMPANION_SET(&dwc->dwc3->dev, ACPI_COMPANION(dev));
+-      ret = device_add_software_node(&dwc->dwc3->dev, (void *)id->driver_data);
+-      if (ret < 0)
+-              goto err;
+-
+-      ret = dwc3_pci_quirks(dwc);
++      ret = dwc3_pci_quirks(dwc, (void *)id->driver_data);
+       if (ret)
+               goto err;
+-- 
+2.35.1
+
diff --git a/queue-5.17/usb-ehci-add-pci-device-support-for-aspeed-platforms.patch b/queue-5.17/usb-ehci-add-pci-device-support-for-aspeed-platforms.patch
new file mode 100644 (file)
index 0000000..585c149
--- /dev/null
@@ -0,0 +1,52 @@
+From 9150a74448bf9a320fcd67e3b3d1bc0123912492 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Feb 2022 18:16:57 +0800
+Subject: usb: ehci: add pci device support for Aspeed platforms
+
+From: Neal Liu <neal_liu@aspeedtech.com>
+
+[ Upstream commit c3c9cee592828528fd228b01d312c7526c584a42 ]
+
+Enable Aspeed quirks in commit 7f2d73788d90 ("usb: ehci:
+handshake CMD_RUN instead of STS_HALT") to support Aspeed
+ehci-pci device.
+
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Neal Liu <neal_liu@aspeedtech.com>
+Link: https://lore.kernel.org/r/20220208101657.76459-1-neal_liu@aspeedtech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/ehci-pci.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
+index e87cf3a00fa4..638f03b89739 100644
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -21,6 +21,9 @@ static const char hcd_name[] = "ehci-pci";
+ /* defined here to avoid adding to pci_ids.h for single instance use */
+ #define PCI_DEVICE_ID_INTEL_CE4100_USB        0x2e70
++#define PCI_VENDOR_ID_ASPEED          0x1a03
++#define PCI_DEVICE_ID_ASPEED_EHCI     0x2603
++
+ /*-------------------------------------------------------------------------*/
+ #define PCI_DEVICE_ID_INTEL_QUARK_X1000_SOC           0x0939
+ static inline bool is_intel_quark_x1000(struct pci_dev *pdev)
+@@ -222,6 +225,12 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
+                       ehci->has_synopsys_hc_bug = 1;
+               }
+               break;
++      case PCI_VENDOR_ID_ASPEED:
++              if (pdev->device == PCI_DEVICE_ID_ASPEED_EHCI) {
++                      ehci_info(ehci, "applying Aspeed HC workaround\n");
++                      ehci->is_aspeed = 1;
++              }
++              break;
+       }
+       /* optional debug port, normally in the first BAR */
+-- 
+2.35.1
+
diff --git a/queue-5.17/usb-gadget-tegra-xudc-do-not-program-sparam.patch b/queue-5.17/usb-gadget-tegra-xudc-do-not-program-sparam.patch
new file mode 100644 (file)
index 0000000..4ea7cc7
--- /dev/null
@@ -0,0 +1,52 @@
+From 8f20f3d7cefac9d1652bf1353c4a31f43306e9c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jan 2022 17:04:43 +0800
+Subject: usb: gadget: tegra-xudc: Do not program SPARAM
+
+From: Wayne Chang <waynec@nvidia.com>
+
+[ Upstream commit 62fb61580eb48fc890b7bc9fb5fd263367baeca8 ]
+
+According to the Tegra Technical Reference Manual, SPARAM
+is a read-only register and should not be programmed in
+the driver.
+
+The change removes the wrong SPARAM usage.
+
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Link: https://lore.kernel.org/r/20220107090443.149021-1-waynec@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/tegra-xudc.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index 43f1b0d461c1..716d9ab2d2ff 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -32,9 +32,6 @@
+ #include <linux/workqueue.h>
+ /* XUSB_DEV registers */
+-#define SPARAM 0x000
+-#define  SPARAM_ERSTMAX_MASK GENMASK(20, 16)
+-#define  SPARAM_ERSTMAX(x) (((x) << 16) & SPARAM_ERSTMAX_MASK)
+ #define DB 0x004
+ #define  DB_TARGET_MASK GENMASK(15, 8)
+ #define  DB_TARGET(x) (((x) << 8) & DB_TARGET_MASK)
+@@ -3295,11 +3292,6 @@ static void tegra_xudc_init_event_ring(struct tegra_xudc *xudc)
+       unsigned int i;
+       u32 val;
+-      val = xudc_readl(xudc, SPARAM);
+-      val &= ~(SPARAM_ERSTMAX_MASK);
+-      val |= SPARAM_ERSTMAX(XUDC_NR_EVENT_RINGS);
+-      xudc_writel(xudc, val, SPARAM);
+-
+       for (i = 0; i < ARRAY_SIZE(xudc->event_ring); i++) {
+               memset(xudc->event_ring[i], 0, XUDC_EVENT_RING_SIZE *
+                      sizeof(*xudc->event_ring[i]));
+-- 
+2.35.1
+
diff --git a/queue-5.17/usb-gadget-tegra-xudc-fix-control-endpoint-s-definit.patch b/queue-5.17/usb-gadget-tegra-xudc-fix-control-endpoint-s-definit.patch
new file mode 100644 (file)
index 0000000..eea6ad7
--- /dev/null
@@ -0,0 +1,64 @@
+From 4b12e526edb0ff7c572b4f31323e4f1ee595ce9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jan 2022 17:13:49 +0800
+Subject: usb: gadget: tegra-xudc: Fix control endpoint's definitions
+
+From: Wayne Chang <waynec@nvidia.com>
+
+[ Upstream commit 7bd42fb95eb4f98495ccadf467ad15124208ec49 ]
+
+According to the Tegra Technical Reference Manual, the seq_num
+field of control endpoint is not [31:24] but [31:27]. Bit 24
+is reserved and bit 26 is splitxstate.
+
+The change fixes the wrong control endpoint's definitions.
+
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Link: https://lore.kernel.org/r/20220107091349.149798-1-waynec@nvidia.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 | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index 716d9ab2d2ff..be76f891b9c5 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -272,8 +272,10 @@ BUILD_EP_CONTEXT_RW(deq_hi, deq_hi, 0, 0xffffffff)
+ BUILD_EP_CONTEXT_RW(avg_trb_len, tx_info, 0, 0xffff)
+ BUILD_EP_CONTEXT_RW(max_esit_payload, tx_info, 16, 0xffff)
+ BUILD_EP_CONTEXT_RW(edtla, rsvd[0], 0, 0xffffff)
+-BUILD_EP_CONTEXT_RW(seq_num, rsvd[0], 24, 0xff)
++BUILD_EP_CONTEXT_RW(rsvd, rsvd[0], 24, 0x1)
+ BUILD_EP_CONTEXT_RW(partial_td, rsvd[0], 25, 0x1)
++BUILD_EP_CONTEXT_RW(splitxstate, rsvd[0], 26, 0x1)
++BUILD_EP_CONTEXT_RW(seq_num, rsvd[0], 27, 0x1f)
+ BUILD_EP_CONTEXT_RW(cerrcnt, rsvd[1], 18, 0x3)
+ BUILD_EP_CONTEXT_RW(data_offset, rsvd[2], 0, 0x1ffff)
+ BUILD_EP_CONTEXT_RW(numtrbs, rsvd[2], 22, 0x1f)
+@@ -1554,6 +1556,9 @@ static int __tegra_xudc_ep_set_halt(struct tegra_xudc_ep *ep, bool halt)
+               ep_reload(xudc, ep->index);
+               ep_ctx_write_state(ep->context, EP_STATE_RUNNING);
++              ep_ctx_write_rsvd(ep->context, 0);
++              ep_ctx_write_partial_td(ep->context, 0);
++              ep_ctx_write_splitxstate(ep->context, 0);
+               ep_ctx_write_seq_num(ep->context, 0);
+               ep_reload(xudc, ep->index);
+@@ -2809,7 +2814,10 @@ static void tegra_xudc_reset(struct tegra_xudc *xudc)
+       xudc->setup_seq_num = 0;
+       xudc->queued_setup_packet = false;
+-      ep_ctx_write_seq_num(ep0->context, xudc->setup_seq_num);
++      ep_ctx_write_rsvd(ep0->context, 0);
++      ep_ctx_write_partial_td(ep0->context, 0);
++      ep_ctx_write_splitxstate(ep0->context, 0);
++      ep_ctx_write_seq_num(ep0->context, 0);
+       deq_ptr = trb_virt_to_phys(ep0, &ep0->transfer_ring[ep0->deq_ptr]);
+-- 
+2.35.1
+
diff --git a/queue-5.17/vfio-pci-stub-vfio_pci_vga_rw-when-config_vfio_pci_v.patch b/queue-5.17/vfio-pci-stub-vfio_pci_vga_rw-when-config_vfio_pci_v.patch
new file mode 100644 (file)
index 0000000..bb74c56
--- /dev/null
@@ -0,0 +1,69 @@
+From 80ddf12f3a030bc286408a3964eeb0f015b3798d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jan 2022 16:11:37 -0700
+Subject: vfio/pci: Stub vfio_pci_vga_rw when !CONFIG_VFIO_PCI_VGA
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+[ Upstream commit 6e031ec0e5a2dda53e12e0d2a7e9b15b47a3c502 ]
+
+Resolve build errors reported against UML build for undefined
+ioport_map() and ioport_unmap() functions.  Without this config
+option a device cannot have vfio_pci_core_device.has_vga set,
+so the existing function would always return -EINVAL anyway.
+
+Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/r/20220123125737.2658758-1-geert@linux-m68k.org
+Link: https://lore.kernel.org/r/164306582968.3758255.15192949639574660648.stgit@omen
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/vfio_pci_rdwr.c | 2 ++
+ include/linux/vfio_pci_core.h    | 9 +++++++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
+index 57d3b2cbbd8e..82ac1569deb0 100644
+--- a/drivers/vfio/pci/vfio_pci_rdwr.c
++++ b/drivers/vfio/pci/vfio_pci_rdwr.c
+@@ -288,6 +288,7 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
+       return done;
+ }
++#ifdef CONFIG_VFIO_PCI_VGA
+ ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
+                              size_t count, loff_t *ppos, bool iswrite)
+ {
+@@ -355,6 +356,7 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
+       return done;
+ }
++#endif
+ static void vfio_pci_ioeventfd_do_write(struct vfio_pci_ioeventfd *ioeventfd,
+                                       bool test_mem)
+diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
+index ef9a44b6cf5d..ae6f4838ab75 100644
+--- a/include/linux/vfio_pci_core.h
++++ b/include/linux/vfio_pci_core.h
+@@ -159,8 +159,17 @@ extern ssize_t vfio_pci_config_rw(struct vfio_pci_core_device *vdev,
+ extern ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
+                              size_t count, loff_t *ppos, bool iswrite);
++#ifdef CONFIG_VFIO_PCI_VGA
+ extern ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
+                              size_t count, loff_t *ppos, bool iswrite);
++#else
++static inline ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev,
++                                    char __user *buf, size_t count,
++                                    loff_t *ppos, bool iswrite)
++{
++      return -EINVAL;
++}
++#endif
+ extern long vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
+                              uint64_t data, int count, int fd);
+-- 
+2.35.1
+
diff --git a/queue-5.17/virtio_console-eliminate-anonymous-module_init-modul.patch b/queue-5.17/virtio_console-eliminate-anonymous-module_init-modul.patch
new file mode 100644 (file)
index 0000000..c134496
--- /dev/null
@@ -0,0 +1,76 @@
+From 548af703e0d6ff1ec0ed0792056d3f5aa93fd662 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Mar 2022 12:20:03 -0700
+Subject: virtio_console: eliminate anonymous module_init & module_exit
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit fefb8a2a941338d871e2d83fbd65fbfa068857bd ]
+
+Eliminate anonymous module_init() and module_exit(), which can lead to
+confusion or ambiguity when reading System.map, crashes/oops/bugs,
+or an initcall_debug log.
+
+Give each of these init and exit functions unique driver-specific
+names to eliminate the anonymous names.
+
+Example 1: (System.map)
+ ffffffff832fc78c t init
+ ffffffff832fc79e t init
+ ffffffff832fc8f8 t init
+
+Example 2: (initcall_debug log)
+ calling  init+0x0/0x12 @ 1
+ initcall init+0x0/0x12 returned 0 after 15 usecs
+ calling  init+0x0/0x60 @ 1
+ initcall init+0x0/0x60 returned 0 after 2 usecs
+ calling  init+0x0/0x9a @ 1
+ initcall init+0x0/0x9a returned 0 after 74 usecs
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reviewed-by: Amit Shah <amit@kernel.org>
+Cc: virtualization@lists.linux-foundation.org
+Cc: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20220316192010.19001-3-rdunlap@infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/virtio_console.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index e3c430539a17..9fa3c76a267f 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -2245,7 +2245,7 @@ static struct virtio_driver virtio_rproc_serial = {
+       .remove =       virtcons_remove,
+ };
+-static int __init init(void)
++static int __init virtio_console_init(void)
+ {
+       int err;
+@@ -2280,7 +2280,7 @@ static int __init init(void)
+       return err;
+ }
+-static void __exit fini(void)
++static void __exit virtio_console_fini(void)
+ {
+       reclaim_dma_bufs();
+@@ -2290,8 +2290,8 @@ static void __exit fini(void)
+       class_destroy(pdrvdata.class);
+       debugfs_remove_recursive(pdrvdata.debugfs_dir);
+ }
+-module_init(init);
+-module_exit(fini);
++module_init(virtio_console_init);
++module_exit(virtio_console_fini);
+ MODULE_DESCRIPTION("Virtio console driver");
+ MODULE_LICENSE("GPL");
+-- 
+2.35.1
+
diff --git a/queue-5.17/w1-w1_therm-fixes-w1_seq-for-ds28ea00-sensors.patch b/queue-5.17/w1-w1_therm-fixes-w1_seq-for-ds28ea00-sensors.patch
new file mode 100644 (file)
index 0000000..442bef4
--- /dev/null
@@ -0,0 +1,52 @@
+From c23caa464141d4d2585a0dac98404ebdf61df8a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 11:35:55 +0000
+Subject: w1: w1_therm: fixes w1_seq for ds28ea00 sensors
+
+From: Lucas Denefle <lucas.denefle@converge.io>
+
+[ Upstream commit 41a92a89eee819298f805c40187ad8b02bb53426 ]
+
+w1_seq was failing due to several devices responding to the
+CHAIN_DONE at the same time. Now properly selects the current
+device in the chain with MATCH_ROM. Also acknowledgment was
+read twice.
+
+Signed-off-by: Lucas Denefle <lucas.denefle@converge.io>
+Link: https://lore.kernel.org/r/20220223113558.232750-1-lucas.denefle@converge.io
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/w1/slaves/w1_therm.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
+index 565578002d79..c7b8a8e787e2 100644
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -2089,16 +2089,20 @@ static ssize_t w1_seq_show(struct device *device,
+               if (sl->reg_num.id == reg_num->id)
+                       seq = i;
++              if (w1_reset_bus(sl->master))
++                      goto error;
++
++              /* Put the device into chain DONE state */
++              w1_write_8(sl->master, W1_MATCH_ROM);
++              w1_write_block(sl->master, (u8 *)&rn, 8);
+               w1_write_8(sl->master, W1_42_CHAIN);
+               w1_write_8(sl->master, W1_42_CHAIN_DONE);
+               w1_write_8(sl->master, W1_42_CHAIN_DONE_INV);
+-              w1_read_block(sl->master, &ack, sizeof(ack));
+               /* check for acknowledgment */
+               ack = w1_read_8(sl->master);
+               if (ack != W1_42_SUCCESS_CONFIRM_BYTE)
+                       goto error;
+-
+       }
+       /* Exit from CHAIN state */
+-- 
+2.35.1
+
diff --git a/queue-5.17/x86-annotate-call_on_stack.patch b/queue-5.17/x86-annotate-call_on_stack.patch
new file mode 100644 (file)
index 0000000..589ff43
--- /dev/null
@@ -0,0 +1,63 @@
+From f619bc26d9bdfdaca9ae33cd10dd1059f16e060c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Mar 2022 16:30:50 +0100
+Subject: x86: Annotate call_on_stack()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit be0075951fde739f14ee2b659e2fd6e2499c46c0 ]
+
+vmlinux.o: warning: objtool: page_fault_oops()+0x13c: unreachable instruction
+
+0000 000000000005b460 <page_fault_oops>:
+...
+0128    5b588:  49 89 23                mov    %rsp,(%r11)
+012b    5b58b:  4c 89 dc                mov    %r11,%rsp
+012e    5b58e:  4c 89 f2                mov    %r14,%rdx
+0131    5b591:  48 89 ee                mov    %rbp,%rsi
+0134    5b594:  4c 89 e7                mov    %r12,%rdi
+0137    5b597:  e8 00 00 00 00          call   5b59c <page_fault_oops+0x13c>    5b598: R_X86_64_PLT32   handle_stack_overflow-0x4
+013c    5b59c:  5c                      pop    %rsp
+
+vmlinux.o: warning: objtool: sysvec_reboot()+0x6d: unreachable instruction
+
+0000 00000000000033f0 <sysvec_reboot>:
+...
+005d     344d:  4c 89 dc                mov    %r11,%rsp
+0060     3450:  e8 00 00 00 00          call   3455 <sysvec_reboot+0x65>        3451: R_X86_64_PLT32    irq_enter_rcu-0x4
+0065     3455:  48 89 ef                mov    %rbp,%rdi
+0068     3458:  e8 00 00 00 00          call   345d <sysvec_reboot+0x6d>        3459: R_X86_64_PC32     .text+0x47d0c
+006d     345d:  e8 00 00 00 00          call   3462 <sysvec_reboot+0x72>        345e: R_X86_64_PLT32    irq_exit_rcu-0x4
+0072     3462:  5c                      pop    %rsp
+
+Both cases are due to a call_on_stack() calling a __noreturn function.
+Since that's an inline asm, GCC can't do anything about the
+instructions after the CALL. Therefore put in an explicit
+ASM_REACHABLE annotation to make sure objtool and gcc are consistently
+confused about control flow.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/r/20220308154319.468805622@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/irq_stack.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h
+index ae9d40f6c706..05af249d6bec 100644
+--- a/arch/x86/include/asm/irq_stack.h
++++ b/arch/x86/include/asm/irq_stack.h
+@@ -99,7 +99,8 @@
+ }
+ #define ASM_CALL_ARG0                                                 \
+-      "call %P[__func]                                \n"
++      "call %P[__func]                                \n"             \
++      ASM_REACHABLE
+ #define ASM_CALL_ARG1                                                 \
+       "movq   %[arg1], %%rdi                          \n"             \
+-- 
+2.35.1
+
diff --git a/queue-5.17/x86-kconfig-do-not-allow-config_x86_x32_abi-y-with-l.patch b/queue-5.17/x86-kconfig-do-not-allow-config_x86_x32_abi-y-with-l.patch
new file mode 100644 (file)
index 0000000..a2b7612
--- /dev/null
@@ -0,0 +1,61 @@
+From 68ef98c12b106ef5bec3a2f5d4c2a24c7593034e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Mar 2022 12:48:42 -0700
+Subject: x86/Kconfig: Do not allow CONFIG_X86_X32_ABI=y with llvm-objcopy
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit aaeed6ecc1253ce1463fa1aca0b70a4ccbc9fa75 ]
+
+There are two outstanding issues with CONFIG_X86_X32_ABI and
+llvm-objcopy, with similar root causes:
+
+1. llvm-objcopy does not properly convert .note.gnu.property when going
+   from x86_64 to x86_x32, resulting in a corrupted section when
+   linking:
+
+   https://github.com/ClangBuiltLinux/linux/issues/1141
+
+2. llvm-objcopy produces corrupted compressed debug sections when going
+   from x86_64 to x86_x32, also resulting in an error when linking:
+
+   https://github.com/ClangBuiltLinux/linux/issues/514
+
+After commit 41c5ef31ad71 ("x86/ibt: Base IBT bits"), the
+.note.gnu.property section is always generated when
+CONFIG_X86_KERNEL_IBT is enabled, which causes the first issue to become
+visible with an allmodconfig build:
+
+  ld.lld: error: arch/x86/entry/vdso/vclock_gettime-x32.o:(.note.gnu.property+0x1c): program property is too short
+
+To avoid this error, do not allow CONFIG_X86_X32_ABI to be selected when
+using llvm-objcopy. If the two issues ever get fixed in llvm-objcopy,
+this can be turned into a feature check.
+
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20220314194842.3452-3-nathan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/Kconfig | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 9f5bd41bf660..d0ecc4005df3 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -2837,6 +2837,11 @@ config IA32_AOUT
+ config X86_X32
+       bool "x32 ABI for 64-bit mode"
+       depends on X86_64
++      # llvm-objcopy does not convert x86_64 .note.gnu.property or
++      # compressed debug sections to x86_x32 properly:
++      # https://github.com/ClangBuiltLinux/linux/issues/514
++      # https://github.com/ClangBuiltLinux/linux/issues/1141
++      depends on $(success,$(OBJCOPY) --version | head -n1 | grep -qv llvm)
+       help
+         Include code to run binaries for the x32 native 32-bit ABI
+         for 64-bit processors.  An x32 process gets access to the
+-- 
+2.35.1
+
diff --git a/queue-5.17/x86-mce-work-around-an-erratum-on-fast-string-copy-i.patch b/queue-5.17/x86-mce-work-around-an-erratum-on-fast-string-copy-i.patch
new file mode 100644 (file)
index 0000000..359f693
--- /dev/null
@@ -0,0 +1,189 @@
+From 9a9bdb45fad5ee1e8961e4b7de1b6ecfb3aa0b9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 17:32:09 -0800
+Subject: x86/mce: Work around an erratum on fast string copy instructions
+
+From: Jue Wang <juew@google.com>
+
+[ Upstream commit 8ca97812c3c830573f965a07bbd84223e8c5f5bd ]
+
+A rare kernel panic scenario can happen when the following conditions
+are met due to an erratum on fast string copy instructions:
+
+1) An uncorrected error.
+2) That error must be in first cache line of a page.
+3) Kernel must execute page_copy from the page immediately before that
+page.
+
+The fast string copy instructions ("REP; MOVS*") could consume an
+uncorrectable memory error in the cache line _right after_ the desired
+region to copy and raise an MCE.
+
+Bit 0 of MSR_IA32_MISC_ENABLE can be cleared to disable fast string
+copy and will avoid such spurious machine checks. However, that is less
+preferable due to the permanent performance impact. Considering memory
+poison is rare, it's desirable to keep fast string copy enabled until an
+MCE is seen.
+
+Intel has confirmed the following:
+1. The CPU erratum of fast string copy only applies to Skylake,
+Cascade Lake and Cooper Lake generations.
+
+Directly return from the MCE handler:
+2. Will result in complete execution of the "REP; MOVS*" with no data
+loss or corruption.
+3. Will not result in another MCE firing on the next poisoned cache line
+due to "REP; MOVS*".
+4. Will resume execution from a correct point in code.
+5. Will result in the same instruction that triggered the MCE firing a
+second MCE immediately for any other software recoverable data fetch
+errors.
+6. Is not safe without disabling the fast string copy, as the next fast
+string copy of the same buffer on the same CPU would result in a PANIC
+MCE.
+
+This should mitigate the erratum completely with the only caveat that
+the fast string copy is disabled on the affected hyper thread thus
+performance degradation.
+
+This is still better than the OS crashing on MCEs raised on an
+irrelevant process due to "REP; MOVS*' accesses in a kernel context,
+e.g., copy_page.
+
+Tested:
+
+Injected errors on 1st cache line of 8 anonymous pages of process
+'proc1' and observed MCE consumption from 'proc2' with no panic
+(directly returned).
+
+Without the fix, the host panicked within a few minutes on a
+random 'proc2' process due to kernel access from copy_page.
+
+  [ bp: Fix comment style + touch ups, zap an unlikely(), improve the
+    quirk function's readability. ]
+
+Signed-off-by: Jue Wang <juew@google.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20220218013209.2436006-1-juew@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/mce/core.c     | 64 ++++++++++++++++++++++++++++++
+ arch/x86/kernel/cpu/mce/internal.h |  5 ++-
+ 2 files changed, 68 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
+index 5818b837fd4d..2d719e0d2e40 100644
+--- a/arch/x86/kernel/cpu/mce/core.c
++++ b/arch/x86/kernel/cpu/mce/core.c
+@@ -834,6 +834,59 @@ static void quirk_sandybridge_ifu(int bank, struct mce *m, struct pt_regs *regs)
+       m->cs = regs->cs;
+ }
++/*
++ * Disable fast string copy and return from the MCE handler upon the first SRAR
++ * MCE on bank 1 due to a CPU erratum on Intel Skylake/Cascade Lake/Cooper Lake
++ * CPUs.
++ * The fast string copy instructions ("REP; MOVS*") could consume an
++ * uncorrectable memory error in the cache line _right after_ the desired region
++ * to copy and raise an MCE with RIP pointing to the instruction _after_ the
++ * "REP; MOVS*".
++ * This mitigation addresses the issue completely with the caveat of performance
++ * degradation on the CPU affected. This is still better than the OS crashing on
++ * MCEs raised on an irrelevant process due to "REP; MOVS*" accesses from a
++ * kernel context (e.g., copy_page).
++ *
++ * Returns true when fast string copy on CPU has been disabled.
++ */
++static noinstr bool quirk_skylake_repmov(void)
++{
++      u64 mcgstatus   = mce_rdmsrl(MSR_IA32_MCG_STATUS);
++      u64 misc_enable = mce_rdmsrl(MSR_IA32_MISC_ENABLE);
++      u64 mc1_status;
++
++      /*
++       * Apply the quirk only to local machine checks, i.e., no broadcast
++       * sync is needed.
++       */
++      if (!(mcgstatus & MCG_STATUS_LMCES) ||
++          !(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING))
++              return false;
++
++      mc1_status = mce_rdmsrl(MSR_IA32_MCx_STATUS(1));
++
++      /* Check for a software-recoverable data fetch error. */
++      if ((mc1_status &
++           (MCI_STATUS_VAL | MCI_STATUS_OVER | MCI_STATUS_UC | MCI_STATUS_EN |
++            MCI_STATUS_ADDRV | MCI_STATUS_MISCV | MCI_STATUS_PCC |
++            MCI_STATUS_AR | MCI_STATUS_S)) ==
++           (MCI_STATUS_VAL |                   MCI_STATUS_UC | MCI_STATUS_EN |
++            MCI_STATUS_ADDRV | MCI_STATUS_MISCV |
++            MCI_STATUS_AR | MCI_STATUS_S)) {
++              misc_enable &= ~MSR_IA32_MISC_ENABLE_FAST_STRING;
++              mce_wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
++              mce_wrmsrl(MSR_IA32_MCx_STATUS(1), 0);
++
++              instrumentation_begin();
++              pr_err_once("Erratum detected, disable fast string copy instructions.\n");
++              instrumentation_end();
++
++              return true;
++      }
++
++      return false;
++}
++
+ /*
+  * Do a quick check if any of the events requires a panic.
+  * This decides if we keep the events around or clear them.
+@@ -1403,6 +1456,9 @@ noinstr void do_machine_check(struct pt_regs *regs)
+       else if (unlikely(!mca_cfg.initialized))
+               return unexpected_machine_check(regs);
++      if (mce_flags.skx_repmov_quirk && quirk_skylake_repmov())
++              goto clear;
++
+       /*
+        * Establish sequential order between the CPUs entering the machine
+        * check handler.
+@@ -1545,6 +1601,7 @@ noinstr void do_machine_check(struct pt_regs *regs)
+ out:
+       instrumentation_end();
++clear:
+       mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);
+ }
+ EXPORT_SYMBOL_GPL(do_machine_check);
+@@ -1858,6 +1915,13 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
+               if (c->x86 == 6 && c->x86_model == 45)
+                       mce_flags.snb_ifu_quirk = 1;
++
++              /*
++               * Skylake, Cascacde Lake and Cooper Lake require a quirk on
++               * rep movs.
++               */
++              if (c->x86 == 6 && c->x86_model == INTEL_FAM6_SKYLAKE_X)
++                      mce_flags.skx_repmov_quirk = 1;
+       }
+       if (c->x86_vendor == X86_VENDOR_ZHAOXIN) {
+diff --git a/arch/x86/kernel/cpu/mce/internal.h b/arch/x86/kernel/cpu/mce/internal.h
+index 52c633950b38..24d099e2d2a2 100644
+--- a/arch/x86/kernel/cpu/mce/internal.h
++++ b/arch/x86/kernel/cpu/mce/internal.h
+@@ -170,7 +170,10 @@ struct mce_vendor_flags {
+       /* SandyBridge IFU quirk */
+       snb_ifu_quirk           : 1,
+-      __reserved_0            : 57;
++      /* Skylake, Cascade Lake, Cooper Lake REP;MOVS* quirk */
++      skx_repmov_quirk        : 1,
++
++      __reserved_0            : 56;
+ };
+ extern struct mce_vendor_flags mce_flags;
+-- 
+2.35.1
+
diff --git a/queue-5.17/xen-delay-xen_hvm_init_time_ops-if-kdump-is-boot-on-.patch b/queue-5.17/xen-delay-xen_hvm_init_time_ops-if-kdump-is-boot-on-.patch
new file mode 100644 (file)
index 0000000..f99aabc
--- /dev/null
@@ -0,0 +1,124 @@
+From d28ee8cf4abb0e35f428244699a1f778265169d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 08:40:32 -0800
+Subject: xen: delay xen_hvm_init_time_ops() if kdump is boot on vcpu>=32
+
+From: Dongli Zhang <dongli.zhang@oracle.com>
+
+[ Upstream commit eed05744322da07dd7e419432dcedf3c2e017179 ]
+
+The sched_clock() can be used very early since commit 857baa87b642
+("sched/clock: Enable sched clock early"). In addition, with commit
+38669ba205d1 ("x86/xen/time: Output xen sched_clock time from 0"), kdump
+kernel in Xen HVM guest may panic at very early stage when accessing
+&__this_cpu_read(xen_vcpu)->time as in below:
+
+setup_arch()
+ -> init_hypervisor_platform()
+     -> x86_init.hyper.init_platform = xen_hvm_guest_init()
+         -> xen_hvm_init_time_ops()
+             -> xen_clocksource_read()
+                 -> src = &__this_cpu_read(xen_vcpu)->time;
+
+This is because Xen HVM supports at most MAX_VIRT_CPUS=32 'vcpu_info'
+embedded inside 'shared_info' during early stage until xen_vcpu_setup() is
+used to allocate/relocate 'vcpu_info' for boot cpu at arbitrary address.
+
+However, when Xen HVM guest panic on vcpu >= 32, since
+xen_vcpu_info_reset(0) would set per_cpu(xen_vcpu, cpu) = NULL when
+vcpu >= 32, xen_clocksource_read() on vcpu >= 32 would panic.
+
+This patch calls xen_hvm_init_time_ops() again later in
+xen_hvm_smp_prepare_boot_cpu() after the 'vcpu_info' for boot vcpu is
+registered when the boot vcpu is >= 32.
+
+This issue can be reproduced on purpose via below command at the guest
+side when kdump/kexec is enabled:
+
+"taskset -c 33 echo c > /proc/sysrq-trigger"
+
+The bugfix for PVM is not implemented due to the lack of testing
+environment.
+
+[boris: xen_hvm_init_time_ops() returns on errors instead of jumping to end]
+
+Cc: Joe Jin <joe.jin@oracle.com>
+Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Link: https://lore.kernel.org/r/20220302164032.14569-3-dongli.zhang@oracle.com
+Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/smp_hvm.c |  6 ++++++
+ arch/x86/xen/time.c    | 24 +++++++++++++++++++++++-
+ 2 files changed, 29 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/xen/smp_hvm.c b/arch/x86/xen/smp_hvm.c
+index 6ff3c887e0b9..b70afdff419c 100644
+--- a/arch/x86/xen/smp_hvm.c
++++ b/arch/x86/xen/smp_hvm.c
+@@ -19,6 +19,12 @@ static void __init xen_hvm_smp_prepare_boot_cpu(void)
+        */
+       xen_vcpu_setup(0);
++      /*
++       * Called again in case the kernel boots on vcpu >= MAX_VIRT_CPUS.
++       * Refer to comments in xen_hvm_init_time_ops().
++       */
++      xen_hvm_init_time_ops();
++
+       /*
+        * The alternative logic (which patches the unlock/lock) runs before
+        * the smp bootup up code is activated. Hence we need to set this up
+diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
+index d9c945ee1100..9ef0a5cca96e 100644
+--- a/arch/x86/xen/time.c
++++ b/arch/x86/xen/time.c
+@@ -558,6 +558,11 @@ static void xen_hvm_setup_cpu_clockevents(void)
+ void __init xen_hvm_init_time_ops(void)
+ {
++      static bool hvm_time_initialized;
++
++      if (hvm_time_initialized)
++              return;
++
+       /*
+        * vector callback is needed otherwise we cannot receive interrupts
+        * on cpu > 0 and at this point we don't know how many cpus are
+@@ -567,7 +572,22 @@ void __init xen_hvm_init_time_ops(void)
+               return;
+       if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
+-              pr_info("Xen doesn't support pvclock on HVM, disable pv timer");
++              pr_info_once("Xen doesn't support pvclock on HVM, disable pv timer");
++              return;
++      }
++
++      /*
++       * Only MAX_VIRT_CPUS 'vcpu_info' are embedded inside 'shared_info'.
++       * The __this_cpu_read(xen_vcpu) is still NULL when Xen HVM guest
++       * boots on vcpu >= MAX_VIRT_CPUS (e.g., kexec), To access
++       * __this_cpu_read(xen_vcpu) via xen_clocksource_read() will panic.
++       *
++       * The xen_hvm_init_time_ops() should be called again later after
++       * __this_cpu_read(xen_vcpu) is available.
++       */
++      if (!__this_cpu_read(xen_vcpu)) {
++              pr_info("Delay xen_init_time_common() as kernel is running on vcpu=%d\n",
++                      xen_vcpu_nr(0));
+               return;
+       }
+@@ -577,6 +597,8 @@ void __init xen_hvm_init_time_ops(void)
+       x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents;
+       x86_platform.set_wallclock = xen_set_wallclock;
++
++      hvm_time_initialized = true;
+ }
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.17/xen-usb-harden-xen_hcd-against-malicious-backends.patch b/queue-5.17/xen-usb-harden-xen_hcd-against-malicious-backends.patch
new file mode 100644 (file)
index 0000000..2639d92
--- /dev/null
@@ -0,0 +1,170 @@
+From 8f1e68c5cb829002be70323da65d406e9fe01eae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Mar 2022 11:35:09 +0100
+Subject: xen/usb: harden xen_hcd against malicious backends
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit aff477cb8f94613f501d386d10f20019e294bc35 ]
+
+Make sure a malicious backend can't cause any harm other than wrong
+I/O data.
+
+Missing are verification of the request id in a response, sanitizing
+the reported actual I/O length, and protection against interrupt storms
+from the backend.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/20220311103509.12908-1-jgross@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xen-hcd.c | 57 ++++++++++++++++++++++++++++----------
+ 1 file changed, 43 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/host/xen-hcd.c b/drivers/usb/host/xen-hcd.c
+index 19b8c7ed74cb..4ed3ee328a4a 100644
+--- a/drivers/usb/host/xen-hcd.c
++++ b/drivers/usb/host/xen-hcd.c
+@@ -51,6 +51,7 @@ struct vdevice_status {
+ struct usb_shadow {
+       struct xenusb_urb_request req;
+       struct urb *urb;
++      bool in_flight;
+ };
+ struct xenhcd_info {
+@@ -722,6 +723,12 @@ static void xenhcd_gnttab_done(struct xenhcd_info *info, unsigned int id)
+       int nr_segs = 0;
+       int i;
++      if (!shadow->in_flight) {
++              xenhcd_set_error(info, "Illegal request id");
++              return;
++      }
++      shadow->in_flight = false;
++
+       nr_segs = shadow->req.nr_buffer_segs;
+       if (xenusb_pipeisoc(shadow->req.pipe))
+@@ -805,6 +812,7 @@ static int xenhcd_do_request(struct xenhcd_info *info, struct urb_priv *urbp)
+       info->urb_ring.req_prod_pvt++;
+       info->shadow[id].urb = urb;
++      info->shadow[id].in_flight = true;
+       RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->urb_ring, notify);
+       if (notify)
+@@ -933,10 +941,27 @@ static int xenhcd_unlink_urb(struct xenhcd_info *info, struct urb_priv *urbp)
+       return ret;
+ }
+-static int xenhcd_urb_request_done(struct xenhcd_info *info)
++static void xenhcd_res_to_urb(struct xenhcd_info *info,
++                            struct xenusb_urb_response *res, struct urb *urb)
++{
++      if (unlikely(!urb))
++              return;
++
++      if (res->actual_length > urb->transfer_buffer_length)
++              urb->actual_length = urb->transfer_buffer_length;
++      else if (res->actual_length < 0)
++              urb->actual_length = 0;
++      else
++              urb->actual_length = res->actual_length;
++      urb->error_count = res->error_count;
++      urb->start_frame = res->start_frame;
++      xenhcd_giveback_urb(info, urb, res->status);
++}
++
++static int xenhcd_urb_request_done(struct xenhcd_info *info,
++                                 unsigned int *eoiflag)
+ {
+       struct xenusb_urb_response res;
+-      struct urb *urb;
+       RING_IDX i, rp;
+       __u16 id;
+       int more_to_do = 0;
+@@ -963,16 +988,12 @@ static int xenhcd_urb_request_done(struct xenhcd_info *info)
+                       xenhcd_gnttab_done(info, id);
+                       if (info->error)
+                               goto err;
+-                      urb = info->shadow[id].urb;
+-                      if (likely(urb)) {
+-                              urb->actual_length = res.actual_length;
+-                              urb->error_count = res.error_count;
+-                              urb->start_frame = res.start_frame;
+-                              xenhcd_giveback_urb(info, urb, res.status);
+-                      }
++                      xenhcd_res_to_urb(info, &res, info->shadow[id].urb);
+               }
+               xenhcd_add_id_to_freelist(info, id);
++
++              *eoiflag = 0;
+       }
+       info->urb_ring.rsp_cons = i;
+@@ -990,7 +1011,7 @@ static int xenhcd_urb_request_done(struct xenhcd_info *info)
+       return 0;
+ }
+-static int xenhcd_conn_notify(struct xenhcd_info *info)
++static int xenhcd_conn_notify(struct xenhcd_info *info, unsigned int *eoiflag)
+ {
+       struct xenusb_conn_response res;
+       struct xenusb_conn_request *req;
+@@ -1035,6 +1056,8 @@ static int xenhcd_conn_notify(struct xenhcd_info *info)
+                                      info->conn_ring.req_prod_pvt);
+               req->id = id;
+               info->conn_ring.req_prod_pvt++;
++
++              *eoiflag = 0;
+       }
+       if (rc != info->conn_ring.req_prod_pvt)
+@@ -1057,14 +1080,19 @@ static int xenhcd_conn_notify(struct xenhcd_info *info)
+ static irqreturn_t xenhcd_int(int irq, void *dev_id)
+ {
+       struct xenhcd_info *info = (struct xenhcd_info *)dev_id;
++      unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
+-      if (unlikely(info->error))
++      if (unlikely(info->error)) {
++              xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
+               return IRQ_HANDLED;
++      }
+-      while (xenhcd_urb_request_done(info) | xenhcd_conn_notify(info))
++      while (xenhcd_urb_request_done(info, &eoiflag) |
++             xenhcd_conn_notify(info, &eoiflag))
+               /* Yield point for this unbounded loop. */
+               cond_resched();
++      xen_irq_lateeoi(irq, eoiflag);
+       return IRQ_HANDLED;
+ }
+@@ -1141,9 +1169,9 @@ static int xenhcd_setup_rings(struct xenbus_device *dev,
+               goto fail;
+       }
+-      err = bind_evtchn_to_irq(info->evtchn);
++      err = bind_evtchn_to_irq_lateeoi(info->evtchn);
+       if (err <= 0) {
+-              xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq");
++              xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq_lateeoi");
+               goto fail;
+       }
+@@ -1496,6 +1524,7 @@ static struct usb_hcd *xenhcd_create_hcd(struct xenbus_device *dev)
+       for (i = 0; i < XENUSB_URB_RING_SIZE; i++) {
+               info->shadow[i].req.id = i + 1;
+               info->shadow[i].urb = NULL;
++              info->shadow[i].in_flight = false;
+       }
+       info->shadow[XENUSB_URB_RING_SIZE - 1].req.id = 0x0fff;
+-- 
+2.35.1
+
diff --git a/queue-5.17/xtensa-fix-dtc-warning-unit_address_format.patch b/queue-5.17/xtensa-fix-dtc-warning-unit_address_format.patch
new file mode 100644 (file)
index 0000000..e25b134
--- /dev/null
@@ -0,0 +1,103 @@
+From 07ef0c07baf4d6e5337d09ab946b692c280951c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Mar 2022 02:49:41 -0700
+Subject: xtensa: fix DTC warning unit_address_format
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+[ Upstream commit e85d29ba4b24f68e7a78cb85c55e754362eeb2de ]
+
+DTC issues the following warnings when building xtfpga device trees:
+
+ /soc/flash@00000000/partition@0x0: unit name should not have leading "0x"
+ /soc/flash@00000000/partition@0x6000000: unit name should not have leading "0x"
+ /soc/flash@00000000/partition@0x6800000: unit name should not have leading "0x"
+ /soc/flash@00000000/partition@0x7fe0000: unit name should not have leading "0x"
+
+Drop leading 0x from flash partition unit names.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi | 8 ++++----
+ arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi  | 8 ++++----
+ arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi   | 4 ++--
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi
+index 9bf8bad1dd18..c33932568aa7 100644
+--- a/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi
++++ b/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi
+@@ -8,19 +8,19 @@
+                       reg = <0x00000000 0x08000000>;
+                       bank-width = <2>;
+                       device-width = <2>;
+-                      partition@0x0 {
++                      partition@0 {
+                               label = "data";
+                               reg = <0x00000000 0x06000000>;
+                       };
+-                      partition@0x6000000 {
++                      partition@6000000 {
+                               label = "boot loader area";
+                               reg = <0x06000000 0x00800000>;
+                       };
+-                      partition@0x6800000 {
++                      partition@6800000 {
+                               label = "kernel image";
+                               reg = <0x06800000 0x017e0000>;
+                       };
+-                      partition@0x7fe0000 {
++                      partition@7fe0000 {
+                               label = "boot environment";
+                               reg = <0x07fe0000 0x00020000>;
+                       };
+diff --git a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi
+index 40c2f81f7cb6..7bde2ab2d6fb 100644
+--- a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi
++++ b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi
+@@ -8,19 +8,19 @@
+                       reg = <0x08000000 0x01000000>;
+                       bank-width = <2>;
+                       device-width = <2>;
+-                      partition@0x0 {
++                      partition@0 {
+                               label = "boot loader area";
+                               reg = <0x00000000 0x00400000>;
+                       };
+-                      partition@0x400000 {
++                      partition@400000 {
+                               label = "kernel image";
+                               reg = <0x00400000 0x00600000>;
+                       };
+-                      partition@0xa00000 {
++                      partition@a00000 {
+                               label = "data";
+                               reg = <0x00a00000 0x005e0000>;
+                       };
+-                      partition@0xfe0000 {
++                      partition@fe0000 {
+                               label = "boot environment";
+                               reg = <0x00fe0000 0x00020000>;
+                       };
+diff --git a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi
+index fb8d3a9f33c2..0655b868749a 100644
+--- a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi
++++ b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi
+@@ -8,11 +8,11 @@
+                       reg = <0x08000000 0x00400000>;
+                       bank-width = <2>;
+                       device-width = <2>;
+-                      partition@0x0 {
++                      partition@0 {
+                               label = "boot loader area";
+                               reg = <0x00000000 0x003f0000>;
+                       };
+-                      partition@0x3f0000 {
++                      partition@3f0000 {
+                               label = "boot environment";
+                               reg = <0x003f0000 0x00010000>;
+                       };
+-- 
+2.35.1
+