]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.11
authorSasha Levin <sashal@kernel.org>
Sat, 15 May 2021 02:13:35 +0000 (22:13 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 15 May 2021 02:13:35 +0000 (22:13 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
218 files changed:
queue-5.11/alsa-bebob-enable-to-deliver-midi-messages-for-multi.patch [new file with mode: 0644]
queue-5.11/alsa-hda-hdmi-fix-race-in-handling-acomp-eld-notific.patch [new file with mode: 0644]
queue-5.11/alsa-hda-realtek-add-quirk-for-lenovo-ideapad-s740.patch [new file with mode: 0644]
queue-5.11/alsa-hdsp-don-t-disable-if-not-enabled.patch [new file with mode: 0644]
queue-5.11/alsa-hdspm-don-t-disable-if-not-enabled.patch [new file with mode: 0644]
queue-5.11/alsa-rme9652-don-t-disable-if-not-enabled.patch [new file with mode: 0644]
queue-5.11/alsa-usb-audio-add-pioneer-djm-850-to-quirks-table.patch [new file with mode: 0644]
queue-5.11/arm-9064-1-hw_breakpoint-do-not-directly-check-the-e.patch [new file with mode: 0644]
queue-5.11/arm64-entry-always-set-gic_prio_psr_i_set-during-ent.patch [new file with mode: 0644]
queue-5.11/arm64-entry-factor-irq-triage-logic-into-macros.patch [new file with mode: 0644]
queue-5.11/asoc-intel-bytcr_rt5640-add-quirk-for-the-chuwi-hi8-.patch [new file with mode: 0644]
queue-5.11/asoc-intel-bytcr_rt5640-enable-jack-detect-support-o.patch [new file with mode: 0644]
queue-5.11/asoc-intel-sof_sdw-add-quirk-for-new-adl-p-rvp.patch [new file with mode: 0644]
queue-5.11/asoc-rsnd-call-rsnd_ssi_master_clk_start-from-rsnd_s.patch [new file with mode: 0644]
queue-5.11/asoc-rsnd-core-check-convert-rate-in-rsnd_hw_params.patch [new file with mode: 0644]
queue-5.11/asoc-rt286-generalize-support-for-alc3263-codec.patch [new file with mode: 0644]
queue-5.11/asoc-rt286-make-rt286_set_gpio_-readable-and-writabl.patch [new file with mode: 0644]
queue-5.11/asoc-rt5670-add-a-quirk-for-the-dell-venue-10-pro-50.patch [new file with mode: 0644]
queue-5.11/asoc-soc-compress-lock-pcm_mutex-to-resolve-lockdep-.patch [new file with mode: 0644]
queue-5.11/ata-ahci_brcm-fix-use-of-bcm7216-reset-controller.patch [new file with mode: 0644]
queue-5.11/ath11k-fix-thermal-temperature-read.patch [new file with mode: 0644]
queue-5.11/block-rnbd-clt-change-queue_depth-type-in-rnbd_clt_s.patch [new file with mode: 0644]
queue-5.11/block-rnbd-clt-check-the-return-value-of-the-functio.patch [new file with mode: 0644]
queue-5.11/bluetooth-btusb-enable-quirk-boolean-flag-for-mediat.patch [new file with mode: 0644]
queue-5.11/bluetooth-check-for-zapped-sk-before-connecting.patch [new file with mode: 0644]
queue-5.11/bluetooth-do-not-set-cur_adv_instance-in-adv-param-m.patch [new file with mode: 0644]
queue-5.11/bluetooth-fix-incorrect-status-handling-in-le-phy-up.patch [new file with mode: 0644]
queue-5.11/bluetooth-initialize-skb_queue_head-at-l2cap_chan_cr.patch [new file with mode: 0644]
queue-5.11/bluetooth-set-conf_not_complete-as-l2cap_chan-defaul.patch [new file with mode: 0644]
queue-5.11/bnxt_en-add-pci-ids-for-hyper-v-vf-devices.patch [new file with mode: 0644]
queue-5.11/can-m_can-m_can_tx_work_queue-fix-tx_skb-race-condit.patch [new file with mode: 0644]
queue-5.11/can-mcp251x-fix-resume-from-sleep-before-interface-w.patch [new file with mode: 0644]
queue-5.11/can-mcp251xfd-mcp251xfd_probe-add-missing-can_rx_off.patch [new file with mode: 0644]
queue-5.11/ceph-fix-inode-leak-on-getattr-error-in-__fh_to_dent.patch [new file with mode: 0644]
queue-5.11/coresight-do-not-scan-for-graph-if-none-is-present.patch [new file with mode: 0644]
queue-5.11/crypto-ccp-free-sev-device-if-sev-init-fails.patch [new file with mode: 0644]
queue-5.11/cuse-prevent-clone.patch [new file with mode: 0644]
queue-5.11/dma-idxd-use-define_mutex-for-mutex-lock.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-cleanup-pci-interrupt-vector-allocati.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-fix-cdev-setup-and-free-device-lifeti.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-fix-dma-device-lifetime.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-fix-engine-conf_dev-lifetime.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-fix-group-conf_dev-lifetime.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-fix-idxd-conf_dev-struct-device-lifet.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-fix-potential-null-dereference-on-poi.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-fix-wq-conf_dev-struct-device-lifetim.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-removal-of-pcim-managed-mmio-mapping.patch [new file with mode: 0644]
queue-5.11/dmaengine-idxd-use-ida-for-device-instance-enumerati.patch [new file with mode: 0644]
queue-5.11/drm-amd-display-add-handling-for-hdcp2-rx-id-list-va.patch [new file with mode: 0644]
queue-5.11/drm-amd-display-fixed-divide-by-zero-kernel-crash-du.patch [new file with mode: 0644]
queue-5.11/drm-amd-display-force-vsync-flip-when-reconfiguring-.patch [new file with mode: 0644]
queue-5.11/drm-amdgpu-add-mem-sync-flag-for-ib-allocated-by-sa.patch [new file with mode: 0644]
queue-5.11/drm-radeon-avoid-power-table-parsing-memory-leaks.patch [new file with mode: 0644]
queue-5.11/drm-radeon-fix-off-by-one-power_state-index-heap-ove.patch [new file with mode: 0644]
queue-5.11/ethernet-enic-fix-a-use-after-free-bug-in-enic_hard_.patch [new file with mode: 0644]
queue-5.11/ethtool-fix-missing-nlm_f_multi-flag-when-dumping.patch [new file with mode: 0644]
queue-5.11/ethtool-ioctl-fix-out-of-bounds-warning-in-store_lin.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-a-hungtask-problem-in-atomic-write.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-a-redundant-call-to-f2fs_balance_fs-if-an-e.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-panic-during-f2fs_resize_fs.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-to-align-to-section-for-fallocate-on-pinned.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-to-allow-migrating-fully-valid-segment.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-to-avoid-accessing-invalid-fio-in-f2fs_allo.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-to-avoid-touching-checkpointed-data-in-get_.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-to-cover-__allocate_new_section-with-curseg.patch [new file with mode: 0644]
queue-5.11/f2fs-fix-to-update-last-i_size-if-fallocate-partiall.patch [new file with mode: 0644]
queue-5.11/flow_dissector-fix-out-of-bounds-warning-in-__skb_fl.patch [new file with mode: 0644]
queue-5.11/fs-9p-fix-v9fs_file_open-writeback-fid-error-check.patch [new file with mode: 0644]
queue-5.11/fs-dlm-add-check-if-dlm-is-currently-running.patch [new file with mode: 0644]
queue-5.11/fs-dlm-add-errno-handling-to-check-callback.patch [new file with mode: 0644]
queue-5.11/fs-dlm-add-shutdown-hook.patch [new file with mode: 0644]
queue-5.11/fs-dlm-change-allocation-limits.patch [new file with mode: 0644]
queue-5.11/fs-dlm-check-on-minimum-msglen-size.patch [new file with mode: 0644]
queue-5.11/fs-dlm-fix-debugfs-dump.patch [new file with mode: 0644]
queue-5.11/fs-dlm-fix-mark-setting-deadlock.patch [new file with mode: 0644]
queue-5.11/fs-dlm-flush-swork-on-shutdown.patch [new file with mode: 0644]
queue-5.11/fs-proc-generic.c-fix-incorrect-pde_is_permanent-che.patch [new file with mode: 0644]
queue-5.11/fuse-invalidate-attrs-when-page-writeback-completes.patch [new file with mode: 0644]
queue-5.11/i2c-add-i2c_aq_no_rep_start-adapter-quirk.patch [new file with mode: 0644]
queue-5.11/i2c-bail-out-early-when-rdwr-parameters-are-wrong.patch [new file with mode: 0644]
queue-5.11/i2c-imx-fix-pm-reference-leak-in-i2c_imx_reg_slave.patch [new file with mode: 0644]
queue-5.11/i40e-fix-broken-xdp-support.patch [new file with mode: 0644]
queue-5.11/i40e-fix-phy-type-identifiers-for-2.5g-and-5g-adapte.patch [new file with mode: 0644]
queue-5.11/i40e-fix-the-restart-auto-negotiation-after-fec-modi.patch [new file with mode: 0644]
queue-5.11/i40e-fix-use-after-free-in-i40e_client_subtask.patch [new file with mode: 0644]
queue-5.11/ia64-module-fix-symbolizer-crash-on-fdescr.patch [new file with mode: 0644]
queue-5.11/iavf-remove-duplicate-free-resources-calls.patch [new file with mode: 0644]
queue-5.11/ib-hfi1-correct-oversized-ring-allocation.patch [new file with mode: 0644]
queue-5.11/ice-handle-increasing-tx-or-rx-ring-sizes.patch [new file with mode: 0644]
queue-5.11/iommu-amd-remove-performance-counter-pre-initializat.patch [new file with mode: 0644]
queue-5.11/ip6_vti-proper-dev_-hold-put-in-ndo_-un-init-methods.patch [new file with mode: 0644]
queue-5.11/iwlwifi-pcie-make-cfg-vs.-trans_cfg-more-robust.patch [new file with mode: 0644]
queue-5.11/iwlwifi-queue-avoid-memory-leak-in-reset-flow.patch [new file with mode: 0644]
queue-5.11/kbuild-generate-module.symvers-only-when-vmlinux-exi.patch [new file with mode: 0644]
queue-5.11/kconfig-nconf-stop-endless-search-loops.patch [new file with mode: 0644]
queue-5.11/kernel-kexec_file-fix-error-return-code-of-kexec_cal.patch [new file with mode: 0644]
queue-5.11/kernel-resource-make-walk_mem_res-find-all-busy-iore.patch [new file with mode: 0644]
queue-5.11/kernel-resource-make-walk_system_ram_res-find-all-bu.patch [new file with mode: 0644]
queue-5.11/khugepaged-fix-wrong-result-value-for-trace_mm_colla.patch [new file with mode: 0644]
queue-5.11/ksm-fix-potential-missing-rmap_item-for-stable_node.patch [new file with mode: 0644]
queue-5.11/libbpf-fix-signed-overflow-in-ringbuf_process_ring.patch [new file with mode: 0644]
queue-5.11/mac80211-clear-the-beacon-s-crc-after-channel-switch.patch [new file with mode: 0644]
queue-5.11/mac80211-properly-drop-the-connection-in-case-of-inv.patch [new file with mode: 0644]
queue-5.11/mac80211-set-priority-and-queue-mapping-for-injected.patch [new file with mode: 0644]
queue-5.11/mips-loongson64-use-_cache_uncached-instead-of-_cach.patch [new file with mode: 0644]
queue-5.11/mm-gup-check-every-subpage-of-a-compound-page-during.patch [new file with mode: 0644]
queue-5.11/mm-gup-check-for-isolation-errors.patch [new file with mode: 0644]
queue-5.11/mm-gup-return-an-error-on-migration-failure.patch [new file with mode: 0644]
queue-5.11/mm-hugeltb-handle-the-error-case-in-hugetlb_fix_rese.patch [new file with mode: 0644]
queue-5.11/mm-migrate.c-fix-potential-indeterminate-pte-entry-i.patch [new file with mode: 0644]
queue-5.11/mptcp-fix-splat-when-closing-unaccepted-socket.patch [new file with mode: 0644]
queue-5.11/mt76-mt7615-fix-entering-driver-own-state-on-mt7663.patch [new file with mode: 0644]
queue-5.11/mt76-mt7615-fix-key-set-delete-issues.patch [new file with mode: 0644]
queue-5.11/mt76-mt7615-support-loading-eeprom-for-mt7613be.patch [new file with mode: 0644]
queue-5.11/mt76-mt76x0-disable-gtk-offloading.patch [new file with mode: 0644]
queue-5.11/mt76-mt7915-add-wifi-subsystem-reset.patch [new file with mode: 0644]
queue-5.11/mt76-mt7915-always-check-return-value-from-mt7915_mc.patch [new file with mode: 0644]
queue-5.11/mt76-mt7915-fix-key-set-delete-issue.patch [new file with mode: 0644]
queue-5.11/mt76-mt7915-fix-txpower-init-for-tssi-off-chips.patch [new file with mode: 0644]
queue-5.11/net-bridge-when-suppression-is-enabled-exclude-rarp-.patch [new file with mode: 0644]
queue-5.11/net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch [new file with mode: 0644]
queue-5.11/net-fix-nla_strcmp-to-handle-more-then-one-trailing-.patch [new file with mode: 0644]
queue-5.11/net-hns3-add-check-for-hns3_nic_state_inited-in-hns3.patch [new file with mode: 0644]
queue-5.11/net-hns3-add-handling-for-xmit-skb-with-recursive-fr.patch [new file with mode: 0644]
queue-5.11/net-hns3-disable-phy-loopback-setting-in-hclge_mac_s.patch [new file with mode: 0644]
queue-5.11/net-hns3-fix-for-vxlan-gpe-tx-checksum-bug.patch [new file with mode: 0644]
queue-5.11/net-hns3-fix-incorrect-configuration-for-igu_egu_hw_.patch [new file with mode: 0644]
queue-5.11/net-hns3-initialize-the-message-content-in-hclge_get.patch [new file with mode: 0644]
queue-5.11/net-hns3-remediate-a-potential-overflow-risk-of-bd_n.patch [new file with mode: 0644]
queue-5.11/net-hns3-use-netif_tx_disable-to-stop-the-transmit-q.patch [new file with mode: 0644]
queue-5.11/net-ipa-fix-inter-ee-irq-register-definitions.patch [new file with mode: 0644]
queue-5.11/net-mlx5e-use-net_prefetchw-instead-of-prefetchw-in-.patch [new file with mode: 0644]
queue-5.11/net-sched-cls_flower-use-ntohs-for-struct-flow_disse.patch [new file with mode: 0644]
queue-5.11/net-sched-tapr-prevent-cycle_time-0-in-parse_taprio_.patch [new file with mode: 0644]
queue-5.11/net-stmmac-clear-receive-all-ra-bit-when-promiscuous.patch [new file with mode: 0644]
queue-5.11/net-stmmac-set-fifo-sizes-for-ipq806x.patch [new file with mode: 0644]
queue-5.11/netfilter-nfnetlink_osf-fix-a-missing-skb_header_poi.patch [new file with mode: 0644]
queue-5.11/netfilter-nftables-avoid-overflows-in-nft_hash_bucke.patch [new file with mode: 0644]
queue-5.11/netfilter-nftables-fix-a-memleak-from-userdata-error.patch [new file with mode: 0644]
queue-5.11/netfilter-xt_secmark-add-new-revision-to-fix-structu.patch [new file with mode: 0644]
queue-5.11/nfs-deal-correctly-with-attribute-generation-counter.patch [new file with mode: 0644]
queue-5.11/nfs-fix-attribute-bitmask-in-_nfs42_proc_fallocate.patch [new file with mode: 0644]
queue-5.11/nfs-fix-handling-of-cookie-verifier-in-uncached_read.patch [new file with mode: 0644]
queue-5.11/nfs-nfs4_bitmask_adjust-must-not-change-the-server-g.patch [new file with mode: 0644]
queue-5.11/nfs-only-change-the-cookie-verifier-if-the-directory.patch [new file with mode: 0644]
queue-5.11/nfs-subsequent-readdir-calls-should-carry-non-zero-c.patch [new file with mode: 0644]
queue-5.11/nfsd-ensure-new-clients-break-delegations.patch [new file with mode: 0644]
queue-5.11/nfsv4.2-always-flush-out-writes-in-nfs42_proc_falloc.patch [new file with mode: 0644]
queue-5.11/nfsv4.2-fix-handling-of-sr_eof-in-seek-s-reply.patch [new file with mode: 0644]
queue-5.11/nfsv4.x-don-t-return-nfs4err_nomatching_layout-if-we.patch [new file with mode: 0644]
queue-5.11/pci-brcmstb-use-reset-rearm-instead-of-deassert-asse.patch [new file with mode: 0644]
queue-5.11/pci-endpoint-add-helper-api-to-get-the-next-unreserv.patch [new file with mode: 0644]
queue-5.11/pci-endpoint-fix-missing-destroy_workqueue.patch [new file with mode: 0644]
queue-5.11/pci-endpoint-fix-null-pointer-dereference-for-get_fe.patch [new file with mode: 0644]
queue-5.11/pci-endpoint-make-_free_bar-to-return-error-codes-on.patch [new file with mode: 0644]
queue-5.11/pci-endpoint-make-_get_first_free_bar-take-into-acco.patch [new file with mode: 0644]
queue-5.11/pci-iproc-fix-return-value-of-iproc_msi_irq_domain_a.patch [new file with mode: 0644]
queue-5.11/pci-rcec-fix-rciep-device-to-rcec-association.patch [new file with mode: 0644]
queue-5.11/pci-release-of-node-in-pci_scan_device-s-error-path.patch [new file with mode: 0644]
queue-5.11/pinctrl-samsung-use-int-for-register-masks-in-exynos.patch [new file with mode: 0644]
queue-5.11/pnfs-flexfiles-fix-incorrect-size-check-in-decode_nf.patch [new file with mode: 0644]
queue-5.11/powerpc-32-statically-initialise-first-emergency-con.patch [new file with mode: 0644]
queue-5.11/powerpc-iommu-annotate-nested-lock-for-lockdep.patch [new file with mode: 0644]
queue-5.11/powerpc-mm-add-cond_resched-while-removing-hpte-mapp.patch [new file with mode: 0644]
queue-5.11/powerpc-pseries-stop-calling-printk-in-rtas_stop_sel.patch [new file with mode: 0644]
queue-5.11/powerpc-smp-set-numa-node-before-updating-mask.patch [new file with mode: 0644]
queue-5.11/powerpc-xive-use-the-ibm-chip-id-property-only-under.patch [new file with mode: 0644]
queue-5.11/pwm-atmel-fix-duty-cycle-calculation-in-.get_state.patch [new file with mode: 0644]
queue-5.11/qtnfmac-fix-possible-buffer-overflow-in-qtnf_event_h.patch [new file with mode: 0644]
queue-5.11/remoteproc-pru-fix-and-cleanup-firmware-interrupt-ma.patch [new file with mode: 0644]
queue-5.11/remoteproc-pru-fix-wrong-success-return-value-for-fw.patch [new file with mode: 0644]
queue-5.11/remoteproc-pru-fixup-interrupt-parent-logic-for-fw-e.patch [new file with mode: 0644]
queue-5.11/remoteproc-qcom_q6v5_mss-validate-p_filesz-in-elf-lo.patch [new file with mode: 0644]
queue-5.11/revert-iommu-amd-fix-performance-counter-initializat.patch [new file with mode: 0644]
queue-5.11/risc-v-fix-error-code-returned-by-riscv_hartid_to_cp.patch [new file with mode: 0644]
queue-5.11/rpmsg-qcom_glink_native-fix-error-return-code-of-qco.patch [new file with mode: 0644]
queue-5.11/rtc-ds1307-fix-wday-settings-for-rx8130.patch [new file with mode: 0644]
queue-5.11/rtc-fsl-ftm-alarm-add-module_table.patch [new file with mode: 0644]
queue-5.11/rtw88-8822c-add-lc-calibration-for-rtl8822c.patch [new file with mode: 0644]
queue-5.11/samples-bpf-fix-broken-tracex1-due-to-kprobe-argumen.patch [new file with mode: 0644]
queue-5.11/sched-fair-fix-unfairness-caused-by-missing-load-dec.patch [new file with mode: 0644]
queue-5.11/sched-fix-out-of-bound-access-in-uclamp.patch [new file with mode: 0644]
queue-5.11/scsi-qla2xxx-prevent-prli-in-target-mode.patch [new file with mode: 0644]
queue-5.11/scsi-ufs-core-cancel-rpm_dev_flush_recheck_work-duri.patch [new file with mode: 0644]
queue-5.11/scsi-ufs-core-do-not-put-ufs-power-into-lpm-if-link-.patch [new file with mode: 0644]
queue-5.11/scsi-ufs-core-narrow-down-fast-path-in-system-suspen.patch [new file with mode: 0644]
queue-5.11/sctp-do-asoc-update-earlier-in-sctp_sf_do_dupcook_a.patch [new file with mode: 0644]
queue-5.11/sctp-fix-a-sctp_mib_currestab-leak-in-sctp_sf_do_dup.patch [new file with mode: 0644]
queue-5.11/sctp-fix-out-of-bounds-warning-in-sctp_process_ascon.patch [new file with mode: 0644]
queue-5.11/selftests-mlxsw-fix-mausezahn-invocation-in-erspan-s.patch [new file with mode: 0644]
queue-5.11/selftests-mlxsw-increase-the-tolerance-of-backlog-bu.patch [new file with mode: 0644]
queue-5.11/selftests-mptcp-launch-mptcp_connect-with-timeout.patch [new file with mode: 0644]
queue-5.11/selftests-powerpc-fix-l1d-flushing-tests-for-power10.patch [new file with mode: 0644]
queue-5.11/selftests-set-cc-to-clang-in-lib.mk-if-llvm-is-set.patch [new file with mode: 0644]
queue-5.11/series
queue-5.11/smc-disallow-tcp_ulp-in-smc_setsockopt.patch [new file with mode: 0644]
queue-5.11/sunrpc-fix-misplaced-barrier-in-call_decode.patch [new file with mode: 0644]
queue-5.11/sunrpc-fix-null-pointer-dereference-in-svc_rqst_free.patch [new file with mode: 0644]
queue-5.11/sunrpc-fix-ternary-sign-expansion-bug-in-tracing.patch [new file with mode: 0644]
queue-5.11/sunrpc-handle-major-timeout-in-xprt_adjust_timeout.patch [new file with mode: 0644]
queue-5.11/sunrpc-move-fault-injection-call-sites.patch [new file with mode: 0644]
queue-5.11/sunrpc-remove-trace_xprt_transmit_queued.patch [new file with mode: 0644]
queue-5.11/swiotlb-fix-the-type-of-index.patch [new file with mode: 0644]
queue-5.11/thermal-drivers-tsens-fix-missing-put_device-error.patch [new file with mode: 0644]
queue-5.11/thermal-thermal_of-fix-error-return-code-of-thermal_.patch [new file with mode: 0644]
queue-5.11/tipc-convert-dest-node-s-address-to-network-order.patch [new file with mode: 0644]
queue-5.11/virtiofs-fix-userns.patch [new file with mode: 0644]
queue-5.11/watchdog-explicitly-update-timestamp-when-reporting-.patch [new file with mode: 0644]
queue-5.11/watchdog-fix-barriers-when-printing-backtraces-from-.patch [new file with mode: 0644]
queue-5.11/watchdog-rename-__touch_watchdog-to-a-better-descrip.patch [new file with mode: 0644]
queue-5.11/watchdog-softlockup-remove-logic-that-tried-to-preve.patch [new file with mode: 0644]
queue-5.11/wilc1000-bring-mac-address-setting-in-line-with-typi.patch [new file with mode: 0644]
queue-5.11/wl3501_cs-fix-out-of-bounds-warnings-in-wl3501_mgmt_.patch [new file with mode: 0644]
queue-5.11/wl3501_cs-fix-out-of-bounds-warnings-in-wl3501_send_.patch [new file with mode: 0644]
queue-5.11/xprtrdma-avoid-receive-queue-wrapping.patch [new file with mode: 0644]
queue-5.11/xprtrdma-fix-cwnd-update-ordering.patch [new file with mode: 0644]
queue-5.11/xprtrdma-rpcrdma_mr_pop-already-does-list_del_init.patch [new file with mode: 0644]
queue-5.11/xsk-fix-for-xp_aligned_validate_desc-when-len-chunk_.patch [new file with mode: 0644]

diff --git a/queue-5.11/alsa-bebob-enable-to-deliver-midi-messages-for-multi.patch b/queue-5.11/alsa-bebob-enable-to-deliver-midi-messages-for-multi.patch
new file mode 100644 (file)
index 0000000..e68f1ef
--- /dev/null
@@ -0,0 +1,58 @@
+From 148b40bb23d00f5dfdeac2afe5eb8798be4006f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Mar 2021 12:28:31 +0900
+Subject: ALSA: bebob: enable to deliver MIDI messages for multiple ports
+
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+
+[ Upstream commit d2b6f15bc18ac8fbce25398290774c21f5b2cd44 ]
+
+Current implementation of bebob driver doesn't correctly handle the case
+that the device has multiple MIDI ports. The cause is the number of MIDI
+conformant data channels is passed to AM824 data block processing layer.
+
+This commit fixes the bug.
+
+Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Link: https://lore.kernel.org/r/20210321032831.340278-4-o-takashi@sakamocchi.jp
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/firewire/bebob/bebob_stream.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
+index bbae04793c50..c18017e0a3d9 100644
+--- a/sound/firewire/bebob/bebob_stream.c
++++ b/sound/firewire/bebob/bebob_stream.c
+@@ -517,20 +517,22 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
+ static int keep_resources(struct snd_bebob *bebob, struct amdtp_stream *stream,
+                         unsigned int rate, unsigned int index)
+ {
+-      struct snd_bebob_stream_formation *formation;
++      unsigned int pcm_channels;
++      unsigned int midi_ports;
+       struct cmp_connection *conn;
+       int err;
+       if (stream == &bebob->tx_stream) {
+-              formation = bebob->tx_stream_formations + index;
++              pcm_channels = bebob->tx_stream_formations[index].pcm;
++              midi_ports = bebob->midi_input_ports;
+               conn = &bebob->out_conn;
+       } else {
+-              formation = bebob->rx_stream_formations + index;
++              pcm_channels = bebob->rx_stream_formations[index].pcm;
++              midi_ports = bebob->midi_output_ports;
+               conn = &bebob->in_conn;
+       }
+-      err = amdtp_am824_set_parameters(stream, rate, formation->pcm,
+-                                       formation->midi, false);
++      err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports, false);
+       if (err < 0)
+               return err;
+-- 
+2.30.2
+
diff --git a/queue-5.11/alsa-hda-hdmi-fix-race-in-handling-acomp-eld-notific.patch b/queue-5.11/alsa-hda-hdmi-fix-race-in-handling-acomp-eld-notific.patch
new file mode 100644 (file)
index 0000000..de40dd8
--- /dev/null
@@ -0,0 +1,66 @@
+From 3314a3c7f00b05e7d3da1d5675386b7daf1306cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 16:11:57 +0300
+Subject: ALSA: hda/hdmi: fix race in handling acomp ELD notification at resume
+
+From: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+
+[ Upstream commit 0c37e2eb6b83e375e8a654d01598292d5591fc65 ]
+
+When snd-hda-codec-hdmi is used with ASoC HDA controller like SOF (acomp
+used for ELD notifications), display connection change done during suspend,
+can be lost due to following sequence of events:
+
+  1. system in S3 suspend
+  2. DP/HDMI receiver connected
+  3. system resumed
+  4. HDA controller resumed, but card->deferred_resume_work not complete
+  5. acomp eld_notify callback
+  6. eld_notify ignored as power state is not CTL_POWER_D0
+  7. HDA resume deferred work completed, power state set to CTL_POWER_D0
+
+This results in losing the notification, and the jack state reported to
+user-space is not correct.
+
+The check on step 6 was added in commit 8ae743e82f0b ("ALSA: hda - Skip
+ELD notification during system suspend"). It would seem with the deferred
+resume logic in ASoC core, this check is not safe.
+
+Fix the issue by modifying the check to use "dev.power.power_state.event"
+instead of ALSA specific card power state variable.
+
+BugLink: https://github.com/thesofproject/linux/issues/2825
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Link: https://lore.kernel.org/r/20210416131157.1881366-1-kai.vehmanen@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_hdmi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index d6387106619f..7b0d9d7a1c38 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -2650,7 +2650,7 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id)
+       /* skip notification during system suspend (but not in runtime PM);
+        * the state will be updated at resume
+        */
+-      if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
++      if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND)
+               return;
+       /* ditto during suspend/resume process itself */
+       if (snd_hdac_is_in_pm(&codec->core))
+@@ -2836,7 +2836,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
+       /* skip notification during system suspend (but not in runtime PM);
+        * the state will be updated at resume
+        */
+-      if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
++      if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND)
+               return;
+       /* ditto during suspend/resume process itself */
+       if (snd_hdac_is_in_pm(&codec->core))
+-- 
+2.30.2
+
diff --git a/queue-5.11/alsa-hda-realtek-add-quirk-for-lenovo-ideapad-s740.patch b/queue-5.11/alsa-hda-realtek-add-quirk-for-lenovo-ideapad-s740.patch
new file mode 100644 (file)
index 0000000..5852c34
--- /dev/null
@@ -0,0 +1,569 @@
+From 936f6c56390d642ddb62314fb4b3e61d44d7f78b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 10:12:11 +0200
+Subject: ALSA: hda/realtek: Add quirk for Lenovo Ideapad S740
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 26928ca1f06aab4361eb5adbe7ef3b5c82f13cf2 ]
+
+Lenovo Ideapad S740 requires quite a few COEF setups to make its
+speakers working.  The verb table was provided from Ryan Prescott as
+the result of investigation via qemu:
+  https://github.com/ryanprescott/realtek-verb-tools/wiki/How-to-sniff-verbs-from-a-Windows-sound-driver
+
+BugLink: https://github.com/thesofproject/linux/issues/2748
+Tested-by: Ryan Prescott <ryan@cousinscomputers.net>
+Link: https://lore.kernel.org/r/20210416081211.20059-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/ideapad_s740_helper.c | 492 ++++++++++++++++++++++++++++
+ sound/pci/hda/patch_realtek.c       |  11 +
+ 2 files changed, 503 insertions(+)
+ create mode 100644 sound/pci/hda/ideapad_s740_helper.c
+
+diff --git a/sound/pci/hda/ideapad_s740_helper.c b/sound/pci/hda/ideapad_s740_helper.c
+new file mode 100644
+index 000000000000..564b9086e52d
+--- /dev/null
++++ b/sound/pci/hda/ideapad_s740_helper.c
+@@ -0,0 +1,492 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Fixes for Lenovo Ideapad S740, to be included from codec driver */
++
++static const struct hda_verb alc285_ideapad_s740_coefs[] = {
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x10 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0320 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
++{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
++{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
++{}
++};
++
++static void alc285_fixup_ideapad_s740_coef(struct hda_codec *codec,
++                                         const struct hda_fixup *fix,
++                                         int action)
++{
++      switch (action) {
++      case HDA_FIXUP_ACT_PRE_PROBE:
++              snd_hda_add_verbs(codec, alc285_ideapad_s740_coefs);
++              break;
++      }
++}
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 8ec57bd351df..1fe70f2fe4fe 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6282,6 +6282,9 @@ static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
+ /* for alc295_fixup_hp_top_speakers */
+ #include "hp_x360_helper.c"
++/* for alc285_fixup_ideapad_s740_coef() */
++#include "ideapad_s740_helper.c"
++
+ enum {
+       ALC269_FIXUP_GPIO2,
+       ALC269_FIXUP_SONY_VAIO,
+@@ -6481,6 +6484,7 @@ enum {
+       ALC282_FIXUP_ACER_DISABLE_LINEOUT,
+       ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST,
+       ALC256_FIXUP_ACER_HEADSET_MIC,
++      ALC285_FIXUP_IDEAPAD_S740_COEF,
+ };
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -7973,6 +7977,12 @@ static const struct hda_fixup alc269_fixups[] = {
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
+       },
++      [ALC285_FIXUP_IDEAPAD_S740_COEF] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc285_fixup_ideapad_s740_coef,
++              .chained = true,
++              .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -8320,6 +8330,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME),
++      SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF),
+       SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
+       SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
+       SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
+-- 
+2.30.2
+
diff --git a/queue-5.11/alsa-hdsp-don-t-disable-if-not-enabled.patch b/queue-5.11/alsa-hdsp-don-t-disable-if-not-enabled.patch
new file mode 100644 (file)
index 0000000..2417091
--- /dev/null
@@ -0,0 +1,49 @@
+From 72f303841fdba2896c78552f4d3a1ca2b0b38f29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Mar 2021 11:38:38 -0400
+Subject: ALSA: hdsp: don't disable if not enabled
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit 507cdb9adba006a7798c358456426e1aea3d9c4f ]
+
+hdsp wants to disable a not enabled pci device, which makes kernel
+throw a warning. Make sure the device is enabled before calling disable.
+
+[    1.758292] snd_hdsp 0000:00:03.0: disabling already-disabled device
+[    1.758327] WARNING: CPU: 0 PID: 180 at drivers/pci/pci.c:2146 pci_disable_device+0x91/0xb0
+[    1.766985] Call Trace:
+[    1.767121]  snd_hdsp_card_free+0x94/0xf0 [snd_hdsp]
+[    1.767388]  release_card_device+0x4b/0x80 [snd]
+[    1.767639]  device_release+0x3b/0xa0
+[    1.767838]  kobject_put+0x94/0x1b0
+[    1.768027]  put_device+0x13/0x20
+[    1.768207]  snd_card_free+0x61/0x90 [snd]
+[    1.768430]  snd_hdsp_probe+0x524/0x5e0 [snd_hdsp]
+
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Link: https://lore.kernel.org/r/20210321153840.378226-2-ztong0001@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/rme9652/hdsp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
+index cea53a878c36..4aee30db034d 100644
+--- a/sound/pci/rme9652/hdsp.c
++++ b/sound/pci/rme9652/hdsp.c
+@@ -5321,7 +5321,8 @@ static int snd_hdsp_free(struct hdsp *hdsp)
+       if (hdsp->port)
+               pci_release_regions(hdsp->pci);
+-      pci_disable_device(hdsp->pci);
++      if (pci_is_enabled(hdsp->pci))
++              pci_disable_device(hdsp->pci);
+       return 0;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/alsa-hdspm-don-t-disable-if-not-enabled.patch b/queue-5.11/alsa-hdspm-don-t-disable-if-not-enabled.patch
new file mode 100644 (file)
index 0000000..85ce8d3
--- /dev/null
@@ -0,0 +1,49 @@
+From 04ad9f8519272fe28007f193a1a6178f483dd2a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Mar 2021 11:38:39 -0400
+Subject: ALSA: hdspm: don't disable if not enabled
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit 790f5719b85e12e10c41753b864e74249585ed08 ]
+
+hdspm wants to disable a not enabled pci device, which makes kernel
+throw a warning. Make sure the device is enabled before calling disable.
+
+[    1.786391] snd_hdspm 0000:00:03.0: disabling already-disabled device
+[    1.786400] WARNING: CPU: 0 PID: 182 at drivers/pci/pci.c:2146 pci_disable_device+0x91/0xb0
+[    1.795181] Call Trace:
+[    1.795320]  snd_hdspm_card_free+0x58/0xa0 [snd_hdspm]
+[    1.795595]  release_card_device+0x4b/0x80 [snd]
+[    1.795860]  device_release+0x3b/0xa0
+[    1.796072]  kobject_put+0x94/0x1b0
+[    1.796260]  put_device+0x13/0x20
+[    1.796438]  snd_card_free+0x61/0x90 [snd]
+[    1.796659]  snd_hdspm_probe+0x97b/0x1440 [snd_hdspm]
+
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Link: https://lore.kernel.org/r/20210321153840.378226-3-ztong0001@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/rme9652/hdspm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
+index 04e878a0f773..49fee31ad905 100644
+--- a/sound/pci/rme9652/hdspm.c
++++ b/sound/pci/rme9652/hdspm.c
+@@ -6884,7 +6884,8 @@ static int snd_hdspm_free(struct hdspm * hdspm)
+       if (hdspm->port)
+               pci_release_regions(hdspm->pci);
+-      pci_disable_device(hdspm->pci);
++      if (pci_is_enabled(hdspm->pci))
++              pci_disable_device(hdspm->pci);
+       return 0;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/alsa-rme9652-don-t-disable-if-not-enabled.patch b/queue-5.11/alsa-rme9652-don-t-disable-if-not-enabled.patch
new file mode 100644 (file)
index 0000000..5ef7a6e
--- /dev/null
@@ -0,0 +1,49 @@
+From f71187b75a166e96f005ef90fbe1e8ac590cf901 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Mar 2021 11:38:40 -0400
+Subject: ALSA: rme9652: don't disable if not enabled
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit f57a741874bb6995089020e97a1dcdf9b165dcbe ]
+
+rme9652 wants to disable a not enabled pci device, which makes kernel
+throw a warning. Make sure the device is enabled before calling disable.
+
+[    1.751595] snd_rme9652 0000:00:03.0: disabling already-disabled device
+[    1.751605] WARNING: CPU: 0 PID: 174 at drivers/pci/pci.c:2146 pci_disable_device+0x91/0xb0
+[    1.759968] Call Trace:
+[    1.760145]  snd_rme9652_card_free+0x76/0xa0 [snd_rme9652]
+[    1.760434]  release_card_device+0x4b/0x80 [snd]
+[    1.760679]  device_release+0x3b/0xa0
+[    1.760874]  kobject_put+0x94/0x1b0
+[    1.761059]  put_device+0x13/0x20
+[    1.761235]  snd_card_free+0x61/0x90 [snd]
+[    1.761454]  snd_rme9652_probe+0x3be/0x700 [snd_rme9652]
+
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Link: https://lore.kernel.org/r/20210321153840.378226-4-ztong0001@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/rme9652/rme9652.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
+index 012fbec5e6a7..0f4ab86a29f6 100644
+--- a/sound/pci/rme9652/rme9652.c
++++ b/sound/pci/rme9652/rme9652.c
+@@ -1733,7 +1733,8 @@ static int snd_rme9652_free(struct snd_rme9652 *rme9652)
+       if (rme9652->port)
+               pci_release_regions(rme9652->pci);
+-      pci_disable_device(rme9652->pci);
++      if (pci_is_enabled(rme9652->pci))
++              pci_disable_device(rme9652->pci);
+       return 0;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/alsa-usb-audio-add-pioneer-djm-850-to-quirks-table.patch b/queue-5.11/alsa-usb-audio-add-pioneer-djm-850-to-quirks-table.patch
new file mode 100644 (file)
index 0000000..0a8865b
--- /dev/null
@@ -0,0 +1,99 @@
+From a0ad292f754323f9a6fe654a3fc0efca7dfd00ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 16:27:26 +0100
+Subject: ALSA: usb-audio: Add Pioneer DJM-850 to quirks-table
+
+From: Nicolas MURE <nicolas.mure2019@gmail.com>
+
+[ Upstream commit a3c30b0cb6d05f5bf66d1a5d42e876f31753a447 ]
+
+Declare the Pioneer DJM-850 interfaces for capture and playback.
+
+See https://github.com/nm2107/Pioneer-DJM-850-driver-reverse-engineering/blob/172fb9a61055960c88c67b7c416fe5bf3609807b/doc/usb-device-specifications.md
+for the complete device spec.
+
+Signed-off-by: Nicolas MURE <nicolas.mure2019@gmail.com>
+Link: https://lore.kernel.org/r/20210301152729.18094-2-nicolas.mure2019@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks-table.h | 63 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 63 insertions(+)
+
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 48facd262658..8a8fe2b980a1 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -3827,6 +3827,69 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
+               }
+       }
+ },
++{
++      /*
++       * Pioneer DJ DJM-850
++       * 8 channels playback and 8 channels capture @ 44.1/48/96kHz S24LE
++       * Playback on EP 0x05
++       * Capture on EP 0x86
++       */
++      USB_DEVICE_VENDOR_SPEC(0x08e4, 0x0163),
++      .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++              .ifnum = QUIRK_ANY_INTERFACE,
++              .type = QUIRK_COMPOSITE,
++              .data = (const struct snd_usb_audio_quirk[]) {
++                      {
++                              .ifnum = 0,
++                              .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++                              .data = &(const struct audioformat) {
++                                      .formats = SNDRV_PCM_FMTBIT_S24_3LE,
++                                      .channels = 8,
++                                      .iface = 0,
++                                      .altsetting = 1,
++                                      .altset_idx = 1,
++                                      .endpoint = 0x05,
++                                      .ep_attr = USB_ENDPOINT_XFER_ISOC|
++                                          USB_ENDPOINT_SYNC_ASYNC|
++                                              USB_ENDPOINT_USAGE_DATA,
++                                      .rates = SNDRV_PCM_RATE_44100|
++                                              SNDRV_PCM_RATE_48000|
++                                              SNDRV_PCM_RATE_96000,
++                                      .rate_min = 44100,
++                                      .rate_max = 96000,
++                                      .nr_rates = 3,
++                                      .rate_table = (unsigned int[]) { 44100, 48000, 96000 }
++                              }
++                      },
++                      {
++                              .ifnum = 0,
++                              .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++                              .data = &(const struct audioformat) {
++                                      .formats = SNDRV_PCM_FMTBIT_S24_3LE,
++                                      .channels = 8,
++                                      .iface = 0,
++                                      .altsetting = 1,
++                                      .altset_idx = 1,
++                                      .endpoint = 0x86,
++                                      .ep_idx = 1,
++                                      .ep_attr = USB_ENDPOINT_XFER_ISOC|
++                                              USB_ENDPOINT_SYNC_ASYNC|
++                                              USB_ENDPOINT_USAGE_DATA,
++                                      .rates = SNDRV_PCM_RATE_44100|
++                                              SNDRV_PCM_RATE_48000|
++                                              SNDRV_PCM_RATE_96000,
++                                      .rate_min = 44100,
++                                      .rate_max = 96000,
++                                      .nr_rates = 3,
++                                      .rate_table = (unsigned int[]) { 44100, 48000, 96000 }
++                              }
++                      },
++                      {
++                              .ifnum = -1
++                      }
++              }
++      }
++},
+ {
+       /*
+        * Pioneer DJ DJM-450
+-- 
+2.30.2
+
diff --git a/queue-5.11/arm-9064-1-hw_breakpoint-do-not-directly-check-the-e.patch b/queue-5.11/arm-9064-1-hw_breakpoint-do-not-directly-check-the-e.patch
new file mode 100644 (file)
index 0000000..cede838
--- /dev/null
@@ -0,0 +1,48 @@
+From 0d34ad20900418f745985a6e9bdeb516d704b410 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Feb 2021 03:00:05 +0100
+Subject: ARM: 9064/1: hw_breakpoint: Do not directly check the event's
+ overflow_handler hook
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit a506bd5756290821a4314f502b4bafc2afcf5260 ]
+
+The commit 1879445dfa7b ("perf/core: Set event's default
+::overflow_handler()") set a default event->overflow_handler in
+perf_event_alloc(), and replace the check event->overflow_handler with
+is_default_overflow_handler(), but one is missing.
+
+Currently, the bp->overflow_handler can not be NULL. As a result,
+enable_single_step() is always not invoked.
+
+Comments from Zhen Lei:
+
+ https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210207105934.2001-1-thunder.leizhen@huawei.com/
+
+Fixes: 1879445dfa7b ("perf/core: Set event's default ::overflow_handler()")
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Cc: Wang Nan <wangnan0@huawei.com>
+Acked-by: Will Deacon <will@kernel.org>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/kernel/hw_breakpoint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
+index 08660ae9dcbc..b1423fb130ea 100644
+--- a/arch/arm/kernel/hw_breakpoint.c
++++ b/arch/arm/kernel/hw_breakpoint.c
+@@ -886,7 +886,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
+                       info->trigger = addr;
+                       pr_debug("breakpoint fired: address = 0x%x\n", addr);
+                       perf_bp_event(bp, regs);
+-                      if (!bp->overflow_handler)
++                      if (is_default_overflow_handler(bp))
+                               enable_single_step(bp, addr);
+                       goto unlock;
+               }
+-- 
+2.30.2
+
diff --git a/queue-5.11/arm64-entry-always-set-gic_prio_psr_i_set-during-ent.patch b/queue-5.11/arm64-entry-always-set-gic_prio_psr_i_set-during-ent.patch
new file mode 100644 (file)
index 0000000..c7baf97
--- /dev/null
@@ -0,0 +1,219 @@
+From cb6426a42fc133d4d249ebb636a86c7e614a0df0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 12:15:55 +0100
+Subject: arm64: entry: always set GIC_PRIO_PSR_I_SET during entry
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 4d6a38da8e79e94cbd1344aa90876f0f805db705 ]
+
+Zenghui reports that booting a kernel with "irqchip.gicv3_pseudo_nmi=1"
+on the command line hits a warning during kernel entry, due to the way
+we manipulate the PMR.
+
+Early in the entry sequence, we call lockdep_hardirqs_off() to inform
+lockdep that interrupts have been masked (as the HW sets DAIF wqhen
+entering an exception). Architecturally PMR_EL1 is not affected by
+exception entry, and we don't set GIC_PRIO_PSR_I_SET in the PMR early in
+the exception entry sequence, so early in exception entry the PMR can
+indicate that interrupts are unmasked even though they are masked by
+DAIF.
+
+If DEBUG_LOCKDEP is selected, lockdep_hardirqs_off() will check that
+interrupts are masked, before we set GIC_PRIO_PSR_I_SET in any of the
+exception entry paths, and hence lockdep_hardirqs_off() will WARN() that
+something is amiss.
+
+We can avoid this by consistently setting GIC_PRIO_PSR_I_SET during
+exception entry so that kernel code sees a consistent environment. We
+must also update local_daif_inherit() to undo this, as currently only
+touches DAIF. For other paths, local_daif_restore() will update both
+DAIF and the PMR. With this done, we can remove the existing special
+cases which set this later in the entry code.
+
+We always use (GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET) for consistency with
+local_daif_save(), as this will warn if it ever encounters
+(GIC_PRIO_IRQOFF | GIC_PRIO_PSR_I_SET), and never sets this itself. This
+matches the gic_prio_kentry_setup that we have to retain for
+ret_to_user.
+
+The original splat from Zenghui's report was:
+
+| DEBUG_LOCKS_WARN_ON(!irqs_disabled())
+| WARNING: CPU: 3 PID: 125 at kernel/locking/lockdep.c:4258 lockdep_hardirqs_off+0xd4/0xe8
+| Modules linked in:
+| CPU: 3 PID: 125 Comm: modprobe Tainted: G        W         5.12.0-rc8+ #463
+| Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
+| pstate: 604003c5 (nZCv DAIF +PAN -UAO -TCO BTYPE=--)
+| pc : lockdep_hardirqs_off+0xd4/0xe8
+| lr : lockdep_hardirqs_off+0xd4/0xe8
+| sp : ffff80002a39bad0
+| pmr_save: 000000e0
+| x29: ffff80002a39bad0 x28: ffff0000de214bc0
+| x27: ffff0000de1c0400 x26: 000000000049b328
+| x25: 0000000000406f30 x24: ffff0000de1c00a0
+| x23: 0000000020400005 x22: ffff8000105f747c
+| x21: 0000000096000044 x20: 0000000000498ef9
+| x19: ffff80002a39bc88 x18: ffffffffffffffff
+| x17: 0000000000000000 x16: ffff800011c61eb0
+| x15: ffff800011700a88 x14: 0720072007200720
+| x13: 0720072007200720 x12: 0720072007200720
+| x11: 0720072007200720 x10: 0720072007200720
+| x9 : ffff80002a39bad0 x8 : ffff80002a39bad0
+| x7 : ffff8000119f0800 x6 : c0000000ffff7fff
+| x5 : ffff8000119f07a8 x4 : 0000000000000001
+| x3 : 9bcdab23f2432800 x2 : ffff800011730538
+| x1 : 9bcdab23f2432800 x0 : 0000000000000000
+| Call trace:
+|  lockdep_hardirqs_off+0xd4/0xe8
+|  enter_from_kernel_mode.isra.5+0x7c/0xa8
+|  el1_abort+0x24/0x100
+|  el1_sync_handler+0x80/0xd0
+|  el1_sync+0x6c/0x100
+|  __arch_clear_user+0xc/0x90
+|  load_elf_binary+0x9fc/0x1450
+|  bprm_execve+0x404/0x880
+|  kernel_execve+0x180/0x188
+|  call_usermodehelper_exec_async+0xdc/0x158
+|  ret_from_fork+0x10/0x18
+
+Fixes: 23529049c684 ("arm64: entry: fix non-NMI user<->kernel transitions")
+Fixes: 7cd1ea1010ac ("arm64: entry: fix non-NMI kernel<->kernel transitions")
+Fixes: f0cd5ac1e4c5 ("arm64: entry: fix NMI {user, kernel}->kernel transitions")
+Fixes: 2a9b3e6ac69a ("arm64: entry: fix EL1 debug transitions")
+Link: https://lore.kernel.org/r/f4012761-026f-4e51-3a0c-7524e434e8b3@huawei.com
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Reported-by: Zenghui Yu <yuzenghui@huawei.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20210428111555.50880-1-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/daifflags.h |  3 +++
+ arch/arm64/kernel/entry-common.c   | 17 -----------------
+ arch/arm64/kernel/entry.S          | 15 ++-------------
+ 3 files changed, 5 insertions(+), 30 deletions(-)
+
+diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
+index 1c26d7baa67f..cfdde3a56805 100644
+--- a/arch/arm64/include/asm/daifflags.h
++++ b/arch/arm64/include/asm/daifflags.h
+@@ -131,6 +131,9 @@ static inline void local_daif_inherit(struct pt_regs *regs)
+       if (interrupts_enabled(regs))
+               trace_hardirqs_on();
++      if (system_uses_irq_prio_masking())
++              gic_write_pmr(regs->pmr_save);
++
+       /*
+        * We can't use local_daif_restore(regs->pstate) here as
+        * system_has_prio_mask_debugging() won't restore the I bit if it can
+diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
+index 5346953e4382..ead1ecffe054 100644
+--- a/arch/arm64/kernel/entry-common.c
++++ b/arch/arm64/kernel/entry-common.c
+@@ -177,14 +177,6 @@ static void noinstr el1_dbg(struct pt_regs *regs, unsigned long esr)
+ {
+       unsigned long far = read_sysreg(far_el1);
+-      /*
+-       * The CPU masked interrupts, and we are leaving them masked during
+-       * do_debug_exception(). Update PMR as if we had called
+-       * local_daif_mask().
+-       */
+-      if (system_uses_irq_prio_masking())
+-              gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
+-
+       arm64_enter_el1_dbg(regs);
+       do_debug_exception(far, esr, regs);
+       arm64_exit_el1_dbg(regs);
+@@ -348,9 +340,6 @@ static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr)
+       /* Only watchpoints write FAR_EL1, otherwise its UNKNOWN */
+       unsigned long far = read_sysreg(far_el1);
+-      if (system_uses_irq_prio_masking())
+-              gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
+-
+       enter_from_user_mode();
+       do_debug_exception(far, esr, regs);
+       local_daif_restore(DAIF_PROCCTX_NOIRQ);
+@@ -358,9 +347,6 @@ static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr)
+ static void noinstr el0_svc(struct pt_regs *regs)
+ {
+-      if (system_uses_irq_prio_masking())
+-              gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
+-
+       enter_from_user_mode();
+       do_el0_svc(regs);
+ }
+@@ -435,9 +421,6 @@ static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr)
+ static void noinstr el0_svc_compat(struct pt_regs *regs)
+ {
+-      if (system_uses_irq_prio_masking())
+-              gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
+-
+       enter_from_user_mode();
+       do_el0_svc_compat(regs);
+ }
+diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
+index 9ce041e1078a..0deb0194fcd2 100644
+--- a/arch/arm64/kernel/entry.S
++++ b/arch/arm64/kernel/entry.S
+@@ -292,6 +292,8 @@ alternative_else_nop_endif
+ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
+       mrs_s   x20, SYS_ICC_PMR_EL1
+       str     x20, [sp, #S_PMR_SAVE]
++      mov     x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
++      msr_s   SYS_ICC_PMR_EL1, x20
+ alternative_else_nop_endif
+       /* Re-enable tag checking (TCO set on exception entry) */
+@@ -524,17 +526,7 @@ alternative_endif
+ #endif
+       .endm
+-      .macro  gic_prio_irq_setup, pmr:req, tmp:req
+-#ifdef CONFIG_ARM64_PSEUDO_NMI
+-      alternative_if ARM64_HAS_IRQ_PRIO_MASKING
+-      orr     \tmp, \pmr, #GIC_PRIO_PSR_I_SET
+-      msr_s   SYS_ICC_PMR_EL1, \tmp
+-      alternative_else_nop_endif
+-#endif
+-      .endm
+-
+       .macro el1_interrupt_handler, handler:req
+-      gic_prio_irq_setup pmr=x20, tmp=x1
+       enable_da_f
+       mov     x0, sp
+@@ -562,7 +554,6 @@ alternative_else_nop_endif
+       .endm
+       .macro el0_interrupt_handler, handler:req
+-      gic_prio_irq_setup pmr=x20, tmp=x0
+       user_exit_irqoff
+       enable_da_f
+@@ -748,7 +739,6 @@ SYM_CODE_END(el0_irq)
+ SYM_CODE_START_LOCAL(el1_error)
+       kernel_entry 1
+       mrs     x1, esr_el1
+-      gic_prio_kentry_setup tmp=x2
+       enable_dbg
+       mov     x0, sp
+       bl      do_serror
+@@ -759,7 +749,6 @@ SYM_CODE_START_LOCAL(el0_error)
+       kernel_entry 0
+ el0_error_naked:
+       mrs     x25, esr_el1
+-      gic_prio_kentry_setup tmp=x2
+       user_exit_irqoff
+       enable_dbg
+       mov     x0, sp
+-- 
+2.30.2
+
diff --git a/queue-5.11/arm64-entry-factor-irq-triage-logic-into-macros.patch b/queue-5.11/arm64-entry-factor-irq-triage-logic-into-macros.patch
new file mode 100644 (file)
index 0000000..244db59
--- /dev/null
@@ -0,0 +1,152 @@
+From bc7f8d2ac353183e5ff3189142d84ab7b7920627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Mar 2021 11:56:27 +0000
+Subject: arm64: entry: factor irq triage logic into macros
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 9eb563cdabe1d583c262042d5d44cc256f644543 ]
+
+In subsequent patches we'll allow an FIQ handler to be registered, and
+FIQ exceptions will need to be triaged very similarly to IRQ exceptions.
+So that we can reuse the existing logic, this patch factors the IRQ
+triage logic out into macros that can be reused for FIQ.
+
+The macros are named to follow the elX_foo_handler scheme used by the C
+exception handlers. For consistency with other top-level exception
+handlers, the kernel_entry/kernel_exit logic is not moved into the
+macros. As FIQ will use a different C handler, this handler name is
+provided as an argument to the macros.
+
+There should be no functional change as a result of this patch.
+
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+[Mark: rework macros, commit message, rebase before DAIF rework]
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Tested-by: Hector Martin <marcan@marcan.st>
+Cc: James Morse <james.morse@arm.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Will Deacon <will@kernel.org>
+Acked-by: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20210315115629.57191-5-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/entry.S | 80 +++++++++++++++++++++------------------
+ 1 file changed, 43 insertions(+), 37 deletions(-)
+
+diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
+index 14d5119489fe..9ce041e1078a 100644
+--- a/arch/arm64/kernel/entry.S
++++ b/arch/arm64/kernel/entry.S
+@@ -493,8 +493,8 @@ tsk        .req    x28             // current thread_info
+ /*
+  * Interrupt handling.
+  */
+-      .macro  irq_handler
+-      ldr_l   x1, handle_arch_irq
++      .macro  irq_handler, handler:req
++      ldr_l   x1, \handler
+       mov     x0, sp
+       irq_stack_entry
+       blr     x1
+@@ -533,6 +533,45 @@ alternative_endif
+ #endif
+       .endm
++      .macro el1_interrupt_handler, handler:req
++      gic_prio_irq_setup pmr=x20, tmp=x1
++      enable_da_f
++
++      mov     x0, sp
++      bl      enter_el1_irq_or_nmi
++
++      irq_handler     \handler
++
++#ifdef CONFIG_PREEMPTION
++      ldr     x24, [tsk, #TSK_TI_PREEMPT]     // get preempt count
++alternative_if ARM64_HAS_IRQ_PRIO_MASKING
++      /*
++       * DA_F were cleared at start of handling. If anything is set in DAIF,
++       * we come back from an NMI, so skip preemption
++       */
++      mrs     x0, daif
++      orr     x24, x24, x0
++alternative_else_nop_endif
++      cbnz    x24, 1f                         // preempt count != 0 || NMI return path
++      bl      arm64_preempt_schedule_irq      // irq en/disable is done inside
++1:
++#endif
++
++      mov     x0, sp
++      bl      exit_el1_irq_or_nmi
++      .endm
++
++      .macro el0_interrupt_handler, handler:req
++      gic_prio_irq_setup pmr=x20, tmp=x0
++      user_exit_irqoff
++      enable_da_f
++
++      tbz     x22, #55, 1f
++      bl      do_el0_irq_bp_hardening
++1:
++      irq_handler     \handler
++      .endm
++
+       .text
+ /*
+@@ -662,32 +701,7 @@ SYM_CODE_END(el1_sync)
+       .align  6
+ SYM_CODE_START_LOCAL_NOALIGN(el1_irq)
+       kernel_entry 1
+-      gic_prio_irq_setup pmr=x20, tmp=x1
+-      enable_da_f
+-
+-      mov     x0, sp
+-      bl      enter_el1_irq_or_nmi
+-
+-      irq_handler
+-
+-#ifdef CONFIG_PREEMPTION
+-      ldr     x24, [tsk, #TSK_TI_PREEMPT]     // get preempt count
+-alternative_if ARM64_HAS_IRQ_PRIO_MASKING
+-      /*
+-       * DA_F were cleared at start of handling. If anything is set in DAIF,
+-       * we come back from an NMI, so skip preemption
+-       */
+-      mrs     x0, daif
+-      orr     x24, x24, x0
+-alternative_else_nop_endif
+-      cbnz    x24, 1f                         // preempt count != 0 || NMI return path
+-      bl      arm64_preempt_schedule_irq      // irq en/disable is done inside
+-1:
+-#endif
+-
+-      mov     x0, sp
+-      bl      exit_el1_irq_or_nmi
+-
++      el1_interrupt_handler handle_arch_irq
+       kernel_exit 1
+ SYM_CODE_END(el1_irq)
+@@ -727,15 +741,7 @@ SYM_CODE_END(el0_error_compat)
+ SYM_CODE_START_LOCAL_NOALIGN(el0_irq)
+       kernel_entry 0
+ el0_irq_naked:
+-      gic_prio_irq_setup pmr=x20, tmp=x0
+-      user_exit_irqoff
+-      enable_da_f
+-
+-      tbz     x22, #55, 1f
+-      bl      do_el0_irq_bp_hardening
+-1:
+-      irq_handler
+-
++      el0_interrupt_handler handle_arch_irq
+       b       ret_to_user
+ SYM_CODE_END(el0_irq)
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-intel-bytcr_rt5640-add-quirk-for-the-chuwi-hi8-.patch b/queue-5.11/asoc-intel-bytcr_rt5640-add-quirk-for-the-chuwi-hi8-.patch
new file mode 100644 (file)
index 0000000..8b9147f
--- /dev/null
@@ -0,0 +1,56 @@
+From 471172ed3629f560b8c56a7cc75ac44d9d9f6ff5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 23:10:54 +0100
+Subject: ASoC: Intel: bytcr_rt5640: Add quirk for the Chuwi Hi8 tablet
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 875c40eadf6ac6644c0f71842a4f30dd9968d281 ]
+
+The Chuwi Hi8 tablet is using an analog mic on IN1 and has its
+jack-detect connected to JD2_IN4N, instead of using the default
+IN3 for its internal mic and JD1_IN4P for jack-detect.
+
+It also only has 1 speaker.
+
+Add a quirk applying the correct settings for this configuration.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20210325221054.22714-1-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcr_rt5640.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index 07730ed7ab3c..d45f43290653 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -514,6 +514,23 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+                                       BYT_RT5640_SSP0_AIF1 |
+                                       BYT_RT5640_MCLK_EN),
+       },
++      {
++              /* Chuwi Hi8 (CWI509) */
++              .matches = {
++                      DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
++                      DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
++                      DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
++              },
++              .driver_data = (void *)(BYT_RT5640_IN1_MAP |
++                                      BYT_RT5640_JD_SRC_JD2_IN4N |
++                                      BYT_RT5640_OVCD_TH_2000UA |
++                                      BYT_RT5640_OVCD_SF_0P75 |
++                                      BYT_RT5640_MONO_SPEAKER |
++                                      BYT_RT5640_DIFF_MIC |
++                                      BYT_RT5640_SSP0_AIF1 |
++                                      BYT_RT5640_MCLK_EN),
++      },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-intel-bytcr_rt5640-enable-jack-detect-support-o.patch b/queue-5.11/asoc-intel-bytcr_rt5640-enable-jack-detect-support-o.patch
new file mode 100644 (file)
index 0000000..2e8643e
--- /dev/null
@@ -0,0 +1,41 @@
+From 2fe2e27ce859adf181c265e74876502b45b3a81b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 12:48:50 +0100
+Subject: ASoC: Intel: bytcr_rt5640: Enable jack-detect support on Asus T100TAF
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit b7c7203a1f751348f35fc4bcb157572d303f7573 ]
+
+The Asus T100TAF uses the same jack-detect settings as the T100TA,
+this has been confirmed on actual hardware.
+
+Add these settings to the T100TAF quirks to enable jack-detect support
+on the T100TAF.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210312114850.13832-1-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcr_rt5640.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index 21d2e1cba380..07730ed7ab3c 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -478,6 +478,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
+               },
+               .driver_data = (void *)(BYT_RT5640_IN1_MAP |
++                                      BYT_RT5640_JD_SRC_JD2_IN4N |
++                                      BYT_RT5640_OVCD_TH_2000UA |
++                                      BYT_RT5640_OVCD_SF_0P75 |
+                                       BYT_RT5640_MONO_SPEAKER |
+                                       BYT_RT5640_DIFF_MIC |
+                                       BYT_RT5640_SSP0_AIF2 |
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-intel-sof_sdw-add-quirk-for-new-adl-p-rvp.patch b/queue-5.11/asoc-intel-sof_sdw-add-quirk-for-new-adl-p-rvp.patch
new file mode 100644 (file)
index 0000000..3265697
--- /dev/null
@@ -0,0 +1,47 @@
+From 1fc114cf6e8031a5b416b7efdf614644d102f753 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 12:50:09 -0500
+Subject: ASoC: Intel: sof_sdw: add quirk for new ADL-P Rvp
+
+From: Vamshi Krishna Gopal <vamshi.krishna.gopal@intel.com>
+
+[ Upstream commit d25bbe80485f8bcbbeb91a2a6cd8798c124b27b7 ]
+
+Add quirks for jack detection, rt711 DAI and DMIC
+
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Signed-off-by: Vamshi Krishna Gopal <vamshi.krishna.gopal@intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210415175013.192862-6-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 1d7677376e74..9dc982c2c776 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -187,6 +187,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+                                       SOF_RT715_DAI_ID_FIX |
+                                       SOF_SDW_FOUR_SPK),
+       },
++      /* AlderLake devices */
++      {
++              .callback = sof_sdw_quirk_cb,
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
++              },
++              .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
++                                      SOF_SDW_TGL_HDMI |
++                                      SOF_SDW_PCH_DMIC),
++      },
+       {}
+ };
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-rsnd-call-rsnd_ssi_master_clk_start-from-rsnd_s.patch b/queue-5.11/asoc-rsnd-call-rsnd_ssi_master_clk_start-from-rsnd_s.patch
new file mode 100644 (file)
index 0000000..baa765f
--- /dev/null
@@ -0,0 +1,116 @@
+From a86a9f89d1280e9f0f75b701e073fb1965b0dad7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 13:28:38 +0900
+Subject: ASoC: rsnd: call rsnd_ssi_master_clk_start() from rsnd_ssi_init()
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+[ Upstream commit a122a116fc6d8fcf2f202dcd185173a54268f239 ]
+
+Current rsnd needs to call .prepare (P) for clock settings,
+.trigger for playback start (S) and stop (E).
+It should be called as below from SSI point of view.
+
+       P -> S -> E -> P -> S -> E -> ...
+
+But, if you used MIXer, below case might happen
+
+                     (2)
+       1: P -> S ---> E -> ...
+       2:         P ----> S -> ...
+                 (1)     (3)
+
+P(1) setups clock, but E(2) resets it. and starts playback (3).
+In such case, it will reports "SSI parent/child should use same rate".
+
+rsnd_ssi_master_clk_start() which is the main function at (P)
+was called from rsnd_ssi_init() (= S) before,
+but was moved by below patch to rsnd_soc_dai_prepare() (= P) to avoid
+using clk_get_rate() which shouldn't be used under atomic context.
+
+       commit 4d230d1271064 ("ASoC: rsnd: fixup not to call clk_get/set
+                               under non-atomic")
+
+Because of above patch, rsnd_ssi_master_clk_start() is now called at (P)
+which is for non atomic context. But (P) is assuming that spin lock is
+*not* used.
+One issue now is rsnd_ssi_master_clk_start() is checking ssi->xxx
+which should be protected by spin lock.
+
+After above patch, adg.c had below patch for other reasons.
+
+       commit 06e8f5c842f2d ("ASoC: rsnd: don't call clk_get_rate()
+                               under atomic context")
+
+clk_get_rate() is used at probe() timing by this patch.
+In other words, rsnd_ssi_master_clk_start() is no longer using
+clk_get_rate() any more.
+
+This means we can call it from rsnd_ssi_init() (= S) again which is
+protected by spin lock.
+This patch re-move it to under spin lock, and solves
+1. checking ssi->xxx without spin lock issue.
+2. clk setting / device start / device stop race condition.
+
+Reported-by: Linh Phung T. Y. <linh.phung.jy@renesas.com>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Link: https://lore.kernel.org/r/875z0x1jt5.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sh/rcar/ssi.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
+index d0ded427a836..a2f8138d40c7 100644
+--- a/sound/soc/sh/rcar/ssi.c
++++ b/sound/soc/sh/rcar/ssi.c
+@@ -507,10 +507,15 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
+                        struct rsnd_priv *priv)
+ {
+       struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
++      int ret;
+       if (!rsnd_ssi_is_run_mods(mod, io))
+               return 0;
++      ret = rsnd_ssi_master_clk_start(mod, io);
++      if (ret < 0)
++              return ret;
++
+       ssi->usrcnt++;
+       rsnd_mod_power_on(mod);
+@@ -1060,13 +1065,6 @@ static int rsnd_ssi_pio_pointer(struct rsnd_mod *mod,
+       return 0;
+ }
+-static int rsnd_ssi_prepare(struct rsnd_mod *mod,
+-                          struct rsnd_dai_stream *io,
+-                          struct rsnd_priv *priv)
+-{
+-      return rsnd_ssi_master_clk_start(mod, io);
+-}
+-
+ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
+       .name           = SSI_NAME,
+       .probe          = rsnd_ssi_common_probe,
+@@ -1079,7 +1077,6 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
+       .pointer        = rsnd_ssi_pio_pointer,
+       .pcm_new        = rsnd_ssi_pcm_new,
+       .hw_params      = rsnd_ssi_hw_params,
+-      .prepare        = rsnd_ssi_prepare,
+       .get_status     = rsnd_ssi_get_status,
+ };
+@@ -1166,7 +1163,6 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
+       .pcm_new        = rsnd_ssi_pcm_new,
+       .fallback       = rsnd_ssi_fallback,
+       .hw_params      = rsnd_ssi_hw_params,
+-      .prepare        = rsnd_ssi_prepare,
+       .get_status     = rsnd_ssi_get_status,
+ };
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-rsnd-core-check-convert-rate-in-rsnd_hw_params.patch b/queue-5.11/asoc-rsnd-core-check-convert-rate-in-rsnd_hw_params.patch
new file mode 100644 (file)
index 0000000..0d4cfe3
--- /dev/null
@@ -0,0 +1,113 @@
+From a98dec948cc6fb96f12fbb585dc7fd5110932448 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Mar 2021 14:47:35 +1000
+Subject: ASoC: rsnd: core: Check convert rate in rsnd_hw_params
+
+From: Mikhail Durnev <mikhail_durnev@mentor.com>
+
+[ Upstream commit 19c6a63ced5e07e40f3a5255cb1f0fe0d3be7b14 ]
+
+snd_pcm_hw_params_set_rate_near can return incorrect sample rate in
+some cases, e.g. when the backend output rate is set to some value higher
+than 48000 Hz and the input rate is 8000 Hz. So passing the value returned
+by snd_pcm_hw_params_set_rate_near to snd_pcm_hw_params will result in
+"FSO/FSI ratio error" and playing no audio at all while the userland
+is not properly notified about the issue.
+
+If SRC is unable to convert the requested sample rate to the sample rate
+the backend is using, then the requested sample rate should be adjusted in
+rsnd_hw_params. The userland will be notified about that change in the
+returned hw_params structure.
+
+Signed-off-by: Mikhail Durnev <mikhail_durnev@mentor.com>
+Link: https://lore.kernel.org/r/1615870055-13954-1-git-send-email-mikhail_durnev@mentor.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sh/rcar/core.c | 69 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 68 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
+index 6e670b3e92a0..289928d4c0c9 100644
+--- a/sound/soc/sh/rcar/core.c
++++ b/sound/soc/sh/rcar/core.c
+@@ -1428,8 +1428,75 @@ static int rsnd_hw_params(struct snd_soc_component *component,
+               }
+               if (io->converted_chan)
+                       dev_dbg(dev, "convert channels = %d\n", io->converted_chan);
+-              if (io->converted_rate)
++              if (io->converted_rate) {
++                      /*
++                       * SRC supports convert rates from params_rate(hw_params)/k_down
++                       * to params_rate(hw_params)*k_up, where k_up is always 6, and
++                       * k_down depends on number of channels and SRC unit.
++                       * So all SRC units can upsample audio up to 6 times regardless
++                       * its number of channels. And all SRC units can downsample
++                       * 2 channel audio up to 6 times too.
++                       */
++                      int k_up = 6;
++                      int k_down = 6;
++                      int channel;
++                      struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
++
+                       dev_dbg(dev, "convert rate     = %d\n", io->converted_rate);
++
++                      channel = io->converted_chan ? io->converted_chan :
++                                params_channels(hw_params);
++
++                      switch (rsnd_mod_id(src_mod)) {
++                      /*
++                       * SRC0 can downsample 4, 6 and 8 channel audio up to 4 times.
++                       * SRC1, SRC3 and SRC4 can downsample 4 channel audio
++                       * up to 4 times.
++                       * SRC1, SRC3 and SRC4 can downsample 6 and 8 channel audio
++                       * no more than twice.
++                       */
++                      case 1:
++                      case 3:
++                      case 4:
++                              if (channel > 4) {
++                                      k_down = 2;
++                                      break;
++                              }
++                              fallthrough;
++                      case 0:
++                              if (channel > 2)
++                                      k_down = 4;
++                              break;
++
++                      /* Other SRC units do not support more than 2 channels */
++                      default:
++                              if (channel > 2)
++                                      return -EINVAL;
++                      }
++
++                      if (params_rate(hw_params) > io->converted_rate * k_down) {
++                              hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->min =
++                                      io->converted_rate * k_down;
++                              hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->max =
++                                      io->converted_rate * k_down;
++                              hw_params->cmask |= SNDRV_PCM_HW_PARAM_RATE;
++                      } else if (params_rate(hw_params) * k_up < io->converted_rate) {
++                              hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->min =
++                                      (io->converted_rate + k_up - 1) / k_up;
++                              hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->max =
++                                      (io->converted_rate + k_up - 1) / k_up;
++                              hw_params->cmask |= SNDRV_PCM_HW_PARAM_RATE;
++                      }
++
++                      /*
++                       * TBD: Max SRC input and output rates also depend on number
++                       * of channels and SRC unit:
++                       * SRC1, SRC3 and SRC4 do not support more than 128kHz
++                       * for 6 channel and 96kHz for 8 channel audio.
++                       * Perhaps this function should return EINVAL if the input or
++                       * the output rate exceeds the limitation.
++                       */
++              }
+       }
+       return rsnd_dai_call(hw_params, io, substream, hw_params);
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-rt286-generalize-support-for-alc3263-codec.patch b/queue-5.11/asoc-rt286-generalize-support-for-alc3263-codec.patch
new file mode 100644 (file)
index 0000000..4930f45
--- /dev/null
@@ -0,0 +1,99 @@
+From 306b3381b216e5ca43a5fa60141180fa05056412 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Apr 2021 09:46:58 -0400
+Subject: ASoC: rt286: Generalize support for ALC3263 codec
+
+From: David Ward <david.ward@gatech.edu>
+
+[ Upstream commit aa2f9c12821e6a4ba1df4fb34a3dbc6a2a1ee7fe ]
+
+The ALC3263 codec on the XPS 13 9343 is also found on the Latitude 13 7350
+and Venue 11 Pro 7140. They require the same handling for the combo jack to
+work with a headset: GPIO pin 6 must be set.
+
+The HDA driver always sets this pin on the ALC3263, which it distinguishes
+by the codec vendor/device ID 0x10ec0288 and PCI subsystem vendor ID 0x1028
+(Dell). The ASoC driver does not use PCI, so adapt this check to use DMI to
+determine if Dell is the system vendor.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=150601
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205961
+Signed-off-by: David Ward <david.ward@gatech.edu>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210418134658.4333-6-david.ward@gatech.edu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt286.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
+index 5fb9653d9131..8ae2e2eaad3d 100644
+--- a/sound/soc/codecs/rt286.c
++++ b/sound/soc/codecs/rt286.c
+@@ -1117,12 +1117,11 @@ static const struct dmi_system_id force_combo_jack_table[] = {
+       { }
+ };
+-static const struct dmi_system_id dmi_dell_dino[] = {
++static const struct dmi_system_id dmi_dell[] = {
+       {
+-              .ident = "Dell Dino",
++              .ident = "Dell",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+-                      DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343")
+               }
+       },
+       { }
+@@ -1133,7 +1132,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
+ {
+       struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev);
+       struct rt286_priv *rt286;
+-      int i, ret, val;
++      int i, ret, vendor_id;
+       rt286 = devm_kzalloc(&i2c->dev, sizeof(*rt286),
+                               GFP_KERNEL);
+@@ -1149,14 +1148,15 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
+       }
+       ret = regmap_read(rt286->regmap,
+-              RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val);
++              RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &vendor_id);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "I2C error %d\n", ret);
+               return ret;
+       }
+-      if (val != RT286_VENDOR_ID && val != RT288_VENDOR_ID) {
++      if (vendor_id != RT286_VENDOR_ID && vendor_id != RT288_VENDOR_ID) {
+               dev_err(&i2c->dev,
+-                      "Device with ID register %#x is not rt286\n", val);
++                      "Device with ID register %#x is not rt286\n",
++                      vendor_id);
+               return -ENODEV;
+       }
+@@ -1180,8 +1180,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
+       if (pdata)
+               rt286->pdata = *pdata;
+-      if (dmi_check_system(force_combo_jack_table) ||
+-              dmi_check_system(dmi_dell_dino))
++      if ((vendor_id == RT288_VENDOR_ID && dmi_check_system(dmi_dell)) ||
++              dmi_check_system(force_combo_jack_table))
+               rt286->pdata.cbj_en = true;
+       regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3);
+@@ -1220,7 +1220,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
+       regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737);
+       regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f);
+-      if (dmi_check_system(dmi_dell_dino)) {
++      if (vendor_id == RT288_VENDOR_ID && dmi_check_system(dmi_dell)) {
+               regmap_update_bits(rt286->regmap,
+                       RT286_SET_GPIO_MASK, 0x40, 0x40);
+               regmap_update_bits(rt286->regmap,
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-rt286-make-rt286_set_gpio_-readable-and-writabl.patch b/queue-5.11/asoc-rt286-make-rt286_set_gpio_-readable-and-writabl.patch
new file mode 100644 (file)
index 0000000..b0f0529
--- /dev/null
@@ -0,0 +1,39 @@
+From 6ee57ff7701ebd1b973c95ca854930cc27a09926 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Apr 2021 09:46:57 -0400
+Subject: ASoC: rt286: Make RT286_SET_GPIO_* readable and writable
+
+From: David Ward <david.ward@gatech.edu>
+
+[ Upstream commit cd8499d5c03ba260e3191e90236d0e5f6b147563 ]
+
+The GPIO configuration cannot be applied if the registers are inaccessible.
+This prevented the headset mic from working on the Dell XPS 13 9343.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=114171
+Signed-off-by: David Ward <david.ward@gatech.edu>
+Link: https://lore.kernel.org/r/20210418134658.4333-5-david.ward@gatech.edu
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt286.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
+index 8ae2e2eaad3d..eec2dd93ecbb 100644
+--- a/sound/soc/codecs/rt286.c
++++ b/sound/soc/codecs/rt286.c
+@@ -171,6 +171,9 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg)
+       case RT286_PROC_COEF:
+       case RT286_SET_AMP_GAIN_ADC_IN1:
+       case RT286_SET_AMP_GAIN_ADC_IN2:
++      case RT286_SET_GPIO_MASK:
++      case RT286_SET_GPIO_DIRECTION:
++      case RT286_SET_GPIO_DATA:
+       case RT286_SET_POWER(RT286_DAC_OUT1):
+       case RT286_SET_POWER(RT286_DAC_OUT2):
+       case RT286_SET_POWER(RT286_ADC_IN1):
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-rt5670-add-a-quirk-for-the-dell-venue-10-pro-50.patch b/queue-5.11/asoc-rt5670-add-a-quirk-for-the-dell-venue-10-pro-50.patch
new file mode 100644 (file)
index 0000000..38a6446
--- /dev/null
@@ -0,0 +1,47 @@
+From f18231852718cc33d29a40720ff30c24c2692b41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Apr 2021 16:07:45 +0200
+Subject: ASoC: rt5670: Add a quirk for the Dell Venue 10 Pro 5055
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 84cb0d5581b6a7bd5d96013f67e9f2eb0c7b4378 ]
+
+Add a quirk with the jack-detect and dmic settings necessary to make
+jack-detect and the builtin mic work on Dell Venue 10 Pro 5055 tablets.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210402140747.174716-5-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt5670.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
+index a0c8f58d729b..47ce074289ca 100644
+--- a/sound/soc/codecs/rt5670.c
++++ b/sound/soc/codecs/rt5670.c
+@@ -2908,6 +2908,18 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = {
+                                                RT5670_GPIO1_IS_IRQ |
+                                                RT5670_JD_MODE3),
+       },
++      {
++              .callback = rt5670_quirk_cb,
++              .ident = "Dell Venue 10 Pro 5055",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"),
++              },
++              .driver_data = (unsigned long *)(RT5670_DMIC_EN |
++                                               RT5670_DMIC2_INR |
++                                               RT5670_GPIO1_IS_IRQ |
++                                               RT5670_JD_MODE1),
++      },
+       {
+               .callback = rt5670_quirk_cb,
+               .ident = "Aegex 10 tablet (RU2)",
+-- 
+2.30.2
+
diff --git a/queue-5.11/asoc-soc-compress-lock-pcm_mutex-to-resolve-lockdep-.patch b/queue-5.11/asoc-soc-compress-lock-pcm_mutex-to-resolve-lockdep-.patch
new file mode 100644 (file)
index 0000000..d78ff0f
--- /dev/null
@@ -0,0 +1,61 @@
+From 5cc7623300c1a3d7d0f1d8712b293fa1ca3115e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 13:14:04 +0900
+Subject: ASoC: soc-compress: lock pcm_mutex to resolve lockdep error
+
+From: Gyeongtaek Lee <gt82.lee@samsung.com>
+
+[ Upstream commit 45475bf60cc1d42da229a0aa757180c88bab8d22 ]
+
+If panic_on_warn=1 is added in bootargs and compress offload playback with
+DPCM is started, kernel panic would be occurred because rtd->card->pcm_mutex
+isn't held in soc_compr_open_fe() and soc_compr_free_fe() and it generates
+lockdep warning in the following code.
+
+void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd,
+                           int stream, int action)
+{
+       struct snd_soc_dai *dai;
+       int i;
+
+       lockdep_assert_held(&rtd->card->pcm_mutex);
+
+To prevent lockdep warning but minimize side effect by adding mutex,
+pcm_mutex is held just before snd_soc_runtime_activate() and
+snd_soc_runtime_deactivate() and is released right after them.
+
+Signed-off-by: Gyeongtaek Lee <gt82.lee@samsung.com>
+Link: https://lore.kernel.org/r/1891546521.01617772502282.JavaMail.epsvc@epcpadp3
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-compress.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
+index 246a5e32e22a..b4810266f5e5 100644
+--- a/sound/soc/soc-compress.c
++++ b/sound/soc/soc-compress.c
+@@ -153,7 +153,9 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
+       fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
+       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
++      mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass);
+       snd_soc_runtime_activate(fe, stream);
++      mutex_unlock(&fe->card->pcm_mutex);
+       mutex_unlock(&fe->card->mutex);
+@@ -181,7 +183,9 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
+       mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
++      mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass);
+       snd_soc_runtime_deactivate(fe, stream);
++      mutex_unlock(&fe->card->pcm_mutex);
+       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+-- 
+2.30.2
+
diff --git a/queue-5.11/ata-ahci_brcm-fix-use-of-bcm7216-reset-controller.patch b/queue-5.11/ata-ahci_brcm-fix-use-of-bcm7216-reset-controller.patch
new file mode 100644 (file)
index 0000000..4bb397d
--- /dev/null
@@ -0,0 +1,129 @@
+From d482fce6d4df09adb2d59854786ed7c79d08d37a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 11:21:55 -0400
+Subject: ata: ahci_brcm: Fix use of BCM7216 reset controller
+
+From: Jim Quinlan <jim2101024@gmail.com>
+
+[ Upstream commit e8d6f9e56187c101b325e8d18f1d4032420d08ff ]
+
+This driver may use one of two resets controllers.  Keep them in separate
+variables to keep things simple.  The reset controller "rescal" is shared
+between the AHCI driver and the PCIe driver for the BrcmSTB 7216 chip.  Use
+devm_reset_control_get_optional_shared() to handle this sharing.
+
+[bhelgaas: add Jens' ack from v5 posting]
+Fixes: 272ecd60a636 ("ata: ahci_brcm: BCM7216 reset is self de-asserting")
+Fixes: c345ec6a50e9 ("ata: ahci_brcm: Support BCM7216 reset controller name")
+Link: https://lore.kernel.org/r/20210430152156.21162-3-jim2101024@gmail.com
+Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Jens Axboe <axboe@kernel.dk>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/ahci_brcm.c | 46 ++++++++++++++++++++---------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c
+index 5b32df5d33ad..6e9c5ade4c2e 100644
+--- a/drivers/ata/ahci_brcm.c
++++ b/drivers/ata/ahci_brcm.c
+@@ -86,7 +86,8 @@ struct brcm_ahci_priv {
+       u32 port_mask;
+       u32 quirks;
+       enum brcm_ahci_version version;
+-      struct reset_control *rcdev;
++      struct reset_control *rcdev_rescal;
++      struct reset_control *rcdev_ahci;
+ };
+ static inline u32 brcm_sata_readreg(void __iomem *addr)
+@@ -352,8 +353,8 @@ static int brcm_ahci_suspend(struct device *dev)
+       else
+               ret = 0;
+-      if (priv->version != BRCM_SATA_BCM7216)
+-              reset_control_assert(priv->rcdev);
++      reset_control_assert(priv->rcdev_ahci);
++      reset_control_rearm(priv->rcdev_rescal);
+       return ret;
+ }
+@@ -365,10 +366,10 @@ static int __maybe_unused brcm_ahci_resume(struct device *dev)
+       struct brcm_ahci_priv *priv = hpriv->plat_data;
+       int ret = 0;
+-      if (priv->version == BRCM_SATA_BCM7216)
+-              ret = reset_control_reset(priv->rcdev);
+-      else
+-              ret = reset_control_deassert(priv->rcdev);
++      ret = reset_control_deassert(priv->rcdev_ahci);
++      if (ret)
++              return ret;
++      ret = reset_control_reset(priv->rcdev_rescal);
+       if (ret)
+               return ret;
+@@ -434,7 +435,6 @@ static int brcm_ahci_probe(struct platform_device *pdev)
+ {
+       const struct of_device_id *of_id;
+       struct device *dev = &pdev->dev;
+-      const char *reset_name = NULL;
+       struct brcm_ahci_priv *priv;
+       struct ahci_host_priv *hpriv;
+       struct resource *res;
+@@ -456,15 +456,15 @@ static int brcm_ahci_probe(struct platform_device *pdev)
+       if (IS_ERR(priv->top_ctrl))
+               return PTR_ERR(priv->top_ctrl);
+-      /* Reset is optional depending on platform and named differently */
+-      if (priv->version == BRCM_SATA_BCM7216)
+-              reset_name = "rescal";
+-      else
+-              reset_name = "ahci";
+-
+-      priv->rcdev = devm_reset_control_get_optional(&pdev->dev, reset_name);
+-      if (IS_ERR(priv->rcdev))
+-              return PTR_ERR(priv->rcdev);
++      if (priv->version == BRCM_SATA_BCM7216) {
++              priv->rcdev_rescal = devm_reset_control_get_optional_shared(
++                      &pdev->dev, "rescal");
++              if (IS_ERR(priv->rcdev_rescal))
++                      return PTR_ERR(priv->rcdev_rescal);
++      }
++      priv->rcdev_ahci = devm_reset_control_get_optional(&pdev->dev, "ahci");
++      if (IS_ERR(priv->rcdev_ahci))
++              return PTR_ERR(priv->rcdev_ahci);
+       hpriv = ahci_platform_get_resources(pdev, 0);
+       if (IS_ERR(hpriv))
+@@ -485,10 +485,10 @@ static int brcm_ahci_probe(struct platform_device *pdev)
+               break;
+       }
+-      if (priv->version == BRCM_SATA_BCM7216)
+-              ret = reset_control_reset(priv->rcdev);
+-      else
+-              ret = reset_control_deassert(priv->rcdev);
++      ret = reset_control_reset(priv->rcdev_rescal);
++      if (ret)
++              return ret;
++      ret = reset_control_deassert(priv->rcdev_ahci);
+       if (ret)
+               return ret;
+@@ -539,8 +539,8 @@ out_disable_regulators:
+ out_disable_clks:
+       ahci_platform_disable_clks(hpriv);
+ out_reset:
+-      if (priv->version != BRCM_SATA_BCM7216)
+-              reset_control_assert(priv->rcdev);
++      reset_control_assert(priv->rcdev_ahci);
++      reset_control_rearm(priv->rcdev_rescal);
+       return ret;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/ath11k-fix-thermal-temperature-read.patch b/queue-5.11/ath11k-fix-thermal-temperature-read.patch
new file mode 100644 (file)
index 0000000..fbb901d
--- /dev/null
@@ -0,0 +1,106 @@
+From 1a6f2feb14ad3822185015201839d3617cb6668c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Feb 2021 10:27:08 -0800
+Subject: ath11k: fix thermal temperature read
+
+From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
+
+[ Upstream commit e3de5bb7ac1a4cb262f8768924fd3ef6182b10bb ]
+
+Fix dangling pointer in thermal temperature event which causes
+incorrect temperature read.
+
+Tested-on: IPQ8074 AHB WLAN.HK.2.4.0.1-00041-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210218182708.8844-1-pradeepc@codeaurora.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/wmi.c | 53 +++++++++++----------------
+ 1 file changed, 21 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 73869d445c5b..f457a089b63c 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -5190,31 +5190,6 @@ int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb,
+       return 0;
+ }
+-static int
+-ath11k_pull_pdev_temp_ev(struct ath11k_base *ab, u8 *evt_buf,
+-                       u32 len, const struct wmi_pdev_temperature_event *ev)
+-{
+-      const void **tb;
+-      int ret;
+-
+-      tb = ath11k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC);
+-      if (IS_ERR(tb)) {
+-              ret = PTR_ERR(tb);
+-              ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
+-              return ret;
+-      }
+-
+-      ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
+-      if (!ev) {
+-              ath11k_warn(ab, "failed to fetch pdev temp ev");
+-              kfree(tb);
+-              return -EPROTO;
+-      }
+-
+-      kfree(tb);
+-      return 0;
+-}
+-
+ size_t ath11k_wmi_fw_stats_num_vdevs(struct list_head *head)
+ {
+       struct ath11k_fw_stats_vdev *i;
+@@ -6622,23 +6597,37 @@ ath11k_wmi_pdev_temperature_event(struct ath11k_base *ab,
+                                 struct sk_buff *skb)
+ {
+       struct ath11k *ar;
+-      struct wmi_pdev_temperature_event ev = {0};
++      const void **tb;
++      const struct wmi_pdev_temperature_event *ev;
++      int ret;
++
++      tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
++      if (IS_ERR(tb)) {
++              ret = PTR_ERR(tb);
++              ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
++              return;
++      }
+-      if (ath11k_pull_pdev_temp_ev(ab, skb->data, skb->len, &ev) != 0) {
+-              ath11k_warn(ab, "failed to extract pdev temperature event");
++      ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
++      if (!ev) {
++              ath11k_warn(ab, "failed to fetch pdev temp ev");
++              kfree(tb);
+               return;
+       }
+       ath11k_dbg(ab, ATH11K_DBG_WMI,
+-                 "pdev temperature ev temp %d pdev_id %d\n", ev.temp, ev.pdev_id);
++                 "pdev temperature ev temp %d pdev_id %d\n", ev->temp, ev->pdev_id);
+-      ar = ath11k_mac_get_ar_by_pdev_id(ab, ev.pdev_id);
++      ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
+       if (!ar) {
+-              ath11k_warn(ab, "invalid pdev id in pdev temperature ev %d", ev.pdev_id);
++              ath11k_warn(ab, "invalid pdev id in pdev temperature ev %d", ev->pdev_id);
++              kfree(tb);
+               return;
+       }
+-      ath11k_thermal_event_temperature(ar, ev.temp);
++      ath11k_thermal_event_temperature(ar, ev->temp);
++
++      kfree(tb);
+ }
+ static void ath11k_fils_discovery_event(struct ath11k_base *ab,
+-- 
+2.30.2
+
diff --git a/queue-5.11/block-rnbd-clt-change-queue_depth-type-in-rnbd_clt_s.patch b/queue-5.11/block-rnbd-clt-change-queue_depth-type-in-rnbd_clt_s.patch
new file mode 100644 (file)
index 0000000..9f9678e
--- /dev/null
@@ -0,0 +1,40 @@
+From c6f1d83330672388348bd6d9110e6de420d89be1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 08:13:56 +0200
+Subject: block/rnbd-clt: Change queue_depth type in rnbd_clt_session to size_t
+
+From: Md Haris Iqbal <haris.iqbal@cloud.ionos.com>
+
+[ Upstream commit 80d43cbd46155744ee450d2476ee4fcf2917ae9b ]
+
+The member queue_depth in the structure rnbd_clt_session is read from the
+rtrs client side using the function rtrs_clt_query, which in turn is read
+from the rtrs_clt structure. It should really be of type size_t.
+
+Fixes: 90426e89f54db ("block/rnbd: client: private header with client structs and functions")
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Reviewed-by: Guoqing Jiang <guoqing.jiang@ionos.com>
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Link: https://lore.kernel.org/r/20210428061359.206794-2-gi-oh.kim@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/rnbd/rnbd-clt.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/block/rnbd/rnbd-clt.h b/drivers/block/rnbd/rnbd-clt.h
+index 537d499dad3b..73d980840531 100644
+--- a/drivers/block/rnbd/rnbd-clt.h
++++ b/drivers/block/rnbd/rnbd-clt.h
+@@ -87,7 +87,7 @@ struct rnbd_clt_session {
+       DECLARE_BITMAP(cpu_queues_bm, NR_CPUS);
+       int     __percpu        *cpu_rr; /* per-cpu var for CPU round-robin */
+       atomic_t                busy;
+-      int                     queue_depth;
++      size_t                  queue_depth;
+       u32                     max_io_size;
+       struct blk_mq_tag_set   tag_set;
+       struct mutex            lock; /* protects state and devs_list */
+-- 
+2.30.2
+
diff --git a/queue-5.11/block-rnbd-clt-check-the-return-value-of-the-functio.patch b/queue-5.11/block-rnbd-clt-check-the-return-value-of-the-functio.patch
new file mode 100644 (file)
index 0000000..eb13a3c
--- /dev/null
@@ -0,0 +1,58 @@
+From 0747f8ecb448b6d9f9aea016f61a3939998c5cdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 08:13:58 +0200
+Subject: block/rnbd-clt: Check the return value of the function rtrs_clt_query
+
+From: Md Haris Iqbal <haris.iqbal@cloud.ionos.com>
+
+[ Upstream commit 1056ad829ec43f9b705b507c2093b05e2088b0b7 ]
+
+In case none of the paths are in connected state, the function
+rtrs_clt_query returns an error. In such a case, error out since the
+values in the rtrs_attrs structure would be garbage.
+
+Fixes: f7a7a5c228d45 ("block/rnbd: client: main functionality")
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Reviewed-by: Guoqing Jiang <guoqing.jiang@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Link: https://lore.kernel.org/r/20210428061359.206794-4-gi-oh.kim@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/rnbd/rnbd-clt.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
+index 45a470076652..5ab7319ff2ea 100644
+--- a/drivers/block/rnbd/rnbd-clt.c
++++ b/drivers/block/rnbd/rnbd-clt.c
+@@ -693,7 +693,11 @@ static void remap_devs(struct rnbd_clt_session *sess)
+               return;
+       }
+-      rtrs_clt_query(sess->rtrs, &attrs);
++      err = rtrs_clt_query(sess->rtrs, &attrs);
++      if (err) {
++              pr_err("rtrs_clt_query(\"%s\"): %d\n", sess->sessname, err);
++              return;
++      }
+       mutex_lock(&sess->lock);
+       sess->max_io_size = attrs.max_io_size;
+@@ -1234,7 +1238,11 @@ find_and_get_or_create_sess(const char *sessname,
+               err = PTR_ERR(sess->rtrs);
+               goto wake_up_and_put;
+       }
+-      rtrs_clt_query(sess->rtrs, &attrs);
++
++      err = rtrs_clt_query(sess->rtrs, &attrs);
++      if (err)
++              goto close_rtrs;
++
+       sess->max_io_size = attrs.max_io_size;
+       sess->queue_depth = attrs.queue_depth;
+-- 
+2.30.2
+
diff --git a/queue-5.11/bluetooth-btusb-enable-quirk-boolean-flag-for-mediat.patch b/queue-5.11/bluetooth-btusb-enable-quirk-boolean-flag-for-mediat.patch
new file mode 100644 (file)
index 0000000..cab465c
--- /dev/null
@@ -0,0 +1,36 @@
+From 3d2d7fd9fc498eca7ab91f74522cb829f8d06bc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 01:18:33 +0800
+Subject: Bluetooth: btusb: Enable quirk boolean flag for Mediatek Chip.
+
+From: mark-yw.chen <mark-yw.chen@mediatek.com>
+
+[ Upstream commit 27e554a4fcd84e499bf0a82122b8c4c3f1de38b6 ]
+
+Adding support LE scatternet and WBS for Mediatek Chip
+
+Signed-off-by: mark-yw.chen <mark-yw.chen@mediatek.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index a4f834a50a98..3620981e8b1c 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -397,7 +397,9 @@ static const struct usb_device_id blacklist_table[] = {
+       /* MediaTek Bluetooth devices */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x0e8d, 0xe0, 0x01, 0x01),
+-        .driver_info = BTUSB_MEDIATEK },
++        .driver_info = BTUSB_MEDIATEK |
++                       BTUSB_WIDEBAND_SPEECH |
++                       BTUSB_VALID_LE_STATES },
+       /* Additional MediaTek MT7615E Bluetooth devices */
+       { USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK},
+-- 
+2.30.2
+
diff --git a/queue-5.11/bluetooth-check-for-zapped-sk-before-connecting.patch b/queue-5.11/bluetooth-check-for-zapped-sk-before-connecting.patch
new file mode 100644 (file)
index 0000000..6417129
--- /dev/null
@@ -0,0 +1,69 @@
+From 41cba1f0dc93b3a98174eb8d040795757ec637f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Mar 2021 16:32:20 +0800
+Subject: Bluetooth: check for zapped sk before connecting
+
+From: Archie Pusaka <apusaka@chromium.org>
+
+[ Upstream commit 3af70b39fa2d415dc86c370e5b24ddb9fdacbd6f ]
+
+There is a possibility of receiving a zapped sock on
+l2cap_sock_connect(). This could lead to interesting crashes, one
+such case is tearing down an already tore l2cap_sock as is happened
+with this call trace:
+
+__dump_stack lib/dump_stack.c:15 [inline]
+dump_stack+0xc4/0x118 lib/dump_stack.c:56
+register_lock_class kernel/locking/lockdep.c:792 [inline]
+register_lock_class+0x239/0x6f6 kernel/locking/lockdep.c:742
+__lock_acquire+0x209/0x1e27 kernel/locking/lockdep.c:3105
+lock_acquire+0x29c/0x2fb kernel/locking/lockdep.c:3599
+__raw_spin_lock_bh include/linux/spinlock_api_smp.h:137 [inline]
+_raw_spin_lock_bh+0x38/0x47 kernel/locking/spinlock.c:175
+spin_lock_bh include/linux/spinlock.h:307 [inline]
+lock_sock_nested+0x44/0xfa net/core/sock.c:2518
+l2cap_sock_teardown_cb+0x88/0x2fb net/bluetooth/l2cap_sock.c:1345
+l2cap_chan_del+0xa3/0x383 net/bluetooth/l2cap_core.c:598
+l2cap_chan_close+0x537/0x5dd net/bluetooth/l2cap_core.c:756
+l2cap_chan_timeout+0x104/0x17e net/bluetooth/l2cap_core.c:429
+process_one_work+0x7e3/0xcb0 kernel/workqueue.c:2064
+worker_thread+0x5a5/0x773 kernel/workqueue.c:2196
+kthread+0x291/0x2a6 kernel/kthread.c:211
+ret_from_fork+0x4e/0x80 arch/x86/entry/entry_64.S:604
+
+Signed-off-by: Archie Pusaka <apusaka@chromium.org>
+Reported-by: syzbot+abfc0f5e668d4099af73@syzkaller.appspotmail.com
+Reviewed-by: Alain Michaud <alainm@chromium.org>
+Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_sock.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
+index f1b1edd0b697..c99d65ef13b1 100644
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -179,9 +179,17 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
+       struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+       struct sockaddr_l2 la;
+       int len, err = 0;
++      bool zapped;
+       BT_DBG("sk %p", sk);
++      lock_sock(sk);
++      zapped = sock_flag(sk, SOCK_ZAPPED);
++      release_sock(sk);
++
++      if (zapped)
++              return -EINVAL;
++
+       if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
+           addr->sa_family != AF_BLUETOOTH)
+               return -EINVAL;
+-- 
+2.30.2
+
diff --git a/queue-5.11/bluetooth-do-not-set-cur_adv_instance-in-adv-param-m.patch b/queue-5.11/bluetooth-do-not-set-cur_adv_instance-in-adv-param-m.patch
new file mode 100644 (file)
index 0000000..0041dd5
--- /dev/null
@@ -0,0 +1,51 @@
+From 3a2a7dd8a68fb4229cef124da4a7a78786c50a4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Apr 2021 16:33:05 -0700
+Subject: Bluetooth: Do not set cur_adv_instance in adv param MGMT request
+
+From: Daniel Winkler <danielwinkler@google.com>
+
+[ Upstream commit b6f1b79deabd32f89adbf24ef7b30f82d029808a ]
+
+We set hdev->cur_adv_instance in the adv param MGMT request to allow the
+callback to the hci param request to set the tx power to the correct
+instance. Now that the callbacks use the advertising handle from the hci
+request (as they should), this workaround is no longer necessary.
+
+Furthermore, this change resolves a race condition that is more
+prevalent when using the extended advertising MGMT calls - if
+hdev->cur_adv_instance is set in the params request, then when the data
+request is called, we believe our new instance is already active. This
+treats it as an update and immediately schedules the instance with the
+controller, which has a potential race with the software rotation adv
+update. By not setting hdev->cur_adv_instance too early, the new
+instance is queued as it should be, to be used when the rotation comes
+around again.
+
+This change is tested on harrison peak to confirm that it resolves the
+race condition on registration, and that there is no regression in
+single- and multi-advertising automated tests.
+
+Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
+Signed-off-by: Daniel Winkler <danielwinkler@google.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index fa0f7a4a1d2f..01e143c2bbc0 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7768,7 +7768,6 @@ static int add_ext_adv_params(struct sock *sk, struct hci_dev *hdev,
+               goto unlock;
+       }
+-      hdev->cur_adv_instance = cp->instance;
+       /* Submit request for advertising params if ext adv available */
+       if (ext_adv_capable(hdev)) {
+               hci_req_init(&req, hdev);
+-- 
+2.30.2
+
diff --git a/queue-5.11/bluetooth-fix-incorrect-status-handling-in-le-phy-up.patch b/queue-5.11/bluetooth-fix-incorrect-status-handling-in-le-phy-up.patch
new file mode 100644 (file)
index 0000000..9c5c261
--- /dev/null
@@ -0,0 +1,35 @@
+From 0cbaac2191463ce512b908bb671d29cf499a4b4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 16:52:14 +0530
+Subject: Bluetooth: Fix incorrect status handling in LE PHY UPDATE event
+
+From: Ayush Garg <ayush.garg@samsung.com>
+
+[ Upstream commit 87df8bcccd2cede62dfb97dc3d4ca1fe66cb4f83 ]
+
+Skip updation of tx and rx PHYs values, when PHY Update
+event's status is not successful.
+
+Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 7a3e42e75235..82f4973a011d 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -5912,7 +5912,7 @@ static void hci_le_phy_update_evt(struct hci_dev *hdev, struct sk_buff *skb)
+       BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+-      if (!ev->status)
++      if (ev->status)
+               return;
+       hci_dev_lock(hdev);
+-- 
+2.30.2
+
diff --git a/queue-5.11/bluetooth-initialize-skb_queue_head-at-l2cap_chan_cr.patch b/queue-5.11/bluetooth-initialize-skb_queue_head-at-l2cap_chan_cr.patch
new file mode 100644 (file)
index 0000000..c2f9b44
--- /dev/null
@@ -0,0 +1,43 @@
+From 321a66fab55cd5fc9ae1fe85253d455ac7b3c665 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 07:52:07 +0900
+Subject: Bluetooth: initialize skb_queue_head at l2cap_chan_create()
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit be8597239379f0f53c9710dd6ab551bbf535bec6 ]
+
+syzbot is hitting "INFO: trying to register non-static key." message [1],
+for "struct l2cap_chan"->tx_q.lock spinlock is not yet initialized when
+l2cap_chan_del() is called due to e.g. timeout.
+
+Since "struct l2cap_chan"->lock mutex is initialized at l2cap_chan_create()
+immediately after "struct l2cap_chan" is allocated using kzalloc(), let's
+as well initialize "struct l2cap_chan"->{tx_q,srej_q}.lock spinlocks there.
+
+[1] https://syzkaller.appspot.com/bug?extid=fadfba6a911f6bf71842
+
+Reported-and-tested-by: syzbot <syzbot+fadfba6a911f6bf71842@syzkaller.appspotmail.com>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 46da4c1d0177..78776d0782c5 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -451,6 +451,8 @@ struct l2cap_chan *l2cap_chan_create(void)
+       if (!chan)
+               return NULL;
++      skb_queue_head_init(&chan->tx_q);
++      skb_queue_head_init(&chan->srej_q);
+       mutex_init(&chan->lock);
+       /* Set default lock nesting level */
+-- 
+2.30.2
+
diff --git a/queue-5.11/bluetooth-set-conf_not_complete-as-l2cap_chan-defaul.patch b/queue-5.11/bluetooth-set-conf_not_complete-as-l2cap_chan-defaul.patch
new file mode 100644 (file)
index 0000000..b203b53
--- /dev/null
@@ -0,0 +1,77 @@
+From ea22d5e436e9e267ee1596d9f8d99c2022b35627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 14:02:15 +0800
+Subject: Bluetooth: Set CONF_NOT_COMPLETE as l2cap_chan default
+
+From: Archie Pusaka <apusaka@chromium.org>
+
+[ Upstream commit 3a9d54b1947ecea8eea9a902c0b7eb58a98add8a ]
+
+Currently l2cap_chan_set_defaults() reset chan->conf_state to zero.
+However, there is a flag CONF_NOT_COMPLETE which is set when
+creating the l2cap_chan. It is suggested that the flag should be
+cleared when l2cap_chan is ready, but when l2cap_chan_set_defaults()
+is called, l2cap_chan is not yet ready. Therefore, we must set this
+flag as the default.
+
+Example crash call trace:
+__dump_stack lib/dump_stack.c:15 [inline]
+dump_stack+0xc4/0x118 lib/dump_stack.c:56
+panic+0x1c6/0x38b kernel/panic.c:117
+__warn+0x170/0x1b9 kernel/panic.c:471
+warn_slowpath_fmt+0xc7/0xf8 kernel/panic.c:494
+debug_print_object+0x175/0x193 lib/debugobjects.c:260
+debug_object_assert_init+0x171/0x1bf lib/debugobjects.c:614
+debug_timer_assert_init kernel/time/timer.c:629 [inline]
+debug_assert_init kernel/time/timer.c:677 [inline]
+del_timer+0x7c/0x179 kernel/time/timer.c:1034
+try_to_grab_pending+0x81/0x2e5 kernel/workqueue.c:1230
+cancel_delayed_work+0x7c/0x1c4 kernel/workqueue.c:2929
+l2cap_clear_timer+0x1e/0x41 include/net/bluetooth/l2cap.h:834
+l2cap_chan_del+0x2d8/0x37e net/bluetooth/l2cap_core.c:640
+l2cap_chan_close+0x532/0x5d8 net/bluetooth/l2cap_core.c:756
+l2cap_sock_shutdown+0x806/0x969 net/bluetooth/l2cap_sock.c:1174
+l2cap_sock_release+0x64/0x14d net/bluetooth/l2cap_sock.c:1217
+__sock_release+0xda/0x217 net/socket.c:580
+sock_close+0x1b/0x1f net/socket.c:1039
+__fput+0x322/0x55c fs/file_table.c:208
+____fput+0x17/0x19 fs/file_table.c:244
+task_work_run+0x19b/0x1d3 kernel/task_work.c:115
+exit_task_work include/linux/task_work.h:21 [inline]
+do_exit+0xe4c/0x204a kernel/exit.c:766
+do_group_exit+0x291/0x291 kernel/exit.c:891
+get_signal+0x749/0x1093 kernel/signal.c:2396
+do_signal+0xa5/0xcdb arch/x86/kernel/signal.c:737
+exit_to_usermode_loop arch/x86/entry/common.c:243 [inline]
+prepare_exit_to_usermode+0xed/0x235 arch/x86/entry/common.c:277
+syscall_return_slowpath+0x3a7/0x3b3 arch/x86/entry/common.c:348
+int_ret_from_sys_call+0x25/0xa3
+
+Signed-off-by: Archie Pusaka <apusaka@chromium.org>
+Reported-by: syzbot+338f014a98367a08a114@syzkaller.appspotmail.com
+Reviewed-by: Alain Michaud <alainm@chromium.org>
+Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 17b87b57a175..46da4c1d0177 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -516,7 +516,9 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
+       chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+       chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
+       chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
++
+       chan->conf_state = 0;
++      set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
+       set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/bnxt_en-add-pci-ids-for-hyper-v-vf-devices.patch b/queue-5.11/bnxt_en-add-pci-ids-for-hyper-v-vf-devices.patch
new file mode 100644 (file)
index 0000000..b9d0c4f
--- /dev/null
@@ -0,0 +1,86 @@
+From 8101e948f0bdf667ee25407080274deb84d871a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Apr 2021 13:45:25 -0400
+Subject: bnxt_en: Add PCI IDs for Hyper-V VF devices.
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 7fbf359bb2c19c824cbb1954020680824f6ee5a5 ]
+
+Support VF device IDs used by the Hyper-V hypervisor.
+
+Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
+Reviewed-by: Andy Gospodarek <gospo@broadcom.com>
+Signed-off-by: Edwin Peer <edwin.peer@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.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index f3c659bc6bb6..87406d85d914 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -122,7 +122,10 @@ enum board_idx {
+       NETXTREME_E_VF,
+       NETXTREME_C_VF,
+       NETXTREME_S_VF,
++      NETXTREME_C_VF_HV,
++      NETXTREME_E_VF_HV,
+       NETXTREME_E_P5_VF,
++      NETXTREME_E_P5_VF_HV,
+ };
+ /* indexed by enum above */
+@@ -170,7 +173,10 @@ static const struct {
+       [NETXTREME_E_VF] = { "Broadcom NetXtreme-E Ethernet Virtual Function" },
+       [NETXTREME_C_VF] = { "Broadcom NetXtreme-C Ethernet Virtual Function" },
+       [NETXTREME_S_VF] = { "Broadcom NetXtreme-S Ethernet Virtual Function" },
++      [NETXTREME_C_VF_HV] = { "Broadcom NetXtreme-C Virtual Function for Hyper-V" },
++      [NETXTREME_E_VF_HV] = { "Broadcom NetXtreme-E Virtual Function for Hyper-V" },
+       [NETXTREME_E_P5_VF] = { "Broadcom BCM5750X NetXtreme-E Ethernet Virtual Function" },
++      [NETXTREME_E_P5_VF_HV] = { "Broadcom BCM5750X NetXtreme-E Virtual Function for Hyper-V" },
+ };
+ static const struct pci_device_id bnxt_pci_tbl[] = {
+@@ -222,15 +228,25 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
+       { PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 },
+ #ifdef CONFIG_BNXT_SRIOV
+       { PCI_VDEVICE(BROADCOM, 0x1606), .driver_data = NETXTREME_E_VF },
++      { PCI_VDEVICE(BROADCOM, 0x1607), .driver_data = NETXTREME_E_VF_HV },
++      { PCI_VDEVICE(BROADCOM, 0x1608), .driver_data = NETXTREME_E_VF_HV },
+       { PCI_VDEVICE(BROADCOM, 0x1609), .driver_data = NETXTREME_E_VF },
++      { PCI_VDEVICE(BROADCOM, 0x16bd), .driver_data = NETXTREME_E_VF_HV },
+       { PCI_VDEVICE(BROADCOM, 0x16c1), .driver_data = NETXTREME_E_VF },
++      { PCI_VDEVICE(BROADCOM, 0x16c2), .driver_data = NETXTREME_C_VF_HV },
++      { PCI_VDEVICE(BROADCOM, 0x16c3), .driver_data = NETXTREME_C_VF_HV },
++      { PCI_VDEVICE(BROADCOM, 0x16c4), .driver_data = NETXTREME_E_VF_HV },
++      { PCI_VDEVICE(BROADCOM, 0x16c5), .driver_data = NETXTREME_E_VF_HV },
+       { PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = NETXTREME_C_VF },
+       { PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = NETXTREME_E_VF },
+       { PCI_VDEVICE(BROADCOM, 0x16dc), .driver_data = NETXTREME_E_VF },
+       { PCI_VDEVICE(BROADCOM, 0x16e1), .driver_data = NETXTREME_C_VF },
+       { PCI_VDEVICE(BROADCOM, 0x16e5), .driver_data = NETXTREME_C_VF },
++      { PCI_VDEVICE(BROADCOM, 0x16e6), .driver_data = NETXTREME_C_VF_HV },
+       { PCI_VDEVICE(BROADCOM, 0x1806), .driver_data = NETXTREME_E_P5_VF },
+       { PCI_VDEVICE(BROADCOM, 0x1807), .driver_data = NETXTREME_E_P5_VF },
++      { PCI_VDEVICE(BROADCOM, 0x1808), .driver_data = NETXTREME_E_P5_VF_HV },
++      { PCI_VDEVICE(BROADCOM, 0x1809), .driver_data = NETXTREME_E_P5_VF_HV },
+       { PCI_VDEVICE(BROADCOM, 0xd800), .driver_data = NETXTREME_S_VF },
+ #endif
+       { 0 }
+@@ -263,7 +279,8 @@ static struct workqueue_struct *bnxt_pf_wq;
+ static bool bnxt_vf_pciid(enum board_idx idx)
+ {
+       return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF ||
+-              idx == NETXTREME_S_VF || idx == NETXTREME_E_P5_VF);
++              idx == NETXTREME_S_VF || idx == NETXTREME_C_VF_HV ||
++              idx == NETXTREME_E_VF_HV || idx == NETXTREME_E_P5_VF);
+ }
+ #define DB_CP_REARM_FLAGS     (DB_KEY_CP | DB_IDX_VALID)
+-- 
+2.30.2
+
diff --git a/queue-5.11/can-m_can-m_can_tx_work_queue-fix-tx_skb-race-condit.patch b/queue-5.11/can-m_can-m_can_tx_work_queue-fix-tx_skb-race-condit.patch
new file mode 100644 (file)
index 0000000..2207d03
--- /dev/null
@@ -0,0 +1,49 @@
+From d51bce11f37f48989d04d7f4288f81c9b0f10e7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 13:32:27 +0200
+Subject: can: m_can: m_can_tx_work_queue(): fix tx_skb race condition
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit e04b2cfe61072c7966e1a5fb73dd1feb30c206ed ]
+
+The m_can_start_xmit() function checks if the cdev->tx_skb is NULL and
+returns with NETDEV_TX_BUSY in case tx_sbk is not NULL.
+
+There is a race condition in the m_can_tx_work_queue(), where first
+the skb is send to the driver and then the case tx_sbk is set to NULL.
+A TX complete IRQ might come in between and wake the queue, which
+results in tx_skb not being cleared yet.
+
+Fixes: f524f829b75a ("can: m_can: Create a m_can platform framework")
+Tested-by: Torin Cooper-Bennun <torin@maxiluxsystems.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/m_can/m_can.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 44b3f4b3aea5..f6c135d0a35f 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -1455,6 +1455,8 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev)
+       int i;
+       int putidx;
++      cdev->tx_skb = NULL;
++
+       /* Generate ID field for TX buffer Element */
+       /* Common to all supported M_CAN versions */
+       if (cf->can_id & CAN_EFF_FLAG) {
+@@ -1571,7 +1573,6 @@ static void m_can_tx_work_queue(struct work_struct *ws)
+                                                  tx_work);
+       m_can_tx_handler(cdev);
+-      cdev->tx_skb = NULL;
+ }
+ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
+-- 
+2.30.2
+
diff --git a/queue-5.11/can-mcp251x-fix-resume-from-sleep-before-interface-w.patch b/queue-5.11/can-mcp251x-fix-resume-from-sleep-before-interface-w.patch
new file mode 100644 (file)
index 0000000..79db756
--- /dev/null
@@ -0,0 +1,119 @@
+From 56a61beb9f4ab7f0b151bb69ebaddb9a5c98a4a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 09:14:15 +0200
+Subject: can: mcp251x: fix resume from sleep before interface was brought up
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit 03c427147b2d3e503af258711af4fc792b89b0af ]
+
+Since 8ce8c0abcba3 the driver queues work via priv->restart_work when
+resuming after suspend, even when the interface was not previously
+enabled. This causes a null dereference error as the workqueue is only
+allocated and initialized in mcp251x_open().
+
+To fix this we move the workqueue init to mcp251x_can_probe() as there
+is no reason to do it later and repeat it whenever mcp251x_open() is
+called.
+
+Fixes: 8ce8c0abcba3 ("can: mcp251x: only reset hardware as required")
+Link: https://lore.kernel.org/r/17d5d714-b468-482f-f37a-482e3d6df84e@kontron.de
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+[mkl: fix error handling in mcp251x_stop()]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/spi/mcp251x.c | 35 ++++++++++++++++++-----------------
+ 1 file changed, 18 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
+index e7be36dc2159..24ae221c2f10 100644
+--- a/drivers/net/can/spi/mcp251x.c
++++ b/drivers/net/can/spi/mcp251x.c
+@@ -956,8 +956,6 @@ static int mcp251x_stop(struct net_device *net)
+       priv->force_quit = 1;
+       free_irq(spi->irq, priv);
+-      destroy_workqueue(priv->wq);
+-      priv->wq = NULL;
+       mutex_lock(&priv->mcp_lock);
+@@ -1224,24 +1222,15 @@ static int mcp251x_open(struct net_device *net)
+               goto out_close;
+       }
+-      priv->wq = alloc_workqueue("mcp251x_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,
+-                                 0);
+-      if (!priv->wq) {
+-              ret = -ENOMEM;
+-              goto out_clean;
+-      }
+-      INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
+-      INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler);
+-
+       ret = mcp251x_hw_wake(spi);
+       if (ret)
+-              goto out_free_wq;
++              goto out_free_irq;
+       ret = mcp251x_setup(net, spi);
+       if (ret)
+-              goto out_free_wq;
++              goto out_free_irq;
+       ret = mcp251x_set_normal_mode(spi);
+       if (ret)
+-              goto out_free_wq;
++              goto out_free_irq;
+       can_led_event(net, CAN_LED_EVENT_OPEN);
+@@ -1250,9 +1239,7 @@ static int mcp251x_open(struct net_device *net)
+       return 0;
+-out_free_wq:
+-      destroy_workqueue(priv->wq);
+-out_clean:
++out_free_irq:
+       free_irq(spi->irq, priv);
+       mcp251x_hw_sleep(spi);
+ out_close:
+@@ -1373,6 +1360,15 @@ static int mcp251x_can_probe(struct spi_device *spi)
+       if (ret)
+               goto out_clk;
++      priv->wq = alloc_workqueue("mcp251x_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,
++                                 0);
++      if (!priv->wq) {
++              ret = -ENOMEM;
++              goto out_clk;
++      }
++      INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
++      INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler);
++
+       priv->spi = spi;
+       mutex_init(&priv->mcp_lock);
+@@ -1417,6 +1413,8 @@ static int mcp251x_can_probe(struct spi_device *spi)
+       return 0;
+ error_probe:
++      destroy_workqueue(priv->wq);
++      priv->wq = NULL;
+       mcp251x_power_enable(priv->power, 0);
+ out_clk:
+@@ -1438,6 +1436,9 @@ static int mcp251x_can_remove(struct spi_device *spi)
+       mcp251x_power_enable(priv->power, 0);
++      destroy_workqueue(priv->wq);
++      priv->wq = NULL;
++
+       clk_disable_unprepare(priv->clk);
+       free_candev(net);
+-- 
+2.30.2
+
diff --git a/queue-5.11/can-mcp251xfd-mcp251xfd_probe-add-missing-can_rx_off.patch b/queue-5.11/can-mcp251xfd-mcp251xfd_probe-add-missing-can_rx_off.patch
new file mode 100644 (file)
index 0000000..92ba523
--- /dev/null
@@ -0,0 +1,42 @@
+From bd797563e6e843eff0744fe4d33e9bb29ac01af2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 May 2021 11:34:34 +0200
+Subject: can: mcp251xfd: mcp251xfd_probe(): add missing can_rx_offload_del()
+ in error path
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 4376ea42db8bfcac2bc3a30bba93917244a8c2d4 ]
+
+This patch adds the missing can_rx_offload_del(), that must be called
+if mcp251xfd_register() fails.
+
+Fixes: 55e5b97f003e ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN")
+Link: https://lore.kernel.org/r/20210504091838.1109047-1-mkl@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+index ee39e79927ef..486dbd3357aa 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+@@ -2947,10 +2947,12 @@ static int mcp251xfd_probe(struct spi_device *spi)
+       err = mcp251xfd_register(priv);
+       if (err)
+-              goto out_free_candev;
++              goto out_can_rx_offload_del;
+       return 0;
++ out_can_rx_offload_del:
++      can_rx_offload_del(&priv->offload);
+  out_free_candev:
+       spi->max_speed_hz = priv->spi_max_speed_hz_orig;
+-- 
+2.30.2
+
diff --git a/queue-5.11/ceph-fix-inode-leak-on-getattr-error-in-__fh_to_dent.patch b/queue-5.11/ceph-fix-inode-leak-on-getattr-error-in-__fh_to_dent.patch
new file mode 100644 (file)
index 0000000..d54d65a
--- /dev/null
@@ -0,0 +1,37 @@
+From 81ea865e05b56d90daa32c0dc1b5a0ee3955edcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 09:21:53 -0400
+Subject: ceph: fix inode leak on getattr error in __fh_to_dentry
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit 1775c7ddacfcea29051c67409087578f8f4d751b ]
+
+Fixes: 878dabb64117 ("ceph: don't return -ESTALE if there's still an open file")
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: Xiubo Li <xiubli@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/export.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ceph/export.c b/fs/ceph/export.c
+index e088843a7734..baa6368bece5 100644
+--- a/fs/ceph/export.c
++++ b/fs/ceph/export.c
+@@ -178,8 +178,10 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, u64 ino)
+               return ERR_CAST(inode);
+       /* We need LINK caps to reliably check i_nlink */
+       err = ceph_do_getattr(inode, CEPH_CAP_LINK_SHARED, false);
+-      if (err)
++      if (err) {
++              iput(inode);
+               return ERR_PTR(err);
++      }
+       /* -ESTALE if inode as been unlinked and no file is open */
+       if ((inode->i_nlink == 0) && (atomic_read(&inode->i_count) == 1)) {
+               iput(inode);
+-- 
+2.30.2
+
diff --git a/queue-5.11/coresight-do-not-scan-for-graph-if-none-is-present.patch b/queue-5.11/coresight-do-not-scan-for-graph-if-none-is-present.patch
new file mode 100644 (file)
index 0000000..0a780a1
--- /dev/null
@@ -0,0 +1,50 @@
+From 9f7deeb183aaff1a23f54fb69194ead7986d164e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Apr 2021 17:42:57 +0100
+Subject: coresight: Do not scan for graph if none is present
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit 2b921b671a8d29c2adb255a86409aad1e3267309 ]
+
+If a graph node is not found for a given node, of_get_next_endpoint()
+will emit the following error message :
+
+ OF: graph: no port node found in /<node_name>
+
+If the given component doesn't have any explicit connections (e.g,
+ETE) we could simply ignore the graph parsing. As for any legacy
+component where this is mandatory, the device will not be usable
+as before this patch. Updating the DT bindings to Yaml and enabling
+the schema checks can detect such issues with the DT.
+
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20210405164307.1720226-11-suzuki.poulose@arm.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-platform.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
+index 3629b7885aca..c594f45319fc 100644
+--- a/drivers/hwtracing/coresight/coresight-platform.c
++++ b/drivers/hwtracing/coresight/coresight-platform.c
+@@ -90,6 +90,12 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
+       struct of_endpoint endpoint;
+       int in = 0, out = 0;
++      /*
++       * Avoid warnings in of_graph_get_next_endpoint()
++       * if the device doesn't have any graph connections
++       */
++      if (!of_graph_is_present(node))
++              return;
+       do {
+               ep = of_graph_get_next_endpoint(node, ep);
+               if (!ep)
+-- 
+2.30.2
+
diff --git a/queue-5.11/crypto-ccp-free-sev-device-if-sev-init-fails.patch b/queue-5.11/crypto-ccp-free-sev-device-if-sev-init-fails.patch
new file mode 100644 (file)
index 0000000..326bb90
--- /dev/null
@@ -0,0 +1,49 @@
+From f052fe360c7ceb1e7d316c67e827a103c87876a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 15:49:45 -0700
+Subject: crypto: ccp: Free SEV device if SEV init fails
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit b61a9071dc72a3c709192c0c00ab87c2b3de1d94 ]
+
+Free the SEV device if later initialization fails.  The memory isn't
+technically leaked as it's tracked in the top-level device's devres
+list, but unless the top-level device is removed, the memory won't be
+freed and is effectively leaked.
+
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210406224952.4177376-2-seanjc@google.com>
+Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 5b82ba7acc7c..21caed429cc5 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -989,7 +989,7 @@ int sev_dev_init(struct psp_device *psp)
+       if (!sev->vdata) {
+               ret = -ENODEV;
+               dev_err(dev, "sev: missing driver data\n");
+-              goto e_err;
++              goto e_sev;
+       }
+       psp_set_sev_irq_handler(psp, sev_irq_handler, sev);
+@@ -1004,6 +1004,8 @@ int sev_dev_init(struct psp_device *psp)
+ e_irq:
+       psp_clear_sev_irq_handler(psp);
++e_sev:
++      devm_kfree(dev, sev);
+ e_err:
+       psp->sev_data = NULL;
+-- 
+2.30.2
+
diff --git a/queue-5.11/cuse-prevent-clone.patch b/queue-5.11/cuse-prevent-clone.patch
new file mode 100644 (file)
index 0000000..3c143e1
--- /dev/null
@@ -0,0 +1,37 @@
+From dcc9f77cd10c371f7c8577617158475449cde434 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Apr 2021 10:40:58 +0200
+Subject: cuse: prevent clone
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+[ Upstream commit 8217673d07256b22881127bf50dce874d0e51653 ]
+
+For cloned connections cuse_channel_release() will be called more than
+once, resulting in use after free.
+
+Prevent device cloning for CUSE, which does not make sense at this point,
+and highly unlikely to be used in real life.
+
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/cuse.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
+index 45082269e698..a37528b51798 100644
+--- a/fs/fuse/cuse.c
++++ b/fs/fuse/cuse.c
+@@ -627,6 +627,8 @@ static int __init cuse_init(void)
+       cuse_channel_fops.owner         = THIS_MODULE;
+       cuse_channel_fops.open          = cuse_channel_open;
+       cuse_channel_fops.release       = cuse_channel_release;
++      /* CUSE is not prepared for FUSE_DEV_IOC_CLONE */
++      cuse_channel_fops.unlocked_ioctl        = NULL;
+       cuse_class = class_create(THIS_MODULE, "cuse");
+       if (IS_ERR(cuse_class))
+-- 
+2.30.2
+
diff --git a/queue-5.11/dma-idxd-use-define_mutex-for-mutex-lock.patch b/queue-5.11/dma-idxd-use-define_mutex-for-mutex-lock.patch
new file mode 100644 (file)
index 0000000..0877b5a
--- /dev/null
@@ -0,0 +1,45 @@
+From 0dbcf2e42a94308bfb01a7759e173a37181ec4c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Dec 2020 21:22:54 +0800
+Subject: dma: idxd: use DEFINE_MUTEX() for mutex lock
+
+From: Zheng Yongjun <zhengyongjun3@huawei.com>
+
+[ Upstream commit e2fcd6e427c2fae92b366b24759f95d77b6f7bc7 ]
+
+mutex lock can be initialized automatically with DEFINE_MUTEX()
+rather than explicitly calling mutex_init().
+
+Signed-off-by: Zheng Yongjun <zhengyongjun3@huawei.com>
+Acked-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20201224132254.30961-1-zhengyongjun3@huawei.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/init.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index ababd059da6f..d223242a34f4 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -31,7 +31,7 @@ MODULE_AUTHOR("Intel Corporation");
+ bool support_enqcmd;
+ static struct idr idxd_idrs[IDXD_TYPE_MAX];
+-static struct mutex idxd_idr_lock;
++static DEFINE_MUTEX(idxd_idr_lock);
+ static struct pci_device_id idxd_pci_tbl[] = {
+       /* DSA ver 1.0 platforms */
+@@ -543,7 +543,6 @@ static int __init idxd_init_module(void)
+       else
+               support_enqcmd = true;
+-      mutex_init(&idxd_idr_lock);
+       for (i = 0; i < IDXD_TYPE_MAX; i++)
+               idr_init(&idxd_idrs[i]);
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-cleanup-pci-interrupt-vector-allocati.patch b/queue-5.11/dmaengine-idxd-cleanup-pci-interrupt-vector-allocati.patch
new file mode 100644 (file)
index 0000000..7abb6f6
--- /dev/null
@@ -0,0 +1,209 @@
+From f6c5fc5705eba68e07a450ebbad32eb455849056 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:15 -0700
+Subject: dmaengine: idxd: cleanup pci interrupt vector allocation management
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit 5fc8e85ff12ce0530ac658686902a0ee64600f56 ]
+
+The devm managed lifetime is incompatible with 'struct device' objects that
+resides in idxd context. This is one of the series that clean up the idxd
+driver 'struct device' lifetime. Remove devm managed pci interrupt vectors
+and replace with unmanged allocators.
+
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Link: https://lore.kernel.org/r/161852983563.2203940.8116028229124776669.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/device.c |  4 +--
+ drivers/dma/idxd/idxd.h   |  2 +-
+ drivers/dma/idxd/init.c   | 64 +++++++++++++++++----------------------
+ 3 files changed, 30 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index d255bb016c4d..3f696abd74ac 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -19,7 +19,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
+ /* Interrupt control bits */
+ void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id)
+ {
+-      struct irq_data *data = irq_get_irq_data(idxd->msix_entries[vec_id].vector);
++      struct irq_data *data = irq_get_irq_data(idxd->irq_entries[vec_id].vector);
+       pci_msi_mask_irq(data);
+ }
+@@ -36,7 +36,7 @@ void idxd_mask_msix_vectors(struct idxd_device *idxd)
+ void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id)
+ {
+-      struct irq_data *data = irq_get_irq_data(idxd->msix_entries[vec_id].vector);
++      struct irq_data *data = irq_get_irq_data(idxd->irq_entries[vec_id].vector);
+       pci_msi_unmask_irq(data);
+ }
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index 80e534680c9a..401b035e42b1 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -36,6 +36,7 @@ struct idxd_device_driver {
+ struct idxd_irq_entry {
+       struct idxd_device *idxd;
+       int id;
++      int vector;
+       struct llist_head pending_llist;
+       struct list_head work_list;
+       /*
+@@ -219,7 +220,6 @@ struct idxd_device {
+       union sw_err_reg sw_err;
+       wait_queue_head_t cmd_waitq;
+-      struct msix_entry *msix_entries;
+       int num_wq_irqs;
+       struct idxd_irq_entry *irq_entries;
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index 8f3df64aa1be..d54a5e5f82a2 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -57,7 +57,6 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
+ {
+       struct pci_dev *pdev = idxd->pdev;
+       struct device *dev = &pdev->dev;
+-      struct msix_entry *msix;
+       struct idxd_irq_entry *irq_entry;
+       int i, msixcnt;
+       int rc = 0;
+@@ -65,23 +64,13 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
+       msixcnt = pci_msix_vec_count(pdev);
+       if (msixcnt < 0) {
+               dev_err(dev, "Not MSI-X interrupt capable.\n");
+-              goto err_no_irq;
++              return -ENOSPC;
+       }
+-      idxd->msix_entries = devm_kzalloc(dev, sizeof(struct msix_entry) *
+-                      msixcnt, GFP_KERNEL);
+-      if (!idxd->msix_entries) {
+-              rc = -ENOMEM;
+-              goto err_no_irq;
+-      }
+-
+-      for (i = 0; i < msixcnt; i++)
+-              idxd->msix_entries[i].entry = i;
+-
+-      rc = pci_enable_msix_exact(pdev, idxd->msix_entries, msixcnt);
+-      if (rc) {
+-              dev_err(dev, "Failed enabling %d MSIX entries.\n", msixcnt);
+-              goto err_no_irq;
++      rc = pci_alloc_irq_vectors(pdev, msixcnt, msixcnt, PCI_IRQ_MSIX);
++      if (rc != msixcnt) {
++              dev_err(dev, "Failed enabling %d MSIX entries: %d\n", msixcnt, rc);
++              return -ENOSPC;
+       }
+       dev_dbg(dev, "Enabled %d msix vectors\n", msixcnt);
+@@ -94,58 +83,57 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
+                                        GFP_KERNEL);
+       if (!idxd->irq_entries) {
+               rc = -ENOMEM;
+-              goto err_no_irq;
++              goto err_irq_entries;
+       }
+       for (i = 0; i < msixcnt; i++) {
+               idxd->irq_entries[i].id = i;
+               idxd->irq_entries[i].idxd = idxd;
++              idxd->irq_entries[i].vector = pci_irq_vector(pdev, i);
+               spin_lock_init(&idxd->irq_entries[i].list_lock);
+       }
+-      msix = &idxd->msix_entries[0];
+       irq_entry = &idxd->irq_entries[0];
+-      rc = devm_request_threaded_irq(dev, msix->vector, idxd_irq_handler,
+-                                     idxd_misc_thread, 0, "idxd-misc",
+-                                     irq_entry);
++      rc = request_threaded_irq(irq_entry->vector, idxd_irq_handler, idxd_misc_thread,
++                                0, "idxd-misc", irq_entry);
+       if (rc < 0) {
+               dev_err(dev, "Failed to allocate misc interrupt.\n");
+-              goto err_no_irq;
++              goto err_misc_irq;
+       }
+-      dev_dbg(dev, "Allocated idxd-misc handler on msix vector %d\n",
+-              msix->vector);
++      dev_dbg(dev, "Allocated idxd-misc handler on msix vector %d\n", irq_entry->vector);
+       /* first MSI-X entry is not for wq interrupts */
+       idxd->num_wq_irqs = msixcnt - 1;
+       for (i = 1; i < msixcnt; i++) {
+-              msix = &idxd->msix_entries[i];
+               irq_entry = &idxd->irq_entries[i];
+               init_llist_head(&idxd->irq_entries[i].pending_llist);
+               INIT_LIST_HEAD(&idxd->irq_entries[i].work_list);
+-              rc = devm_request_threaded_irq(dev, msix->vector,
+-                                             idxd_irq_handler,
+-                                             idxd_wq_thread, 0,
+-                                             "idxd-portal", irq_entry);
++              rc = request_threaded_irq(irq_entry->vector, idxd_irq_handler,
++                                        idxd_wq_thread, 0, "idxd-portal", irq_entry);
+               if (rc < 0) {
+-                      dev_err(dev, "Failed to allocate irq %d.\n",
+-                              msix->vector);
+-                      goto err_no_irq;
++                      dev_err(dev, "Failed to allocate irq %d.\n", irq_entry->vector);
++                      goto err_wq_irqs;
+               }
+-              dev_dbg(dev, "Allocated idxd-msix %d for vector %d\n",
+-                      i, msix->vector);
++              dev_dbg(dev, "Allocated idxd-msix %d for vector %d\n", i, irq_entry->vector);
+       }
+       idxd_unmask_error_interrupts(idxd);
+       idxd_msix_perm_setup(idxd);
+       return 0;
+- err_no_irq:
++ err_wq_irqs:
++      while (--i >= 0) {
++              irq_entry = &idxd->irq_entries[i];
++              free_irq(irq_entry->vector, irq_entry);
++      }
++ err_misc_irq:
+       /* Disable error interrupt generation */
+       idxd_mask_error_interrupts(idxd);
+-      pci_disable_msix(pdev);
++ err_irq_entries:
++      pci_free_irq_vectors(pdev);
+       dev_err(dev, "No usable interrupts\n");
+       return rc;
+ }
+@@ -489,7 +477,8 @@ static void idxd_shutdown(struct pci_dev *pdev)
+       for (i = 0; i < msixcnt; i++) {
+               irq_entry = &idxd->irq_entries[i];
+-              synchronize_irq(idxd->msix_entries[i].vector);
++              synchronize_irq(irq_entry->vector);
++              free_irq(irq_entry->vector, irq_entry);
+               if (i == 0)
+                       continue;
+               idxd_flush_pending_llist(irq_entry);
+@@ -497,6 +486,7 @@ static void idxd_shutdown(struct pci_dev *pdev)
+       }
+       idxd_msix_perm_clear(idxd);
++      pci_free_irq_vectors(pdev);
+       destroy_workqueue(idxd->wq);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-fix-cdev-setup-and-free-device-lifeti.patch b/queue-5.11/dmaengine-idxd-fix-cdev-setup-and-free-device-lifeti.patch
new file mode 100644 (file)
index 0000000..f65076b
--- /dev/null
@@ -0,0 +1,312 @@
+From 4f0281378b4e650410975c758a92bf8a2849c097 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:57 -0700
+Subject: dmaengine: idxd: fix cdev setup and free device lifetime issues
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit 04922b7445a1950b86f130a1fe8c52cc27b3e30b ]
+
+The char device setup and cleanup has device lifetime issues regarding when
+parts are initialized and cleaned up. The initialization of struct device is
+done incorrectly. device_initialize() needs to be called on the 'struct
+device' and then additional changes can be added. The ->release() function
+needs to be setup via device_type before dev_set_name() to allow proper
+cleanup. The change re-parents the cdev under the wq->conf_dev to get
+natural reference inheritance. No known dependency on the old device path exists.
+
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: 42d279f9137a ("dmaengine: idxd: add char driver to expose submission portal to userland")
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Link: https://lore.kernel.org/r/161852987721.2203940.1478218825576630810.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/cdev.c  | 129 ++++++++++++++-------------------------
+ drivers/dma/idxd/idxd.h  |   7 ++-
+ drivers/dma/idxd/init.c  |   2 +-
+ drivers/dma/idxd/irq.c   |   4 +-
+ drivers/dma/idxd/sysfs.c |  10 ++-
+ 5 files changed, 63 insertions(+), 89 deletions(-)
+
+diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c
+index 0db9b82ed8cf..1d8a3876b745 100644
+--- a/drivers/dma/idxd/cdev.c
++++ b/drivers/dma/idxd/cdev.c
+@@ -39,15 +39,15 @@ struct idxd_user_context {
+       struct iommu_sva *sva;
+ };
+-enum idxd_cdev_cleanup {
+-      CDEV_NORMAL = 0,
+-      CDEV_FAILED,
+-};
+-
+ static void idxd_cdev_dev_release(struct device *dev)
+ {
+-      dev_dbg(dev, "releasing cdev device\n");
+-      kfree(dev);
++      struct idxd_cdev *idxd_cdev = container_of(dev, struct idxd_cdev, dev);
++      struct idxd_cdev_context *cdev_ctx;
++      struct idxd_wq *wq = idxd_cdev->wq;
++
++      cdev_ctx = &ictx[wq->idxd->type];
++      ida_simple_remove(&cdev_ctx->minor_ida, idxd_cdev->minor);
++      kfree(idxd_cdev);
+ }
+ static struct device_type idxd_cdev_device_type = {
+@@ -62,14 +62,11 @@ static inline struct idxd_cdev *inode_idxd_cdev(struct inode *inode)
+       return container_of(cdev, struct idxd_cdev, cdev);
+ }
+-static inline struct idxd_wq *idxd_cdev_wq(struct idxd_cdev *idxd_cdev)
+-{
+-      return container_of(idxd_cdev, struct idxd_wq, idxd_cdev);
+-}
+-
+ static inline struct idxd_wq *inode_wq(struct inode *inode)
+ {
+-      return idxd_cdev_wq(inode_idxd_cdev(inode));
++      struct idxd_cdev *idxd_cdev = inode_idxd_cdev(inode);
++
++      return idxd_cdev->wq;
+ }
+ static int idxd_cdev_open(struct inode *inode, struct file *filp)
+@@ -220,11 +217,10 @@ static __poll_t idxd_cdev_poll(struct file *filp,
+       struct idxd_user_context *ctx = filp->private_data;
+       struct idxd_wq *wq = ctx->wq;
+       struct idxd_device *idxd = wq->idxd;
+-      struct idxd_cdev *idxd_cdev = &wq->idxd_cdev;
+       unsigned long flags;
+       __poll_t out = 0;
+-      poll_wait(filp, &idxd_cdev->err_queue, wait);
++      poll_wait(filp, &wq->err_queue, wait);
+       spin_lock_irqsave(&idxd->dev_lock, flags);
+       if (idxd->sw_err.valid)
+               out = EPOLLIN | EPOLLRDNORM;
+@@ -246,98 +242,67 @@ int idxd_cdev_get_major(struct idxd_device *idxd)
+       return MAJOR(ictx[idxd->type].devt);
+ }
+-static int idxd_wq_cdev_dev_setup(struct idxd_wq *wq)
++int idxd_wq_add_cdev(struct idxd_wq *wq)
+ {
+       struct idxd_device *idxd = wq->idxd;
+-      struct idxd_cdev *idxd_cdev = &wq->idxd_cdev;
+-      struct idxd_cdev_context *cdev_ctx;
++      struct idxd_cdev *idxd_cdev;
++      struct cdev *cdev;
+       struct device *dev;
+-      int minor, rc;
++      struct idxd_cdev_context *cdev_ctx;
++      int rc, minor;
+-      idxd_cdev->dev = kzalloc(sizeof(*idxd_cdev->dev), GFP_KERNEL);
+-      if (!idxd_cdev->dev)
++      idxd_cdev = kzalloc(sizeof(*idxd_cdev), GFP_KERNEL);
++      if (!idxd_cdev)
+               return -ENOMEM;
+-      dev = idxd_cdev->dev;
+-      dev->parent = &idxd->pdev->dev;
+-      dev_set_name(dev, "%s/wq%u.%u", idxd_get_dev_name(idxd),
+-                   idxd->id, wq->id);
+-      dev->bus = idxd_get_bus_type(idxd);
+-
++      idxd_cdev->wq = wq;
++      cdev = &idxd_cdev->cdev;
++      dev = &idxd_cdev->dev;
+       cdev_ctx = &ictx[wq->idxd->type];
+       minor = ida_simple_get(&cdev_ctx->minor_ida, 0, MINORMASK, GFP_KERNEL);
+       if (minor < 0) {
+-              rc = minor;
+-              kfree(dev);
+-              goto ida_err;
+-      }
+-
+-      dev->devt = MKDEV(MAJOR(cdev_ctx->devt), minor);
+-      dev->type = &idxd_cdev_device_type;
+-      rc = device_register(dev);
+-      if (rc < 0) {
+-              dev_err(&idxd->pdev->dev, "device register failed\n");
+-              goto dev_reg_err;
++              kfree(idxd_cdev);
++              return minor;
+       }
+       idxd_cdev->minor = minor;
+-      return 0;
+-
+- dev_reg_err:
+-      ida_simple_remove(&cdev_ctx->minor_ida, MINOR(dev->devt));
+-      put_device(dev);
+- ida_err:
+-      idxd_cdev->dev = NULL;
+-      return rc;
+-}
+-
+-static void idxd_wq_cdev_cleanup(struct idxd_wq *wq,
+-                               enum idxd_cdev_cleanup cdev_state)
+-{
+-      struct idxd_cdev *idxd_cdev = &wq->idxd_cdev;
+-      struct idxd_cdev_context *cdev_ctx;
+-
+-      cdev_ctx = &ictx[wq->idxd->type];
+-      if (cdev_state == CDEV_NORMAL)
+-              cdev_del(&idxd_cdev->cdev);
+-      device_unregister(idxd_cdev->dev);
+-      /*
+-       * The device_type->release() will be called on the device and free
+-       * the allocated struct device. We can just forget it.
+-       */
+-      ida_simple_remove(&cdev_ctx->minor_ida, idxd_cdev->minor);
+-      idxd_cdev->dev = NULL;
+-      idxd_cdev->minor = -1;
+-}
+-
+-int idxd_wq_add_cdev(struct idxd_wq *wq)
+-{
+-      struct idxd_cdev *idxd_cdev = &wq->idxd_cdev;
+-      struct cdev *cdev = &idxd_cdev->cdev;
+-      struct device *dev;
+-      int rc;
++      device_initialize(dev);
++      dev->parent = &wq->conf_dev;
++      dev->bus = idxd_get_bus_type(idxd);
++      dev->type = &idxd_cdev_device_type;
++      dev->devt = MKDEV(MAJOR(cdev_ctx->devt), minor);
+-      rc = idxd_wq_cdev_dev_setup(wq);
++      rc = dev_set_name(dev, "%s/wq%u.%u", idxd_get_dev_name(idxd),
++                        idxd->id, wq->id);
+       if (rc < 0)
+-              return rc;
++              goto err;
+-      dev = idxd_cdev->dev;
++      wq->idxd_cdev = idxd_cdev;
+       cdev_init(cdev, &idxd_cdev_fops);
+-      cdev_set_parent(cdev, &dev->kobj);
+-      rc = cdev_add(cdev, dev->devt, 1);
++      rc = cdev_device_add(cdev, dev);
+       if (rc) {
+               dev_dbg(&wq->idxd->pdev->dev, "cdev_add failed: %d\n", rc);
+-              idxd_wq_cdev_cleanup(wq, CDEV_FAILED);
+-              return rc;
++              goto err;
+       }
+-      init_waitqueue_head(&idxd_cdev->err_queue);
+       return 0;
++
++ err:
++      put_device(dev);
++      wq->idxd_cdev = NULL;
++      return rc;
+ }
+ void idxd_wq_del_cdev(struct idxd_wq *wq)
+ {
+-      idxd_wq_cdev_cleanup(wq, CDEV_NORMAL);
++      struct idxd_cdev *idxd_cdev;
++      struct idxd_cdev_context *cdev_ctx;
++
++      cdev_ctx = &ictx[wq->idxd->type];
++      idxd_cdev = wq->idxd_cdev;
++      wq->idxd_cdev = NULL;
++      cdev_device_del(&idxd_cdev->cdev, &idxd_cdev->dev);
++      put_device(&idxd_cdev->dev);
+ }
+ int idxd_cdev_register(void)
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index 3c4ce7997c88..89daf746d121 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -80,10 +80,10 @@ enum idxd_wq_type {
+ };
+ struct idxd_cdev {
++      struct idxd_wq *wq;
+       struct cdev cdev;
+-      struct device *dev;
++      struct device dev;
+       int minor;
+-      struct wait_queue_head err_queue;
+ };
+ #define IDXD_ALLOCATED_BATCH_SIZE     128U
+@@ -109,7 +109,8 @@ struct idxd_dma_chan {
+ struct idxd_wq {
+       void __iomem *portal;
+       struct device conf_dev;
+-      struct idxd_cdev idxd_cdev;
++      struct idxd_cdev *idxd_cdev;
++      struct wait_queue_head err_queue;
+       struct idxd_device *idxd;
+       int id;
+       enum idxd_wq_type type;
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index 25d801916aec..3d43c08f3a76 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -172,7 +172,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
+               }
+               mutex_init(&wq->wq_lock);
+-              wq->idxd_cdev.minor = -1;
++              init_waitqueue_head(&wq->err_queue);
+               wq->max_xfer_bytes = idxd->max_xfer_bytes;
+               wq->max_batch_size = idxd->max_batch_size;
+               wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
+diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c
+index 7b0181532f77..fc0781e3f36d 100644
+--- a/drivers/dma/idxd/irq.c
++++ b/drivers/dma/idxd/irq.c
+@@ -133,7 +133,7 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause)
+                       struct idxd_wq *wq = idxd->wqs[id];
+                       if (wq->type == IDXD_WQT_USER)
+-                              wake_up_interruptible(&wq->idxd_cdev.err_queue);
++                              wake_up_interruptible(&wq->err_queue);
+               } else {
+                       int i;
+@@ -141,7 +141,7 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause)
+                               struct idxd_wq *wq = idxd->wqs[i];
+                               if (wq->type == IDXD_WQT_USER)
+-                                      wake_up_interruptible(&wq->idxd_cdev.err_queue);
++                                      wake_up_interruptible(&wq->err_queue);
+                       }
+               }
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index f793688039c9..9586b55abce5 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -1169,8 +1169,16 @@ static ssize_t wq_cdev_minor_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
+ {
+       struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
++      int minor = -1;
+-      return sprintf(buf, "%d\n", wq->idxd_cdev.minor);
++      mutex_lock(&wq->wq_lock);
++      if (wq->idxd_cdev)
++              minor = wq->idxd_cdev->minor;
++      mutex_unlock(&wq->wq_lock);
++
++      if (minor == -1)
++              return -ENXIO;
++      return sysfs_emit(buf, "%d\n", minor);
+ }
+ static struct device_attribute dev_attr_wq_cdev_minor =
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-fix-dma-device-lifetime.patch b/queue-5.11/dmaengine-idxd-fix-dma-device-lifetime.patch
new file mode 100644 (file)
index 0000000..d1ce9f6
--- /dev/null
@@ -0,0 +1,243 @@
+From 3cf2e5344a9e5e803e435e55582334506e4bffe2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:10 -0700
+Subject: dmaengine: idxd: fix dma device lifetime
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit 397862855619271296e46d10f7dfa7bafe71eb81 ]
+
+The devm managed lifetime is incompatible with 'struct device' objects that
+resides in idxd context. This is one of the series that clean up the idxd
+driver 'struct device' lifetime. Remove embedding of dma_device and dma_chan
+in idxd since it's not the only interface that idxd will use. The freeing of
+the dma_device will be managed by the ->release() function.
+
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Link: https://lore.kernel.org/r/161852983001.2203940.14817017492384561719.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/device.c |  2 -
+ drivers/dma/idxd/dma.c    | 77 ++++++++++++++++++++++++++++++++-------
+ drivers/dma/idxd/idxd.h   | 18 +++++++--
+ 3 files changed, 79 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index 78d2dc5e9bd8..d255bb016c4d 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -186,8 +186,6 @@ int idxd_wq_alloc_resources(struct idxd_wq *wq)
+               desc->id = i;
+               desc->wq = wq;
+               desc->cpu = -1;
+-              dma_async_tx_descriptor_init(&desc->txd, &wq->dma_chan);
+-              desc->txd.tx_submit = idxd_dma_tx_submit;
+       }
+       return 0;
+diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c
+index a15e50126434..77439b645044 100644
+--- a/drivers/dma/idxd/dma.c
++++ b/drivers/dma/idxd/dma.c
+@@ -14,7 +14,10 @@
+ static inline struct idxd_wq *to_idxd_wq(struct dma_chan *c)
+ {
+-      return container_of(c, struct idxd_wq, dma_chan);
++      struct idxd_dma_chan *idxd_chan;
++
++      idxd_chan = container_of(c, struct idxd_dma_chan, chan);
++      return idxd_chan->wq;
+ }
+ void idxd_dma_complete_txd(struct idxd_desc *desc,
+@@ -135,7 +138,7 @@ static void idxd_dma_issue_pending(struct dma_chan *dma_chan)
+ {
+ }
+-dma_cookie_t idxd_dma_tx_submit(struct dma_async_tx_descriptor *tx)
++static dma_cookie_t idxd_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+ {
+       struct dma_chan *c = tx->chan;
+       struct idxd_wq *wq = to_idxd_wq(c);
+@@ -156,14 +159,25 @@ dma_cookie_t idxd_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+ static void idxd_dma_release(struct dma_device *device)
+ {
++      struct idxd_dma_dev *idxd_dma = container_of(device, struct idxd_dma_dev, dma);
++
++      kfree(idxd_dma);
+ }
+ int idxd_register_dma_device(struct idxd_device *idxd)
+ {
+-      struct dma_device *dma = &idxd->dma_dev;
++      struct idxd_dma_dev *idxd_dma;
++      struct dma_device *dma;
++      struct device *dev = &idxd->pdev->dev;
++      int rc;
++      idxd_dma = kzalloc_node(sizeof(*idxd_dma), GFP_KERNEL, dev_to_node(dev));
++      if (!idxd_dma)
++              return -ENOMEM;
++
++      dma = &idxd_dma->dma;
+       INIT_LIST_HEAD(&dma->channels);
+-      dma->dev = &idxd->pdev->dev;
++      dma->dev = dev;
+       dma_cap_set(DMA_PRIVATE, dma->cap_mask);
+       dma_cap_set(DMA_COMPLETION_NO_ORDER, dma->cap_mask);
+@@ -179,35 +193,72 @@ int idxd_register_dma_device(struct idxd_device *idxd)
+       dma->device_alloc_chan_resources = idxd_dma_alloc_chan_resources;
+       dma->device_free_chan_resources = idxd_dma_free_chan_resources;
+-      return dma_async_device_register(&idxd->dma_dev);
++      rc = dma_async_device_register(dma);
++      if (rc < 0) {
++              kfree(idxd_dma);
++              return rc;
++      }
++
++      idxd_dma->idxd = idxd;
++      /*
++       * This pointer is protected by the refs taken by the dma_chan. It will remain valid
++       * as long as there are outstanding channels.
++       */
++      idxd->idxd_dma = idxd_dma;
++      return 0;
+ }
+ void idxd_unregister_dma_device(struct idxd_device *idxd)
+ {
+-      dma_async_device_unregister(&idxd->dma_dev);
++      dma_async_device_unregister(&idxd->idxd_dma->dma);
+ }
+ int idxd_register_dma_channel(struct idxd_wq *wq)
+ {
+       struct idxd_device *idxd = wq->idxd;
+-      struct dma_device *dma = &idxd->dma_dev;
+-      struct dma_chan *chan = &wq->dma_chan;
+-      int rc;
++      struct dma_device *dma = &idxd->idxd_dma->dma;
++      struct device *dev = &idxd->pdev->dev;
++      struct idxd_dma_chan *idxd_chan;
++      struct dma_chan *chan;
++      int rc, i;
++
++      idxd_chan = kzalloc_node(sizeof(*idxd_chan), GFP_KERNEL, dev_to_node(dev));
++      if (!idxd_chan)
++              return -ENOMEM;
+-      memset(&wq->dma_chan, 0, sizeof(struct dma_chan));
++      chan = &idxd_chan->chan;
+       chan->device = dma;
+       list_add_tail(&chan->device_node, &dma->channels);
++
++      for (i = 0; i < wq->num_descs; i++) {
++              struct idxd_desc *desc = wq->descs[i];
++
++              dma_async_tx_descriptor_init(&desc->txd, chan);
++              desc->txd.tx_submit = idxd_dma_tx_submit;
++      }
++
+       rc = dma_async_device_channel_register(dma, chan);
+-      if (rc < 0)
++      if (rc < 0) {
++              kfree(idxd_chan);
+               return rc;
++      }
++
++      wq->idxd_chan = idxd_chan;
++      idxd_chan->wq = wq;
++      get_device(&wq->conf_dev);
+       return 0;
+ }
+ void idxd_unregister_dma_channel(struct idxd_wq *wq)
+ {
+-      struct dma_chan *chan = &wq->dma_chan;
++      struct idxd_dma_chan *idxd_chan = wq->idxd_chan;
++      struct dma_chan *chan = &idxd_chan->chan;
++      struct idxd_dma_dev *idxd_dma = wq->idxd->idxd_dma;
+-      dma_async_device_channel_unregister(&wq->idxd->dma_dev, chan);
++      dma_async_device_channel_unregister(&idxd_dma->dma, chan);
+       list_del(&chan->device_node);
++      kfree(wq->idxd_chan);
++      wq->idxd_chan = NULL;
++      put_device(&wq->conf_dev);
+ }
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index 76014c14f473..80e534680c9a 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -14,6 +14,9 @@
+ extern struct kmem_cache *idxd_desc_pool;
++struct idxd_device;
++struct idxd_wq;
++
+ #define IDXD_REG_TIMEOUT      50
+ #define IDXD_DRAIN_TIMEOUT    5000
+@@ -96,6 +99,11 @@ enum idxd_complete_type {
+       IDXD_COMPLETE_DEV_FAIL,
+ };
++struct idxd_dma_chan {
++      struct dma_chan chan;
++      struct idxd_wq *wq;
++};
++
+ struct idxd_wq {
+       void __iomem *portal;
+       struct device conf_dev;
+@@ -125,7 +133,7 @@ struct idxd_wq {
+       int compls_size;
+       struct idxd_desc **descs;
+       struct sbitmap_queue sbq;
+-      struct dma_chan dma_chan;
++      struct idxd_dma_chan *idxd_chan;
+       char name[WQ_NAME_SIZE + 1];
+       u64 max_xfer_bytes;
+       u32 max_batch_size;
+@@ -162,6 +170,11 @@ enum idxd_device_flag {
+       IDXD_FLAG_PASID_ENABLED,
+ };
++struct idxd_dma_dev {
++      struct idxd_device *idxd;
++      struct dma_device dma;
++};
++
+ struct idxd_device {
+       enum idxd_type type;
+       struct device conf_dev;
+@@ -210,7 +223,7 @@ struct idxd_device {
+       int num_wq_irqs;
+       struct idxd_irq_entry *irq_entries;
+-      struct dma_device dma_dev;
++      struct idxd_dma_dev *idxd_dma;
+       struct workqueue_struct *wq;
+       struct work_struct work;
+ };
+@@ -363,7 +376,6 @@ void idxd_unregister_dma_channel(struct idxd_wq *wq);
+ void idxd_parse_completion_status(u8 status, enum dmaengine_tx_result *res);
+ void idxd_dma_complete_txd(struct idxd_desc *desc,
+                          enum idxd_complete_type comp_type);
+-dma_cookie_t idxd_dma_tx_submit(struct dma_async_tx_descriptor *tx);
+ /* cdev */
+ int idxd_cdev_register(void);
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-fix-engine-conf_dev-lifetime.patch b/queue-5.11/dmaengine-idxd-fix-engine-conf_dev-lifetime.patch
new file mode 100644 (file)
index 0000000..d80ce92
--- /dev/null
@@ -0,0 +1,293 @@
+From aac3ce1b631fa0c3f17afc81f3ddae23515844a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:44 -0700
+Subject: dmaengine: idxd: fix engine conf_dev lifetime
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit 75b911309060f42ba94bbbf46f5f497d35d5cd02 ]
+
+Remove devm_* allocation and fix engine->conf_dev 'struct device'
+lifetime. Address issues flagged by CONFIG_DEBUG_KOBJECT_RELEASE.
+Add release functions in order to free the allocated memory at the
+engine conf_dev destruction time.
+
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/161852986460.2203940.16603218225412118431.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/device.c |  2 +-
+ drivers/dma/idxd/idxd.h   |  3 +-
+ drivers/dma/idxd/init.c   | 60 +++++++++++++++++++++++++-------
+ drivers/dma/idxd/sysfs.c  | 72 +++++++++++++++++++--------------------
+ 4 files changed, 86 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index c4183294a704..be1dcddfe3c4 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -786,7 +786,7 @@ static int idxd_engines_setup(struct idxd_device *idxd)
+       }
+       for (i = 0; i < idxd->max_engines; i++) {
+-              eng = &idxd->engines[i];
++              eng = idxd->engines[i];
+               group = eng->group;
+               if (!group)
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index 6cade6a05314..b9b7e8e8c384 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -195,7 +195,7 @@ struct idxd_device {
+       struct completion *cmd_done;
+       struct idxd_group *groups;
+       struct idxd_wq **wqs;
+-      struct idxd_engine *engines;
++      struct idxd_engine **engines;
+       struct iommu_sva *sva;
+       unsigned int pasid;
+@@ -259,6 +259,7 @@ extern bool support_enqcmd;
+ extern struct device_type dsa_device_type;
+ extern struct device_type iax_device_type;
+ extern struct device_type idxd_wq_device_type;
++extern struct device_type idxd_engine_device_type;
+ static inline bool is_dsa_dev(struct device *dev)
+ {
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index ffc00152891e..68b58869b0cc 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -192,6 +192,46 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
+       return rc;
+ }
++static int idxd_setup_engines(struct idxd_device *idxd)
++{
++      struct idxd_engine *engine;
++      struct device *dev = &idxd->pdev->dev;
++      int i, rc;
++
++      idxd->engines = kcalloc_node(idxd->max_engines, sizeof(struct idxd_engine *),
++                                   GFP_KERNEL, dev_to_node(dev));
++      if (!idxd->engines)
++              return -ENOMEM;
++
++      for (i = 0; i < idxd->max_engines; i++) {
++              engine = kzalloc_node(sizeof(*engine), GFP_KERNEL, dev_to_node(dev));
++              if (!engine) {
++                      rc = -ENOMEM;
++                      goto err;
++              }
++
++              engine->id = i;
++              engine->idxd = idxd;
++              device_initialize(&engine->conf_dev);
++              engine->conf_dev.parent = &idxd->conf_dev;
++              engine->conf_dev.type = &idxd_engine_device_type;
++              rc = dev_set_name(&engine->conf_dev, "engine%d.%d", idxd->id, engine->id);
++              if (rc < 0) {
++                      put_device(&engine->conf_dev);
++                      goto err;
++              }
++
++              idxd->engines[i] = engine;
++      }
++
++      return 0;
++
++ err:
++      while (--i >= 0)
++              put_device(&idxd->engines[i]->conf_dev);
++      return rc;
++}
++
+ static int idxd_setup_internals(struct idxd_device *idxd)
+ {
+       struct device *dev = &idxd->pdev->dev;
+@@ -203,6 +243,10 @@ static int idxd_setup_internals(struct idxd_device *idxd)
+       if (rc < 0)
+               return rc;
++      rc = idxd_setup_engines(idxd);
++      if (rc < 0)
++              goto err_engine;
++
+       idxd->groups = devm_kcalloc(dev, idxd->max_groups,
+                                   sizeof(struct idxd_group), GFP_KERNEL);
+       if (!idxd->groups) {
+@@ -217,19 +261,6 @@ static int idxd_setup_internals(struct idxd_device *idxd)
+               idxd->groups[i].tc_b = -1;
+       }
+-      idxd->engines = devm_kcalloc(dev, idxd->max_engines,
+-                                   sizeof(struct idxd_engine), GFP_KERNEL);
+-      if (!idxd->engines) {
+-              rc = -ENOMEM;
+-              goto err;
+-      }
+-
+-
+-      for (i = 0; i < idxd->max_engines; i++) {
+-              idxd->engines[i].idxd = idxd;
+-              idxd->engines[i].id = i;
+-      }
+-
+       idxd->wq = create_workqueue(dev_name(dev));
+       if (!idxd->wq) {
+               rc = -ENOMEM;
+@@ -239,6 +270,9 @@ static int idxd_setup_internals(struct idxd_device *idxd)
+       return 0;
+  err:
++      for (i = 0; i < idxd->max_engines; i++)
++              put_device(&idxd->engines[i]->conf_dev);
++ err_engine:
+       for (i = 0; i < idxd->max_wqs; i++)
+               put_device(&idxd->wqs[i]->conf_dev);
+       return rc;
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index 409b3ce52f07..ab02e3b4d75d 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -26,11 +26,6 @@ static struct device_type idxd_group_device_type = {
+       .release = idxd_conf_sub_device_release,
+ };
+-static struct device_type idxd_engine_device_type = {
+-      .name = "engine",
+-      .release = idxd_conf_sub_device_release,
+-};
+-
+ static int idxd_config_bus_match(struct device *dev,
+                                struct device_driver *drv)
+ {
+@@ -464,6 +459,19 @@ static const struct attribute_group *idxd_engine_attribute_groups[] = {
+       NULL,
+ };
++static void idxd_conf_engine_release(struct device *dev)
++{
++      struct idxd_engine *engine = container_of(dev, struct idxd_engine, conf_dev);
++
++      kfree(engine);
++}
++
++struct device_type idxd_engine_device_type = {
++      .name = "engine",
++      .release = idxd_conf_engine_release,
++      .groups = idxd_engine_attribute_groups,
++};
++
+ /* Group attributes */
+ static void idxd_set_free_tokens(struct idxd_device *idxd)
+@@ -626,7 +634,7 @@ static ssize_t group_engines_show(struct device *dev,
+       struct idxd_device *idxd = group->idxd;
+       for (i = 0; i < idxd->max_engines; i++) {
+-              struct idxd_engine *engine = &idxd->engines[i];
++              struct idxd_engine *engine = idxd->engines[i];
+               if (!engine->group)
+                       continue;
+@@ -1634,37 +1642,27 @@ struct device_type iax_device_type = {
+       .groups = idxd_attribute_groups,
+ };
+-static int idxd_setup_engine_sysfs(struct idxd_device *idxd)
++static int idxd_register_engine_devices(struct idxd_device *idxd)
+ {
+-      struct device *dev = &idxd->pdev->dev;
+-      int i, rc;
++      int i, j, rc;
+       for (i = 0; i < idxd->max_engines; i++) {
+-              struct idxd_engine *engine = &idxd->engines[i];
+-
+-              engine->conf_dev.parent = &idxd->conf_dev;
+-              dev_set_name(&engine->conf_dev, "engine%d.%d",
+-                           idxd->id, engine->id);
+-              engine->conf_dev.bus = idxd_get_bus_type(idxd);
+-              engine->conf_dev.groups = idxd_engine_attribute_groups;
+-              engine->conf_dev.type = &idxd_engine_device_type;
+-              dev_dbg(dev, "Engine device register: %s\n",
+-                      dev_name(&engine->conf_dev));
+-              rc = device_register(&engine->conf_dev);
+-              if (rc < 0) {
+-                      put_device(&engine->conf_dev);
++              struct idxd_engine *engine = idxd->engines[i];
++
++              rc = device_add(&engine->conf_dev);
++              if (rc < 0)
+                       goto cleanup;
+-              }
+       }
+       return 0;
+ cleanup:
+-      while (i--) {
+-              struct idxd_engine *engine = &idxd->engines[i];
++      j = i - 1;
++      for (; i < idxd->max_engines; i++)
++              put_device(&idxd->engines[i]->conf_dev);
+-              device_unregister(&engine->conf_dev);
+-      }
++      while (j--)
++              device_unregister(&idxd->engines[j]->conf_dev);
+       return rc;
+ }
+@@ -1741,23 +1739,25 @@ int idxd_register_devices(struct idxd_device *idxd)
+               goto err_wq;
+       }
+-      rc = idxd_setup_group_sysfs(idxd);
++      rc = idxd_register_engine_devices(idxd);
+       if (rc < 0) {
+-              /* unregister conf dev */
+-              dev_dbg(dev, "Group sysfs registering failed: %d\n", rc);
+-              goto err;
++              dev_dbg(dev, "Engine devices registering failed: %d\n", rc);
++              goto err_engine;
+       }
+-      rc = idxd_setup_engine_sysfs(idxd);
++      rc = idxd_setup_group_sysfs(idxd);
+       if (rc < 0) {
+               /* unregister conf dev */
+-              dev_dbg(dev, "Engine sysfs registering failed: %d\n", rc);
+-              goto err;
++              dev_dbg(dev, "Group sysfs registering failed: %d\n", rc);
++              goto err_group;
+       }
+       return 0;
+- err:
++ err_group:
++      for (i = 0; i < idxd->max_engines; i++)
++              device_unregister(&idxd->engines[i]->conf_dev);
++ err_engine:
+       for (i = 0; i < idxd->max_wqs; i++)
+               device_unregister(&idxd->wqs[i]->conf_dev);
+  err_wq:
+@@ -1776,7 +1776,7 @@ void idxd_unregister_devices(struct idxd_device *idxd)
+       }
+       for (i = 0; i < idxd->max_engines; i++) {
+-              struct idxd_engine *engine = &idxd->engines[i];
++              struct idxd_engine *engine = idxd->engines[i];
+               device_unregister(&engine->conf_dev);
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-fix-group-conf_dev-lifetime.patch b/queue-5.11/dmaengine-idxd-fix-group-conf_dev-lifetime.patch
new file mode 100644 (file)
index 0000000..50551e3
--- /dev/null
@@ -0,0 +1,328 @@
+From f3c814197af4d1a4fe0cea0cabc1d5108e941e02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:51 -0700
+Subject: dmaengine: idxd: fix group conf_dev lifetime
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit defe49f96012ca91e8e673cb95b5c30b4a3735e8 ]
+
+Remove devm_* allocation and fix group->conf_dev 'struct device'
+lifetime. Address issues flagged by CONFIG_DEBUG_KOBJECT_RELEASE.
+Add release functions in order to free the allocated memory at the
+group->conf_dev destruction time.
+
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/161852987144.2203940.8830315575880047.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/device.c |  8 ++---
+ drivers/dma/idxd/idxd.h   |  3 +-
+ drivers/dma/idxd/init.c   | 68 ++++++++++++++++++++++++++++++---------
+ drivers/dma/idxd/sysfs.c  | 68 +++++++++++++++++----------------------
+ 4 files changed, 88 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index be1dcddfe3c4..4fef57717049 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -659,7 +659,7 @@ static int idxd_groups_config_write(struct idxd_device *idxd)
+               ioread32(idxd->reg_base + IDXD_GENCFG_OFFSET));
+       for (i = 0; i < idxd->max_groups; i++) {
+-              struct idxd_group *group = &idxd->groups[i];
++              struct idxd_group *group = idxd->groups[i];
+               idxd_group_config_write(group);
+       }
+@@ -754,7 +754,7 @@ static void idxd_group_flags_setup(struct idxd_device *idxd)
+       /* TC-A 0 and TC-B 1 should be defaults */
+       for (i = 0; i < idxd->max_groups; i++) {
+-              struct idxd_group *group = &idxd->groups[i];
++              struct idxd_group *group = idxd->groups[i];
+               if (group->tc_a == -1)
+                       group->tc_a = group->grpcfg.flags.tc_a = 0;
+@@ -781,7 +781,7 @@ static int idxd_engines_setup(struct idxd_device *idxd)
+       struct idxd_group *group;
+       for (i = 0; i < idxd->max_groups; i++) {
+-              group = &idxd->groups[i];
++              group = idxd->groups[i];
+               group->grpcfg.engines = 0;
+       }
+@@ -810,7 +810,7 @@ static int idxd_wqs_setup(struct idxd_device *idxd)
+       struct device *dev = &idxd->pdev->dev;
+       for (i = 0; i < idxd->max_groups; i++) {
+-              group = &idxd->groups[i];
++              group = idxd->groups[i];
+               for (j = 0; j < 4; j++)
+                       group->grpcfg.wqs[j] = 0;
+       }
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index b9b7e8e8c384..3c4ce7997c88 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -193,7 +193,7 @@ struct idxd_device {
+       spinlock_t dev_lock;    /* spinlock for device */
+       struct completion *cmd_done;
+-      struct idxd_group *groups;
++      struct idxd_group **groups;
+       struct idxd_wq **wqs;
+       struct idxd_engine **engines;
+@@ -260,6 +260,7 @@ extern struct device_type dsa_device_type;
+ extern struct device_type iax_device_type;
+ extern struct device_type idxd_wq_device_type;
+ extern struct device_type idxd_engine_device_type;
++extern struct device_type idxd_group_device_type;
+ static inline bool is_dsa_dev(struct device *dev)
+ {
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index 68b58869b0cc..25d801916aec 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -232,11 +232,54 @@ static int idxd_setup_engines(struct idxd_device *idxd)
+       return rc;
+ }
+-static int idxd_setup_internals(struct idxd_device *idxd)
++static int idxd_setup_groups(struct idxd_device *idxd)
+ {
+       struct device *dev = &idxd->pdev->dev;
++      struct idxd_group *group;
+       int i, rc;
++      idxd->groups = kcalloc_node(idxd->max_groups, sizeof(struct idxd_group *),
++                                  GFP_KERNEL, dev_to_node(dev));
++      if (!idxd->groups)
++              return -ENOMEM;
++
++      for (i = 0; i < idxd->max_groups; i++) {
++              group = kzalloc_node(sizeof(*group), GFP_KERNEL, dev_to_node(dev));
++              if (!group) {
++                      rc = -ENOMEM;
++                      goto err;
++              }
++
++              group->id = i;
++              group->idxd = idxd;
++              device_initialize(&group->conf_dev);
++              group->conf_dev.parent = &idxd->conf_dev;
++              group->conf_dev.bus = idxd_get_bus_type(idxd);
++              group->conf_dev.type = &idxd_group_device_type;
++              rc = dev_set_name(&group->conf_dev, "group%d.%d", idxd->id, group->id);
++              if (rc < 0) {
++                      put_device(&group->conf_dev);
++                      goto err;
++              }
++
++              idxd->groups[i] = group;
++              group->tc_a = -1;
++              group->tc_b = -1;
++      }
++
++      return 0;
++
++ err:
++      while (--i >= 0)
++              put_device(&idxd->groups[i]->conf_dev);
++      return rc;
++}
++
++static int idxd_setup_internals(struct idxd_device *idxd)
++{
++      struct device *dev = &idxd->pdev->dev;
++      int rc, i;
++
+       init_waitqueue_head(&idxd->cmd_waitq);
+       rc = idxd_setup_wqs(idxd);
+@@ -247,29 +290,22 @@ static int idxd_setup_internals(struct idxd_device *idxd)
+       if (rc < 0)
+               goto err_engine;
+-      idxd->groups = devm_kcalloc(dev, idxd->max_groups,
+-                                  sizeof(struct idxd_group), GFP_KERNEL);
+-      if (!idxd->groups) {
+-              rc = -ENOMEM;
+-              goto err;
+-      }
+-
+-      for (i = 0; i < idxd->max_groups; i++) {
+-              idxd->groups[i].idxd = idxd;
+-              idxd->groups[i].id = i;
+-              idxd->groups[i].tc_a = -1;
+-              idxd->groups[i].tc_b = -1;
+-      }
++      rc = idxd_setup_groups(idxd);
++      if (rc < 0)
++              goto err_group;
+       idxd->wq = create_workqueue(dev_name(dev));
+       if (!idxd->wq) {
+               rc = -ENOMEM;
+-              goto err;
++              goto err_wkq_create;
+       }
+       return 0;
+- err:
++ err_wkq_create:
++      for (i = 0; i < idxd->max_groups; i++)
++              put_device(&idxd->groups[i]->conf_dev);
++ err_group:
+       for (i = 0; i < idxd->max_engines; i++)
+               put_device(&idxd->engines[i]->conf_dev);
+  err_engine:
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index ab02e3b4d75d..f793688039c9 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -16,16 +16,6 @@ static char *idxd_wq_type_names[] = {
+       [IDXD_WQT_USER]         = "user",
+ };
+-static void idxd_conf_sub_device_release(struct device *dev)
+-{
+-      dev_dbg(dev, "%s for %s\n", __func__, dev_name(dev));
+-}
+-
+-static struct device_type idxd_group_device_type = {
+-      .name = "group",
+-      .release = idxd_conf_sub_device_release,
+-};
+-
+ static int idxd_config_bus_match(struct device *dev,
+                                struct device_driver *drv)
+ {
+@@ -435,7 +425,7 @@ static ssize_t engine_group_id_store(struct device *dev,
+       if (prevg)
+               prevg->num_engines--;
+-      engine->group = &idxd->groups[id];
++      engine->group = idxd->groups[id];
+       engine->group->num_engines++;
+       return count;
+@@ -479,7 +469,7 @@ static void idxd_set_free_tokens(struct idxd_device *idxd)
+       int i, tokens;
+       for (i = 0, tokens = 0; i < idxd->max_groups; i++) {
+-              struct idxd_group *g = &idxd->groups[i];
++              struct idxd_group *g = idxd->groups[i];
+               tokens += g->tokens_reserved;
+       }
+@@ -784,6 +774,19 @@ static const struct attribute_group *idxd_group_attribute_groups[] = {
+       NULL,
+ };
++static void idxd_conf_group_release(struct device *dev)
++{
++      struct idxd_group *group = container_of(dev, struct idxd_group, conf_dev);
++
++      kfree(group);
++}
++
++struct device_type idxd_group_device_type = {
++      .name = "group",
++      .release = idxd_conf_group_release,
++      .groups = idxd_group_attribute_groups,
++};
++
+ /* IDXD work queue attribs */
+ static ssize_t wq_clients_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+@@ -856,7 +859,7 @@ static ssize_t wq_group_id_store(struct device *dev,
+               return count;
+       }
+-      group = &idxd->groups[id];
++      group = idxd->groups[id];
+       prevg = wq->group;
+       if (prevg)
+@@ -1666,37 +1669,27 @@ cleanup:
+       return rc;
+ }
+-static int idxd_setup_group_sysfs(struct idxd_device *idxd)
++static int idxd_register_group_devices(struct idxd_device *idxd)
+ {
+-      struct device *dev = &idxd->pdev->dev;
+-      int i, rc;
++      int i, j, rc;
+       for (i = 0; i < idxd->max_groups; i++) {
+-              struct idxd_group *group = &idxd->groups[i];
+-
+-              group->conf_dev.parent = &idxd->conf_dev;
+-              dev_set_name(&group->conf_dev, "group%d.%d",
+-                           idxd->id, group->id);
+-              group->conf_dev.bus = idxd_get_bus_type(idxd);
+-              group->conf_dev.groups = idxd_group_attribute_groups;
+-              group->conf_dev.type = &idxd_group_device_type;
+-              dev_dbg(dev, "Group device register: %s\n",
+-                      dev_name(&group->conf_dev));
+-              rc = device_register(&group->conf_dev);
+-              if (rc < 0) {
+-                      put_device(&group->conf_dev);
++              struct idxd_group *group = idxd->groups[i];
++
++              rc = device_add(&group->conf_dev);
++              if (rc < 0)
+                       goto cleanup;
+-              }
+       }
+       return 0;
+ cleanup:
+-      while (i--) {
+-              struct idxd_group *group = &idxd->groups[i];
++      j = i - 1;
++      for (; i < idxd->max_groups; i++)
++              put_device(&idxd->groups[i]->conf_dev);
+-              device_unregister(&group->conf_dev);
+-      }
++      while (j--)
++              device_unregister(&idxd->groups[j]->conf_dev);
+       return rc;
+ }
+@@ -1745,10 +1738,9 @@ int idxd_register_devices(struct idxd_device *idxd)
+               goto err_engine;
+       }
+-      rc = idxd_setup_group_sysfs(idxd);
++      rc = idxd_register_group_devices(idxd);
+       if (rc < 0) {
+-              /* unregister conf dev */
+-              dev_dbg(dev, "Group sysfs registering failed: %d\n", rc);
++              dev_dbg(dev, "Group device registering failed: %d\n", rc);
+               goto err_group;
+       }
+@@ -1782,7 +1774,7 @@ void idxd_unregister_devices(struct idxd_device *idxd)
+       }
+       for (i = 0; i < idxd->max_groups; i++) {
+-              struct idxd_group *group = &idxd->groups[i];
++              struct idxd_group *group = idxd->groups[i];
+               device_unregister(&group->conf_dev);
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-fix-idxd-conf_dev-struct-device-lifet.patch b/queue-5.11/dmaengine-idxd-fix-idxd-conf_dev-struct-device-lifet.patch
new file mode 100644 (file)
index 0000000..382615d
--- /dev/null
@@ -0,0 +1,390 @@
+From fe617be1b504f051aeea9c4d5eff573ba4fc54c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:33 -0700
+Subject: dmaengine: idxd: fix idxd conf_dev 'struct device' lifetime
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit 47c16ac27d4cb664cee53ee0b9b7e2f907923fb3 ]
+
+The devm managed lifetime is incompatible with 'struct device' objects that
+resides in idxd context. This is one of the series that clean up the idxd
+driver 'struct device' lifetime. Fix idxd->conf_dev 'struct device'
+lifetime. Address issues flagged by CONFIG_DEBUG_KOBJECT_RELEASE.
+Add release functions in order to free the allocated memory at the
+appropriate time.
+
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/161852985319.2203940.4650791514462735368.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/idxd.h  | 36 ++++++++++------
+ drivers/dma/idxd/init.c  | 56 ++++++++++++++++--------
+ drivers/dma/idxd/sysfs.c | 92 ++++++++++++++--------------------------
+ 3 files changed, 94 insertions(+), 90 deletions(-)
+
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index 401b035e42b1..bb3a580732af 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -8,6 +8,7 @@
+ #include <linux/percpu-rwsem.h>
+ #include <linux/wait.h>
+ #include <linux/cdev.h>
++#include <linux/idr.h>
+ #include "registers.h"
+ #define IDXD_DRIVER_VERSION   "1.00"
+@@ -255,6 +256,23 @@ extern struct bus_type dsa_bus_type;
+ extern struct bus_type iax_bus_type;
+ extern bool support_enqcmd;
++extern struct device_type dsa_device_type;
++extern struct device_type iax_device_type;
++
++static inline bool is_dsa_dev(struct device *dev)
++{
++      return dev->type == &dsa_device_type;
++}
++
++static inline bool is_iax_dev(struct device *dev)
++{
++      return dev->type == &iax_device_type;
++}
++
++static inline bool is_idxd_dev(struct device *dev)
++{
++      return is_dsa_dev(dev) || is_iax_dev(dev);
++}
+ static inline bool wq_dedicated(struct idxd_wq *wq)
+ {
+@@ -292,18 +310,6 @@ static inline int idxd_get_wq_portal_full_offset(int wq_id,
+       return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot);
+ }
+-static inline void idxd_set_type(struct idxd_device *idxd)
+-{
+-      struct pci_dev *pdev = idxd->pdev;
+-
+-      if (pdev->device == PCI_DEVICE_ID_INTEL_DSA_SPR0)
+-              idxd->type = IDXD_TYPE_DSA;
+-      else if (pdev->device == PCI_DEVICE_ID_INTEL_IAX_SPR0)
+-              idxd->type = IDXD_TYPE_IAX;
+-      else
+-              idxd->type = IDXD_TYPE_UNKNOWN;
+-}
+-
+ static inline void idxd_wq_get(struct idxd_wq *wq)
+ {
+       wq->client_count++;
+@@ -319,14 +325,16 @@ static inline int idxd_wq_refcount(struct idxd_wq *wq)
+       return wq->client_count;
+ };
++struct ida *idxd_ida(struct idxd_device *idxd);
+ const char *idxd_get_dev_name(struct idxd_device *idxd);
+ int idxd_register_bus_type(void);
+ void idxd_unregister_bus_type(void);
+-int idxd_setup_sysfs(struct idxd_device *idxd);
+-void idxd_cleanup_sysfs(struct idxd_device *idxd);
++int idxd_register_devices(struct idxd_device *idxd);
++void idxd_unregister_devices(struct idxd_device *idxd);
+ int idxd_register_driver(void);
+ void idxd_unregister_driver(void);
+ struct bus_type *idxd_get_bus_type(struct idxd_device *idxd);
++struct device_type *idxd_get_device_type(struct idxd_device *idxd);
+ /* device interrupt control */
+ void idxd_msix_perm_setup(struct idxd_device *idxd);
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index 6e97a9870ba8..20ca57c8ef68 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -47,6 +47,11 @@ static char *idxd_name[] = {
+       "iax"
+ };
++struct ida *idxd_ida(struct idxd_device *idxd)
++{
++      return &idxd_idas[idxd->type];
++}
++
+ const char *idxd_get_dev_name(struct idxd_device *idxd)
+ {
+       return idxd_name[idxd->type];
+@@ -77,9 +82,8 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
+        * We implement 1 completion list per MSI-X entry except for
+        * entry 0, which is for errors and others.
+        */
+-      idxd->irq_entries = devm_kcalloc(dev, msixcnt,
+-                                       sizeof(struct idxd_irq_entry),
+-                                       GFP_KERNEL);
++      idxd->irq_entries = kcalloc_node(msixcnt, sizeof(struct idxd_irq_entry),
++                                       GFP_KERNEL, dev_to_node(dev));
+       if (!idxd->irq_entries) {
+               rc = -ENOMEM;
+               goto err_irq_entries;
+@@ -258,16 +262,44 @@ static void idxd_read_caps(struct idxd_device *idxd)
+       }
+ }
++static inline void idxd_set_type(struct idxd_device *idxd)
++{
++      struct pci_dev *pdev = idxd->pdev;
++
++      if (pdev->device == PCI_DEVICE_ID_INTEL_DSA_SPR0)
++              idxd->type = IDXD_TYPE_DSA;
++      else if (pdev->device == PCI_DEVICE_ID_INTEL_IAX_SPR0)
++              idxd->type = IDXD_TYPE_IAX;
++      else
++              idxd->type = IDXD_TYPE_UNKNOWN;
++}
++
+ static struct idxd_device *idxd_alloc(struct pci_dev *pdev)
+ {
+       struct device *dev = &pdev->dev;
+       struct idxd_device *idxd;
++      int rc;
+-      idxd = devm_kzalloc(dev, sizeof(struct idxd_device), GFP_KERNEL);
++      idxd = kzalloc_node(sizeof(*idxd), GFP_KERNEL, dev_to_node(dev));
+       if (!idxd)
+               return NULL;
+       idxd->pdev = pdev;
++      idxd_set_type(idxd);
++      idxd->id = ida_alloc(idxd_ida(idxd), GFP_KERNEL);
++      if (idxd->id < 0)
++              return NULL;
++
++      device_initialize(&idxd->conf_dev);
++      idxd->conf_dev.parent = dev;
++      idxd->conf_dev.bus = idxd_get_bus_type(idxd);
++      idxd->conf_dev.type = idxd_get_device_type(idxd);
++      rc = dev_set_name(&idxd->conf_dev, "%s%d", idxd_get_dev_name(idxd), idxd->id);
++      if (rc < 0) {
++              put_device(&idxd->conf_dev);
++              return NULL;
++      }
++
+       spin_lock_init(&idxd->dev_lock);
+       return idxd;
+@@ -341,20 +373,11 @@ static int idxd_probe(struct idxd_device *idxd)
+       dev_dbg(dev, "IDXD interrupt setup complete.\n");
+-      idxd->id = ida_alloc(&idxd_idas[idxd->type], GFP_KERNEL);
+-      if (idxd->id < 0) {
+-              rc = -ENOMEM;
+-              goto err_ida_fail;
+-      }
+-
+       idxd->major = idxd_cdev_get_major(idxd);
+       dev_dbg(dev, "IDXD device %d probed successfully\n", idxd->id);
+       return 0;
+- err_ida_fail:
+-      idxd_mask_error_interrupts(idxd);
+-      idxd_mask_msix_vectors(idxd);
+  err_setup:
+       if (device_pasid_enabled(idxd))
+               idxd_disable_system_pasid(idxd);
+@@ -406,7 +429,6 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       if (rc)
+               goto err;
+-      idxd_set_type(idxd);
+       idxd_type_init(idxd);
+@@ -421,7 +443,7 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+               goto err;
+       }
+-      rc = idxd_setup_sysfs(idxd);
++      rc = idxd_register_devices(idxd);
+       if (rc) {
+               dev_err(dev, "IDXD sysfs setup failed\n");
+               goto err;
+@@ -437,6 +459,7 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+  err:
+       pci_iounmap(pdev, idxd->reg_base);
+  err_iomap:
++      put_device(&idxd->conf_dev);
+  err_idxd_alloc:
+       pci_disable_device(pdev);
+       return rc;
+@@ -505,11 +528,10 @@ static void idxd_remove(struct pci_dev *pdev)
+       struct idxd_device *idxd = pci_get_drvdata(pdev);
+       dev_dbg(&pdev->dev, "%s called\n", __func__);
+-      idxd_cleanup_sysfs(idxd);
+       idxd_shutdown(pdev);
+       if (device_pasid_enabled(idxd))
+               idxd_disable_system_pasid(idxd);
+-      ida_free(&idxd_idas[idxd->type], idxd->id);
++      idxd_unregister_devices(idxd);
+ }
+ static struct pci_driver idxd_pci_driver = {
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index 18bf4d148989..36193e555e36 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -16,51 +16,26 @@ static char *idxd_wq_type_names[] = {
+       [IDXD_WQT_USER]         = "user",
+ };
+-static void idxd_conf_device_release(struct device *dev)
++static void idxd_conf_sub_device_release(struct device *dev)
+ {
+       dev_dbg(dev, "%s for %s\n", __func__, dev_name(dev));
+ }
+ static struct device_type idxd_group_device_type = {
+       .name = "group",
+-      .release = idxd_conf_device_release,
++      .release = idxd_conf_sub_device_release,
+ };
+ static struct device_type idxd_wq_device_type = {
+       .name = "wq",
+-      .release = idxd_conf_device_release,
++      .release = idxd_conf_sub_device_release,
+ };
+ static struct device_type idxd_engine_device_type = {
+       .name = "engine",
+-      .release = idxd_conf_device_release,
++      .release = idxd_conf_sub_device_release,
+ };
+-static struct device_type dsa_device_type = {
+-      .name = "dsa",
+-      .release = idxd_conf_device_release,
+-};
+-
+-static struct device_type iax_device_type = {
+-      .name = "iax",
+-      .release = idxd_conf_device_release,
+-};
+-
+-static inline bool is_dsa_dev(struct device *dev)
+-{
+-      return dev ? dev->type == &dsa_device_type : false;
+-}
+-
+-static inline bool is_iax_dev(struct device *dev)
+-{
+-      return dev ? dev->type == &iax_device_type : false;
+-}
+-
+-static inline bool is_idxd_dev(struct device *dev)
+-{
+-      return is_dsa_dev(dev) || is_iax_dev(dev);
+-}
+-
+ static inline bool is_idxd_wq_dev(struct device *dev)
+ {
+       return dev ? dev->type == &idxd_wq_device_type : false;
+@@ -405,7 +380,7 @@ struct bus_type *idxd_get_bus_type(struct idxd_device *idxd)
+       return idxd_bus_types[idxd->type];
+ }
+-static struct device_type *idxd_get_device_type(struct idxd_device *idxd)
++struct device_type *idxd_get_device_type(struct idxd_device *idxd)
+ {
+       if (idxd->type == IDXD_TYPE_DSA)
+               return &dsa_device_type;
+@@ -1644,6 +1619,30 @@ static const struct attribute_group *idxd_attribute_groups[] = {
+       NULL,
+ };
++static void idxd_conf_device_release(struct device *dev)
++{
++      struct idxd_device *idxd = container_of(dev, struct idxd_device, conf_dev);
++
++      kfree(idxd->groups);
++      kfree(idxd->wqs);
++      kfree(idxd->engines);
++      kfree(idxd->irq_entries);
++      ida_free(idxd_ida(idxd), idxd->id);
++      kfree(idxd);
++}
++
++struct device_type dsa_device_type = {
++      .name = "dsa",
++      .release = idxd_conf_device_release,
++      .groups = idxd_attribute_groups,
++};
++
++struct device_type iax_device_type = {
++      .name = "iax",
++      .release = idxd_conf_device_release,
++      .groups = idxd_attribute_groups,
++};
++
+ static int idxd_setup_engine_sysfs(struct idxd_device *idxd)
+ {
+       struct device *dev = &idxd->pdev->dev;
+@@ -1745,39 +1744,14 @@ cleanup:
+       return rc;
+ }
+-static int idxd_setup_device_sysfs(struct idxd_device *idxd)
++int idxd_register_devices(struct idxd_device *idxd)
+ {
+       struct device *dev = &idxd->pdev->dev;
+       int rc;
+-      char devname[IDXD_NAME_SIZE];
+-      sprintf(devname, "%s%d", idxd_get_dev_name(idxd), idxd->id);
+-      idxd->conf_dev.parent = dev;
+-      dev_set_name(&idxd->conf_dev, "%s", devname);
+-      idxd->conf_dev.bus = idxd_get_bus_type(idxd);
+-      idxd->conf_dev.groups = idxd_attribute_groups;
+-      idxd->conf_dev.type = idxd_get_device_type(idxd);
+-
+-      dev_dbg(dev, "IDXD device register: %s\n", dev_name(&idxd->conf_dev));
+-      rc = device_register(&idxd->conf_dev);
+-      if (rc < 0) {
+-              put_device(&idxd->conf_dev);
+-              return rc;
+-      }
+-
+-      return 0;
+-}
+-
+-int idxd_setup_sysfs(struct idxd_device *idxd)
+-{
+-      struct device *dev = &idxd->pdev->dev;
+-      int rc;
+-
+-      rc = idxd_setup_device_sysfs(idxd);
+-      if (rc < 0) {
+-              dev_dbg(dev, "Device sysfs registering failed: %d\n", rc);
++      rc = device_add(&idxd->conf_dev);
++      if (rc < 0)
+               return rc;
+-      }
+       rc = idxd_setup_wq_sysfs(idxd);
+       if (rc < 0) {
+@@ -1803,7 +1777,7 @@ int idxd_setup_sysfs(struct idxd_device *idxd)
+       return 0;
+ }
+-void idxd_cleanup_sysfs(struct idxd_device *idxd)
++void idxd_unregister_devices(struct idxd_device *idxd)
+ {
+       int i;
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-fix-potential-null-dereference-on-poi.patch b/queue-5.11/dmaengine-idxd-fix-potential-null-dereference-on-poi.patch
new file mode 100644 (file)
index 0000000..b6ef23d
--- /dev/null
@@ -0,0 +1,44 @@
+From 1cf7a71a947e2e35107f824020237d42097cdf50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 12:06:54 +0100
+Subject: dmaengine: idxd: Fix potential null dereference on pointer status
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit 28ac8e03c43dfc6a703aa420d18222540b801120 ]
+
+There are calls to idxd_cmd_exec that pass a null status pointer however
+a recent commit has added an assignment to *status that can end up
+with a null pointer dereference.  The function expects a null status
+pointer sometimes as there is a later assignment to *status where
+status is first null checked.  Fix the issue by null checking status
+before making the assignment.
+
+Addresses-Coverity: ("Explicit null dereferenced")
+Fixes: 89e3becd8f82 ("dmaengine: idxd: check device state before issue command")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Acked-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20210415110654.1941580-1-colin.king@canonical.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/device.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index 31c819544a22..78d2dc5e9bd8 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -451,7 +451,8 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
+       if (idxd_device_is_halted(idxd)) {
+               dev_warn(&idxd->pdev->dev, "Device is HALTED!\n");
+-              *status = IDXD_CMDSTS_HW_ERR;
++              if (status)
++                      *status = IDXD_CMDSTS_HW_ERR;
+               return;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-fix-wq-conf_dev-struct-device-lifetim.patch b/queue-5.11/dmaengine-idxd-fix-wq-conf_dev-struct-device-lifetim.patch
new file mode 100644 (file)
index 0000000..9095349
--- /dev/null
@@ -0,0 +1,506 @@
+From 9ab152cce25017ecca8baf9aeea3b96c26e315d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:39 -0700
+Subject: dmaengine: idxd: fix wq conf_dev 'struct device' lifetime
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit 7c5dd23e57c14cf7177b8a5e0fd08916e0c60005 ]
+
+Remove devm_* allocation and fix wq->conf_dev 'struct device' lifetime.
+Address issues flagged by CONFIG_DEBUG_KOBJECT_RELEASE. Add release
+functions in order to free the allocated memory for the wq context at
+device destruction time.
+
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/161852985907.2203940.6840120734115043753.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/device.c |   6 +--
+ drivers/dma/idxd/idxd.h   |  20 +++++++-
+ drivers/dma/idxd/init.c   | 105 ++++++++++++++++++++++++++++----------
+ drivers/dma/idxd/irq.c    |   6 +--
+ drivers/dma/idxd/sysfs.c  | 100 ++++++++++++++++--------------------
+ 5 files changed, 146 insertions(+), 91 deletions(-)
+
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index 3f696abd74ac..c4183294a704 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -520,7 +520,7 @@ void idxd_device_wqs_clear_state(struct idxd_device *idxd)
+       lockdep_assert_held(&idxd->dev_lock);
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
++              struct idxd_wq *wq = idxd->wqs[i];
+               if (wq->state == IDXD_WQ_ENABLED) {
+                       idxd_wq_disable_cleanup(wq);
+@@ -738,7 +738,7 @@ static int idxd_wqs_config_write(struct idxd_device *idxd)
+       int i, rc;
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
++              struct idxd_wq *wq = idxd->wqs[i];
+               rc = idxd_wq_config_write(wq);
+               if (rc < 0)
+@@ -816,7 +816,7 @@ static int idxd_wqs_setup(struct idxd_device *idxd)
+       }
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              wq = &idxd->wqs[i];
++              wq = idxd->wqs[i];
+               group = wq->group;
+               if (!wq->group)
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index bb3a580732af..6cade6a05314 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -194,7 +194,7 @@ struct idxd_device {
+       spinlock_t dev_lock;    /* spinlock for device */
+       struct completion *cmd_done;
+       struct idxd_group *groups;
+-      struct idxd_wq *wqs;
++      struct idxd_wq **wqs;
+       struct idxd_engine *engines;
+       struct iommu_sva *sva;
+@@ -258,6 +258,7 @@ extern struct bus_type iax_bus_type;
+ extern bool support_enqcmd;
+ extern struct device_type dsa_device_type;
+ extern struct device_type iax_device_type;
++extern struct device_type idxd_wq_device_type;
+ static inline bool is_dsa_dev(struct device *dev)
+ {
+@@ -274,6 +275,23 @@ static inline bool is_idxd_dev(struct device *dev)
+       return is_dsa_dev(dev) || is_iax_dev(dev);
+ }
++static inline bool is_idxd_wq_dev(struct device *dev)
++{
++      return dev->type == &idxd_wq_device_type;
++}
++
++static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq)
++{
++      if (wq->type == IDXD_WQT_KERNEL && strcmp(wq->name, "dmaengine") == 0)
++              return true;
++      return false;
++}
++
++static inline bool is_idxd_wq_cdev(struct idxd_wq *wq)
++{
++      return wq->type == IDXD_WQT_USER;
++}
++
+ static inline bool wq_dedicated(struct idxd_wq *wq)
+ {
+       return test_bit(WQ_FLAG_DEDICATED, &wq->flags);
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index 20ca57c8ef68..ffc00152891e 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -141,16 +141,74 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
+       return rc;
+ }
++static int idxd_setup_wqs(struct idxd_device *idxd)
++{
++      struct device *dev = &idxd->pdev->dev;
++      struct idxd_wq *wq;
++      int i, rc;
++
++      idxd->wqs = kcalloc_node(idxd->max_wqs, sizeof(struct idxd_wq *),
++                               GFP_KERNEL, dev_to_node(dev));
++      if (!idxd->wqs)
++              return -ENOMEM;
++
++      for (i = 0; i < idxd->max_wqs; i++) {
++              wq = kzalloc_node(sizeof(*wq), GFP_KERNEL, dev_to_node(dev));
++              if (!wq) {
++                      rc = -ENOMEM;
++                      goto err;
++              }
++
++              wq->id = i;
++              wq->idxd = idxd;
++              device_initialize(&wq->conf_dev);
++              wq->conf_dev.parent = &idxd->conf_dev;
++              wq->conf_dev.bus = idxd_get_bus_type(idxd);
++              wq->conf_dev.type = &idxd_wq_device_type;
++              rc = dev_set_name(&wq->conf_dev, "wq%d.%d", idxd->id, wq->id);
++              if (rc < 0) {
++                      put_device(&wq->conf_dev);
++                      goto err;
++              }
++
++              mutex_init(&wq->wq_lock);
++              wq->idxd_cdev.minor = -1;
++              wq->max_xfer_bytes = idxd->max_xfer_bytes;
++              wq->max_batch_size = idxd->max_batch_size;
++              wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
++              if (!wq->wqcfg) {
++                      put_device(&wq->conf_dev);
++                      rc = -ENOMEM;
++                      goto err;
++              }
++              idxd->wqs[i] = wq;
++      }
++
++      return 0;
++
++ err:
++      while (--i >= 0)
++              put_device(&idxd->wqs[i]->conf_dev);
++      return rc;
++}
++
+ static int idxd_setup_internals(struct idxd_device *idxd)
+ {
+       struct device *dev = &idxd->pdev->dev;
+-      int i;
++      int i, rc;
+       init_waitqueue_head(&idxd->cmd_waitq);
++
++      rc = idxd_setup_wqs(idxd);
++      if (rc < 0)
++              return rc;
++
+       idxd->groups = devm_kcalloc(dev, idxd->max_groups,
+                                   sizeof(struct idxd_group), GFP_KERNEL);
+-      if (!idxd->groups)
+-              return -ENOMEM;
++      if (!idxd->groups) {
++              rc = -ENOMEM;
++              goto err;
++      }
+       for (i = 0; i < idxd->max_groups; i++) {
+               idxd->groups[i].idxd = idxd;
+@@ -159,40 +217,31 @@ static int idxd_setup_internals(struct idxd_device *idxd)
+               idxd->groups[i].tc_b = -1;
+       }
+-      idxd->wqs = devm_kcalloc(dev, idxd->max_wqs, sizeof(struct idxd_wq),
+-                               GFP_KERNEL);
+-      if (!idxd->wqs)
+-              return -ENOMEM;
+-
+       idxd->engines = devm_kcalloc(dev, idxd->max_engines,
+                                    sizeof(struct idxd_engine), GFP_KERNEL);
+-      if (!idxd->engines)
+-              return -ENOMEM;
+-
+-      for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
+-
+-              wq->id = i;
+-              wq->idxd = idxd;
+-              mutex_init(&wq->wq_lock);
+-              wq->idxd_cdev.minor = -1;
+-              wq->max_xfer_bytes = idxd->max_xfer_bytes;
+-              wq->max_batch_size = idxd->max_batch_size;
+-              wq->wqcfg = devm_kzalloc(dev, idxd->wqcfg_size, GFP_KERNEL);
+-              if (!wq->wqcfg)
+-                      return -ENOMEM;
++      if (!idxd->engines) {
++              rc = -ENOMEM;
++              goto err;
+       }
++
+       for (i = 0; i < idxd->max_engines; i++) {
+               idxd->engines[i].idxd = idxd;
+               idxd->engines[i].id = i;
+       }
+       idxd->wq = create_workqueue(dev_name(dev));
+-      if (!idxd->wq)
+-              return -ENOMEM;
++      if (!idxd->wq) {
++              rc = -ENOMEM;
++              goto err;
++      }
+       return 0;
++
++ err:
++      for (i = 0; i < idxd->max_wqs; i++)
++              put_device(&idxd->wqs[i]->conf_dev);
++      return rc;
+ }
+ static void idxd_read_table_offsets(struct idxd_device *idxd)
+@@ -365,11 +414,11 @@ static int idxd_probe(struct idxd_device *idxd)
+       rc = idxd_setup_internals(idxd);
+       if (rc)
+-              goto err_setup;
++              goto err;
+       rc = idxd_setup_interrupts(idxd);
+       if (rc)
+-              goto err_setup;
++              goto err;
+       dev_dbg(dev, "IDXD interrupt setup complete.\n");
+@@ -378,7 +427,7 @@ static int idxd_probe(struct idxd_device *idxd)
+       dev_dbg(dev, "IDXD device %d probed successfully\n", idxd->id);
+       return 0;
+- err_setup:
++ err:
+       if (device_pasid_enabled(idxd))
+               idxd_disable_system_pasid(idxd);
+       return rc;
+diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c
+index f1463fc58112..7b0181532f77 100644
+--- a/drivers/dma/idxd/irq.c
++++ b/drivers/dma/idxd/irq.c
+@@ -45,7 +45,7 @@ static void idxd_device_reinit(struct work_struct *work)
+               goto out;
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
++              struct idxd_wq *wq = idxd->wqs[i];
+               if (wq->state == IDXD_WQ_ENABLED) {
+                       rc = idxd_wq_enable(wq);
+@@ -130,7 +130,7 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause)
+               if (idxd->sw_err.valid && idxd->sw_err.wq_idx_valid) {
+                       int id = idxd->sw_err.wq_idx;
+-                      struct idxd_wq *wq = &idxd->wqs[id];
++                      struct idxd_wq *wq = idxd->wqs[id];
+                       if (wq->type == IDXD_WQT_USER)
+                               wake_up_interruptible(&wq->idxd_cdev.err_queue);
+@@ -138,7 +138,7 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause)
+                       int i;
+                       for (i = 0; i < idxd->max_wqs; i++) {
+-                              struct idxd_wq *wq = &idxd->wqs[i];
++                              struct idxd_wq *wq = idxd->wqs[i];
+                               if (wq->type == IDXD_WQT_USER)
+                                       wake_up_interruptible(&wq->idxd_cdev.err_queue);
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index 36193e555e36..409b3ce52f07 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -26,34 +26,11 @@ static struct device_type idxd_group_device_type = {
+       .release = idxd_conf_sub_device_release,
+ };
+-static struct device_type idxd_wq_device_type = {
+-      .name = "wq",
+-      .release = idxd_conf_sub_device_release,
+-};
+-
+ static struct device_type idxd_engine_device_type = {
+       .name = "engine",
+       .release = idxd_conf_sub_device_release,
+ };
+-static inline bool is_idxd_wq_dev(struct device *dev)
+-{
+-      return dev ? dev->type == &idxd_wq_device_type : false;
+-}
+-
+-static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq)
+-{
+-      if (wq->type == IDXD_WQT_KERNEL &&
+-          strcmp(wq->name, "dmaengine") == 0)
+-              return true;
+-      return false;
+-}
+-
+-static inline bool is_idxd_wq_cdev(struct idxd_wq *wq)
+-{
+-      return wq->type == IDXD_WQT_USER;
+-}
+-
+ static int idxd_config_bus_match(struct device *dev,
+                                struct device_driver *drv)
+ {
+@@ -297,7 +274,7 @@ static int idxd_config_bus_remove(struct device *dev)
+               dev_dbg(dev, "%s removing dev %s\n", __func__,
+                       dev_name(&idxd->conf_dev));
+               for (i = 0; i < idxd->max_wqs; i++) {
+-                      struct idxd_wq *wq = &idxd->wqs[i];
++                      struct idxd_wq *wq = idxd->wqs[i];
+                       if (wq->state == IDXD_WQ_DISABLED)
+                               continue;
+@@ -309,7 +286,7 @@ static int idxd_config_bus_remove(struct device *dev)
+               idxd_unregister_dma_device(idxd);
+               rc = idxd_device_disable(idxd);
+               for (i = 0; i < idxd->max_wqs; i++) {
+-                      struct idxd_wq *wq = &idxd->wqs[i];
++                      struct idxd_wq *wq = idxd->wqs[i];
+                       mutex_lock(&wq->wq_lock);
+                       idxd_wq_disable_cleanup(wq);
+@@ -678,7 +655,7 @@ static ssize_t group_work_queues_show(struct device *dev,
+       struct idxd_device *idxd = group->idxd;
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
++              struct idxd_wq *wq = idxd->wqs[i];
+               if (!wq->group)
+                       continue;
+@@ -935,7 +912,7 @@ static int total_claimed_wq_size(struct idxd_device *idxd)
+       int wq_size = 0;
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
++              struct idxd_wq *wq = idxd->wqs[i];
+               wq_size += wq->size;
+       }
+@@ -1331,6 +1308,20 @@ static const struct attribute_group *idxd_wq_attribute_groups[] = {
+       NULL,
+ };
++static void idxd_conf_wq_release(struct device *dev)
++{
++      struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
++
++      kfree(wq->wqcfg);
++      kfree(wq);
++}
++
++struct device_type idxd_wq_device_type = {
++      .name = "wq",
++      .release = idxd_conf_wq_release,
++      .groups = idxd_wq_attribute_groups,
++};
++
+ /* IDXD device attribs */
+ static ssize_t version_show(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+@@ -1461,7 +1452,7 @@ static ssize_t clients_show(struct device *dev,
+       spin_lock_irqsave(&idxd->dev_lock, flags);
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
++              struct idxd_wq *wq = idxd->wqs[i];
+               count += wq->client_count;
+       }
+@@ -1711,70 +1702,67 @@ cleanup:
+       return rc;
+ }
+-static int idxd_setup_wq_sysfs(struct idxd_device *idxd)
++static int idxd_register_wq_devices(struct idxd_device *idxd)
+ {
+-      struct device *dev = &idxd->pdev->dev;
+-      int i, rc;
++      int i, rc, j;
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
+-
+-              wq->conf_dev.parent = &idxd->conf_dev;
+-              dev_set_name(&wq->conf_dev, "wq%d.%d", idxd->id, wq->id);
+-              wq->conf_dev.bus = idxd_get_bus_type(idxd);
+-              wq->conf_dev.groups = idxd_wq_attribute_groups;
+-              wq->conf_dev.type = &idxd_wq_device_type;
+-              dev_dbg(dev, "WQ device register: %s\n",
+-                      dev_name(&wq->conf_dev));
+-              rc = device_register(&wq->conf_dev);
+-              if (rc < 0) {
+-                      put_device(&wq->conf_dev);
++              struct idxd_wq *wq = idxd->wqs[i];
++
++              rc = device_add(&wq->conf_dev);
++              if (rc < 0)
+                       goto cleanup;
+-              }
+       }
+       return 0;
+ cleanup:
+-      while (i--) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
++      j = i - 1;
++      for (; i < idxd->max_wqs; i++)
++              put_device(&idxd->wqs[i]->conf_dev);
+-              device_unregister(&wq->conf_dev);
+-      }
++      while (j--)
++              device_unregister(&idxd->wqs[j]->conf_dev);
+       return rc;
+ }
+ int idxd_register_devices(struct idxd_device *idxd)
+ {
+       struct device *dev = &idxd->pdev->dev;
+-      int rc;
++      int rc, i;
+       rc = device_add(&idxd->conf_dev);
+       if (rc < 0)
+               return rc;
+-      rc = idxd_setup_wq_sysfs(idxd);
++      rc = idxd_register_wq_devices(idxd);
+       if (rc < 0) {
+-              /* unregister conf dev */
+-              dev_dbg(dev, "Work Queue sysfs registering failed: %d\n", rc);
+-              return rc;
++              dev_dbg(dev, "WQ devices registering failed: %d\n", rc);
++              goto err_wq;
+       }
+       rc = idxd_setup_group_sysfs(idxd);
+       if (rc < 0) {
+               /* unregister conf dev */
+               dev_dbg(dev, "Group sysfs registering failed: %d\n", rc);
+-              return rc;
++              goto err;
+       }
+       rc = idxd_setup_engine_sysfs(idxd);
+       if (rc < 0) {
+               /* unregister conf dev */
+               dev_dbg(dev, "Engine sysfs registering failed: %d\n", rc);
+-              return rc;
++              goto err;
+       }
+       return 0;
++
++ err:
++      for (i = 0; i < idxd->max_wqs; i++)
++              device_unregister(&idxd->wqs[i]->conf_dev);
++ err_wq:
++      device_del(&idxd->conf_dev);
++      return rc;
+ }
+ void idxd_unregister_devices(struct idxd_device *idxd)
+@@ -1782,7 +1770,7 @@ void idxd_unregister_devices(struct idxd_device *idxd)
+       int i;
+       for (i = 0; i < idxd->max_wqs; i++) {
+-              struct idxd_wq *wq = &idxd->wqs[i];
++              struct idxd_wq *wq = idxd->wqs[i];
+               device_unregister(&wq->conf_dev);
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-removal-of-pcim-managed-mmio-mapping.patch b/queue-5.11/dmaengine-idxd-removal-of-pcim-managed-mmio-mapping.patch
new file mode 100644 (file)
index 0000000..46a86fb
--- /dev/null
@@ -0,0 +1,117 @@
+From cdb42852a3e3762cfe9112affd8b6624bb7b23f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:21 -0700
+Subject: dmaengine: idxd: removal of pcim managed mmio mapping
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit a39c7cd0438ee2f0b859ee1eb86cdc52217d2223 ]
+
+The devm managed lifetime is incompatible with 'struct device' objects that
+resides in idxd context. This is one of the series that clean up the idxd
+driver 'struct device' lifetime. Remove pcim_* management of the PCI device
+and the ioremap of MMIO BAR and replace with unmanaged versions. This is
+for consistency of removing all the pcim/devm based calls.
+
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Link: https://lore.kernel.org/r/161852984150.2203940.8043988289748519056.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/init.c | 33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index d54a5e5f82a2..ababd059da6f 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -378,32 +378,36 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       struct idxd_device *idxd;
+       int rc;
+-      rc = pcim_enable_device(pdev);
++      rc = pci_enable_device(pdev);
+       if (rc)
+               return rc;
+       dev_dbg(dev, "Alloc IDXD context\n");
+       idxd = idxd_alloc(pdev);
+-      if (!idxd)
+-              return -ENOMEM;
++      if (!idxd) {
++              rc = -ENOMEM;
++              goto err_idxd_alloc;
++      }
+       dev_dbg(dev, "Mapping BARs\n");
+-      idxd->reg_base = pcim_iomap(pdev, IDXD_MMIO_BAR, 0);
+-      if (!idxd->reg_base)
+-              return -ENOMEM;
++      idxd->reg_base = pci_iomap(pdev, IDXD_MMIO_BAR, 0);
++      if (!idxd->reg_base) {
++              rc = -ENOMEM;
++              goto err_iomap;
++      }
+       dev_dbg(dev, "Set DMA masks\n");
+       rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+       if (rc)
+               rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (rc)
+-              return rc;
++              goto err;
+       rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+       if (rc)
+               rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (rc)
+-              return rc;
++              goto err;
+       idxd_set_type(idxd);
+@@ -417,13 +421,13 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       rc = idxd_probe(idxd);
+       if (rc) {
+               dev_err(dev, "Intel(R) IDXD DMA Engine init failed\n");
+-              return -ENODEV;
++              goto err;
+       }
+       rc = idxd_setup_sysfs(idxd);
+       if (rc) {
+               dev_err(dev, "IDXD sysfs setup failed\n");
+-              return -ENODEV;
++              goto err;
+       }
+       idxd->state = IDXD_DEV_CONF_READY;
+@@ -432,6 +436,13 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+                idxd->hw.version);
+       return 0;
++
++ err:
++      pci_iounmap(pdev, idxd->reg_base);
++ err_iomap:
++ err_idxd_alloc:
++      pci_disable_device(pdev);
++      return rc;
+ }
+ static void idxd_flush_pending_llist(struct idxd_irq_entry *ie)
+@@ -487,6 +498,8 @@ static void idxd_shutdown(struct pci_dev *pdev)
+       idxd_msix_perm_clear(idxd);
+       pci_free_irq_vectors(pdev);
++      pci_iounmap(pdev, idxd->reg_base);
++      pci_disable_device(pdev);
+       destroy_workqueue(idxd->wq);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/dmaengine-idxd-use-ida-for-device-instance-enumerati.patch b/queue-5.11/dmaengine-idxd-use-ida-for-device-instance-enumerati.patch
new file mode 100644 (file)
index 0000000..db1b67b
--- /dev/null
@@ -0,0 +1,83 @@
+From 3b3ced55cdfa14e55d0b12605659405633bdbbca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 16:37:27 -0700
+Subject: dmaengine: idxd: use ida for device instance enumeration
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+[ Upstream commit f7f7739847bd68b3c3103fd1b50d943038bd14c7 ]
+
+The idr is only used for an device id, never to lookup context from that
+id. Switch to plain ida.
+
+Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/161852984730.2203940.15032482460902003819.stgit@djiang5-desk3.ch.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/init.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index d223242a34f4..6e97a9870ba8 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -30,8 +30,7 @@ MODULE_AUTHOR("Intel Corporation");
+ bool support_enqcmd;
+-static struct idr idxd_idrs[IDXD_TYPE_MAX];
+-static DEFINE_MUTEX(idxd_idr_lock);
++static struct ida idxd_idas[IDXD_TYPE_MAX];
+ static struct pci_device_id idxd_pci_tbl[] = {
+       /* DSA ver 1.0 platforms */
+@@ -342,12 +341,10 @@ static int idxd_probe(struct idxd_device *idxd)
+       dev_dbg(dev, "IDXD interrupt setup complete.\n");
+-      mutex_lock(&idxd_idr_lock);
+-      idxd->id = idr_alloc(&idxd_idrs[idxd->type], idxd, 0, 0, GFP_KERNEL);
+-      mutex_unlock(&idxd_idr_lock);
++      idxd->id = ida_alloc(&idxd_idas[idxd->type], GFP_KERNEL);
+       if (idxd->id < 0) {
+               rc = -ENOMEM;
+-              goto err_idr_fail;
++              goto err_ida_fail;
+       }
+       idxd->major = idxd_cdev_get_major(idxd);
+@@ -355,7 +352,7 @@ static int idxd_probe(struct idxd_device *idxd)
+       dev_dbg(dev, "IDXD device %d probed successfully\n", idxd->id);
+       return 0;
+- err_idr_fail:
++ err_ida_fail:
+       idxd_mask_error_interrupts(idxd);
+       idxd_mask_msix_vectors(idxd);
+  err_setup:
+@@ -512,9 +509,7 @@ static void idxd_remove(struct pci_dev *pdev)
+       idxd_shutdown(pdev);
+       if (device_pasid_enabled(idxd))
+               idxd_disable_system_pasid(idxd);
+-      mutex_lock(&idxd_idr_lock);
+-      idr_remove(&idxd_idrs[idxd->type], idxd->id);
+-      mutex_unlock(&idxd_idr_lock);
++      ida_free(&idxd_idas[idxd->type], idxd->id);
+ }
+ static struct pci_driver idxd_pci_driver = {
+@@ -544,7 +539,7 @@ static int __init idxd_init_module(void)
+               support_enqcmd = true;
+       for (i = 0; i < IDXD_TYPE_MAX; i++)
+-              idr_init(&idxd_idrs[i]);
++              ida_init(&idxd_idas[i]);
+       err = idxd_register_bus_type();
+       if (err < 0)
+-- 
+2.30.2
+
diff --git a/queue-5.11/drm-amd-display-add-handling-for-hdcp2-rx-id-list-va.patch b/queue-5.11/drm-amd-display-add-handling-for-hdcp2-rx-id-list-va.patch
new file mode 100644 (file)
index 0000000..271eb55
--- /dev/null
@@ -0,0 +1,44 @@
+From 4598edd0b82c109272f19db8ccd28c25d3b6ce6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jan 2021 18:05:50 -0500
+Subject: drm/amd/display: add handling for hdcp2 rx id list validation
+
+From: Dingchen (David) Zhang <dingchen.zhang@amd.com>
+
+[ Upstream commit 4ccf9446b2a3615615045346c97f8a1e2a16568a ]
+
+[why]
+the current implementation of hdcp2 rx id list validation does not
+have handler/checker for invalid message status, e.g. HMAC, the V
+parameter calculated from PSP not matching the V prime from Rx.
+
+[how]
+return a generic FAILURE for any message status not SUCCESS or
+REVOKED.
+
+Signed-off-by: Dingchen (David) Zhang <dingchen.zhang@amd.com>
+Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Acked-by: Aurabindo Pillai <aurabindo.pillai@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/modules/hdcp/hdcp_psp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+index 3a367a5968ae..972f2600f967 100644
+--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+@@ -789,6 +789,8 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp)
+                          TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {
+                       hdcp->connection.is_hdcp2_revoked = 1;
+                       status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED;
++              } else {
++                      status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE;
+               }
+       }
+       mutex_unlock(&psp->hdcp_context.mutex);
+-- 
+2.30.2
+
diff --git a/queue-5.11/drm-amd-display-fixed-divide-by-zero-kernel-crash-du.patch b/queue-5.11/drm-amd-display-fixed-divide-by-zero-kernel-crash-du.patch
new file mode 100644 (file)
index 0000000..f5b0a2f
--- /dev/null
@@ -0,0 +1,112 @@
+From ea8b2743cf72065573a7e41ea7428805869f4ee2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Dec 2020 19:14:48 -0500
+Subject: drm/amd/display: fixed divide by zero kernel crash during dsc
+ enablement
+
+From: Robin Singh <robin.singh@amd.com>
+
+[ Upstream commit 19cc1f3829567e7dca21c1389ea6407b8f5efab4 ]
+
+[why]
+During dsc enable, a divide by zero condition triggered the
+kernel crash.
+
+[how]
+An IGT test, which enable the DSC, was crashing at the time of
+restore the default dsc status, becaue of h_totals value
+becoming 0. So add a check before divide condition. If h_total
+is zero, gracefully ignore and set the default value.
+
+kernel panic log:
+
+       [  128.758827] divide error: 0000 [#1] PREEMPT SMP NOPTI
+       [  128.762714] CPU: 5 PID: 4562 Comm: amd_dp_dsc Tainted: G        W         5.4.19-android-x86_64 #1
+       [  128.769728] Hardware name: ADVANCED MICRO DEVICES, INC. Mauna/Mauna, BIOS WMN0B13N Nov 11 2020
+       [  128.777695] RIP: 0010:hubp2_vready_at_or_After_vsync+0x37/0x7a [amdgpu]
+       [  128.785707] Code: 80 02 00 00 48 89 f3 48 8b 7f 08 b ......
+       [  128.805696] RSP: 0018:ffffad8f82d43628 EFLAGS: 00010246
+       ......
+       [  128.857707] CR2: 00007106d8465000 CR3: 0000000426530000 CR4: 0000000000140ee0
+       [  128.865695] Call Trace:
+       [  128.869712] hubp3_setup+0x1f/0x7f [amdgpu]
+       [  128.873705] dcn20_update_dchubp_dpp+0xc8/0x54a [amdgpu]
+       [  128.877706] dcn20_program_front_end_for_ctx+0x31d/0x463 [amdgpu]
+       [  128.885706] dc_commit_state+0x3d2/0x658 [amdgpu]
+       [  128.889707] amdgpu_dm_atomic_commit_tail+0x4b3/0x1e7c [amdgpu]
+       [  128.897699] ? dm_read_reg_func+0x41/0xb5 [amdgpu]
+       [  128.901707] ? dm_read_reg_func+0x41/0xb5 [amdgpu]
+       [  128.905706] ? __is_insn_slot_addr+0x43/0x48
+       [  128.909706] ? fill_plane_buffer_attributes+0x29e/0x3dc [amdgpu]
+       [  128.917705] ? dm_plane_helper_prepare_fb+0x255/0x284 [amdgpu]
+       [  128.921700] ? usleep_range+0x7c/0x7c
+       [  128.925705] ? preempt_count_sub+0xf/0x18
+       [  128.929706] ? _raw_spin_unlock_irq+0x13/0x24
+       [  128.933732] ? __wait_for_common+0x11e/0x18f
+       [  128.937705] ? _raw_spin_unlock_irq+0x13/0x24
+       [  128.941706] ? __wait_for_common+0x11e/0x18f
+       [  128.945705] commit_tail+0x8b/0xd2 [drm_kms_helper]
+       [  128.949707] drm_atomic_helper_commit+0xd8/0xf5 [drm_kms_helper]
+       [  128.957706] amdgpu_dm_atomic_commit+0x337/0x360 [amdgpu]
+       [  128.961705] ? drm_atomic_check_only+0x543/0x68d [drm]
+       [  128.969705] ? drm_atomic_set_property+0x760/0x7af [drm]
+       [  128.973704] ? drm_mode_atomic_ioctl+0x6f3/0x85a [drm]
+       [  128.977705] drm_mode_atomic_ioctl+0x6f3/0x85a [drm]
+       [  128.985705] ? drm_atomic_set_property+0x7af/0x7af [drm]
+       [  128.989706] drm_ioctl_kernel+0x82/0xda [drm]
+       [  128.993706] drm_ioctl+0x225/0x319 [drm]
+       [  128.997707] ? drm_atomic_set_property+0x7af/0x7af [drm]
+       [  129.001706] ? preempt_count_sub+0xf/0x18
+       [  129.005713] amdgpu_drm_ioctl+0x4b/0x76 [amdgpu]
+       [  129.009705] vfs_ioctl+0x1d/0x2a
+       [  129.013705] do_vfs_ioctl+0x419/0x43d
+       [  129.017707] ksys_ioctl+0x52/0x71
+       [  129.021707] __x64_sys_ioctl+0x16/0x19
+       [  129.025706] do_syscall_64+0x78/0x85
+       [  129.029705] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Signed-off-by: Robin Singh <robin.singh@amd.com>
+Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
+Reviewed-by: Robin Singh <Robin.Singh@amd.com>
+Acked-by: Aurabindo Pillai <aurabindo.pillai@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/dcn20/dcn20_hubp.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+index bec7059f6d5d..a1318c31bcfa 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2012-17 Advanced Micro Devices, Inc.
++ * Copyright 2012-2021 Advanced Micro Devices, Inc.
+  *
+  * Permission is hereby granted, free of charge, to any person obtaining a
+  * copy of this software and associated documentation files (the "Software"),
+@@ -181,11 +181,14 @@ void hubp2_vready_at_or_After_vsync(struct hubp *hubp,
+       else
+               Set HUBP_VREADY_AT_OR_AFTER_VSYNC = 0
+       */
+-      if ((pipe_dest->vstartup_start - (pipe_dest->vready_offset+pipe_dest->vupdate_width
+-              + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) {
+-              value = 1;
+-      } else
+-              value = 0;
++      if (pipe_dest->htotal != 0) {
++              if ((pipe_dest->vstartup_start - (pipe_dest->vready_offset+pipe_dest->vupdate_width
++                      + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) {
++                      value = 1;
++              } else
++                      value = 0;
++      }
++
+       REG_UPDATE(DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, value);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/drm-amd-display-force-vsync-flip-when-reconfiguring-.patch b/queue-5.11/drm-amd-display-force-vsync-flip-when-reconfiguring-.patch
new file mode 100644 (file)
index 0000000..9769a02
--- /dev/null
@@ -0,0 +1,45 @@
+From 4098b2302972c7483e7f31189ab9b8db5b268337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 11:03:35 -0400
+Subject: drm/amd/display: Force vsync flip when reconfiguring MPCC
+
+From: Anthony Wang <anthony1.wang@amd.com>
+
+[ Upstream commit 56d63782af9bbd1271bff1422a6a013123eade4d ]
+
+[Why]
+Underflow observed when disabling PIP overlay in-game when
+vsync is disabled, due to OTC master lock not working with
+game pipe which is immediate flip.
+
+[How]
+When performing a full update, override flip_immediate value
+to false for all planes, so that flip occurs on vsync.
+
+Signed-off-by: Anthony Wang <anthony1.wang@amd.com>
+Acked-by: Bindu Ramamurthy <bindur12@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index ccac86347315..2d4f8780922e 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2528,6 +2528,10 @@ static void commit_planes_for_stream(struct dc *dc,
+                                               plane_state->triplebuffer_flips = true;
+                               }
+                       }
++                      if (update_type == UPDATE_TYPE_FULL) {
++                              /* force vsync flip when reconfiguring pipes to prevent underflow */
++                              plane_state->flip_immediate = false;
++                      }
+               }
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/drm-amdgpu-add-mem-sync-flag-for-ib-allocated-by-sa.patch b/queue-5.11/drm-amdgpu-add-mem-sync-flag-for-ib-allocated-by-sa.patch
new file mode 100644 (file)
index 0000000..a929df4
--- /dev/null
@@ -0,0 +1,40 @@
+From 432e37d08a1ca6ce7328fa0e5d23ef48a8c2c64e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Apr 2021 16:17:14 +0800
+Subject: drm/amdgpu: Add mem sync flag for IB allocated by SA
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jinzhou Su <Jinzhou.Su@amd.com>
+
+[ Upstream commit 5c88e3b86a88f14efa0a3ddd28641c6ff49fb9c4 ]
+
+The buffer of SA bo will be used by many cases. So it's better
+to invalidate the cache of indirect buffer allocated by SA before
+commit the IB.
+
+Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+index 024d0a563a65..f41764cee690 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+@@ -77,6 +77,8 @@ int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+               }
+               ib->ptr = amdgpu_sa_bo_cpu_addr(ib->sa_bo);
++              /* flush the cache before commit the IB */
++              ib->flags = AMDGPU_IB_FLAG_EMIT_MEM_SYNC;
+               if (!vm)
+                       ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
+-- 
+2.30.2
+
diff --git a/queue-5.11/drm-radeon-avoid-power-table-parsing-memory-leaks.patch b/queue-5.11/drm-radeon-avoid-power-table-parsing-memory-leaks.patch
new file mode 100644 (file)
index 0000000..b9e8585
--- /dev/null
@@ -0,0 +1,64 @@
+From 97248fa18ff55cf23e32fea792f575d4f1a3d640 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 May 2021 22:06:08 -0700
+Subject: drm/radeon: Avoid power table parsing memory leaks
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit c69f27137a38d24301a6b659454a91ad85dff4aa ]
+
+Avoid leaving a hanging pre-allocated clock_info if last mode is
+invalid, and avoid heap corruption if no valid modes are found.
+
+Bug: https://bugzilla.kernel.org/show_bug.cgi?id=211537
+Fixes: 6991b8f2a319 ("drm/radeon/kms: fix segfault in pm rework")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_atombios.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
+index 11eeabe13d22..70821d73f58f 100644
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -2119,11 +2119,14 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
+               return state_index;
+       /* last mode is usually default, array is low to high */
+       for (i = 0; i < num_modes; i++) {
+-              rdev->pm.power_state[state_index].clock_info =
+-                      kcalloc(1, sizeof(struct radeon_pm_clock_info),
+-                              GFP_KERNEL);
++              /* avoid memory leaks from invalid modes or unknown frev. */
++              if (!rdev->pm.power_state[state_index].clock_info) {
++                      rdev->pm.power_state[state_index].clock_info =
++                              kzalloc(sizeof(struct radeon_pm_clock_info),
++                                      GFP_KERNEL);
++              }
+               if (!rdev->pm.power_state[state_index].clock_info)
+-                      return state_index;
++                      goto out;
+               rdev->pm.power_state[state_index].num_clock_modes = 1;
+               rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
+               switch (frev) {
+@@ -2242,8 +2245,15 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
+                       break;
+               }
+       }
++out:
++      /* free any unused clock_info allocation. */
++      if (state_index && state_index < num_modes) {
++              kfree(rdev->pm.power_state[state_index].clock_info);
++              rdev->pm.power_state[state_index].clock_info = NULL;
++      }
++
+       /* last mode is usually default */
+-      if (rdev->pm.default_power_state_index == -1) {
++      if (state_index && rdev->pm.default_power_state_index == -1) {
+               rdev->pm.power_state[state_index - 1].type =
+                       POWER_STATE_TYPE_DEFAULT;
+               rdev->pm.default_power_state_index = state_index - 1;
+-- 
+2.30.2
+
diff --git a/queue-5.11/drm-radeon-fix-off-by-one-power_state-index-heap-ove.patch b/queue-5.11/drm-radeon-fix-off-by-one-power_state-index-heap-ove.patch
new file mode 100644 (file)
index 0000000..3100df7
--- /dev/null
@@ -0,0 +1,119 @@
+From 535756d1fea18429b213ca4e0d83104629a91630 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 May 2021 22:06:07 -0700
+Subject: drm/radeon: Fix off-by-one power_state index heap overwrite
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 5bbf219328849e83878bddb7c226d8d42e84affc ]
+
+An out of bounds write happens when setting the default power state.
+KASAN sees this as:
+
+[drm] radeon: 512M of GTT memory ready.
+[drm] GART: num cpu pages 131072, num gpu pages 131072
+==================================================================
+BUG: KASAN: slab-out-of-bounds in
+radeon_atombios_parse_power_table_1_3+0x1837/0x1998 [radeon]
+Write of size 4 at addr ffff88810178d858 by task systemd-udevd/157
+
+CPU: 0 PID: 157 Comm: systemd-udevd Not tainted 5.12.0-E620 #50
+Hardware name: eMachines        eMachines E620  /Nile       , BIOS V1.03 09/30/2008
+Call Trace:
+ dump_stack+0xa5/0xe6
+ print_address_description.constprop.0+0x18/0x239
+ kasan_report+0x170/0x1a8
+ radeon_atombios_parse_power_table_1_3+0x1837/0x1998 [radeon]
+ radeon_atombios_get_power_modes+0x144/0x1888 [radeon]
+ radeon_pm_init+0x1019/0x1904 [radeon]
+ rs690_init+0x76e/0x84a [radeon]
+ radeon_device_init+0x1c1a/0x21e5 [radeon]
+ radeon_driver_load_kms+0xf5/0x30b [radeon]
+ drm_dev_register+0x255/0x4a0 [drm]
+ radeon_pci_probe+0x246/0x2f6 [radeon]
+ pci_device_probe+0x1aa/0x294
+ really_probe+0x30e/0x850
+ driver_probe_device+0xe6/0x135
+ device_driver_attach+0xc1/0xf8
+ __driver_attach+0x13f/0x146
+ bus_for_each_dev+0xfa/0x146
+ bus_add_driver+0x2b3/0x447
+ driver_register+0x242/0x2c1
+ do_one_initcall+0x149/0x2fd
+ do_init_module+0x1ae/0x573
+ load_module+0x4dee/0x5cca
+ __do_sys_finit_module+0xf1/0x140
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Without KASAN, this will manifest later when the kernel attempts to
+allocate memory that was stomped, since it collides with the inline slab
+freelist pointer:
+
+invalid opcode: 0000 [#1] SMP NOPTI
+CPU: 0 PID: 781 Comm: openrc-run.sh Tainted: G        W 5.10.12-gentoo-E620 #2
+Hardware name: eMachines        eMachines E620  /Nile , BIOS V1.03       09/30/2008
+RIP: 0010:kfree+0x115/0x230
+Code: 89 c5 e8 75 ea ff ff 48 8b 00 0f ba e0 09 72 63 e8 1f f4 ff ff 41 89 c4 48 8b 45 00 0f ba e0 10 72 0a 48 8b 45 08 a8 01 75 02 <0f> 0b 44 89 e1 48 c7 c2 00 f0 ff ff be 06 00 00 00 48 d3 e2 48 c7
+RSP: 0018:ffffb42f40267e10 EFLAGS: 00010246
+RAX: ffffd61280ee8d88 RBX: 0000000000000004 RCX: 000000008010000d
+RDX: 4000000000000000 RSI: ffffffffba1360b0 RDI: ffffd61280ee8d80
+RBP: ffffd61280ee8d80 R08: ffffffffb91bebdf R09: 0000000000000000
+R10: ffff8fe2c1047ac8 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000100
+FS:  00007fe80eff6b68(0000) GS:ffff8fe339c00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007fe80eec7bc0 CR3: 0000000038012000 CR4: 00000000000006f0
+Call Trace:
+ __free_fdtable+0x16/0x1f
+ put_files_struct+0x81/0x9b
+ do_exit+0x433/0x94d
+ do_group_exit+0xa6/0xa6
+ __x64_sys_exit_group+0xf/0xf
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+RIP: 0033:0x7fe80ef64bea
+Code: Unable to access opcode bytes at RIP 0x7fe80ef64bc0.
+RSP: 002b:00007ffdb1c47528 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
+RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fe80ef64bea
+RDX: 00007fe80ef64f60 RSI: 0000000000000000 RDI: 0000000000000000
+RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000
+R10: 00007fe80ee2c620 R11: 0000000000000246 R12: 00007fe80eff41e0
+R13: 00000000ffffffff R14: 0000000000000024 R15: 00007fe80edf9cd0
+Modules linked in: radeon(+) ath5k(+) snd_hda_codec_realtek ...
+
+Use a valid power_state index when initializing the "flags" and "misc"
+and "misc2" fields.
+
+Bug: https://bugzilla.kernel.org/show_bug.cgi?id=211537
+Reported-by: Erhard F. <erhard_f@mailbox.org>
+Fixes: a48b9b4edb8b ("drm/radeon/kms/pm: add asic specific callbacks for getting power state (v2)")
+Fixes: 79daedc94281 ("drm/radeon/kms: minor pm cleanups")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_atombios.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
+index be96d9b64e43..11eeabe13d22 100644
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -2249,10 +2249,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
+               rdev->pm.default_power_state_index = state_index - 1;
+               rdev->pm.power_state[state_index - 1].default_clock_mode =
+                       &rdev->pm.power_state[state_index - 1].clock_info[0];
+-              rdev->pm.power_state[state_index].flags &=
++              rdev->pm.power_state[state_index - 1].flags &=
+                       ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
+-              rdev->pm.power_state[state_index].misc = 0;
+-              rdev->pm.power_state[state_index].misc2 = 0;
++              rdev->pm.power_state[state_index - 1].misc = 0;
++              rdev->pm.power_state[state_index - 1].misc2 = 0;
+       }
+       return state_index;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/ethernet-enic-fix-a-use-after-free-bug-in-enic_hard_.patch b/queue-5.11/ethernet-enic-fix-a-use-after-free-bug-in-enic_hard_.patch
new file mode 100644 (file)
index 0000000..e652935
--- /dev/null
@@ -0,0 +1,69 @@
+From 88151130abf542cb98395d56d33f551715186b87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 May 2021 04:58:18 -0700
+Subject: ethernet:enic: Fix a use after free bug in enic_hard_start_xmit
+
+From: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+
+[ Upstream commit 643001b47adc844ae33510c4bb93c236667008a3 ]
+
+In enic_hard_start_xmit, it calls enic_queue_wq_skb(). Inside
+enic_queue_wq_skb, if some error happens, the skb will be freed
+by dev_kfree_skb(skb). But the freed skb is still used in
+skb_tx_timestamp(skb).
+
+My patch makes enic_queue_wq_skb() return error and goto spin_unlock()
+incase of error. The solution is provided by Govind.
+See https://lkml.org/lkml/2021/4/30/961.
+
+Fixes: fb7516d42478e ("enic: add sw timestamp support")
+Signed-off-by: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+Acked-by: Govindarajulu Varadarajan <gvaradar@cisco.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cisco/enic/enic_main.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
+index fb269d587b74..548d8095c0a7 100644
+--- a/drivers/net/ethernet/cisco/enic/enic_main.c
++++ b/drivers/net/ethernet/cisco/enic/enic_main.c
+@@ -768,7 +768,7 @@ static inline int enic_queue_wq_skb_encap(struct enic *enic, struct vnic_wq *wq,
+       return err;
+ }
+-static inline void enic_queue_wq_skb(struct enic *enic,
++static inline int enic_queue_wq_skb(struct enic *enic,
+       struct vnic_wq *wq, struct sk_buff *skb)
+ {
+       unsigned int mss = skb_shinfo(skb)->gso_size;
+@@ -814,6 +814,7 @@ static inline void enic_queue_wq_skb(struct enic *enic,
+               wq->to_use = buf->next;
+               dev_kfree_skb(skb);
+       }
++      return err;
+ }
+ /* netif_tx_lock held, process context with BHs disabled, or BH */
+@@ -857,7 +858,8 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
+               return NETDEV_TX_BUSY;
+       }
+-      enic_queue_wq_skb(enic, wq, skb);
++      if (enic_queue_wq_skb(enic, wq, skb))
++              goto error;
+       if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)
+               netif_tx_stop_queue(txq);
+@@ -865,6 +867,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
+       if (!netdev_xmit_more() || netif_xmit_stopped(txq))
+               vnic_wq_doorbell(wq);
++error:
+       spin_unlock(&enic->wq_lock[txq_map]);
+       return NETDEV_TX_OK;
+-- 
+2.30.2
+
diff --git a/queue-5.11/ethtool-fix-missing-nlm_f_multi-flag-when-dumping.patch b/queue-5.11/ethtool-fix-missing-nlm_f_multi-flag-when-dumping.patch
new file mode 100644 (file)
index 0000000..d4177c4
--- /dev/null
@@ -0,0 +1,39 @@
+From 218f75a8152ebacad0baf4e5e9cbc372c2b1edea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 00:47:14 +0200
+Subject: ethtool: fix missing NLM_F_MULTI flag when dumping
+
+From: Fernando Fernandez Mancera <ffmancera@riseup.net>
+
+[ Upstream commit cf754ae331be7cc192b951756a1dd031e9ed978a ]
+
+When dumping the ethtool information from all the interfaces, the
+netlink reply should contain the NLM_F_MULTI flag. This flag allows
+userspace tools to identify that multiple messages are expected.
+
+Link: https://bugzilla.redhat.com/1953847
+Fixes: 365f9ae4ee36 ("ethtool: fix genlmsg_put() failure handling in ethnl_default_dumpit()")
+Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/netlink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
+index 50d3c8896f91..25a55086d2b6 100644
+--- a/net/ethtool/netlink.c
++++ b/net/ethtool/netlink.c
+@@ -384,7 +384,8 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
+       int ret;
+       ehdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+-                         &ethtool_genl_family, 0, ctx->ops->reply_cmd);
++                         &ethtool_genl_family, NLM_F_MULTI,
++                         ctx->ops->reply_cmd);
+       if (!ehdr)
+               return -EMSGSIZE;
+-- 
+2.30.2
+
diff --git a/queue-5.11/ethtool-ioctl-fix-out-of-bounds-warning-in-store_lin.patch b/queue-5.11/ethtool-ioctl-fix-out-of-bounds-warning-in-store_lin.patch
new file mode 100644 (file)
index 0000000..2165829
--- /dev/null
@@ -0,0 +1,50 @@
+From d6e232dadbc91ce07ebd002cf2629757879792a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 15:15:40 -0500
+Subject: ethtool: ioctl: Fix out-of-bounds warning in
+ store_link_ksettings_for_user()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit c1d9e34e11281a8ba1a1c54e4db554232a461488 ]
+
+Fix the following out-of-bounds warning:
+
+net/ethtool/ioctl.c:492:2: warning: 'memcpy' offset [49, 84] from the object at 'link_usettings' is out of the bounds of referenced subobject 'base' with type 'struct ethtool_link_settings' at offset 0 [-Warray-bounds]
+
+The problem is that the original code is trying to copy data into a
+some struct members adjacent to each other in a single call to
+memcpy(). This causes a legitimate compiler warning because memcpy()
+overruns the length of &link_usettings.base. Fix this by directly
+using &link_usettings and _from_ as destination and source addresses,
+instead.
+
+This helps with the ongoing efforts to globally enable -Warray-bounds
+and get us closer to being able to tighten the FORTIFY_SOURCE routines
+on memcpy().
+
+Link: https://github.com/KSPP/linux/issues/109
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 771688e1b0da..2603966da904 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -489,7 +489,7 @@ store_link_ksettings_for_user(void __user *to,
+ {
+       struct ethtool_link_usettings link_usettings;
+-      memcpy(&link_usettings.base, &from->base, sizeof(link_usettings));
++      memcpy(&link_usettings, from, sizeof(link_usettings));
+       bitmap_to_arr32(link_usettings.link_modes.supported,
+                       from->link_modes.supported,
+                       __ETHTOOL_LINK_MODE_MASK_NBITS);
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-a-hungtask-problem-in-atomic-write.patch b/queue-5.11/f2fs-fix-a-hungtask-problem-in-atomic-write.patch
new file mode 100644 (file)
index 0000000..feb3584
--- /dev/null
@@ -0,0 +1,114 @@
+From 7c255e81f9b983db254b83696344c16ea87a0c77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 17:34:14 +0800
+Subject: f2fs: Fix a hungtask problem in atomic write
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yi Zhuang <zhuangyi1@huawei.com>
+
+[ Upstream commit be1ee45d51384161681ecf21085a42d316ae25f7 ]
+
+In the cache writing process, if it is an atomic file, increase the page
+count of F2FS_WB_CP_DATA, otherwise increase the page count of
+F2FS_WB_DATA.
+
+When you step into the hook branch due to insufficient memory in
+f2fs_write_begin, f2fs_drop_inmem_pages_all will be called to traverse
+all atomic inodes and clear the FI_ATOMIC_FILE mark of all atomic files.
+
+In f2fs_drop_inmem_pages,first acquire the inmem_lock , revoke all the
+inmem_pages, and then clear the FI_ATOMIC_FILE mark. Before this mark is
+cleared, other threads may hold inmem_lock to add inmem_pages to the inode
+that has just been emptied inmem_pages, and increase the page count of
+F2FS_WB_CP_DATA.
+
+When the IO returns, it is found that the FI_ATOMIC_FILE flag is cleared
+by f2fs_drop_inmem_pages_all, and f2fs_is_atomic_file returns false,which
+causes the page count of F2FS_WB_DATA to be decremented. The page count of
+F2FS_WB_CP_DATA cannot be cleared. Finally, hungtask is triggered in
+f2fs_wait_on_all_pages because get_pages will never return zero.
+
+process A:                             process B:
+f2fs_drop_inmem_pages_all
+->f2fs_drop_inmem_pages of inode#1
+    ->mutex_lock(&fi->inmem_lock)
+    ->__revoke_inmem_pages of inode#1  f2fs_ioc_commit_atomic_write
+    ->mutex_unlock(&fi->inmem_lock)    ->f2fs_commit_inmem_pages of inode#1
+                                       ->mutex_lock(&fi->inmem_lock)
+                                       ->__f2fs_commit_inmem_pages
+                                           ->f2fs_do_write_data_page
+                                               ->f2fs_outplace_write_data
+                                                   ->do_write_page
+                                                       ->f2fs_submit_page_write
+                                                           ->inc_page_count(sbi, F2FS_WB_CP_DATA )
+                                       ->mutex_unlock(&fi->inmem_lock)
+    ->spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
+    ->clear_inode_flag(inode, FI_ATOMIC_FILE)
+    ->spin_unlock(&sbi->inode_lock[ATOMIC_FILE])
+                                       f2fs_write_end_io
+                                       ->dec_page_count(sbi, F2FS_WB_DATA );
+
+We can fix the problem by putting the action of clearing the FI_ATOMIC_FILE
+mark into the inmem_lock lock. This operation can ensure that no one will
+submit the inmem pages before the FI_ATOMIC_FILE mark is cleared, so that
+there will be no atomic writes waiting for writeback.
+
+Fixes: 57864ae5ce3a ("f2fs: limit # of inmemory pages")
+Signed-off-by: Yi Zhuang <zhuangyi1@huawei.com>
+Reviewed-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 73db79d958bd..af765d60351f 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -327,23 +327,27 @@ void f2fs_drop_inmem_pages(struct inode *inode)
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       struct f2fs_inode_info *fi = F2FS_I(inode);
+-      while (!list_empty(&fi->inmem_pages)) {
++      do {
+               mutex_lock(&fi->inmem_lock);
++              if (list_empty(&fi->inmem_pages)) {
++                      fi->i_gc_failures[GC_FAILURE_ATOMIC] = 0;
++
++                      spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
++                      if (!list_empty(&fi->inmem_ilist))
++                              list_del_init(&fi->inmem_ilist);
++                      if (f2fs_is_atomic_file(inode)) {
++                              clear_inode_flag(inode, FI_ATOMIC_FILE);
++                              sbi->atomic_files--;
++                      }
++                      spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
++
++                      mutex_unlock(&fi->inmem_lock);
++                      break;
++              }
+               __revoke_inmem_pages(inode, &fi->inmem_pages,
+                                               true, false, true);
+               mutex_unlock(&fi->inmem_lock);
+-      }
+-
+-      fi->i_gc_failures[GC_FAILURE_ATOMIC] = 0;
+-
+-      spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
+-      if (!list_empty(&fi->inmem_ilist))
+-              list_del_init(&fi->inmem_ilist);
+-      if (f2fs_is_atomic_file(inode)) {
+-              clear_inode_flag(inode, FI_ATOMIC_FILE);
+-              sbi->atomic_files--;
+-      }
+-      spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
++      } while (1);
+ }
+ void f2fs_drop_inmem_page(struct inode *inode, struct page *page)
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-a-redundant-call-to-f2fs_balance_fs-if-an-e.patch b/queue-5.11/f2fs-fix-a-redundant-call-to-f2fs_balance_fs-if-an-e.patch
new file mode 100644 (file)
index 0000000..ce1df2b
--- /dev/null
@@ -0,0 +1,45 @@
+From d6c3d403fee4489d5c0aead74a50a3d3cdeb37eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Mar 2021 09:21:18 +0000
+Subject: f2fs: fix a redundant call to f2fs_balance_fs if an error occurs
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit 28e18ee636ba28532dbe425540af06245a0bbecb ]
+
+The  uninitialized variable dn.node_changed does not get set when a
+call to f2fs_get_node_page fails.  This uninitialized value gets used
+in the call to f2fs_balance_fs() that may or not may not balances
+dirty node and dentry pages depending on the uninitialized state of
+the variable. Fix this by only calling f2fs_balance_fs if err is
+not set.
+
+Thanks to Jaegeuk Kim for suggesting an appropriate fix.
+
+Addresses-Coverity: ("Uninitialized scalar variable")
+Fixes: 2a3407607028 ("f2fs: call f2fs_balance_fs only when node was changed")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Reviewed-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/inline.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
+index 993caefcd2bb..92652ca7a7c8 100644
+--- a/fs/f2fs/inline.c
++++ b/fs/f2fs/inline.c
+@@ -219,7 +219,8 @@ out:
+       f2fs_put_page(page, 1);
+-      f2fs_balance_fs(sbi, dn.node_changed);
++      if (!err)
++              f2fs_balance_fs(sbi, dn.node_changed);
+       return err;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-panic-during-f2fs_resize_fs.patch b/queue-5.11/f2fs-fix-panic-during-f2fs_resize_fs.patch
new file mode 100644 (file)
index 0000000..e2f2e72
--- /dev/null
@@ -0,0 +1,75 @@
+From 97d3051765efeb87b1b818a166572b2cbee734f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Feb 2021 17:35:41 +0800
+Subject: f2fs: fix panic during f2fs_resize_fs()
+
+From: Chao Yu <yuchao0@huawei.com>
+
+[ Upstream commit 3ab0598e6d860ef49d029943ba80f627c15c15d6 ]
+
+f2fs_resize_fs() hangs in below callstack with testcase:
+- mkfs 16GB image & mount image
+- dd 8GB fileA
+- dd 8GB fileB
+- sync
+- rm fileA
+- sync
+- resize filesystem to 8GB
+
+kernel BUG at segment.c:2484!
+Call Trace:
+ allocate_segment_by_default+0x92/0xf0 [f2fs]
+ f2fs_allocate_data_block+0x44b/0x7e0 [f2fs]
+ do_write_page+0x5a/0x110 [f2fs]
+ f2fs_outplace_write_data+0x55/0x100 [f2fs]
+ f2fs_do_write_data_page+0x392/0x850 [f2fs]
+ move_data_page+0x233/0x320 [f2fs]
+ do_garbage_collect+0x14d9/0x1660 [f2fs]
+ free_segment_range+0x1f7/0x310 [f2fs]
+ f2fs_resize_fs+0x118/0x330 [f2fs]
+ __f2fs_ioctl+0x487/0x3680 [f2fs]
+ __x64_sys_ioctl+0x8e/0xd0
+ do_syscall_64+0x33/0x80
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+The root cause is we forgot to check that whether we have enough space
+in resized filesystem to store all valid blocks in before-resizing
+filesystem, then allocator will run out-of-space during block migration
+in free_segment_range().
+
+Fixes: b4b10061ef98 ("f2fs: refactor resize_fs to avoid meta updates in progress")
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 21ceec733066..b206797d202b 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1979,7 +1979,20 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count)
+       /* stop CP to protect MAIN_SEC in free_segment_range */
+       f2fs_lock_op(sbi);
++
++      spin_lock(&sbi->stat_lock);
++      if (shrunk_blocks + valid_user_blocks(sbi) +
++              sbi->current_reserved_blocks + sbi->unusable_block_count +
++              F2FS_OPTION(sbi).root_reserved_blocks > sbi->user_block_count)
++              err = -ENOSPC;
++      spin_unlock(&sbi->stat_lock);
++
++      if (err)
++              goto out_unlock;
++
+       err = free_segment_range(sbi, secs, true);
++
++out_unlock:
+       f2fs_unlock_op(sbi);
+       up_write(&sbi->gc_lock);
+       if (err)
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-to-align-to-section-for-fallocate-on-pinned.patch b/queue-5.11/f2fs-fix-to-align-to-section-for-fallocate-on-pinned.patch
new file mode 100644 (file)
index 0000000..3f7f8f4
--- /dev/null
@@ -0,0 +1,163 @@
+From 2724108c1f56643cd8f0ef4e104ccf6b0f599993 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Mar 2021 17:56:01 +0800
+Subject: f2fs: fix to align to section for fallocate() on pinned file
+
+From: Chao Yu <yuchao0@huawei.com>
+
+[ Upstream commit e1175f02291141bbd924fc578299305fcde35855 ]
+
+Now, fallocate() on a pinned file only allocates blocks which aligns
+to segment rather than section, so GC may try to migrate pinned file's
+block, and after several times of failure, pinned file's block could
+be migrated to other place, however user won't be aware of such
+condition, and then old obsolete block address may be readed/written
+incorrectly.
+
+To avoid such condition, let's try to allocate pinned file's blocks
+with section alignment.
+
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h    |  2 +-
+ fs/f2fs/file.c    | 19 +++++++++----------
+ fs/f2fs/segment.c | 34 ++++++++++++++++++++++++++--------
+ 3 files changed, 36 insertions(+), 19 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index a150633400ed..e72ed7baf17f 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3329,7 +3329,7 @@ void f2fs_get_new_segment(struct f2fs_sb_info *sbi,
+                       unsigned int *newseg, bool new_sec, int dir);
+ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+                                       unsigned int start, unsigned int end);
+-void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
++void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type);
+ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
+ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
+ bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 2af0f0e292d5..00e89f45ccde 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1643,27 +1643,26 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
+               return 0;
+       if (f2fs_is_pinned_file(inode)) {
+-              block_t len = (map.m_len >> sbi->log_blocks_per_seg) <<
+-                                      sbi->log_blocks_per_seg;
++              block_t sec_blks = BLKS_PER_SEC(sbi);
++              block_t sec_len = roundup(map.m_len, sec_blks);
+               block_t done = 0;
+-              if (map.m_len % sbi->blocks_per_seg)
+-                      len += sbi->blocks_per_seg;
+-
+-              map.m_len = sbi->blocks_per_seg;
++              map.m_len = sec_blks;
+ next_alloc:
+               if (has_not_enough_free_secs(sbi, 0,
+                       GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) {
+                       down_write(&sbi->gc_lock);
+                       err = f2fs_gc(sbi, true, false, false, NULL_SEGNO);
+-                      if (err && err != -ENODATA && err != -EAGAIN)
++                      if (err && err != -ENODATA && err != -EAGAIN) {
++                              map.m_len = done;
+                               goto out_err;
++                      }
+               }
+               down_write(&sbi->pin_sem);
+               f2fs_lock_op(sbi);
+-              f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);
++              f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED);
+               f2fs_unlock_op(sbi);
+               map.m_seg_type = CURSEG_COLD_DATA_PINNED;
+@@ -1672,9 +1671,9 @@ next_alloc:
+               up_write(&sbi->pin_sem);
+               done += map.m_len;
+-              len -= map.m_len;
++              sec_len -= map.m_len;
+               map.m_lblk += map.m_len;
+-              if (!err && len)
++              if (!err && sec_len)
+                       goto next_alloc;
+               map.m_len = done;
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index f447fcbff5bb..86bbba93c349 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2910,7 +2910,8 @@ unlock:
+       up_read(&SM_I(sbi)->curseg_lock);
+ }
+-static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
++static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
++                                                              bool new_sec)
+ {
+       struct curseg_info *curseg = CURSEG_I(sbi, type);
+       unsigned int old_segno;
+@@ -2918,10 +2919,22 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
+       if (!curseg->inited)
+               goto alloc;
+-      if (!curseg->next_blkoff &&
+-              !get_valid_blocks(sbi, curseg->segno, false) &&
+-              !get_ckpt_valid_blocks(sbi, curseg->segno))
+-              return;
++      if (curseg->next_blkoff ||
++              get_valid_blocks(sbi, curseg->segno, new_sec))
++              goto alloc;
++
++      if (new_sec) {
++              unsigned int segno = START_SEGNO(curseg->segno);
++              int i;
++
++              for (i = 0; i < sbi->segs_per_sec; i++, segno++) {
++                      if (get_ckpt_valid_blocks(sbi, segno))
++                              goto alloc;
++              }
++      } else {
++              if (!get_ckpt_valid_blocks(sbi, curseg->segno))
++                      return;
++      }
+ alloc:
+       old_segno = curseg->segno;
+@@ -2929,10 +2942,15 @@ alloc:
+       locate_dirty_segment(sbi, old_segno);
+ }
+-void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type)
++static void __allocate_new_section(struct f2fs_sb_info *sbi, int type)
++{
++      __allocate_new_segment(sbi, type, true);
++}
++
++void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type)
+ {
+       down_write(&SIT_I(sbi)->sentry_lock);
+-      __allocate_new_segment(sbi, type);
++      __allocate_new_section(sbi, type);
+       up_write(&SIT_I(sbi)->sentry_lock);
+ }
+@@ -2942,7 +2960,7 @@ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
+       down_write(&SIT_I(sbi)->sentry_lock);
+       for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
+-              __allocate_new_segment(sbi, i);
++              __allocate_new_segment(sbi, i, false);
+       up_write(&SIT_I(sbi)->sentry_lock);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-to-allow-migrating-fully-valid-segment.patch b/queue-5.11/f2fs-fix-to-allow-migrating-fully-valid-segment.patch
new file mode 100644 (file)
index 0000000..38b6ad6
--- /dev/null
@@ -0,0 +1,193 @@
+From fe6c6329343dd272045b6ca7715f588573c6e3f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Feb 2021 17:35:40 +0800
+Subject: f2fs: fix to allow migrating fully valid segment
+
+From: Chao Yu <yuchao0@huawei.com>
+
+[ Upstream commit 7dede88659df38f96128ab3922c50dde2d29c574 ]
+
+F2FS_IOC_FLUSH_DEVICE/F2FS_IOC_RESIZE_FS needs to migrate all blocks of
+target segment to other place, no matter the segment has partially or fully
+valid blocks.
+
+However, after commit 803e74be04b3 ("f2fs: stop GC when the victim becomes
+fully valid"), we may skip migration due to target segment is fully valid,
+result in failing the ioctl interface, fix this.
+
+Fixes: 803e74be04b3 ("f2fs: stop GC when the victim becomes fully valid")
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h    |  2 +-
+ fs/f2fs/file.c    |  9 +++++----
+ fs/f2fs/gc.c      | 21 ++++++++++++---------
+ fs/f2fs/segment.c |  2 +-
+ fs/f2fs/super.c   |  2 +-
+ 5 files changed, 20 insertions(+), 16 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 1578402c5844..a150633400ed 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3490,7 +3490,7 @@ void f2fs_destroy_post_read_wq(struct f2fs_sb_info *sbi);
+ int f2fs_start_gc_thread(struct f2fs_sb_info *sbi);
+ void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi);
+ block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode);
+-int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background,
++int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background, bool force,
+                       unsigned int segno);
+ void f2fs_build_gc_manager(struct f2fs_sb_info *sbi);
+ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index d5ebc67c7130..2af0f0e292d5 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1655,7 +1655,7 @@ next_alloc:
+               if (has_not_enough_free_secs(sbi, 0,
+                       GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) {
+                       down_write(&sbi->gc_lock);
+-                      err = f2fs_gc(sbi, true, false, NULL_SEGNO);
++                      err = f2fs_gc(sbi, true, false, false, NULL_SEGNO);
+                       if (err && err != -ENODATA && err != -EAGAIN)
+                               goto out_err;
+               }
+@@ -2486,7 +2486,7 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg)
+               down_write(&sbi->gc_lock);
+       }
+-      ret = f2fs_gc(sbi, sync, true, NULL_SEGNO);
++      ret = f2fs_gc(sbi, sync, true, false, NULL_SEGNO);
+ out:
+       mnt_drop_write_file(filp);
+       return ret;
+@@ -2522,7 +2522,8 @@ do_more:
+               down_write(&sbi->gc_lock);
+       }
+-      ret = f2fs_gc(sbi, range->sync, true, GET_SEGNO(sbi, range->start));
++      ret = f2fs_gc(sbi, range->sync, true, false,
++                              GET_SEGNO(sbi, range->start));
+       if (ret) {
+               if (ret == -EBUSY)
+                       ret = -EAGAIN;
+@@ -2975,7 +2976,7 @@ static int f2fs_ioc_flush_device(struct file *filp, unsigned long arg)
+               sm->last_victim[GC_CB] = end_segno + 1;
+               sm->last_victim[GC_GREEDY] = end_segno + 1;
+               sm->last_victim[ALLOC_NEXT] = end_segno + 1;
+-              ret = f2fs_gc(sbi, true, true, start_segno);
++              ret = f2fs_gc(sbi, true, true, true, start_segno);
+               if (ret == -EAGAIN)
+                       ret = 0;
+               else if (ret < 0)
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 3ef84e6ded41..21ceec733066 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -112,7 +112,7 @@ do_gc:
+               sync_mode = F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_SYNC;
+               /* if return value is not zero, no victim was selected */
+-              if (f2fs_gc(sbi, sync_mode, true, NULL_SEGNO))
++              if (f2fs_gc(sbi, sync_mode, true, false, NULL_SEGNO))
+                       wait_ms = gc_th->no_gc_sleep_time;
+               trace_f2fs_background_gc(sbi->sb, wait_ms,
+@@ -1356,7 +1356,8 @@ out:
+  * the victim data block is ignored.
+  */
+ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+-              struct gc_inode_list *gc_list, unsigned int segno, int gc_type)
++              struct gc_inode_list *gc_list, unsigned int segno, int gc_type,
++              bool force_migrate)
+ {
+       struct super_block *sb = sbi->sb;
+       struct f2fs_summary *entry;
+@@ -1385,8 +1386,8 @@ next_step:
+                * race condition along with SSR block allocation.
+                */
+               if ((gc_type == BG_GC && has_not_enough_free_secs(sbi, 0, 0)) ||
+-                              get_valid_blocks(sbi, segno, true) ==
+-                                                      BLKS_PER_SEC(sbi))
++                      (!force_migrate && get_valid_blocks(sbi, segno, true) ==
++                                                      BLKS_PER_SEC(sbi)))
+                       return submitted;
+               if (check_valid_map(sbi, segno, off) == 0)
+@@ -1521,7 +1522,8 @@ static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim,
+ static int do_garbage_collect(struct f2fs_sb_info *sbi,
+                               unsigned int start_segno,
+-                              struct gc_inode_list *gc_list, int gc_type)
++                              struct gc_inode_list *gc_list, int gc_type,
++                              bool force_migrate)
+ {
+       struct page *sum_page;
+       struct f2fs_summary_block *sum;
+@@ -1608,7 +1610,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
+                                                               gc_type);
+               else
+                       submitted += gc_data_segment(sbi, sum->entries, gc_list,
+-                                                      segno, gc_type);
++                                                      segno, gc_type,
++                                                      force_migrate);
+               stat_inc_seg_count(sbi, type, gc_type);
+               migrated++;
+@@ -1636,7 +1639,7 @@ skip:
+ }
+ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
+-                      bool background, unsigned int segno)
++                      bool background, bool force, unsigned int segno)
+ {
+       int gc_type = sync ? FG_GC : BG_GC;
+       int sec_freed = 0, seg_freed = 0, total_freed = 0;
+@@ -1698,7 +1701,7 @@ gc_more:
+       if (ret)
+               goto stop;
+-      seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type);
++      seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type, force);
+       if (gc_type == FG_GC &&
+               seg_freed == f2fs_usable_segs_in_sec(sbi, segno))
+               sec_freed++;
+@@ -1837,7 +1840,7 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
+                       .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
+               };
+-              do_garbage_collect(sbi, segno, &gc_list, FG_GC);
++              do_garbage_collect(sbi, segno, &gc_list, FG_GC, true);
+               put_gc_inode(&gc_list);
+               if (!gc_only && get_valid_blocks(sbi, segno, true)) {
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index deca74cb17df..f447fcbff5bb 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -507,7 +507,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
+        */
+       if (has_not_enough_free_secs(sbi, 0, 0)) {
+               down_write(&sbi->gc_lock);
+-              f2fs_gc(sbi, false, false, NULL_SEGNO);
++              f2fs_gc(sbi, false, false, false, NULL_SEGNO);
+       }
+ }
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 972736d71fa4..e89655285120 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1755,7 +1755,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi)
+       while (!f2fs_time_over(sbi, DISABLE_TIME)) {
+               down_write(&sbi->gc_lock);
+-              err = f2fs_gc(sbi, true, false, NULL_SEGNO);
++              err = f2fs_gc(sbi, true, false, false, NULL_SEGNO);
+               if (err == -ENODATA) {
+                       err = 0;
+                       break;
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-to-avoid-accessing-invalid-fio-in-f2fs_allo.patch b/queue-5.11/f2fs-fix-to-avoid-accessing-invalid-fio-in-f2fs_allo.patch
new file mode 100644 (file)
index 0000000..7743672
--- /dev/null
@@ -0,0 +1,44 @@
+From bfc3b6a9d72b550acce46f92c20901799e38ce7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Apr 2021 17:22:23 +0800
+Subject: f2fs: fix to avoid accessing invalid fio in
+ f2fs_allocate_data_block()
+
+From: Chao Yu <yuchao0@huawei.com>
+
+[ Upstream commit 25ae837e61dee712b4b1df36602ebfe724b2a0b6 ]
+
+Callers may pass fio parameter with NULL value to f2fs_allocate_data_block(),
+so we should make sure accessing fio's field after fio's validation check.
+
+Fixes: f608c38c59c6 ("f2fs: clean up parameter of f2fs_allocate_data_block()")
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index af765d60351f..b053e3c32e1f 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -3414,12 +3414,12 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+               f2fs_inode_chksum_set(sbi, page);
+       }
+-      if (F2FS_IO_ALIGNED(sbi))
+-              fio->retry = false;
+-
+       if (fio) {
+               struct f2fs_bio_info *io;
++              if (F2FS_IO_ALIGNED(sbi))
++                      fio->retry = false;
++
+               INIT_LIST_HEAD(&fio->list);
+               fio->in_list = true;
+               io = sbi->write_io[fio->type] + fio->temp;
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-to-avoid-touching-checkpointed-data-in-get_.patch b/queue-5.11/f2fs-fix-to-avoid-touching-checkpointed-data-in-get_.patch
new file mode 100644 (file)
index 0000000..965cb5d
--- /dev/null
@@ -0,0 +1,200 @@
+From fba030a1d1c58c4566620ce61823f37b6fb85160 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Mar 2021 11:18:28 +0800
+Subject: f2fs: fix to avoid touching checkpointed data in get_victim()
+
+From: Chao Yu <yuchao0@huawei.com>
+
+[ Upstream commit 61461fc921b756ae16e64243f72af2bfc2e620db ]
+
+In CP disabling mode, there are two issues when using LFS or SSR | AT_SSR
+mode to select victim:
+
+1. LFS is set to find source section during GC, the victim should have
+no checkpointed data, since after GC, section could not be set free for
+reuse.
+
+Previously, we only check valid chpt blocks in current segment rather
+than section, fix it.
+
+2. SSR | AT_SSR are set to find target segment for writes which can be
+fully filled by checkpointed and newly written blocks, we should never
+select such segment, otherwise it can cause panic or data corruption
+during allocation, potential case is described as below:
+
+ a) target segment has 'n' (n < 512) ckpt valid blocks
+ b) GC migrates 'n' valid blocks to other segment (segment is still
+    in dirty list)
+ c) GC migrates '512 - n' blocks to target segment (segment has 'n'
+    cp_vblocks and '512 - n' vblocks)
+ d) If GC selects target segment via {AT,}SSR allocator, however there
+    is no free space in targe segment.
+
+Fixes: 4354994f097d ("f2fs: checkpoint disabling")
+Fixes: 093749e296e2 ("f2fs: support age threshold based garbage collection")
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h    |  1 +
+ fs/f2fs/gc.c      | 28 ++++++++++++++++++++--------
+ fs/f2fs/segment.c | 36 +++++++++++++++++++++---------------
+ fs/f2fs/segment.h | 14 +++++++++++++-
+ 4 files changed, 55 insertions(+), 24 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index e72ed7baf17f..c9d54652a518 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3322,6 +3322,7 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi);
+ int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
+ void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
+ int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
++bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
+ void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
+ void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
+ void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index b206797d202b..f4e426352aad 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -392,10 +392,6 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
+               if (p->gc_mode == GC_AT &&
+                       get_valid_blocks(sbi, segno, true) == 0)
+                       return;
+-
+-              if (p->alloc_mode == AT_SSR &&
+-                      get_seg_entry(sbi, segno)->ckpt_valid_blocks == 0)
+-                      return;
+       }
+       for (i = 0; i < sbi->segs_per_sec; i++)
+@@ -728,11 +724,27 @@ retry:
+               if (sec_usage_check(sbi, secno))
+                       goto next;
++
+               /* Don't touch checkpointed data */
+-              if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
+-                                      get_ckpt_valid_blocks(sbi, segno) &&
+-                                      p.alloc_mode == LFS))
+-                      goto next;
++              if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
++                      if (p.alloc_mode == LFS) {
++                              /*
++                               * LFS is set to find source section during GC.
++                               * The victim should have no checkpointed data.
++                               */
++                              if (get_ckpt_valid_blocks(sbi, segno, true))
++                                      goto next;
++                      } else {
++                              /*
++                               * SSR | AT_SSR are set to find target segment
++                               * for writes which can be full by checkpointed
++                               * and newly written blocks.
++                               */
++                              if (!f2fs_segment_has_free_slot(sbi, segno))
++                                      goto next;
++                      }
++              }
++
+               if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
+                       goto next;
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 86bbba93c349..ab0a2d2de9a9 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -878,7 +878,7 @@ static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
+       mutex_lock(&dirty_i->seglist_lock);
+       valid_blocks = get_valid_blocks(sbi, segno, false);
+-      ckpt_valid_blocks = get_ckpt_valid_blocks(sbi, segno);
++      ckpt_valid_blocks = get_ckpt_valid_blocks(sbi, segno, false);
+       if (valid_blocks == 0 && (!is_sbi_flag_set(sbi, SBI_CP_DISABLED) ||
+               ckpt_valid_blocks == usable_blocks)) {
+@@ -963,7 +963,7 @@ static unsigned int get_free_segment(struct f2fs_sb_info *sbi)
+       for_each_set_bit(segno, dirty_i->dirty_segmap[DIRTY], MAIN_SEGS(sbi)) {
+               if (get_valid_blocks(sbi, segno, false))
+                       continue;
+-              if (get_ckpt_valid_blocks(sbi, segno))
++              if (get_ckpt_valid_blocks(sbi, segno, false))
+                       continue;
+               mutex_unlock(&dirty_i->seglist_lock);
+               return segno;
+@@ -2653,6 +2653,23 @@ static void __refresh_next_blkoff(struct f2fs_sb_info *sbi,
+               seg->next_blkoff++;
+ }
++bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno)
++{
++      struct seg_entry *se = get_seg_entry(sbi, segno);
++      int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long);
++      unsigned long *target_map = SIT_I(sbi)->tmp_map;
++      unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map;
++      unsigned long *cur_map = (unsigned long *)se->cur_valid_map;
++      int i, pos;
++
++      for (i = 0; i < entries; i++)
++              target_map[i] = ckpt_map[i] | cur_map[i];
++
++      pos = __find_rev_next_zero_bit(target_map, sbi->blocks_per_seg, 0);
++
++      return pos < sbi->blocks_per_seg;
++}
++
+ /*
+  * This function always allocates a used segment(from dirty seglist) by SSR
+  * manner, so it should recover the existing segment information of valid blocks
+@@ -2923,19 +2940,8 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
+               get_valid_blocks(sbi, curseg->segno, new_sec))
+               goto alloc;
+-      if (new_sec) {
+-              unsigned int segno = START_SEGNO(curseg->segno);
+-              int i;
+-
+-              for (i = 0; i < sbi->segs_per_sec; i++, segno++) {
+-                      if (get_ckpt_valid_blocks(sbi, segno))
+-                              goto alloc;
+-              }
+-      } else {
+-              if (!get_ckpt_valid_blocks(sbi, curseg->segno))
+-                      return;
+-      }
+-
++      if (!get_ckpt_valid_blocks(sbi, curseg->segno, new_sec))
++              return;
+ alloc:
+       old_segno = curseg->segno;
+       SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 229814b4f4a6..1bf33fc27b8f 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -361,8 +361,20 @@ static inline unsigned int get_valid_blocks(struct f2fs_sb_info *sbi,
+ }
+ static inline unsigned int get_ckpt_valid_blocks(struct f2fs_sb_info *sbi,
+-                              unsigned int segno)
++                              unsigned int segno, bool use_section)
+ {
++      if (use_section && __is_large_section(sbi)) {
++              unsigned int start_segno = START_SEGNO(segno);
++              unsigned int blocks = 0;
++              int i;
++
++              for (i = 0; i < sbi->segs_per_sec; i++, start_segno++) {
++                      struct seg_entry *se = get_seg_entry(sbi, start_segno);
++
++                      blocks += se->ckpt_valid_blocks;
++              }
++              return blocks;
++      }
+       return get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-to-cover-__allocate_new_section-with-curseg.patch b/queue-5.11/f2fs-fix-to-cover-__allocate_new_section-with-curseg.patch
new file mode 100644 (file)
index 0000000..ac5c05c
--- /dev/null
@@ -0,0 +1,50 @@
+From 688d3f077ee9fe5f7cd006b8f73a40167deb09ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 09:46:22 +0800
+Subject: f2fs: fix to cover __allocate_new_section() with curseg_lock
+
+From: Chao Yu <yuchao0@huawei.com>
+
+[ Upstream commit 823d13e12b6cbaef2f6e5d63c648643e7bc094dd ]
+
+In order to avoid race with f2fs_do_replace_block().
+
+Fixes: f5a53edcf01e ("f2fs: support aligned pinned file")
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index ab0a2d2de9a9..73db79d958bd 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2955,19 +2955,23 @@ static void __allocate_new_section(struct f2fs_sb_info *sbi, int type)
+ void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type)
+ {
++      down_read(&SM_I(sbi)->curseg_lock);
+       down_write(&SIT_I(sbi)->sentry_lock);
+       __allocate_new_section(sbi, type);
+       up_write(&SIT_I(sbi)->sentry_lock);
++      up_read(&SM_I(sbi)->curseg_lock);
+ }
+ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
+ {
+       int i;
++      down_read(&SM_I(sbi)->curseg_lock);
+       down_write(&SIT_I(sbi)->sentry_lock);
+       for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
+               __allocate_new_segment(sbi, i, false);
+       up_write(&SIT_I(sbi)->sentry_lock);
++      up_read(&SM_I(sbi)->curseg_lock);
+ }
+ static const struct segment_allocation default_salloc_ops = {
+-- 
+2.30.2
+
diff --git a/queue-5.11/f2fs-fix-to-update-last-i_size-if-fallocate-partiall.patch b/queue-5.11/f2fs-fix-to-update-last-i_size-if-fallocate-partiall.patch
new file mode 100644 (file)
index 0000000..7c6025a
--- /dev/null
@@ -0,0 +1,106 @@
+From 26cd8b877115d9022d133bf0963f96c5d13e0024 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Mar 2021 11:24:33 +0800
+Subject: f2fs: fix to update last i_size if fallocate partially succeeds
+
+From: Chao Yu <yuchao0@huawei.com>
+
+[ Upstream commit 88f2cfc5fa90326edb569b4a81bb38ed4dcd3108 ]
+
+In the case of expanding pinned file, map.m_lblk and map.m_len
+will update in each round of section allocation, so in error
+path, last i_size will be calculated with wrong m_lblk and m_len,
+fix it.
+
+Fixes: f5a53edcf01e ("f2fs: support aligned pinned file")
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 00e89f45ccde..42563d7c442d 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1616,9 +1616,10 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
+       struct f2fs_map_blocks map = { .m_next_pgofs = NULL,
+                       .m_next_extent = NULL, .m_seg_type = NO_CHECK_TYPE,
+                       .m_may_create = true };
+-      pgoff_t pg_end;
++      pgoff_t pg_start, pg_end;
+       loff_t new_size = i_size_read(inode);
+       loff_t off_end;
++      block_t expanded = 0;
+       int err;
+       err = inode_newsize_ok(inode, (len + offset));
+@@ -1631,11 +1632,12 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
+       f2fs_balance_fs(sbi, true);
++      pg_start = ((unsigned long long)offset) >> PAGE_SHIFT;
+       pg_end = ((unsigned long long)offset + len) >> PAGE_SHIFT;
+       off_end = (offset + len) & (PAGE_SIZE - 1);
+-      map.m_lblk = ((unsigned long long)offset) >> PAGE_SHIFT;
+-      map.m_len = pg_end - map.m_lblk;
++      map.m_lblk = pg_start;
++      map.m_len = pg_end - pg_start;
+       if (off_end)
+               map.m_len++;
+@@ -1645,7 +1647,6 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
+       if (f2fs_is_pinned_file(inode)) {
+               block_t sec_blks = BLKS_PER_SEC(sbi);
+               block_t sec_len = roundup(map.m_len, sec_blks);
+-              block_t done = 0;
+               map.m_len = sec_blks;
+ next_alloc:
+@@ -1653,10 +1654,8 @@ next_alloc:
+                       GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) {
+                       down_write(&sbi->gc_lock);
+                       err = f2fs_gc(sbi, true, false, false, NULL_SEGNO);
+-                      if (err && err != -ENODATA && err != -EAGAIN) {
+-                              map.m_len = done;
++                      if (err && err != -ENODATA && err != -EAGAIN)
+                               goto out_err;
+-                      }
+               }
+               down_write(&sbi->pin_sem);
+@@ -1670,24 +1669,25 @@ next_alloc:
+               up_write(&sbi->pin_sem);
+-              done += map.m_len;
++              expanded += map.m_len;
+               sec_len -= map.m_len;
+               map.m_lblk += map.m_len;
+               if (!err && sec_len)
+                       goto next_alloc;
+-              map.m_len = done;
++              map.m_len = expanded;
+       } else {
+               err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_AIO);
++              expanded = map.m_len;
+       }
+ out_err:
+       if (err) {
+               pgoff_t last_off;
+-              if (!map.m_len)
++              if (!expanded)
+                       return err;
+-              last_off = map.m_lblk + map.m_len - 1;
++              last_off = pg_start + expanded - 1;
+               /* update new size to the failed position */
+               new_size = (last_off == pg_end) ? offset + len :
+-- 
+2.30.2
+
diff --git a/queue-5.11/flow_dissector-fix-out-of-bounds-warning-in-__skb_fl.patch b/queue-5.11/flow_dissector-fix-out-of-bounds-warning-in-__skb_fl.patch
new file mode 100644 (file)
index 0000000..4111220
--- /dev/null
@@ -0,0 +1,53 @@
+From 272e9d3db62804713f2b70a75e963bad252bcd81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 14:31:51 -0500
+Subject: flow_dissector: Fix out-of-bounds warning in
+ __skb_flow_bpf_to_target()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 1e3d976dbb23b3fce544752b434bdc32ce64aabc ]
+
+Fix the following out-of-bounds warning:
+
+net/core/flow_dissector.c:835:3: warning: 'memcpy' offset [33, 48] from the object at 'flow_keys' is out of the bounds of referenced subobject 'ipv6_src' with type '__u32[4]' {aka 'unsigned int[4]'} at offset 16 [-Warray-bounds]
+
+The problem is that the original code is trying to copy data into a
+couple of struct members adjacent to each other in a single call to
+memcpy().  So, the compiler legitimately complains about it. As these
+are just a couple of members, fix this by copying each one of them in
+separate calls to memcpy().
+
+This helps with the ongoing efforts to globally enable -Warray-bounds
+and get us closer to being able to tighten the FORTIFY_SOURCE routines
+on memcpy().
+
+Link: https://github.com/KSPP/linux/issues/109
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/flow_dissector.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 180be5102efc..aa997de1d44c 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -822,8 +822,10 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
+               key_addrs = skb_flow_dissector_target(flow_dissector,
+                                                     FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+                                                     target_container);
+-              memcpy(&key_addrs->v6addrs, &flow_keys->ipv6_src,
+-                     sizeof(key_addrs->v6addrs));
++              memcpy(&key_addrs->v6addrs.src, &flow_keys->ipv6_src,
++                     sizeof(key_addrs->v6addrs.src));
++              memcpy(&key_addrs->v6addrs.dst, &flow_keys->ipv6_dst,
++                     sizeof(key_addrs->v6addrs.dst));
+               key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-9p-fix-v9fs_file_open-writeback-fid-error-check.patch b/queue-5.11/fs-9p-fix-v9fs_file_open-writeback-fid-error-check.patch
new file mode 100644 (file)
index 0000000..89afd93
--- /dev/null
@@ -0,0 +1,41 @@
+From ab8736e66d7e3223b8d1262f35d2d116ace7137c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Mar 2021 21:06:32 +0800
+Subject: fs: 9p: fix v9fs_file_open writeback fid error check
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f8b139e2f24112f4e21f1eb02c7fc7600fea4b8d ]
+
+IS_ERR() and PTR_ERR() use wrong pointer, it should be
+writeback_fid, fix it.
+
+Link: http://lkml.kernel.org/r/20210330130632.1054357-1-yangyingliang@huawei.com
+Fixes: 5bfe97d7382b ("9p: Fix writeback fid incorrectly being attached to dentry")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+[Dominique: adjusted commit summary]
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/9p/vfs_file.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
+index 649f04f112dc..59c32c9b799f 100644
+--- a/fs/9p/vfs_file.c
++++ b/fs/9p/vfs_file.c
+@@ -86,8 +86,8 @@ int v9fs_file_open(struct inode *inode, struct file *file)
+                * to work.
+                */
+               writeback_fid = v9fs_writeback_fid(file_dentry(file));
+-              if (IS_ERR(fid)) {
+-                      err = PTR_ERR(fid);
++              if (IS_ERR(writeback_fid)) {
++                      err = PTR_ERR(writeback_fid);
+                       mutex_unlock(&v9inode->v_mutex);
+                       goto out_error;
+               }
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-dlm-add-check-if-dlm-is-currently-running.patch b/queue-5.11/fs-dlm-add-check-if-dlm-is-currently-running.patch
new file mode 100644 (file)
index 0000000..792bb6f
--- /dev/null
@@ -0,0 +1,112 @@
+From d1d44d96829f2ea5737a47cf22cc0a067321d7b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:05:13 -0500
+Subject: fs: dlm: add check if dlm is currently running
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit 517461630d1c25ee4dfc1dee80973a64189d6ccf ]
+
+This patch adds checks for dlm config attributes regarding to protocol
+parameters as it makes only sense to change them when dlm is not running.
+It also adds a check for valid protocol specifiers and return invalid
+argument if they are not supported.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/config.c   | 34 ++++++++++++++++++++++++++++++++--
+ fs/dlm/lowcomms.c |  2 +-
+ fs/dlm/lowcomms.h |  3 +++
+ 3 files changed, 36 insertions(+), 3 deletions(-)
+
+diff --git a/fs/dlm/config.c b/fs/dlm/config.c
+index 8439610c266a..88d95d96e36c 100644
+--- a/fs/dlm/config.c
++++ b/fs/dlm/config.c
+@@ -164,6 +164,36 @@ static ssize_t cluster_##name##_show(struct config_item *item, char *buf)     \
+ }                                                                             \
+ CONFIGFS_ATTR(cluster_, name);
++static int dlm_check_protocol_and_dlm_running(unsigned int x)
++{
++      switch (x) {
++      case 0:
++              /* TCP */
++              break;
++      case 1:
++              /* SCTP */
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      if (dlm_allow_conn)
++              return -EBUSY;
++
++      return 0;
++}
++
++static int dlm_check_zero_and_dlm_running(unsigned int x)
++{
++      if (!x)
++              return -EINVAL;
++
++      if (dlm_allow_conn)
++              return -EBUSY;
++
++      return 0;
++}
++
+ static int dlm_check_zero(unsigned int x)
+ {
+       if (!x)
+@@ -180,7 +210,7 @@ static int dlm_check_buffer_size(unsigned int x)
+       return 0;
+ }
+-CLUSTER_ATTR(tcp_port, dlm_check_zero);
++CLUSTER_ATTR(tcp_port, dlm_check_zero_and_dlm_running);
+ CLUSTER_ATTR(buffer_size, dlm_check_buffer_size);
+ CLUSTER_ATTR(rsbtbl_size, dlm_check_zero);
+ CLUSTER_ATTR(recover_timer, dlm_check_zero);
+@@ -188,7 +218,7 @@ CLUSTER_ATTR(toss_secs, dlm_check_zero);
+ CLUSTER_ATTR(scan_secs, dlm_check_zero);
+ CLUSTER_ATTR(log_debug, NULL);
+ CLUSTER_ATTR(log_info, NULL);
+-CLUSTER_ATTR(protocol, NULL);
++CLUSTER_ATTR(protocol, dlm_check_protocol_and_dlm_running);
+ CLUSTER_ATTR(mark, NULL);
+ CLUSTER_ATTR(timewarn_cs, dlm_check_zero);
+ CLUSTER_ATTR(waitwarn_us, NULL);
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index a4fabcced0f2..0f7fa23cccf0 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -135,7 +135,7 @@ static DEFINE_SPINLOCK(dlm_node_addrs_spin);
+ static struct listen_connection listen_con;
+ static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT];
+ static int dlm_local_count;
+-static int dlm_allow_conn;
++int dlm_allow_conn;
+ /* Work queues */
+ static struct workqueue_struct *recv_workqueue;
+diff --git a/fs/dlm/lowcomms.h b/fs/dlm/lowcomms.h
+index 790d6703b17e..bcd4dbd1dc98 100644
+--- a/fs/dlm/lowcomms.h
++++ b/fs/dlm/lowcomms.h
+@@ -14,6 +14,9 @@
+ #define LOWCOMMS_MAX_TX_BUFFER_LEN    4096
++/* switch to check if dlm is running */
++extern int dlm_allow_conn;
++
+ int dlm_lowcomms_start(void);
+ void dlm_lowcomms_stop(void);
+ void dlm_lowcomms_exit(void);
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-dlm-add-errno-handling-to-check-callback.patch b/queue-5.11/fs-dlm-add-errno-handling-to-check-callback.patch
new file mode 100644 (file)
index 0000000..bca8e67
--- /dev/null
@@ -0,0 +1,74 @@
+From 67359a1c0a539be8801f76bdc7631a06af32721a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:05:12 -0500
+Subject: fs: dlm: add errno handling to check callback
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit 8aa9540b49e0833feba75dbf4f45babadd0ed215 ]
+
+This allows to return individual errno values for the config attribute
+check callback instead of returning invalid argument only.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/config.c | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/fs/dlm/config.c b/fs/dlm/config.c
+index 582bffa09a66..8439610c266a 100644
+--- a/fs/dlm/config.c
++++ b/fs/dlm/config.c
+@@ -125,7 +125,7 @@ static ssize_t cluster_cluster_name_store(struct config_item *item,
+ CONFIGFS_ATTR(cluster_, cluster_name);
+ static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field,
+-                         int *info_field, bool (*check_cb)(unsigned int x),
++                         int *info_field, int (*check_cb)(unsigned int x),
+                          const char *buf, size_t len)
+ {
+       unsigned int x;
+@@ -137,8 +137,11 @@ static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field,
+       if (rc)
+               return rc;
+-      if (check_cb && check_cb(x))
+-              return -EINVAL;
++      if (check_cb) {
++              rc = check_cb(x);
++              if (rc)
++                      return rc;
++      }
+       *cl_field = x;
+       *info_field = x;
+@@ -161,14 +164,20 @@ static ssize_t cluster_##name##_show(struct config_item *item, char *buf)     \
+ }                                                                             \
+ CONFIGFS_ATTR(cluster_, name);
+-static bool dlm_check_zero(unsigned int x)
++static int dlm_check_zero(unsigned int x)
+ {
+-      return !x;
++      if (!x)
++              return -EINVAL;
++
++      return 0;
+ }
+-static bool dlm_check_buffer_size(unsigned int x)
++static int dlm_check_buffer_size(unsigned int x)
+ {
+-      return (x < DEFAULT_BUFFER_SIZE);
++      if (x < DEFAULT_BUFFER_SIZE)
++              return -EINVAL;
++
++      return 0;
+ }
+ CLUSTER_ATTR(tcp_port, dlm_check_zero);
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-dlm-add-shutdown-hook.patch b/queue-5.11/fs-dlm-add-shutdown-hook.patch
new file mode 100644 (file)
index 0000000..ac2dca1
--- /dev/null
@@ -0,0 +1,197 @@
+From de348262519fc3311ed5f11a8a746b43e4405739 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:05:20 -0500
+Subject: fs: dlm: add shutdown hook
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit 9d232469bcd772dbedb9e75a165c681b920524ee ]
+
+This patch fixes issues which occurs when dlm lowcomms synchronize their
+workqueues but dlm application layer already released the lockspace. In
+such cases messages like:
+
+dlm: gfs2: release_lockspace final free
+dlm: invalid lockspace 3841231384 from 1 cmd 1 type 11
+
+are printed on the kernel log. This patch is solving this issue by
+introducing a new "shutdown" hook before calling "stop" hook when the
+lockspace is going to be released finally. This should pretend any
+dlm messages sitting in the workqueues during or after lockspace
+removal.
+
+It's necessary to call dlm_scand_stop() as I instrumented
+dlm_lowcomms_get_buffer() code to report a warning after it's called after
+dlm_midcomms_shutdown() functionality, see below:
+
+WARNING: CPU: 1 PID: 3794 at fs/dlm/midcomms.c:1003 dlm_midcomms_get_buffer+0x167/0x180
+Modules linked in: joydev iTCO_wdt intel_pmc_bxt iTCO_vendor_support drm_ttm_helper ttm pcspkr serio_raw i2c_i801 i2c_smbus drm_kms_helper virtio_scsi lpc_ich virtio_balloon virtio_console xhci_pci xhci_pci_renesas cec qemu_fw_cfg drm [last unloaded: qxl]
+CPU: 1 PID: 3794 Comm: dlm_scand Tainted: G        W         5.11.0+ #26
+Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.13.0-2.module+el8.3.0+7353+9de0a3cc 04/01/2014
+RIP: 0010:dlm_midcomms_get_buffer+0x167/0x180
+Code: 5d 41 5c 41 5d 41 5e 41 5f c3 0f 0b 45 31 e4 5b 5d 4c 89 e0 41 5c 41 5d 41 5e 41 5f c3 4c 89 e7 45 31 e4 e8 3b f1 ec ff eb 86 <0f> 0b 4c 89 e7 45 31 e4 e8 2c f1 ec ff e9 74 ff ff ff 0f 1f 80 00
+RSP: 0018:ffffa81503f8fe60 EFLAGS: 00010202
+RAX: 0000000000000008 RBX: ffff8f969827f200 RCX: 0000000000000001
+RDX: 0000000000000000 RSI: ffffffffad1e89a0 RDI: ffff8f96a5294160
+RBP: 0000000000000001 R08: 0000000000000000 R09: ffff8f96a250bc60
+R10: 00000000000045d3 R11: 0000000000000000 R12: ffff8f96a250bc60
+R13: ffffa81503f8fec8 R14: 0000000000000070 R15: 0000000000000c40
+FS:  0000000000000000(0000) GS:ffff8f96fbc00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000055aa3351c000 CR3: 000000010bf22000 CR4: 00000000000006e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ dlm_scan_rsbs+0x420/0x670
+ ? dlm_uevent+0x20/0x20
+ dlm_scand+0xbf/0xe0
+ kthread+0x13a/0x150
+ ? __kthread_bind_mask+0x60/0x60
+ ret_from_fork+0x22/0x30
+
+To synchronize all dlm scand messages we stop it right before shutdown
+hook.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lockspace.c | 20 +++++++++++---------
+ fs/dlm/lowcomms.c  | 42 +++++++++++++++++++++++-------------------
+ fs/dlm/lowcomms.h  |  1 +
+ 3 files changed, 35 insertions(+), 28 deletions(-)
+
+diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
+index 561dcad08ad6..c14cf2b7faab 100644
+--- a/fs/dlm/lockspace.c
++++ b/fs/dlm/lockspace.c
+@@ -404,12 +404,6 @@ static int threads_start(void)
+       return error;
+ }
+-static void threads_stop(void)
+-{
+-      dlm_scand_stop();
+-      dlm_lowcomms_stop();
+-}
+-
+ static int new_lockspace(const char *name, const char *cluster,
+                        uint32_t flags, int lvblen,
+                        const struct dlm_lockspace_ops *ops, void *ops_arg,
+@@ -702,8 +696,11 @@ int dlm_new_lockspace(const char *name, const char *cluster,
+               ls_count++;
+       if (error > 0)
+               error = 0;
+-      if (!ls_count)
+-              threads_stop();
++      if (!ls_count) {
++              dlm_scand_stop();
++              dlm_lowcomms_shutdown();
++              dlm_lowcomms_stop();
++      }
+  out:
+       mutex_unlock(&ls_lock);
+       return error;
+@@ -788,6 +785,11 @@ static int release_lockspace(struct dlm_ls *ls, int force)
+       dlm_recoverd_stop(ls);
++      if (ls_count == 1) {
++              dlm_scand_stop();
++              dlm_lowcomms_shutdown();
++      }
++
+       dlm_callback_stop(ls);
+       remove_lockspace(ls);
+@@ -880,7 +882,7 @@ int dlm_release_lockspace(void *lockspace, int force)
+       if (!error)
+               ls_count--;
+       if (!ls_count)
+-              threads_stop();
++              dlm_lowcomms_stop();
+       mutex_unlock(&ls_lock);
+       return error;
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 5fe571e44b1a..45c2fdaf34c4 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1608,6 +1608,29 @@ static int work_start(void)
+       return 0;
+ }
++static void shutdown_conn(struct connection *con)
++{
++      if (con->shutdown_action)
++              con->shutdown_action(con);
++}
++
++void dlm_lowcomms_shutdown(void)
++{
++      /* Set all the flags to prevent any
++       * socket activity.
++       */
++      dlm_allow_conn = 0;
++
++      if (recv_workqueue)
++              flush_workqueue(recv_workqueue);
++      if (send_workqueue)
++              flush_workqueue(send_workqueue);
++
++      dlm_close_sock(&listen_con.sock);
++
++      foreach_conn(shutdown_conn);
++}
++
+ static void _stop_conn(struct connection *con, bool and_other)
+ {
+       mutex_lock(&con->sock_mutex);
+@@ -1629,12 +1652,6 @@ static void stop_conn(struct connection *con)
+       _stop_conn(con, true);
+ }
+-static void shutdown_conn(struct connection *con)
+-{
+-      if (con->shutdown_action)
+-              con->shutdown_action(con);
+-}
+-
+ static void connection_release(struct rcu_head *rcu)
+ {
+       struct connection *con = container_of(rcu, struct connection, rcu);
+@@ -1691,19 +1708,6 @@ static void work_flush(void)
+ void dlm_lowcomms_stop(void)
+ {
+-      /* Set all the flags to prevent any
+-         socket activity.
+-      */
+-      dlm_allow_conn = 0;
+-
+-      if (recv_workqueue)
+-              flush_workqueue(recv_workqueue);
+-      if (send_workqueue)
+-              flush_workqueue(send_workqueue);
+-
+-      dlm_close_sock(&listen_con.sock);
+-
+-      foreach_conn(shutdown_conn);
+       work_flush();
+       foreach_conn(free_conn);
+       work_stop();
+diff --git a/fs/dlm/lowcomms.h b/fs/dlm/lowcomms.h
+index bcd4dbd1dc98..48bbc4e18761 100644
+--- a/fs/dlm/lowcomms.h
++++ b/fs/dlm/lowcomms.h
+@@ -18,6 +18,7 @@
+ extern int dlm_allow_conn;
+ int dlm_lowcomms_start(void);
++void dlm_lowcomms_shutdown(void);
+ void dlm_lowcomms_stop(void);
+ void dlm_lowcomms_exit(void);
+ int dlm_lowcomms_close(int nodeid);
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-dlm-change-allocation-limits.patch b/queue-5.11/fs-dlm-change-allocation-limits.patch
new file mode 100644 (file)
index 0000000..2ef643c
--- /dev/null
@@ -0,0 +1,45 @@
+From ffe50e039bc605bc9c4475f2d56a7da9c14316dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:05:14 -0500
+Subject: fs: dlm: change allocation limits
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit c45674fbdda138814ca21138475219c96fa5aa1f ]
+
+While running tcpkill I experienced invalid header length values while
+receiving to check that a node doesn't try to send a invalid dlm message
+we also check on applications minimum allocation limit. Also use
+DEFAULT_BUFFER_SIZE as maximum allocation limit. The define
+LOWCOMMS_MAX_TX_BUFFER_LEN is to calculate maximum buffer limits on
+application layer, future midcomms layer will subtract their needs from
+this define.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lowcomms.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 0f7fa23cccf0..f827d0b3962a 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1375,9 +1375,11 @@ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc)
+       struct writequeue_entry *e;
+       int offset = 0;
+-      if (len > LOWCOMMS_MAX_TX_BUFFER_LEN) {
+-              BUILD_BUG_ON(PAGE_SIZE < LOWCOMMS_MAX_TX_BUFFER_LEN);
++      if (len > DEFAULT_BUFFER_SIZE ||
++          len < sizeof(struct dlm_header)) {
++              BUILD_BUG_ON(PAGE_SIZE < DEFAULT_BUFFER_SIZE);
+               log_print("failed to allocate a buffer of size %d", len);
++              WARN_ON(1);
+               return NULL;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-dlm-check-on-minimum-msglen-size.patch b/queue-5.11/fs-dlm-check-on-minimum-msglen-size.patch
new file mode 100644 (file)
index 0000000..0514b53
--- /dev/null
@@ -0,0 +1,42 @@
+From 5a16761d4798c466d28f6ad5eff9fba72cdb9c0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:05:17 -0500
+Subject: fs: dlm: check on minimum msglen size
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit 710176e8363f269c6ecd73d203973b31ace119d3 ]
+
+This patch adds an additional check for minimum dlm header size which is
+an invalid dlm message and signals a broken stream. A msglen field cannot
+be less than the dlm header size because the field is inclusive header
+lengths.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/midcomms.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c
+index fde3a6afe4be..0bedfa8606a2 100644
+--- a/fs/dlm/midcomms.c
++++ b/fs/dlm/midcomms.c
+@@ -49,9 +49,10 @@ int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len)
+                * cannot deliver this message to upper layers
+                */
+               msglen = get_unaligned_le16(&hd->h_length);
+-              if (msglen > DEFAULT_BUFFER_SIZE) {
+-                      log_print("received invalid length header: %u, will abort message parsing",
+-                                msglen);
++              if (msglen > DEFAULT_BUFFER_SIZE ||
++                  msglen < sizeof(struct dlm_header)) {
++                      log_print("received invalid length header: %u from node %d, will abort message parsing",
++                                msglen, nodeid);
+                       return -EBADMSG;
+               }
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-dlm-fix-debugfs-dump.patch b/queue-5.11/fs-dlm-fix-debugfs-dump.patch
new file mode 100644 (file)
index 0000000..45af713
--- /dev/null
@@ -0,0 +1,40 @@
+From 90ba849633107407b979c3e7df7d141edd5efb04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:05:08 -0500
+Subject: fs: dlm: fix debugfs dump
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit 92c48950b43f4a767388cf87709d8687151a641f ]
+
+This patch fixes the following message which randomly pops up during
+glocktop call:
+
+seq_file: buggy .next function table_seq_next did not update position index
+
+The issue is that seq_read_iter() in fs/seq_file.c also needs an
+increment of the index in an non next record case as well which this
+patch fixes otherwise seq_read_iter() will print out the above message.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/debug_fs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c
+index d6bbccb0ed15..d5bd990bcab8 100644
+--- a/fs/dlm/debug_fs.c
++++ b/fs/dlm/debug_fs.c
+@@ -542,6 +542,7 @@ static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos)
+               if (bucket >= ls->ls_rsbtbl_size) {
+                       kfree(ri);
++                      ++*pos;
+                       return NULL;
+               }
+               tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-dlm-fix-mark-setting-deadlock.patch b/queue-5.11/fs-dlm-fix-mark-setting-deadlock.patch
new file mode 100644 (file)
index 0000000..3dcadc2
--- /dev/null
@@ -0,0 +1,287 @@
+From 5535555d666c4d4a72e25df88554ac250413417c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:05:09 -0500
+Subject: fs: dlm: fix mark setting deadlock
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit e125fbeb538e5e35a00c6c8150a5361bef34814c ]
+
+This patch fixes an deadlock issue when dlm_lowcomms_close() is called.
+When dlm_lowcomms_close() is called the clusters_root.subsys.su_mutex is
+held to remove configfs items. At this time we flushing (e.g.
+cancel_work_sync()) the workers of send and recv workqueue. Due the fact
+that we accessing configfs items (mark values), these workers will lock
+clusters_root.subsys.su_mutex as well which are already hold by
+dlm_lowcomms_close() and ends in a deadlock situation.
+
+[67170.703046] ======================================================
+[67170.703965] WARNING: possible circular locking dependency detected
+[67170.704758] 5.11.0-rc4+ #22 Tainted: G        W
+[67170.705433] ------------------------------------------------------
+[67170.706228] dlm_controld/280 is trying to acquire lock:
+[67170.706915] ffff9f2f475a6948 ((wq_completion)dlm_recv){+.+.}-{0:0}, at: __flush_work+0x203/0x4c0
+[67170.708026]
+               but task is already holding lock:
+[67170.708758] ffffffffa132f878 (&clusters_root.subsys.su_mutex){+.+.}-{3:3}, at: configfs_rmdir+0x29b/0x310
+[67170.710016]
+               which lock already depends on the new lock.
+
+The new behaviour adds the mark value to the node address configuration
+which doesn't require to held the clusters_root.subsys.su_mutex by
+accessing mark values in a separate datastructure. However the mark
+values can be set now only after a node address was set which is the
+case when the user is using dlm_controld.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/config.c   | 29 ++++++++++------------------
+ fs/dlm/config.h   |  1 -
+ fs/dlm/lowcomms.c | 49 ++++++++++++++++++++++++++++++++---------------
+ fs/dlm/lowcomms.h |  1 +
+ 4 files changed, 45 insertions(+), 35 deletions(-)
+
+diff --git a/fs/dlm/config.c b/fs/dlm/config.c
+index 49c5f9407098..582bffa09a66 100644
+--- a/fs/dlm/config.c
++++ b/fs/dlm/config.c
+@@ -688,6 +688,7 @@ static ssize_t comm_mark_show(struct config_item *item, char *buf)
+ static ssize_t comm_mark_store(struct config_item *item, const char *buf,
+                              size_t len)
+ {
++      struct dlm_comm *comm;
+       unsigned int mark;
+       int rc;
+@@ -695,7 +696,15 @@ static ssize_t comm_mark_store(struct config_item *item, const char *buf,
+       if (rc)
+               return rc;
+-      config_item_to_comm(item)->mark = mark;
++      if (mark == 0)
++              mark = dlm_config.ci_mark;
++
++      comm = config_item_to_comm(item);
++      rc = dlm_lowcomms_nodes_set_mark(comm->nodeid, mark);
++      if (rc)
++              return rc;
++
++      comm->mark = mark;
+       return len;
+ }
+@@ -870,24 +879,6 @@ int dlm_comm_seq(int nodeid, uint32_t *seq)
+       return 0;
+ }
+-void dlm_comm_mark(int nodeid, unsigned int *mark)
+-{
+-      struct dlm_comm *cm;
+-
+-      cm = get_comm(nodeid);
+-      if (!cm) {
+-              *mark = dlm_config.ci_mark;
+-              return;
+-      }
+-
+-      if (cm->mark)
+-              *mark = cm->mark;
+-      else
+-              *mark = dlm_config.ci_mark;
+-
+-      put_comm(cm);
+-}
+-
+ int dlm_our_nodeid(void)
+ {
+       return local_comm ? local_comm->nodeid : 0;
+diff --git a/fs/dlm/config.h b/fs/dlm/config.h
+index c210250a2581..d2cd4bd20313 100644
+--- a/fs/dlm/config.h
++++ b/fs/dlm/config.h
+@@ -48,7 +48,6 @@ void dlm_config_exit(void);
+ int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
+                    int *count_out);
+ int dlm_comm_seq(int nodeid, uint32_t *seq);
+-void dlm_comm_mark(int nodeid, unsigned int *mark);
+ int dlm_our_nodeid(void);
+ int dlm_our_addr(struct sockaddr_storage *addr, int num);
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index f7d2c52791f8..a4fabcced0f2 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -116,6 +116,7 @@ struct writequeue_entry {
+ struct dlm_node_addr {
+       struct list_head list;
+       int nodeid;
++      int mark;
+       int addr_count;
+       int curr_addr_index;
+       struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT];
+@@ -303,7 +304,8 @@ static int addr_compare(const struct sockaddr_storage *x,
+ }
+ static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out,
+-                        struct sockaddr *sa_out, bool try_new_addr)
++                        struct sockaddr *sa_out, bool try_new_addr,
++                        unsigned int *mark)
+ {
+       struct sockaddr_storage sas;
+       struct dlm_node_addr *na;
+@@ -331,6 +333,8 @@ static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out,
+       if (!na->addr_count)
+               return -ENOENT;
++      *mark = na->mark;
++
+       if (sas_out)
+               memcpy(sas_out, &sas, sizeof(struct sockaddr_storage));
+@@ -350,7 +354,8 @@ static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out,
+       return 0;
+ }
+-static int addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid)
++static int addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid,
++                        unsigned int *mark)
+ {
+       struct dlm_node_addr *na;
+       int rv = -EEXIST;
+@@ -364,6 +369,7 @@ static int addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid)
+               for (addr_i = 0; addr_i < na->addr_count; addr_i++) {
+                       if (addr_compare(na->addr[addr_i], addr)) {
+                               *nodeid = na->nodeid;
++                              *mark = na->mark;
+                               rv = 0;
+                               goto unlock;
+                       }
+@@ -412,6 +418,7 @@ int dlm_lowcomms_addr(int nodeid, struct sockaddr_storage *addr, int len)
+               new_node->nodeid = nodeid;
+               new_node->addr[0] = new_addr;
+               new_node->addr_count = 1;
++              new_node->mark = dlm_config.ci_mark;
+               list_add(&new_node->list, &dlm_node_addrs);
+               spin_unlock(&dlm_node_addrs_spin);
+               return 0;
+@@ -519,6 +526,23 @@ int dlm_lowcomms_connect_node(int nodeid)
+       return 0;
+ }
++int dlm_lowcomms_nodes_set_mark(int nodeid, unsigned int mark)
++{
++      struct dlm_node_addr *na;
++
++      spin_lock(&dlm_node_addrs_spin);
++      na = find_node_addr(nodeid);
++      if (!na) {
++              spin_unlock(&dlm_node_addrs_spin);
++              return -ENOENT;
++      }
++
++      na->mark = mark;
++      spin_unlock(&dlm_node_addrs_spin);
++
++      return 0;
++}
++
+ static void lowcomms_error_report(struct sock *sk)
+ {
+       struct connection *con;
+@@ -867,7 +891,7 @@ static int accept_from_sock(struct listen_connection *con)
+       /* Get the new node's NODEID */
+       make_sockaddr(&peeraddr, 0, &len);
+-      if (addr_to_nodeid(&peeraddr, &nodeid)) {
++      if (addr_to_nodeid(&peeraddr, &nodeid, &mark)) {
+               unsigned char *b=(unsigned char *)&peeraddr;
+               log_print("connect from non cluster node");
+               print_hex_dump_bytes("ss: ", DUMP_PREFIX_NONE, 
+@@ -876,9 +900,6 @@ static int accept_from_sock(struct listen_connection *con)
+               return -1;
+       }
+-      dlm_comm_mark(nodeid, &mark);
+-      sock_set_mark(newsock->sk, mark);
+-
+       log_print("got connection from %d", nodeid);
+       /*  Check to see if we already have a connection to this node. This
+@@ -892,6 +913,8 @@ static int accept_from_sock(struct listen_connection *con)
+               goto accept_err;
+       }
++      sock_set_mark(newsock->sk, mark);
++
+       mutex_lock(&newcon->sock_mutex);
+       if (newcon->sock) {
+               struct connection *othercon = newcon->othercon;
+@@ -1016,8 +1039,6 @@ static void sctp_connect_to_sock(struct connection *con)
+       struct socket *sock;
+       unsigned int mark;
+-      dlm_comm_mark(con->nodeid, &mark);
+-
+       mutex_lock(&con->sock_mutex);
+       /* Some odd races can cause double-connects, ignore them */
+@@ -1030,7 +1051,7 @@ static void sctp_connect_to_sock(struct connection *con)
+       }
+       memset(&daddr, 0, sizeof(daddr));
+-      result = nodeid_to_addr(con->nodeid, &daddr, NULL, true);
++      result = nodeid_to_addr(con->nodeid, &daddr, NULL, true, &mark);
+       if (result < 0) {
+               log_print("no address for nodeid %d", con->nodeid);
+               goto out;
+@@ -1105,13 +1126,11 @@ out:
+ static void tcp_connect_to_sock(struct connection *con)
+ {
+       struct sockaddr_storage saddr, src_addr;
++      unsigned int mark;
+       int addr_len;
+       struct socket *sock = NULL;
+-      unsigned int mark;
+       int result;
+-      dlm_comm_mark(con->nodeid, &mark);
+-
+       mutex_lock(&con->sock_mutex);
+       if (con->retries++ > MAX_CONNECT_RETRIES)
+               goto out;
+@@ -1126,15 +1145,15 @@ static void tcp_connect_to_sock(struct connection *con)
+       if (result < 0)
+               goto out_err;
+-      sock_set_mark(sock->sk, mark);
+-
+       memset(&saddr, 0, sizeof(saddr));
+-      result = nodeid_to_addr(con->nodeid, &saddr, NULL, false);
++      result = nodeid_to_addr(con->nodeid, &saddr, NULL, false, &mark);
+       if (result < 0) {
+               log_print("no address for nodeid %d", con->nodeid);
+               goto out_err;
+       }
++      sock_set_mark(sock->sk, mark);
++
+       add_sock(sock, con);
+       /* Bind to our cluster-known address connecting to avoid
+diff --git a/fs/dlm/lowcomms.h b/fs/dlm/lowcomms.h
+index 0918f9376489..790d6703b17e 100644
+--- a/fs/dlm/lowcomms.h
++++ b/fs/dlm/lowcomms.h
+@@ -21,6 +21,7 @@ int dlm_lowcomms_close(int nodeid);
+ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc);
+ void dlm_lowcomms_commit_buffer(void *mh);
+ int dlm_lowcomms_connect_node(int nodeid);
++int dlm_lowcomms_nodes_set_mark(int nodeid, unsigned int mark);
+ int dlm_lowcomms_addr(int nodeid, struct sockaddr_storage *addr, int len);
+ #endif                                /* __LOWCOMMS_DOT_H__ */
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-dlm-flush-swork-on-shutdown.patch b/queue-5.11/fs-dlm-flush-swork-on-shutdown.patch
new file mode 100644 (file)
index 0000000..c36d2dc
--- /dev/null
@@ -0,0 +1,42 @@
+From b47dcd023dc1fe294ab67662000024d4024290c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:05:19 -0500
+Subject: fs: dlm: flush swork on shutdown
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit eec054b5a7cfe6d1f1598a323b05771ee99857b5 ]
+
+This patch fixes the flushing of send work before shutdown. The function
+cancel_work_sync() is not the right workqueue functionality to use here
+as it would cancel the work if the work queues itself. In cases of
+EAGAIN in send() for dlm message we need to be sure that everything is
+send out before. The function flush_work() will ensure that every send
+work is be done inclusive in EAGAIN cases.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lowcomms.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index f827d0b3962a..5fe571e44b1a 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -709,10 +709,7 @@ static void shutdown_connection(struct connection *con)
+ {
+       int ret;
+-      if (cancel_work_sync(&con->swork)) {
+-              log_print("canceled swork for node %d", con->nodeid);
+-              clear_bit(CF_WRITE_PENDING, &con->flags);
+-      }
++      flush_work(&con->swork);
+       mutex_lock(&con->sock_mutex);
+       /* nothing to shutdown */
+-- 
+2.30.2
+
diff --git a/queue-5.11/fs-proc-generic.c-fix-incorrect-pde_is_permanent-che.patch b/queue-5.11/fs-proc-generic.c-fix-incorrect-pde_is_permanent-che.patch
new file mode 100644 (file)
index 0000000..8f33079
--- /dev/null
@@ -0,0 +1,43 @@
+From 7a052e67f631ec48c859ab695b73a5fcc8e76287 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 18:02:10 -0700
+Subject: fs/proc/generic.c: fix incorrect pde_is_permanent check
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit f4bf74d82915708208bc9d0c9bd3f769f56bfbec ]
+
+Currently the pde_is_permanent() check is being run on root multiple times
+rather than on the next proc directory entry.  This looks like a
+copy-paste error.  Fix this by replacing root with next.
+
+Addresses-Coverity: ("Copy-paste error")
+Link: https://lkml.kernel.org/r/20210318122633.14222-1-colin.king@canonical.com
+Fixes: d919b33dafb3 ("proc: faster open/read/close with "permanent" files")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
+Reviewed-by: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: Greg Kroah-Hartman <gregkh@google.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/proc/generic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/proc/generic.c b/fs/proc/generic.c
+index 6c0a05f55d6b..09e4d8a499a3 100644
+--- a/fs/proc/generic.c
++++ b/fs/proc/generic.c
+@@ -754,7 +754,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
+       while (1) {
+               next = pde_subdir_first(de);
+               if (next) {
+-                      if (unlikely(pde_is_permanent(root))) {
++                      if (unlikely(pde_is_permanent(next))) {
+                               write_unlock(&proc_subdir_lock);
+                               WARN(1, "removing permanent /proc entry '%s/%s'",
+                                       next->parent->name, next->name);
+-- 
+2.30.2
+
diff --git a/queue-5.11/fuse-invalidate-attrs-when-page-writeback-completes.patch b/queue-5.11/fuse-invalidate-attrs-when-page-writeback-completes.patch
new file mode 100644 (file)
index 0000000..fa2a08a
--- /dev/null
@@ -0,0 +1,80 @@
+From 96e275ea923e6e3d876298af659bc7e6f8374409 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 10:07:06 -0400
+Subject: fuse: invalidate attrs when page writeback completes
+
+From: Vivek Goyal <vgoyal@redhat.com>
+
+[ Upstream commit 3466958beb31a8e9d3a1441a34228ed088b84f3e ]
+
+In fuse when a direct/write-through write happens we invalidate attrs
+because that might have updated mtime/ctime on server and cached
+mtime/ctime will be stale.
+
+What about page writeback path.  Looks like we don't invalidate attrs
+there.  To be consistent, invalidate attrs in writeback path as well.  Only
+exception is when writeback_cache is enabled.  In that case we strust local
+mtime/ctime and there is no need to invalidate attrs.
+
+Recently users started experiencing failure of xfstests generic/080,
+geneirc/215 and generic/614 on virtiofs.  This happened only newer "stat"
+utility and not older one.  This patch fixes the issue.
+
+So what's the root cause of the issue.  Here is detailed explanation.
+
+generic/080 test does mmap write to a file, closes the file and then checks
+if mtime has been updated or not.  When file is closed, it leads to
+flushing of dirty pages (and that should update mtime/ctime on server).
+But we did not explicitly invalidate attrs after writeback finished.  Still
+generic/080 passed so far and reason being that we invalidated atime in
+fuse_readpages_end().  This is called in fuse_readahead() path and always
+seems to trigger before mmaped write.
+
+So after mmaped write when lstat() is called, it sees that atleast one of
+the fields being asked for is invalid (atime) and that results in
+generating GETATTR to server and mtime/ctime also get updated and test
+passes.
+
+But newer /usr/bin/stat seems to have moved to using statx() syscall now
+(instead of using lstat()).  And statx() allows it to query only ctime or
+mtime (and not rest of the basic stat fields).  That means when querying
+for mtime, fuse_update_get_attr() sees that mtime is not invalid (only
+atime is invalid).  So it does not generate a new GETATTR and fill stat
+with cached mtime/ctime.  And that means updated mtime is not seen by
+xfstest and tests start failing.
+
+Invalidating attrs after writeback completion should solve this problem in
+a generic manner.
+
+Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/file.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index eff4abaa87da..6e6d1e599869 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1776,8 +1776,17 @@ static void fuse_writepage_end(struct fuse_mount *fm, struct fuse_args *args,
+               container_of(args, typeof(*wpa), ia.ap.args);
+       struct inode *inode = wpa->inode;
+       struct fuse_inode *fi = get_fuse_inode(inode);
++      struct fuse_conn *fc = get_fuse_conn(inode);
+       mapping_set_error(inode->i_mapping, error);
++      /*
++       * A writeback finished and this might have updated mtime/ctime on
++       * server making local mtime/ctime stale.  Hence invalidate attrs.
++       * Do this only if writeback_cache is not enabled.  If writeback_cache
++       * is enabled, we trust local ctime/mtime.
++       */
++      if (!fc->writeback_cache)
++              fuse_invalidate_attr(inode);
+       spin_lock(&fi->lock);
+       rb_erase(&wpa->writepages_entry, &fi->writepages);
+       while (wpa->next) {
+-- 
+2.30.2
+
diff --git a/queue-5.11/i2c-add-i2c_aq_no_rep_start-adapter-quirk.patch b/queue-5.11/i2c-add-i2c_aq_no_rep_start-adapter-quirk.patch
new file mode 100644 (file)
index 0000000..170dc73
--- /dev/null
@@ -0,0 +1,39 @@
+From 539b2ab3669acfa994da0f43c56f77cf103d5a45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 19:19:20 +0000
+Subject: i2c: Add I2C_AQ_NO_REP_START adapter quirk
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bence Csókás <bence98@sch.bme.hu>
+
+[ Upstream commit aca01415e076aa96cca0f801f4420ee5c10c660d ]
+
+This quirk signifies that the adapter cannot do a repeated
+START, it always issues a STOP condition after transfers.
+
+Suggested-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Bence Csókás <bence98@sch.bme.hu>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/i2c.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+index 56622658b215..a670ae129f4b 100644
+--- a/include/linux/i2c.h
++++ b/include/linux/i2c.h
+@@ -687,6 +687,8 @@ struct i2c_adapter_quirks {
+ #define I2C_AQ_NO_ZERO_LEN_READ               BIT(5)
+ #define I2C_AQ_NO_ZERO_LEN_WRITE      BIT(6)
+ #define I2C_AQ_NO_ZERO_LEN            (I2C_AQ_NO_ZERO_LEN_READ | I2C_AQ_NO_ZERO_LEN_WRITE)
++/* adapter cannot do repeated START */
++#define I2C_AQ_NO_REP_START           BIT(7)
+ /*
+  * i2c_adapter is the structure used to identify a physical i2c bus along
+-- 
+2.30.2
+
diff --git a/queue-5.11/i2c-bail-out-early-when-rdwr-parameters-are-wrong.patch b/queue-5.11/i2c-bail-out-early-when-rdwr-parameters-are-wrong.patch
new file mode 100644 (file)
index 0000000..1cd3136
--- /dev/null
@@ -0,0 +1,46 @@
+From cfd744989aafdf22b17c7d3599d4b99dbb24db0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 12:57:34 +0100
+Subject: i2c: bail out early when RDWR parameters are wrong
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 71581562ee36032d2d574a9b23ad4af6d6a64cf7 ]
+
+The buggy parameters currently get caught later, but emit a noisy WARN.
+Userspace should not be able to trigger this, so add similar checks much
+earlier. Also avoids some unneeded code paths, of course. Apply kernel
+coding stlye to a comment while here.
+
+Reported-by: syzbot+ffb0b3ffa6cfbc7d7b3f@syzkaller.appspotmail.com
+Tested-by: syzbot+ffb0b3ffa6cfbc7d7b3f@syzkaller.appspotmail.com
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/i2c-dev.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
+index 6ceb11cc4be1..6ef38a8ee95c 100644
+--- a/drivers/i2c/i2c-dev.c
++++ b/drivers/i2c/i2c-dev.c
+@@ -440,8 +440,13 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+                                  sizeof(rdwr_arg)))
+                       return -EFAULT;
+-              /* Put an arbitrary limit on the number of messages that can
+-               * be sent at once */
++              if (!rdwr_arg.msgs || rdwr_arg.nmsgs == 0)
++                      return -EINVAL;
++
++              /*
++               * Put an arbitrary limit on the number of messages that can
++               * be sent at once
++               */
+               if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
+                       return -EINVAL;
+-- 
+2.30.2
+
diff --git a/queue-5.11/i2c-imx-fix-pm-reference-leak-in-i2c_imx_reg_slave.patch b/queue-5.11/i2c-imx-fix-pm-reference-leak-in-i2c_imx_reg_slave.patch
new file mode 100644 (file)
index 0000000..7b8728d
--- /dev/null
@@ -0,0 +1,39 @@
+From 526a53c634f2597f97dfeb43c78127ef030aa531 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 19:06:38 +0800
+Subject: i2c: imx: Fix PM reference leak in i2c_imx_reg_slave()
+
+From: Ye Weihua <yeweihua4@huawei.com>
+
+[ Upstream commit c4b1fcc310e655fa8414696c38a84d36c00684c8 ]
+
+pm_runtime_get_sync() will increment the PM reference count even on
+failure. Forgetting to put the reference again will result in a leak.
+
+Replace it with pm_runtime_resume_and_get() to keep the usage counter
+balanced.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Ye Weihua <yeweihua4@huawei.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-imx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
+index 8a694b2eebfd..d6b3fdf09b8f 100644
+--- a/drivers/i2c/busses/i2c-imx.c
++++ b/drivers/i2c/busses/i2c-imx.c
+@@ -763,7 +763,7 @@ static int i2c_imx_reg_slave(struct i2c_client *client)
+       i2c_imx->slave = client;
+       /* Resume */
+-      ret = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
++      ret = pm_runtime_resume_and_get(i2c_imx->adapter.dev.parent);
+       if (ret < 0) {
+               dev_err(&i2c_imx->adapter.dev, "failed to resume i2c controller");
+               return ret;
+-- 
+2.30.2
+
diff --git a/queue-5.11/i40e-fix-broken-xdp-support.patch b/queue-5.11/i40e-fix-broken-xdp-support.patch
new file mode 100644 (file)
index 0000000..b63cb4d
--- /dev/null
@@ -0,0 +1,77 @@
+From a443870a5d4ae10931ee7e7d2ff1298f16c7a637 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Apr 2021 13:14:01 +0200
+Subject: i40e: fix broken XDP support
+
+From: Magnus Karlsson <magnus.karlsson@intel.com>
+
+[ Upstream commit ae4393dfd472b194c90d75d2123105fb5ed59b04 ]
+
+Commit 12738ac4754e ("i40e: Fix sparse errors in i40e_txrx.c") broke
+XDP support in the i40e driver. That commit was fixing a sparse error
+in the code by introducing a new variable xdp_res instead of
+overloading this into the skb pointer. The problem is that the code
+later uses the skb pointer in if statements and these where not
+extended to also test for the new xdp_res variable. Fix this by adding
+the correct tests for xdp_res in these places.
+
+The skb pointer was used to store the result of the XDP program by
+overloading the results in the error pointer
+ERR_PTR(-result). Therefore, the allocation failure test that used to
+only test for !skb now need to be extended to also consider !xdp_res.
+
+i40e_cleanup_headers() had a check that based on the skb value being
+an error pointer, i.e. a result from the XDP program != XDP_PASS, and
+if so start to process a new packet immediately, instead of populating
+skb fields and sending the skb to the stack. This check is not needed
+anymore, since we have added an explicit test for xdp_res being set
+and if so just do continue to pick the next packet from the NIC.
+
+Fixes: 12738ac4754e ("i40e: Fix sparse errors in i40e_txrx.c")
+Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Tested-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Reported-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Signed-off-by: Magnus Karlsson <magnus.karlsson@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_txrx.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+index 92ce835bc79e..c779512f44f4 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+@@ -1821,10 +1821,6 @@ static bool i40e_cleanup_headers(struct i40e_ring *rx_ring, struct sk_buff *skb,
+                                union i40e_rx_desc *rx_desc)
+ {
+-      /* XDP packets use error pointer so abort at this point */
+-      if (IS_ERR(skb))
+-              return true;
+-
+       /* ERR_MASK will only have valid bits if EOP set, and
+        * what we are doing here is actually checking
+        * I40E_RX_DESC_ERROR_RXE_SHIFT, since it is the zeroth bit in
+@@ -2437,7 +2433,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
+               }
+               /* exit if we failed to retrieve a buffer */
+-              if (!skb) {
++              if (!xdp_res && !skb) {
+                       rx_ring->rx_stats.alloc_buff_failed++;
+                       rx_buffer->pagecnt_bias++;
+                       break;
+@@ -2449,7 +2445,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
+               if (i40e_is_non_eop(rx_ring, rx_desc, skb))
+                       continue;
+-              if (i40e_cleanup_headers(rx_ring, skb, rx_desc)) {
++              if (xdp_res || i40e_cleanup_headers(rx_ring, skb, rx_desc)) {
+                       skb = NULL;
+                       continue;
+               }
+-- 
+2.30.2
+
diff --git a/queue-5.11/i40e-fix-phy-type-identifiers-for-2.5g-and-5g-adapte.patch b/queue-5.11/i40e-fix-phy-type-identifiers-for-2.5g-and-5g-adapte.patch
new file mode 100644 (file)
index 0000000..ac39960
--- /dev/null
@@ -0,0 +1,96 @@
+From 297e4fb6fb432047315f7ec8d1e51e905100f29a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Apr 2021 14:43:07 +0000
+Subject: i40e: Fix PHY type identifiers for 2.5G and 5G adapters
+
+From: Mateusz Palczewski <mateusz.palczewski@intel.com>
+
+[ Upstream commit 15395ec4685bd45a43d1b54b8fd9846b87e2c621 ]
+
+Unlike other supported adapters, 2.5G and 5G use different
+PHY type identifiers for reading/writing PHY settings
+and for reading link status. This commit introduces
+separate PHY identifiers for these two operation types.
+
+Fixes: 2e45d3f4677a ("i40e: Add support for X710 B/P & SFP+ cards")
+Signed-off-by: Dawid Lukwinski <dawid.lukwinski@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Dave Switzer <david.switzer@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_adminq_cmd.h | 6 ++++--
+ drivers/net/ethernet/intel/i40e/i40e_common.c     | 4 ++--
+ drivers/net/ethernet/intel/i40e/i40e_ethtool.c    | 4 ++--
+ drivers/net/ethernet/intel/i40e/i40e_type.h       | 7 ++-----
+ 4 files changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+index 1e960c3c7ef0..e84054fb8213 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+@@ -1565,8 +1565,10 @@ enum i40e_aq_phy_type {
+       I40E_PHY_TYPE_25GBASE_LR                = 0x22,
+       I40E_PHY_TYPE_25GBASE_AOC               = 0x23,
+       I40E_PHY_TYPE_25GBASE_ACC               = 0x24,
+-      I40E_PHY_TYPE_2_5GBASE_T                = 0x30,
+-      I40E_PHY_TYPE_5GBASE_T                  = 0x31,
++      I40E_PHY_TYPE_2_5GBASE_T                = 0x26,
++      I40E_PHY_TYPE_5GBASE_T                  = 0x27,
++      I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS    = 0x30,
++      I40E_PHY_TYPE_5GBASE_T_LINK_STATUS      = 0x31,
+       I40E_PHY_TYPE_MAX,
+       I40E_PHY_TYPE_NOT_SUPPORTED_HIGH_TEMP   = 0xFD,
+       I40E_PHY_TYPE_EMPTY                     = 0xFE,
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
+index adc9e4fa4789..ba109073d605 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
+@@ -1154,8 +1154,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
+               break;
+       case I40E_PHY_TYPE_100BASE_TX:
+       case I40E_PHY_TYPE_1000BASE_T:
+-      case I40E_PHY_TYPE_2_5GBASE_T:
+-      case I40E_PHY_TYPE_5GBASE_T:
++      case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS:
++      case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS:
+       case I40E_PHY_TYPE_10GBASE_T:
+               media = I40E_MEDIA_TYPE_BASET;
+               break;
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index 13554706c180..5d48bc0c3f6c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -841,8 +841,8 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
+                                                            10000baseT_Full);
+               break;
+       case I40E_PHY_TYPE_10GBASE_T:
+-      case I40E_PHY_TYPE_5GBASE_T:
+-      case I40E_PHY_TYPE_2_5GBASE_T:
++      case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS:
++      case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS:
+       case I40E_PHY_TYPE_1000BASE_T:
+       case I40E_PHY_TYPE_100BASE_TX:
+               ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
+index c0bdc666f557..add67f7b73e8 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
+@@ -239,11 +239,8 @@ struct i40e_phy_info {
+ #define I40E_CAP_PHY_TYPE_25GBASE_ACC BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC + \
+                                            I40E_PHY_TYPE_OFFSET)
+ /* Offset for 2.5G/5G PHY Types value to bit number conversion */
+-#define I40E_PHY_TYPE_OFFSET2 (-10)
+-#define I40E_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T + \
+-                                           I40E_PHY_TYPE_OFFSET2)
+-#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T + \
+-                                           I40E_PHY_TYPE_OFFSET2)
++#define I40E_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T)
++#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T)
+ #define I40E_HW_CAP_MAX_GPIO                  30
+ /* Capabilities of a PF or a VF or the whole device */
+ struct i40e_hw_capabilities {
+-- 
+2.30.2
+
diff --git a/queue-5.11/i40e-fix-the-restart-auto-negotiation-after-fec-modi.patch b/queue-5.11/i40e-fix-the-restart-auto-negotiation-after-fec-modi.patch
new file mode 100644 (file)
index 0000000..50fcbb1
--- /dev/null
@@ -0,0 +1,41 @@
+From 4eca56bf3c49afa5e01ab982968e01a39ee3f16f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Apr 2021 14:19:40 +0000
+Subject: i40e: fix the restart auto-negotiation after FEC modified
+
+From: Jaroslaw Gawin <jaroslawx.gawin@intel.com>
+
+[ Upstream commit 61343e6da7810de81d6b826698946ae4f9070819 ]
+
+When FEC mode was changed the link didn't know it because
+the link was not reset and new parameters were not negotiated.
+Set a flag 'I40E_AQ_PHY_ENABLE_ATOMIC_LINK' in 'abilities'
+to restart the link and make it run with the new settings.
+
+Fixes: 1d96340196f1 ("i40e: Add support FEC configuration for Fortville 25G")
+Signed-off-by: Jaroslaw Gawin <jaroslawx.gawin@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Dave Switzer <david.switzer@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_ethtool.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index 31d48a85cfaf..13554706c180 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -1409,7 +1409,8 @@ static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg)
+               memset(&config, 0, sizeof(config));
+               config.phy_type = abilities.phy_type;
+-              config.abilities = abilities.abilities;
++              config.abilities = abilities.abilities |
++                                 I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+               config.phy_type_ext = abilities.phy_type_ext;
+               config.link_speed = abilities.link_speed;
+               config.eee_capability = abilities.eee_capability;
+-- 
+2.30.2
+
diff --git a/queue-5.11/i40e-fix-use-after-free-in-i40e_client_subtask.patch b/queue-5.11/i40e-fix-use-after-free-in-i40e_client_subtask.patch
new file mode 100644 (file)
index 0000000..07c89f6
--- /dev/null
@@ -0,0 +1,37 @@
+From 53bb28dcc71144cc2b11998e00bdabc0378b0670 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Apr 2021 22:41:18 +0800
+Subject: i40e: Fix use-after-free in i40e_client_subtask()
+
+From: Yunjian Wang <wangyunjian@huawei.com>
+
+[ Upstream commit 38318f23a7ef86a8b1862e5e8078c4de121960c3 ]
+
+Currently the call to i40e_client_del_instance frees the object
+pf->cinst, however pf->cinst->lan_info is being accessed after
+the free. Fix this by adding the missing return.
+
+Addresses-Coverity: ("Read from pointer after free")
+Fixes: 7b0b1a6d0ac9 ("i40e: Disable iWARP VSI PETCP_ENA flag on netdev down events")
+Signed-off-by: Yunjian Wang <wangyunjian@huawei.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_client.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c
+index a2dba32383f6..32f3facbed1a 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_client.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_client.c
+@@ -375,6 +375,7 @@ void i40e_client_subtask(struct i40e_pf *pf)
+                               clear_bit(__I40E_CLIENT_INSTANCE_OPENED,
+                                         &cdev->state);
+                               i40e_client_del_instance(pf);
++                              return;
+                       }
+               }
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/ia64-module-fix-symbolizer-crash-on-fdescr.patch b/queue-5.11/ia64-module-fix-symbolizer-crash-on-fdescr.patch
new file mode 100644 (file)
index 0000000..f9200d4
--- /dev/null
@@ -0,0 +1,120 @@
+From 851d507c26f344fd7283ee7fe7ce5626fe2026fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 22:53:48 -0700
+Subject: ia64: module: fix symbolizer crash on fdescr
+
+From: Sergei Trofimovich <slyfox@gentoo.org>
+
+[ Upstream commit 99e729bd40fb3272fa4b0140839d5e957b58588a ]
+
+Noticed failure as a crash on ia64 when tried to symbolize all backtraces
+collected by page_owner=on:
+
+    $ cat /sys/kernel/debug/page_owner
+    <oops>
+
+    CPU: 1 PID: 2074 Comm: cat Not tainted 5.12.0-rc4 #226
+    Hardware name: hp server rx3600, BIOS 04.03 04/08/2008
+    ip is at dereference_module_function_descriptor+0x41/0x100
+
+Crash happens at dereference_module_function_descriptor() due to
+use-after-free when dereferencing ".opd" section header.
+
+All section headers are already freed after module is laoded successfully.
+
+To keep symbolizer working the change stores ".opd" address and size after
+module is relocated to a new place and before section headers are
+discarded.
+
+To make similar errors less obscure module_finalize() now zeroes out all
+variables relevant to module loading only.
+
+Link: https://lkml.kernel.org/r/20210403074803.3309096-1-slyfox@gentoo.org
+Signed-off-by: Sergei Trofimovich <slyfox@gentoo.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>
+---
+ arch/ia64/include/asm/module.h |  6 +++++-
+ arch/ia64/kernel/module.c      | 29 +++++++++++++++++++++++++----
+ 2 files changed, 30 insertions(+), 5 deletions(-)
+
+diff --git a/arch/ia64/include/asm/module.h b/arch/ia64/include/asm/module.h
+index 5a29652e6def..7271b9c5fc76 100644
+--- a/arch/ia64/include/asm/module.h
++++ b/arch/ia64/include/asm/module.h
+@@ -14,16 +14,20 @@
+ struct elf64_shdr;                    /* forward declration */
+ struct mod_arch_specific {
++      /* Used only at module load time. */
+       struct elf64_shdr *core_plt;    /* core PLT section */
+       struct elf64_shdr *init_plt;    /* init PLT section */
+       struct elf64_shdr *got;         /* global offset table */
+       struct elf64_shdr *opd;         /* official procedure descriptors */
+       struct elf64_shdr *unwind;      /* unwind-table section */
+       unsigned long gp;               /* global-pointer for module */
++      unsigned int next_got_entry;    /* index of next available got entry */
++      /* Used at module run and cleanup time. */
+       void *core_unw_table;           /* core unwind-table cookie returned by unwinder */
+       void *init_unw_table;           /* init unwind-table cookie returned by unwinder */
+-      unsigned int next_got_entry;    /* index of next available got entry */
++      void *opd_addr;                 /* symbolize uses .opd to get to actual function */
++      unsigned long opd_size;
+ };
+ #define ARCH_SHF_SMALL        SHF_IA_64_SHORT
+diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
+index 00a496cb346f..2cba53c1da82 100644
+--- a/arch/ia64/kernel/module.c
++++ b/arch/ia64/kernel/module.c
+@@ -905,9 +905,31 @@ register_unwind_table (struct module *mod)
+ int
+ module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod)
+ {
++      struct mod_arch_specific *mas = &mod->arch;
++
+       DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
+-      if (mod->arch.unwind)
++      if (mas->unwind)
+               register_unwind_table(mod);
++
++      /*
++       * ".opd" was already relocated to the final destination. Store
++       * it's address for use in symbolizer.
++       */
++      mas->opd_addr = (void *)mas->opd->sh_addr;
++      mas->opd_size = mas->opd->sh_size;
++
++      /*
++       * Module relocation was already done at this point. Section
++       * headers are about to be deleted. Wipe out load-time context.
++       */
++      mas->core_plt = NULL;
++      mas->init_plt = NULL;
++      mas->got = NULL;
++      mas->opd = NULL;
++      mas->unwind = NULL;
++      mas->gp = 0;
++      mas->next_got_entry = 0;
++
+       return 0;
+ }
+@@ -926,10 +948,9 @@ module_arch_cleanup (struct module *mod)
+ void *dereference_module_function_descriptor(struct module *mod, void *ptr)
+ {
+-      Elf64_Shdr *opd = mod->arch.opd;
++      struct mod_arch_specific *mas = &mod->arch;
+-      if (ptr < (void *)opd->sh_addr ||
+-                      ptr >= (void *)(opd->sh_addr + opd->sh_size))
++      if (ptr < mas->opd_addr || ptr >= mas->opd_addr + mas->opd_size)
+               return ptr;
+       return dereference_function_descriptor(ptr);
+-- 
+2.30.2
+
diff --git a/queue-5.11/iavf-remove-duplicate-free-resources-calls.patch b/queue-5.11/iavf-remove-duplicate-free-resources-calls.patch
new file mode 100644 (file)
index 0000000..c25e230
--- /dev/null
@@ -0,0 +1,36 @@
+From d1d7be2a4aa948f92e9bed7a0618ea562fd7b45f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Mar 2021 15:41:42 +0100
+Subject: iavf: remove duplicate free resources calls
+
+From: Stefan Assmann <sassmann@kpanic.de>
+
+[ Upstream commit 1a0e880b028f97478dc689e2900b312741d0d772 ]
+
+Both iavf_free_all_tx_resources() and iavf_free_all_rx_resources() have
+already been called in the very same function.
+Remove the duplicate calls.
+
+Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index dc5b3c06d1e0..ebd08543791b 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -3899,8 +3899,6 @@ static void iavf_remove(struct pci_dev *pdev)
+       iounmap(hw->hw_addr);
+       pci_release_regions(pdev);
+-      iavf_free_all_tx_resources(adapter);
+-      iavf_free_all_rx_resources(adapter);
+       iavf_free_queues(adapter);
+       kfree(adapter->vf_res);
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+-- 
+2.30.2
+
diff --git a/queue-5.11/ib-hfi1-correct-oversized-ring-allocation.patch b/queue-5.11/ib-hfi1-correct-oversized-ring-allocation.patch
new file mode 100644 (file)
index 0000000..f329e8e
--- /dev/null
@@ -0,0 +1,96 @@
+From 5a09495d4601242f13cf9a9d278b65debc846fe1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 09:54:09 -0400
+Subject: IB/hfi1: Correct oversized ring allocation
+
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+
+[ Upstream commit b536d4b2a279733f440c911dc831764690b90050 ]
+
+The completion ring for tx is using the wrong size to size the ring,
+oversizing the ring by two orders of magniture.
+
+Correct the allocation size and use kcalloc_node() to allocate the ring.
+Fix mistaken GFP defines in similar allocations.
+
+Link: https://lore.kernel.org/r/1617026056-50483-4-git-send-email-dennis.dalessandro@cornelisnetworks.com
+Reviewed-by: Kaike Wan <kaike.wan@intel.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/ipoib.h    |  3 ++-
+ drivers/infiniband/hw/hfi1/ipoib_tx.c | 14 +++++++-------
+ 2 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/ipoib.h b/drivers/infiniband/hw/hfi1/ipoib.h
+index f650cac9d424..d30c23b6527a 100644
+--- a/drivers/infiniband/hw/hfi1/ipoib.h
++++ b/drivers/infiniband/hw/hfi1/ipoib.h
+@@ -52,8 +52,9 @@ union hfi1_ipoib_flow {
+  * @producer_lock: producer sync lock
+  * @consumer_lock: consumer sync lock
+  */
++struct ipoib_txreq;
+ struct hfi1_ipoib_circ_buf {
+-      void **items;
++      struct ipoib_txreq **items;
+       unsigned long head;
+       unsigned long tail;
+       unsigned long max_items;
+diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+index edd4eeac8dd1..cdc26ee3cf52 100644
+--- a/drivers/infiniband/hw/hfi1/ipoib_tx.c
++++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+@@ -702,14 +702,14 @@ int hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv)
+       priv->tx_napis = kcalloc_node(dev->num_tx_queues,
+                                     sizeof(struct napi_struct),
+-                                    GFP_ATOMIC,
++                                    GFP_KERNEL,
+                                     priv->dd->node);
+       if (!priv->tx_napis)
+               goto free_txreq_cache;
+       priv->txqs = kcalloc_node(dev->num_tx_queues,
+                                 sizeof(struct hfi1_ipoib_txq),
+-                                GFP_ATOMIC,
++                                GFP_KERNEL,
+                                 priv->dd->node);
+       if (!priv->txqs)
+               goto free_tx_napis;
+@@ -741,9 +741,9 @@ int hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv)
+                                            priv->dd->node);
+               txq->tx_ring.items =
+-                      vzalloc_node(array_size(tx_ring_size,
+-                                              sizeof(struct ipoib_txreq)),
+-                                   priv->dd->node);
++                      kcalloc_node(tx_ring_size,
++                                   sizeof(struct ipoib_txreq *),
++                                   GFP_KERNEL, priv->dd->node);
+               if (!txq->tx_ring.items)
+                       goto free_txqs;
+@@ -764,7 +764,7 @@ free_txqs:
+               struct hfi1_ipoib_txq *txq = &priv->txqs[i];
+               netif_napi_del(txq->napi);
+-              vfree(txq->tx_ring.items);
++              kfree(txq->tx_ring.items);
+       }
+       kfree(priv->txqs);
+@@ -817,7 +817,7 @@ void hfi1_ipoib_txreq_deinit(struct hfi1_ipoib_dev_priv *priv)
+               hfi1_ipoib_drain_tx_list(txq);
+               netif_napi_del(txq->napi);
+               (void)hfi1_ipoib_drain_tx_ring(txq, txq->tx_ring.max_items);
+-              vfree(txq->tx_ring.items);
++              kfree(txq->tx_ring.items);
+       }
+       kfree(priv->txqs);
+-- 
+2.30.2
+
diff --git a/queue-5.11/ice-handle-increasing-tx-or-rx-ring-sizes.patch b/queue-5.11/ice-handle-increasing-tx-or-rx-ring-sizes.patch
new file mode 100644 (file)
index 0000000..2e67163
--- /dev/null
@@ -0,0 +1,215 @@
+From fa4a38bf4865bd28a0418ddb1e350874dcc20293 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Mar 2021 10:12:05 -0800
+Subject: ice: handle increasing Tx or Rx ring sizes
+
+From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
+
+[ Upstream commit 2ec5638559c13b923250eccf495d2a033fccb3e7 ]
+
+There is an issue when the Tx or Rx ring size increases using
+'ethtool -L ...' where the new rings don't get the correct ITR
+values because when we rebuild the VSI we don't know that some
+of the rings may be new.
+
+Fix this by looking at the original number of rings and
+determining if the rings in ice_vsi_rebuild_set_coalesce()
+were not present in the original rings received in
+ice_vsi_rebuild_get_coalesce().
+
+Also change the code to return an error if we can't allocate
+memory for the coalesce data in ice_vsi_rebuild().
+
+Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_lib.c  | 123 ++++++++++++++++------
+ drivers/net/ethernet/intel/ice/ice_txrx.h |   2 +
+ 2 files changed, 92 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
+index 170367eaa95a..e1384503dd4d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -2684,38 +2684,46 @@ int ice_vsi_release(struct ice_vsi *vsi)
+ }
+ /**
+- * ice_vsi_rebuild_update_coalesce - set coalesce for a q_vector
++ * ice_vsi_rebuild_update_coalesce_intrl - set interrupt rate limit for a q_vector
+  * @q_vector: pointer to q_vector which is being updated
+- * @coalesce: pointer to array of struct with stored coalesce
++ * @stored_intrl_setting: original INTRL setting
+  *
+  * Set coalesce param in q_vector and update these parameters in HW.
+  */
+ static void
+-ice_vsi_rebuild_update_coalesce(struct ice_q_vector *q_vector,
+-                              struct ice_coalesce_stored *coalesce)
++ice_vsi_rebuild_update_coalesce_intrl(struct ice_q_vector *q_vector,
++                                    u16 stored_intrl_setting)
+ {
+-      struct ice_ring_container *rx_rc = &q_vector->rx;
+-      struct ice_ring_container *tx_rc = &q_vector->tx;
+       struct ice_hw *hw = &q_vector->vsi->back->hw;
+-      tx_rc->itr_setting = coalesce->itr_tx;
+-      rx_rc->itr_setting = coalesce->itr_rx;
+-
+-      /* dynamic ITR values will be updated during Tx/Rx */
+-      if (!ITR_IS_DYNAMIC(tx_rc->itr_setting))
+-              wr32(hw, GLINT_ITR(tx_rc->itr_idx, q_vector->reg_idx),
+-                   ITR_REG_ALIGN(tx_rc->itr_setting) >>
+-                   ICE_ITR_GRAN_S);
+-      if (!ITR_IS_DYNAMIC(rx_rc->itr_setting))
+-              wr32(hw, GLINT_ITR(rx_rc->itr_idx, q_vector->reg_idx),
+-                   ITR_REG_ALIGN(rx_rc->itr_setting) >>
+-                   ICE_ITR_GRAN_S);
+-
+-      q_vector->intrl = coalesce->intrl;
++      q_vector->intrl = stored_intrl_setting;
+       wr32(hw, GLINT_RATE(q_vector->reg_idx),
+            ice_intrl_usec_to_reg(q_vector->intrl, hw->intrl_gran));
+ }
++/**
++ * ice_vsi_rebuild_update_coalesce_itr - set coalesce for a q_vector
++ * @q_vector: pointer to q_vector which is being updated
++ * @rc: pointer to ring container
++ * @stored_itr_setting: original ITR setting
++ *
++ * Set coalesce param in q_vector and update these parameters in HW.
++ */
++static void
++ice_vsi_rebuild_update_coalesce_itr(struct ice_q_vector *q_vector,
++                                  struct ice_ring_container *rc,
++                                  u16 stored_itr_setting)
++{
++      struct ice_hw *hw = &q_vector->vsi->back->hw;
++
++      rc->itr_setting = stored_itr_setting;
++
++      /* dynamic ITR values will be updated during Tx/Rx */
++      if (!ITR_IS_DYNAMIC(rc->itr_setting))
++              wr32(hw, GLINT_ITR(rc->itr_idx, q_vector->reg_idx),
++                   ITR_REG_ALIGN(rc->itr_setting) >> ICE_ITR_GRAN_S);
++}
++
+ /**
+  * ice_vsi_rebuild_get_coalesce - get coalesce from all q_vectors
+  * @vsi: VSI connected with q_vectors
+@@ -2735,6 +2743,11 @@ ice_vsi_rebuild_get_coalesce(struct ice_vsi *vsi,
+               coalesce[i].itr_tx = q_vector->tx.itr_setting;
+               coalesce[i].itr_rx = q_vector->rx.itr_setting;
+               coalesce[i].intrl = q_vector->intrl;
++
++              if (i < vsi->num_txq)
++                      coalesce[i].tx_valid = true;
++              if (i < vsi->num_rxq)
++                      coalesce[i].rx_valid = true;
+       }
+       return vsi->num_q_vectors;
+@@ -2759,17 +2772,59 @@ ice_vsi_rebuild_set_coalesce(struct ice_vsi *vsi,
+       if ((size && !coalesce) || !vsi)
+               return;
+-      for (i = 0; i < size && i < vsi->num_q_vectors; i++)
+-              ice_vsi_rebuild_update_coalesce(vsi->q_vectors[i],
+-                                              &coalesce[i]);
+-
+-      /* number of q_vectors increased, so assume coalesce settings were
+-       * changed globally (i.e. ethtool -C eth0 instead of per-queue) and use
+-       * the previous settings from q_vector 0 for all of the new q_vectors
++      /* There are a couple of cases that have to be handled here:
++       *   1. The case where the number of queue vectors stays the same, but
++       *      the number of Tx or Rx rings changes (the first for loop)
++       *   2. The case where the number of queue vectors increased (the
++       *      second for loop)
+        */
+-      for (; i < vsi->num_q_vectors; i++)
+-              ice_vsi_rebuild_update_coalesce(vsi->q_vectors[i],
+-                                              &coalesce[0]);
++      for (i = 0; i < size && i < vsi->num_q_vectors; i++) {
++              /* There are 2 cases to handle here and they are the same for
++               * both Tx and Rx:
++               *   if the entry was valid previously (coalesce[i].[tr]x_valid
++               *   and the loop variable is less than the number of rings
++               *   allocated, then write the previous values
++               *
++               *   if the entry was not valid previously, but the number of
++               *   rings is less than are allocated (this means the number of
++               *   rings increased from previously), then write out the
++               *   values in the first element
++               */
++              if (i < vsi->alloc_rxq && coalesce[i].rx_valid)
++                      ice_vsi_rebuild_update_coalesce_itr(vsi->q_vectors[i],
++                                                          &vsi->q_vectors[i]->rx,
++                                                          coalesce[i].itr_rx);
++              else if (i < vsi->alloc_rxq)
++                      ice_vsi_rebuild_update_coalesce_itr(vsi->q_vectors[i],
++                                                          &vsi->q_vectors[i]->rx,
++                                                          coalesce[0].itr_rx);
++
++              if (i < vsi->alloc_txq && coalesce[i].tx_valid)
++                      ice_vsi_rebuild_update_coalesce_itr(vsi->q_vectors[i],
++                                                          &vsi->q_vectors[i]->tx,
++                                                          coalesce[i].itr_tx);
++              else if (i < vsi->alloc_txq)
++                      ice_vsi_rebuild_update_coalesce_itr(vsi->q_vectors[i],
++                                                          &vsi->q_vectors[i]->tx,
++                                                          coalesce[0].itr_tx);
++
++              ice_vsi_rebuild_update_coalesce_intrl(vsi->q_vectors[i],
++                                                    coalesce[i].intrl);
++      }
++
++      /* the number of queue vectors increased so write whatever is in
++       * the first element
++       */
++      for (; i < vsi->num_q_vectors; i++) {
++              ice_vsi_rebuild_update_coalesce_itr(vsi->q_vectors[i],
++                                                  &vsi->q_vectors[i]->tx,
++                                                  coalesce[0].itr_tx);
++              ice_vsi_rebuild_update_coalesce_itr(vsi->q_vectors[i],
++                                                  &vsi->q_vectors[i]->rx,
++                                                  coalesce[0].itr_rx);
++              ice_vsi_rebuild_update_coalesce_intrl(vsi->q_vectors[i],
++                                                    coalesce[0].intrl);
++      }
+ }
+ /**
+@@ -2798,9 +2853,11 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
+       coalesce = kcalloc(vsi->num_q_vectors,
+                          sizeof(struct ice_coalesce_stored), GFP_KERNEL);
+-      if (coalesce)
+-              prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi,
+-                                                                coalesce);
++      if (!coalesce)
++              return -ENOMEM;
++
++      prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi, coalesce);
++
+       ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);
+       ice_vsi_free_q_vectors(vsi);
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
+index ff1a1cbd078e..eab7ceae926b 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
+@@ -351,6 +351,8 @@ struct ice_coalesce_stored {
+       u16 itr_tx;
+       u16 itr_rx;
+       u8 intrl;
++      u8 tx_valid;
++      u8 rx_valid;
+ };
+ /* iterator for handling rings in ring container */
+-- 
+2.30.2
+
diff --git a/queue-5.11/iommu-amd-remove-performance-counter-pre-initializat.patch b/queue-5.11/iommu-amd-remove-performance-counter-pre-initializat.patch
new file mode 100644 (file)
index 0000000..1bc70cb
--- /dev/null
@@ -0,0 +1,98 @@
+From fda26427547bc49ddd5b40f5fc365376b7096197 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Apr 2021 03:58:48 -0500
+Subject: iommu/amd: Remove performance counter pre-initialization test
+
+From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+
+[ Upstream commit 994d6608efe4a4c8834bdc5014c86f4bc6aceea6 ]
+
+In early AMD desktop/mobile platforms (during 2013), when the IOMMU
+Performance Counter (PMC) support was first introduced in
+commit 30861ddc9cca ("perf/x86/amd: Add IOMMU Performance Counter
+resource management"), there was a HW bug where the counters could not
+be accessed. The result was reading of the counter always return zero.
+
+At the time, the suggested workaround was to add a test logic prior
+to initializing the PMC feature to check if the counters can be programmed
+and read back the same value. This has been working fine until the more
+recent desktop/mobile platforms start enabling power gating for the PMC,
+which prevents access to the counters. This results in the PMC support
+being disabled unnecesarily.
+
+Unfortunatly, there is no documentation of since which generation
+of hardware the original PMC HW bug was fixed. Although, it was fixed
+soon after the first introduction of the PMC. Base on this, we assume
+that the buggy platforms are less likely to be in used, and it should
+be relatively safe to remove this legacy logic.
+
+Link: https://lore.kernel.org/linux-iommu/alpine.LNX.3.20.13.2006030935570.3181@monopod.intra.ispras.ru/
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=201753
+Cc: Tj (Elloe Linux) <ml.linux@elloe.vision>
+Cc: Shuah Khan <skhan@linuxfoundation.org>
+Cc: Alexander Monakov <amonakov@ispras.ru>
+Cc: David Coe <david.coe@live.co.uk>
+Cc: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Tested-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20210409085848.3908-3-suravee.suthikulpanit@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/init.c | 24 +-----------------------
+ 1 file changed, 1 insertion(+), 23 deletions(-)
+
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index 3d417afb581b..735ad74e2c8f 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -1712,33 +1712,16 @@ static int __init init_iommu_all(struct acpi_table_header *table)
+       return 0;
+ }
+-static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
+-                              u8 fxn, u64 *value, bool is_write);
+-
+ static void init_iommu_perf_ctr(struct amd_iommu *iommu)
+ {
++      u64 val;
+       struct pci_dev *pdev = iommu->dev;
+-      u64 val = 0xabcd, val2 = 0, save_reg = 0;
+       if (!iommu_feature(iommu, FEATURE_PC))
+               return;
+       amd_iommu_pc_present = true;
+-      /* save the value to restore, if writable */
+-      if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, false))
+-              goto pc_false;
+-
+-      /* Check if the performance counters can be written to */
+-      if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true)) ||
+-          (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false)) ||
+-          (val != val2))
+-              goto pc_false;
+-
+-      /* restore */
+-      if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, true))
+-              goto pc_false;
+-
+       pci_info(pdev, "IOMMU performance counters supported\n");
+       val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET);
+@@ -1746,11 +1729,6 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu)
+       iommu->max_counters = (u8) ((val >> 7) & 0xf);
+       return;
+-
+-pc_false:
+-      pci_err(pdev, "Unable to read/write to IOMMU perf counter.\n");
+-      amd_iommu_pc_present = false;
+-      return;
+ }
+ static ssize_t amd_iommu_show_cap(struct device *dev,
+-- 
+2.30.2
+
diff --git a/queue-5.11/ip6_vti-proper-dev_-hold-put-in-ndo_-un-init-methods.patch b/queue-5.11/ip6_vti-proper-dev_-hold-put-in-ndo_-un-init-methods.patch
new file mode 100644 (file)
index 0000000..668a0ed
--- /dev/null
@@ -0,0 +1,98 @@
+From 18581e4ec7928958333ce75eaf385955e5ba2962 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 12:12:54 -0700
+Subject: ip6_vti: proper dev_{hold|put} in ndo_[un]init methods
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 40cb881b5aaa0b69a7d93dec8440d5c62dae299f ]
+
+After adopting CONFIG_PCPU_DEV_REFCNT=n option, syzbot was able to trigger
+a warning [1]
+
+Issue here is that:
+
+- all dev_put() should be paired with a corresponding prior dev_hold().
+
+- A driver doing a dev_put() in its ndo_uninit() MUST also
+  do a dev_hold() in its ndo_init(), only when ndo_init()
+  is returning 0.
+
+Otherwise, register_netdevice() would call ndo_uninit()
+in its error path and release a refcount too soon.
+
+Therefore, we need to move dev_hold() call from
+vti6_tnl_create2() to vti6_dev_init_gen()
+
+[1]
+WARNING: CPU: 0 PID: 15951 at lib/refcount.c:31 refcount_warn_saturate+0xbf/0x1e0 lib/refcount.c:31
+Modules linked in:
+CPU: 0 PID: 15951 Comm: syz-executor.3 Not tainted 5.12.0-rc4-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+RIP: 0010:refcount_warn_saturate+0xbf/0x1e0 lib/refcount.c:31
+Code: 1d 6a 5a e8 09 31 ff 89 de e8 8d 1a ab fd 84 db 75 e0 e8 d4 13 ab fd 48 c7 c7 a0 e1 c1 89 c6 05 4a 5a e8 09 01 e8 2e 36 fb 04 <0f> 0b eb c4 e8 b8 13 ab fd 0f b6 1d 39 5a e8 09 31 ff 89 de e8 58
+RSP: 0018:ffffc90001eaef28 EFLAGS: 00010282
+RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
+RDX: 0000000000040000 RSI: ffffffff815c51f5 RDI: fffff520003d5dd7
+RBP: 0000000000000004 R08: 0000000000000000 R09: 0000000000000000
+R10: ffffffff815bdf8e R11: 0000000000000000 R12: ffff88801bb1c568
+R13: ffff88801f69e800 R14: 00000000ffffffff R15: ffff888050889d40
+FS:  00007fc79314e700(0000) GS:ffff8880b9c00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f1c1ff47108 CR3: 0000000020fd5000 CR4: 00000000001506f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ __refcount_dec include/linux/refcount.h:344 [inline]
+ refcount_dec include/linux/refcount.h:359 [inline]
+ dev_put include/linux/netdevice.h:4135 [inline]
+ vti6_dev_uninit+0x31a/0x360 net/ipv6/ip6_vti.c:297
+ register_netdevice+0xadf/0x1500 net/core/dev.c:10308
+ vti6_tnl_create2+0x1b5/0x400 net/ipv6/ip6_vti.c:190
+ vti6_newlink+0x9d/0xd0 net/ipv6/ip6_vti.c:1020
+ __rtnl_newlink+0x1062/0x1710 net/core/rtnetlink.c:3443
+ rtnl_newlink+0x64/0xa0 net/core/rtnetlink.c:3491
+ rtnetlink_rcv_msg+0x44e/0xad0 net/core/rtnetlink.c:5553
+ netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2502
+ netlink_unicast_kernel net/netlink/af_netlink.c:1312 [inline]
+ netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1338
+ netlink_sendmsg+0x856/0xd90 net/netlink/af_netlink.c:1927
+ sock_sendmsg_nosec net/socket.c:654 [inline]
+ sock_sendmsg+0xcf/0x120 net/socket.c:674
+ ____sys_sendmsg+0x331/0x810 net/socket.c:2350
+ ___sys_sendmsg+0xf3/0x170 net/socket.c:2404
+ __sys_sendmmsg+0x195/0x470 net/socket.c:2490
+ __do_sys_sendmmsg net/socket.c:2519 [inline]
+ __se_sys_sendmmsg net/socket.c:2516 [inline]
+ __x64_sys_sendmmsg+0x99/0x100 net/socket.c:2516
+
+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/ip6_vti.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index f10e7a72ea62..a018afdb3e06 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -193,7 +193,6 @@ static int vti6_tnl_create2(struct net_device *dev)
+       strcpy(t->parms.name, dev->name);
+-      dev_hold(dev);
+       vti6_tnl_link(ip6n, t);
+       return 0;
+@@ -932,6 +931,7 @@ static inline int vti6_dev_init_gen(struct net_device *dev)
+       dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
+       if (!dev->tstats)
+               return -ENOMEM;
++      dev_hold(dev);
+       return 0;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/iwlwifi-pcie-make-cfg-vs.-trans_cfg-more-robust.patch b/queue-5.11/iwlwifi-pcie-make-cfg-vs.-trans_cfg-more-robust.patch
new file mode 100644 (file)
index 0000000..d12bd76
--- /dev/null
@@ -0,0 +1,113 @@
+From 10e243e1bbd7b562000b8115a0353093b1d8134d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Mar 2021 16:24:58 +0300
+Subject: iwlwifi: pcie: make cfg vs. trans_cfg more robust
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 48a5494d6a4cb5812f0640d9515f1876ffc7a013 ]
+
+If we (for example) have a trans_cfg entry in the PCI IDs table,
+but then don't find a full cfg entry for it in the info table,
+we fall through to the code that treats the PCI ID table entry
+as a full cfg entry. This obviously causes crashes later, e.g.
+when trying to build the firmware name string.
+
+Avoid such crashes by using the low bit of the pointer as a tag
+for trans_cfg entries (automatically using a macro that checks
+the type when assigning) and then checking that before trying to
+use the data as a full entry - if it's just a partial entry at
+that point, fail.
+
+Since we're adding some macro magic, also check that the type is
+in fact either struct iwl_cfg_trans_params or struct iwl_cfg,
+failing compilation ("initializer element is not constant") if
+it isn't.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20210330162204.6f69fe6e4128.I921d4ae20ef5276716baeeeda0b001cf25b9b968@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 35 +++++++++++++++----
+ 1 file changed, 28 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index 018daa84ddd2..70752f0c67b0 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -17,10 +17,20 @@
+ #include "iwl-prph.h"
+ #include "internal.h"
++#define TRANS_CFG_MARKER BIT(0)
++#define _IS_A(cfg, _struct) __builtin_types_compatible_p(typeof(cfg), \
++                                                       struct _struct)
++extern int _invalid_type;
++#define _TRANS_CFG_MARKER(cfg)                                                \
++      (__builtin_choose_expr(_IS_A(cfg, iwl_cfg_trans_params),        \
++                             TRANS_CFG_MARKER,                        \
++       __builtin_choose_expr(_IS_A(cfg, iwl_cfg), 0, _invalid_type)))
++#define _ASSIGN_CFG(cfg) (_TRANS_CFG_MARKER(cfg) + (kernel_ulong_t)&(cfg))
++
+ #define IWL_PCI_DEVICE(dev, subdev, cfg) \
+       .vendor = PCI_VENDOR_ID_INTEL,  .device = (dev), \
+       .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
+-      .driver_data = (kernel_ulong_t)&(cfg)
++      .driver_data = _ASSIGN_CFG(cfg)
+ /* Hardware specific file defines the PCI IDs table for that hardware module */
+ static const struct pci_device_id iwl_hw_card_ids[] = {
+@@ -988,19 +998,22 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+-      const struct iwl_cfg_trans_params *trans =
+-              (struct iwl_cfg_trans_params *)(ent->driver_data);
++      const struct iwl_cfg_trans_params *trans;
+       const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;
+       struct iwl_trans *iwl_trans;
+       struct iwl_trans_pcie *trans_pcie;
+       int i, ret;
++      const struct iwl_cfg *cfg;
++
++      trans = (void *)(ent->driver_data & ~TRANS_CFG_MARKER);
++
+       /*
+        * This is needed for backwards compatibility with the old
+        * tables, so we don't need to change all the config structs
+        * at the same time.  The cfg is used to compare with the old
+        * full cfg structs.
+        */
+-      const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
++      cfg = (void *)(ent->driver_data & ~TRANS_CFG_MARKER);
+       /* make sure trans is the first element in iwl_cfg */
+       BUILD_BUG_ON(offsetof(struct iwl_cfg, trans));
+@@ -1102,11 +1115,19 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ #endif
+       /*
+-       * If we didn't set the cfg yet, assume the trans is actually
+-       * a full cfg from the old tables.
++       * If we didn't set the cfg yet, the PCI ID table entry should have
++       * been a full config - if yes, use it, otherwise fail.
+        */
+-      if (!iwl_trans->cfg)
++      if (!iwl_trans->cfg) {
++              if (ent->driver_data & TRANS_CFG_MARKER) {
++                      pr_err("No config found for PCI dev %04x/%04x, rev=0x%x, rfid=0x%x\n",
++                             pdev->device, pdev->subsystem_device,
++                             iwl_trans->hw_rev, iwl_trans->hw_rf_id);
++                      ret = -EINVAL;
++                      goto out_free_trans;
++              }
+               iwl_trans->cfg = cfg;
++      }
+       /* if we don't have a name yet, copy name from the old cfg */
+       if (!iwl_trans->name)
+-- 
+2.30.2
+
diff --git a/queue-5.11/iwlwifi-queue-avoid-memory-leak-in-reset-flow.patch b/queue-5.11/iwlwifi-queue-avoid-memory-leak-in-reset-flow.patch
new file mode 100644 (file)
index 0000000..1cde39c
--- /dev/null
@@ -0,0 +1,121 @@
+From 8cfa242a36fba405e7625c2d0492ad36875befad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Apr 2021 12:46:22 +0300
+Subject: iwlwifi: queue: avoid memory leak in reset flow
+
+From: Mordechay Goodstein <mordechay.goodstein@intel.com>
+
+[ Upstream commit 4cf2f5904d971a461f67825434ae3c31900ff84b ]
+
+In case the device is stopped any usage of hw queues needs to be
+reallocated in fw due to fw reset after device stop, so all driver
+internal queue should also be freed, and if we don't free the next usage
+would leak the old memory and get in recover flows
+"iwlwifi 0000:00:03.0: dma_pool_destroy iwlwifi:bc" warning.
+
+Also warn about trying to reuse an internal allocated queue.
+
+Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20210411124417.c72d2f0355c4.Ia3baff633b9b9109f88ab379ef0303aa152c16bf@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/intel/iwlwifi/pcie/trans-gen2.c  |  4 +--
+ drivers/net/wireless/intel/iwlwifi/queue/tx.c | 30 ++++---------------
+ drivers/net/wireless/intel/iwlwifi/queue/tx.h |  3 +-
+ 3 files changed, 9 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+index 08788bc90683..fd7398daaf65 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+@@ -1,7 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+  * Copyright (C) 2017 Intel Deutschland GmbH
+- * Copyright (C) 2018-2020 Intel Corporation
++ * Copyright (C) 2018-2021 Intel Corporation
+  */
+ #include "iwl-trans.h"
+ #include "iwl-prph.h"
+@@ -141,7 +141,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
+       if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+               IWL_DEBUG_INFO(trans,
+                              "DEVICE_ENABLED bit was set and is now cleared\n");
+-              iwl_txq_gen2_tx_stop(trans);
++              iwl_txq_gen2_tx_free(trans);
+               iwl_pcie_rx_stop(trans);
+       }
+diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c
+index 7ff1bb0ccc9c..cd5b06ce3e9c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c
+@@ -13,30 +13,6 @@
+ #include "iwl-scd.h"
+ #include <linux/dmapool.h>
+-/*
+- * iwl_txq_gen2_tx_stop - Stop all Tx DMA channels
+- */
+-void iwl_txq_gen2_tx_stop(struct iwl_trans *trans)
+-{
+-      int txq_id;
+-
+-      /*
+-       * This function can be called before the op_mode disabled the
+-       * queues. This happens when we have an rfkill interrupt.
+-       * Since we stop Tx altogether - mark the queues as stopped.
+-       */
+-      memset(trans->txqs.queue_stopped, 0,
+-             sizeof(trans->txqs.queue_stopped));
+-      memset(trans->txqs.queue_used, 0, sizeof(trans->txqs.queue_used));
+-
+-      /* Unmap DMA from host system and free skb's */
+-      for (txq_id = 0; txq_id < ARRAY_SIZE(trans->txqs.txq); txq_id++) {
+-              if (!trans->txqs.txq[txq_id])
+-                      continue;
+-              iwl_txq_gen2_unmap(trans, txq_id);
+-      }
+-}
+-
+ /*
+  * iwl_txq_update_byte_tbl - Set up entry in Tx byte-count array
+  */
+@@ -1189,6 +1165,12 @@ static int iwl_txq_alloc_response(struct iwl_trans *trans, struct iwl_txq *txq,
+               goto error_free_resp;
+       }
++      if (WARN_ONCE(trans->txqs.txq[qid],
++                    "queue %d already allocated\n", qid)) {
++              ret = -EIO;
++              goto error_free_resp;
++      }
++
+       txq->id = qid;
+       trans->txqs.txq[qid] = txq;
+       wr_ptr &= (trans->trans_cfg->base_params->max_tfd_queue_size - 1);
+diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.h b/drivers/net/wireless/intel/iwlwifi/queue/tx.h
+index cff694c25ccc..d32256d78917 100644
+--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.h
++++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2020 Intel Corporation
++ * Copyright (C) 2020-2021 Intel Corporation
+  */
+ #ifndef __iwl_trans_queue_tx_h__
+ #define __iwl_trans_queue_tx_h__
+@@ -123,7 +123,6 @@ int iwl_txq_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
+ void iwl_txq_dyn_free(struct iwl_trans *trans, int queue);
+ void iwl_txq_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq);
+ void iwl_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq);
+-void iwl_txq_gen2_tx_stop(struct iwl_trans *trans);
+ void iwl_txq_gen2_tx_free(struct iwl_trans *trans);
+ int iwl_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num,
+                bool cmd_queue);
+-- 
+2.30.2
+
diff --git a/queue-5.11/kbuild-generate-module.symvers-only-when-vmlinux-exi.patch b/queue-5.11/kbuild-generate-module.symvers-only-when-vmlinux-exi.patch
new file mode 100644 (file)
index 0000000..ef69e17
--- /dev/null
@@ -0,0 +1,144 @@
+From 1339359c8473a2a0bb139f579d1c6379578210c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 03:54:09 +0900
+Subject: kbuild: generate Module.symvers only when vmlinux exists
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 69bc8d386aebbd91a6bb44b6d33f77c8dfa9ed8c ]
+
+The external module build shows the following warning if Module.symvers
+is missing in the kernel tree.
+
+  WARNING: Symbol version dump "Module.symvers" is missing.
+           Modules may not have dependencies or modversions.
+
+I think this is an important heads-up because the resulting modules may
+not work as expected. This happens when you did not build the entire
+kernel tree, for example, you might have prepared the minimal setups
+for external modules by 'make defconfig && make modules_preapre'.
+
+A problem is that 'make modules' creates Module.symvers even without
+vmlinux. In this case, that warning is suppressed since Module.symvers
+already exists in spite of its incomplete content.
+
+The incomplete (i.e. invalid) Module.symvers should not be created.
+
+This commit changes the second pass of modpost to dump symbols into
+modules-only.symvers. The final Module.symvers is created by
+concatenating vmlinux.symvers and modules-only.symvers if both exist.
+
+Module.symvers is supposed to collect symbols from both vmlinux and
+modules. It might be a bit confusing, and I am not quite sure if it
+is an official interface, but presumably it is difficult to rename it
+because some tools (e.g. kmod) parse it.
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .gitignore               |  1 +
+ Documentation/dontdiff   |  1 +
+ Makefile                 |  2 +-
+ scripts/Makefile.modpost | 15 ++++++++++++++-
+ scripts/mod/modpost.c    | 15 +--------------
+ 5 files changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/.gitignore b/.gitignore
+index d01cda8e1177..67d2f3503128 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -55,6 +55,7 @@ modules.order
+ /tags
+ /TAGS
+ /linux
++/modules-only.symvers
+ /vmlinux
+ /vmlinux.32
+ /vmlinux.symvers
+diff --git a/Documentation/dontdiff b/Documentation/dontdiff
+index e361fc95ca29..82e3eee7363b 100644
+--- a/Documentation/dontdiff
++++ b/Documentation/dontdiff
+@@ -178,6 +178,7 @@ mktables
+ mktree
+ mkutf8data
+ modpost
++modules-only.symvers
+ modules.builtin
+ modules.builtin.modinfo
+ modules.nsdeps
+diff --git a/Makefile b/Makefile
+index 11ca74eabf47..8ca39f45f622 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1482,7 +1482,7 @@ endif # CONFIG_MODULES
+ # make distclean Remove editor backup files, patch leftover files and the like
+ # Directories & files removed with 'make clean'
+-CLEAN_FILES += include/ksym vmlinux.symvers \
++CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \
+              modules.builtin modules.builtin.modinfo modules.nsdeps \
+              compile_commands.json
+diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
+index f54b6ac37ac2..12a87be0fb44 100644
+--- a/scripts/Makefile.modpost
++++ b/scripts/Makefile.modpost
+@@ -65,7 +65,20 @@ else
+ ifeq ($(KBUILD_EXTMOD),)
+ input-symdump := vmlinux.symvers
+-output-symdump := Module.symvers
++output-symdump := modules-only.symvers
++
++quiet_cmd_cat = GEN     $@
++      cmd_cat = cat $(real-prereqs) > $@
++
++ifneq ($(wildcard vmlinux.symvers),)
++
++__modpost: Module.symvers
++Module.symvers: vmlinux.symvers modules-only.symvers FORCE
++      $(call if_changed,cat)
++
++targets += Module.symvers
++
++endif
+ else
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index d6c81657d695..5f9d8d9147d0 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -2469,19 +2469,6 @@ fail:
+       fatal("parse error in symbol dump file\n");
+ }
+-/* For normal builds always dump all symbols.
+- * For external modules only dump symbols
+- * that are not read from kernel Module.symvers.
+- **/
+-static int dump_sym(struct symbol *sym)
+-{
+-      if (!external_module)
+-              return 1;
+-      if (sym->module->from_dump)
+-              return 0;
+-      return 1;
+-}
+-
+ static void write_dump(const char *fname)
+ {
+       struct buffer buf = { };
+@@ -2492,7 +2479,7 @@ static void write_dump(const char *fname)
+       for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
+               symbol = symbolhash[n];
+               while (symbol) {
+-                      if (dump_sym(symbol)) {
++                      if (!symbol->module->from_dump) {
+                               namespace = symbol->namespace;
+                               buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
+                                          symbol->crc, symbol->name,
+-- 
+2.30.2
+
diff --git a/queue-5.11/kconfig-nconf-stop-endless-search-loops.patch b/queue-5.11/kconfig-nconf-stop-endless-search-loops.patch
new file mode 100644 (file)
index 0000000..18ff3ff
--- /dev/null
@@ -0,0 +1,62 @@
+From eb57b334e0af17d6167449f89788f1672623196f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 09:28:03 +0200
+Subject: kconfig: nconf: stop endless search loops
+
+From: Mihai Moldovan <ionic@ionic.de>
+
+[ Upstream commit 8c94b430b9f6213dec84e309bb480a71778c4213 ]
+
+If the user selects the very first entry in a page and performs a
+search-up operation, or selects the very last entry in a page and
+performs a search-down operation that will not succeed (e.g., via
+[/]asdfzzz[Up Arrow]), nconf will never terminate searching the page.
+
+The reason is that in this case, the starting point will be set to -1
+or n, which is then translated into (n - 1) (i.e., the last entry of
+the page) or 0 (i.e., the first entry of the page) and finally the
+search begins. This continues to work fine until the index reaches 0 or
+(n - 1), at which point it will be decremented to -1 or incremented to
+n, but not checked against the starting point right away. Instead, it's
+wrapped around to the bottom or top again, after which the starting
+point check occurs... and naturally fails.
+
+My original implementation added another check for -1 before wrapping
+the running index variable around, but Masahiro Yamada pointed out that
+the actual issue is that the comparison point (starting point) exceeds
+bounds (i.e., the [0,n-1] interval) in the first place and that,
+instead, the starting point should be fixed.
+
+This has the welcome side-effect of also fixing the case where the
+starting point was n while searching down, which also lead to an
+infinite loop.
+
+OTOH, this code is now essentially all his work.
+
+Amazingly, nobody seems to have been hit by this for 11 years - or at
+the very least nobody bothered to debug and fix this.
+
+Signed-off-by: Mihai Moldovan <ionic@ionic.de>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/kconfig/nconf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
+index e0f965529166..af814b39b876 100644
+--- a/scripts/kconfig/nconf.c
++++ b/scripts/kconfig/nconf.c
+@@ -504,8 +504,8 @@ static int get_mext_match(const char *match_str, match_f flag)
+       else if (flag == FIND_NEXT_MATCH_UP)
+               --match_start;
++      match_start = (match_start + items_num) % items_num;
+       index = match_start;
+-      index = (index + items_num) % items_num;
+       while (true) {
+               char *str = k_menu_items[index].str;
+               if (strcasestr(str, match_str) != NULL)
+-- 
+2.30.2
+
diff --git a/queue-5.11/kernel-kexec_file-fix-error-return-code-of-kexec_cal.patch b/queue-5.11/kernel-kexec_file-fix-error-return-code-of-kexec_cal.patch
new file mode 100644 (file)
index 0000000..4268120
--- /dev/null
@@ -0,0 +1,45 @@
+From 6018eca53fc7436ac3d9afd6a419d42509325f36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 18:04:38 -0700
+Subject: kernel: kexec_file: fix error return code of
+ kexec_calculate_store_digests()
+
+From: Jia-Ju Bai <baijiaju1990@gmail.com>
+
+[ Upstream commit 31d82c2c787d5cf65fedd35ebbc0c1bd95c1a679 ]
+
+When vzalloc() returns NULL to sha_regions, no error return code of
+kexec_calculate_store_digests() is assigned.  To fix this bug, ret is
+assigned with -ENOMEM in this case.
+
+Link: https://lkml.kernel.org/r/20210309083904.24321-1-baijiaju1990@gmail.com
+Fixes: a43cac0d9dc2 ("kexec: split kexec_file syscall code to kexec_file.c")
+Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
+Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
+Acked-by: Baoquan He <bhe@redhat.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>
+---
+ kernel/kexec_file.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
+index 5c3447cf7ad5..33400ff051a8 100644
+--- a/kernel/kexec_file.c
++++ b/kernel/kexec_file.c
+@@ -740,8 +740,10 @@ static int kexec_calculate_store_digests(struct kimage *image)
+       sha_region_sz = KEXEC_SEGMENT_MAX * sizeof(struct kexec_sha_region);
+       sha_regions = vzalloc(sha_region_sz);
+-      if (!sha_regions)
++      if (!sha_regions) {
++              ret = -ENOMEM;
+               goto out_free_desc;
++      }
+       desc->tfm   = tfm;
+-- 
+2.30.2
+
diff --git a/queue-5.11/kernel-resource-make-walk_mem_res-find-all-busy-iore.patch b/queue-5.11/kernel-resource-make-walk_mem_res-find-all-busy-iore.patch
new file mode 100644 (file)
index 0000000..bfcebe0
--- /dev/null
@@ -0,0 +1,76 @@
+From 1f4940957092ec9e3a98e9d09d30ab79ee109d14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 18:05:16 -0700
+Subject: kernel/resource: make walk_mem_res() find all busy IORESOURCE_MEM
+ resources
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit 3c9c797534364593b73ba6ab060a014af8934721 ]
+
+It used to be true that we can have system RAM (IORESOURCE_SYSTEM_RAM |
+IORESOURCE_BUSY) only on the first level in the resource tree.  However,
+this is no longer holds for driver-managed system RAM (i.e., added via
+dax/kmem and virtio-mem), which gets added on lower levels, for example,
+inside device containers.
+
+IORESOURCE_SYSTEM_RAM is defined as IORESOURCE_MEM | IORESOURCE_SYSRAM and
+just a special type of IORESOURCE_MEM.
+
+The function walk_mem_res() only considers the first level and is used in
+arch/x86/mm/ioremap.c:__ioremap_check_mem() only.  We currently fail to
+identify System RAM added by dax/kmem and virtio-mem as
+"IORES_MAP_SYSTEM_RAM", for example, allowing for remapping of such
+"normal RAM" in __ioremap_caller().
+
+Let's find all IORESOURCE_MEM | IORESOURCE_BUSY resources, making the
+function behave similar to walk_system_ram_res().
+
+Link: https://lkml.kernel.org/r/20210325115326.7826-3-david@redhat.com
+Fixes: ebf71552bb0e ("virtio-mem: Add parent resource for all added "System RAM"")
+Fixes: c221c0b0308f ("device-dax: "Hotplug" persistent memory for use like normal RAM")
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Cc: Dave Young <dyoung@redhat.com>
+Cc: Baoquan He <bhe@redhat.com>
+Cc: Vivek Goyal <vgoyal@redhat.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Keith Busch <keith.busch@intel.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Qian Cai <cai@lca.pw>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Eric Biederman <ebiederm@xmission.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Brijesh Singh <brijesh.singh@amd.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>
+---
+ kernel/resource.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/resource.c b/kernel/resource.c
+index 5c86d266be34..c99cf3f35802 100644
+--- a/kernel/resource.c
++++ b/kernel/resource.c
+@@ -467,7 +467,7 @@ int walk_mem_res(u64 start, u64 end, void *arg,
+ {
+       unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+-      return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, true,
++      return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, false,
+                                    arg, func);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/kernel-resource-make-walk_system_ram_res-find-all-bu.patch b/queue-5.11/kernel-resource-make-walk_system_ram_res-find-all-bu.patch
new file mode 100644 (file)
index 0000000..ef78b8b
--- /dev/null
@@ -0,0 +1,106 @@
+From dba06c687c02eeaee4276852eaf9867b1c908cf8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 18:05:12 -0700
+Subject: kernel/resource: make walk_system_ram_res() find all busy
+ IORESOURCE_SYSTEM_RAM resources
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit 97f61c8f44ec9020708b97a51188170add4f3084 ]
+
+Patch series "kernel/resource: make walk_system_ram_res() and walk_mem_res() search the whole tree", v2.
+
+Playing with kdump+virtio-mem I noticed that kexec_file_load() does not
+consider System RAM added via dax/kmem and virtio-mem when preparing the
+elf header for kdump.  Looking into the details, the logic used in
+walk_system_ram_res() and walk_mem_res() seems to be outdated.
+
+walk_system_ram_range() already does the right thing, let's change
+walk_system_ram_res() and walk_mem_res(), and clean up.
+
+Loading a kdump kernel via "kexec -p -s" ...  will result in the kdump
+kernel to also dump dax/kmem and virtio-mem added System RAM now.
+
+Note: kexec-tools on x86-64 also have to be updated to consider this
+memory in the kexec_load() case when processing /proc/iomem.
+
+This patch (of 3):
+
+It used to be true that we can have system RAM (IORESOURCE_SYSTEM_RAM |
+IORESOURCE_BUSY) only on the first level in the resource tree.  However,
+this is no longer holds for driver-managed system RAM (i.e., added via
+dax/kmem and virtio-mem), which gets added on lower levels, for example,
+inside device containers.
+
+We have two users of walk_system_ram_res(), which currently only
+consideres the first level:
+
+a) kernel/kexec_file.c:kexec_walk_resources() -- We properly skip
+   IORESOURCE_SYSRAM_DRIVER_MANAGED resources via
+   locate_mem_hole_callback(), so even after this change, we won't be
+   placing kexec images onto dax/kmem and virtio-mem added memory.  No
+   change.
+
+b) arch/x86/kernel/crash.c:fill_up_crash_elf_data() -- we're currently
+   not adding relevant ranges to the crash elf header, resulting in them
+   not getting dumped via kdump.
+
+This change fixes loading a crashkernel via kexec_file_load() and
+including dax/kmem and virtio-mem added System RAM in the crashdump on
+x86-64.  Note that e.g,, arm64 relies on memblock data and, therefore,
+always considers all added System RAM already.
+
+Let's find all IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY resources, making
+the function behave like walk_system_ram_range().
+
+Link: https://lkml.kernel.org/r/20210325115326.7826-1-david@redhat.com
+Link: https://lkml.kernel.org/r/20210325115326.7826-2-david@redhat.com
+Fixes: ebf71552bb0e ("virtio-mem: Add parent resource for all added "System RAM"")
+Fixes: c221c0b0308f ("device-dax: "Hotplug" persistent memory for use like normal RAM")
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Acked-by: Baoquan He <bhe@redhat.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Cc: Dave Young <dyoung@redhat.com>
+Cc: Baoquan He <bhe@redhat.com>
+Cc: Vivek Goyal <vgoyal@redhat.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Keith Busch <keith.busch@intel.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Qian Cai <cai@lca.pw>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Eric Biederman <ebiederm@xmission.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Brijesh Singh <brijesh.singh@amd.com>
+Cc: "Eric W. Biederman" <ebiederm@xmission.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>
+---
+ kernel/resource.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/resource.c b/kernel/resource.c
+index 833394f9c608..5c86d266be34 100644
+--- a/kernel/resource.c
++++ b/kernel/resource.c
+@@ -454,7 +454,7 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
+ {
+       unsigned long flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+-      return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, true,
++      return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, false,
+                                    arg, func);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/khugepaged-fix-wrong-result-value-for-trace_mm_colla.patch b/queue-5.11/khugepaged-fix-wrong-result-value-for-trace_mm_colla.patch
new file mode 100644 (file)
index 0000000..532b7c2
--- /dev/null
@@ -0,0 +1,63 @@
+From c12de38ffb3a0e28ee6f774411e516e1b539bfaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 18:33:46 -0700
+Subject: khugepaged: fix wrong result value for
+ trace_mm_collapse_huge_page_isolate()
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 74e579bf231a337ab3786d59e64bc94f45ca7b3f ]
+
+In writable and !referenced case, the result value should be
+SCAN_LACK_REFERENCED_PAGE for trace_mm_collapse_huge_page_isolate()
+instead of default 0 (SCAN_FAIL) here.
+
+Link: https://lkml.kernel.org/r/20210306032947.35921-5-linmiaohe@huawei.com
+Fixes: 7d2eba0557c1 ("mm: add tracepoint for scanning pages")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: Ebru Akagunduz <ebru.akagunduz@gmail.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Rik van Riel <riel@redhat.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/khugepaged.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 494d3cb0b58a..897b91c5f1d2 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -716,17 +716,17 @@ next:
+               if (pte_write(pteval))
+                       writable = true;
+       }
+-      if (likely(writable)) {
+-              if (likely(referenced)) {
+-                      result = SCAN_SUCCEED;
+-                      trace_mm_collapse_huge_page_isolate(page, none_or_zero,
+-                                                          referenced, writable, result);
+-                      return 1;
+-              }
+-      } else {
++
++      if (unlikely(!writable)) {
+               result = SCAN_PAGE_RO;
++      } else if (unlikely(!referenced)) {
++              result = SCAN_LACK_REFERENCED_PAGE;
++      } else {
++              result = SCAN_SUCCEED;
++              trace_mm_collapse_huge_page_isolate(page, none_or_zero,
++                                                  referenced, writable, result);
++              return 1;
+       }
+-
+ out:
+       release_pte_pages(pte, _pte, compound_pagelist);
+       trace_mm_collapse_huge_page_isolate(page, none_or_zero,
+-- 
+2.30.2
+
diff --git a/queue-5.11/ksm-fix-potential-missing-rmap_item-for-stable_node.patch b/queue-5.11/ksm-fix-potential-missing-rmap_item-for-stable_node.patch
new file mode 100644 (file)
index 0000000..76479f3
--- /dev/null
@@ -0,0 +1,57 @@
+From a722bddd1047d1c33e7fe4f1c9f760834842c4fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 18:37:45 -0700
+Subject: ksm: fix potential missing rmap_item for stable_node
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit c89a384e2551c692a9fe60d093fd7080f50afc51 ]
+
+When removing rmap_item from stable tree, STABLE_FLAG of rmap_item is
+cleared with head reserved.  So the following scenario might happen: For
+ksm page with rmap_item1:
+
+cmp_and_merge_page
+  stable_node->head = &migrate_nodes;
+  remove_rmap_item_from_tree, but head still equal to stable_node;
+  try_to_merge_with_ksm_page failed;
+  return;
+
+For the same ksm page with rmap_item2, stable node migration succeed this
+time.  The stable_node->head does not equal to migrate_nodes now.  For ksm
+page with rmap_item1 again:
+
+cmp_and_merge_page
+ stable_node->head != &migrate_nodes && rmap_item->head == stable_node
+ return;
+
+We would miss the rmap_item for stable_node and might result in failed
+rmap_walk_ksm().  Fix this by set rmap_item->head to NULL when rmap_item
+is removed from stable tree.
+
+Link: https://lkml.kernel.org/r/20210330140228.45635-5-linmiaohe@huawei.com
+Fixes: 4146d2d673e8 ("ksm: make !merge_across_nodes migration safe")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Hugh Dickins <hughd@google.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/ksm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/mm/ksm.c b/mm/ksm.c
+index 9694ee2c71de..b32391ccf6d5 100644
+--- a/mm/ksm.c
++++ b/mm/ksm.c
+@@ -794,6 +794,7 @@ static void remove_rmap_item_from_tree(struct rmap_item *rmap_item)
+               stable_node->rmap_hlist_len--;
+               put_anon_vma(rmap_item->anon_vma);
++              rmap_item->head = NULL;
+               rmap_item->address &= PAGE_MASK;
+       } else if (rmap_item->address & UNSTABLE_FLAG) {
+-- 
+2.30.2
+
diff --git a/queue-5.11/libbpf-fix-signed-overflow-in-ringbuf_process_ring.patch b/queue-5.11/libbpf-fix-signed-overflow-in-ringbuf_process_ring.patch
new file mode 100644 (file)
index 0000000..01dd137
--- /dev/null
@@ -0,0 +1,106 @@
+From 33f428fb4e34b05167f3d03e217c6072990e6b04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 13:05:10 +0000
+Subject: libbpf: Fix signed overflow in ringbuf_process_ring
+
+From: Brendan Jackman <jackmanb@google.com>
+
+[ Upstream commit 2a30f9440640c418bcfbea9b2b344d268b58e0a2 ]
+
+One of our benchmarks running in (Google-internal) CI pushes data
+through the ringbuf faster htan than userspace is able to consume
+it. In this case it seems we're actually able to get >INT_MAX entries
+in a single ring_buffer__consume() call. ASAN detected that cnt
+overflows in this case.
+
+Fix by using 64-bit counter internally and then capping the result to
+INT_MAX before converting to the int return type. Do the same for
+the ring_buffer__poll().
+
+Fixes: bf99c936f947 (libbpf: Add BPF ring buffer support)
+Signed-off-by: Brendan Jackman <jackmanb@google.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20210429130510.1621665-1-jackmanb@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/ringbuf.c | 30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c
+index e7a8d847161f..1d80ad4e0de8 100644
+--- a/tools/lib/bpf/ringbuf.c
++++ b/tools/lib/bpf/ringbuf.c
+@@ -202,9 +202,11 @@ static inline int roundup_len(__u32 len)
+       return (len + 7) / 8 * 8;
+ }
+-static int ringbuf_process_ring(struct ring* r)
++static int64_t ringbuf_process_ring(struct ring* r)
+ {
+-      int *len_ptr, len, err, cnt = 0;
++      int *len_ptr, len, err;
++      /* 64-bit to avoid overflow in case of extreme application behavior */
++      int64_t cnt = 0;
+       unsigned long cons_pos, prod_pos;
+       bool got_new_data;
+       void *sample;
+@@ -244,12 +246,14 @@ done:
+ }
+ /* Consume available ring buffer(s) data without event polling.
+- * Returns number of records consumed across all registered ring buffers, or
+- * negative number if any of the callbacks return error.
++ * Returns number of records consumed across all registered ring buffers (or
++ * INT_MAX, whichever is less), or negative number if any of the callbacks
++ * return error.
+  */
+ int ring_buffer__consume(struct ring_buffer *rb)
+ {
+-      int i, err, res = 0;
++      int64_t err, res = 0;
++      int i;
+       for (i = 0; i < rb->ring_cnt; i++) {
+               struct ring *ring = &rb->rings[i];
+@@ -259,18 +263,24 @@ int ring_buffer__consume(struct ring_buffer *rb)
+                       return err;
+               res += err;
+       }
++      if (res > INT_MAX)
++              return INT_MAX;
+       return res;
+ }
+ /* Poll for available data and consume records, if any are available.
+- * Returns number of records consumed, or negative number, if any of the
+- * registered callbacks returned error.
++ * Returns number of records consumed (or INT_MAX, whichever is less), or
++ * negative number, if any of the registered callbacks returned error.
+  */
+ int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms)
+ {
+-      int i, cnt, err, res = 0;
++      int i, cnt;
++      int64_t err, res = 0;
+       cnt = epoll_wait(rb->epoll_fd, rb->events, rb->ring_cnt, timeout_ms);
++      if (cnt < 0)
++              return -errno;
++
+       for (i = 0; i < cnt; i++) {
+               __u32 ring_id = rb->events[i].data.fd;
+               struct ring *ring = &rb->rings[ring_id];
+@@ -280,7 +290,9 @@ int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms)
+                       return err;
+               res += err;
+       }
+-      return cnt < 0 ? -errno : res;
++      if (res > INT_MAX)
++              return INT_MAX;
++      return res;
+ }
+ /* Get an fd that can be used to sleep until data is available in the ring(s) */
+-- 
+2.30.2
+
diff --git a/queue-5.11/mac80211-clear-the-beacon-s-crc-after-channel-switch.patch b/queue-5.11/mac80211-clear-the-beacon-s-crc-after-channel-switch.patch
new file mode 100644 (file)
index 0000000..ba7385b
--- /dev/null
@@ -0,0 +1,52 @@
+From 620ff6d32048b509c335b70f5787413e4e99ee03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 14:31:25 +0200
+Subject: mac80211: clear the beacon's CRC after channel switch
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+[ Upstream commit d6843d1ee283137723b4a8c76244607ce6db1951 ]
+
+After channel switch, we should consider any beacon with a
+CSA IE as a new switch. If the CSA IE is a leftover from
+before the switch that the AP forgot to remove, we'll get
+a CSA-to-Self.
+
+This caused issues in iwlwifi where the firmware saw a beacon
+with a CSA-to-Self with mode = 1 on the new channel after a
+switch. The firmware considered this a new switch and closed
+its queues. Since the beacon didn't change between before and
+after the switch, we wouldn't handle it (the CRC is the same)
+and we wouldn't let the firmware open its queues again or
+disconnect if the CSA IE stays for too long.
+
+Clear the CRC valid state after we switch to make sure that
+we handle the beacon and handle the CSA IE as required.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Link: https://lore.kernel.org/r/20210408143124.b9e68aa98304.I465afb55ca2c7d59f7bf610c6046a1fd732b4c28@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/mlme.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index b7155b078b19..c9eb75603576 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1295,6 +1295,11 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata)
+       sdata->vif.csa_active = false;
+       ifmgd->csa_waiting_bcn = false;
++      /*
++       * If the CSA IE is still present on the beacon after the switch,
++       * we need to consider it as a new CSA (possibly to self).
++       */
++      ifmgd->beacon_crc_valid = false;
+       ret = drv_post_channel_switch(sdata);
+       if (ret) {
+-- 
+2.30.2
+
diff --git a/queue-5.11/mac80211-properly-drop-the-connection-in-case-of-inv.patch b/queue-5.11/mac80211-properly-drop-the-connection-in-case-of-inv.patch
new file mode 100644 (file)
index 0000000..38cd525
--- /dev/null
@@ -0,0 +1,46 @@
+From 167d26a4a5b14a09a9500348cf4afc8f2d19940c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Apr 2021 12:40:16 +0300
+Subject: mac80211: properly drop the connection in case of invalid CSA IE
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+[ Upstream commit 253907ab8bc0818639af382f6398810fa1f022b3 ]
+
+In case the frequency is invalid, ieee80211_parse_ch_switch_ie
+will fail and we may not even reach the check in
+ieee80211_sta_process_chanswitch. Drop the connection
+in case ieee80211_parse_ch_switch_ie failed, but still
+take into account the CSA mode to remember not to send
+a deauth frame in case if it is forbidden to.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20210409123755.34712ef96a0a.I75d7ad7f1d654e8b0aa01cd7189ff00a510512b3@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/mlme.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index c9eb75603576..fe71c1ca984a 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1405,11 +1405,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
+               ch_switch.delay = csa_ie.max_switch_time;
+       }
+-      if (res < 0) {
+-              ieee80211_queue_work(&local->hw,
+-                                   &ifmgd->csa_connection_drop_work);
+-              return;
+-      }
++      if (res < 0)
++              goto lock_and_drop_connection;
+       if (beacon && sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) {
+               if (res)
+-- 
+2.30.2
+
diff --git a/queue-5.11/mac80211-set-priority-and-queue-mapping-for-injected.patch b/queue-5.11/mac80211-set-priority-and-queue-mapping-for-injected.patch
new file mode 100644 (file)
index 0000000..e3db951
--- /dev/null
@@ -0,0 +1,68 @@
+From 4a0f61eeaea31480109073790c15f670b741fb51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Apr 2021 18:44:55 +0200
+Subject: mac80211: Set priority and queue mapping for injected frames
+
+From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
+
+[ Upstream commit 96a7109a16665255b65d021e24141c2edae0e202 ]
+
+Some drivers, for example mt76, use the skb priority field, and
+expects that to be consistent with the skb queue mapping. On some
+frame injection code paths that was not true, and it broke frame
+injection. Now the skb queue mapping is set according to the skb
+priority value when the frame is injected. The skb priority value
+is also derived from the frame data for all frame types, as it
+was done prior to commit dbd50a851c50 (only allocate one queue
+when using iTXQs). Fixes frame injection with the mt76 driver on
+MT7610E chipset.
+
+Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
+Link: https://lore.kernel.org/r/20210401164455.978245-1-johan.almbladh@anyfinetworks.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/tx.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 64fae4f645f5..f6bfa0ce262c 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -2269,17 +2269,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
+                                                   payload[7]);
+       }
+-      /* Initialize skb->priority for QoS frames. If the DONT_REORDER flag
+-       * is set, stick to the default value for skb->priority to assure
+-       * frames injected with this flag are not reordered relative to each
+-       * other.
+-       */
+-      if (ieee80211_is_data_qos(hdr->frame_control) &&
+-          !(info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER)) {
+-              u8 *p = ieee80211_get_qos_ctl(hdr);
+-              skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
+-      }
+-
+       rcu_read_lock();
+       /*
+@@ -2343,6 +2332,15 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
+       info->band = chandef->chan->band;
++      /* Initialize skb->priority according to frame type and TID class,
++       * with respect to the sub interface that the frame will actually
++       * be transmitted on. If the DONT_REORDER flag is set, the original
++       * skb-priority is preserved to assure frames injected with this
++       * flag are not reordered relative to each other.
++       */
++      ieee80211_select_queue_80211(sdata, skb, hdr);
++      skb_set_queue_mapping(skb, ieee80211_ac_from_tid(skb->priority));
++
+       /* remove the injection radiotap header */
+       skb_pull(skb, len_rthdr);
+-- 
+2.30.2
+
diff --git a/queue-5.11/mips-loongson64-use-_cache_uncached-instead-of-_cach.patch b/queue-5.11/mips-loongson64-use-_cache_uncached-instead-of-_cach.patch
new file mode 100644 (file)
index 0000000..6703d55
--- /dev/null
@@ -0,0 +1,68 @@
+From 311c433193652f2ee19c980a04607872916678c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 17:25:12 +0800
+Subject: MIPS: Loongson64: Use _CACHE_UNCACHED instead of
+ _CACHE_UNCACHED_ACCELERATED
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+[ Upstream commit 5e65c52ec716af6e8f51dacdaeb4a4d872249af1 ]
+
+Loongson64 processors have a writecombine issue that maybe failed to
+write back framebuffer used with ATI Radeon or AMD GPU at times, after
+commit 8a08e50cee66 ("drm: Permit video-buffers writecombine mapping
+for MIPS"), there exists some errors such as blurred screen and lockup,
+and so on.
+
+[   60.958721] radeon 0000:03:00.0: ring 0 stalled for more than 10079msec
+[   60.965315] radeon 0000:03:00.0: GPU lockup (current fence id 0x0000000000000112 last fence id 0x000000000000011d on ring 0)
+[   60.976525] radeon 0000:03:00.0: ring 3 stalled for more than 10086msec
+[   60.983156] radeon 0000:03:00.0: GPU lockup (current fence id 0x0000000000000374 last fence id 0x00000000000003a8 on ring 3)
+
+As discussed earlier [1], it might be better to disable writecombine
+on the CPU detection side because the root cause is unknown now.
+
+Actually, this patch is a temporary solution to just make it work well,
+it is not a proper and final solution, I hope someone will have a better
+solution to fix this issue in the future.
+
+[1] https://lore.kernel.org/patchwork/patch/1285542/
+
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/kernel/cpu-probe.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
+index 21794db53c05..8895eb6568ca 100644
+--- a/arch/mips/kernel/cpu-probe.c
++++ b/arch/mips/kernel/cpu-probe.c
+@@ -1743,7 +1743,6 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
+                       set_isa(c, MIPS_CPU_ISA_M64R2);
+                       break;
+               }
+-              c->writecombine = _CACHE_UNCACHED_ACCELERATED;
+               c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_EXT |
+                               MIPS_ASE_LOONGSON_EXT2);
+               break;
+@@ -1773,7 +1772,6 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
+                * register, we correct it here.
+                */
+               c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
+-              c->writecombine = _CACHE_UNCACHED_ACCELERATED;
+               c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
+                       MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
+               c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */
+@@ -1784,7 +1782,6 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
+               set_elf_platform(cpu, "loongson3a");
+               set_isa(c, MIPS_CPU_ISA_M64R2);
+               decode_cpucfg(c);
+-              c->writecombine = _CACHE_UNCACHED_ACCELERATED;
+               break;
+       default:
+               panic("Unknown Loongson Processor ID!");
+-- 
+2.30.2
+
diff --git a/queue-5.11/mm-gup-check-every-subpage-of-a-compound-page-during.patch b/queue-5.11/mm-gup-check-every-subpage-of-a-compound-page-during.patch
new file mode 100644 (file)
index 0000000..868eafe
--- /dev/null
@@ -0,0 +1,108 @@
+From a88cc2c6c24277fb559c2e7fe4d6bd51eb0d7fa8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 18:38:42 -0700
+Subject: mm/gup: check every subpage of a compound page during isolation
+
+From: Pavel Tatashin <pasha.tatashin@soleen.com>
+
+[ Upstream commit 83c02c23d0747a7bdcd71f99a538aacec94b146c ]
+
+When pages are isolated in check_and_migrate_movable_pages() we skip
+compound number of pages at a time.  However, as Jason noted, it is not
+necessary correct that pages[i] corresponds to the pages that we
+skipped.  This is because it is possible that the addresses in this
+range had split_huge_pmd()/split_huge_pud(), and these functions do not
+update the compound page metadata.
+
+The problem can be reproduced if something like this occurs:
+
+1. User faulted huge pages.
+2. split_huge_pmd() was called for some reason
+3. User has unmapped some sub-pages in the range
+4. User tries to longterm pin the addresses.
+
+The resulting pages[i] might end-up having pages which are not compound
+size page aligned.
+
+Link: https://lkml.kernel.org/r/20210215161349.246722-3-pasha.tatashin@soleen.com
+Fixes: aa712399c1e8 ("mm/gup: speed up check_and_migrate_cma_pages() on huge page")
+Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
+Reported-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Ira Weiny <ira.weiny@intel.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Sasha Levin <sashal@kernel.org>
+Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Cc: Tyler Hicks <tyhicks@linux.microsoft.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+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/gup.c | 19 +++++++------------
+ 1 file changed, 7 insertions(+), 12 deletions(-)
+
+diff --git a/mm/gup.c b/mm/gup.c
+index e4c224cd9661..84d392886d85 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1549,26 +1549,23 @@ static long check_and_migrate_cma_pages(struct mm_struct *mm,
+                                       unsigned int gup_flags)
+ {
+       unsigned long i;
+-      unsigned long step;
+       bool drain_allow = true;
+       bool migrate_allow = true;
+       LIST_HEAD(cma_page_list);
+       long ret = nr_pages;
++      struct page *prev_head, *head;
+       struct migration_target_control mtc = {
+               .nid = NUMA_NO_NODE,
+               .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_NOWARN,
+       };
+ check_again:
+-      for (i = 0; i < nr_pages;) {
+-
+-              struct page *head = compound_head(pages[i]);
+-
+-              /*
+-               * gup may start from a tail page. Advance step by the left
+-               * part.
+-               */
+-              step = compound_nr(head) - (pages[i] - head);
++      prev_head = NULL;
++      for (i = 0; i < nr_pages; i++) {
++              head = compound_head(pages[i]);
++              if (head == prev_head)
++                      continue;
++              prev_head = head;
+               /*
+                * If we get a page from the CMA zone, since we are going to
+                * be pinning these entries, we might as well move them out
+@@ -1592,8 +1589,6 @@ check_again:
+                               }
+                       }
+               }
+-
+-              i += step;
+       }
+       if (!list_empty(&cma_page_list)) {
+-- 
+2.30.2
+
diff --git a/queue-5.11/mm-gup-check-for-isolation-errors.patch b/queue-5.11/mm-gup-check-for-isolation-errors.patch
new file mode 100644 (file)
index 0000000..f899f93
--- /dev/null
@@ -0,0 +1,155 @@
+From 5709de99254df6fe516ddd4bfd439548a701f2de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 18:38:49 -0700
+Subject: mm/gup: check for isolation errors
+
+From: Pavel Tatashin <pasha.tatashin@soleen.com>
+
+[ Upstream commit 6e7f34ebb8d25d71ce7f4580ba3cbfc10b895580 ]
+
+It is still possible that we pin movable CMA pages if there are
+isolation errors and cma_page_list stays empty when we check again.
+
+Check for isolation errors, and return success only when there are no
+isolation errors, and cma_page_list is empty after checking.
+
+Because isolation errors are transient, we retry indefinitely.
+
+Link: https://lkml.kernel.org/r/20210215161349.246722-5-pasha.tatashin@soleen.com
+Fixes: 9a4e9f3b2d73 ("mm: update get_user_pages_longterm to migrate pages allocated from CMA region")
+Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Ira Weiny <ira.weiny@intel.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Sasha Levin <sashal@kernel.org>
+Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Cc: Tyler Hicks <tyhicks@linux.microsoft.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+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/gup.c | 60 ++++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 34 insertions(+), 26 deletions(-)
+
+diff --git a/mm/gup.c b/mm/gup.c
+index 2d7a567b4056..0cdb93e98d00 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1548,8 +1548,8 @@ static long check_and_migrate_cma_pages(struct mm_struct *mm,
+                                       struct vm_area_struct **vmas,
+                                       unsigned int gup_flags)
+ {
+-      unsigned long i;
+-      bool drain_allow = true;
++      unsigned long i, isolation_error_count;
++      bool drain_allow;
+       LIST_HEAD(cma_page_list);
+       long ret = nr_pages;
+       struct page *prev_head, *head;
+@@ -1560,6 +1560,8 @@ static long check_and_migrate_cma_pages(struct mm_struct *mm,
+ check_again:
+       prev_head = NULL;
++      isolation_error_count = 0;
++      drain_allow = true;
+       for (i = 0; i < nr_pages; i++) {
+               head = compound_head(pages[i]);
+               if (head == prev_head)
+@@ -1571,25 +1573,35 @@ check_again:
+                * of the CMA zone if possible.
+                */
+               if (is_migrate_cma_page(head)) {
+-                      if (PageHuge(head))
+-                              isolate_huge_page(head, &cma_page_list);
+-                      else {
++                      if (PageHuge(head)) {
++                              if (!isolate_huge_page(head, &cma_page_list))
++                                      isolation_error_count++;
++                      } else {
+                               if (!PageLRU(head) && drain_allow) {
+                                       lru_add_drain_all();
+                                       drain_allow = false;
+                               }
+-                              if (!isolate_lru_page(head)) {
+-                                      list_add_tail(&head->lru, &cma_page_list);
+-                                      mod_node_page_state(page_pgdat(head),
+-                                                          NR_ISOLATED_ANON +
+-                                                          page_is_file_lru(head),
+-                                                          thp_nr_pages(head));
++                              if (isolate_lru_page(head)) {
++                                      isolation_error_count++;
++                                      continue;
+                               }
++                              list_add_tail(&head->lru, &cma_page_list);
++                              mod_node_page_state(page_pgdat(head),
++                                                  NR_ISOLATED_ANON +
++                                                  page_is_file_lru(head),
++                                                  thp_nr_pages(head));
+                       }
+               }
+       }
++      /*
++       * If list is empty, and no isolation errors, means that all pages are
++       * in the correct zone.
++       */
++      if (list_empty(&cma_page_list) && !isolation_error_count)
++              return ret;
++
+       if (!list_empty(&cma_page_list)) {
+               /*
+                * drop the above get_user_pages reference.
+@@ -1609,23 +1621,19 @@ check_again:
+                       return ret > 0 ? -ENOMEM : ret;
+               }
+-              /*
+-               * We did migrate all the pages, Try to get the page references
+-               * again migrating any new CMA pages which we failed to isolate
+-               * earlier.
+-               */
+-              ret = __get_user_pages_locked(mm, start, nr_pages,
+-                                                 pages, vmas, NULL,
+-                                                 gup_flags);
+-
+-              if (ret > 0) {
+-                      nr_pages = ret;
+-                      drain_allow = true;
+-                      goto check_again;
+-              }
++              /* We unpinned pages before migration, pin them again */
++              ret = __get_user_pages_locked(mm, start, nr_pages, pages, vmas,
++                                            NULL, gup_flags);
++              if (ret <= 0)
++                      return ret;
++              nr_pages = ret;
+       }
+-      return ret;
++      /*
++       * check again because pages were unpinned, and we also might have
++       * had isolation errors and need more pages to migrate.
++       */
++      goto check_again;
+ }
+ #else
+ static long check_and_migrate_cma_pages(struct mm_struct *mm,
+-- 
+2.30.2
+
diff --git a/queue-5.11/mm-gup-return-an-error-on-migration-failure.patch b/queue-5.11/mm-gup-return-an-error-on-migration-failure.patch
new file mode 100644 (file)
index 0000000..bf8e735
--- /dev/null
@@ -0,0 +1,96 @@
+From a1c18b035ca65c7b13302ecb31b3963e1d5b7e64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 18:38:46 -0700
+Subject: mm/gup: return an error on migration failure
+
+From: Pavel Tatashin <pasha.tatashin@soleen.com>
+
+[ Upstream commit f0f4463837da17a89d965dcbe4e411629dbcf308 ]
+
+When migration failure occurs, we still pin pages, which means that we
+may pin CMA movable pages which should never be the case.
+
+Instead return an error without pinning pages when migration failure
+happens.
+
+No need to retry migrating, because migrate_pages() already retries 10
+times.
+
+Link: https://lkml.kernel.org/r/20210215161349.246722-4-pasha.tatashin@soleen.com
+Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Ira Weiny <ira.weiny@intel.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Sasha Levin <sashal@kernel.org>
+Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Cc: Tyler Hicks <tyhicks@linux.microsoft.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+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/gup.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/mm/gup.c b/mm/gup.c
+index 84d392886d85..2d7a567b4056 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1550,7 +1550,6 @@ static long check_and_migrate_cma_pages(struct mm_struct *mm,
+ {
+       unsigned long i;
+       bool drain_allow = true;
+-      bool migrate_allow = true;
+       LIST_HEAD(cma_page_list);
+       long ret = nr_pages;
+       struct page *prev_head, *head;
+@@ -1601,17 +1600,15 @@ check_again:
+                       for (i = 0; i < nr_pages; i++)
+                               put_page(pages[i]);
+-              if (migrate_pages(&cma_page_list, alloc_migration_target, NULL,
+-                      (unsigned long)&mtc, MIGRATE_SYNC, MR_CONTIG_RANGE)) {
+-                      /*
+-                       * some of the pages failed migration. Do get_user_pages
+-                       * without migration.
+-                       */
+-                      migrate_allow = false;
+-
++              ret = migrate_pages(&cma_page_list, alloc_migration_target,
++                                  NULL, (unsigned long)&mtc, MIGRATE_SYNC,
++                                  MR_CONTIG_RANGE);
++              if (ret) {
+                       if (!list_empty(&cma_page_list))
+                               putback_movable_pages(&cma_page_list);
++                      return ret > 0 ? -ENOMEM : ret;
+               }
++
+               /*
+                * We did migrate all the pages, Try to get the page references
+                * again migrating any new CMA pages which we failed to isolate
+@@ -1621,7 +1618,7 @@ check_again:
+                                                  pages, vmas, NULL,
+                                                  gup_flags);
+-              if ((ret > 0) && migrate_allow) {
++              if (ret > 0) {
+                       nr_pages = ret;
+                       drain_allow = true;
+                       goto check_again;
+-- 
+2.30.2
+
diff --git a/queue-5.11/mm-hugeltb-handle-the-error-case-in-hugetlb_fix_rese.patch b/queue-5.11/mm-hugeltb-handle-the-error-case-in-hugetlb_fix_rese.patch
new file mode 100644 (file)
index 0000000..83be51d
--- /dev/null
@@ -0,0 +1,57 @@
+From dfaaf9ff2fb5e7833fcf0f2520fde5a20adc48e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 18:34:38 -0700
+Subject: mm/hugeltb: handle the error case in hugetlb_fix_reserve_counts()
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit da56388c4397878a65b74f7fe97760f5aa7d316b ]
+
+A rare out of memory error would prevent removal of the reserve map region
+for a page.  hugetlb_fix_reserve_counts() handles this rare case to avoid
+dangling with incorrect counts.  Unfortunately, hugepage_subpool_get_pages
+and hugetlb_acct_memory could possibly fail too.  We should correctly
+handle these cases.
+
+Link: https://lkml.kernel.org/r/20210410072348.20437-5-linmiaohe@huawei.com
+Fixes: b5cec28d36f5 ("hugetlbfs: truncate_hugepages() takes a range of pages")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Feilong Lin <linfeilong@huawei.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.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/hugetlb.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 8e89b277ffcc..19c245b96bd1 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -745,13 +745,20 @@ void hugetlb_fix_reserve_counts(struct inode *inode)
+ {
+       struct hugepage_subpool *spool = subpool_inode(inode);
+       long rsv_adjust;
++      bool reserved = false;
+       rsv_adjust = hugepage_subpool_get_pages(spool, 1);
+-      if (rsv_adjust) {
++      if (rsv_adjust > 0) {
+               struct hstate *h = hstate_inode(inode);
+-              hugetlb_acct_memory(h, 1);
++              if (!hugetlb_acct_memory(h, 1))
++                      reserved = true;
++      } else if (!rsv_adjust) {
++              reserved = true;
+       }
++
++      if (!reserved)
++              pr_warn("hugetlb: Huge Page Reserved count may go negative.\n");
+ }
+ /*
+-- 
+2.30.2
+
diff --git a/queue-5.11/mm-migrate.c-fix-potential-indeterminate-pte-entry-i.patch b/queue-5.11/mm-migrate.c-fix-potential-indeterminate-pte-entry-i.patch
new file mode 100644 (file)
index 0000000..3840bd6
--- /dev/null
@@ -0,0 +1,50 @@
+From 619d7068003c88823cdc398a97affb558445ebe4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 18:37:10 -0700
+Subject: mm/migrate.c: fix potential indeterminate pte entry in
+ migrate_vma_insert_page()
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 34f5e9b9d1990d286199084efa752530ee3d8297 ]
+
+If the zone device page does not belong to un-addressable device memory,
+the variable entry will be uninitialized and lead to indeterminate pte
+entry ultimately.  Fix this unexpected case and warn about it.
+
+Link: https://lkml.kernel.org/r/20210325131524.48181-4-linmiaohe@huawei.com
+Fixes: df6ad69838fc ("mm/device-public-memory: device memory cache coherent with CPU")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Cc: Alistair Popple <apopple@nvidia.com>
+Cc: Jerome Glisse <jglisse@redhat.com>
+Cc: Rafael Aquini <aquini@redhat.com>
+Cc: Yang Shi <shy828301@gmail.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/migrate.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 20ca887ea769..4754f2489d78 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -2967,6 +2967,13 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
+                       swp_entry = make_device_private_entry(page, vma->vm_flags & VM_WRITE);
+                       entry = swp_entry_to_pte(swp_entry);
++              } else {
++                      /*
++                       * For now we only support migrating to un-addressable
++                       * device memory.
++                       */
++                      pr_warn_once("Unsupported ZONE_DEVICE page type.\n");
++                      goto abort;
+               }
+       } else {
+               entry = mk_pte(page, vma->vm_page_prot);
+-- 
+2.30.2
+
diff --git a/queue-5.11/mptcp-fix-splat-when-closing-unaccepted-socket.patch b/queue-5.11/mptcp-fix-splat-when-closing-unaccepted-socket.patch
new file mode 100644 (file)
index 0000000..c99576a
--- /dev/null
@@ -0,0 +1,50 @@
+From 0727a5c8c27b21b8ccf27573578cb7d32de98f6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 17:16:38 -0700
+Subject: mptcp: fix splat when closing unaccepted socket
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 578c18eff1627d6a911f08f4cf351eca41fdcc7d ]
+
+If userspace exits before calling accept() on a listener that had at least
+one new connection ready, we get:
+
+   Attempt to release TCP socket in state 8
+
+This happens because the mptcp socket gets cloned when the TCP connection
+is ready, but the socket is never exposed to userspace.
+
+The client additionally sends a DATA_FIN, which brings connection into
+CLOSE_WAIT state.  This in turn prevents the orphan+state reset fixup
+in mptcp_sock_destruct() from doing its job.
+
+Fixes: 3721b9b64676b ("mptcp: Track received DATA_FIN sequence number and add related helpers")
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/185
+Tested-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Link: https://lore.kernel.org/r/20210507001638.225468-1-mathew.j.martineau@linux.intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index f97f29df4505..371a114f3a5f 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -479,8 +479,7 @@ static void mptcp_sock_destruct(struct sock *sk)
+        * ESTABLISHED state and will not have the SOCK_DEAD flag.
+        * Both result in warnings from inet_sock_destruct.
+        */
+-
+-      if (sk->sk_state == TCP_ESTABLISHED) {
++      if ((1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) {
+               sk->sk_state = TCP_CLOSE;
+               WARN_ON_ONCE(sk->sk_socket);
+               sock_orphan(sk);
+-- 
+2.30.2
+
diff --git a/queue-5.11/mt76-mt7615-fix-entering-driver-own-state-on-mt7663.patch b/queue-5.11/mt76-mt7615-fix-entering-driver-own-state-on-mt7663.patch
new file mode 100644 (file)
index 0000000..5d56662
--- /dev/null
@@ -0,0 +1,47 @@
+From dedf69ddacd7e8f88e70979d715f50ba268c4784 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 21:07:53 +0200
+Subject: mt76: mt7615: fix entering driver-own state on mt7663
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 5c7d374444afdeb9dd534a37c4f6c13af032da0c ]
+
+Fixes hardware wakeup issues
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+index c13547841a4e..4c7083d17418 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+@@ -291,12 +291,20 @@ static int mt7615_mcu_drv_pmctrl(struct mt7615_dev *dev)
+       u32 addr;
+       int err;
+-      addr = is_mt7663(mdev) ? MT_PCIE_DOORBELL_PUSH : MT_CFG_LPCR_HOST;
++      if (is_mt7663(mdev)) {
++              /* Clear firmware own via N9 eint */
++              mt76_wr(dev, MT_PCIE_DOORBELL_PUSH, MT_CFG_LPCR_HOST_DRV_OWN);
++              mt76_poll(dev, MT_CONN_ON_MISC, MT_CFG_LPCR_HOST_FW_OWN, 0, 3000);
++
++              addr = MT_CONN_HIF_ON_LPCTL;
++      } else {
++              addr = MT_CFG_LPCR_HOST;
++      }
++
+       mt76_wr(dev, addr, MT_CFG_LPCR_HOST_DRV_OWN);
+       mt7622_trigger_hif_int(dev, true);
+-      addr = is_mt7663(mdev) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
+       err = !mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN, 0, 3000);
+       mt7622_trigger_hif_int(dev, false);
+-- 
+2.30.2
+
diff --git a/queue-5.11/mt76-mt7615-fix-key-set-delete-issues.patch b/queue-5.11/mt76-mt7615-fix-key-set-delete-issues.patch
new file mode 100644 (file)
index 0000000..360e57b
--- /dev/null
@@ -0,0 +1,257 @@
+From 8e65ce317d2f71f3d1b687ccb62c3d6caa812b0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Feb 2021 17:07:27 +0100
+Subject: mt76: mt7615: fix key set/delete issues
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 730d6d0da8d8f5905faafe645a5b3c08ac3f5a8f ]
+
+There were multiple issues in the current key set/remove code:
+- deleting a key with the previous key index deletes the current key
+- BIP key would only be uploaded correctly initially and corrupted on rekey
+
+Rework the code to better keep track of multiple keys and check for the
+key index before deleting the current key
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76.h     |  1 +
+ .../net/wireless/mediatek/mt76/mt7615/mac.c   | 97 ++++++++++---------
+ .../net/wireless/mediatek/mt76/mt7615/main.c  | 18 ++--
+ 3 files changed, 65 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index 5da6b74687ed..7a551811d203 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -222,6 +222,7 @@ struct mt76_wcid {
+       u16 idx;
+       u8 hw_key_idx;
++      u8 hw_key_idx2;
+       u8 sta:1;
+       u8 ext_phy:1;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+index 2cb24c26a074..b2f6cda5a681 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+@@ -1031,7 +1031,7 @@ EXPORT_SYMBOL_GPL(mt7615_mac_set_rates);
+ static int
+ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+                          struct ieee80211_key_conf *key,
+-                         enum mt7615_cipher_type cipher,
++                         enum mt7615_cipher_type cipher, u16 cipher_mask,
+                          enum set_key_cmd cmd)
+ {
+       u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx) + 30 * 4;
+@@ -1048,22 +1048,22 @@ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+                       memcpy(data + 16, key->key + 24, 8);
+                       memcpy(data + 24, key->key + 16, 8);
+               } else {
+-                      if (cipher != MT_CIPHER_BIP_CMAC_128 && wcid->cipher)
+-                              memmove(data + 16, data, 16);
+-                      if (cipher != MT_CIPHER_BIP_CMAC_128 || !wcid->cipher)
++                      if (cipher_mask == BIT(cipher))
+                               memcpy(data, key->key, key->keylen);
+-                      else if (cipher == MT_CIPHER_BIP_CMAC_128)
++                      else if (cipher != MT_CIPHER_BIP_CMAC_128)
++                              memcpy(data, key->key, 16);
++                      if (cipher == MT_CIPHER_BIP_CMAC_128)
+                               memcpy(data + 16, key->key, 16);
+               }
+       } else {
+-              if (wcid->cipher & ~BIT(cipher)) {
+-                      if (cipher != MT_CIPHER_BIP_CMAC_128)
+-                              memmove(data, data + 16, 16);
++              if (cipher == MT_CIPHER_BIP_CMAC_128)
+                       memset(data + 16, 0, 16);
+-              } else {
++              else if (cipher_mask)
++                      memset(data, 0, 16);
++              if (!cipher_mask)
+                       memset(data, 0, sizeof(data));
+-              }
+       }
++
+       mt76_wr_copy(dev, addr, data, sizeof(data));
+       return 0;
+@@ -1071,7 +1071,7 @@ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+ static int
+ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+-                        enum mt7615_cipher_type cipher,
++                        enum mt7615_cipher_type cipher, u16 cipher_mask,
+                         int keyidx, enum set_key_cmd cmd)
+ {
+       u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx), w0, w1;
+@@ -1081,20 +1081,23 @@ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+       w0 = mt76_rr(dev, addr);
+       w1 = mt76_rr(dev, addr + 4);
+-      if (cmd == SET_KEY) {
+-              w0 |= MT_WTBL_W0_RX_KEY_VALID |
+-                    FIELD_PREP(MT_WTBL_W0_RX_IK_VALID,
+-                               cipher == MT_CIPHER_BIP_CMAC_128);
+-              if (cipher != MT_CIPHER_BIP_CMAC_128 ||
+-                  !wcid->cipher)
+-                      w0 |= FIELD_PREP(MT_WTBL_W0_KEY_IDX, keyidx);
+-      }  else {
+-              if (!(wcid->cipher & ~BIT(cipher)))
+-                      w0 &= ~(MT_WTBL_W0_RX_KEY_VALID |
+-                              MT_WTBL_W0_KEY_IDX);
+-              if (cipher == MT_CIPHER_BIP_CMAC_128)
+-                      w0 &= ~MT_WTBL_W0_RX_IK_VALID;
++
++      if (cipher_mask)
++              w0 |= MT_WTBL_W0_RX_KEY_VALID;
++      else
++              w0 &= ~(MT_WTBL_W0_RX_KEY_VALID | MT_WTBL_W0_KEY_IDX);
++      if (cipher_mask & BIT(MT_CIPHER_BIP_CMAC_128))
++              w0 |= MT_WTBL_W0_RX_IK_VALID;
++      else
++              w0 &= ~MT_WTBL_W0_RX_IK_VALID;
++
++      if (cmd == SET_KEY &&
++          (cipher != MT_CIPHER_BIP_CMAC_128 ||
++           cipher_mask == BIT(cipher))) {
++              w0 &= ~MT_WTBL_W0_KEY_IDX;
++              w0 |= FIELD_PREP(MT_WTBL_W0_KEY_IDX, keyidx);
+       }
++
+       mt76_wr(dev, MT_WTBL_RICR0, w0);
+       mt76_wr(dev, MT_WTBL_RICR1, w1);
+@@ -1107,24 +1110,25 @@ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+ static void
+ mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+-                            enum mt7615_cipher_type cipher,
++                            enum mt7615_cipher_type cipher, u16 cipher_mask,
+                             enum set_key_cmd cmd)
+ {
+       u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx);
+-      if (cmd == SET_KEY) {
+-              if (cipher != MT_CIPHER_BIP_CMAC_128 || !wcid->cipher)
+-                      mt76_rmw(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE,
+-                               FIELD_PREP(MT_WTBL_W2_KEY_TYPE, cipher));
+-      } else {
+-              if (cipher != MT_CIPHER_BIP_CMAC_128 &&
+-                  wcid->cipher & BIT(MT_CIPHER_BIP_CMAC_128))
+-                      mt76_rmw(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE,
+-                               FIELD_PREP(MT_WTBL_W2_KEY_TYPE,
+-                                          MT_CIPHER_BIP_CMAC_128));
+-              else if (!(wcid->cipher & ~BIT(cipher)))
+-                      mt76_clear(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE);
++      if (!cipher_mask) {
++              mt76_clear(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE);
++              return;
+       }
++
++      if (cmd != SET_KEY)
++              return;
++
++      if (cipher == MT_CIPHER_BIP_CMAC_128 &&
++          cipher_mask & ~BIT(MT_CIPHER_BIP_CMAC_128))
++              return;
++
++      mt76_rmw(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE,
++               FIELD_PREP(MT_WTBL_W2_KEY_TYPE, cipher));
+ }
+ int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
+@@ -1133,25 +1137,30 @@ int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
+                             enum set_key_cmd cmd)
+ {
+       enum mt7615_cipher_type cipher;
++      u16 cipher_mask = wcid->cipher;
+       int err;
+       cipher = mt7615_mac_get_cipher(key->cipher);
+       if (cipher == MT_CIPHER_NONE)
+               return -EOPNOTSUPP;
+-      mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cmd);
+-      err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cmd);
++      if (cmd == SET_KEY)
++              cipher_mask |= BIT(cipher);
++      else
++              cipher_mask &= ~BIT(cipher);
++
++      mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cipher_mask, cmd);
++      err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cipher_mask,
++                                       cmd);
+       if (err < 0)
+               return err;
+-      err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, key->keyidx, cmd);
++      err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, cipher_mask,
++                                      key->keyidx, cmd);
+       if (err < 0)
+               return err;
+-      if (cmd == SET_KEY)
+-              wcid->cipher |= BIT(cipher);
+-      else
+-              wcid->cipher &= ~BIT(cipher);
++      wcid->cipher = cipher_mask;
+       return 0;
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+index 0ec836af211c..cbfcf00377db 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+@@ -347,7 +347,8 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+       struct mt7615_sta *msta = sta ? (struct mt7615_sta *)sta->drv_priv :
+                                 &mvif->sta;
+       struct mt76_wcid *wcid = &msta->wcid;
+-      int idx = key->keyidx, err;
++      int idx = key->keyidx, err = 0;
++      u8 *wcid_keyidx = &wcid->hw_key_idx;
+       /* The hardware does not support per-STA RX GTK, fallback
+        * to software mode for these.
+@@ -362,6 +363,7 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+       /* fall back to sw encryption for unsupported ciphers */
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_AES_CMAC:
++              wcid_keyidx = &wcid->hw_key_idx2;
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+@@ -379,12 +381,13 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+       mt7615_mutex_acquire(dev);
+-      if (cmd == SET_KEY) {
+-              key->hw_key_idx = wcid->idx;
+-              wcid->hw_key_idx = idx;
+-      } else if (idx == wcid->hw_key_idx) {
+-              wcid->hw_key_idx = -1;
+-      }
++      if (cmd == SET_KEY)
++              *wcid_keyidx = idx;
++      else if (idx == *wcid_keyidx)
++              *wcid_keyidx = -1;
++      else
++              goto out;
++
+       mt76_wcid_key_setup(&dev->mt76, wcid,
+                           cmd == SET_KEY ? key : NULL);
+@@ -393,6 +396,7 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+       else
+               err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
++out:
+       mt7615_mutex_release(dev);
+       return err;
+-- 
+2.30.2
+
diff --git a/queue-5.11/mt76-mt7615-support-loading-eeprom-for-mt7613be.patch b/queue-5.11/mt76-mt7615-support-loading-eeprom-for-mt7613be.patch
new file mode 100644 (file)
index 0000000..e5c8d0f
--- /dev/null
@@ -0,0 +1,38 @@
+From e44f4547d46dae3fd538a333e05a8d5eef4d1710 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Feb 2021 09:59:53 +0100
+Subject: mt76: mt7615: support loading EEPROM for MT7613BE
+
+From: Sander Vanheule <sander@svanheule.net>
+
+[ Upstream commit 858ebf446bee7d5077bd99488aae617908c3f4fe ]
+
+EEPROM blobs for MT7613BE radios start with (little endian) 0x7663,
+which is also the PCI device ID for this device. The EEPROM is required
+for the radio to work at useful power levels, otherwise only the lowest
+power level is available.
+
+Suggested-by: Georgi Vlaev <georgi.vlaev@konsulko.com>
+Tested-by: Stijn Segers <foss@volatilesystems.org>
+Signed-off-by: Sander Vanheule <sander@svanheule.net>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+index 3232ebd5eda6..a31fa2017f52 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+@@ -86,6 +86,7 @@ static int mt7615_check_eeprom(struct mt76_dev *dev)
+       switch (val) {
+       case 0x7615:
+       case 0x7622:
++      case 0x7663:
+               return 0;
+       default:
+               return -EINVAL;
+-- 
+2.30.2
+
diff --git a/queue-5.11/mt76-mt76x0-disable-gtk-offloading.patch b/queue-5.11/mt76-mt76x0-disable-gtk-offloading.patch
new file mode 100644 (file)
index 0000000..a69526b
--- /dev/null
@@ -0,0 +1,46 @@
+From c3bee63f1016ce1b485d9150f637ea908e561987 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Feb 2021 16:09:17 +0100
+Subject: mt76: mt76x0: disable GTK offloading
+
+From: David Bauer <mail@david-bauer.net>
+
+[ Upstream commit 4b36cc6b390f18dbc59a45fb4141f90d7dfe2b23 ]
+
+When operating two VAP on a MT7610 with encryption (PSK2, SAE, OWE),
+only the first one to be created will transmit properly encrypteded
+frames.
+
+All subsequently created VAPs will sent out frames with the payload left
+unencrypted, breaking multicast traffic (ICMP6 NDP) and potentially
+disclosing information to a third party.
+
+Disable GTK offloading and encrypt these frames in software to
+circumvent this issue. THis only seems to be necessary on MT7610 chips,
+as MT7612 is not affected from our testing.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+index 7ac20d3c16d7..aaa597b941cd 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+@@ -447,6 +447,10 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+           !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+               return -EOPNOTSUPP;
++      /* MT76x0 GTK offloading does not work with more than one VIF */
++      if (is_mt76x0(dev) && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
++              return -EOPNOTSUPP;
++
+       msta = sta ? (struct mt76x02_sta *)sta->drv_priv : NULL;
+       wcid = msta ? &msta->wcid : &mvif->group_wcid;
+-- 
+2.30.2
+
diff --git a/queue-5.11/mt76-mt7915-add-wifi-subsystem-reset.patch b/queue-5.11/mt76-mt7915-add-wifi-subsystem-reset.patch
new file mode 100644 (file)
index 0000000..691cdf4
--- /dev/null
@@ -0,0 +1,177 @@
+From 7f42523a820096c28a814c7b4d7d2719ef63ea3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 12:46:09 +0800
+Subject: mt76: mt7915: add wifi subsystem reset
+
+From: Ryder Lee <ryder.lee@mediatek.com>
+
+[ Upstream commit e07419a7dca97dd9bddfe5d099380857c19535f3 ]
+
+Reset wifi subsystem when MCU is already running.
+Fixes firmware download failure after soft reboot on systems where the PCIe
+reset could not be performed properly.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Co-developed-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7915/init.c  | 58 ++++++++++++++++++-
+ .../net/wireless/mediatek/mt76/mt7915/mcu.c   | 15 +----
+ .../net/wireless/mediatek/mt76/mt7915/regs.h  | 13 +++++
+ 3 files changed, 70 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+index 148a92efdd4e..76358f8d42a1 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -4,6 +4,7 @@
+ #include <linux/etherdevice.h>
+ #include "mt7915.h"
+ #include "mac.h"
++#include "mcu.h"
+ #include "eeprom.h"
+ #define CCK_RATE(_idx, _rate) {                                               \
+@@ -282,9 +283,50 @@ static void mt7915_init_work(struct work_struct *work)
+       mt7915_register_ext_phy(dev);
+ }
++static void mt7915_wfsys_reset(struct mt7915_dev *dev)
++{
++      u32 val = MT_TOP_PWR_KEY | MT_TOP_PWR_SW_PWR_ON | MT_TOP_PWR_PWR_ON;
++      u32 reg = mt7915_reg_map_l1(dev, MT_TOP_MISC);
++
++#define MT_MCU_DUMMY_RANDOM   GENMASK(15, 0)
++#define MT_MCU_DUMMY_DEFAULT  GENMASK(31, 16)
++
++      mt76_wr(dev, MT_MCU_WFDMA0_DUMMY_CR, MT_MCU_DUMMY_RANDOM);
++
++      /* change to software control */
++      val |= MT_TOP_PWR_SW_RST;
++      mt76_wr(dev, MT_TOP_PWR_CTRL, val);
++
++      /* reset wfsys */
++      val &= ~MT_TOP_PWR_SW_RST;
++      mt76_wr(dev, MT_TOP_PWR_CTRL, val);
++
++      /* release wfsys then mcu re-excutes romcode */
++      val |= MT_TOP_PWR_SW_RST;
++      mt76_wr(dev, MT_TOP_PWR_CTRL, val);
++
++      /* switch to hw control */
++      val &= ~MT_TOP_PWR_SW_RST;
++      val |= MT_TOP_PWR_HW_CTRL;
++      mt76_wr(dev, MT_TOP_PWR_CTRL, val);
++
++      /* check whether mcu resets to default */
++      if (!mt76_poll_msec(dev, MT_MCU_WFDMA0_DUMMY_CR, MT_MCU_DUMMY_DEFAULT,
++                          MT_MCU_DUMMY_DEFAULT, 1000)) {
++              dev_err(dev->mt76.dev, "wifi subsystem reset failure\n");
++              return;
++      }
++
++      /* wfsys reset won't clear host registers */
++      mt76_clear(dev, reg, MT_TOP_MISC_FW_STATE);
++
++      msleep(100);
++}
++
+ static int mt7915_init_hardware(struct mt7915_dev *dev)
+ {
+       int ret, idx;
++      u32 val;
+       mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
+@@ -294,6 +336,12 @@ static int mt7915_init_hardware(struct mt7915_dev *dev)
+       dev->dbdc_support = !!(mt7915_l1_rr(dev, MT_HW_BOUND) & BIT(5));
++      val = mt76_rr(dev, mt7915_reg_map_l1(dev, MT_TOP_MISC));
++
++      /* If MCU was already running, it is likely in a bad state */
++      if (FIELD_GET(MT_TOP_MISC_FW_STATE, val) > FW_STATE_FW_DOWNLOAD)
++              mt7915_wfsys_reset(dev);
++
+       ret = mt7915_dma_init(dev);
+       if (ret)
+               return ret;
+@@ -307,8 +355,14 @@ static int mt7915_init_hardware(struct mt7915_dev *dev)
+       mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
+       ret = mt7915_mcu_init(dev);
+-      if (ret)
+-              return ret;
++      if (ret) {
++              /* Reset and try again */
++              mt7915_wfsys_reset(dev);
++
++              ret = mt7915_mcu_init(dev);
++              if (ret)
++                      return ret;
++      }
+       ret = mt7915_eeprom_init(dev);
+       if (ret < 0)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 178d615f45c5..db204cbcde96 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -2790,21 +2790,8 @@ out:
+ static int mt7915_load_firmware(struct mt7915_dev *dev)
+ {
++      u32 reg = mt7915_reg_map_l1(dev, MT_TOP_MISC);
+       int ret;
+-      u32 val, reg = mt7915_reg_map_l1(dev, MT_TOP_MISC);
+-
+-      val = FIELD_PREP(MT_TOP_MISC_FW_STATE, FW_STATE_FW_DOWNLOAD);
+-
+-      if (!mt76_poll_msec(dev, reg, MT_TOP_MISC_FW_STATE, val, 1000)) {
+-              /* restart firmware once */
+-              __mt76_mcu_restart(&dev->mt76);
+-              if (!mt76_poll_msec(dev, reg, MT_TOP_MISC_FW_STATE,
+-                                  val, 1000)) {
+-                      dev_err(dev->mt76.dev,
+-                              "Firmware is not ready for download\n");
+-                      return -EIO;
+-              }
+-      }
+       ret = mt7915_load_patch(dev);
+       if (ret)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+index 294cc0769331..12bbe565cdd1 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+@@ -4,6 +4,11 @@
+ #ifndef __MT7915_REGS_H
+ #define __MT7915_REGS_H
++/* MCU WFDMA0 */
++#define MT_MCU_WFDMA0_BASE            0x2000
++#define MT_MCU_WFDMA0(ofs)            (MT_MCU_WFDMA0_BASE + (ofs))
++#define MT_MCU_WFDMA0_DUMMY_CR                MT_MCU_WFDMA0(0x120)
++
+ /* MCU WFDMA1 */
+ #define MT_MCU_WFDMA1_BASE            0x3000
+ #define MT_MCU_WFDMA1(ofs)            (MT_MCU_WFDMA1_BASE + (ofs))
+@@ -376,6 +381,14 @@
+ #define MT_WFDMA1_PCIE1_BUSY_ENA_TX_FIFO1     BIT(1)
+ #define MT_WFDMA1_PCIE1_BUSY_ENA_RX_FIFO      BIT(2)
++#define MT_TOP_RGU_BASE                               0xf0000
++#define MT_TOP_PWR_CTRL                               (MT_TOP_RGU_BASE + (0x0))
++#define MT_TOP_PWR_KEY                                (0x5746 << 16)
++#define MT_TOP_PWR_SW_RST                     BIT(0)
++#define MT_TOP_PWR_SW_PWR_ON                  GENMASK(3, 2)
++#define MT_TOP_PWR_HW_CTRL                    BIT(4)
++#define MT_TOP_PWR_PWR_ON                     BIT(7)
++
+ #define MT_INFRA_CFG_BASE             0xf1000
+ #define MT_INFRA(ofs)                 (MT_INFRA_CFG_BASE + (ofs))
+-- 
+2.30.2
+
diff --git a/queue-5.11/mt76-mt7915-always-check-return-value-from-mt7915_mc.patch b/queue-5.11/mt76-mt7915-always-check-return-value-from-mt7915_mc.patch
new file mode 100644 (file)
index 0000000..0a2d0c3
--- /dev/null
@@ -0,0 +1,69 @@
+From 8f587a97e390f72071b58aa0c00092f0fd6a5261 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Feb 2021 20:30:04 +0100
+Subject: mt76: mt7915: always check return value from
+ mt7915_mcu_alloc_wtbl_req
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 45f93e368211fbbd247e1ece254ffb121e20fa10 ]
+
+As done for mt76_connac_mcu_alloc_wtbl_req, even if this is not a real
+bug since mt7915_mcu_alloc_wtbl_req routine can fails just if nskb is NULL,
+always check return value from mt7915_mcu_alloc_wtbl_req in order to avoid
+possible future mistake.
+
+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/mt7915/mcu.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 35bfa197dff6..178d615f45c5 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -1180,6 +1180,9 @@ mt7915_mcu_sta_ba(struct mt7915_dev *dev,
+       wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, sta_wtbl,
+                                            &skb);
++      if (IS_ERR(wtbl_hdr))
++              return PTR_ERR(wtbl_hdr);
++
+       mt7915_mcu_wtbl_ba_tlv(skb, params, enable, tx, sta_wtbl, wtbl_hdr);
+       ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
+@@ -1696,6 +1699,9 @@ int mt7915_mcu_sta_update_hdr_trans(struct mt7915_dev *dev,
+               return -ENOMEM;
+       wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, NULL, &skb);
++      if (IS_ERR(wtbl_hdr))
++              return PTR_ERR(wtbl_hdr);
++
+       mt7915_mcu_wtbl_hdr_trans_tlv(skb, vif, sta, NULL, wtbl_hdr);
+       return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_WTBL_UPDATE,
+@@ -1720,6 +1726,9 @@ int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+       wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, sta_wtbl,
+                                            &skb);
++      if (IS_ERR(wtbl_hdr))
++              return PTR_ERR(wtbl_hdr);
++
+       mt7915_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_hdr);
+       return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+@@ -2289,6 +2298,9 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+       wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_RESET_AND_SET,
+                                            sta_wtbl, &skb);
++      if (IS_ERR(wtbl_hdr))
++              return PTR_ERR(wtbl_hdr);
++
+       if (enable) {
+               mt7915_mcu_wtbl_generic_tlv(skb, vif, sta, sta_wtbl, wtbl_hdr);
+               mt7915_mcu_wtbl_hdr_trans_tlv(skb, vif, sta, sta_wtbl, wtbl_hdr);
+-- 
+2.30.2
+
diff --git a/queue-5.11/mt76-mt7915-fix-key-set-delete-issue.patch b/queue-5.11/mt76-mt7915-fix-key-set-delete-issue.patch
new file mode 100644 (file)
index 0000000..3599ae6
--- /dev/null
@@ -0,0 +1,76 @@
+From 0a4b6bf613c1114a958277bd87c82a9964c4de49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 21:39:57 +0100
+Subject: mt76: mt7915: fix key set/delete issue
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 1da4fd48d28436f8b690cdc2879603dede6d8355 ]
+
+Deleting a key with the previous key index deletes the current key
+Rework the code to better keep track of multiple keys and check for the
+key index before deleting the current key
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7915/main.c  | 25 +++++++++++++------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+index 0721e9d85b65..2f3527179b7d 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+@@ -314,7 +314,9 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+       struct mt7915_sta *msta = sta ? (struct mt7915_sta *)sta->drv_priv :
+                                 &mvif->sta;
+       struct mt76_wcid *wcid = &msta->wcid;
++      u8 *wcid_keyidx = &wcid->hw_key_idx;
+       int idx = key->keyidx;
++      int err = 0;
+       /* The hardware does not support per-STA RX GTK, fallback
+        * to software mode for these.
+@@ -329,6 +331,7 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+       /* fall back to sw encryption for unsupported ciphers */
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_AES_CMAC:
++              wcid_keyidx = &wcid->hw_key_idx2;
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+@@ -344,16 +347,24 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+               return -EOPNOTSUPP;
+       }
+-      if (cmd == SET_KEY) {
+-              key->hw_key_idx = wcid->idx;
+-              wcid->hw_key_idx = idx;
+-      } else if (idx == wcid->hw_key_idx) {
+-              wcid->hw_key_idx = -1;
+-      }
++      mutex_lock(&dev->mt76.mutex);
++
++      if (cmd == SET_KEY)
++              *wcid_keyidx = idx;
++      else if (idx == *wcid_keyidx)
++              *wcid_keyidx = -1;
++      else
++              goto out;
++
+       mt76_wcid_key_setup(&dev->mt76, wcid,
+                           cmd == SET_KEY ? key : NULL);
+-      return mt7915_mcu_add_key(dev, vif, msta, key, cmd);
++      err = mt7915_mcu_add_key(dev, vif, msta, key, cmd);
++
++out:
++      mutex_unlock(&dev->mt76.mutex);
++
++      return err;
+ }
+ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
+-- 
+2.30.2
+
diff --git a/queue-5.11/mt76-mt7915-fix-txpower-init-for-tssi-off-chips.patch b/queue-5.11/mt76-mt7915-fix-txpower-init-for-tssi-off-chips.patch
new file mode 100644 (file)
index 0000000..01d648e
--- /dev/null
@@ -0,0 +1,63 @@
+From f875f23e9f7a90d8d976c43481cd92f26b92c36e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Apr 2021 10:31:29 +0800
+Subject: mt76: mt7915: fix txpower init for TSSI off chips
+
+From: Shayne Chen <shayne.chen@mediatek.com>
+
+[ Upstream commit a226ccd04c479ccd23d6927c64bad1b441707f70 ]
+
+Fix incorrect txpower init value for TSSI off chips which causes
+too small txpower.
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/mediatek/mt76/mt7915/eeprom.c    | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+index 7a2be3f61398..c3e32555cf24 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+@@ -114,7 +114,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
+                                  struct ieee80211_channel *chan,
+                                  u8 chain_idx)
+ {
+-      int index;
++      int index, target_power;
+       bool tssi_on;
+       if (chain_idx > 3)
+@@ -123,15 +123,22 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
+       tssi_on = mt7915_tssi_enabled(dev, chan->band);
+       if (chan->band == NL80211_BAND_2GHZ) {
+-              index = MT_EE_TX0_POWER_2G + chain_idx * 3 + !tssi_on;
++              index = MT_EE_TX0_POWER_2G + chain_idx * 3;
++              target_power = mt7915_eeprom_read(dev, index);
++
++              if (!tssi_on)
++                      target_power += mt7915_eeprom_read(dev, index + 1);
+       } else {
+-              int group = tssi_on ?
+-                          mt7915_get_channel_group(chan->hw_value) : 8;
++              int group = mt7915_get_channel_group(chan->hw_value);
++
++              index = MT_EE_TX0_POWER_5G + chain_idx * 12;
++              target_power = mt7915_eeprom_read(dev, index + group);
+-              index = MT_EE_TX0_POWER_5G + chain_idx * 12 + group;
++              if (!tssi_on)
++                      target_power += mt7915_eeprom_read(dev, index + 8);
+       }
+-      return mt7915_eeprom_read(dev, index);
++      return target_power;
+ }
+ static const u8 sku_cck_delta_map[] = {
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-bridge-when-suppression-is-enabled-exclude-rarp-.patch b/queue-5.11/net-bridge-when-suppression-is-enabled-exclude-rarp-.patch
new file mode 100644 (file)
index 0000000..d2df1a4
--- /dev/null
@@ -0,0 +1,44 @@
+From be986748c91175eb39e8e3631ac05fa673637ec7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 17:45:27 +0200
+Subject: net: bridge: when suppression is enabled exclude RARP packets
+
+From: Nikolay Aleksandrov <nikolay@nvidia.com>
+
+[ Upstream commit 0353b4a96b7a9f60fe20d1b3ebd4931a4085f91c ]
+
+Recently we had an interop issue where RARP packets got suppressed with
+bridge neigh suppression enabled, but the check in the code was meant to
+suppress GARP. Exclude RARP packets from it which would allow some VMWare
+setups to work, to quote the report:
+"Those RARP packets usually get generated by vMware to notify physical
+switches when vMotion occurs. vMware may use random sip/tip or just use
+sip=tip=0. So the RARP packet sometimes get properly flooded by the vtep
+and other times get dropped by the logic"
+
+Reported-by: Amer Abdalamer <amer@nvidia.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_arp_nd_proxy.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c
+index dfec65eca8a6..3db1def4437b 100644
+--- a/net/bridge/br_arp_nd_proxy.c
++++ b/net/bridge/br_arp_nd_proxy.c
+@@ -160,7 +160,9 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
+       if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {
+               if (p && (p->flags & BR_NEIGH_SUPPRESS))
+                       return;
+-              if (ipv4_is_zeronet(sip) || sip == tip) {
++              if (parp->ar_op != htons(ARPOP_RREQUEST) &&
++                  parp->ar_op != htons(ARPOP_RREPLY) &&
++                  (ipv4_is_zeronet(sip) || sip == tip)) {
+                       /* prevent flooding to neigh suppress ports */
+                       BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
+                       return;
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch b/queue-5.11/net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch
new file mode 100644 (file)
index 0000000..fae4543
--- /dev/null
@@ -0,0 +1,50 @@
+From 18d9b8cffc21e0c9b4910818c33a722f535b4e3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 22:20:54 -0700
+Subject: net: ethernet: mtk_eth_soc: fix RX VLAN offload
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 3f57d8c40fea9b20543cab4da12f4680d2ef182c ]
+
+The VLAN ID in the rx descriptor is only valid if the RX_DMA_VTAG bit is
+set. Fixes frames wrongly marked with VLAN tags.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+[Ilya: fix commit message]
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 6d2d60675ffd..d930fcda9c3b 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1319,7 +1319,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+               skb->protocol = eth_type_trans(skb, netdev);
+               if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
+-                  RX_DMA_VID(trxd.rxd3))
++                  (trxd.rxd2 & RX_DMA_VTAG))
+                       __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+                                              RX_DMA_VID(trxd.rxd3));
+               skb_record_rx_queue(skb, 0);
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+index 454cfcd465fd..73ce1f0f307a 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -295,6 +295,7 @@
+ #define RX_DMA_LSO            BIT(30)
+ #define RX_DMA_PLEN0(_x)      (((_x) & 0x3fff) << 16)
+ #define RX_DMA_GET_PLEN0(_x)  (((_x) >> 16) & 0x3fff)
++#define RX_DMA_VTAG           BIT(15)
+ /* QDMA descriptor rxd3 */
+ #define RX_DMA_VID(_x)                ((_x) & 0xfff)
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-fix-nla_strcmp-to-handle-more-then-one-trailing-.patch b/queue-5.11/net-fix-nla_strcmp-to-handle-more-then-one-trailing-.patch
new file mode 100644 (file)
index 0000000..251c1cb
--- /dev/null
@@ -0,0 +1,52 @@
+From 4ad3fe824392e9e5431a1aa0681486e33b9d6fd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 09:58:31 -0700
+Subject: net: fix nla_strcmp to handle more then one trailing null character
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Å»enczykowski <maze@google.com>
+
+[ Upstream commit 2c16db6c92b0ee4aa61e88366df82169e83c3f7e ]
+
+Android userspace has been using TCA_KIND with a char[IFNAMESIZ]
+many-null-terminated buffer containing the string 'bpf'.
+
+This works on 4.19 and ceases to work on 5.10.
+
+I'm not entirely sure what fixes tag to use, but I think the issue
+was likely introduced in the below mentioned 5.4 commit.
+
+Reported-by: Nucca Chen <nuccachen@google.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
+Cc: Jamal Hadi Salim <jhs@mojatatu.com>
+Cc: Jiri Pirko <jiri@mellanox.com>
+Cc: Jiri Pirko <jiri@resnulli.us>
+Fixes: 62794fc4fbf5 ("net_sched: add max len check for TCA_KIND")
+Change-Id: I66dc281f165a2858fc29a44869a270a2d698a82b
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/nlattr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/nlattr.c b/lib/nlattr.c
+index 5b6116e81f9f..1d051ef66afe 100644
+--- a/lib/nlattr.c
++++ b/lib/nlattr.c
+@@ -828,7 +828,7 @@ int nla_strcmp(const struct nlattr *nla, const char *str)
+       int attrlen = nla_len(nla);
+       int d;
+-      if (attrlen > 0 && buf[attrlen - 1] == '\0')
++      while (attrlen > 0 && buf[attrlen - 1] == '\0')
+               attrlen--;
+       d = attrlen - len;
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-hns3-add-check-for-hns3_nic_state_inited-in-hns3.patch b/queue-5.11/net-hns3-add-check-for-hns3_nic_state_inited-in-hns3.patch
new file mode 100644 (file)
index 0000000..e9e8e31
--- /dev/null
@@ -0,0 +1,44 @@
+From 09da6d136ef3ba6169fbc16872dd31ec3eb2e80c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 16:34:52 +0800
+Subject: net: hns3: add check for HNS3_NIC_STATE_INITED in
+ hns3_reset_notify_up_enet()
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit b4047aac4ec1066bab6c71950623746d7bcf7154 ]
+
+In some cases, the device is not initialized because reset failed.
+If another task calls hns3_reset_notify_up_enet() before reset
+retry, it will cause an error since uninitialized pointer access.
+So add check for HNS3_NIC_STATE_INITED before calling
+hns3_nic_net_open() in hns3_reset_notify_up_enet().
+
+Fixes: bb6b94a896d4 ("net: hns3: Add reset interface implementation in client")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index e9b8b9aa3b95..9c34fd3b65d1 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -4612,6 +4612,11 @@ static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
+       struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev);
+       int ret = 0;
++      if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state)) {
++              netdev_err(kinfo->netdev, "device is not initialized yet\n");
++              return -EFAULT;
++      }
++
+       clear_bit(HNS3_NIC_STATE_RESETTING, &priv->state);
+       if (netif_running(kinfo->netdev)) {
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-hns3-add-handling-for-xmit-skb-with-recursive-fr.patch b/queue-5.11/net-hns3-add-handling-for-xmit-skb-with-recursive-fr.patch
new file mode 100644 (file)
index 0000000..29d0777
--- /dev/null
@@ -0,0 +1,297 @@
+From 0ec18e09de71b2fa6623b387d99944a27195496d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 11:57:50 +0800
+Subject: net: hns3: add handling for xmit skb with recursive fraglist
+
+From: Yunsheng Lin <linyunsheng@huawei.com>
+
+[ Upstream commit d5d5e0193ee8f88efbbc7f1471087255657bc19a ]
+
+Currently hns3 driver only handle the xmit skb with one level of
+fraglist skb, add handling for multi level by calling hns3_tx_bd_num()
+recursively when calculating bd num and calling hns3_fill_skb_to_desc()
+recursively when filling tx desc.
+
+When the skb has a fraglist level of 24, the skb is simply dropped and
+stats.max_recursion_level is added to record the error. Move the stat
+handling from hns3_nic_net_xmit() to hns3_nic_maybe_stop_tx() in order
+to handle different error stat and add the 'max_recursion_level' and
+'hw_limitation' stat.
+
+Note that the max recursive level as 24 is chose according to below:
+commit 48a1df65334b ("skbuff: return -EMSGSIZE in skb_to_sgvec to
+prevent overflow").
+
+And that we are not able to find a testcase to verify the recursive
+fraglist case, so Fixes tag is not provided.
+
+Reported-by: Barry Song <song.bao.hua@hisilicon.com>
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns3/hns3_enet.c   | 115 +++++++++++-------
+ .../net/ethernet/hisilicon/hns3/hns3_enet.h   |   2 +
+ .../ethernet/hisilicon/hns3/hns3_ethtool.c    |   2 +
+ 3 files changed, 78 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index c8a43a725ebc..e9b8b9aa3b95 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -1277,23 +1277,21 @@ static unsigned int hns3_skb_bd_num(struct sk_buff *skb, unsigned int *bd_size,
+ }
+ static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size,
+-                                 u8 max_non_tso_bd_num)
++                                 u8 max_non_tso_bd_num, unsigned int bd_num,
++                                 unsigned int recursion_level)
+ {
++#define HNS3_MAX_RECURSION_LEVEL      24
++
+       struct sk_buff *frag_skb;
+-      unsigned int bd_num = 0;
+       /* If the total len is within the max bd limit */
+-      if (likely(skb->len <= HNS3_MAX_BD_SIZE && !skb_has_frag_list(skb) &&
++      if (likely(skb->len <= HNS3_MAX_BD_SIZE && !recursion_level &&
++                 !skb_has_frag_list(skb) &&
+                  skb_shinfo(skb)->nr_frags < max_non_tso_bd_num))
+               return skb_shinfo(skb)->nr_frags + 1U;
+-      /* The below case will always be linearized, return
+-       * HNS3_MAX_BD_NUM_TSO + 1U to make sure it is linearized.
+-       */
+-      if (unlikely(skb->len > HNS3_MAX_TSO_SIZE ||
+-                   (!skb_is_gso(skb) && skb->len >
+-                    HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num))))
+-              return HNS3_MAX_TSO_BD_NUM + 1U;
++      if (unlikely(recursion_level >= HNS3_MAX_RECURSION_LEVEL))
++              return UINT_MAX;
+       bd_num = hns3_skb_bd_num(skb, bd_size, bd_num);
+@@ -1301,7 +1299,8 @@ static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size,
+               return bd_num;
+       skb_walk_frags(skb, frag_skb) {
+-              bd_num = hns3_skb_bd_num(frag_skb, bd_size, bd_num);
++              bd_num = hns3_tx_bd_num(frag_skb, bd_size, max_non_tso_bd_num,
++                                      bd_num, recursion_level + 1);
+               if (bd_num > HNS3_MAX_TSO_BD_NUM)
+                       return bd_num;
+       }
+@@ -1361,6 +1360,43 @@ void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size)
+               size[i] = skb_frag_size(&shinfo->frags[i]);
+ }
++static int hns3_skb_linearize(struct hns3_enet_ring *ring,
++                            struct sk_buff *skb,
++                            u8 max_non_tso_bd_num,
++                            unsigned int bd_num)
++{
++      /* 'bd_num == UINT_MAX' means the skb' fraglist has a
++       * recursion level of over HNS3_MAX_RECURSION_LEVEL.
++       */
++      if (bd_num == UINT_MAX) {
++              u64_stats_update_begin(&ring->syncp);
++              ring->stats.over_max_recursion++;
++              u64_stats_update_end(&ring->syncp);
++              return -ENOMEM;
++      }
++
++      /* The skb->len has exceeded the hw limitation, linearization
++       * will not help.
++       */
++      if (skb->len > HNS3_MAX_TSO_SIZE ||
++          (!skb_is_gso(skb) && skb->len >
++           HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num))) {
++              u64_stats_update_begin(&ring->syncp);
++              ring->stats.hw_limitation++;
++              u64_stats_update_end(&ring->syncp);
++              return -ENOMEM;
++      }
++
++      if (__skb_linearize(skb)) {
++              u64_stats_update_begin(&ring->syncp);
++              ring->stats.sw_err_cnt++;
++              u64_stats_update_end(&ring->syncp);
++              return -ENOMEM;
++      }
++
++      return 0;
++}
++
+ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
+                                 struct net_device *netdev,
+                                 struct sk_buff *skb)
+@@ -1370,7 +1406,7 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
+       unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U];
+       unsigned int bd_num;
+-      bd_num = hns3_tx_bd_num(skb, bd_size, max_non_tso_bd_num);
++      bd_num = hns3_tx_bd_num(skb, bd_size, max_non_tso_bd_num, 0, 0);
+       if (unlikely(bd_num > max_non_tso_bd_num)) {
+               if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) &&
+                   !hns3_skb_need_linearized(skb, bd_size, bd_num,
+@@ -1379,16 +1415,11 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
+                       goto out;
+               }
+-              if (__skb_linearize(skb))
++              if (hns3_skb_linearize(ring, skb, max_non_tso_bd_num,
++                                     bd_num))
+                       return -ENOMEM;
+               bd_num = hns3_tx_bd_count(skb->len);
+-              if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
+-                  (!skb_is_gso(skb) &&
+-                   bd_num > max_non_tso_bd_num)) {
+-                      trace_hns3_over_max_bd(skb);
+-                      return -ENOMEM;
+-              }
+               u64_stats_update_begin(&ring->syncp);
+               ring->stats.tx_copy++;
+@@ -1412,6 +1443,10 @@ out:
+               return bd_num;
+       }
++      u64_stats_update_begin(&ring->syncp);
++      ring->stats.tx_busy++;
++      u64_stats_update_end(&ring->syncp);
++
+       return -EBUSY;
+ }
+@@ -1459,6 +1494,7 @@ static int hns3_fill_skb_to_desc(struct hns3_enet_ring *ring,
+                                struct sk_buff *skb, enum hns_desc_type type)
+ {
+       unsigned int size = skb_headlen(skb);
++      struct sk_buff *frag_skb;
+       int i, ret, bd_num = 0;
+       if (size) {
+@@ -1483,6 +1519,15 @@ static int hns3_fill_skb_to_desc(struct hns3_enet_ring *ring,
+               bd_num += ret;
+       }
++      skb_walk_frags(skb, frag_skb) {
++              ret = hns3_fill_skb_to_desc(ring, frag_skb,
++                                          DESC_TYPE_FRAGLIST_SKB);
++              if (unlikely(ret < 0))
++                      return ret;
++
++              bd_num += ret;
++      }
++
+       return bd_num;
+ }
+@@ -1513,8 +1558,6 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+       struct hns3_enet_ring *ring = &priv->ring[skb->queue_mapping];
+       struct netdev_queue *dev_queue;
+       int pre_ntu, next_to_use_head;
+-      struct sk_buff *frag_skb;
+-      int bd_num = 0;
+       bool doorbell;
+       int ret;
+@@ -1530,15 +1573,8 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+       ret = hns3_nic_maybe_stop_tx(ring, netdev, skb);
+       if (unlikely(ret <= 0)) {
+               if (ret == -EBUSY) {
+-                      u64_stats_update_begin(&ring->syncp);
+-                      ring->stats.tx_busy++;
+-                      u64_stats_update_end(&ring->syncp);
+                       hns3_tx_doorbell(ring, 0, true);
+                       return NETDEV_TX_BUSY;
+-              } else if (ret == -ENOMEM) {
+-                      u64_stats_update_begin(&ring->syncp);
+-                      ring->stats.sw_err_cnt++;
+-                      u64_stats_update_end(&ring->syncp);
+               }
+               hns3_rl_err(netdev, "xmit error: %d!\n", ret);
+@@ -1551,21 +1587,14 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+       if (unlikely(ret < 0))
+               goto fill_err;
++      /* 'ret < 0' means filling error, 'ret == 0' means skb->len is
++       * zero, which is unlikely, and 'ret > 0' means how many tx desc
++       * need to be notified to the hw.
++       */
+       ret = hns3_fill_skb_to_desc(ring, skb, DESC_TYPE_SKB);
+-      if (unlikely(ret < 0))
++      if (unlikely(ret <= 0))
+               goto fill_err;
+-      bd_num += ret;
+-
+-      skb_walk_frags(skb, frag_skb) {
+-              ret = hns3_fill_skb_to_desc(ring, frag_skb,
+-                                          DESC_TYPE_FRAGLIST_SKB);
+-              if (unlikely(ret < 0))
+-                      goto fill_err;
+-
+-              bd_num += ret;
+-      }
+-
+       pre_ntu = ring->next_to_use ? (ring->next_to_use - 1) :
+                                       (ring->desc_num - 1);
+       ring->desc[pre_ntu].tx.bdtp_fe_sc_vld_ra_ri |=
+@@ -1576,7 +1605,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+       dev_queue = netdev_get_tx_queue(netdev, ring->queue_index);
+       doorbell = __netdev_tx_sent_queue(dev_queue, skb->len,
+                                         netdev_xmit_more());
+-      hns3_tx_doorbell(ring, bd_num, doorbell);
++      hns3_tx_doorbell(ring, ret, doorbell);
+       return NETDEV_TX_OK;
+@@ -1748,11 +1777,15 @@ static void hns3_nic_get_stats64(struct net_device *netdev,
+                       tx_drop += ring->stats.tx_l4_proto_err;
+                       tx_drop += ring->stats.tx_l2l3l4_err;
+                       tx_drop += ring->stats.tx_tso_err;
++                      tx_drop += ring->stats.over_max_recursion;
++                      tx_drop += ring->stats.hw_limitation;
+                       tx_errors += ring->stats.sw_err_cnt;
+                       tx_errors += ring->stats.tx_vlan_err;
+                       tx_errors += ring->stats.tx_l4_proto_err;
+                       tx_errors += ring->stats.tx_l2l3l4_err;
+                       tx_errors += ring->stats.tx_tso_err;
++                      tx_errors += ring->stats.over_max_recursion;
++                      tx_errors += ring->stats.hw_limitation;
+               } while (u64_stats_fetch_retry_irq(&ring->syncp, start));
+               /* fetch the rx stats */
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+index 0a7b606e7c93..0b531e107e26 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+@@ -377,6 +377,8 @@ struct ring_stats {
+                       u64 tx_l4_proto_err;
+                       u64 tx_l2l3l4_err;
+                       u64 tx_tso_err;
++                      u64 over_max_recursion;
++                      u64 hw_limitation;
+               };
+               struct {
+                       u64 rx_pkts;
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+index e2fc443fe92c..7276cfaa8c3b 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+@@ -44,6 +44,8 @@ static const struct hns3_stats hns3_txq_stats[] = {
+       HNS3_TQP_STAT("l4_proto_err", tx_l4_proto_err),
+       HNS3_TQP_STAT("l2l3l4_err", tx_l2l3l4_err),
+       HNS3_TQP_STAT("tso_err", tx_tso_err),
++      HNS3_TQP_STAT("over_max_recursion", over_max_recursion),
++      HNS3_TQP_STAT("hw_limitation", hw_limitation),
+ };
+ #define HNS3_TXQ_STATS_COUNT ARRAY_SIZE(hns3_txq_stats)
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-hns3-disable-phy-loopback-setting-in-hclge_mac_s.patch b/queue-5.11/net-hns3-disable-phy-loopback-setting-in-hclge_mac_s.patch
new file mode 100644 (file)
index 0000000..b3439b3
--- /dev/null
@@ -0,0 +1,39 @@
+From ce38b51dbf1bd0073f66f63c22115538a0196ebb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 17:06:22 +0800
+Subject: net: hns3: disable phy loopback setting in hclge_mac_start_phy
+
+From: Yufeng Mo <moyufeng@huawei.com>
+
+[ Upstream commit 472497d0bdae890a896013332a0b673f9acdf2bf ]
+
+If selftest and reset are performed at the same time, the phy
+loopback setting may be still in enable state after the reset,
+and device cannot link up. So fix this issue by disabling phy
+loopback before phy_start().
+
+Fixes: 256727da7395 ("net: hns3: Add MDIO support to HNS3 Ethernet driver for hip08 SoC")
+Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+index e89820702540..c194bba187d6 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+@@ -255,6 +255,8 @@ void hclge_mac_start_phy(struct hclge_dev *hdev)
+       if (!phydev)
+               return;
++      phy_loopback(phydev, false);
++
+       phy_start(phydev);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-hns3-fix-for-vxlan-gpe-tx-checksum-bug.patch b/queue-5.11/net-hns3-fix-for-vxlan-gpe-tx-checksum-bug.patch
new file mode 100644 (file)
index 0000000..bf52511
--- /dev/null
@@ -0,0 +1,51 @@
+From 4c763a2cfc31e6bef4f8b051f63ed6d29aed10c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 17:06:19 +0800
+Subject: net: hns3: fix for vxlan gpe tx checksum bug
+
+From: Hao Chen <chenhao288@hisilicon.com>
+
+[ Upstream commit 905416f18fe74bdd4de91bf94ef5a790a36e4b99 ]
+
+When skb->ip_summed is CHECKSUM_PARTIAL, for non-tunnel udp packet,
+which has a dest port as the IANA assigned, the hardware is expected
+to do the checksum offload, but the hardware whose version is below
+V3 will not do the checksum offload when udp dest port is 4790.
+
+So fixes it by doing the checksum in software for this case.
+
+Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
+Signed-off-by: Hao Chen <chenhao288@hisilicon.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 9c34fd3b65d1..0a7bc0163046 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -823,7 +823,7 @@ static int hns3_get_l4_protocol(struct sk_buff *skb, u8 *ol4_proto,
+  * and it is udp packet, which has a dest port as the IANA assigned.
+  * the hardware is expected to do the checksum offload, but the
+  * hardware will not do the checksum offload when udp dest port is
+- * 4789 or 6081.
++ * 4789, 4790 or 6081.
+  */
+ static bool hns3_tunnel_csum_bug(struct sk_buff *skb)
+ {
+@@ -841,7 +841,8 @@ static bool hns3_tunnel_csum_bug(struct sk_buff *skb)
+       if (!(!skb->encapsulation &&
+             (l4.udp->dest == htons(IANA_VXLAN_UDP_PORT) ||
+-            l4.udp->dest == htons(GENEVE_UDP_PORT))))
++            l4.udp->dest == htons(GENEVE_UDP_PORT) ||
++            l4.udp->dest == htons(4790))))
+               return false;
+       skb_checksum_help(skb);
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-hns3-fix-incorrect-configuration-for-igu_egu_hw_.patch b/queue-5.11/net-hns3-fix-incorrect-configuration-for-igu_egu_hw_.patch
new file mode 100644 (file)
index 0000000..2899071
--- /dev/null
@@ -0,0 +1,56 @@
+From 9cd5898ff188f0bfb6bd07b2bfc1940b61d9b054 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 16:34:50 +0800
+Subject: net: hns3: fix incorrect configuration for igu_egu_hw_err
+
+From: Yufeng Mo <moyufeng@huawei.com>
+
+[ Upstream commit 2867298dd49ee84214b8721521dc7a5a6382520c ]
+
+According to the UM, the type and enable status of igu_egu_hw_err
+should be configured separately. Currently, the type field is
+incorrect when disable this error. So fix it by configuring these
+two fields separately.
+
+Fixes: bf1faf9415dd ("net: hns3: Add enable and process hw errors from IGU, EGU and NCSI")
+Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c | 3 ++-
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.h | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
+index 9ee55ee0487d..3226ca176155 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
+@@ -753,8 +753,9 @@ static int hclge_config_igu_egu_hw_err_int(struct hclge_dev *hdev, bool en)
+       /* configure IGU,EGU error interrupts */
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_IGU_COMMON_INT_EN, false);
++      desc.data[0] = cpu_to_le32(HCLGE_IGU_ERR_INT_TYPE);
+       if (en)
+-              desc.data[0] = cpu_to_le32(HCLGE_IGU_ERR_INT_EN);
++              desc.data[0] |= cpu_to_le32(HCLGE_IGU_ERR_INT_EN);
+       desc.data[1] = cpu_to_le32(HCLGE_IGU_ERR_INT_EN_MASK);
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.h
+index 608fe26fc3fe..d647f3c84134 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.h
+@@ -32,7 +32,8 @@
+ #define HCLGE_TQP_ECC_ERR_INT_EN_MASK 0x0FFF
+ #define HCLGE_MSIX_SRAM_ECC_ERR_INT_EN_MASK   0x0F000000
+ #define HCLGE_MSIX_SRAM_ECC_ERR_INT_EN        0x0F000000
+-#define HCLGE_IGU_ERR_INT_EN  0x0000066F
++#define HCLGE_IGU_ERR_INT_EN  0x0000000F
++#define HCLGE_IGU_ERR_INT_TYPE        0x00000660
+ #define HCLGE_IGU_ERR_INT_EN_MASK     0x000F
+ #define HCLGE_IGU_TNL_ERR_INT_EN    0x0002AABF
+ #define HCLGE_IGU_TNL_ERR_INT_EN_MASK  0x003F
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-hns3-initialize-the-message-content-in-hclge_get.patch b/queue-5.11/net-hns3-initialize-the-message-content-in-hclge_get.patch
new file mode 100644 (file)
index 0000000..31d7ff3
--- /dev/null
@@ -0,0 +1,38 @@
+From 297f5175f11946263f253493a0ff25e7f66ae9a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 16:34:51 +0800
+Subject: net: hns3: initialize the message content in hclge_get_link_mode()
+
+From: Yufeng Mo <moyufeng@huawei.com>
+
+[ Upstream commit 568a54bdf70b143f3e0befa298e22ad469ffc732 ]
+
+The message sent to VF should be initialized, otherwise random
+value of some contents may cause improper processing by the target.
+So add a initialization to message in hclge_get_link_mode().
+
+Fixes: 9194d18b0577 ("net: hns3: fix the problem that the supported port is empty")
+Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index ffb416e088a9..cdd77430e4de 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -535,7 +535,7 @@ static void hclge_get_link_mode(struct hclge_vport *vport,
+       unsigned long advertising;
+       unsigned long supported;
+       unsigned long send_data;
+-      u8 msg_data[10];
++      u8 msg_data[10] = {};
+       u8 dest_vfid;
+       advertising = hdev->hw.mac.advertising[0];
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-hns3-remediate-a-potential-overflow-risk-of-bd_n.patch b/queue-5.11/net-hns3-remediate-a-potential-overflow-risk-of-bd_n.patch
new file mode 100644 (file)
index 0000000..c51c8a3
--- /dev/null
@@ -0,0 +1,113 @@
+From 23935f4e9b3d5964bc9923a771eca6ed48cd533d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 11:57:47 +0800
+Subject: net: hns3: remediate a potential overflow risk of bd_num_list
+
+From: Guangbin Huang <huangguangbin2@huawei.com>
+
+[ Upstream commit a2ee6fd28a190588e142ad8ea9d40069cd3c9f98 ]
+
+The array size of bd_num_list is a fixed value, it may have potential
+overflow risk when array size of hclge_dfx_bd_offset_list is greater
+than that fixed value. So modify bd_num_list as a pointer and allocate
+memory for it according to array size of hclge_dfx_bd_offset_list.
+
+Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../hisilicon/hns3/hns3pf/hclge_main.c        | 27 ++++++++++++++-----
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 67764d930435..1c13cf34ae9f 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -11284,7 +11284,6 @@ static int hclge_get_64_bit_regs(struct hclge_dev *hdev, u32 regs_num,
+ #define REG_LEN_PER_LINE      (REG_NUM_PER_LINE * sizeof(u32))
+ #define REG_SEPARATOR_LINE    1
+ #define REG_NUM_REMAIN_MASK   3
+-#define BD_LIST_MAX_NUM               30
+ int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, struct hclge_desc *desc)
+ {
+@@ -11378,15 +11377,19 @@ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
+ {
+       u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
+       int data_len_per_desc, bd_num, i;
+-      int bd_num_list[BD_LIST_MAX_NUM];
++      int *bd_num_list;
+       u32 data_len;
+       int ret;
++      bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL);
++      if (!bd_num_list)
++              return -ENOMEM;
++
+       ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "Get dfx reg bd num fail, status is %d.\n", ret);
+-              return ret;
++              goto out;
+       }
+       data_len_per_desc = sizeof_field(struct hclge_desc, data);
+@@ -11397,6 +11400,8 @@ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
+               *len += (data_len / REG_LEN_PER_LINE + 1) * REG_LEN_PER_LINE;
+       }
++out:
++      kfree(bd_num_list);
+       return ret;
+ }
+@@ -11404,16 +11409,20 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+ {
+       u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
+       int bd_num, bd_num_max, buf_len, i;
+-      int bd_num_list[BD_LIST_MAX_NUM];
+       struct hclge_desc *desc_src;
++      int *bd_num_list;
+       u32 *reg = data;
+       int ret;
++      bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL);
++      if (!bd_num_list)
++              return -ENOMEM;
++
+       ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "Get dfx reg bd num fail, status is %d.\n", ret);
+-              return ret;
++              goto out;
+       }
+       bd_num_max = bd_num_list[0];
+@@ -11422,8 +11431,10 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+       buf_len = sizeof(*desc_src) * bd_num_max;
+       desc_src = kzalloc(buf_len, GFP_KERNEL);
+-      if (!desc_src)
+-              return -ENOMEM;
++      if (!desc_src) {
++              ret = -ENOMEM;
++              goto out;
++      }
+       for (i = 0; i < dfx_reg_type_num; i++) {
+               bd_num = bd_num_list[i];
+@@ -11439,6 +11450,8 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+       }
+       kfree(desc_src);
++out:
++      kfree(bd_num_list);
+       return ret;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-hns3-use-netif_tx_disable-to-stop-the-transmit-q.patch b/queue-5.11/net-hns3-use-netif_tx_disable-to-stop-the-transmit-q.patch
new file mode 100644 (file)
index 0000000..003a739
--- /dev/null
@@ -0,0 +1,44 @@
+From 50b64192ec2cce49ecd9f7c7f187cdffb09a1c54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 17:06:20 +0800
+Subject: net: hns3: use netif_tx_disable to stop the transmit queue
+
+From: Peng Li <lipeng321@huawei.com>
+
+[ Upstream commit b416e872be06fdace3c36cf5210130509d0f0e72 ]
+
+Currently, netif_tx_stop_all_queues() is used to ensure that
+the xmit is not running, but for the concurrent case it will
+not take effect, since netif_tx_stop_all_queues() just sets
+a flag without locking to indicate that the xmit queue(s)
+should not be run.
+
+So use netif_tx_disable() to replace netif_tx_stop_all_queues(),
+it takes the xmit queue lock while marking the queue stopped.
+
+Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 0a7bc0163046..3b8074e83476 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -576,8 +576,8 @@ static int hns3_nic_net_stop(struct net_device *netdev)
+       if (h->ae_algo->ops->set_timer_task)
+               h->ae_algo->ops->set_timer_task(priv->ae_handle, false);
+-      netif_tx_stop_all_queues(netdev);
+       netif_carrier_off(netdev);
++      netif_tx_disable(netdev);
+       hns3_nic_net_down(netdev);
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-ipa-fix-inter-ee-irq-register-definitions.patch b/queue-5.11/net-ipa-fix-inter-ee-irq-register-definitions.patch
new file mode 100644 (file)
index 0000000..760bf75
--- /dev/null
@@ -0,0 +1,76 @@
+From 15ea93fa7dac6566e9ed6e4323cf841e1074b62d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 17:36:36 -0500
+Subject: net: ipa: fix inter-EE IRQ register definitions
+
+From: Alex Elder <elder@linaro.org>
+
+[ Upstream commit 6a780f51f87b430cc69ebf4e859e7e9be720b283 ]
+
+In gsi_irq_setup(), two registers are written with the intention of
+disabling inter-EE channel and event IRQs.
+
+But the wrong registers are used (and defined); the ones used are
+read-only registers that indicate whether the interrupt condition is
+present.
+
+Define the mask registers instead of the status registers, and use
+them to disable the inter-EE interrupt types.
+
+Fixes: 46f748ccaf01 ("net: ipa: explicitly disallow inter-EE interrupts")
+Signed-off-by: Alex Elder <elder@linaro.org>
+Link: https://lore.kernel.org/r/20210505223636.232527-1-elder@linaro.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipa/gsi.c     |  4 ++--
+ drivers/net/ipa/gsi_reg.h | 18 +++++++++---------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
+index febfac75dd6a..537853b9301b 100644
+--- a/drivers/net/ipa/gsi.c
++++ b/drivers/net/ipa/gsi.c
+@@ -205,8 +205,8 @@ static void gsi_irq_setup(struct gsi *gsi)
+       iowrite32(0, gsi->virt + GSI_CNTXT_SRC_IEOB_IRQ_MSK_OFFSET);
+       /* The inter-EE registers are in the non-adjusted address range */
+-      iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_CH_IRQ_OFFSET);
+-      iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_EV_CH_IRQ_OFFSET);
++      iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_CH_IRQ_MSK_OFFSET);
++      iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_EV_CH_IRQ_MSK_OFFSET);
+       iowrite32(0, gsi->virt + GSI_CNTXT_GSI_IRQ_EN_OFFSET);
+ }
+diff --git a/drivers/net/ipa/gsi_reg.h b/drivers/net/ipa/gsi_reg.h
+index 1622d8cf8dea..48ef04afab79 100644
+--- a/drivers/net/ipa/gsi_reg.h
++++ b/drivers/net/ipa/gsi_reg.h
+@@ -53,15 +53,15 @@
+ #define GSI_EE_REG_ADJUST                     0x0000d000      /* IPA v4.5+ */
+ /* The two inter-EE IRQ register offsets are relative to gsi->virt_raw */
+-#define GSI_INTER_EE_SRC_CH_IRQ_OFFSET \
+-                      GSI_INTER_EE_N_SRC_CH_IRQ_OFFSET(GSI_EE_AP)
+-#define GSI_INTER_EE_N_SRC_CH_IRQ_OFFSET(ee) \
+-                      (0x0000c018 + 0x1000 * (ee))
+-
+-#define GSI_INTER_EE_SRC_EV_CH_IRQ_OFFSET \
+-                      GSI_INTER_EE_N_SRC_EV_CH_IRQ_OFFSET(GSI_EE_AP)
+-#define GSI_INTER_EE_N_SRC_EV_CH_IRQ_OFFSET(ee) \
+-                      (0x0000c01c + 0x1000 * (ee))
++#define GSI_INTER_EE_SRC_CH_IRQ_MSK_OFFSET \
++                      GSI_INTER_EE_N_SRC_CH_IRQ_MSK_OFFSET(GSI_EE_AP)
++#define GSI_INTER_EE_N_SRC_CH_IRQ_MSK_OFFSET(ee) \
++                      (0x0000c020 + 0x1000 * (ee))
++
++#define GSI_INTER_EE_SRC_EV_CH_IRQ_MSK_OFFSET \
++                      GSI_INTER_EE_N_SRC_EV_CH_IRQ_MSK_OFFSET(GSI_EE_AP)
++#define GSI_INTER_EE_N_SRC_EV_CH_IRQ_MSK_OFFSET(ee) \
++                      (0x0000c024 + 0x1000 * (ee))
+ /* All other register offsets are relative to gsi->virt */
+ #define GSI_CH_C_CNTXT_0_OFFSET(ch) \
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-mlx5e-use-net_prefetchw-instead-of-prefetchw-in-.patch b/queue-5.11/net-mlx5e-use-net_prefetchw-instead-of-prefetchw-in-.patch
new file mode 100644 (file)
index 0000000..68180f1
--- /dev/null
@@ -0,0 +1,46 @@
+From 65e79a0d7e2acd18f3ae0b5961dcfa48c9f1f4bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jan 2021 18:43:31 +0200
+Subject: net/mlx5e: Use net_prefetchw instead of prefetchw in MPWQE TX
+ datapath
+
+From: Maxim Mikityanskiy <maximmi@mellanox.com>
+
+[ Upstream commit 991b2654605b455a94dac73e14b23480e7e20991 ]
+
+Commit e20f0dbf204f ("net/mlx5e: RX, Add a prefetch command for small
+L1_CACHE_BYTES") switched to using net_prefetchw at all places in mlx5e.
+In the same time frame, commit 5af75c747e2a ("net/mlx5e: Enhanced TX
+MPWQE for SKBs") added one more usage of prefetchw. When these two
+changes were merged, this new occurrence of prefetchw wasn't replaced
+with net_prefetchw.
+
+This commit fixes this last occurrence of prefetchw in
+mlx5e_tx_mpwqe_session_start, making the same change that was done in
+mlx5e_xdp_mpwqe_session_start.
+
+Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com>
+Reviewed-by: Saeed Mahameed <saeedm@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_tx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+index 61ed671fe741..1b3c93c3fd23 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+@@ -553,7 +553,7 @@ static void mlx5e_tx_mpwqe_session_start(struct mlx5e_txqsq *sq,
+       pi = mlx5e_txqsq_get_next_pi(sq, MLX5E_TX_MPW_MAX_WQEBBS);
+       wqe = MLX5E_TX_FETCH_WQE(sq, pi);
+-      prefetchw(wqe->data);
++      net_prefetchw(wqe->data);
+       *session = (struct mlx5e_tx_mpwqe) {
+               .wqe = wqe,
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-sched-cls_flower-use-ntohs-for-struct-flow_disse.patch b/queue-5.11/net-sched-cls_flower-use-ntohs-for-struct-flow_disse.patch
new file mode 100644 (file)
index 0000000..c3687a9
--- /dev/null
@@ -0,0 +1,108 @@
+From 8b03bf29dadabe59aa031d68d2ee49478c6d09e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Mar 2021 23:05:48 +0200
+Subject: net/sched: cls_flower: use ntohs for struct flow_dissector_key_ports
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 6215afcb9a7e35cef334dc0ae7f998cc72c8465f ]
+
+A make W=1 build complains that:
+
+net/sched/cls_flower.c:214:20: warning: cast from restricted __be16
+net/sched/cls_flower.c:214:20: warning: incorrect type in argument 1 (different base types)
+net/sched/cls_flower.c:214:20:    expected unsigned short [usertype] val
+net/sched/cls_flower.c:214:20:    got restricted __be16 [usertype] dst
+
+This is because we use htons on struct flow_dissector_key_ports members
+src and dst, which are defined as __be16, so they are already in network
+byte order, not host. The byte swap function for the other direction
+should have been used.
+
+Because htons and ntohs do the same thing (either both swap, or none
+does), this change has no functional effect except to silence the
+warnings.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/cls_flower.c | 36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
+index 14316ba9b3b3..a5212a3f86e2 100644
+--- a/net/sched/cls_flower.c
++++ b/net/sched/cls_flower.c
+@@ -209,16 +209,16 @@ static bool fl_range_port_dst_cmp(struct cls_fl_filter *filter,
+                                 struct fl_flow_key *key,
+                                 struct fl_flow_key *mkey)
+ {
+-      __be16 min_mask, max_mask, min_val, max_val;
++      u16 min_mask, max_mask, min_val, max_val;
+-      min_mask = htons(filter->mask->key.tp_range.tp_min.dst);
+-      max_mask = htons(filter->mask->key.tp_range.tp_max.dst);
+-      min_val = htons(filter->key.tp_range.tp_min.dst);
+-      max_val = htons(filter->key.tp_range.tp_max.dst);
++      min_mask = ntohs(filter->mask->key.tp_range.tp_min.dst);
++      max_mask = ntohs(filter->mask->key.tp_range.tp_max.dst);
++      min_val = ntohs(filter->key.tp_range.tp_min.dst);
++      max_val = ntohs(filter->key.tp_range.tp_max.dst);
+       if (min_mask && max_mask) {
+-              if (htons(key->tp_range.tp.dst) < min_val ||
+-                  htons(key->tp_range.tp.dst) > max_val)
++              if (ntohs(key->tp_range.tp.dst) < min_val ||
++                  ntohs(key->tp_range.tp.dst) > max_val)
+                       return false;
+               /* skb does not have min and max values */
+@@ -232,16 +232,16 @@ static bool fl_range_port_src_cmp(struct cls_fl_filter *filter,
+                                 struct fl_flow_key *key,
+                                 struct fl_flow_key *mkey)
+ {
+-      __be16 min_mask, max_mask, min_val, max_val;
++      u16 min_mask, max_mask, min_val, max_val;
+-      min_mask = htons(filter->mask->key.tp_range.tp_min.src);
+-      max_mask = htons(filter->mask->key.tp_range.tp_max.src);
+-      min_val = htons(filter->key.tp_range.tp_min.src);
+-      max_val = htons(filter->key.tp_range.tp_max.src);
++      min_mask = ntohs(filter->mask->key.tp_range.tp_min.src);
++      max_mask = ntohs(filter->mask->key.tp_range.tp_max.src);
++      min_val = ntohs(filter->key.tp_range.tp_min.src);
++      max_val = ntohs(filter->key.tp_range.tp_max.src);
+       if (min_mask && max_mask) {
+-              if (htons(key->tp_range.tp.src) < min_val ||
+-                  htons(key->tp_range.tp.src) > max_val)
++              if (ntohs(key->tp_range.tp.src) < min_val ||
++                  ntohs(key->tp_range.tp.src) > max_val)
+                       return false;
+               /* skb does not have min and max values */
+@@ -779,16 +779,16 @@ static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
+                      TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src));
+       if (mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst &&
+-          htons(key->tp_range.tp_max.dst) <=
+-          htons(key->tp_range.tp_min.dst)) {
++          ntohs(key->tp_range.tp_max.dst) <=
++          ntohs(key->tp_range.tp_min.dst)) {
+               NL_SET_ERR_MSG_ATTR(extack,
+                                   tb[TCA_FLOWER_KEY_PORT_DST_MIN],
+                                   "Invalid destination port range (min must be strictly smaller than max)");
+               return -EINVAL;
+       }
+       if (mask->tp_range.tp_min.src && mask->tp_range.tp_max.src &&
+-          htons(key->tp_range.tp_max.src) <=
+-          htons(key->tp_range.tp_min.src)) {
++          ntohs(key->tp_range.tp_max.src) <=
++          ntohs(key->tp_range.tp_min.src)) {
+               NL_SET_ERR_MSG_ATTR(extack,
+                                   tb[TCA_FLOWER_KEY_PORT_SRC_MIN],
+                                   "Invalid source port range (min must be strictly smaller than max)");
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-sched-tapr-prevent-cycle_time-0-in-parse_taprio_.patch b/queue-5.11/net-sched-tapr-prevent-cycle_time-0-in-parse_taprio_.patch
new file mode 100644 (file)
index 0000000..f2a928f
--- /dev/null
@@ -0,0 +1,46 @@
+From 5cb3bd5c33b162b443cde472dd3b89d7de37dfb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Apr 2021 07:30:46 +0800
+Subject: net: sched: tapr: prevent cycle_time == 0 in parse_taprio_schedule
+
+From: Du Cheng <ducheng2@gmail.com>
+
+[ Upstream commit ed8157f1ebf1ae81a8fa2653e3f20d2076fad1c9 ]
+
+There is a reproducible sequence from the userland that will trigger a WARN_ON()
+condition in taprio_get_start_time, which causes kernel to panic if configured
+as "panic_on_warn". Catch this condition in parse_taprio_schedule to
+prevent this condition.
+
+Reported as bug on syzkaller:
+https://syzkaller.appspot.com/bug?extid=d50710fd0873a9c6b40c
+
+Reported-by: syzbot+d50710fd0873a9c6b40c@syzkaller.appspotmail.com
+Signed-off-by: Du Cheng <ducheng2@gmail.com>
+Acked-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_taprio.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
+index 6f775275826a..c70f93d64483 100644
+--- a/net/sched/sch_taprio.c
++++ b/net/sched/sch_taprio.c
+@@ -901,6 +901,12 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
+               list_for_each_entry(entry, &new->entries, list)
+                       cycle = ktime_add_ns(cycle, entry->interval);
++
++              if (!cycle) {
++                      NL_SET_ERR_MSG(extack, "'cycle_time' can never be 0");
++                      return -EINVAL;
++              }
++
+               new->cycle_time = cycle;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-stmmac-clear-receive-all-ra-bit-when-promiscuous.patch b/queue-5.11/net-stmmac-clear-receive-all-ra-bit-when-promiscuous.patch
new file mode 100644 (file)
index 0000000..6c93597
--- /dev/null
@@ -0,0 +1,37 @@
+From 353b7b8d65b000919ccfb4048f3965e472a04df2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 21:12:41 +0530
+Subject: net: stmmac: Clear receive all(RA) bit when promiscuous mode is off
+
+From: Ramesh Babu B <ramesh.babu.b@intel.com>
+
+[ Upstream commit 4c7a94286ef7ac7301d633f17519fb1bb89d7550 ]
+
+In promiscuous mode Receive All bit is set in GMAC packet filter register,
+but outside promiscuous mode Receive All bit is not cleared,
+which resulted in all network packets are received when toggle (ON/OFF)
+the promiscuous mode.
+
+Fixes: e0f9956a3862 ("net: stmmac: Add option for VLAN filter fail queue enable")
+Signed-off-by: Ramesh Babu B <ramesh.babu.b@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+index 29f765a246a0..aaf37598cbd3 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+@@ -638,6 +638,7 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
+       value &= ~GMAC_PACKET_FILTER_PCF;
+       value &= ~GMAC_PACKET_FILTER_PM;
+       value &= ~GMAC_PACKET_FILTER_PR;
++      value &= ~GMAC_PACKET_FILTER_RA;
+       if (dev->flags & IFF_PROMISC) {
+               /* VLAN Tag Filter Fail Packets Queuing */
+               if (hw->vlan_fail_q_en) {
+-- 
+2.30.2
+
diff --git a/queue-5.11/net-stmmac-set-fifo-sizes-for-ipq806x.patch b/queue-5.11/net-stmmac-set-fifo-sizes-for-ipq806x.patch
new file mode 100644 (file)
index 0000000..581f210
--- /dev/null
@@ -0,0 +1,44 @@
+From 8e64331fcd62c1709ec4ba416b36cd3ee67c6563 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Mar 2021 13:18:26 +0000
+Subject: net: stmmac: Set FIFO sizes for ipq806x
+
+From: Jonathan McDowell <noodles@earth.li>
+
+[ Upstream commit e127906b68b49ddb3ecba39ffa36a329c48197d3 ]
+
+Commit eaf4fac47807 ("net: stmmac: Do not accept invalid MTU values")
+started using the TX FIFO size to verify what counts as a valid MTU
+request for the stmmac driver.  This is unset for the ipq806x variant.
+Looking at older patches for this it seems the RX + TXs buffers can be
+up to 8k, so set appropriately.
+
+(I sent this as an RFC patch in June last year, but received no replies.
+I've been running with this on my hardware (a MikroTik RB3011) since
+then with larger MTUs to support both the internal qca8k switch and
+VLANs with no problems. Without the patch it's impossible to set the
+larger MTU required to support this.)
+
+Signed-off-by: Jonathan McDowell <noodles@earth.li>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+index bf3250e0e59c..749585fe6fc9 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+@@ -352,6 +352,8 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
+       plat_dat->bsp_priv = gmac;
+       plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
+       plat_dat->multicast_filter_bins = 0;
++      plat_dat->tx_fifo_size = 8192;
++      plat_dat->rx_fifo_size = 8192;
+       err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (err)
+-- 
+2.30.2
+
diff --git a/queue-5.11/netfilter-nfnetlink_osf-fix-a-missing-skb_header_poi.patch b/queue-5.11/netfilter-nfnetlink_osf-fix-a-missing-skb_header_poi.patch
new file mode 100644 (file)
index 0000000..2b6c30b
--- /dev/null
@@ -0,0 +1,36 @@
+From 6a395e5fc7a1744fe83030dc7fcc730bc4ec05b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 22:25:24 +0200
+Subject: netfilter: nfnetlink_osf: Fix a missing skb_header_pointer() NULL
+ check
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 5e024c325406470d1165a09c6feaf8ec897936be ]
+
+Do not assume that the tcph->doff field is correct when parsing for TCP
+options, skb_header_pointer() might fail to fetch these bits.
+
+Fixes: 11eeef41d5f6 ("netfilter: passive OS fingerprint xtables match")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nfnetlink_osf.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
+index 916a3c7f9eaf..79fbf37291f3 100644
+--- a/net/netfilter/nfnetlink_osf.c
++++ b/net/netfilter/nfnetlink_osf.c
+@@ -186,6 +186,8 @@ static const struct tcphdr *nf_osf_hdr_ctx_init(struct nf_osf_hdr_ctx *ctx,
+               ctx->optp = skb_header_pointer(skb, ip_hdrlen(skb) +
+                               sizeof(struct tcphdr), ctx->optsize, opts);
++              if (!ctx->optp)
++                      return NULL;
+       }
+       return tcp;
+-- 
+2.30.2
+
diff --git a/queue-5.11/netfilter-nftables-avoid-overflows-in-nft_hash_bucke.patch b/queue-5.11/netfilter-nftables-avoid-overflows-in-nft_hash_bucke.patch
new file mode 100644 (file)
index 0000000..6cf604e
--- /dev/null
@@ -0,0 +1,76 @@
+From 4c85a5ec3df830c5d18d15c86416b91d42551d2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 05:53:23 -0700
+Subject: netfilter: nftables: avoid overflows in nft_hash_buckets()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a54754ec9891830ba548e2010c889e3c8146e449 ]
+
+Number of buckets being stored in 32bit variables, we have to
+ensure that no overflows occur in nft_hash_buckets()
+
+syzbot injected a size == 0x40000000 and reported:
+
+UBSAN: shift-out-of-bounds in ./include/linux/log2.h:57:13
+shift exponent 64 is too large for 64-bit type 'long unsigned int'
+CPU: 1 PID: 29539 Comm: syz-executor.4 Not tainted 5.12.0-rc7-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:79 [inline]
+ dump_stack+0x141/0x1d7 lib/dump_stack.c:120
+ ubsan_epilogue+0xb/0x5a lib/ubsan.c:148
+ __ubsan_handle_shift_out_of_bounds.cold+0xb1/0x181 lib/ubsan.c:327
+ __roundup_pow_of_two include/linux/log2.h:57 [inline]
+ nft_hash_buckets net/netfilter/nft_set_hash.c:411 [inline]
+ nft_hash_estimate.cold+0x19/0x1e net/netfilter/nft_set_hash.c:652
+ nft_select_set_ops net/netfilter/nf_tables_api.c:3586 [inline]
+ nf_tables_newset+0xe62/0x3110 net/netfilter/nf_tables_api.c:4322
+ nfnetlink_rcv_batch+0xa09/0x24b0 net/netfilter/nfnetlink.c:488
+ nfnetlink_rcv_skb_batch net/netfilter/nfnetlink.c:612 [inline]
+ nfnetlink_rcv+0x3af/0x420 net/netfilter/nfnetlink.c:630
+ netlink_unicast_kernel net/netlink/af_netlink.c:1312 [inline]
+ netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1338
+ netlink_sendmsg+0x856/0xd90 net/netlink/af_netlink.c:1927
+ sock_sendmsg_nosec net/socket.c:654 [inline]
+ sock_sendmsg+0xcf/0x120 net/socket.c:674
+ ____sys_sendmsg+0x6e8/0x810 net/socket.c:2350
+ ___sys_sendmsg+0xf3/0x170 net/socket.c:2404
+ __sys_sendmsg+0xe5/0x1b0 net/socket.c:2433
+ do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
+
+Fixes: 0ed6389c483d ("netfilter: nf_tables: rename set implementations")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_hash.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
+index bf618b7ec1ae..560c2cda52ee 100644
+--- a/net/netfilter/nft_set_hash.c
++++ b/net/netfilter/nft_set_hash.c
+@@ -406,9 +406,17 @@ static void nft_rhash_destroy(const struct nft_set *set)
+                                   (void *)set);
+ }
++/* Number of buckets is stored in u32, so cap our result to 1U<<31 */
++#define NFT_MAX_BUCKETS (1U << 31)
++
+ static u32 nft_hash_buckets(u32 size)
+ {
+-      return roundup_pow_of_two(size * 4 / 3);
++      u64 val = div_u64((u64)size * 4, 3);
++
++      if (val >= NFT_MAX_BUCKETS)
++              return NFT_MAX_BUCKETS;
++
++      return roundup_pow_of_two(val);
+ }
+ static bool nft_rhash_estimate(const struct nft_set_desc *desc, u32 features,
+-- 
+2.30.2
+
diff --git a/queue-5.11/netfilter-nftables-fix-a-memleak-from-userdata-error.patch b/queue-5.11/netfilter-nftables-fix-a-memleak-from-userdata-error.patch
new file mode 100644 (file)
index 0000000..d7c8882
--- /dev/null
@@ -0,0 +1,38 @@
+From 7541f03a529fbc4b0e2b9b6fd48b86a922a17884 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 23:06:43 +0200
+Subject: netfilter: nftables: Fix a memleak from userdata error path in new
+ objects
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 85dfd816fabfc16e71786eda0a33a7046688b5b0 ]
+
+Release object name if userdata allocation fails.
+
+Fixes: b131c96496b3 ("netfilter: nf_tables: add userdata support for nft_object")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index d6ec76a0fe62..1380369d5787 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -6213,9 +6213,9 @@ err_obj_ht:
+       INIT_LIST_HEAD(&obj->list);
+       return err;
+ err_trans:
+-      kfree(obj->key.name);
+-err_userdata:
+       kfree(obj->udata);
++err_userdata:
++      kfree(obj->key.name);
+ err_strdup:
+       if (obj->ops->destroy)
+               obj->ops->destroy(&ctx, obj);
+-- 
+2.30.2
+
diff --git a/queue-5.11/netfilter-xt_secmark-add-new-revision-to-fix-structu.patch b/queue-5.11/netfilter-xt_secmark-add-new-revision-to-fix-structu.patch
new file mode 100644 (file)
index 0000000..7d4d18d
--- /dev/null
@@ -0,0 +1,173 @@
+From 0c729dd36435fd5332cbdb603231edb3c7a7b021 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 14:00:13 +0200
+Subject: netfilter: xt_SECMARK: add new revision to fix structure layout
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit c7d13358b6a2f49f81a34aa323a2d0878a0532a2 ]
+
+This extension breaks when trying to delete rules, add a new revision to
+fix this.
+
+Fixes: 5e6874cdb8de ("[SECMARK]: Add xtables SECMARK target")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/netfilter/xt_SECMARK.h |  6 ++
+ net/netfilter/xt_SECMARK.c                | 88 ++++++++++++++++++-----
+ 2 files changed, 75 insertions(+), 19 deletions(-)
+
+diff --git a/include/uapi/linux/netfilter/xt_SECMARK.h b/include/uapi/linux/netfilter/xt_SECMARK.h
+index 1f2a708413f5..beb2cadba8a9 100644
+--- a/include/uapi/linux/netfilter/xt_SECMARK.h
++++ b/include/uapi/linux/netfilter/xt_SECMARK.h
+@@ -20,4 +20,10 @@ struct xt_secmark_target_info {
+       char secctx[SECMARK_SECCTX_MAX];
+ };
++struct xt_secmark_target_info_v1 {
++      __u8 mode;
++      char secctx[SECMARK_SECCTX_MAX];
++      __u32 secid;
++};
++
+ #endif /*_XT_SECMARK_H_target */
+diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
+index 75625d13e976..498a0bf6f044 100644
+--- a/net/netfilter/xt_SECMARK.c
++++ b/net/netfilter/xt_SECMARK.c
+@@ -24,10 +24,9 @@ MODULE_ALIAS("ip6t_SECMARK");
+ static u8 mode;
+ static unsigned int
+-secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
++secmark_tg(struct sk_buff *skb, const struct xt_secmark_target_info_v1 *info)
+ {
+       u32 secmark = 0;
+-      const struct xt_secmark_target_info *info = par->targinfo;
+       switch (mode) {
+       case SECMARK_MODE_SEL:
+@@ -41,7 +40,7 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
+       return XT_CONTINUE;
+ }
+-static int checkentry_lsm(struct xt_secmark_target_info *info)
++static int checkentry_lsm(struct xt_secmark_target_info_v1 *info)
+ {
+       int err;
+@@ -73,15 +72,15 @@ static int checkentry_lsm(struct xt_secmark_target_info *info)
+       return 0;
+ }
+-static int secmark_tg_check(const struct xt_tgchk_param *par)
++static int
++secmark_tg_check(const char *table, struct xt_secmark_target_info_v1 *info)
+ {
+-      struct xt_secmark_target_info *info = par->targinfo;
+       int err;
+-      if (strcmp(par->table, "mangle") != 0 &&
+-          strcmp(par->table, "security") != 0) {
++      if (strcmp(table, "mangle") != 0 &&
++          strcmp(table, "security") != 0) {
+               pr_info_ratelimited("only valid in \'mangle\' or \'security\' table, not \'%s\'\n",
+-                                  par->table);
++                                  table);
+               return -EINVAL;
+       }
+@@ -116,25 +115,76 @@ static void secmark_tg_destroy(const struct xt_tgdtor_param *par)
+       }
+ }
+-static struct xt_target secmark_tg_reg __read_mostly = {
+-      .name       = "SECMARK",
+-      .revision   = 0,
+-      .family     = NFPROTO_UNSPEC,
+-      .checkentry = secmark_tg_check,
+-      .destroy    = secmark_tg_destroy,
+-      .target     = secmark_tg,
+-      .targetsize = sizeof(struct xt_secmark_target_info),
+-      .me         = THIS_MODULE,
++static int secmark_tg_check_v0(const struct xt_tgchk_param *par)
++{
++      struct xt_secmark_target_info *info = par->targinfo;
++      struct xt_secmark_target_info_v1 newinfo = {
++              .mode   = info->mode,
++      };
++      int ret;
++
++      memcpy(newinfo.secctx, info->secctx, SECMARK_SECCTX_MAX);
++
++      ret = secmark_tg_check(par->table, &newinfo);
++      info->secid = newinfo.secid;
++
++      return ret;
++}
++
++static unsigned int
++secmark_tg_v0(struct sk_buff *skb, const struct xt_action_param *par)
++{
++      const struct xt_secmark_target_info *info = par->targinfo;
++      struct xt_secmark_target_info_v1 newinfo = {
++              .secid  = info->secid,
++      };
++
++      return secmark_tg(skb, &newinfo);
++}
++
++static int secmark_tg_check_v1(const struct xt_tgchk_param *par)
++{
++      return secmark_tg_check(par->table, par->targinfo);
++}
++
++static unsigned int
++secmark_tg_v1(struct sk_buff *skb, const struct xt_action_param *par)
++{
++      return secmark_tg(skb, par->targinfo);
++}
++
++static struct xt_target secmark_tg_reg[] __read_mostly = {
++      {
++              .name           = "SECMARK",
++              .revision       = 0,
++              .family         = NFPROTO_UNSPEC,
++              .checkentry     = secmark_tg_check_v0,
++              .destroy        = secmark_tg_destroy,
++              .target         = secmark_tg_v0,
++              .targetsize     = sizeof(struct xt_secmark_target_info),
++              .me             = THIS_MODULE,
++      },
++      {
++              .name           = "SECMARK",
++              .revision       = 1,
++              .family         = NFPROTO_UNSPEC,
++              .checkentry     = secmark_tg_check_v1,
++              .destroy        = secmark_tg_destroy,
++              .target         = secmark_tg_v1,
++              .targetsize     = sizeof(struct xt_secmark_target_info_v1),
++              .usersize       = offsetof(struct xt_secmark_target_info_v1, secid),
++              .me             = THIS_MODULE,
++      },
+ };
+ static int __init secmark_tg_init(void)
+ {
+-      return xt_register_target(&secmark_tg_reg);
++      return xt_register_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg));
+ }
+ static void __exit secmark_tg_exit(void)
+ {
+-      xt_unregister_target(&secmark_tg_reg);
++      xt_unregister_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg));
+ }
+ module_init(secmark_tg_init);
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfs-deal-correctly-with-attribute-generation-counter.patch b/queue-5.11/nfs-deal-correctly-with-attribute-generation-counter.patch
new file mode 100644 (file)
index 0000000..ace737f
--- /dev/null
@@ -0,0 +1,49 @@
+From 9e7071feefcd787587e88f76e0bd76ff6354dea6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 16:46:05 -0400
+Subject: NFS: Deal correctly with attribute generation counter overflow
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 9fdbfad1777cb4638f489eeb62d85432010c0031 ]
+
+We need to use unsigned long subtraction and then convert to signed in
+order to deal correcly with C overflow rules.
+
+Fixes: f5062003465c ("NFS: Set an attribute barrier on all updates")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/inode.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 522aa10a1a3e..fd073b1caf6c 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -1635,10 +1635,10 @@ EXPORT_SYMBOL_GPL(_nfs_display_fhandle);
+  */
+ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
+ {
+-      const struct nfs_inode *nfsi = NFS_I(inode);
++      unsigned long attr_gencount = NFS_I(inode)->attr_gencount;
+-      return ((long)fattr->gencount - (long)nfsi->attr_gencount) > 0 ||
+-              ((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0);
++      return (long)(fattr->gencount - attr_gencount) > 0 ||
++             (long)(attr_gencount - nfs_read_attr_generation_counter()) > 0;
+ }
+ static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
+@@ -2067,7 +2067,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
+                       nfsi->attrtimeo_timestamp = now;
+               }
+               /* Set the barrier to be more recent than this fattr */
+-              if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0)
++              if ((long)(fattr->gencount - nfsi->attr_gencount) > 0)
+                       nfsi->attr_gencount = fattr->gencount;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfs-fix-attribute-bitmask-in-_nfs42_proc_fallocate.patch b/queue-5.11/nfs-fix-attribute-bitmask-in-_nfs42_proc_fallocate.patch
new file mode 100644 (file)
index 0000000..3a1109b
--- /dev/null
@@ -0,0 +1,63 @@
+From c613340cea3ded4d20eff28939f50cb419b4ffe5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Mar 2021 18:12:03 -0400
+Subject: NFS: Fix attribute bitmask in _nfs42_proc_fallocate()
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit e99812e1382f0bfb6149393262bc70645c9f537a ]
+
+We can't use nfs4_fattr_bitmap as a bitmask, because it hasn't been
+filtered to represent the attributes supported by the server. Instead,
+let's revert to using server->cache_consistency_bitmask after adding in
+the missing SPACE_USED attribute.
+
+Fixes: 913eca1aea87 ("NFS: Fallocate should use the nfs4_fattr_bitmap")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42proc.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index f3fd935620fc..1edce2d7ecef 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -46,11 +46,12 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+ {
+       struct inode *inode = file_inode(filep);
+       struct nfs_server *server = NFS_SERVER(inode);
++      u32 bitmask[3];
+       struct nfs42_falloc_args args = {
+               .falloc_fh      = NFS_FH(inode),
+               .falloc_offset  = offset,
+               .falloc_length  = len,
+-              .falloc_bitmask = nfs4_fattr_bitmap,
++              .falloc_bitmask = bitmask,
+       };
+       struct nfs42_falloc_res res = {
+               .falloc_server  = server,
+@@ -68,6 +69,10 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+               return status;
+       }
++      memcpy(bitmask, server->cache_consistency_bitmask, sizeof(bitmask));
++      if (server->attr_bitmask[1] & FATTR4_WORD1_SPACE_USED)
++              bitmask[1] |= FATTR4_WORD1_SPACE_USED;
++
+       res.falloc_fattr = nfs_alloc_fattr();
+       if (!res.falloc_fattr)
+               return -ENOMEM;
+@@ -75,7 +80,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+       status = nfs4_call_sync(server->client, server, msg,
+                               &args.seq_args, &res.seq_res, 0);
+       if (status == 0)
+-              status = nfs_post_op_update_inode(inode, res.falloc_fattr);
++              status = nfs_post_op_update_inode_force_wcc(inode,
++                                                          res.falloc_fattr);
+       kfree(res.falloc_fattr);
+       return status;
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfs-fix-handling-of-cookie-verifier-in-uncached_read.patch b/queue-5.11/nfs-fix-handling-of-cookie-verifier-in-uncached_read.patch
new file mode 100644 (file)
index 0000000..49d675d
--- /dev/null
@@ -0,0 +1,84 @@
+From d8cf2ffe22b65f97b6f16609fd4e83137172154c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Mar 2021 07:57:40 -0400
+Subject: NFS: Fix handling of cookie verifier in uncached_readdir()
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 13884ff2bef01df37c450c6dd09122f92333dccc ]
+
+If we're doing uncached readdir(), then the readdir cookie could be
+different from the one cached in the nfs_inode. We should therefore
+ensure that we save that one in the struct nfs_open_dir_context.
+
+Fixes: 35df59d3ef69 ("NFS: Reduce number of RPC calls when doing uncached readdir")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/dir.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index c3618b6abfc0..ca1dddc81436 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -975,10 +975,10 @@ static int readdir_search_pagecache(struct nfs_readdir_descriptor *desc)
+ /*
+  * Once we've found the start of the dirent within a page: fill 'er up...
+  */
+-static void nfs_do_filldir(struct nfs_readdir_descriptor *desc)
++static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
++                         const __be32 *verf)
+ {
+       struct file     *file = desc->file;
+-      struct nfs_inode *nfsi = NFS_I(file_inode(file));
+       struct nfs_cache_array *array;
+       unsigned int i = 0;
+@@ -992,7 +992,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc)
+                       desc->eof = true;
+                       break;
+               }
+-              memcpy(desc->verf, nfsi->cookieverf, sizeof(desc->verf));
++              memcpy(desc->verf, verf, sizeof(desc->verf));
+               if (i < (array->size-1))
+                       desc->dir_cookie = array->array[i+1].cookie;
+               else
+@@ -1049,7 +1049,7 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
+       for (i = 0; !desc->eof && i < sz && arrays[i]; i++) {
+               desc->page = arrays[i];
+-              nfs_do_filldir(desc);
++              nfs_do_filldir(desc, verf);
+       }
+       desc->page = NULL;
+@@ -1070,6 +1070,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
+ {
+       struct dentry   *dentry = file_dentry(file);
+       struct inode    *inode = d_inode(dentry);
++      struct nfs_inode *nfsi = NFS_I(inode);
+       struct nfs_open_dir_context *dir_ctx = file->private_data;
+       struct nfs_readdir_descriptor *desc;
+       int res;
+@@ -1123,7 +1124,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
+                       break;
+               }
+               if (res == -ETOOSMALL && desc->plus) {
+-                      clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
++                      clear_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags);
+                       nfs_zap_caches(inode);
+                       desc->page_index = 0;
+                       desc->plus = false;
+@@ -1133,7 +1134,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
+               if (res < 0)
+                       break;
+-              nfs_do_filldir(desc);
++              nfs_do_filldir(desc, nfsi->cookieverf);
+               nfs_readdir_page_unlock_and_put_cached(desc);
+       } while (!desc->eof);
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfs-nfs4_bitmask_adjust-must-not-change-the-server-g.patch b/queue-5.11/nfs-nfs4_bitmask_adjust-must-not-change-the-server-g.patch
new file mode 100644 (file)
index 0000000..1797957
--- /dev/null
@@ -0,0 +1,188 @@
+From c194aa03bd084747d3eec846e60b170da5dd4bb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 18:15:36 -0400
+Subject: NFS: nfs4_bitmask_adjust() must not change the server global bitmasks
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 332d1a0373be32a3a3c152756bca45ff4f4e11b5 ]
+
+As currently set, the calls to nfs4_bitmask_adjust() will end up
+overwriting the contents of the nfs_server cache_consistency_bitmask
+field.
+The intention here should be to modify a private copy of that mask in
+the close/delegreturn/write arguments.
+
+Fixes: 76bd5c016ef4 ("NFSv4: make cache consistency bitmask dynamic")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c       | 56 +++++++++++++++++++++++++----------------
+ include/linux/nfs_xdr.h | 11 +++++---
+ 2 files changed, 42 insertions(+), 25 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 95d3b8540f8e..8b4d2fc0cb01 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -112,9 +112,10 @@ static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
+ static int nfs41_free_stateid(struct nfs_server *, const nfs4_stateid *,
+               const struct cred *, bool);
+ #endif
+-static void nfs4_bitmask_adjust(__u32 *bitmask, struct inode *inode,
+-              struct nfs_server *server,
+-              struct nfs4_label *label);
++static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ],
++                           const __u32 *src, struct inode *inode,
++                           struct nfs_server *server,
++                           struct nfs4_label *label);
+ #ifdef CONFIG_NFS_V4_SECURITY_LABEL
+ static inline struct nfs4_label *
+@@ -3598,6 +3599,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
+       struct nfs4_closedata *calldata = data;
+       struct nfs4_state *state = calldata->state;
+       struct inode *inode = calldata->inode;
++      struct nfs_server *server = NFS_SERVER(inode);
+       struct pnfs_layout_hdr *lo;
+       bool is_rdonly, is_wronly, is_rdwr;
+       int call_close = 0;
+@@ -3654,8 +3656,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
+       if (calldata->arg.fmode == 0 || calldata->arg.fmode == FMODE_READ) {
+               /* Close-to-open cache consistency revalidation */
+               if (!nfs4_have_delegation(inode, FMODE_READ)) {
+-                      calldata->arg.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
+-                      nfs4_bitmask_adjust(calldata->arg.bitmask, inode, NFS_SERVER(inode), NULL);
++                      nfs4_bitmask_set(calldata->arg.bitmask_store,
++                                       server->cache_consistency_bitmask,
++                                       inode, server, NULL);
++                      calldata->arg.bitmask = calldata->arg.bitmask_store;
+               } else
+                       calldata->arg.bitmask = NULL;
+       }
+@@ -5423,19 +5427,17 @@ bool nfs4_write_need_cache_consistency_data(struct nfs_pgio_header *hdr)
+       return nfs4_have_delegation(hdr->inode, FMODE_READ) == 0;
+ }
+-static void nfs4_bitmask_adjust(__u32 *bitmask, struct inode *inode,
+-                              struct nfs_server *server,
+-                              struct nfs4_label *label)
++static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], const __u32 *src,
++                           struct inode *inode, struct nfs_server *server,
++                           struct nfs4_label *label)
+ {
+-
+       unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
++      unsigned int i;
+-      if ((cache_validity & NFS_INO_INVALID_DATA) ||
+-              (cache_validity & NFS_INO_REVAL_PAGECACHE) ||
+-              (cache_validity & NFS_INO_REVAL_FORCED) ||
+-              (cache_validity & NFS_INO_INVALID_OTHER))
+-              nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode);
++      memcpy(bitmask, src, sizeof(*bitmask) * NFS4_BITMASK_SZ);
++      if (cache_validity & (NFS_INO_INVALID_CHANGE | NFS_INO_REVAL_PAGECACHE))
++              bitmask[0] |= FATTR4_WORD0_CHANGE;
+       if (cache_validity & NFS_INO_INVALID_ATIME)
+               bitmask[1] |= FATTR4_WORD1_TIME_ACCESS;
+       if (cache_validity & NFS_INO_INVALID_OTHER)
+@@ -5444,16 +5446,22 @@ static void nfs4_bitmask_adjust(__u32 *bitmask, struct inode *inode,
+                               FATTR4_WORD1_NUMLINKS;
+       if (label && label->len && cache_validity & NFS_INO_INVALID_LABEL)
+               bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL;
+-      if (cache_validity & NFS_INO_INVALID_CHANGE)
+-              bitmask[0] |= FATTR4_WORD0_CHANGE;
+       if (cache_validity & NFS_INO_INVALID_CTIME)
+               bitmask[1] |= FATTR4_WORD1_TIME_METADATA;
+       if (cache_validity & NFS_INO_INVALID_MTIME)
+               bitmask[1] |= FATTR4_WORD1_TIME_MODIFY;
+-      if (cache_validity & NFS_INO_INVALID_SIZE)
+-              bitmask[0] |= FATTR4_WORD0_SIZE;
+       if (cache_validity & NFS_INO_INVALID_BLOCKS)
+               bitmask[1] |= FATTR4_WORD1_SPACE_USED;
++
++      if (nfs4_have_delegation(inode, FMODE_READ) &&
++          !(cache_validity & NFS_INO_REVAL_FORCED))
++              bitmask[0] &= ~FATTR4_WORD0_SIZE;
++      else if (cache_validity &
++               (NFS_INO_INVALID_SIZE | NFS_INO_REVAL_PAGECACHE))
++              bitmask[0] |= FATTR4_WORD0_SIZE;
++
++      for (i = 0; i < NFS4_BITMASK_SZ; i++)
++              bitmask[i] &= server->attr_bitmask[i];
+ }
+ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,
+@@ -5466,8 +5474,10 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,
+               hdr->args.bitmask = NULL;
+               hdr->res.fattr = NULL;
+       } else {
+-              hdr->args.bitmask = server->cache_consistency_bitmask;
+-              nfs4_bitmask_adjust(hdr->args.bitmask, hdr->inode, server, NULL);
++              nfs4_bitmask_set(hdr->args.bitmask_store,
++                               server->cache_consistency_bitmask,
++                               hdr->inode, server, NULL);
++              hdr->args.bitmask = hdr->args.bitmask_store;
+       }
+       if (!hdr->pgio_done_cb)
+@@ -6509,8 +6519,10 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred,
+       data->args.fhandle = &data->fh;
+       data->args.stateid = &data->stateid;
+-      data->args.bitmask = server->cache_consistency_bitmask;
+-      nfs4_bitmask_adjust(data->args.bitmask, inode, server, NULL);
++      nfs4_bitmask_set(data->args.bitmask_store,
++                       server->cache_consistency_bitmask, inode, server,
++                       NULL);
++      data->args.bitmask = data->args.bitmask_store;
+       nfs_copy_fh(&data->fh, NFS_FH(inode));
+       nfs4_stateid_copy(&data->stateid, stateid);
+       data->res.fattr = &data->fattr;
+diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
+index 3327239fa2f9..cc29dee508f7 100644
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -15,6 +15,8 @@
+ #define NFS_DEF_FILE_IO_SIZE  (4096U)
+ #define NFS_MIN_FILE_IO_SIZE  (1024U)
++#define NFS_BITMASK_SZ                3
++
+ struct nfs4_string {
+       unsigned int len;
+       char *data;
+@@ -525,7 +527,8 @@ struct nfs_closeargs {
+       struct nfs_seqid *      seqid;
+       fmode_t                 fmode;
+       u32                     share_access;
+-      u32 *                   bitmask;
++      const u32 *             bitmask;
++      u32                     bitmask_store[NFS_BITMASK_SZ];
+       struct nfs4_layoutreturn_args *lr_args;
+ };
+@@ -608,7 +611,8 @@ struct nfs4_delegreturnargs {
+       struct nfs4_sequence_args       seq_args;
+       const struct nfs_fh *fhandle;
+       const nfs4_stateid *stateid;
+-      u32 * bitmask;
++      const u32 *bitmask;
++      u32 bitmask_store[NFS_BITMASK_SZ];
+       struct nfs4_layoutreturn_args *lr_args;
+ };
+@@ -648,7 +652,8 @@ struct nfs_pgio_args {
+       union {
+               unsigned int            replen;                 /* used by read */
+               struct {
+-                      u32 *                   bitmask;        /* used by write */
++                      const u32 *             bitmask;        /* used by write */
++                      u32 bitmask_store[NFS_BITMASK_SZ];      /* used by write */
+                       enum nfs3_stable_how    stable;         /* used by write */
+               };
+       };
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfs-only-change-the-cookie-verifier-if-the-directory.patch b/queue-5.11/nfs-only-change-the-cookie-verifier-if-the-directory.patch
new file mode 100644 (file)
index 0000000..5f9e426
--- /dev/null
@@ -0,0 +1,45 @@
+From dbb4601e2ce44c19b18ed22f2b481a6b3122eb21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 08:46:19 -0400
+Subject: NFS: Only change the cookie verifier if the directory page cache is
+ empty
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit f892c41c14e0fa3d78ce37de1d5c8161ed13bf08 ]
+
+The cached NFSv3/v4 readdir cookies are associated with a verifier,
+which is checked by the server on subsequent calls to readdir, and is
+only expected to change when the cookies (and hence also the page cache
+contents) are considered invalid.
+We therefore do have to store the verifier, but only when the page cache
+is empty.
+
+Fixes: b593c09f83a2 ("NFS: Improve handling of directory verifiers")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/dir.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index ca1dddc81436..d5f28a1f3671 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -928,7 +928,12 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)
+                       }
+                       return res;
+               }
+-              memcpy(nfsi->cookieverf, verf, sizeof(nfsi->cookieverf));
++              /*
++               * Set the cookie verifier if the page cache was empty
++               */
++              if (desc->page_index == 0)
++                      memcpy(nfsi->cookieverf, verf,
++                             sizeof(nfsi->cookieverf));
+       }
+       res = nfs_readdir_search_array(desc);
+       if (res == 0) {
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfs-subsequent-readdir-calls-should-carry-non-zero-c.patch b/queue-5.11/nfs-subsequent-readdir-calls-should-carry-non-zero-c.patch
new file mode 100644 (file)
index 0000000..e371ea2
--- /dev/null
@@ -0,0 +1,38 @@
+From 184fec4265efa4f8743a0bf85e3bc92cbe9ad123 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Mar 2021 10:25:14 +0000
+Subject: nfs: Subsequent READDIR calls should carry non-zero cookieverifier
+
+From: Nagendra S Tomar <natomar@microsoft.com>
+
+[ Upstream commit ee3707ae2c1f1327ad5188836b7ab62ed2c93b28 ]
+
+If the loop in nfs_readdir_xdr_to_array() runs more than once, subsequent
+READDIR RPCs may wrongly carry a zero cookie verifier and non-zero cookie.
+Make sure subsequent calls to READDIR carry the cookie verifier returned
+by the first call.
+
+Signed-off-by: Nagendra S Tomar <natomar@microsoft.com>
+Fixes: b593c09f83a2 ("NFS: Improve handling of directory verifiers")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/dir.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index 4db3018776f6..c3618b6abfc0 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -865,6 +865,8 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
+                       break;
+               }
++              verf_arg = verf_res;
++
+               status = nfs_readdir_page_filler(desc, entry, pages, pglen,
+                                                arrays, narrays);
+       } while (!status && nfs_readdir_page_needs_filling(page));
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfsd-ensure-new-clients-break-delegations.patch b/queue-5.11/nfsd-ensure-new-clients-break-delegations.patch
new file mode 100644 (file)
index 0000000..f5fe53b
--- /dev/null
@@ -0,0 +1,71 @@
+From 31f52d3c96be9cf2ecbb5a572ea2ca2903705122 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 14:00:14 -0400
+Subject: nfsd: ensure new clients break delegations
+
+From: J. Bruce Fields <bfields@redhat.com>
+
+[ Upstream commit 217fd6f625af591e2866bebb8cda778cf85bea2e ]
+
+If nfsd already has an open file that it plans to use for IO from
+another, it may not need to do another vfs open, but it still may need
+to break any delegations in case the existing opens are for another
+client.
+
+Symptoms are that we may incorrectly fail to break a delegation on a
+write open from a different client, when the delegation-holding client
+already has a write open.
+
+Fixes: 28df3d1539de ("nfsd: clients don't need to break their own delegations")
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4state.c | 24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index a501bb9a2fac..eca36d804158 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -4874,6 +4874,11 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
+       if (nf)
+               nfsd_file_put(nf);
++      status = nfserrno(nfsd_open_break_lease(cur_fh->fh_dentry->d_inode,
++                                                              access));
++      if (status)
++              goto out_put_access;
++
+       status = nfsd4_truncate(rqstp, cur_fh, open);
+       if (status)
+               goto out_put_access;
+@@ -6856,11 +6861,20 @@ out:
+ static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
+ {
+       struct nfsd_file *nf;
+-      __be32 err = nfsd_file_acquire(rqstp, fhp, NFSD_MAY_READ, &nf);
+-      if (!err) {
+-              err = nfserrno(vfs_test_lock(nf->nf_file, lock));
+-              nfsd_file_put(nf);
+-      }
++      __be32 err;
++
++      err = nfsd_file_acquire(rqstp, fhp, NFSD_MAY_READ, &nf);
++      if (err)
++              return err;
++      fh_lock(fhp); /* to block new leases till after test_lock: */
++      err = nfserrno(nfsd_open_break_lease(fhp->fh_dentry->d_inode,
++                                                      NFSD_MAY_READ));
++      if (err)
++              goto out;
++      err = nfserrno(vfs_test_lock(nf->nf_file, lock));
++out:
++      fh_unlock(fhp);
++      nfsd_file_put(nf);
+       return err;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfsv4.2-always-flush-out-writes-in-nfs42_proc_falloc.patch b/queue-5.11/nfsv4.2-always-flush-out-writes-in-nfs42_proc_falloc.patch
new file mode 100644 (file)
index 0000000..6ef0350
--- /dev/null
@@ -0,0 +1,78 @@
+From e56617f0dce832dab1c44381ca80c4c2844c4d6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Mar 2021 18:17:14 -0400
+Subject: NFSv4.2: Always flush out writes in nfs42_proc_fallocate()
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 99f23783224355e7022ceea9b8d9f62c0fd01bd8 ]
+
+Whether we're allocating or delallocating space, we should flush out the
+pending writes in order to avoid races with attribute updates.
+
+Fixes: 1e564d3dbd68 ("NFSv4.2: Fix a race in nfs42_proc_deallocate()")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42proc.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index 1edce2d7ecef..7add6332016a 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -90,7 +90,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+ static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+                               loff_t offset, loff_t len)
+ {
+-      struct nfs_server *server = NFS_SERVER(file_inode(filep));
++      struct inode *inode = file_inode(filep);
++      struct nfs_server *server = NFS_SERVER(inode);
+       struct nfs4_exception exception = { };
+       struct nfs_lock_context *lock;
+       int err;
+@@ -99,9 +100,13 @@ static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+       if (IS_ERR(lock))
+               return PTR_ERR(lock);
+-      exception.inode = file_inode(filep);
++      exception.inode = inode;
+       exception.state = lock->open_context->state;
++      err = nfs_sync_inode(inode);
++      if (err)
++              goto out;
++
+       do {
+               err = _nfs42_proc_fallocate(msg, filep, lock, offset, len);
+               if (err == -ENOTSUPP) {
+@@ -110,7 +115,7 @@ static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+               }
+               err = nfs4_handle_exception(server, err, &exception);
+       } while (exception.retry);
+-
++out:
+       nfs_put_lock_context(lock);
+       return err;
+ }
+@@ -148,16 +153,13 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
+               return -EOPNOTSUPP;
+       inode_lock(inode);
+-      err = nfs_sync_inode(inode);
+-      if (err)
+-              goto out_unlock;
+       err = nfs42_proc_fallocate(&msg, filep, offset, len);
+       if (err == 0)
+               truncate_pagecache_range(inode, offset, (offset + len) -1);
+       if (err == -EOPNOTSUPP)
+               NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
+-out_unlock:
++
+       inode_unlock(inode);
+       return err;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfsv4.2-fix-handling-of-sr_eof-in-seek-s-reply.patch b/queue-5.11/nfsv4.2-fix-handling-of-sr_eof-in-seek-s-reply.patch
new file mode 100644 (file)
index 0000000..bd92361
--- /dev/null
@@ -0,0 +1,43 @@
+From 0edfb20fbfea08490843b8e54814a5280e18fd7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 15:30:25 -0400
+Subject: NFSv4.2 fix handling of sr_eof in SEEK's reply
+
+From: Olga Kornievskaia <kolga@netapp.com>
+
+[ Upstream commit 73f5c88f521a630ea1628beb9c2d48a2e777a419 ]
+
+Currently the client ignores the value of the sr_eof of the SEEK
+operation. According to the spec, if the server didn't find the
+requested extent and reached the end of the file, the server
+would return sr_eof=true. In case the request for DATA and no
+data was found (ie in the middle of the hole), then the lseek
+expects that ENXIO would be returned.
+
+Fixes: 1c6dcbe5ceff8 ("NFS: Implement SEEK")
+Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42proc.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index 7add6332016a..b85f7d56a155 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -665,7 +665,10 @@ static loff_t _nfs42_proc_llseek(struct file *filep,
+       if (status)
+               return status;
+-      return vfs_setpos(filep, res.sr_offset, inode->i_sb->s_maxbytes);
++      if (whence == SEEK_DATA && res.sr_eof)
++              return -NFS4ERR_NXIO;
++      else
++              return vfs_setpos(filep, res.sr_offset, inode->i_sb->s_maxbytes);
+ }
+ loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
+-- 
+2.30.2
+
diff --git a/queue-5.11/nfsv4.x-don-t-return-nfs4err_nomatching_layout-if-we.patch b/queue-5.11/nfsv4.x-don-t-return-nfs4err_nomatching_layout-if-we.patch
new file mode 100644 (file)
index 0000000..8d09a06
--- /dev/null
@@ -0,0 +1,61 @@
+From ef3ec9fb17cb197d4dcfce78b65cb794ac9aef43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 15:09:41 -0400
+Subject: NFSv4.x: Don't return NFS4ERR_NOMATCHING_LAYOUT if we're unmounting
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 8926cc8302819be9e67f70409ed001ecb2c924a9 ]
+
+If the NFS super block is being unmounted, then we currently may end up
+telling the server that we've forgotten the layout while it is actually
+still in use by the client.
+In that case, just assume that the client will soon return the layout
+anyway, and so return NFS4ERR_DELAY in response to the layout recall.
+
+Fixes: 58ac3e59235f ("NFSv4/pnfs: Clean up nfs_layout_find_inode()")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/callback_proc.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
+index f7786e00a6a7..ed9d580826f5 100644
+--- a/fs/nfs/callback_proc.c
++++ b/fs/nfs/callback_proc.c
+@@ -137,12 +137,12 @@ static struct inode *nfs_layout_find_inode_by_stateid(struct nfs_client *clp,
+               list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) {
+                       if (!pnfs_layout_is_valid(lo))
+                               continue;
+-                      if (stateid != NULL &&
+-                          !nfs4_stateid_match_other(stateid, &lo->plh_stateid))
++                      if (!nfs4_stateid_match_other(stateid, &lo->plh_stateid))
+                               continue;
+-                      if (!nfs_sb_active(server->super))
+-                              continue;
+-                      inode = igrab(lo->plh_inode);
++                      if (nfs_sb_active(server->super))
++                              inode = igrab(lo->plh_inode);
++                      else
++                              inode = ERR_PTR(-EAGAIN);
+                       rcu_read_unlock();
+                       if (inode)
+                               return inode;
+@@ -176,9 +176,10 @@ static struct inode *nfs_layout_find_inode_by_fh(struct nfs_client *clp,
+                               continue;
+                       if (nfsi->layout != lo)
+                               continue;
+-                      if (!nfs_sb_active(server->super))
+-                              continue;
+-                      inode = igrab(lo->plh_inode);
++                      if (nfs_sb_active(server->super))
++                              inode = igrab(lo->plh_inode);
++                      else
++                              inode = ERR_PTR(-EAGAIN);
+                       rcu_read_unlock();
+                       if (inode)
+                               return inode;
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-brcmstb-use-reset-rearm-instead-of-deassert-asse.patch b/queue-5.11/pci-brcmstb-use-reset-rearm-instead-of-deassert-asse.patch
new file mode 100644 (file)
index 0000000..afd7d2d
--- /dev/null
@@ -0,0 +1,102 @@
+From e37dd57c0bc8d6b6b828f9744e057665f4ba6d04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 11:21:56 -0400
+Subject: PCI: brcmstb: Use reset/rearm instead of deassert/assert
+
+From: Jim Quinlan <jim2101024@gmail.com>
+
+[ Upstream commit bb610757fcd74558ad94fe19993fd4470208dd02 ]
+
+The Broadcom STB PCIe RC uses a reset control "rescal" for certain chips.
+The "rescal" implements a "pulse reset" so using assert/deassert is wrong
+for this device.  Instead, we use reset/rearm.  We need to use rearm so
+that we can reset it after a suspend/resume cycle; w/o using "rearm", the
+"rescal" device will only ever fire once.
+
+Of course for suspend/resume to work we also need to put the reset/rearm
+calls in the suspend and resume routines.
+
+Fixes: 740d6c3708a9 ("PCI: brcmstb: Add control of rescal reset")
+Link: https://lore.kernel.org/r/20210430152156.21162-4-jim2101024@gmail.com
+Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-brcmstb.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
+index d41257f43a8f..7cbd56d8a5ff 100644
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -1127,6 +1127,7 @@ static int brcm_pcie_suspend(struct device *dev)
+       brcm_pcie_turn_off(pcie);
+       ret = brcm_phy_stop(pcie);
++      reset_control_rearm(pcie->rescal);
+       clk_disable_unprepare(pcie->clk);
+       return ret;
+@@ -1142,9 +1143,13 @@ static int brcm_pcie_resume(struct device *dev)
+       base = pcie->base;
+       clk_prepare_enable(pcie->clk);
++      ret = reset_control_reset(pcie->rescal);
++      if (ret)
++              goto err_disable_clk;
++
+       ret = brcm_phy_start(pcie);
+       if (ret)
+-              goto err;
++              goto err_reset;
+       /* Take bridge out of reset so we can access the SERDES reg */
+       pcie->bridge_sw_init_set(pcie, 0);
+@@ -1159,14 +1164,16 @@ static int brcm_pcie_resume(struct device *dev)
+       ret = brcm_pcie_setup(pcie);
+       if (ret)
+-              goto err;
++              goto err_reset;
+       if (pcie->msi)
+               brcm_msi_set_regs(pcie->msi);
+       return 0;
+-err:
++err_reset:
++      reset_control_rearm(pcie->rescal);
++err_disable_clk:
+       clk_disable_unprepare(pcie->clk);
+       return ret;
+ }
+@@ -1176,7 +1183,7 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie)
+       brcm_msi_remove(pcie);
+       brcm_pcie_turn_off(pcie);
+       brcm_phy_stop(pcie);
+-      reset_control_assert(pcie->rescal);
++      reset_control_rearm(pcie->rescal);
+       clk_disable_unprepare(pcie->clk);
+ }
+@@ -1251,13 +1258,13 @@ static int brcm_pcie_probe(struct platform_device *pdev)
+               return PTR_ERR(pcie->rescal);
+       }
+-      ret = reset_control_deassert(pcie->rescal);
++      ret = reset_control_reset(pcie->rescal);
+       if (ret)
+               dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
+       ret = brcm_phy_start(pcie);
+       if (ret) {
+-              reset_control_assert(pcie->rescal);
++              reset_control_rearm(pcie->rescal);
+               clk_disable_unprepare(pcie->clk);
+               return ret;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-endpoint-add-helper-api-to-get-the-next-unreserv.patch b/queue-5.11/pci-endpoint-add-helper-api-to-get-the-next-unreserv.patch
new file mode 100644 (file)
index 0000000..4e379b0
--- /dev/null
@@ -0,0 +1,97 @@
+From 1ce9ec7916c299b3075e00c758c579c08a559183 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Feb 2021 01:27:55 +0530
+Subject: PCI: endpoint: Add helper API to get the 'next' unreserved BAR
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit fa8fef0e104a23efe568b835d9e7e188d1d97610 ]
+
+Add an API to get the next unreserved BAR starting from a given BAR number
+that can be used by the endpoint function.
+
+Link: https://lore.kernel.org/r/20210201195809.7342-4-kishon@ti.com
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/pci-epc-core.c | 26 ++++++++++++++++++++++----
+ include/linux/pci-epc.h             |  2 ++
+ 2 files changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
+index 25e57672e1a1..1afe5d9afb0d 100644
+--- a/drivers/pci/endpoint/pci-epc-core.c
++++ b/drivers/pci/endpoint/pci-epc-core.c
+@@ -87,17 +87,36 @@ EXPORT_SYMBOL_GPL(pci_epc_get);
+  * pci_epc_get_first_free_bar() - helper to get first unreserved BAR
+  * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
+  *
+- * Invoke to get the first unreserved BAR that can be used for endpoint
++ * Invoke to get the first unreserved BAR that can be used by the endpoint
+  * function. For any incorrect value in reserved_bar return '0'.
+  */
+ unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
+                                       *epc_features)
++{
++      return pci_epc_get_next_free_bar(epc_features, BAR_0);
++}
++EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
++
++/**
++ * pci_epc_get_next_free_bar() - helper to get unreserved BAR starting from @bar
++ * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
++ * @bar: the starting BAR number from where unreserved BAR should be searched
++ *
++ * Invoke to get the next unreserved BAR starting from @bar that can be used
++ * for endpoint function. For any incorrect value in reserved_bar return '0'.
++ */
++unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
++                                     *epc_features, enum pci_barno bar)
+ {
+       unsigned long free_bar;
+       if (!epc_features)
+               return 0;
++      /* If 'bar - 1' is a 64-bit BAR, move to the next BAR */
++      if ((epc_features->bar_fixed_64bit << 1) & 1 << bar)
++              bar++;
++
+       /* Find if the reserved BAR is also a 64-bit BAR */
+       free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit;
+@@ -105,14 +124,13 @@ unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
+       free_bar <<= 1;
+       free_bar |= epc_features->reserved_bar;
+-      /* Now find the free BAR */
+-      free_bar = ffz(free_bar);
++      free_bar = find_next_zero_bit(&free_bar, 6, bar);
+       if (free_bar > 5)
+               return 0;
+       return free_bar;
+ }
+-EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
++EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar);
+ /**
+  * pci_epc_get_features() - get the features supported by EPC
+diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
+index cc66bec8be90..cfe9b427e6b7 100644
+--- a/include/linux/pci-epc.h
++++ b/include/linux/pci-epc.h
+@@ -203,6 +203,8 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
+                                                   u8 func_no);
+ unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
+                                       *epc_features);
++unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
++                                     *epc_features, enum pci_barno bar);
+ struct pci_epc *pci_epc_get(const char *epc_name);
+ void pci_epc_put(struct pci_epc *epc);
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-endpoint-fix-missing-destroy_workqueue.patch b/queue-5.11/pci-endpoint-fix-missing-destroy_workqueue.patch
new file mode 100644 (file)
index 0000000..441a9cb
--- /dev/null
@@ -0,0 +1,47 @@
+From 153543b5150094f0be8cc2f717e500c4eff04d4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 16:40:12 +0800
+Subject: PCI: endpoint: Fix missing destroy_workqueue()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit acaef7981a218813e3617edb9c01837808de063c ]
+
+Add the missing destroy_workqueue() before return from
+pci_epf_test_init() in the error handling case and add
+destroy_workqueue() in pci_epf_test_exit().
+
+Link: https://lore.kernel.org/r/20210331084012.2091010-1-yangyingliang@huawei.com
+Fixes: 349e7a85b25fa ("PCI: endpoint: functions: Add an EP function to test PCI")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 5f6ce120a67a..d41570715dc7 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -922,6 +922,7 @@ static int __init pci_epf_test_init(void)
+       ret = pci_epf_register_driver(&test_driver);
+       if (ret) {
++              destroy_workqueue(kpcitest_workqueue);
+               pr_err("Failed to register pci epf test driver --> %d\n", ret);
+               return ret;
+       }
+@@ -932,6 +933,8 @@ module_init(pci_epf_test_init);
+ static void __exit pci_epf_test_exit(void)
+ {
++      if (kpcitest_workqueue)
++              destroy_workqueue(kpcitest_workqueue);
+       pci_epf_unregister_driver(&test_driver);
+ }
+ module_exit(pci_epf_test_exit);
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-endpoint-fix-null-pointer-dereference-for-get_fe.patch b/queue-5.11/pci-endpoint-fix-null-pointer-dereference-for-get_fe.patch
new file mode 100644 (file)
index 0000000..4f4b286
--- /dev/null
@@ -0,0 +1,78 @@
+From 0afdac3cfdeeaa673a9dab985ba9040bd9355b8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Mar 2021 15:46:09 +0530
+Subject: PCI: endpoint: Fix NULL pointer dereference for ->get_features()
+
+From: Shradha Todi <shradha.t@samsung.com>
+
+[ Upstream commit 6613bc2301ba291a1c5a90e1dc24cf3edf223c03 ]
+
+get_features ops of pci_epc_ops may return NULL, causing NULL pointer
+dereference in pci_epf_test_alloc_space function. Let us add a check for
+pci_epc_feature pointer in pci_epf_test_bind before we access it to avoid
+any such NULL pointer dereference and return -ENOTSUPP in case
+pci_epc_feature is not found.
+
+When the patch is not applied and EPC features is not implemented in the
+platform driver, we see the following dump due to kernel NULL pointer
+dereference.
+
+Call trace:
+ pci_epf_test_bind+0xf4/0x388
+ pci_epf_bind+0x3c/0x80
+ pci_epc_epf_link+0xa8/0xcc
+ configfs_symlink+0x1a4/0x48c
+ vfs_symlink+0x104/0x184
+ do_symlinkat+0x80/0xd4
+ __arm64_sys_symlinkat+0x1c/0x24
+ el0_svc_common.constprop.3+0xb8/0x170
+ el0_svc_handler+0x70/0x88
+ el0_svc+0x8/0x640
+Code: d2800581 b9403ab9 f9404ebb 8b394f60 (f9400400)
+---[ end trace a438e3c5a24f9df0 ]---
+
+Link: https://lore.kernel.org/r/20210324101609.79278-1-shradha.t@samsung.com
+Fixes: 2c04c5b8eef79 ("PCI: pci-epf-test: Use pci_epc_get_features() to get EPC features")
+Signed-off-by: Sriram Dash <dash.sriram@gmail.com>
+Signed-off-by: Shradha Todi <shradha.t@samsung.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Pankaj Dubey <pankaj.dubey@samsung.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 | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 7a1f3abfde48..5f6ce120a67a 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -830,15 +830,18 @@ static int pci_epf_test_bind(struct pci_epf *epf)
+               return -EINVAL;
+       epc_features = pci_epc_get_features(epc, epf->func_no);
+-      if (epc_features) {
+-              linkup_notifier = epc_features->linkup_notifier;
+-              core_init_notifier = epc_features->core_init_notifier;
+-              test_reg_bar = pci_epc_get_first_free_bar(epc_features);
+-              if (test_reg_bar < 0)
+-                      return -EINVAL;
+-              pci_epf_configure_bar(epf, epc_features);
++      if (!epc_features) {
++              dev_err(&epf->dev, "epc_features not implemented\n");
++              return -EOPNOTSUPP;
+       }
++      linkup_notifier = epc_features->linkup_notifier;
++      core_init_notifier = epc_features->core_init_notifier;
++      test_reg_bar = pci_epc_get_first_free_bar(epc_features);
++      if (test_reg_bar < 0)
++              return -EINVAL;
++      pci_epf_configure_bar(epf, epc_features);
++
+       epf_test->test_reg_bar = test_reg_bar;
+       epf_test->epc_features = epc_features;
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-endpoint-make-_free_bar-to-return-error-codes-on.patch b/queue-5.11/pci-endpoint-make-_free_bar-to-return-error-codes-on.patch
new file mode 100644 (file)
index 0000000..592f111
--- /dev/null
@@ -0,0 +1,112 @@
+From b047cf74f6dfc371b80a0199a8eb461920916313 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Feb 2021 01:27:56 +0530
+Subject: PCI: endpoint: Make *_free_bar() to return error codes on failure
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit 0e27aeccfa3d1bab7c6a29fb8e6fcedbad7b09a8 ]
+
+Modify pci_epc_get_next_free_bar() and pci_epc_get_first_free_bar() to
+return error values if there are no free BARs available.
+
+Link: https://lore.kernel.org/r/20210201195809.7342-5-kishon@ti.com
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c |  2 ++
+ drivers/pci/endpoint/pci-epc-core.c           | 12 ++++++------
+ include/linux/pci-epc.h                       |  8 ++++----
+ include/linux/pci-epf.h                       |  1 +
+ 4 files changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index e4e51d884553..7a1f3abfde48 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -834,6 +834,8 @@ static int pci_epf_test_bind(struct pci_epf *epf)
+               linkup_notifier = epc_features->linkup_notifier;
+               core_init_notifier = epc_features->core_init_notifier;
+               test_reg_bar = pci_epc_get_first_free_bar(epc_features);
++              if (test_reg_bar < 0)
++                      return -EINVAL;
+               pci_epf_configure_bar(epf, epc_features);
+       }
+diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
+index 1afe5d9afb0d..ea7e7465ce7a 100644
+--- a/drivers/pci/endpoint/pci-epc-core.c
++++ b/drivers/pci/endpoint/pci-epc-core.c
+@@ -90,8 +90,8 @@ EXPORT_SYMBOL_GPL(pci_epc_get);
+  * Invoke to get the first unreserved BAR that can be used by the endpoint
+  * function. For any incorrect value in reserved_bar return '0'.
+  */
+-unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
+-                                      *epc_features)
++enum pci_barno
++pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features)
+ {
+       return pci_epc_get_next_free_bar(epc_features, BAR_0);
+ }
+@@ -105,13 +105,13 @@ EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
+  * Invoke to get the next unreserved BAR starting from @bar that can be used
+  * for endpoint function. For any incorrect value in reserved_bar return '0'.
+  */
+-unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
+-                                     *epc_features, enum pci_barno bar)
++enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
++                                       *epc_features, enum pci_barno bar)
+ {
+       unsigned long free_bar;
+       if (!epc_features)
+-              return 0;
++              return BAR_0;
+       /* If 'bar - 1' is a 64-bit BAR, move to the next BAR */
+       if ((epc_features->bar_fixed_64bit << 1) & 1 << bar)
+@@ -126,7 +126,7 @@ unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
+       free_bar = find_next_zero_bit(&free_bar, 6, bar);
+       if (free_bar > 5)
+-              return 0;
++              return NO_BAR;
+       return free_bar;
+ }
+diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
+index cfe9b427e6b7..88d311bad984 100644
+--- a/include/linux/pci-epc.h
++++ b/include/linux/pci-epc.h
+@@ -201,10 +201,10 @@ int pci_epc_start(struct pci_epc *epc);
+ void pci_epc_stop(struct pci_epc *epc);
+ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
+                                                   u8 func_no);
+-unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
+-                                      *epc_features);
+-unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
+-                                     *epc_features, enum pci_barno bar);
++enum pci_barno
++pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features);
++enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
++                                       *epc_features, enum pci_barno bar);
+ struct pci_epc *pci_epc_get(const char *epc_name);
+ void pci_epc_put(struct pci_epc *epc);
+diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
+index 6644ff3b0702..fa3aca43eb19 100644
+--- a/include/linux/pci-epf.h
++++ b/include/linux/pci-epf.h
+@@ -21,6 +21,7 @@ enum pci_notify_event {
+ };
+ enum pci_barno {
++      NO_BAR = -1,
+       BAR_0,
+       BAR_1,
+       BAR_2,
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-endpoint-make-_get_first_free_bar-take-into-acco.patch b/queue-5.11/pci-endpoint-make-_get_first_free_bar-take-into-acco.patch
new file mode 100644 (file)
index 0000000..30a2347
--- /dev/null
@@ -0,0 +1,57 @@
+From cf0ebfdefbe8691a1fb97b7704542a745a201d1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Feb 2021 01:27:54 +0530
+Subject: PCI: endpoint: Make *_get_first_free_bar() take into account 64 bit
+ BAR
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit 959a48d0eac0321948c9f3d1707ba22c100e92d5 ]
+
+pci_epc_get_first_free_bar() uses only "reserved_bar" member in
+epc_features to get the first unreserved BAR. However if the reserved BAR
+is also a 64-bit BAR, then the next BAR shouldn't be returned (since 64-bit
+BAR uses two BARs).
+
+Make pci_epc_get_first_free_bar() take into account 64 bit BAR while
+returning the first free unreserved BAR.
+
+Link: https://lore.kernel.org/r/20210201195809.7342-3-kishon@ti.com
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/pci-epc-core.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
+index cadd3db0cbb0..25e57672e1a1 100644
+--- a/drivers/pci/endpoint/pci-epc-core.c
++++ b/drivers/pci/endpoint/pci-epc-core.c
+@@ -93,12 +93,20 @@ EXPORT_SYMBOL_GPL(pci_epc_get);
+ unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
+                                       *epc_features)
+ {
+-      int free_bar;
++      unsigned long free_bar;
+       if (!epc_features)
+               return 0;
+-      free_bar = ffz(epc_features->reserved_bar);
++      /* Find if the reserved BAR is also a 64-bit BAR */
++      free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit;
++
++      /* Set the adjacent bit if the reserved BAR is also a 64-bit BAR */
++      free_bar <<= 1;
++      free_bar |= epc_features->reserved_bar;
++
++      /* Now find the free BAR */
++      free_bar = ffz(free_bar);
+       if (free_bar > 5)
+               return 0;
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-iproc-fix-return-value-of-iproc_msi_irq_domain_a.patch b/queue-5.11/pci-iproc-fix-return-value-of-iproc_msi_irq_domain_a.patch
new file mode 100644 (file)
index 0000000..4f82760
--- /dev/null
@@ -0,0 +1,43 @@
+From 57ade81a51d231b02df89c483ba05369b4ffe461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 15:22:02 +0100
+Subject: PCI: iproc: Fix return value of iproc_msi_irq_domain_alloc()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 1e83130f01b04c16579ed5a5e03d729bcffc4c5d ]
+
+IRQ domain alloc function should return zero on success. Non-zero value
+indicates failure.
+
+Link: https://lore.kernel.org/r/20210303142202.25780-1-pali@kernel.org
+Fixes: fc54bae28818 ("PCI: iproc: Allow allocation of multiple MSIs")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Krzysztof WilczyÅ„ski <kw@linux.com>
+Acked-by: Ray Jui <ray.jui@broadcom.com>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-iproc-msi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/pcie-iproc-msi.c b/drivers/pci/controller/pcie-iproc-msi.c
+index 908475d27e0e..eede4e8f3f75 100644
+--- a/drivers/pci/controller/pcie-iproc-msi.c
++++ b/drivers/pci/controller/pcie-iproc-msi.c
+@@ -271,7 +271,7 @@ static int iproc_msi_irq_domain_alloc(struct irq_domain *domain,
+                                   NULL, NULL);
+       }
+-      return hwirq;
++      return 0;
+ }
+ static void iproc_msi_irq_domain_free(struct irq_domain *domain,
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-rcec-fix-rciep-device-to-rcec-association.patch b/queue-5.11/pci-rcec-fix-rciep-device-to-rcec-association.patch
new file mode 100644 (file)
index 0000000..e9ceb02
--- /dev/null
@@ -0,0 +1,47 @@
+From 140be354e76b12caa5335d56c1f2ae7ed7c6823f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Feb 2021 09:17:17 +0800
+Subject: PCI/RCEC: Fix RCiEP device to RCEC association
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit d9b7eae8e3424c3480fe9f40ebafbb0c96426e4c ]
+
+rcec_assoc_rciep() used "rciep->devfn" (a single byte encoding both the
+device and function number) as the device number to check whether the
+corresponding bit was set in the RCEC's Association Bitmap for RCiEPs.
+
+But per PCIe r5.0, sec 7.9.10.2, "Association Bitmap for RCiEPs", the
+32-bit bitmap contains one bit per device.  That bit applies to all
+functions of the device.
+
+Fix rcec_assoc_rciep() to convert the value of "rciep->devfn" to a device
+number to ensure that RCiEP devices are correctly associated with the RCEC.
+
+Reported-and-tested-by: Wen Jin <wen.jin@intel.com>
+Fixes: 507b460f8144 ("PCI/ERR: Add pcie_link_rcec() to associate RCiEPs")
+Link: https://lore.kernel.org/r/20210222011717.43266-1-qiuxu.zhuo@intel.com
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Sean V Kelley <sean.v.kelley@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/rcec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pcie/rcec.c b/drivers/pci/pcie/rcec.c
+index 2c5c552994e4..d0bcd141ac9c 100644
+--- a/drivers/pci/pcie/rcec.c
++++ b/drivers/pci/pcie/rcec.c
+@@ -32,7 +32,7 @@ static bool rcec_assoc_rciep(struct pci_dev *rcec, struct pci_dev *rciep)
+       /* Same bus, so check bitmap */
+       for_each_set_bit(devn, &bitmap, 32)
+-              if (devn == rciep->devfn)
++              if (devn == PCI_SLOT(rciep->devfn))
+                       return true;
+       return false;
+-- 
+2.30.2
+
diff --git a/queue-5.11/pci-release-of-node-in-pci_scan_device-s-error-path.patch b/queue-5.11/pci-release-of-node-in-pci_scan_device-s-error-path.patch
new file mode 100644 (file)
index 0000000..8a91d07
--- /dev/null
@@ -0,0 +1,38 @@
+From 6afbf93fdd366d12e6d133ac46ca6c6eac315a8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jan 2021 02:28:26 +0300
+Subject: PCI: Release OF node in pci_scan_device()'s error path
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit c99e755a4a4c165cad6effb39faffd0f3377c02d ]
+
+In pci_scan_device(), if pci_setup_device() fails for any reason, the code
+will not release device's of_node by calling pci_release_of_node().  Fix
+that by calling the release function.
+
+Fixes: 98d9f30c820d ("pci/of: Match PCI devices to OF nodes dynamically")
+Link: https://lore.kernel.org/r/20210124232826.1879-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/probe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 953f15abc850..be51670572fa 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -2353,6 +2353,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
+       pci_set_of_node(dev);
+       if (pci_setup_device(dev)) {
++              pci_release_of_node(dev);
+               pci_bus_put(dev->bus);
+               kfree(dev);
+               return NULL;
+-- 
+2.30.2
+
diff --git a/queue-5.11/pinctrl-samsung-use-int-for-register-masks-in-exynos.patch b/queue-5.11/pinctrl-samsung-use-int-for-register-masks-in-exynos.patch
new file mode 100644 (file)
index 0000000..dcf3691
--- /dev/null
@@ -0,0 +1,72 @@
+From 88560d99f344c8ea4dc7e23ead3c7f51d37e91e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 21:50:29 +0200
+Subject: pinctrl: samsung: use 'int' for register masks in Exynos
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit fa0c10a5f3a49130dd11281aa27e7e1c8654abc7 ]
+
+The Special Function Registers on all Exynos SoC, including ARM64, are
+32-bit wide, so entire driver uses matching functions like readl() or
+writel().  On 64-bit ARM using unsigned long for register masks:
+1. makes little sense as immediately after bitwise operation it will be
+   cast to 32-bit value when calling writel(),
+2. is actually error-prone because it might promote other operands to
+   64-bit.
+
+Addresses-Coverity: Unintentional integer overflow
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Link: https://lore.kernel.org/r/20210408195029.69974-1-krzysztof.kozlowski@canonical.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/samsung/pinctrl-exynos.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
+index b9ea09fabf84..493079a47d05 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
++++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
+@@ -55,7 +55,7 @@ static void exynos_irq_mask(struct irq_data *irqd)
+       struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
+-      unsigned long mask;
++      unsigned int mask;
+       unsigned long flags;
+       spin_lock_irqsave(&bank->slock, flags);
+@@ -83,7 +83,7 @@ static void exynos_irq_unmask(struct irq_data *irqd)
+       struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
+-      unsigned long mask;
++      unsigned int mask;
+       unsigned long flags;
+       /*
+@@ -483,7 +483,7 @@ static void exynos_irq_eint0_15(struct irq_desc *desc)
+       chained_irq_exit(chip, desc);
+ }
+-static inline void exynos_irq_demux_eint(unsigned long pend,
++static inline void exynos_irq_demux_eint(unsigned int pend,
+                                               struct irq_domain *domain)
+ {
+       unsigned int irq;
+@@ -500,8 +500,8 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
+ {
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+       struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc);
+-      unsigned long pend;
+-      unsigned long mask;
++      unsigned int pend;
++      unsigned int mask;
+       int i;
+       chained_irq_enter(chip, desc);
+-- 
+2.30.2
+
diff --git a/queue-5.11/pnfs-flexfiles-fix-incorrect-size-check-in-decode_nf.patch b/queue-5.11/pnfs-flexfiles-fix-incorrect-size-check-in-decode_nf.patch
new file mode 100644 (file)
index 0000000..079e2d0
--- /dev/null
@@ -0,0 +1,52 @@
+From d5df9af8e554281b8e2b6bd539c76050e3cd4211 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 11:56:49 +0300
+Subject: pNFS/flexfiles: fix incorrect size check in decode_nfs_fh()
+
+From: Nikola Livic <nlivic@gmail.com>
+
+[ Upstream commit ed34695e15aba74f45247f1ee2cf7e09d449f925 ]
+
+We (adam zabrocki, alexander matrosov, alexander tereshkin, maksym
+bazalii) observed the check:
+
+       if (fh->size > sizeof(struct nfs_fh))
+
+should not use the size of the nfs_fh struct which includes an extra two
+bytes from the size field.
+
+struct nfs_fh {
+       unsigned short         size;
+       unsigned char          data[NFS_MAXFHSIZE];
+}
+
+but should determine the size from data[NFS_MAXFHSIZE] so the memcpy
+will not write 2 bytes beyond destination.  The proposed fix is to
+compare against the NFS_MAXFHSIZE directly, as is done elsewhere in fs
+code base.
+
+Fixes: d67ae825a59d ("pnfs/flexfiles: Add the FlexFile Layout Driver")
+Signed-off-by: Nikola Livic <nlivic@gmail.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/flexfilelayout/flexfilelayout.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
+index 872112bffcab..d383de00d486 100644
+--- a/fs/nfs/flexfilelayout/flexfilelayout.c
++++ b/fs/nfs/flexfilelayout/flexfilelayout.c
+@@ -106,7 +106,7 @@ static int decode_nfs_fh(struct xdr_stream *xdr, struct nfs_fh *fh)
+       if (unlikely(!p))
+               return -ENOBUFS;
+       fh->size = be32_to_cpup(p++);
+-      if (fh->size > sizeof(struct nfs_fh)) {
++      if (fh->size > NFS_MAXFHSIZE) {
+               printk(KERN_ERR "NFS flexfiles: Too big fh received %d\n",
+                      fh->size);
+               return -EOVERFLOW;
+-- 
+2.30.2
+
diff --git a/queue-5.11/powerpc-32-statically-initialise-first-emergency-con.patch b/queue-5.11/powerpc-32-statically-initialise-first-emergency-con.patch
new file mode 100644 (file)
index 0000000..5e64a0f
--- /dev/null
@@ -0,0 +1,59 @@
+From 7337e7086bbc33633fa6e38f3531b5138b05c05d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 12:50:25 +0000
+Subject: powerpc/32: Statically initialise first emergency context
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit a4719f5bb6d7dc220bffdc1b9f5ce5eaa5543581 ]
+
+The check of the emergency context initialisation in
+vmap_stack_overflow is buggy for the SMP case, as it
+compares r1 with 0 while in the SMP case r1 is offseted
+by the CPU id.
+
+Instead of fixing it, just perform static initialisation
+of the first emergency context.
+
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/4a67ba422be75713286dca0c86ee0d3df2eb6dfa.1615552867.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/head_32.h  | 6 +-----
+ arch/powerpc/kernel/setup_32.c | 2 +-
+ 2 files changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h
+index abc7b603ab65..294dd0082ad2 100644
+--- a/arch/powerpc/kernel/head_32.h
++++ b/arch/powerpc/kernel/head_32.h
+@@ -331,11 +331,7 @@ label:
+       lis     r1, emergency_ctx@ha
+ #endif
+       lwz     r1, emergency_ctx@l(r1)
+-      cmpwi   cr1, r1, 0
+-      bne     cr1, 1f
+-      lis     r1, init_thread_union@ha
+-      addi    r1, r1, init_thread_union@l
+-1:    addi    r1, r1, THREAD_SIZE - INT_FRAME_SIZE
++      addi    r1, r1, THREAD_SIZE - INT_FRAME_SIZE
+       EXCEPTION_PROLOG_2
+       SAVE_NVGPRS(r11)
+       addi    r3, r1, STACK_FRAME_OVERHEAD
+diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
+index 8ba49a6bf515..d7c1f92152af 100644
+--- a/arch/powerpc/kernel/setup_32.c
++++ b/arch/powerpc/kernel/setup_32.c
+@@ -164,7 +164,7 @@ void __init irqstack_early_init(void)
+ }
+ #ifdef CONFIG_VMAP_STACK
+-void *emergency_ctx[NR_CPUS] __ro_after_init;
++void *emergency_ctx[NR_CPUS] __ro_after_init = {[0] = &init_stack};
+ void __init emergency_stack_init(void)
+ {
+-- 
+2.30.2
+
diff --git a/queue-5.11/powerpc-iommu-annotate-nested-lock-for-lockdep.patch b/queue-5.11/powerpc-iommu-annotate-nested-lock-for-lockdep.patch
new file mode 100644 (file)
index 0000000..d68bfa8
--- /dev/null
@@ -0,0 +1,70 @@
+From 3a61428d97174c33b177d80cc982c7822e4ce29a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 17:36:53 +1100
+Subject: powerpc/iommu: Annotate nested lock for lockdep
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+[ Upstream commit cc7130bf119add37f36238343a593b71ef6ecc1e ]
+
+The IOMMU table is divided into pools for concurrent mappings and each
+pool has a separate spinlock. When taking the ownership of an IOMMU group
+to pass through a device to a VM, we lock these spinlocks which triggers
+a false negative warning in lockdep (below).
+
+This fixes it by annotating the large pool's spinlock as a nest lock
+which makes lockdep not complaining when locking nested locks if
+the nest lock is locked already.
+
+===
+WARNING: possible recursive locking detected
+5.11.0-le_syzkaller_a+fstn1 #100 Not tainted
+--------------------------------------------
+qemu-system-ppc/4129 is trying to acquire lock:
+c0000000119bddb0 (&(p->lock)/1){....}-{2:2}, at: iommu_take_ownership+0xac/0x1e0
+
+but task is already holding lock:
+c0000000119bdd30 (&(p->lock)/1){....}-{2:2}, at: iommu_take_ownership+0xac/0x1e0
+
+other info that might help us debug this:
+ Possible unsafe locking scenario:
+
+       CPU0
+       ----
+  lock(&(p->lock)/1);
+  lock(&(p->lock)/1);
+===
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210301063653.51003-1-aik@ozlabs.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/iommu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
+index 5b69a6a72a0e..6806eefa52ce 100644
+--- a/arch/powerpc/kernel/iommu.c
++++ b/arch/powerpc/kernel/iommu.c
+@@ -1050,7 +1050,7 @@ int iommu_take_ownership(struct iommu_table *tbl)
+       spin_lock_irqsave(&tbl->large_pool.lock, flags);
+       for (i = 0; i < tbl->nr_pools; i++)
+-              spin_lock(&tbl->pools[i].lock);
++              spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock);
+       iommu_table_release_pages(tbl);
+@@ -1078,7 +1078,7 @@ void iommu_release_ownership(struct iommu_table *tbl)
+       spin_lock_irqsave(&tbl->large_pool.lock, flags);
+       for (i = 0; i < tbl->nr_pools; i++)
+-              spin_lock(&tbl->pools[i].lock);
++              spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock);
+       memset(tbl->it_map, 0, sz);
+-- 
+2.30.2
+
diff --git a/queue-5.11/powerpc-mm-add-cond_resched-while-removing-hpte-mapp.patch b/queue-5.11/powerpc-mm-add-cond_resched-while-removing-hpte-mapp.patch
new file mode 100644 (file)
index 0000000..248d1a6
--- /dev/null
@@ -0,0 +1,87 @@
+From fe23e781e9b731a7717ee01f0302ea61615a0d35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Apr 2021 22:01:48 +0530
+Subject: powerpc/mm: Add cond_resched() while removing hpte mappings
+
+From: Vaibhav Jain <vaibhav@linux.ibm.com>
+
+[ Upstream commit a5d6a3e73acbd619dd5b7b831762b755f9e2db80 ]
+
+While removing large number of mappings from hash page tables for
+large memory systems as soft-lockup is reported because of the time
+spent inside htap_remove_mapping() like one below:
+
+ watchdog: BUG: soft lockup - CPU#8 stuck for 23s!
+ <snip>
+ NIP plpar_hcall+0x38/0x58
+ LR  pSeries_lpar_hpte_invalidate+0x68/0xb0
+ Call Trace:
+  0x1fffffffffff000 (unreliable)
+  pSeries_lpar_hpte_removebolted+0x9c/0x230
+  hash__remove_section_mapping+0xec/0x1c0
+  remove_section_mapping+0x28/0x3c
+  arch_remove_memory+0xfc/0x150
+  devm_memremap_pages_release+0x180/0x2f0
+  devm_action_release+0x30/0x50
+  release_nodes+0x28c/0x300
+  device_release_driver_internal+0x16c/0x280
+  unbind_store+0x124/0x170
+  drv_attr_store+0x44/0x60
+  sysfs_kf_write+0x64/0x90
+  kernfs_fop_write+0x1b0/0x290
+  __vfs_write+0x3c/0x70
+  vfs_write+0xd4/0x270
+  ksys_write+0xdc/0x130
+  system_call+0x5c/0x70
+
+Fix this by adding a cond_resched() to the loop in
+htap_remove_mapping() that issues hcall to remove hpte mapping. The
+call to cond_resched() is issued every HZ jiffies which should prevent
+the soft-lockup from being reported.
+
+Suggested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210404163148.321346-1-vaibhav@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/book3s64/hash_utils.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
+index 73b06adb6eeb..f81b09769e0b 100644
+--- a/arch/powerpc/mm/book3s64/hash_utils.c
++++ b/arch/powerpc/mm/book3s64/hash_utils.c
+@@ -337,7 +337,7 @@ repeat:
+ int htab_remove_mapping(unsigned long vstart, unsigned long vend,
+                     int psize, int ssize)
+ {
+-      unsigned long vaddr;
++      unsigned long vaddr, time_limit;
+       unsigned int step, shift;
+       int rc;
+       int ret = 0;
+@@ -350,8 +350,19 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend,
+       /* Unmap the full range specificied */
+       vaddr = ALIGN_DOWN(vstart, step);
++      time_limit = jiffies + HZ;
++
+       for (;vaddr < vend; vaddr += step) {
+               rc = mmu_hash_ops.hpte_removebolted(vaddr, psize, ssize);
++
++              /*
++               * For large number of mappings introduce a cond_resched()
++               * to prevent softlockup warnings.
++               */
++              if (time_after(jiffies, time_limit)) {
++                      cond_resched();
++                      time_limit = jiffies + HZ;
++              }
+               if (rc == -ENOENT) {
+                       ret = -ENOENT;
+                       continue;
+-- 
+2.30.2
+
diff --git a/queue-5.11/powerpc-pseries-stop-calling-printk-in-rtas_stop_sel.patch b/queue-5.11/powerpc-pseries-stop-calling-printk-in-rtas_stop_sel.patch
new file mode 100644 (file)
index 0000000..8176124
--- /dev/null
@@ -0,0 +1,72 @@
+From b7430494f411cf8b61afbb93de4ff9b6ce511061 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Apr 2021 23:54:13 +1000
+Subject: powerpc/pseries: Stop calling printk in rtas_stop_self()
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit ed8029d7b472369a010a1901358567ca3b6dbb0d ]
+
+RCU complains about us calling printk() from an offline CPU:
+
+  =============================
+  WARNING: suspicious RCU usage
+  5.12.0-rc7-02874-g7cf90e481cb8 #1 Not tainted
+  -----------------------------
+  kernel/locking/lockdep.c:3568 RCU-list traversed in non-reader section!!
+
+  other info that might help us debug this:
+
+  RCU used illegally from offline CPU!
+  rcu_scheduler_active = 2, debug_locks = 1
+  no locks held by swapper/0/0.
+
+  stack backtrace:
+  CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.12.0-rc7-02874-g7cf90e481cb8 #1
+  Call Trace:
+    dump_stack+0xec/0x144 (unreliable)
+    lockdep_rcu_suspicious+0x124/0x144
+    __lock_acquire+0x1098/0x28b0
+    lock_acquire+0x128/0x600
+    _raw_spin_lock_irqsave+0x6c/0xc0
+    down_trylock+0x2c/0x70
+    __down_trylock_console_sem+0x60/0x140
+    vprintk_emit+0x1a8/0x4b0
+    vprintk_func+0xcc/0x200
+    printk+0x40/0x54
+    pseries_cpu_offline_self+0xc0/0x120
+    arch_cpu_idle_dead+0x54/0x70
+    do_idle+0x174/0x4a0
+    cpu_startup_entry+0x38/0x40
+    rest_init+0x268/0x388
+    start_kernel+0x748/0x790
+    start_here_common+0x1c/0x614
+
+Which happens because by the time we get to rtas_stop_self() we are
+already offline. In addition the message can be spammy, and is not that
+helpful for users, so remove it.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210418135413.1204031-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/hotplug-cpu.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+index 12cbffd3c2e3..325f3b220f36 100644
+--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
++++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+@@ -47,9 +47,6 @@ static void rtas_stop_self(void)
+       BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
+-      printk("cpu %u (hwid %u) Ready to die...\n",
+-             smp_processor_id(), hard_smp_processor_id());
+-
+       rtas_call_unlocked(&args, rtas_stop_self_token, 0, 1, NULL);
+       panic("Alas, I survived.\n");
+-- 
+2.30.2
+
diff --git a/queue-5.11/powerpc-smp-set-numa-node-before-updating-mask.patch b/queue-5.11/powerpc-smp-set-numa-node-before-updating-mask.patch
new file mode 100644 (file)
index 0000000..81767db
--- /dev/null
@@ -0,0 +1,90 @@
+From 5a370c5e598cd323833bd21e862ceded5d049dea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Apr 2021 21:12:00 +0530
+Subject: powerpc/smp: Set numa node before updating mask
+
+From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+
+[ Upstream commit 6980d13f0dd189846887bbbfa43793d9a41768d3 ]
+
+Geethika reported a trace when doing a dlpar CPU add.
+
+------------[ cut here ]------------
+WARNING: CPU: 152 PID: 1134 at kernel/sched/topology.c:2057
+CPU: 152 PID: 1134 Comm: kworker/152:1 Not tainted 5.12.0-rc5-master #5
+Workqueue: events cpuset_hotplug_workfn
+NIP:  c0000000001cfc14 LR: c0000000001cfc10 CTR: c0000000007e3420
+REGS: c0000034a08eb260 TRAP: 0700   Not tainted  (5.12.0-rc5-master+)
+MSR:  8000000000029033 <SF,EE,ME,IR,DR,RI,LE>  CR: 28828422  XER: 00000020
+CFAR: c0000000001fd888 IRQMASK: 0 #012GPR00: c0000000001cfc10
+c0000034a08eb500 c000000001f35400 0000000000000027 #012GPR04:
+c0000035abaa8010 c0000035abb30a00 0000000000000027 c0000035abaa8018
+#012GPR08: 0000000000000023 c0000035abaaef48 00000035aa540000
+c0000035a49dffe8 #012GPR12: 0000000028828424 c0000035bf1a1c80
+0000000000000497 0000000000000004 #012GPR16: c00000000347a258
+0000000000000140 c00000000203d468 c000000001a1a490 #012GPR20:
+c000000001f9c160 c0000034adf70920 c0000034aec9fd20 0000000100087bd3
+#012GPR24: 0000000100087bd3 c0000035b3de09f8 0000000000000030
+c0000035b3de09f8 #012GPR28: 0000000000000028 c00000000347a280
+c0000034aefe0b00 c0000000010a2a68
+NIP [c0000000001cfc14] build_sched_domains+0x6a4/0x1500
+LR [c0000000001cfc10] build_sched_domains+0x6a0/0x1500
+Call Trace:
+[c0000034a08eb500] [c0000000001cfc10] build_sched_domains+0x6a0/0x1500 (unreliable)
+[c0000034a08eb640] [c0000000001d1e6c] partition_sched_domains_locked+0x3ec/0x530
+[c0000034a08eb6e0] [c0000000002936d4] rebuild_sched_domains_locked+0x524/0xbf0
+[c0000034a08eb7e0] [c000000000296bb0] rebuild_sched_domains+0x40/0x70
+[c0000034a08eb810] [c000000000296e74] cpuset_hotplug_workfn+0x294/0xe20
+[c0000034a08ebc30] [c000000000178dd0] process_one_work+0x300/0x670
+[c0000034a08ebd10] [c0000000001791b8] worker_thread+0x78/0x520
+[c0000034a08ebda0] [c000000000185090] kthread+0x1a0/0x1b0
+[c0000034a08ebe10] [c00000000000ccec] ret_from_kernel_thread+0x5c/0x70
+Instruction dump:
+7d2903a6 4e800421 e8410018 7f67db78 7fe6fb78 7f45d378 7f84e378 7c681b78
+3c62ff1a 3863c6f8 4802dc35 60000000 <0fe00000> 3920fff4 f9210070 e86100a0
+---[ end trace 532d9066d3d4d7ec ]---
+
+Some of the per-CPU masks use cpu_cpu_mask as a filter to limit the search
+for related CPUs. On a dlpar add of a CPU, update cpu_cpu_mask before
+updating the per-CPU masks. This will ensure the cpu_cpu_mask is updated
+correctly before its used in setting the masks. Setting the numa_node will
+ensure that when cpu_cpu_mask() gets called, the correct node number is
+used. This code movement helped fix the above call trace.
+
+Reported-by: Geetika Moolchandani <Geetika.Moolchandani1@ibm.com>
+Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+Reviewed-by: Nathan Lynch <nathanl@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210401154200.150077-1-srikar@linux.vnet.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/smp.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
+index d1bc51a128b2..e285d55f9213 100644
+--- a/arch/powerpc/kernel/smp.c
++++ b/arch/powerpc/kernel/smp.c
+@@ -1545,6 +1545,9 @@ void start_secondary(void *unused)
+       vdso_getcpu_init();
+ #endif
++      set_numa_node(numa_cpu_lookup_table[cpu]);
++      set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu]));
++
+       /* Update topology CPU masks */
+       add_cpu_to_masks(cpu);
+@@ -1563,9 +1566,6 @@ void start_secondary(void *unused)
+                       shared_caches = true;
+       }
+-      set_numa_node(numa_cpu_lookup_table[cpu]);
+-      set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu]));
+-
+       smp_wmb();
+       notify_cpu_starting(cpu);
+       set_cpu_online(cpu, true);
+-- 
+2.30.2
+
diff --git a/queue-5.11/powerpc-xive-use-the-ibm-chip-id-property-only-under.patch b/queue-5.11/powerpc-xive-use-the-ibm-chip-id-property-only-under.patch
new file mode 100644 (file)
index 0000000..55c2deb
--- /dev/null
@@ -0,0 +1,101 @@
+From b37b02b70ee04e865c0ea59e57b01d8291711ac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Apr 2021 15:03:52 +0200
+Subject: powerpc/xive: Use the "ibm, chip-id" property only under PowerNV
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cédric Le Goater <clg@kaod.org>
+
+[ Upstream commit e9e16917bc388846163b8566a298a291d71e44c9 ]
+
+The 'chip_id' field of the XIVE CPU structure is used to choose a
+target for a source located on the same chip. For that, the XIVE
+driver queries the chip identifier from the "ibm,chip-id" property
+and compares it to a 'src_chip' field identifying the chip of a
+source. This information is only available on the PowerNV platform,
+'src_chip' being assigned to XIVE_INVALID_CHIP_ID under pSeries.
+
+The "ibm,chip-id" property is also not available on all platforms. It
+was first introduced on PowerNV and later, under QEMU for pSeries/KVM.
+However, the property is not part of PAPR and does not exist under
+pSeries/PowerVM.
+
+Assign 'chip_id' to XIVE_INVALID_CHIP_ID by default and let the
+PowerNV platform override the value with the "ibm,chip-id" property.
+
+Signed-off-by: Cédric Le Goater <clg@kaod.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210413130352.1183267-1-clg@kaod.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/sysdev/xive/common.c        | 9 +++------
+ arch/powerpc/sysdev/xive/native.c        | 6 ++++++
+ arch/powerpc/sysdev/xive/xive-internal.h | 1 +
+ 3 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
+index 5cacb632eb37..31b657c37735 100644
+--- a/arch/powerpc/sysdev/xive/common.c
++++ b/arch/powerpc/sysdev/xive/common.c
+@@ -1341,17 +1341,14 @@ static int xive_prepare_cpu(unsigned int cpu)
+       xc = per_cpu(xive_cpu, cpu);
+       if (!xc) {
+-              struct device_node *np;
+-
+               xc = kzalloc_node(sizeof(struct xive_cpu),
+                                 GFP_KERNEL, cpu_to_node(cpu));
+               if (!xc)
+                       return -ENOMEM;
+-              np = of_get_cpu_node(cpu, NULL);
+-              if (np)
+-                      xc->chip_id = of_get_ibm_chip_id(np);
+-              of_node_put(np);
+               xc->hw_ipi = XIVE_BAD_IRQ;
++              xc->chip_id = XIVE_INVALID_CHIP_ID;
++              if (xive_ops->prepare_cpu)
++                      xive_ops->prepare_cpu(cpu, xc);
+               per_cpu(xive_cpu, cpu) = xc;
+       }
+diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c
+index 05a800a3104e..57e3f1540435 100644
+--- a/arch/powerpc/sysdev/xive/native.c
++++ b/arch/powerpc/sysdev/xive/native.c
+@@ -380,6 +380,11 @@ static void xive_native_update_pending(struct xive_cpu *xc)
+       }
+ }
++static void xive_native_prepare_cpu(unsigned int cpu, struct xive_cpu *xc)
++{
++      xc->chip_id = cpu_to_chip_id(cpu);
++}
++
+ static void xive_native_setup_cpu(unsigned int cpu, struct xive_cpu *xc)
+ {
+       s64 rc;
+@@ -462,6 +467,7 @@ static const struct xive_ops xive_native_ops = {
+       .match                  = xive_native_match,
+       .shutdown               = xive_native_shutdown,
+       .update_pending         = xive_native_update_pending,
++      .prepare_cpu            = xive_native_prepare_cpu,
+       .setup_cpu              = xive_native_setup_cpu,
+       .teardown_cpu           = xive_native_teardown_cpu,
+       .sync_source            = xive_native_sync_source,
+diff --git a/arch/powerpc/sysdev/xive/xive-internal.h b/arch/powerpc/sysdev/xive/xive-internal.h
+index 9cf57c722faa..6478be19b4d3 100644
+--- a/arch/powerpc/sysdev/xive/xive-internal.h
++++ b/arch/powerpc/sysdev/xive/xive-internal.h
+@@ -46,6 +46,7 @@ struct xive_ops {
+                                 u32 *sw_irq);
+       int     (*setup_queue)(unsigned int cpu, struct xive_cpu *xc, u8 prio);
+       void    (*cleanup_queue)(unsigned int cpu, struct xive_cpu *xc, u8 prio);
++      void    (*prepare_cpu)(unsigned int cpu, struct xive_cpu *xc);
+       void    (*setup_cpu)(unsigned int cpu, struct xive_cpu *xc);
+       void    (*teardown_cpu)(unsigned int cpu, struct xive_cpu *xc);
+       bool    (*match)(struct device_node *np);
+-- 
+2.30.2
+
diff --git a/queue-5.11/pwm-atmel-fix-duty-cycle-calculation-in-.get_state.patch b/queue-5.11/pwm-atmel-fix-duty-cycle-calculation-in-.get_state.patch
new file mode 100644 (file)
index 0000000..f5c6a9a
--- /dev/null
@@ -0,0 +1,39 @@
+From d28cb570899d33956c4704e39f3b037687b9832e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Apr 2021 11:51:17 +0200
+Subject: pwm: atmel: Fix duty cycle calculation in .get_state()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 453e8b3d8e36ddcb283b3d1698864a03ea45599a ]
+
+The CDTY register contains the number of inactive cycles. .apply() does
+this correctly, however .get_state() got this wrong.
+
+Fixes: 651b510a74d4 ("pwm: atmel: Implement .get_state()")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-atmel.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
+index 5813339b597b..3292158157b6 100644
+--- a/drivers/pwm/pwm-atmel.c
++++ b/drivers/pwm/pwm-atmel.c
+@@ -319,7 +319,7 @@ static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+               cdty = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
+                                         atmel_pwm->data->regs.duty);
+-              tmp = (u64)cdty * NSEC_PER_SEC;
++              tmp = (u64)(cprd - cdty) * NSEC_PER_SEC;
+               tmp <<= pres;
+               state->duty_cycle = DIV64_U64_ROUND_UP(tmp, rate);
+-- 
+2.30.2
+
diff --git a/queue-5.11/qtnfmac-fix-possible-buffer-overflow-in-qtnf_event_h.patch b/queue-5.11/qtnfmac-fix-possible-buffer-overflow-in-qtnf_event_h.patch
new file mode 100644 (file)
index 0000000..37e579e
--- /dev/null
@@ -0,0 +1,43 @@
+From ef2e73d8a94344ff219ee9c6171ac31a69347b9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 15:58:42 +0100
+Subject: qtnfmac: Fix possible buffer overflow in
+ qtnf_event_handle_external_auth
+
+From: Lee Gibson <leegib@gmail.com>
+
+[ Upstream commit 130f634da1af649205f4a3dd86cbe5c126b57914 ]
+
+Function qtnf_event_handle_external_auth calls memcpy without
+checking the length.
+A user could control that length and trigger a buffer overflow.
+Fix by checking the length is within the maximum allowed size.
+
+Signed-off-by: Lee Gibson <leegib@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210419145842.345787-1-leegib@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/quantenna/qtnfmac/event.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
+index c775c177933b..8dc80574d08d 100644
+--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
+@@ -570,8 +570,10 @@ qtnf_event_handle_external_auth(struct qtnf_vif *vif,
+               return 0;
+       if (ev->ssid_len) {
+-              memcpy(auth.ssid.ssid, ev->ssid, ev->ssid_len);
+-              auth.ssid.ssid_len = ev->ssid_len;
++              int len = clamp_val(ev->ssid_len, 0, IEEE80211_MAX_SSID_LEN);
++
++              memcpy(auth.ssid.ssid, ev->ssid, len);
++              auth.ssid.ssid_len = len;
+       }
+       auth.key_mgmt_suite = le32_to_cpu(ev->akm_suite);
+-- 
+2.30.2
+
diff --git a/queue-5.11/remoteproc-pru-fix-and-cleanup-firmware-interrupt-ma.patch b/queue-5.11/remoteproc-pru-fix-and-cleanup-firmware-interrupt-ma.patch
new file mode 100644 (file)
index 0000000..1ddf6db
--- /dev/null
@@ -0,0 +1,103 @@
+From 6ae0a3ad4f69f7913dcc2fa47ca99adccae0def0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 10:56:41 -0500
+Subject: remoteproc: pru: Fix and cleanup firmware interrupt mapping logic
+
+From: Suman Anna <s-anna@ti.com>
+
+[ Upstream commit 880a66e026fbe6a17cd59fe0ee942bbad62a6c26 ]
+
+The PRU firmware interrupt mappings are configured and unconfigured in
+.start() and .stop() callbacks respectively using the variables 'evt_count'
+and a 'mapped_irq' pointer. These variables are modified only during these
+callbacks but are not re-initialized/reset properly during unwind or
+failure paths. These stale values caused a kernel crash while stopping a
+PRU remoteproc running a different firmware with no events on a subsequent
+run after a previous run that was running a firmware with events.
+
+Fix this crash by ensuring that the evt_count is 0 and the mapped_irq
+pointer is set to NULL in pru_dispose_irq_mapping(). Also, reset these
+variables properly during any failures in the .start() callback. While
+at this, the pru_dispose_irq_mapping() callsites are all made to look
+the same, moving any conditional logic to inside the function.
+
+Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Fixes: c75c9fdac66e ("remoteproc: pru: Add support for PRU specific interrupt configuration")
+Reported-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Suman Anna <s-anna@ti.com>
+Link: https://lore.kernel.org/r/20210407155641.5501-4-s-anna@ti.com
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/pru_rproc.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
+index dcd5ea0d1f37..549ed3fed625 100644
+--- a/drivers/remoteproc/pru_rproc.c
++++ b/drivers/remoteproc/pru_rproc.c
+@@ -266,12 +266,17 @@ static void pru_rproc_create_debug_entries(struct rproc *rproc)
+ static void pru_dispose_irq_mapping(struct pru_rproc *pru)
+ {
+-      while (pru->evt_count--) {
++      if (!pru->mapped_irq)
++              return;
++
++      while (pru->evt_count) {
++              pru->evt_count--;
+               if (pru->mapped_irq[pru->evt_count] > 0)
+                       irq_dispose_mapping(pru->mapped_irq[pru->evt_count]);
+       }
+       kfree(pru->mapped_irq);
++      pru->mapped_irq = NULL;
+ }
+ /*
+@@ -307,8 +312,10 @@ static int pru_handle_intrmap(struct rproc *rproc)
+       pru->evt_count = rsc->num_evts;
+       pru->mapped_irq = kcalloc(pru->evt_count, sizeof(unsigned int),
+                                 GFP_KERNEL);
+-      if (!pru->mapped_irq)
++      if (!pru->mapped_irq) {
++              pru->evt_count = 0;
+               return -ENOMEM;
++      }
+       /*
+        * parse and fill in system event to interrupt channel and
+@@ -317,13 +324,19 @@ static int pru_handle_intrmap(struct rproc *rproc)
+        * corresponding sibling PRUSS INTC node.
+        */
+       parent = of_get_parent(dev_of_node(pru->dev));
+-      if (!parent)
++      if (!parent) {
++              kfree(pru->mapped_irq);
++              pru->mapped_irq = NULL;
++              pru->evt_count = 0;
+               return -ENODEV;
++      }
+       irq_parent = of_get_child_by_name(parent, "interrupt-controller");
+       of_node_put(parent);
+       if (!irq_parent) {
+               kfree(pru->mapped_irq);
++              pru->mapped_irq = NULL;
++              pru->evt_count = 0;
+               return -ENODEV;
+       }
+@@ -398,8 +411,7 @@ static int pru_rproc_stop(struct rproc *rproc)
+       pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
+       /* dispose irq mapping - new firmware can provide new mapping */
+-      if (pru->mapped_irq)
+-              pru_dispose_irq_mapping(pru);
++      pru_dispose_irq_mapping(pru);
+       return 0;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/remoteproc-pru-fix-wrong-success-return-value-for-fw.patch b/queue-5.11/remoteproc-pru-fix-wrong-success-return-value-for-fw.patch
new file mode 100644 (file)
index 0000000..d5e6ff5
--- /dev/null
@@ -0,0 +1,49 @@
+From 3113b1a5b84887db134e268f63f2321a6cec41ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 10:56:40 -0500
+Subject: remoteproc: pru: Fix wrong success return value for fw events
+
+From: Suman Anna <s-anna@ti.com>
+
+[ Upstream commit 1fe72bcfac087dba5ab52778e0646ed9e145cd32 ]
+
+The irq_create_fwspec_mapping() returns a proper virq value on success
+and 0 upon any failure. The pru_handle_intrmap() treats this as an error
+and disposes all firmware event mappings correctly, but is returning
+this incorrect value as is, letting the pru_rproc_start() interpret it
+as a success and boot the PRU.
+
+Fix this by returning an error value back upon any such failure. While
+at this, revise the error trace to print some meaningful info about the
+failed event.
+
+Fixes: c75c9fdac66e ("remoteproc: pru: Add support for PRU specific interrupt configuration")
+Signed-off-by: Suman Anna <s-anna@ti.com>
+Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Link: https://lore.kernel.org/r/20210407155641.5501-3-s-anna@ti.com
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/pru_rproc.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
+index 9226b8f3fe14..dcd5ea0d1f37 100644
+--- a/drivers/remoteproc/pru_rproc.c
++++ b/drivers/remoteproc/pru_rproc.c
+@@ -339,8 +339,10 @@ static int pru_handle_intrmap(struct rproc *rproc)
+               pru->mapped_irq[i] = irq_create_fwspec_mapping(&fwspec);
+               if (!pru->mapped_irq[i]) {
+-                      dev_err(dev, "failed to get virq\n");
+-                      ret = pru->mapped_irq[i];
++                      dev_err(dev, "failed to get virq for fw mapping %d: event %d chnl %d host %d\n",
++                              i, fwspec.param[0], fwspec.param[1],
++                              fwspec.param[2]);
++                      ret = -EINVAL;
+                       goto map_fail;
+               }
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/remoteproc-pru-fixup-interrupt-parent-logic-for-fw-e.patch b/queue-5.11/remoteproc-pru-fixup-interrupt-parent-logic-for-fw-e.patch
new file mode 100644 (file)
index 0000000..8650f1c
--- /dev/null
@@ -0,0 +1,82 @@
+From 849298e0aa6353358b0ef1bbc707fdc9c935325f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 10:56:39 -0500
+Subject: remoteproc: pru: Fixup interrupt-parent logic for fw events
+
+From: Suman Anna <s-anna@ti.com>
+
+[ Upstream commit 6d1f2803cb6b414c2e45fa64d1fdad6b581e1e88 ]
+
+The PRU firmware interrupt mapping logic in pru_handle_intrmap() uses
+of_irq_find_parent() with PRU device node to get a handle to the PRUSS
+Interrupt Controller at present. This logic however requires that the
+PRU nodes always define a interrupt-parent property. This property is
+neither a required/defined property as per the PRU remoteproc binding,
+nor is relevant from a DT node point of view without any associated
+interrupts. The current logic finds a wrong interrupt controller and
+fails to perform proper mapping without any interrupt-parent property
+in the PRU nodes.
+
+Fix this logic to always find and use the sibling interrupt controller.
+Also, while at this, fix the acquired interrupt controller device node
+reference properly.
+
+Fixes: c75c9fdac66e ("remoteproc: pru: Add support for PRU specific interrupt configuration")
+Signed-off-by: Suman Anna <s-anna@ti.com>
+Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Link: https://lore.kernel.org/r/20210407155641.5501-2-s-anna@ti.com
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/pru_rproc.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
+index dcb380e868df..9226b8f3fe14 100644
+--- a/drivers/remoteproc/pru_rproc.c
++++ b/drivers/remoteproc/pru_rproc.c
+@@ -284,7 +284,7 @@ static int pru_handle_intrmap(struct rproc *rproc)
+       struct pru_rproc *pru = rproc->priv;
+       struct pru_irq_rsc *rsc = pru->pru_interrupt_map;
+       struct irq_fwspec fwspec;
+-      struct device_node *irq_parent;
++      struct device_node *parent, *irq_parent;
+       int i, ret = 0;
+       /* not having pru_interrupt_map is not an error */
+@@ -312,9 +312,16 @@ static int pru_handle_intrmap(struct rproc *rproc)
+       /*
+        * parse and fill in system event to interrupt channel and
+-       * channel-to-host mapping
++       * channel-to-host mapping. The interrupt controller to be used
++       * for these mappings for a given PRU remoteproc is always its
++       * corresponding sibling PRUSS INTC node.
+        */
+-      irq_parent = of_irq_find_parent(pru->dev->of_node);
++      parent = of_get_parent(dev_of_node(pru->dev));
++      if (!parent)
++              return -ENODEV;
++
++      irq_parent = of_get_child_by_name(parent, "interrupt-controller");
++      of_node_put(parent);
+       if (!irq_parent) {
+               kfree(pru->mapped_irq);
+               return -ENODEV;
+@@ -337,11 +344,13 @@ static int pru_handle_intrmap(struct rproc *rproc)
+                       goto map_fail;
+               }
+       }
++      of_node_put(irq_parent);
+       return ret;
+ map_fail:
+       pru_dispose_irq_mapping(pru);
++      of_node_put(irq_parent);
+       return ret;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/remoteproc-qcom_q6v5_mss-validate-p_filesz-in-elf-lo.patch b/queue-5.11/remoteproc-qcom_q6v5_mss-validate-p_filesz-in-elf-lo.patch
new file mode 100644 (file)
index 0000000..8917add
--- /dev/null
@@ -0,0 +1,62 @@
+From c06709e5eb25e3ed30e45b9b1a1b696d8f64998f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 15:20:02 -0800
+Subject: remoteproc: qcom_q6v5_mss: Validate p_filesz in ELF loader
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+[ Upstream commit 3d2ee78906af5f08d499d6aa3aa504406fa38106 ]
+
+Analog to the issue in the common mdt_loader code the MSS ELF loader
+does not validate that p_filesz bytes will fit in the memory region and
+that the loaded segments are not truncated. Fix this in the same way
+as proposed for the mdt_loader.
+
+Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Fixes: 135b9e8d1cd8 ("remoteproc: qcom_q6v5_mss: Validate modem blob firmware size before load")
+Link: https://lore.kernel.org/r/20210312232002.3466791-1-bjorn.andersson@linaro.org
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_mss.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
+index 66106ba25ba3..14e0ce5f18f5 100644
+--- a/drivers/remoteproc/qcom_q6v5_mss.c
++++ b/drivers/remoteproc/qcom_q6v5_mss.c
+@@ -1210,6 +1210,14 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
+                       goto release_firmware;
+               }
++              if (phdr->p_filesz > phdr->p_memsz) {
++                      dev_err(qproc->dev,
++                              "refusing to load segment %d with p_filesz > p_memsz\n",
++                              i);
++                      ret = -EINVAL;
++                      goto release_firmware;
++              }
++
+               ptr = memremap(qproc->mpss_phys + offset, phdr->p_memsz, MEMREMAP_WC);
+               if (!ptr) {
+                       dev_err(qproc->dev,
+@@ -1241,6 +1249,16 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
+                               goto release_firmware;
+                       }
++                      if (seg_fw->size != phdr->p_filesz) {
++                              dev_err(qproc->dev,
++                                      "failed to load segment %d from truncated file %s\n",
++                                      i, fw_name);
++                              ret = -EINVAL;
++                              release_firmware(seg_fw);
++                              memunmap(ptr);
++                              goto release_firmware;
++                      }
++
+                       release_firmware(seg_fw);
+               }
+-- 
+2.30.2
+
diff --git a/queue-5.11/revert-iommu-amd-fix-performance-counter-initializat.patch b/queue-5.11/revert-iommu-amd-fix-performance-counter-initializat.patch
new file mode 100644 (file)
index 0000000..0541ba1
--- /dev/null
@@ -0,0 +1,125 @@
+From 8f30ef2247b4379f706bb5be01e5f8bcde243b0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Apr 2021 03:58:47 -0500
+Subject: Revert "iommu/amd: Fix performance counter initialization"
+
+From: Paul Menzel <pmenzel@molgen.mpg.de>
+
+[ Upstream commit 715601e4e36903a653cd4294dfd3ed0019101991 ]
+
+This reverts commit 6778ff5b21bd8e78c8bd547fd66437cf2657fd9b.
+
+The original commit tries to address an issue, where PMC power-gating
+causing the IOMMU PMC pre-init test to fail on certain desktop/mobile
+platforms where the power-gating is normally enabled.
+
+There have been several reports that the workaround still does not
+guarantee to work, and can add up to 100 ms (on the worst case)
+to the boot process on certain platforms such as the MSI B350M MORTAR
+with AMD Ryzen 3 2200G.
+
+Therefore, revert this commit as a prelude to removing the pre-init
+test.
+
+Link: https://lore.kernel.org/linux-iommu/alpine.LNX.3.20.13.2006030935570.3181@monopod.intra.ispras.ru/
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=201753
+Cc: Tj (Elloe Linux) <ml.linux@elloe.vision>
+Cc: Shuah Khan <skhan@linuxfoundation.org>
+Cc: Alexander Monakov <amonakov@ispras.ru>
+Cc: David Coe <david.coe@live.co.uk>
+Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Link: https://lore.kernel.org/r/20210409085848.3908-2-suravee.suthikulpanit@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/init.c | 45 ++++++++++------------------------------
+ 1 file changed, 11 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index 9846b01a5214..3d417afb581b 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -12,7 +12,6 @@
+ #include <linux/acpi.h>
+ #include <linux/list.h>
+ #include <linux/bitmap.h>
+-#include <linux/delay.h>
+ #include <linux/slab.h>
+ #include <linux/syscore_ops.h>
+ #include <linux/interrupt.h>
+@@ -255,8 +254,6 @@ static enum iommu_init_state init_state = IOMMU_START_STATE;
+ static int amd_iommu_enable_interrupts(void);
+ static int __init iommu_go_to_state(enum iommu_init_state state);
+ static void init_device_table_dma(void);
+-static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
+-                              u8 fxn, u64 *value, bool is_write);
+ static bool amd_iommu_pre_enabled = true;
+@@ -1715,11 +1712,13 @@ static int __init init_iommu_all(struct acpi_table_header *table)
+       return 0;
+ }
+-static void __init init_iommu_perf_ctr(struct amd_iommu *iommu)
++static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
++                              u8 fxn, u64 *value, bool is_write);
++
++static void init_iommu_perf_ctr(struct amd_iommu *iommu)
+ {
+-      int retry;
+       struct pci_dev *pdev = iommu->dev;
+-      u64 val = 0xabcd, val2 = 0, save_reg, save_src;
++      u64 val = 0xabcd, val2 = 0, save_reg = 0;
+       if (!iommu_feature(iommu, FEATURE_PC))
+               return;
+@@ -1727,39 +1726,17 @@ static void __init init_iommu_perf_ctr(struct amd_iommu *iommu)
+       amd_iommu_pc_present = true;
+       /* save the value to restore, if writable */
+-      if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, false) ||
+-          iommu_pc_get_set_reg(iommu, 0, 0, 8, &save_src, false))
+-              goto pc_false;
+-
+-      /*
+-       * Disable power gating by programing the performance counter
+-       * source to 20 (i.e. counts the reads and writes from/to IOMMU
+-       * Reserved Register [MMIO Offset 1FF8h] that are ignored.),
+-       * which never get incremented during this init phase.
+-       * (Note: The event is also deprecated.)
+-       */
+-      val = 20;
+-      if (iommu_pc_get_set_reg(iommu, 0, 0, 8, &val, true))
++      if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, false))
+               goto pc_false;
+       /* Check if the performance counters can be written to */
+-      val = 0xabcd;
+-      for (retry = 5; retry; retry--) {
+-              if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true) ||
+-                  iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false) ||
+-                  val2)
+-                      break;
+-
+-              /* Wait about 20 msec for power gating to disable and retry. */
+-              msleep(20);
+-      }
+-
+-      /* restore */
+-      if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, true) ||
+-          iommu_pc_get_set_reg(iommu, 0, 0, 8, &save_src, true))
++      if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true)) ||
++          (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false)) ||
++          (val != val2))
+               goto pc_false;
+-      if (val != val2)
++      /* restore */
++      if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, true))
+               goto pc_false;
+       pci_info(pdev, "IOMMU performance counters supported\n");
+-- 
+2.30.2
+
diff --git a/queue-5.11/risc-v-fix-error-code-returned-by-riscv_hartid_to_cp.patch b/queue-5.11/risc-v-fix-error-code-returned-by-riscv_hartid_to_cp.patch
new file mode 100644 (file)
index 0000000..d538f8e
--- /dev/null
@@ -0,0 +1,39 @@
+From cfe247a6f7b912031b792a0f9c7ce9946607f122 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 14:25:22 +0530
+Subject: RISC-V: Fix error code returned by riscv_hartid_to_cpuid()
+
+From: Anup Patel <anup.patel@wdc.com>
+
+[ Upstream commit 533b4f3a789d49574e7ae0f6ececed153f651f97 ]
+
+We should return a negative error code upon failure in
+riscv_hartid_to_cpuid() instead of NR_CPUS. This is also
+aligned with all uses of riscv_hartid_to_cpuid() which
+expect negative error code upon failure.
+
+Fixes: 6825c7a80f18 ("RISC-V: Add logical CPU indexing for RISC-V")
+Fixes: f99fb607fb2b ("RISC-V: Use Linux logical CPU number instead of hartid")
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/smp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
+index ea028d9e0d24..d44567490d91 100644
+--- a/arch/riscv/kernel/smp.c
++++ b/arch/riscv/kernel/smp.c
+@@ -54,7 +54,7 @@ int riscv_hartid_to_cpuid(int hartid)
+                       return i;
+       pr_err("Couldn't find cpu id for hartid [%d]\n", hartid);
+-      return i;
++      return -ENOENT;
+ }
+ void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out)
+-- 
+2.30.2
+
diff --git a/queue-5.11/rpmsg-qcom_glink_native-fix-error-return-code-of-qco.patch b/queue-5.11/rpmsg-qcom_glink_native-fix-error-return-code-of-qco.patch
new file mode 100644 (file)
index 0000000..4915b7f
--- /dev/null
@@ -0,0 +1,39 @@
+From c1fcdf8204a0b32e6cdd68341e7eb0a39c9da4ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Mar 2021 05:36:24 -0800
+Subject: rpmsg: qcom_glink_native: fix error return code of
+ qcom_glink_rx_data()
+
+From: Jia-Ju Bai <baijiaju1990@gmail.com>
+
+[ Upstream commit 26594c6bbb60c6bc87e3762a86ceece57d164c66 ]
+
+When idr_find() returns NULL to intent, no error return code of
+qcom_glink_rx_data() is assigned.
+To fix this bug, ret is assigned with -ENOENT in this case.
+
+Fixes: 64f95f87920d ("rpmsg: glink: Use the local intents when receiving data")
+Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
+Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
+Link: https://lore.kernel.org/r/20210306133624.17237-1-baijiaju1990@gmail.com
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_glink_native.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index 27a05167c18c..4840886532ff 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -857,6 +857,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
+                       dev_err(glink->dev,
+                               "no intent found for channel %s intent %d",
+                               channel->name, liid);
++                      ret = -ENOENT;
+                       goto advance_rx;
+               }
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.11/rtc-ds1307-fix-wday-settings-for-rx8130.patch b/queue-5.11/rtc-ds1307-fix-wday-settings-for-rx8130.patch
new file mode 100644 (file)
index 0000000..270fac5
--- /dev/null
@@ -0,0 +1,53 @@
+From 55fedb8d752da97752025d5e2529298c44224d85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Apr 2021 11:39:17 +0900
+Subject: rtc: ds1307: Fix wday settings for rx8130
+
+From: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+
+[ Upstream commit 204756f016726a380bafe619438ed979088bd04a ]
+
+rx8130 wday specifies the bit position, not BCD.
+
+Fixes: ee0981be7704 ("rtc: ds1307: Add support for Epson RX8130CE")
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20210420023917.1949066-1-nobuhiro1.iwamatsu@toshiba.co.jp
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-ds1307.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
+index 183cf7c01364..c6c16961385b 100644
+--- a/drivers/rtc/rtc-ds1307.c
++++ b/drivers/rtc/rtc-ds1307.c
+@@ -296,7 +296,11 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
+       t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
+       tmp = regs[DS1307_REG_HOUR] & 0x3f;
+       t->tm_hour = bcd2bin(tmp);
+-      t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
++      /* rx8130 is bit position, not BCD */
++      if (ds1307->type == rx_8130)
++              t->tm_wday = fls(regs[DS1307_REG_WDAY] & 0x7f);
++      else
++              t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
+       t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f);
+       tmp = regs[DS1307_REG_MONTH] & 0x1f;
+       t->tm_mon = bcd2bin(tmp) - 1;
+@@ -343,7 +347,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
+       regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
+       regs[DS1307_REG_MIN] = bin2bcd(t->tm_min);
+       regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
+-      regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
++      /* rx8130 is bit position, not BCD */
++      if (ds1307->type == rx_8130)
++              regs[DS1307_REG_WDAY] = 1 << t->tm_wday;
++      else
++              regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
+       regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
+       regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
+-- 
+2.30.2
+
diff --git a/queue-5.11/rtc-fsl-ftm-alarm-add-module_table.patch b/queue-5.11/rtc-fsl-ftm-alarm-add-module_table.patch
new file mode 100644 (file)
index 0000000..649e14c
--- /dev/null
@@ -0,0 +1,36 @@
+From b6c1930aff7d62e90c4364a02ba45868796d115e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Apr 2021 10:40:06 +0200
+Subject: rtc: fsl-ftm-alarm: add MODULE_TABLE()
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit 7fcb86185978661c9188397d474f90364745b8d9 ]
+
+The module doesn't load automatically. Fix it by adding the missing
+MODULE_TABLE().
+
+Fixes: 7b0b551dbc1e ("rtc: fsl-ftm-alarm: add FTM alarm driver")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20210414084006.17933-1-michael@walle.cc
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-fsl-ftm-alarm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c
+index 57cc09d0a806..c0df49fb978c 100644
+--- a/drivers/rtc/rtc-fsl-ftm-alarm.c
++++ b/drivers/rtc/rtc-fsl-ftm-alarm.c
+@@ -310,6 +310,7 @@ static const struct of_device_id ftm_rtc_match[] = {
+       { .compatible = "fsl,lx2160a-ftm-alarm", },
+       { },
+ };
++MODULE_DEVICE_TABLE(of, ftm_rtc_match);
+ static const struct acpi_device_id ftm_imx_acpi_ids[] = {
+       {"NXP0014",},
+-- 
+2.30.2
+
diff --git a/queue-5.11/rtw88-8822c-add-lc-calibration-for-rtl8822c.patch b/queue-5.11/rtw88-8822c-add-lc-calibration-for-rtl8822c.patch
new file mode 100644 (file)
index 0000000..e311a1e
--- /dev/null
@@ -0,0 +1,167 @@
+From 4af80facc807549c1a96d17de534f07fd3127998 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Mar 2021 13:42:16 +0800
+Subject: rtw88: 8822c: add LC calibration for RTL8822C
+
+From: Po-Hao Huang <phhuang@realtek.com>
+
+[ Upstream commit 7ae7784ec2a812c07d2ca91a6538ef2470154fb6 ]
+
+Fix power tracking issue by replacing unnecessary IQ calibration
+with LC calibration.
+When thermal difference exceeds limitation, let RF circuit adjsut
+its characteristic to fit in current environment.
+
+Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210319054218.3319-6-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/main.h     |  2 ++
+ drivers/net/wireless/realtek/rtw88/phy.c      | 14 ++++++++++
+ drivers/net/wireless/realtek/rtw88/phy.h      |  1 +
+ drivers/net/wireless/realtek/rtw88/reg.h      |  5 ++++
+ drivers/net/wireless/realtek/rtw88/rtw8822c.c | 27 +++++++++++++++++--
+ 5 files changed, 47 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
+index 9a318dfd04f9..3d51394edb4a 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.h
++++ b/drivers/net/wireless/realtek/rtw88/main.h
+@@ -1157,6 +1157,7 @@ struct rtw_chip_info {
+       bool en_dis_dpd;
+       u16 dpd_ratemask;
+       u8 iqk_threshold;
++      u8 lck_threshold;
+       const struct rtw_pwr_track_tbl *pwr_track_tbl;
+       u8 bfer_su_max_num;
+@@ -1520,6 +1521,7 @@ struct rtw_dm_info {
+       u8 tx_rate;
+       u8 thermal_avg[RTW_RF_PATH_MAX];
+       u8 thermal_meter_k;
++      u8 thermal_meter_lck;
+       s8 delta_power_index[RTW_RF_PATH_MAX];
+       s8 delta_power_index_last[RTW_RF_PATH_MAX];
+       u8 default_ofdm_index;
+diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
+index a76aac514fc8..e655f6a76cc3 100644
+--- a/drivers/net/wireless/realtek/rtw88/phy.c
++++ b/drivers/net/wireless/realtek/rtw88/phy.c
+@@ -2160,6 +2160,20 @@ s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev,
+ }
+ EXPORT_SYMBOL(rtw_phy_pwrtrack_get_pwridx);
++bool rtw_phy_pwrtrack_need_lck(struct rtw_dev *rtwdev)
++{
++      struct rtw_dm_info *dm_info = &rtwdev->dm_info;
++      u8 delta_lck;
++
++      delta_lck = abs(dm_info->thermal_avg[0] - dm_info->thermal_meter_lck);
++      if (delta_lck >= rtwdev->chip->lck_threshold) {
++              dm_info->thermal_meter_lck = dm_info->thermal_avg[0];
++              return true;
++      }
++      return false;
++}
++EXPORT_SYMBOL(rtw_phy_pwrtrack_need_lck);
++
+ bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev)
+ {
+       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h
+index b924ed07630a..9623248c9466 100644
+--- a/drivers/net/wireless/realtek/rtw88/phy.h
++++ b/drivers/net/wireless/realtek/rtw88/phy.h
+@@ -55,6 +55,7 @@ u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path);
+ s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev,
+                              struct rtw_swing_table *swing_table,
+                              u8 tbl_path, u8 therm_path, u8 delta);
++bool rtw_phy_pwrtrack_need_lck(struct rtw_dev *rtwdev);
+ bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev);
+ void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
+                               struct rtw_swing_table *swing_table);
+diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
+index cf9a3b674d30..767f7777d409 100644
+--- a/drivers/net/wireless/realtek/rtw88/reg.h
++++ b/drivers/net/wireless/realtek/rtw88/reg.h
+@@ -650,8 +650,13 @@
+ #define RF_TXATANK    0x64
+ #define RF_TRXIQ      0x66
+ #define RF_RXIQGEN    0x8d
++#define RF_SYN_PFD    0xb0
+ #define RF_XTALX2     0xb8
++#define RF_SYN_CTRL   0xbb
+ #define RF_MALSEL     0xbe
++#define RF_SYN_AAC    0xc9
++#define RF_AAC_CTRL   0xca
++#define RF_FAST_LCK   0xcc
+ #define RF_RCKD               0xde
+ #define RF_TXADBG     0xde
+ #define RF_LUTDBG     0xdf
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+index dd560c28abb2..448922cb2e63 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+@@ -1126,6 +1126,7 @@ static void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev)
+       dm_info->pwr_trk_triggered = false;
+       dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
++      dm_info->thermal_meter_lck = rtwdev->efuse.thermal_meter_k;
+ }
+ static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev)
+@@ -2108,6 +2109,26 @@ static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev)
+       rtw_write32_set(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN);
+ }
++static void rtw8822c_do_lck(struct rtw_dev *rtwdev)
++{
++      u32 val;
++
++      rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_CTRL, RFREG_MASK, 0x80010);
++      rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0FA);
++      fsleep(1);
++      rtw_write_rf(rtwdev, RF_PATH_A, RF_AAC_CTRL, RFREG_MASK, 0x80000);
++      rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_AAC, RFREG_MASK, 0x80001);
++      read_poll_timeout(rtw_read_rf, val, val != 0x1, 1000, 100000,
++                        true, rtwdev, RF_PATH_A, RF_AAC_CTRL, 0x1000);
++      rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0F8);
++      rtw_write_rf(rtwdev, RF_PATH_B, RF_SYN_CTRL, RFREG_MASK, 0x80010);
++
++      rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000);
++      rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x4f000);
++      fsleep(1);
++      rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000);
++}
++
+ static void rtw8822c_do_iqk(struct rtw_dev *rtwdev)
+ {
+       struct rtw_iqk_para para = {0};
+@@ -3538,11 +3559,12 @@ static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev)
+       rtw_phy_config_swing_table(rtwdev, &swing_table);
++      if (rtw_phy_pwrtrack_need_lck(rtwdev))
++              rtw8822c_do_lck(rtwdev);
++
+       for (i = 0; i < rtwdev->hal.rf_path_num; i++)
+               rtw8822c_pwr_track_path(rtwdev, &swing_table, i);
+-      if (rtw_phy_pwrtrack_need_iqk(rtwdev))
+-              rtw8822c_do_iqk(rtwdev);
+ }
+ static void rtw8822c_pwr_track(struct rtw_dev *rtwdev)
+@@ -4351,6 +4373,7 @@ struct rtw_chip_info rtw8822c_hw_spec = {
+       .dpd_ratemask = DIS_DPD_RATEALL,
+       .pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl,
+       .iqk_threshold = 8,
++      .lck_threshold = 8,
+       .bfer_su_max_num = 2,
+       .bfer_mu_max_num = 1,
+       .rx_ldpc = true,
+-- 
+2.30.2
+
diff --git a/queue-5.11/samples-bpf-fix-broken-tracex1-due-to-kprobe-argumen.patch b/queue-5.11/samples-bpf-fix-broken-tracex1-due-to-kprobe-argumen.patch
new file mode 100644 (file)
index 0000000..cf3a783
--- /dev/null
@@ -0,0 +1,49 @@
+From f32817c3078415a6d2229f15bebb219ad2bbe094 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 23:48:03 +0800
+Subject: samples/bpf: Fix broken tracex1 due to kprobe argument change
+
+From: Yaqi Chen <chendotjs@gmail.com>
+
+[ Upstream commit 137733d08f4ab14a354dacaa9a8fc35217747605 ]
+
+>From commit c0bbbdc32feb ("__netif_receive_skb_core: pass skb by
+reference"), the first argument passed into __netif_receive_skb_core
+has changed to reference of a skb pointer.
+
+This commit fixes by using bpf_probe_read_kernel.
+
+Signed-off-by: Yaqi Chen <chendotjs@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20210416154803.37157-1-chendotjs@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/tracex1_kern.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/samples/bpf/tracex1_kern.c b/samples/bpf/tracex1_kern.c
+index 3f4599c9a202..ef30d2b353b0 100644
+--- a/samples/bpf/tracex1_kern.c
++++ b/samples/bpf/tracex1_kern.c
+@@ -26,7 +26,7 @@
+ SEC("kprobe/__netif_receive_skb_core")
+ int bpf_prog1(struct pt_regs *ctx)
+ {
+-      /* attaches to kprobe netif_receive_skb,
++      /* attaches to kprobe __netif_receive_skb_core,
+        * looks for packets on loobpack device and prints them
+        */
+       char devname[IFNAMSIZ];
+@@ -35,7 +35,7 @@ int bpf_prog1(struct pt_regs *ctx)
+       int len;
+       /* non-portable! works for the given kernel only */
+-      skb = (struct sk_buff *) PT_REGS_PARM1(ctx);
++      bpf_probe_read_kernel(&skb, sizeof(skb), (void *)PT_REGS_PARM1(ctx));
+       dev = _(skb->dev);
+       len = _(skb->len);
+-- 
+2.30.2
+
diff --git a/queue-5.11/sched-fair-fix-unfairness-caused-by-missing-load-dec.patch b/queue-5.11/sched-fair-fix-unfairness-caused-by-missing-load-dec.patch
new file mode 100644 (file)
index 0000000..c532881
--- /dev/null
@@ -0,0 +1,123 @@
+From ba06751df238490261ac6bbc237f4596075b8936 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 16:19:50 +0200
+Subject: sched/fair: Fix unfairness caused by missing load decay
+
+From: Odin Ugedal <odin@uged.al>
+
+[ Upstream commit 0258bdfaff5bd13c4d2383150b7097aecd6b6d82 ]
+
+This fixes an issue where old load on a cfs_rq is not properly decayed,
+resulting in strange behavior where fairness can decrease drastically.
+Real workloads with equally weighted control groups have ended up
+getting a respective 99% and 1%(!!) of cpu time.
+
+When an idle task is attached to a cfs_rq by attaching a pid to a cgroup,
+the old load of the task is attached to the new cfs_rq and sched_entity by
+attach_entity_cfs_rq. If the task is then moved to another cpu (and
+therefore cfs_rq) before being enqueued/woken up, the load will be moved
+to cfs_rq->removed from the sched_entity. Such a move will happen when
+enforcing a cpuset on the task (eg. via a cgroup) that force it to move.
+
+The load will however not be removed from the task_group itself, making
+it look like there is a constant load on that cfs_rq. This causes the
+vruntime of tasks on other sibling cfs_rq's to increase faster than they
+are supposed to; causing severe fairness issues. If no other task is
+started on the given cfs_rq, and due to the cpuset it would not happen,
+this load would never be properly unloaded. With this patch the load
+will be properly removed inside update_blocked_averages. This also
+applies to tasks moved to the fair scheduling class and moved to another
+cpu, and this path will also fix that. For fork, the entity is queued
+right away, so this problem does not affect that.
+
+This applies to cases where the new process is the first in the cfs_rq,
+issue introduced 3d30544f0212 ("sched/fair: Apply more PELT fixes"), and
+when there has previously been load on the cgroup but the cgroup was
+removed from the leaflist due to having null PELT load, indroduced
+in 039ae8bcf7a5 ("sched/fair: Fix O(nr_cgroups) in the load balancing
+path").
+
+For a simple cgroup hierarchy (as seen below) with two equally weighted
+groups, that in theory should get 50/50 of cpu time each, it often leads
+to a load of 60/40 or 70/30.
+
+parent/
+  cg-1/
+    cpu.weight: 100
+    cpuset.cpus: 1
+  cg-2/
+    cpu.weight: 100
+    cpuset.cpus: 1
+
+If the hierarchy is deeper (as seen below), while keeping cg-1 and cg-2
+equally weighted, they should still get a 50/50 balance of cpu time.
+This however sometimes results in a balance of 10/90 or 1/99(!!) between
+the task groups.
+
+$ ps u -C stress
+USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
+root       18568  1.1  0.0   3684   100 pts/12   R+   13:36   0:00 stress --cpu 1
+root       18580 99.3  0.0   3684   100 pts/12   R+   13:36   0:09 stress --cpu 1
+
+parent/
+  cg-1/
+    cpu.weight: 100
+    sub-group/
+      cpu.weight: 1
+      cpuset.cpus: 1
+  cg-2/
+    cpu.weight: 100
+    sub-group/
+      cpu.weight: 10000
+      cpuset.cpus: 1
+
+This can be reproduced by attaching an idle process to a cgroup and
+moving it to a given cpuset before it wakes up. The issue is evident in
+many (if not most) container runtimes, and has been reproduced
+with both crun and runc (and therefore docker and all its "derivatives"),
+and with both cgroup v1 and v2.
+
+Fixes: 3d30544f0212 ("sched/fair: Apply more PELT fixes")
+Fixes: 039ae8bcf7a5 ("sched/fair: Fix O(nr_cgroups) in the load balancing path")
+Signed-off-by: Odin Ugedal <odin@uged.al>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lkml.kernel.org/r/20210501141950.23622-2-odin@uged.al
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index f217e5251fb2..10b8b133145d 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -10885,16 +10885,22 @@ static void propagate_entity_cfs_rq(struct sched_entity *se)
+ {
+       struct cfs_rq *cfs_rq;
++      list_add_leaf_cfs_rq(cfs_rq_of(se));
++
+       /* Start to propagate at parent */
+       se = se->parent;
+       for_each_sched_entity(se) {
+               cfs_rq = cfs_rq_of(se);
+-              if (cfs_rq_throttled(cfs_rq))
+-                      break;
++              if (!cfs_rq_throttled(cfs_rq)){
++                      update_load_avg(cfs_rq, se, UPDATE_TG);
++                      list_add_leaf_cfs_rq(cfs_rq);
++                      continue;
++              }
+-              update_load_avg(cfs_rq, se, UPDATE_TG);
++              if (list_add_leaf_cfs_rq(cfs_rq))
++                      break;
+       }
+ }
+ #else
+-- 
+2.30.2
+
diff --git a/queue-5.11/sched-fix-out-of-bound-access-in-uclamp.patch b/queue-5.11/sched-fix-out-of-bound-access-in-uclamp.patch
new file mode 100644 (file)
index 0000000..950b540
--- /dev/null
@@ -0,0 +1,49 @@
+From 10cd3ccce7bf37aaceeb1ce88331989569ff867c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 15:14:12 +0000
+Subject: sched: Fix out-of-bound access in uclamp
+
+From: Quentin Perret <qperret@google.com>
+
+[ Upstream commit 6d2f8909a5fabb73fe2a63918117943986c39b6c ]
+
+Util-clamp places tasks in different buckets based on their clamp values
+for performance reasons. However, the size of buckets is currently
+computed using a rounding division, which can lead to an off-by-one
+error in some configurations.
+
+For instance, with 20 buckets, the bucket size will be 1024/20=51. A
+task with a clamp of 1024 will be mapped to bucket id 1024/51=20. Sadly,
+correct indexes are in range [0,19], hence leading to an out of bound
+memory access.
+
+Clamp the bucket id to fix the issue.
+
+Fixes: 69842cba9ace ("sched/uclamp: Add CPU's clamp buckets refcounting")
+Suggested-by: Qais Yousef <qais.yousef@arm.com>
+Signed-off-by: Quentin Perret <qperret@google.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Link: https://lkml.kernel.org/r/20210430151412.160913-1-qperret@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index c5fcb5ce2194..984456b431aa 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -928,7 +928,7 @@ DEFINE_STATIC_KEY_FALSE(sched_uclamp_used);
+ static inline unsigned int uclamp_bucket_id(unsigned int clamp_value)
+ {
+-      return clamp_value / UCLAMP_BUCKET_DELTA;
++      return min_t(unsigned int, clamp_value / UCLAMP_BUCKET_DELTA, UCLAMP_BUCKETS - 1);
+ }
+ static inline unsigned int uclamp_none(enum uclamp_id clamp_id)
+-- 
+2.30.2
+
diff --git a/queue-5.11/scsi-qla2xxx-prevent-prli-in-target-mode.patch b/queue-5.11/scsi-qla2xxx-prevent-prli-in-target-mode.patch
new file mode 100644 (file)
index 0000000..6ad9245
--- /dev/null
@@ -0,0 +1,48 @@
+From 1b9bf823b370903b98e35d2ac3e2b8808908af9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 18:34:14 +0300
+Subject: scsi: qla2xxx: Prevent PRLI in target mode
+
+From: Anastasia Kovaleva <a.kovaleva@yadro.com>
+
+[ Upstream commit fcb16d9a8ecf1e9bfced0fc654ea4e2caa7517f4 ]
+
+In a case when the initiator in P2P mode by some circumstances does not
+send PRLI, the target, in a case when the target port's WWPN is less than
+initiator's, changes the discovery state in DSC_GNL. When gnl completes it
+sends PRLI to the initiator.
+
+Usually the initiator in P2P mode always sends PRLI. We caught this issue
+on Linux stable v5.4.6 https://www.spinics.net/lists/stable/msg458515.html.
+
+Fix this particular corner case in the behaviour of the P2P mod target
+login state machine.
+
+Link: https://lore.kernel.org/r/20210422153414.4022-1-a.kovaleva@yadro.com
+Fixes: a9ed06d4e640 ("scsi: qla2xxx: Allow PLOGI in target mode")
+Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Anastasia Kovaleva <a.kovaleva@yadro.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index dcc0f0d823db..5d985d50eab7 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -1190,6 +1190,9 @@ static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport)
+ {
+       struct qla_work_evt *e;
++      if (vha->host->active_mode == MODE_TARGET)
++              return QLA_FUNCTION_FAILED;
++
+       e = qla2x00_alloc_work(vha, QLA_EVT_PRLI);
+       if (!e)
+               return QLA_FUNCTION_FAILED;
+-- 
+2.30.2
+
diff --git a/queue-5.11/scsi-ufs-core-cancel-rpm_dev_flush_recheck_work-duri.patch b/queue-5.11/scsi-ufs-core-cancel-rpm_dev_flush_recheck_work-duri.patch
new file mode 100644 (file)
index 0000000..3d28e10
--- /dev/null
@@ -0,0 +1,41 @@
+From c986ba81cc336433d76aa7e0c9e64919c2fa7ac7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Apr 2021 20:48:39 -0700
+Subject: scsi: ufs: core: Cancel rpm_dev_flush_recheck_work during system
+ suspend
+
+From: Can Guo <cang@codeaurora.org>
+
+[ Upstream commit 637822e63b79ee8a729f7ba2645a26cf5a524ee4 ]
+
+During ufs system suspend, leaving rpm_dev_flush_recheck_work running or
+pending is risky because concurrency may happen between system
+suspend/resume and runtime resume routine. Fix this by cancelling
+rpm_dev_flush_recheck_work synchronously during system suspend.
+
+Link: https://lore.kernel.org/r/1619408921-30426-3-git-send-email-cang@codeaurora.org
+Fixes: 51dd905bd2f6 ("scsi: ufs: Fix WriteBooster flush during runtime suspend")
+Reviewed-by: Daejun Park <daejun7.park@samsung.com>
+Signed-off-by: Can Guo <cang@codeaurora.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ufs/ufshcd.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index 9f811fc5916d..d7e983e952cb 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -8972,6 +8972,8 @@ int ufshcd_system_suspend(struct ufs_hba *hba)
+       if (!hba->is_powered)
+               return 0;
++      cancel_delayed_work_sync(&hba->rpm_dev_flush_recheck_work);
++
+       if ((ufs_get_pm_lvl_to_dev_pwr_mode(hba->spm_lvl) ==
+            hba->curr_dev_pwr_mode) &&
+           (ufs_get_pm_lvl_to_link_pwr_state(hba->spm_lvl) ==
+-- 
+2.30.2
+
diff --git a/queue-5.11/scsi-ufs-core-do-not-put-ufs-power-into-lpm-if-link-.patch b/queue-5.11/scsi-ufs-core-do-not-put-ufs-power-into-lpm-if-link-.patch
new file mode 100644 (file)
index 0000000..8121ea5
--- /dev/null
@@ -0,0 +1,47 @@
+From 4dd74e5daca4134ea20df3098eebf505fa712c42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Apr 2021 20:48:38 -0700
+Subject: scsi: ufs: core: Do not put UFS power into LPM if link is broken
+
+From: Can Guo <cang@codeaurora.org>
+
+[ Upstream commit 23043dd87b153d02eaf676e752d32429be5e5126 ]
+
+During resume, if link is broken due to AH8 failure, make sure
+ufshcd_resume() does not put UFS power back into LPM.
+
+Link: https://lore.kernel.org/r/1619408921-30426-2-git-send-email-cang@codeaurora.org
+Fixes: 4db7a2360597 ("scsi: ufs: Fix concurrency of error handler and other error recovery paths")
+Reviewed-by: Daejun Park <daejun7.park@samsung.com>
+Signed-off-by: Can Guo <cang@codeaurora.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ufs/ufshcd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index e53a3f89e863..9f811fc5916d 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -8577,7 +8577,7 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba *hba)
+       } else if (!ufshcd_is_ufs_dev_active(hba)) {
+               ufshcd_toggle_vreg(hba->dev, hba->vreg_info.vcc, false);
+               vcc_off = true;
+-              if (!ufshcd_is_link_active(hba)) {
++              if (ufshcd_is_link_hibern8(hba) || ufshcd_is_link_off(hba)) {
+                       ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq);
+                       ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq2);
+               }
+@@ -8599,7 +8599,7 @@ static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)
+           !hba->dev_info.is_lu_power_on_wp) {
+               ret = ufshcd_setup_vreg(hba, true);
+       } else if (!ufshcd_is_ufs_dev_active(hba)) {
+-              if (!ret && !ufshcd_is_link_active(hba)) {
++              if (!ufshcd_is_link_active(hba)) {
+                       ret = ufshcd_config_vreg_hpm(hba, hba->vreg_info.vccq);
+                       if (ret)
+                               goto vcc_disable;
+-- 
+2.30.2
+
diff --git a/queue-5.11/scsi-ufs-core-narrow-down-fast-path-in-system-suspen.patch b/queue-5.11/scsi-ufs-core-narrow-down-fast-path-in-system-suspen.patch
new file mode 100644 (file)
index 0000000..a8143fd
--- /dev/null
@@ -0,0 +1,46 @@
+From 3f47df3ff344105edbe2772c5d370536827d50f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Apr 2021 20:48:40 -0700
+Subject: scsi: ufs: core: Narrow down fast path in system suspend path
+
+From: Can Guo <cang@codeaurora.org>
+
+[ Upstream commit ce4f62f9dd8cf43ac044045ed598a0b80ef33890 ]
+
+If spm_lvl is set to 0 or 1, when system suspend kicks start and HBA is
+runtime active, system suspend may just bail without doing anything (the
+fast path), leaving other contexts still running, e.g., clock gating and
+clock scaling. When system resume kicks start, concurrency can happen
+between ufshcd_resume() and these contexts, leading to various stability
+issues.
+
+Add a check against HBA's runtime state and allowing fast path only if HBA
+is runtime suspended, otherwise let system suspend go ahead call
+ufshcd_suspend(). This will guarantee that these contexts are stopped by
+either runtime suspend or system suspend.
+
+Link: https://lore.kernel.org/r/1619408921-30426-4-git-send-email-cang@codeaurora.org
+Fixes: 0b257734344a ("scsi: ufs: optimize system suspend handling")
+Reviewed-by: Daejun Park <daejun7.park@samsung.com>
+Signed-off-by: Can Guo <cang@codeaurora.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ufs/ufshcd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index d7e983e952cb..ab3a5c1b5723 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -8978,6 +8978,7 @@ int ufshcd_system_suspend(struct ufs_hba *hba)
+            hba->curr_dev_pwr_mode) &&
+           (ufs_get_pm_lvl_to_link_pwr_state(hba->spm_lvl) ==
+            hba->uic_link_state) &&
++           pm_runtime_suspended(hba->dev) &&
+            !hba->dev_info.b_rpm_dev_flush_capable)
+               goto out;
+-- 
+2.30.2
+
diff --git a/queue-5.11/sctp-do-asoc-update-earlier-in-sctp_sf_do_dupcook_a.patch b/queue-5.11/sctp-do-asoc-update-earlier-in-sctp_sf_do_dupcook_a.patch
new file mode 100644 (file)
index 0000000..84475a6
--- /dev/null
@@ -0,0 +1,96 @@
+From 2fd6b5d704984873e61a3c9ef47b5e471ecbe21e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 04:02:58 +0800
+Subject: sctp: do asoc update earlier in sctp_sf_do_dupcook_a
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 35b4f24415c854cd718ccdf38dbea6297f010aae ]
+
+There's a panic that occurs in a few of envs, the call trace is as below:
+
+  [] general protection fault, ... 0x29acd70f1000a: 0000 [#1] SMP PTI
+  [] RIP: 0010:sctp_ulpevent_notify_peer_addr_change+0x4b/0x1fa [sctp]
+  []  sctp_assoc_control_transport+0x1b9/0x210 [sctp]
+  []  sctp_do_8_2_transport_strike.isra.16+0x15c/0x220 [sctp]
+  []  sctp_cmd_interpreter.isra.21+0x1231/0x1a10 [sctp]
+  []  sctp_do_sm+0xc3/0x2a0 [sctp]
+  []  sctp_generate_timeout_event+0x81/0xf0 [sctp]
+
+This is caused by a transport use-after-free issue. When processing a
+duplicate COOKIE-ECHO chunk in sctp_sf_do_dupcook_a(), both COOKIE-ACK
+and SHUTDOWN chunks are allocated with the transort from the new asoc.
+However, later in the sideeffect machine, the old asoc is used to send
+them out and old asoc's shutdown_last_sent_to is set to the transport
+that SHUTDOWN chunk attached to in sctp_cmd_setup_t2(), which actually
+belongs to the new asoc. After the new_asoc is freed and the old asoc
+T2 timeout, the old asoc's shutdown_last_sent_to that is already freed
+would be accessed in sctp_sf_t2_timer_expire().
+
+Thanks Alexander and Jere for helping dig into this issue.
+
+To fix it, this patch is to do the asoc update first, then allocate
+the COOKIE-ACK and SHUTDOWN chunks with the 'updated' old asoc. This
+would make more sense, as a chunk from an asoc shouldn't be sent out
+with another asoc. We had fixed quite a few issues caused by this.
+
+Fixes: 145cb2f7177d ("sctp: Fix bundling of SHUTDOWN with COOKIE-ACK")
+Reported-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
+Reported-by: syzbot+bbe538efd1046586f587@syzkaller.appspotmail.com
+Reported-by: Michal Tesar <mtesar@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/sm_statefuns.c | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
+index af2b7041fa4e..c7138f85f18f 100644
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -1852,20 +1852,35 @@ static enum sctp_disposition sctp_sf_do_dupcook_a(
+                       SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
+       sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL());
+-      repl = sctp_make_cookie_ack(new_asoc, chunk);
++      /* Update the content of current association. */
++      if (sctp_assoc_update((struct sctp_association *)asoc, new_asoc)) {
++              struct sctp_chunk *abort;
++
++              abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr));
++              if (abort) {
++                      sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
++                      sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
++              }
++              sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED));
++              sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
++                              SCTP_PERR(SCTP_ERROR_RSRC_LOW));
++              SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
++              SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
++              goto nomem;
++      }
++
++      repl = sctp_make_cookie_ack(asoc, chunk);
+       if (!repl)
+               goto nomem;
+       /* Report association restart to upper layer. */
+       ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0,
+-                                           new_asoc->c.sinit_num_ostreams,
+-                                           new_asoc->c.sinit_max_instreams,
++                                           asoc->c.sinit_num_ostreams,
++                                           asoc->c.sinit_max_instreams,
+                                            NULL, GFP_ATOMIC);
+       if (!ev)
+               goto nomem_ev;
+-      /* Update the content of current association. */
+-      sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
+       sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
+       if ((sctp_state(asoc, SHUTDOWN_PENDING) ||
+            sctp_state(asoc, SHUTDOWN_SENT)) &&
+-- 
+2.30.2
+
diff --git a/queue-5.11/sctp-fix-a-sctp_mib_currestab-leak-in-sctp_sf_do_dup.patch b/queue-5.11/sctp-fix-a-sctp_mib_currestab-leak-in-sctp_sf_do_dup.patch
new file mode 100644 (file)
index 0000000..c405a3b
--- /dev/null
@@ -0,0 +1,52 @@
+From fe64344a37fb287dca2955621fd542870337650c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 May 2021 04:41:20 +0800
+Subject: sctp: fix a SCTP_MIB_CURRESTAB leak in sctp_sf_do_dupcook_b
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit f282df0391267fb2b263da1cc3233aa6fb81defc ]
+
+Normally SCTP_MIB_CURRESTAB is always incremented once asoc enter into
+ESTABLISHED from the state < ESTABLISHED and decremented when the asoc
+is being deleted.
+
+However, in sctp_sf_do_dupcook_b(), the asoc's state can be changed to
+ESTABLISHED from the state >= ESTABLISHED where it shouldn't increment
+SCTP_MIB_CURRESTAB. Otherwise, one asoc may increment MIB_CURRESTAB
+multiple times but only decrement once at the end.
+
+I was able to reproduce it by using scapy to do the 4-way shakehands,
+after that I replayed the COOKIE-ECHO chunk with 'peer_vtag' field
+changed to different values, and SCTP_MIB_CURRESTAB was incremented
+multiple times and never went back to 0 even when the asoc was freed.
+
+This patch is to fix it by only incrementing SCTP_MIB_CURRESTAB when
+the state < ESTABLISHED in sctp_sf_do_dupcook_b().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/sm_statefuns.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
+index c7138f85f18f..73bb4c6e9201 100644
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -1944,7 +1944,8 @@ static enum sctp_disposition sctp_sf_do_dupcook_b(
+       sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
+       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+                       SCTP_STATE(SCTP_STATE_ESTABLISHED));
+-      SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
++      if (asoc->state < SCTP_STATE_ESTABLISHED)
++              SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
+       sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
+       repl = sctp_make_cookie_ack(new_asoc, chunk);
+-- 
+2.30.2
+
diff --git a/queue-5.11/sctp-fix-out-of-bounds-warning-in-sctp_process_ascon.patch b/queue-5.11/sctp-fix-out-of-bounds-warning-in-sctp_process_ascon.patch
new file mode 100644 (file)
index 0000000..9233e71
--- /dev/null
@@ -0,0 +1,44 @@
+From 150252c563b15814230a59615801812ee9b43d65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 14:12:36 -0500
+Subject: sctp: Fix out-of-bounds warning in sctp_process_asconf_param()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit e5272ad4aab347dde5610c0aedb786219e3ff793 ]
+
+Fix the following out-of-bounds warning:
+
+net/sctp/sm_make_chunk.c:3150:4: warning: 'memcpy' offset [17, 28] from the object at 'addr' is out of the bounds of referenced subobject 'v4' with type 'struct sockaddr_in' at offset 0 [-Warray-bounds]
+
+This helps with the ongoing efforts to globally enable -Warray-bounds
+and get us closer to being able to tighten the FORTIFY_SOURCE routines
+on memcpy().
+
+Link: https://github.com/KSPP/linux/issues/109
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/sm_make_chunk.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
+index f77484df097b..da4ce0947c3a 100644
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -3147,7 +3147,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
+                * primary.
+                */
+               if (af->is_any(&addr))
+-                      memcpy(&addr.v4, sctp_source(asconf), sizeof(addr));
++                      memcpy(&addr, sctp_source(asconf), sizeof(addr));
+               if (security_sctp_bind_connect(asoc->ep->base.sk,
+                                              SCTP_PARAM_SET_PRIMARY,
+-- 
+2.30.2
+
diff --git a/queue-5.11/selftests-mlxsw-fix-mausezahn-invocation-in-erspan-s.patch b/queue-5.11/selftests-mlxsw-fix-mausezahn-invocation-in-erspan-s.patch
new file mode 100644 (file)
index 0000000..8b0e40e
--- /dev/null
@@ -0,0 +1,91 @@
+From f2488b57c5461fdbc46f1d92876b711e0a3df3e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 14:19:48 +0200
+Subject: selftests: mlxsw: Fix mausezahn invocation in ERSPAN scale test
+
+From: Petr Machata <petrm@nvidia.com>
+
+[ Upstream commit 1233898ab758cbcf5f6fea10b8dd16a0b2c24fab ]
+
+The mirror_gre_scale test creates as many ERSPAN sessions as the underlying
+chip supports, and tests that they all work. In order to determine that it
+issues a stream of ICMP packets and checks if they are mirrored as
+expected.
+
+However, the mausezahn invocation missed the -6 flag to identify the use of
+IPv6 protocol, and was sending ICMP messages over IPv6, as opposed to
+ICMP6. It also didn't pass an explicit source IP address, which apparently
+worked at some point in the past, but does not anymore.
+
+To fix these issues, extend the function mirror_test() in mirror_lib by
+detecting the IPv6 protocol addresses, and using a different ICMP scheme.
+Fix __mirror_gre_test() in the selftest itself to pass a source IP address.
+
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drivers/net/mlxsw/mirror_gre_scale.sh     |  3 ++-
+ .../selftests/net/forwarding/mirror_lib.sh    | 19 +++++++++++++++++--
+ 2 files changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh
+index 6f3a70df63bc..e00435753008 100644
+--- a/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh
+@@ -120,12 +120,13 @@ __mirror_gre_test()
+       sleep 5
+       for ((i = 0; i < count; ++i)); do
++              local sip=$(mirror_gre_ipv6_addr 1 $i)::1
+               local dip=$(mirror_gre_ipv6_addr 1 $i)::2
+               local htun=h3-gt6-$i
+               local message
+               icmp6_capture_install $htun
+-              mirror_test v$h1 "" $dip $htun 100 10
++              mirror_test v$h1 $sip $dip $htun 100 10
+               icmp6_capture_uninstall $htun
+       done
+ }
+diff --git a/tools/testing/selftests/net/forwarding/mirror_lib.sh b/tools/testing/selftests/net/forwarding/mirror_lib.sh
+index 13db1cb50e57..6406cd76a19d 100644
+--- a/tools/testing/selftests/net/forwarding/mirror_lib.sh
++++ b/tools/testing/selftests/net/forwarding/mirror_lib.sh
+@@ -20,6 +20,13 @@ mirror_uninstall()
+       tc filter del dev $swp1 $direction pref 1000
+ }
++is_ipv6()
++{
++      local addr=$1; shift
++
++      [[ -z ${addr//[0-9a-fA-F:]/} ]]
++}
++
+ mirror_test()
+ {
+       local vrf_name=$1; shift
+@@ -29,9 +36,17 @@ mirror_test()
+       local pref=$1; shift
+       local expect=$1; shift
++      if is_ipv6 $dip; then
++              local proto=-6
++              local type="icmp6 type=128" # Echo request.
++      else
++              local proto=
++              local type="icmp echoreq"
++      fi
++
+       local t0=$(tc_rule_stats_get $dev $pref)
+-      $MZ $vrf_name ${sip:+-A $sip} -B $dip -a own -b bc -q \
+-          -c 10 -d 100msec -t icmp type=8
++      $MZ $proto $vrf_name ${sip:+-A $sip} -B $dip -a own -b bc -q \
++          -c 10 -d 100msec -t $type
+       sleep 0.5
+       local t1=$(tc_rule_stats_get $dev $pref)
+       local delta=$((t1 - t0))
+-- 
+2.30.2
+
diff --git a/queue-5.11/selftests-mlxsw-increase-the-tolerance-of-backlog-bu.patch b/queue-5.11/selftests-mlxsw-increase-the-tolerance-of-backlog-bu.patch
new file mode 100644 (file)
index 0000000..cad635a
--- /dev/null
@@ -0,0 +1,46 @@
+From d1dd5d45b429575cf07c56dd5d511e295cb45b22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 14:19:47 +0200
+Subject: selftests: mlxsw: Increase the tolerance of backlog buildup
+
+From: Petr Machata <petrm@nvidia.com>
+
+[ Upstream commit dda7f4fa55839baeb72ae040aeaf9ccf89d3e416 ]
+
+The intention behind this test is to make sure that qdisc limit is
+correctly projected to the HW. However, first, due to rounding in the
+qdisc, and then in the driver, the number cannot actually be accurate. And
+second, the approach to testing this is to oversubscribe the port with
+traffic generated on the same switch. The actual backlog size therefore
+fluctuates.
+
+In practice, this test proved to be noisier than the rest, and spuriously
+fails every now and then. Increase the tolerance to 10 % to avoid these
+issues.
+
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Acked-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh
+index b0cb1aaffdda..33ddd01689be 100644
+--- a/tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh
+@@ -507,8 +507,8 @@ do_red_test()
+       check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
+       local diff=$((limit - backlog))
+       pct=$((100 * diff / limit))
+-      ((0 <= pct && pct <= 5))
+-      check_err $? "backlog $backlog / $limit expected <= 5% distance"
++      ((0 <= pct && pct <= 10))
++      check_err $? "backlog $backlog / $limit expected <= 10% distance"
+       log_test "TC $((vlan - 10)): RED backlog > limit"
+       stop_traffic
+-- 
+2.30.2
+
diff --git a/queue-5.11/selftests-mptcp-launch-mptcp_connect-with-timeout.patch b/queue-5.11/selftests-mptcp-launch-mptcp_connect-with-timeout.patch
new file mode 100644 (file)
index 0000000..2e9596e
--- /dev/null
@@ -0,0 +1,281 @@
+From 2d45865ea8f0d912fa1e2bbb1d5dcde25302ac94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Apr 2021 16:19:45 -0700
+Subject: selftests: mptcp: launch mptcp_connect with timeout
+
+From: Matthieu Baerts <matthieu.baerts@tessares.net>
+
+[ Upstream commit 5888a61cb4e00695075bbacfd86f3fa73af00413 ]
+
+'mptcp_connect' already has a timeout for poll() but in some cases, it
+is not enough.
+
+With "timeout" tool, we will force the command to fail if it doesn't
+finish on time. Thanks to that, the script will continue and display
+details about the current state before marking the test as failed.
+Displaying this state is very important to be able to understand the
+issue. Best to have our CI reporting the issue than just "the test
+hanged".
+
+Note that in mptcp_connect.sh, we were using a long timeout to validate
+the fact we cannot create a socket if a sysctl is set. We don't need
+this timeout.
+
+In diag.sh, we want to send signals to mptcp_connect instances that have
+been started in the netns. But we cannot send this signal to 'timeout'
+otherwise that will stop the timeout and messages telling us SIGUSR1 has
+been received will be printed. Instead of trying to find the right PID
+and storing them in an array, we can simply use the output of
+'ip netns pids' which is all the PIDs we want to send signal to.
+
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/160
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/mptcp/diag.sh     | 55 ++++++++++++-------
+ .../selftests/net/mptcp/mptcp_connect.sh      | 15 +++--
+ .../testing/selftests/net/mptcp/mptcp_join.sh | 22 ++++++--
+ .../selftests/net/mptcp/simult_flows.sh       | 13 ++++-
+ 4 files changed, 72 insertions(+), 33 deletions(-)
+
+diff --git a/tools/testing/selftests/net/mptcp/diag.sh b/tools/testing/selftests/net/mptcp/diag.sh
+index 39edce4f541c..2674ba20d524 100755
+--- a/tools/testing/selftests/net/mptcp/diag.sh
++++ b/tools/testing/selftests/net/mptcp/diag.sh
+@@ -5,8 +5,9 @@ rndh=$(printf %x $sec)-$(mktemp -u XXXXXX)
+ ns="ns1-$rndh"
+ ksft_skip=4
+ test_cnt=1
++timeout_poll=100
++timeout_test=$((timeout_poll * 2 + 1))
+ ret=0
+-pids=()
+ flush_pids()
+ {
+@@ -14,18 +15,14 @@ flush_pids()
+       # give it some time
+       sleep 1.1
+-      for pid in ${pids[@]}; do
+-              [ -d /proc/$pid ] && kill -SIGUSR1 $pid >/dev/null 2>&1
+-      done
+-      pids=()
++      ip netns pids "${ns}" | xargs --no-run-if-empty kill -SIGUSR1 &>/dev/null
+ }
+ cleanup()
+ {
++      ip netns pids "${ns}" | xargs --no-run-if-empty kill -SIGKILL &>/dev/null
++
+       ip netns del $ns
+-      for pid in ${pids[@]}; do
+-              [ -d /proc/$pid ] && kill -9 $pid >/dev/null 2>&1
+-      done
+ }
+ ip -Version > /dev/null 2>&1
+@@ -79,39 +76,57 @@ trap cleanup EXIT
+ ip netns add $ns
+ ip -n $ns link set dev lo up
+-echo "a" | ip netns exec $ns ./mptcp_connect -p 10000 -l 0.0.0.0 -t 100 >/dev/null &
++echo "a" | \
++      timeout ${timeout_test} \
++              ip netns exec $ns \
++                      ./mptcp_connect -p 10000 -l -t ${timeout_poll} \
++                              0.0.0.0 >/dev/null &
+ sleep 0.1
+-pids[0]=$!
+ chk_msk_nr 0 "no msk on netns creation"
+-echo "b" | ip netns exec $ns ./mptcp_connect -p 10000 127.0.0.1 -j -t 100 >/dev/null &
++echo "b" | \
++      timeout ${timeout_test} \
++              ip netns exec $ns \
++                      ./mptcp_connect -p 10000 -j -t ${timeout_poll} \
++                              127.0.0.1 >/dev/null &
+ sleep 0.1
+-pids[1]=$!
+ chk_msk_nr 2 "after MPC handshake "
+ chk_msk_remote_key_nr 2 "....chk remote_key"
+ chk_msk_fallback_nr 0 "....chk no fallback"
+ flush_pids
+-echo "a" | ip netns exec $ns ./mptcp_connect -p 10001 -s TCP -l 0.0.0.0 -t 100 >/dev/null &
+-pids[0]=$!
++echo "a" | \
++      timeout ${timeout_test} \
++              ip netns exec $ns \
++                      ./mptcp_connect -p 10001 -l -s TCP -t ${timeout_poll} \
++                              0.0.0.0 >/dev/null &
+ sleep 0.1
+-echo "b" | ip netns exec $ns ./mptcp_connect -p 10001 127.0.0.1 -j -t 100 >/dev/null &
+-pids[1]=$!
++echo "b" | \
++      timeout ${timeout_test} \
++              ip netns exec $ns \
++                      ./mptcp_connect -p 10001 -j -t ${timeout_poll} \
++                              127.0.0.1 >/dev/null &
+ sleep 0.1
+ chk_msk_fallback_nr 1 "check fallback"
+ flush_pids
+ NR_CLIENTS=100
+ for I in `seq 1 $NR_CLIENTS`; do
+-      echo "a" | ip netns exec $ns ./mptcp_connect -p $((I+10001)) -l 0.0.0.0 -t 100 -w 10 >/dev/null  &
+-      pids[$((I*2))]=$!
++      echo "a" | \
++              timeout ${timeout_test} \
++                      ip netns exec $ns \
++                              ./mptcp_connect -p $((I+10001)) -l -w 10 \
++                                      -t ${timeout_poll} 0.0.0.0 >/dev/null &
+ done
+ sleep 0.1
+ for I in `seq 1 $NR_CLIENTS`; do
+-      echo "b" | ip netns exec $ns ./mptcp_connect -p $((I+10001)) 127.0.0.1 -t 100 -w 10 >/dev/null &
+-      pids[$((I*2 + 1))]=$!
++      echo "b" | \
++              timeout ${timeout_test} \
++                      ip netns exec $ns \
++                              ./mptcp_connect -p $((I+10001)) -w 10 \
++                                      -t ${timeout_poll} 127.0.0.1 >/dev/null &
+ done
+ sleep 1.5
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+index e927df83efb9..c37acb790bd6 100755
+--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+@@ -11,7 +11,8 @@ cin=""
+ cout=""
+ ksft_skip=4
+ capture=false
+-timeout=30
++timeout_poll=30
++timeout_test=$((timeout_poll * 2 + 1))
+ ipv6=true
+ ethtool_random_on=true
+ tc_delay="$((RANDOM%50))"
+@@ -272,7 +273,7 @@ check_mptcp_disabled()
+       ip netns exec ${disabled_ns} sysctl -q net.mptcp.enabled=0
+       local err=0
+-      LANG=C ip netns exec ${disabled_ns} ./mptcp_connect -t $timeout -p 10000 -s MPTCP 127.0.0.1 < "$cin" 2>&1 | \
++      LANG=C ip netns exec ${disabled_ns} ./mptcp_connect -p 10000 -s MPTCP 127.0.0.1 < "$cin" 2>&1 | \
+               grep -q "^socket: Protocol not available$" && err=1
+       ip netns delete ${disabled_ns}
+@@ -414,14 +415,20 @@ do_transfer()
+       local stat_cookietx_last=$(ip netns exec ${listener_ns} nstat -z -a TcpExtSyncookiesSent | while read a count c rest ;do  echo $count;done)
+       local stat_cookierx_last=$(ip netns exec ${listener_ns} nstat -z -a TcpExtSyncookiesRecv | while read a count c rest ;do  echo $count;done)
+-      ip netns exec ${listener_ns} ./mptcp_connect -t $timeout -l -p $port -s ${srv_proto} $extra_args $local_addr < "$sin" > "$sout" &
++      timeout ${timeout_test} \
++              ip netns exec ${listener_ns} \
++                      ./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
++                              $extra_args $local_addr < "$sin" > "$sout" &
+       local spid=$!
+       wait_local_port_listen "${listener_ns}" "${port}"
+       local start
+       start=$(date +%s%3N)
+-      ip netns exec ${connector_ns} ./mptcp_connect -t $timeout -p $port -s ${cl_proto} $extra_args $connect_addr < "$cin" > "$cout" &
++      timeout ${timeout_test} \
++              ip netns exec ${connector_ns} \
++                      ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
++                              $extra_args $connect_addr < "$cin" > "$cout" &
+       local cpid=$!
+       wait $cpid
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+index 9aa9624cff97..99c5dc0eeb26 100755
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -8,7 +8,8 @@ cin=""
+ cinsent=""
+ cout=""
+ ksft_skip=4
+-timeout=30
++timeout_poll=30
++timeout_test=$((timeout_poll * 2 + 1))
+ mptcp_connect=""
+ capture=0
+@@ -249,17 +250,26 @@ do_transfer()
+               local_addr="0.0.0.0"
+       fi
+-      ip netns exec ${listener_ns} $mptcp_connect -t $timeout -l -p $port \
+-              -s ${srv_proto} ${local_addr} < "$sin" > "$sout" &
++      timeout ${timeout_test} \
++              ip netns exec ${listener_ns} \
++                      $mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
++                              ${local_addr} < "$sin" > "$sout" &
+       spid=$!
+       sleep 1
+       if [ "$test_link_fail" -eq 0 ];then
+-              ip netns exec ${connector_ns} $mptcp_connect -t $timeout -p $port -s ${cl_proto} $connect_addr < "$cin" > "$cout" &
++              timeout ${timeout_test} \
++                      ip netns exec ${connector_ns} \
++                              $mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
++                                      $connect_addr < "$cin" > "$cout" &
+       else
+-              ( cat "$cin" ; sleep 2; link_failure $listener_ns ; cat "$cin" ) | tee "$cinsent" | \
+-              ip netns exec ${connector_ns} $mptcp_connect -t $timeout -p $port -s ${cl_proto} $connect_addr > "$cout" &
++              ( cat "$cin" ; sleep 2; link_failure $listener_ns ; cat "$cin" ) | \
++                      tee "$cinsent" | \
++                      timeout ${timeout_test} \
++                              ip netns exec ${connector_ns} \
++                                      $mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
++                                              $connect_addr > "$cout" &
+       fi
+       cpid=$!
+diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
+index f039ee57eb3c..3aeef3bcb101 100755
+--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
++++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
+@@ -7,7 +7,8 @@ ns2="ns2-$rndh"
+ ns3="ns3-$rndh"
+ capture=false
+ ksft_skip=4
+-timeout=30
++timeout_poll=30
++timeout_test=$((timeout_poll * 2 + 1))
+ test_cnt=1
+ ret=0
+ bail=0
+@@ -157,14 +158,20 @@ do_transfer()
+               sleep 1
+       fi
+-      ip netns exec ${ns3} ./mptcp_connect -jt $timeout -l -p $port 0.0.0.0 < "$sin" > "$sout" &
++      timeout ${timeout_test} \
++              ip netns exec ${ns3} \
++                      ./mptcp_connect -jt ${timeout_poll} -l -p $port \
++                              0.0.0.0 < "$sin" > "$sout" &
+       local spid=$!
+       wait_local_port_listen "${ns3}" "${port}"
+       local start
+       start=$(date +%s%3N)
+-      ip netns exec ${ns1} ./mptcp_connect -jt $timeout -p $port 10.0.3.3 < "$cin" > "$cout" &
++      timeout ${timeout_test} \
++              ip netns exec ${ns1} \
++                      ./mptcp_connect -jt ${timeout_poll} -p $port \
++                              10.0.3.3 < "$cin" > "$cout" &
+       local cpid=$!
+       wait $cpid
+-- 
+2.30.2
+
diff --git a/queue-5.11/selftests-powerpc-fix-l1d-flushing-tests-for-power10.patch b/queue-5.11/selftests-powerpc-fix-l1d-flushing-tests-for-power10.patch
new file mode 100644 (file)
index 0000000..bf93cfd
--- /dev/null
@@ -0,0 +1,82 @@
+From 4e90ac39b310ebb1cd207f2eae11fa8a4767c97d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Feb 2021 17:02:27 +1000
+Subject: selftests/powerpc: Fix L1D flushing tests for Power10
+
+From: Russell Currey <ruscur@russell.cc>
+
+[ Upstream commit 3a72c94ebfb1f171eba0715998010678a09ec796 ]
+
+The rfi_flush and entry_flush selftests work by using the PM_LD_MISS_L1
+perf event to count L1D misses.  The value of this event has changed
+over time:
+
+- Power7 uses 0x400f0
+- Power8 and Power9 use both 0x400f0 and 0x3e054
+- Power10 uses only 0x3e054
+
+Rather than relying on raw values, configure perf to count L1D read
+misses in the most explicit way available.
+
+This fixes the selftests to work on systems without 0x400f0 as
+PM_LD_MISS_L1, and should change no behaviour for systems that the tests
+already worked on.
+
+The only potential downside is that referring to a specific perf event
+requires PMU support implemented in the kernel for that platform.
+
+Signed-off-by: Russell Currey <ruscur@russell.cc>
+Acked-by: Daniel Axtens <dja@axtens.net>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210223070227.2916871-1-ruscur@russell.cc
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/powerpc/security/entry_flush.c | 2 +-
+ tools/testing/selftests/powerpc/security/flush_utils.h | 4 ++++
+ tools/testing/selftests/powerpc/security/rfi_flush.c   | 2 +-
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/powerpc/security/entry_flush.c b/tools/testing/selftests/powerpc/security/entry_flush.c
+index 78cf914fa321..68ce377b205e 100644
+--- a/tools/testing/selftests/powerpc/security/entry_flush.c
++++ b/tools/testing/selftests/powerpc/security/entry_flush.c
+@@ -53,7 +53,7 @@ int entry_flush_test(void)
+       entry_flush = entry_flush_orig;
+-      fd = perf_event_open_counter(PERF_TYPE_RAW, /* L1d miss */ 0x400f0, -1);
++      fd = perf_event_open_counter(PERF_TYPE_HW_CACHE, PERF_L1D_READ_MISS_CONFIG, -1);
+       FAIL_IF(fd < 0);
+       p = (char *)memalign(zero_size, CACHELINE_SIZE);
+diff --git a/tools/testing/selftests/powerpc/security/flush_utils.h b/tools/testing/selftests/powerpc/security/flush_utils.h
+index 07a5eb301466..7a3d60292916 100644
+--- a/tools/testing/selftests/powerpc/security/flush_utils.h
++++ b/tools/testing/selftests/powerpc/security/flush_utils.h
+@@ -9,6 +9,10 @@
+ #define CACHELINE_SIZE 128
++#define PERF_L1D_READ_MISS_CONFIG     ((PERF_COUNT_HW_CACHE_L1D) |            \
++                                      (PERF_COUNT_HW_CACHE_OP_READ << 8) |    \
++                                      (PERF_COUNT_HW_CACHE_RESULT_MISS << 16))
++
+ void syscall_loop(char *p, unsigned long iterations,
+                 unsigned long zero_size);
+diff --git a/tools/testing/selftests/powerpc/security/rfi_flush.c b/tools/testing/selftests/powerpc/security/rfi_flush.c
+index 7565fd786640..f73484a6470f 100644
+--- a/tools/testing/selftests/powerpc/security/rfi_flush.c
++++ b/tools/testing/selftests/powerpc/security/rfi_flush.c
+@@ -54,7 +54,7 @@ int rfi_flush_test(void)
+       rfi_flush = rfi_flush_orig;
+-      fd = perf_event_open_counter(PERF_TYPE_RAW, /* L1d miss */ 0x400f0, -1);
++      fd = perf_event_open_counter(PERF_TYPE_HW_CACHE, PERF_L1D_READ_MISS_CONFIG, -1);
+       FAIL_IF(fd < 0);
+       p = (char *)memalign(zero_size, CACHELINE_SIZE);
+-- 
+2.30.2
+
diff --git a/queue-5.11/selftests-set-cc-to-clang-in-lib.mk-if-llvm-is-set.patch b/queue-5.11/selftests-set-cc-to-clang-in-lib.mk-if-llvm-is-set.patch
new file mode 100644 (file)
index 0000000..903ad2f
--- /dev/null
@@ -0,0 +1,42 @@
+From 6da717248f0aaadb9369511a203a5d43f3c81ad9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Apr 2021 08:34:13 -0700
+Subject: selftests: Set CC to clang in lib.mk if LLVM is set
+
+From: Yonghong Song <yhs@fb.com>
+
+[ Upstream commit 26e6dd1072763cd5696b75994c03982dde952ad9 ]
+
+selftests/bpf/Makefile includes lib.mk. With the following command
+  make -j60 LLVM=1 LLVM_IAS=1  <=== compile kernel
+  make -j60 -C tools/testing/selftests/bpf LLVM=1 LLVM_IAS=1 V=1
+some files are still compiled with gcc. This patch
+fixed lib.mk issue which sets CC to gcc in all cases.
+
+Signed-off-by: Yonghong Song <yhs@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20210413153413.3027426-1-yhs@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/lib.mk | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
+index be17462fe146..0af84ad48aa7 100644
+--- a/tools/testing/selftests/lib.mk
++++ b/tools/testing/selftests/lib.mk
+@@ -1,6 +1,10 @@
+ # This mimics the top-level Makefile. We do it explicitly here so that this
+ # Makefile can operate with or without the kbuild infrastructure.
++ifneq ($(LLVM),)
++CC := clang
++else
+ CC := $(CROSS_COMPILE)gcc
++endif
+ ifeq (0,$(MAKELEVEL))
+     ifeq ($(OUTPUT),)
+-- 
+2.30.2
+
index 16c2458c2500b87e1d41b5c6fa30c6dfb143ddc7..3e4350137b31b01e380abb643a1a3ce4e5c9c712 100644 (file)
@@ -9,3 +9,220 @@ acpi-pm-add-acpi-id-of-alder-lake-fan.patch
 pm-runtime-fix-unpaired-parent-child_count-for-force_resume.patch
 cpufreq-intel_pstate-use-hwp-if-enabled-by-platform-firmware.patch
 kvm-cap-halt-polling-at-kvm-max_halt_poll_ns.patch
+ath11k-fix-thermal-temperature-read.patch
+alsa-usb-audio-add-pioneer-djm-850-to-quirks-table.patch
+fs-dlm-fix-debugfs-dump.patch
+fs-dlm-fix-mark-setting-deadlock.patch
+fs-dlm-add-errno-handling-to-check-callback.patch
+fs-dlm-add-check-if-dlm-is-currently-running.patch
+fs-dlm-change-allocation-limits.patch
+fs-dlm-check-on-minimum-msglen-size.patch
+fs-dlm-flush-swork-on-shutdown.patch
+fs-dlm-add-shutdown-hook.patch
+tipc-convert-dest-node-s-address-to-network-order.patch
+asoc-intel-bytcr_rt5640-enable-jack-detect-support-o.patch
+net-mlx5e-use-net_prefetchw-instead-of-prefetchw-in-.patch
+net-stmmac-set-fifo-sizes-for-ipq806x.patch
+asoc-rsnd-core-check-convert-rate-in-rsnd_hw_params.patch
+bluetooth-fix-incorrect-status-handling-in-le-phy-up.patch
+i2c-bail-out-early-when-rdwr-parameters-are-wrong.patch
+alsa-hdsp-don-t-disable-if-not-enabled.patch
+alsa-hdspm-don-t-disable-if-not-enabled.patch
+alsa-rme9652-don-t-disable-if-not-enabled.patch
+alsa-bebob-enable-to-deliver-midi-messages-for-multi.patch
+bluetooth-set-conf_not_complete-as-l2cap_chan-defaul.patch
+bluetooth-initialize-skb_queue_head-at-l2cap_chan_cr.patch
+net-sched-cls_flower-use-ntohs-for-struct-flow_disse.patch
+net-bridge-when-suppression-is-enabled-exclude-rarp-.patch
+bluetooth-check-for-zapped-sk-before-connecting.patch
+selftests-powerpc-fix-l1d-flushing-tests-for-power10.patch
+powerpc-32-statically-initialise-first-emergency-con.patch
+net-hns3-remediate-a-potential-overflow-risk-of-bd_n.patch
+net-hns3-add-handling-for-xmit-skb-with-recursive-fr.patch
+ip6_vti-proper-dev_-hold-put-in-ndo_-un-init-methods.patch
+asoc-intel-bytcr_rt5640-add-quirk-for-the-chuwi-hi8-.patch
+ice-handle-increasing-tx-or-rx-ring-sizes.patch
+bluetooth-btusb-enable-quirk-boolean-flag-for-mediat.patch
+asoc-rt5670-add-a-quirk-for-the-dell-venue-10-pro-50.patch
+selftests-mptcp-launch-mptcp_connect-with-timeout.patch
+i2c-add-i2c_aq_no_rep_start-adapter-quirk.patch
+bluetooth-do-not-set-cur_adv_instance-in-adv-param-m.patch
+mips-loongson64-use-_cache_uncached-instead-of-_cach.patch
+coresight-do-not-scan-for-graph-if-none-is-present.patch
+ib-hfi1-correct-oversized-ring-allocation.patch
+mac80211-set-priority-and-queue-mapping-for-injected.patch
+mac80211-clear-the-beacon-s-crc-after-channel-switch.patch
+asoc-soc-compress-lock-pcm_mutex-to-resolve-lockdep-.patch
+pinctrl-samsung-use-int-for-register-masks-in-exynos.patch
+rtw88-8822c-add-lc-calibration-for-rtl8822c.patch
+mt76-mt7615-fix-key-set-delete-issues.patch
+mt76-mt7615-support-loading-eeprom-for-mt7613be.patch
+mt76-mt76x0-disable-gtk-offloading.patch
+mt76-mt7915-always-check-return-value-from-mt7915_mc.patch
+mt76-mt7915-fix-key-set-delete-issue.patch
+mt76-mt7915-fix-txpower-init-for-tssi-off-chips.patch
+mt76-mt7915-add-wifi-subsystem-reset.patch
+i2c-imx-fix-pm-reference-leak-in-i2c_imx_reg_slave.patch
+fuse-invalidate-attrs-when-page-writeback-completes.patch
+virtiofs-fix-userns.patch
+cuse-prevent-clone.patch
+iwlwifi-pcie-make-cfg-vs.-trans_cfg-more-robust.patch
+iwlwifi-queue-avoid-memory-leak-in-reset-flow.patch
+powerpc-mm-add-cond_resched-while-removing-hpte-mapp.patch
+asoc-rsnd-call-rsnd_ssi_master_clk_start-from-rsnd_s.patch
+revert-iommu-amd-fix-performance-counter-initializat.patch
+iommu-amd-remove-performance-counter-pre-initializat.patch
+drm-amd-display-force-vsync-flip-when-reconfiguring-.patch
+selftests-set-cc-to-clang-in-lib.mk-if-llvm-is-set.patch
+kconfig-nconf-stop-endless-search-loops.patch
+alsa-hda-realtek-add-quirk-for-lenovo-ideapad-s740.patch
+asoc-intel-sof_sdw-add-quirk-for-new-adl-p-rvp.patch
+alsa-hda-hdmi-fix-race-in-handling-acomp-eld-notific.patch
+sctp-fix-out-of-bounds-warning-in-sctp_process_ascon.patch
+flow_dissector-fix-out-of-bounds-warning-in-__skb_fl.patch
+powerpc-xive-use-the-ibm-chip-id-property-only-under.patch
+powerpc-smp-set-numa-node-before-updating-mask.patch
+wilc1000-bring-mac-address-setting-in-line-with-typi.patch
+mac80211-properly-drop-the-connection-in-case-of-inv.patch
+asoc-rt286-generalize-support-for-alc3263-codec.patch
+ethtool-ioctl-fix-out-of-bounds-warning-in-store_lin.patch
+net-sched-tapr-prevent-cycle_time-0-in-parse_taprio_.patch
+samples-bpf-fix-broken-tracex1-due-to-kprobe-argumen.patch
+powerpc-pseries-stop-calling-printk-in-rtas_stop_sel.patch
+drm-amd-display-fixed-divide-by-zero-kernel-crash-du.patch
+drm-amd-display-add-handling-for-hdcp2-rx-id-list-va.patch
+drm-amdgpu-add-mem-sync-flag-for-ib-allocated-by-sa.patch
+mt76-mt7615-fix-entering-driver-own-state-on-mt7663.patch
+crypto-ccp-free-sev-device-if-sev-init-fails.patch
+wl3501_cs-fix-out-of-bounds-warnings-in-wl3501_send_.patch
+wl3501_cs-fix-out-of-bounds-warnings-in-wl3501_mgmt_.patch
+qtnfmac-fix-possible-buffer-overflow-in-qtnf_event_h.patch
+powerpc-iommu-annotate-nested-lock-for-lockdep.patch
+iavf-remove-duplicate-free-resources-calls.patch
+net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch
+selftests-mlxsw-increase-the-tolerance-of-backlog-bu.patch
+selftests-mlxsw-fix-mausezahn-invocation-in-erspan-s.patch
+kbuild-generate-module.symvers-only-when-vmlinux-exi.patch
+bnxt_en-add-pci-ids-for-hyper-v-vf-devices.patch
+ia64-module-fix-symbolizer-crash-on-fdescr.patch
+watchdog-rename-__touch_watchdog-to-a-better-descrip.patch
+watchdog-explicitly-update-timestamp-when-reporting-.patch
+watchdog-softlockup-remove-logic-that-tried-to-preve.patch
+watchdog-fix-barriers-when-printing-backtraces-from-.patch
+asoc-rt286-make-rt286_set_gpio_-readable-and-writabl.patch
+thermal-thermal_of-fix-error-return-code-of-thermal_.patch
+pci-rcec-fix-rciep-device-to-rcec-association.patch
+f2fs-fix-to-allow-migrating-fully-valid-segment.patch
+f2fs-fix-panic-during-f2fs_resize_fs.patch
+f2fs-fix-a-redundant-call-to-f2fs_balance_fs-if-an-e.patch
+remoteproc-qcom_q6v5_mss-validate-p_filesz-in-elf-lo.patch
+pci-iproc-fix-return-value-of-iproc_msi_irq_domain_a.patch
+pci-release-of-node-in-pci_scan_device-s-error-path.patch
+arm-9064-1-hw_breakpoint-do-not-directly-check-the-e.patch
+f2fs-fix-to-align-to-section-for-fallocate-on-pinned.patch
+f2fs-fix-to-update-last-i_size-if-fallocate-partiall.patch
+pci-endpoint-make-_get_first_free_bar-take-into-acco.patch
+pci-endpoint-add-helper-api-to-get-the-next-unreserv.patch
+pci-endpoint-make-_free_bar-to-return-error-codes-on.patch
+pci-endpoint-fix-null-pointer-dereference-for-get_fe.patch
+f2fs-fix-to-avoid-touching-checkpointed-data-in-get_.patch
+f2fs-fix-to-cover-__allocate_new_section-with-curseg.patch
+fs-9p-fix-v9fs_file_open-writeback-fid-error-check.patch
+f2fs-fix-a-hungtask-problem-in-atomic-write.patch
+nfs-subsequent-readdir-calls-should-carry-non-zero-c.patch
+nfs-fix-handling-of-cookie-verifier-in-uncached_read.patch
+nfs-only-change-the-cookie-verifier-if-the-directory.patch
+f2fs-fix-to-avoid-accessing-invalid-fio-in-f2fs_allo.patch
+rpmsg-qcom_glink_native-fix-error-return-code-of-qco.patch
+nfs-nfs4_bitmask_adjust-must-not-change-the-server-g.patch
+nfs-fix-attribute-bitmask-in-_nfs42_proc_fallocate.patch
+nfsv4.2-always-flush-out-writes-in-nfs42_proc_falloc.patch
+nfs-deal-correctly-with-attribute-generation-counter.patch
+pci-endpoint-fix-missing-destroy_workqueue.patch
+remoteproc-pru-fixup-interrupt-parent-logic-for-fw-e.patch
+remoteproc-pru-fix-wrong-success-return-value-for-fw.patch
+remoteproc-pru-fix-and-cleanup-firmware-interrupt-ma.patch
+pnfs-flexfiles-fix-incorrect-size-check-in-decode_nf.patch
+nfsv4.2-fix-handling-of-sr_eof-in-seek-s-reply.patch
+sunrpc-move-fault-injection-call-sites.patch
+sunrpc-remove-trace_xprt_transmit_queued.patch
+sunrpc-handle-major-timeout-in-xprt_adjust_timeout.patch
+thermal-drivers-tsens-fix-missing-put_device-error.patch
+nfsv4.x-don-t-return-nfs4err_nomatching_layout-if-we.patch
+nfsd-ensure-new-clients-break-delegations.patch
+rtc-fsl-ftm-alarm-add-module_table.patch
+dmaengine-idxd-fix-potential-null-dereference-on-poi.patch
+dmaengine-idxd-fix-dma-device-lifetime.patch
+dmaengine-idxd-cleanup-pci-interrupt-vector-allocati.patch
+dmaengine-idxd-removal-of-pcim-managed-mmio-mapping.patch
+dma-idxd-use-define_mutex-for-mutex-lock.patch
+dmaengine-idxd-use-ida-for-device-instance-enumerati.patch
+dmaengine-idxd-fix-idxd-conf_dev-struct-device-lifet.patch
+dmaengine-idxd-fix-wq-conf_dev-struct-device-lifetim.patch
+dmaengine-idxd-fix-engine-conf_dev-lifetime.patch
+dmaengine-idxd-fix-group-conf_dev-lifetime.patch
+dmaengine-idxd-fix-cdev-setup-and-free-device-lifeti.patch
+sunrpc-fix-ternary-sign-expansion-bug-in-tracing.patch
+sunrpc-fix-null-pointer-dereference-in-svc_rqst_free.patch
+pwm-atmel-fix-duty-cycle-calculation-in-.get_state.patch
+xprtrdma-avoid-receive-queue-wrapping.patch
+xprtrdma-fix-cwnd-update-ordering.patch
+xprtrdma-rpcrdma_mr_pop-already-does-list_del_init.patch
+swiotlb-fix-the-type-of-index.patch
+ceph-fix-inode-leak-on-getattr-error-in-__fh_to_dent.patch
+scsi-qla2xxx-prevent-prli-in-target-mode.patch
+scsi-ufs-core-do-not-put-ufs-power-into-lpm-if-link-.patch
+scsi-ufs-core-cancel-rpm_dev_flush_recheck_work-duri.patch
+scsi-ufs-core-narrow-down-fast-path-in-system-suspen.patch
+rtc-ds1307-fix-wday-settings-for-rx8130.patch
+net-hns3-fix-incorrect-configuration-for-igu_egu_hw_.patch
+net-hns3-initialize-the-message-content-in-hclge_get.patch
+net-hns3-add-check-for-hns3_nic_state_inited-in-hns3.patch
+net-hns3-fix-for-vxlan-gpe-tx-checksum-bug.patch
+net-hns3-use-netif_tx_disable-to-stop-the-transmit-q.patch
+net-hns3-disable-phy-loopback-setting-in-hclge_mac_s.patch
+sctp-do-asoc-update-earlier-in-sctp_sf_do_dupcook_a.patch
+risc-v-fix-error-code-returned-by-riscv_hartid_to_cp.patch
+sunrpc-fix-misplaced-barrier-in-call_decode.patch
+libbpf-fix-signed-overflow-in-ringbuf_process_ring.patch
+block-rnbd-clt-change-queue_depth-type-in-rnbd_clt_s.patch
+block-rnbd-clt-check-the-return-value-of-the-functio.patch
+ata-ahci_brcm-fix-use-of-bcm7216-reset-controller.patch
+pci-brcmstb-use-reset-rearm-instead-of-deassert-asse.patch
+ethernet-enic-fix-a-use-after-free-bug-in-enic_hard_.patch
+sctp-fix-a-sctp_mib_currestab-leak-in-sctp_sf_do_dup.patch
+netfilter-xt_secmark-add-new-revision-to-fix-structu.patch
+xsk-fix-for-xp_aligned_validate_desc-when-len-chunk_.patch
+net-stmmac-clear-receive-all-ra-bit-when-promiscuous.patch
+drm-radeon-fix-off-by-one-power_state-index-heap-ove.patch
+drm-radeon-avoid-power-table-parsing-memory-leaks.patch
+arm64-entry-factor-irq-triage-logic-into-macros.patch
+arm64-entry-always-set-gic_prio_psr_i_set-during-ent.patch
+khugepaged-fix-wrong-result-value-for-trace_mm_colla.patch
+mm-hugeltb-handle-the-error-case-in-hugetlb_fix_rese.patch
+mm-migrate.c-fix-potential-indeterminate-pte-entry-i.patch
+ksm-fix-potential-missing-rmap_item-for-stable_node.patch
+mm-gup-check-every-subpage-of-a-compound-page-during.patch
+mm-gup-return-an-error-on-migration-failure.patch
+mm-gup-check-for-isolation-errors.patch
+ethtool-fix-missing-nlm_f_multi-flag-when-dumping.patch
+net-fix-nla_strcmp-to-handle-more-then-one-trailing-.patch
+smc-disallow-tcp_ulp-in-smc_setsockopt.patch
+netfilter-nfnetlink_osf-fix-a-missing-skb_header_poi.patch
+netfilter-nftables-fix-a-memleak-from-userdata-error.patch
+can-mcp251xfd-mcp251xfd_probe-add-missing-can_rx_off.patch
+can-mcp251x-fix-resume-from-sleep-before-interface-w.patch
+can-m_can-m_can_tx_work_queue-fix-tx_skb-race-condit.patch
+sched-fix-out-of-bound-access-in-uclamp.patch
+sched-fair-fix-unfairness-caused-by-missing-load-dec.patch
+net-ipa-fix-inter-ee-irq-register-definitions.patch
+fs-proc-generic.c-fix-incorrect-pde_is_permanent-che.patch
+kernel-kexec_file-fix-error-return-code-of-kexec_cal.patch
+kernel-resource-make-walk_system_ram_res-find-all-bu.patch
+kernel-resource-make-walk_mem_res-find-all-busy-iore.patch
+netfilter-nftables-avoid-overflows-in-nft_hash_bucke.patch
+i40e-fix-broken-xdp-support.patch
+i40e-fix-use-after-free-in-i40e_client_subtask.patch
+i40e-fix-the-restart-auto-negotiation-after-fec-modi.patch
+i40e-fix-phy-type-identifiers-for-2.5g-and-5g-adapte.patch
+mptcp-fix-splat-when-closing-unaccepted-socket.patch
diff --git a/queue-5.11/smc-disallow-tcp_ulp-in-smc_setsockopt.patch b/queue-5.11/smc-disallow-tcp_ulp-in-smc_setsockopt.patch
new file mode 100644 (file)
index 0000000..0bc39b2
--- /dev/null
@@ -0,0 +1,55 @@
+From 62453903b0019cc7e01690ac2761247762021da6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 12:40:48 -0700
+Subject: smc: disallow TCP_ULP in smc_setsockopt()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 8621436671f3a4bba5db57482e1ee604708bf1eb ]
+
+syzbot is able to setup kTLS on an SMC socket which coincidentally
+uses sk_user_data too. Later, kTLS treats it as psock so triggers a
+refcnt warning. The root cause is that smc_setsockopt() simply calls
+TCP setsockopt() which includes TCP_ULP. I do not think it makes
+sense to setup kTLS on top of SMC sockets, so we should just disallow
+this setup.
+
+It is hard to find a commit to blame, but we can apply this patch
+since the beginning of TCP_ULP.
+
+Reported-and-tested-by: syzbot+b54a1ce86ba4a623b7f0@syzkaller.appspotmail.com
+Fixes: 734942cc4ea6 ("tcp: ULP infrastructure")
+Cc: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 47340b3b514f..cb23cca72c24 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -2162,6 +2162,9 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
+       struct smc_sock *smc;
+       int val, rc;
++      if (level == SOL_TCP && optname == TCP_ULP)
++              return -EOPNOTSUPP;
++
+       smc = smc_sk(sk);
+       /* generic setsockopts reaching us here always apply to the
+@@ -2186,7 +2189,6 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
+       if (rc || smc->use_fallback)
+               goto out;
+       switch (optname) {
+-      case TCP_ULP:
+       case TCP_FASTOPEN:
+       case TCP_FASTOPEN_CONNECT:
+       case TCP_FASTOPEN_KEY:
+-- 
+2.30.2
+
diff --git a/queue-5.11/sunrpc-fix-misplaced-barrier-in-call_decode.patch b/queue-5.11/sunrpc-fix-misplaced-barrier-in-call_decode.patch
new file mode 100644 (file)
index 0000000..5a9b904
--- /dev/null
@@ -0,0 +1,68 @@
+From b470504f690da2b12c481659b0f5f3daca522fe8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 14:10:51 +1000
+Subject: sunrpc: Fix misplaced barrier in call_decode
+
+From: Baptiste Lepers <baptiste.lepers@gmail.com>
+
+[ Upstream commit f8f7e0fb22b2e75be55f2f0c13e229e75b0eac07 ]
+
+Fix a misplaced barrier in call_decode. The struct rpc_rqst is modified
+as follows by xprt_complete_rqst:
+
+req->rq_private_buf.len = copied;
+/* Ensure all writes are done before we update */
+/* req->rq_reply_bytes_recvd */
+smp_wmb();
+req->rq_reply_bytes_recvd = copied;
+
+And currently read as follows by call_decode:
+
+smp_rmb(); // misplaced
+if (!req->rq_reply_bytes_recvd)
+   goto out;
+req->rq_rcv_buf.len = req->rq_private_buf.len;
+
+This patch places the smp_rmb after the if to ensure that
+rq_reply_bytes_recvd and rq_private_buf.len are read in order.
+
+Fixes: 9ba828861c56a ("SUNRPC: Don't try to parse incomplete RPC messages")
+Signed-off-by: Baptiste Lepers <baptiste.lepers@gmail.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/clnt.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index c2a01125be1a..f555d335e910 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -2456,12 +2456,6 @@ call_decode(struct rpc_task *task)
+               task->tk_flags &= ~RPC_CALL_MAJORSEEN;
+       }
+-      /*
+-       * Ensure that we see all writes made by xprt_complete_rqst()
+-       * before it changed req->rq_reply_bytes_recvd.
+-       */
+-      smp_rmb();
+-
+       /*
+        * Did we ever call xprt_complete_rqst()? If not, we should assume
+        * the message is incomplete.
+@@ -2470,6 +2464,11 @@ call_decode(struct rpc_task *task)
+       if (!req->rq_reply_bytes_recvd)
+               goto out;
++      /* Ensure that we see all writes made by xprt_complete_rqst()
++       * before it changed req->rq_reply_bytes_recvd.
++       */
++      smp_rmb();
++
+       req->rq_rcv_buf.len = req->rq_private_buf.len;
+       trace_rpc_xdr_recvfrom(task, &req->rq_rcv_buf);
+-- 
+2.30.2
+
diff --git a/queue-5.11/sunrpc-fix-null-pointer-dereference-in-svc_rqst_free.patch b/queue-5.11/sunrpc-fix-null-pointer-dereference-in-svc_rqst_free.patch
new file mode 100644 (file)
index 0000000..1fc88b4
--- /dev/null
@@ -0,0 +1,39 @@
+From 30f80ba2bd58775fe8ab1222e0d6dbfba633f5cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:42:58 +0800
+Subject: SUNRPC: Fix null pointer dereference in svc_rqst_free()
+
+From: Yunjian Wang <wangyunjian@huawei.com>
+
+[ Upstream commit b9f83ffaa0c096b4c832a43964fe6bff3acffe10 ]
+
+When alloc_pages_node() returns null in svc_rqst_alloc(), the
+null rq_scratch_page pointer will be dereferenced when calling
+put_page() in svc_rqst_free(). Fix it by adding a null check.
+
+Addresses-Coverity: ("Dereference after null check")
+Fixes: 5191955d6fc6 ("SUNRPC: Prepare for xdr_stream-style decoding on the server-side")
+Signed-off-by: Yunjian Wang <wangyunjian@huawei.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/svc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
+index 7034b4755fa1..16b6681a97ab 100644
+--- a/net/sunrpc/svc.c
++++ b/net/sunrpc/svc.c
+@@ -846,7 +846,8 @@ void
+ svc_rqst_free(struct svc_rqst *rqstp)
+ {
+       svc_release_buffer(rqstp);
+-      put_page(rqstp->rq_scratch_page);
++      if (rqstp->rq_scratch_page)
++              put_page(rqstp->rq_scratch_page);
+       kfree(rqstp->rq_resp);
+       kfree(rqstp->rq_argp);
+       kfree(rqstp->rq_auth_data);
+-- 
+2.30.2
+
diff --git a/queue-5.11/sunrpc-fix-ternary-sign-expansion-bug-in-tracing.patch b/queue-5.11/sunrpc-fix-ternary-sign-expansion-bug-in-tracing.patch
new file mode 100644 (file)
index 0000000..c030aed
--- /dev/null
@@ -0,0 +1,42 @@
+From a80138e00064c55dc69bb01508f7bdbfd1cdd4ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 12:14:37 +0300
+Subject: SUNRPC: fix ternary sign expansion bug in tracing
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit cb579086536f6564f5846f89808ec394ef8b8621 ]
+
+This code is supposed to pass negative "err" values for tracing but it
+passes positive values instead.  The problem is that the
+trace_svcsock_tcp_send() function takes a long but "err" is an int and
+"sent" is a u32.  The negative is first type promoted to u32 so it
+becomes a high positive then it is promoted to long and it stays
+positive.
+
+Fix this by casting "err" directly to long.
+
+Fixes: 998024dee197 ("SUNRPC: Add more svcsock tracepoints")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/svcsock.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+index 5a809c64dc7b..42a400135d41 100644
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -1176,7 +1176,7 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp)
+               goto out_notconn;
+       err = svc_tcp_sendmsg(svsk->sk_sock, &msg, xdr, marker, &sent);
+       xdr_free_bvec(xdr);
+-      trace_svcsock_tcp_send(xprt, err < 0 ? err : sent);
++      trace_svcsock_tcp_send(xprt, err < 0 ? (long)err : sent);
+       if (err < 0 || sent != (xdr->len + sizeof(marker)))
+               goto out_close;
+       mutex_unlock(&xprt->xpt_mutex);
+-- 
+2.30.2
+
diff --git a/queue-5.11/sunrpc-handle-major-timeout-in-xprt_adjust_timeout.patch b/queue-5.11/sunrpc-handle-major-timeout-in-xprt_adjust_timeout.patch
new file mode 100644 (file)
index 0000000..7fbf656
--- /dev/null
@@ -0,0 +1,61 @@
+From 339e06ee49a2e8a860fdbba42457c32635661745 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Apr 2021 21:29:26 -0400
+Subject: SUNRPC: Handle major timeout in xprt_adjust_timeout()
+
+From: Chris Dion <Christopher.Dion@dell.com>
+
+[ Upstream commit 09252177d5f924f404551b4b4eded5daa7f04a3a ]
+
+Currently if a major timeout value is reached, but the minor value has
+not been reached, an ETIMEOUT will not be sent back to the caller.
+This can occur if the v4 server is not responding to requests and
+retrans is configured larger than the default of two.
+
+For example, A TCP mount with a configured timeout value of 50 and a
+retransmission count of 3 to a v4 server which is not responding:
+
+1. Initial value and increment set to 5s, maxval set to 20s, retries at 3
+2. Major timeout is set to 20s, minor timeout set to 5s initially
+3. xport_adjust_timeout() is called after 5s, retry with 10s timeout,
+   minor timeout is bumped to 10s
+4. And again after another 10s, 15s total time with minor timeout set
+   to 15s
+5. After 20s total time xport_adjust_timeout is called as major timeout is
+   reached, but skipped because the minor timeout is not reached
+       - After this time the cpu spins continually calling
+                xport_adjust_timeout() and returning 0 for 10 seconds.
+        As seen on perf sched:
+        39243.913182 [0005]  mount.nfs[3794] 4607.938      0.017   9746.863
+6. This continues until the 15s minor timeout condition is reached (in
+   this case for 10 seconds). After which the ETIMEOUT is processed
+   back to the caller, the cpu spinning stops, and normal operations
+   continue
+
+Fixes: 7de62bc09fe6 ("SUNRPC dont update timeout value on connection reset")
+Signed-off-by: Chris Dion <Christopher.Dion@dell.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/xprt.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+index 11ebe8a127b8..20fe31b1b776 100644
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -698,9 +698,9 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
+       const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout;
+       int status = 0;
+-      if (time_before(jiffies, req->rq_minortimeo))
+-              return status;
+       if (time_before(jiffies, req->rq_majortimeo)) {
++              if (time_before(jiffies, req->rq_minortimeo))
++                      return status;
+               if (to->to_exponential)
+                       req->rq_timeout <<= 1;
+               else
+-- 
+2.30.2
+
diff --git a/queue-5.11/sunrpc-move-fault-injection-call-sites.patch b/queue-5.11/sunrpc-move-fault-injection-call-sites.patch
new file mode 100644 (file)
index 0000000..0476ae6
--- /dev/null
@@ -0,0 +1,85 @@
+From 2f535975d4ac1a2d001bd9f611fd00c752f33feb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 13:22:14 -0400
+Subject: SUNRPC: Move fault injection call sites
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 7638e0bfaed1b653d3ca663e560e9ffb44bb1030 ]
+
+I've hit some crashes that occur in the xprt_rdma_inject_disconnect
+path. It appears that, for some provides, rdma_disconnect() can
+take so long that the transport can disconnect and release its
+hardware resources while rdma_disconnect() is still running,
+resulting in a UAF in the provider.
+
+The transport's fault injection method may depend on the stability
+of transport data structures. That means it needs to be invoked
+only from contexts that hold the transport write lock.
+
+Fixes: 4a0682583988 ("SUNRPC: Transport fault injection")
+Signed-off-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/clnt.c               | 1 -
+ net/sunrpc/xprt.c               | 6 ++++--
+ net/sunrpc/xprtrdma/transport.c | 6 ++++--
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 612f0a641f4c..c2a01125be1a 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -1799,7 +1799,6 @@ call_allocate(struct rpc_task *task)
+       status = xprt->ops->buf_alloc(task);
+       trace_rpc_buf_alloc(task, status);
+-      xprt_inject_disconnect(xprt);
+       if (status == 0)
+               return;
+       if (status != -ENOMEM) {
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+index 691ccf8049a4..d616b93751d8 100644
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -1483,7 +1483,10 @@ bool xprt_prepare_transmit(struct rpc_task *task)
+ void xprt_end_transmit(struct rpc_task *task)
+ {
+-      xprt_release_write(task->tk_rqstp->rq_xprt, task);
++      struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
++
++      xprt_inject_disconnect(xprt);
++      xprt_release_write(xprt, task);
+ }
+ /**
+@@ -1885,7 +1888,6 @@ void xprt_release(struct rpc_task *task)
+       spin_unlock(&xprt->transport_lock);
+       if (req->rq_buffer)
+               xprt->ops->buf_free(task);
+-      xprt_inject_disconnect(xprt);
+       xdr_free_bvec(&req->rq_rcv_buf);
+       xdr_free_bvec(&req->rq_snd_buf);
+       if (req->rq_cred != NULL)
+diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
+index 78d29d1bcc20..09953597d055 100644
+--- a/net/sunrpc/xprtrdma/transport.c
++++ b/net/sunrpc/xprtrdma/transport.c
+@@ -262,8 +262,10 @@ xprt_rdma_connect_worker(struct work_struct *work)
+  * xprt_rdma_inject_disconnect - inject a connection fault
+  * @xprt: transport context
+  *
+- * If @xprt is connected, disconnect it to simulate spurious connection
+- * loss.
++ * If @xprt is connected, disconnect it to simulate spurious
++ * connection loss. Caller must hold @xprt's send lock to
++ * ensure that data structures and hardware resources are
++ * stable during the rdma_disconnect() call.
+  */
+ static void
+ xprt_rdma_inject_disconnect(struct rpc_xprt *xprt)
+-- 
+2.30.2
+
diff --git a/queue-5.11/sunrpc-remove-trace_xprt_transmit_queued.patch b/queue-5.11/sunrpc-remove-trace_xprt_transmit_queued.patch
new file mode 100644 (file)
index 0000000..08b6a65
--- /dev/null
@@ -0,0 +1,63 @@
+From d02320e9be4a6b8a6e02e3122e93d4d97aa3efee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 16:03:08 -0400
+Subject: SUNRPC: Remove trace_xprt_transmit_queued
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 6cf23783f750634e10daeede48b0f5f5d64ebf3a ]
+
+This tracepoint can crash when dereferencing snd_task because
+when some transports connect, they put a cookie in that field
+instead of a pointer to an rpc_task.
+
+BUG: KASAN: use-after-free in trace_event_raw_event_xprt_writelock_event+0x141/0x18e [sunrpc]
+Read of size 2 at addr ffff8881a83bd3a0 by task git/331872
+
+CPU: 11 PID: 331872 Comm: git Tainted: G S                5.12.0-rc2-00007-g3ab6e585a7f9 #1453
+Hardware name: Supermicro SYS-6028R-T/X10DRi, BIOS 1.1a 10/16/2015
+Call Trace:
+ dump_stack+0x9c/0xcf
+ print_address_description.constprop.0+0x18/0x239
+ kasan_report+0x174/0x1b0
+ trace_event_raw_event_xprt_writelock_event+0x141/0x18e [sunrpc]
+ xprt_prepare_transmit+0x8e/0xc1 [sunrpc]
+ call_transmit+0x4d/0xc6 [sunrpc]
+
+Fixes: 9ce07ae5eb1d ("SUNRPC: Replace dprintk() call site in xprt_prepare_transmit")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/events/sunrpc.h | 1 -
+ net/sunrpc/xprt.c             | 2 --
+ 2 files changed, 3 deletions(-)
+
+diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
+index 6f89c27265f5..9db5702a84a5 100644
+--- a/include/trace/events/sunrpc.h
++++ b/include/trace/events/sunrpc.h
+@@ -1141,7 +1141,6 @@ DECLARE_EVENT_CLASS(xprt_writelock_event,
+ DEFINE_WRITELOCK_EVENT(reserve_xprt);
+ DEFINE_WRITELOCK_EVENT(release_xprt);
+-DEFINE_WRITELOCK_EVENT(transmit_queued);
+ DECLARE_EVENT_CLASS(xprt_cong_event,
+       TP_PROTO(
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+index d616b93751d8..11ebe8a127b8 100644
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -1469,8 +1469,6 @@ bool xprt_prepare_transmit(struct rpc_task *task)
+       struct rpc_xprt *xprt = req->rq_xprt;
+       if (!xprt_lock_write(xprt, task)) {
+-              trace_xprt_transmit_queued(xprt, task);
+-
+               /* Race breaker: someone may have transmitted us */
+               if (!test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
+                       rpc_wake_up_queued_task_set_status(&xprt->sending,
+-- 
+2.30.2
+
diff --git a/queue-5.11/swiotlb-fix-the-type-of-index.patch b/queue-5.11/swiotlb-fix-the-type-of-index.patch
new file mode 100644 (file)
index 0000000..5e4d78e
--- /dev/null
@@ -0,0 +1,38 @@
+From d885e98e72f657836e65635dbafdb277386f64b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 16:14:53 +0800
+Subject: swiotlb: Fix the type of index
+
+From: Claire Chang <tientzu@chromium.org>
+
+[ Upstream commit 95b079d8215b83b37fa59341fda92fcb9392f14a ]
+
+Fix the type of index from unsigned int to int since find_slots() might
+return -1.
+
+Fixes: 26a7e094783d ("swiotlb: refactor swiotlb_tbl_map_single")
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Claire Chang <tientzu@chromium.org>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/swiotlb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
+index 33a2a702b152..b897756202df 100644
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -579,7 +579,8 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
+               enum dma_data_direction dir, unsigned long attrs)
+ {
+       unsigned int offset = swiotlb_align_offset(dev, orig_addr);
+-      unsigned int index, i;
++      unsigned int i;
++      int index;
+       phys_addr_t tlb_addr;
+       if (no_iotlb_memory)
+-- 
+2.30.2
+
diff --git a/queue-5.11/thermal-drivers-tsens-fix-missing-put_device-error.patch b/queue-5.11/thermal-drivers-tsens-fix-missing-put_device-error.patch
new file mode 100644 (file)
index 0000000..f0d9cab
--- /dev/null
@@ -0,0 +1,45 @@
+From 26b3def26dc5e4bf80373a62759cb73599238210 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Apr 2021 20:54:31 +0800
+Subject: thermal/drivers/tsens: Fix missing put_device error
+
+From: Guangqing Zhu <zhuguangqing83@gmail.com>
+
+[ Upstream commit f4136863e8899fa0554343201b78b9e197c78a78 ]
+
+Fixes coccicheck error:
+
+drivers/thermal/qcom/tsens.c:759:4-10: ERROR: missing put_device; call
+of_find_device_by_node on line 715, but without a corresponding object
+release within this function.
+
+Fixes: a7ff82976122 ("drivers: thermal: tsens: Merge tsens-common.c into tsens.c")
+Signed-off-by: Guangqing Zhu <zhuguangqing83@gmail.com>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20210404125431.12208-1-zhuguangqing83@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qcom/tsens.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index d8ce3a687b80..3c4c0516e58a 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -755,8 +755,10 @@ int __init init_common(struct tsens_priv *priv)
+               for (i = VER_MAJOR; i <= VER_STEP; i++) {
+                       priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
+                                                             priv->fields[i]);
+-                      if (IS_ERR(priv->rf[i]))
+-                              return PTR_ERR(priv->rf[i]);
++                      if (IS_ERR(priv->rf[i])) {
++                              ret = PTR_ERR(priv->rf[i]);
++                              goto err_put_device;
++                      }
+               }
+               ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);
+               if (ret)
+-- 
+2.30.2
+
diff --git a/queue-5.11/thermal-thermal_of-fix-error-return-code-of-thermal_.patch b/queue-5.11/thermal-thermal_of-fix-error-return-code-of-thermal_.patch
new file mode 100644 (file)
index 0000000..2d445c4
--- /dev/null
@@ -0,0 +1,53 @@
+From 0c72b25fe53be30e0551e1785b4646a2ca099e2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Mar 2021 04:24:23 -0800
+Subject: thermal: thermal_of: Fix error return code of
+ thermal_of_populate_bind_params()
+
+From: Jia-Ju Bai <baijiaju1990@gmail.com>
+
+[ Upstream commit 45c7eaeb29d67224db4ba935deb575586a1fda09 ]
+
+When kcalloc() returns NULL to __tcbp or of_count_phandle_with_args()
+returns zero or -ENOENT to count, no error return code of
+thermal_of_populate_bind_params() is assigned.
+To fix these bugs, ret is assigned with -ENOMEM and -ENOENT in these
+cases, respectively.
+
+Fixes: a92bab8919e3 ("of: thermal: Allow multiple devices to share cooling map")
+Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
+Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20210310122423.3266-1-baijiaju1990@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_of.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
+index 69ef12f852b7..5b76f9a1280d 100644
+--- a/drivers/thermal/thermal_of.c
++++ b/drivers/thermal/thermal_of.c
+@@ -704,14 +704,17 @@ static int thermal_of_populate_bind_params(struct device_node *np,
+       count = of_count_phandle_with_args(np, "cooling-device",
+                                          "#cooling-cells");
+-      if (!count) {
++      if (count <= 0) {
+               pr_err("Add a cooling_device property with at least one device\n");
++              ret = -ENOENT;
+               goto end;
+       }
+       __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL);
+-      if (!__tcbp)
++      if (!__tcbp) {
++              ret = -ENOMEM;
+               goto end;
++      }
+       for (i = 0; i < count; i++) {
+               ret = of_parse_phandle_with_args(np, "cooling-device",
+-- 
+2.30.2
+
diff --git a/queue-5.11/tipc-convert-dest-node-s-address-to-network-order.patch b/queue-5.11/tipc-convert-dest-node-s-address-to-network-order.patch
new file mode 100644 (file)
index 0000000..d4311cf
--- /dev/null
@@ -0,0 +1,41 @@
+From 14cc779a4e374b24f2e0fa6d921c0ab4f1dc1bb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Mar 2021 10:33:22 +0700
+Subject: tipc: convert dest node's address to network order
+
+From: Hoang Le <hoang.h.le@dektech.com.au>
+
+[ Upstream commit 1980d37565061ab44bdc2f9e4da477d3b9752e81 ]
+
+(struct tipc_link_info)->dest is in network order (__be32), so we must
+convert the value to network order before assigning. The problem detected
+by sparse:
+
+net/tipc/netlink_compat.c:699:24: warning: incorrect type in assignment (different base types)
+net/tipc/netlink_compat.c:699:24:    expected restricted __be32 [usertype] dest
+net/tipc/netlink_compat.c:699:24:    got int
+
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Hoang Le <hoang.h.le@dektech.com.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/netlink_compat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
+index 5a1ce64039f7..0749df80454d 100644
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -696,7 +696,7 @@ static int tipc_nl_compat_link_dump(struct tipc_nl_compat_msg *msg,
+       if (err)
+               return err;
+-      link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
++      link_info.dest = htonl(nla_get_flag(link[TIPC_NLA_LINK_DEST]));
+       link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
+       nla_strscpy(link_info.str, link[TIPC_NLA_LINK_NAME],
+                   TIPC_MAX_LINK_NAME);
+-- 
+2.30.2
+
diff --git a/queue-5.11/virtiofs-fix-userns.patch b/queue-5.11/virtiofs-fix-userns.patch
new file mode 100644 (file)
index 0000000..28b42d7
--- /dev/null
@@ -0,0 +1,38 @@
+From 8f11e8b52ebe66f3de8877b7739f86cd6199b065 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Apr 2021 10:40:58 +0200
+Subject: virtiofs: fix userns
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+[ Upstream commit 0a7419c68a45d2d066b996be5087aa2d07ce80eb ]
+
+get_user_ns() is done twice (once in virtio_fs_get_tree() and once in
+fuse_conn_init()), resulting in a reference leak.
+
+Also looks better to use fsc->user_ns (which *should* be the
+current_user_ns() at this point).
+
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/virtio_fs.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
+index 1e5affed158e..005209b1cd50 100644
+--- a/fs/fuse/virtio_fs.c
++++ b/fs/fuse/virtio_fs.c
+@@ -1437,8 +1437,7 @@ static int virtio_fs_get_tree(struct fs_context *fsc)
+       if (!fm)
+               goto out_err;
+-      fuse_conn_init(fc, fm, get_user_ns(current_user_ns()),
+-                     &virtio_fs_fiq_ops, fs);
++      fuse_conn_init(fc, fm, fsc->user_ns, &virtio_fs_fiq_ops, fs);
+       fc->release = fuse_free_conn;
+       fc->delete_stale = true;
+       fc->auto_submounts = true;
+-- 
+2.30.2
+
diff --git a/queue-5.11/watchdog-explicitly-update-timestamp-when-reporting-.patch b/queue-5.11/watchdog-explicitly-update-timestamp-when-reporting-.patch
new file mode 100644 (file)
index 0000000..e9cea86
--- /dev/null
@@ -0,0 +1,57 @@
+From 9e64e82789d1d0f8e0456f71905f7f06130d29ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 22:54:23 -0700
+Subject: watchdog: explicitly update timestamp when reporting softlockup
+
+From: Petr Mladek <pmladek@suse.com>
+
+[ Upstream commit c9ad17c991492f4390f42598f6ab0531f87eed07 ]
+
+The softlockup situation might stay for a long time or even forever.  When
+it happens, the softlockup debug messages are printed in regular intervals
+defined by get_softlockup_thresh().
+
+There is a mystery.  The repeated message is printed after the full
+interval that is defined by get_softlockup_thresh().  But the timer
+callback is called more often as defined by sample_period.  The code looks
+like the soflockup should get reported in every sample_period when it was
+once behind the thresh.
+
+It works only by chance.  The watchdog is touched when printing the stall
+report, for example, in printk_stack_address().
+
+Make the behavior clear and predictable by explicitly updating the
+timestamp in watchdog_timer_fn() when the report gets printed.
+
+Link: https://lkml.kernel.org/r/20210311122130.6788-3-pmladek@suse.com
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Laurence Oberman <loberman@redhat.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vincent Whitchurch <vincent.whitchurch@axis.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>
+---
+ kernel/watchdog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/kernel/watchdog.c b/kernel/watchdog.c
+index c58244064de8..7776d53a015c 100644
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -409,6 +409,9 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
+                       }
+               }
++              /* Start period for the next softlockup warning. */
++              update_touch_ts();
++
+               pr_emerg("BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n",
+                       smp_processor_id(), duration,
+                       current->comm, task_pid_nr(current));
+-- 
+2.30.2
+
diff --git a/queue-5.11/watchdog-fix-barriers-when-printing-backtraces-from-.patch b/queue-5.11/watchdog-fix-barriers-when-printing-backtraces-from-.patch
new file mode 100644 (file)
index 0000000..d4e69c0
--- /dev/null
@@ -0,0 +1,76 @@
+From bca2f5908f22f5379aeae4d02b23f1ba5d31255c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 22:54:33 -0700
+Subject: watchdog: fix barriers when printing backtraces from all CPUs
+
+From: Petr Mladek <pmladek@suse.com>
+
+[ Upstream commit 9f113bf760ca90d709f8f89a733d10abb1f04a83 ]
+
+Any parallel softlockup reports are skipped when one CPU is already
+printing backtraces from all CPUs.
+
+The exclusive rights are synchronized using one bit in
+soft_lockup_nmi_warn.  There is also one memory barrier that does not make
+much sense.
+
+Use two barriers on the right location to prevent mixing two reports.
+
+[pmladek@suse.com: use bit lock operations to prevent multiple soft-lockup reports]
+  Link: https://lkml.kernel.org/r/YFSVsLGVWMXTvlbk@alley
+
+Link: https://lkml.kernel.org/r/20210311122130.6788-6-pmladek@suse.com
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Laurence Oberman <loberman@redhat.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vincent Whitchurch <vincent.whitchurch@axis.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>
+---
+ kernel/watchdog.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/kernel/watchdog.c b/kernel/watchdog.c
+index 122e272ad7f2..01bf977090dc 100644
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -393,11 +393,12 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
+               if (kvm_check_and_clear_guest_paused())
+                       return HRTIMER_RESTART;
++              /*
++               * Prevent multiple soft-lockup reports if one cpu is already
++               * engaged in dumping all cpu back traces.
++               */
+               if (softlockup_all_cpu_backtrace) {
+-                      /* Prevent multiple soft-lockup reports if one cpu is already
+-                       * engaged in dumping cpu back traces
+-                       */
+-                      if (test_and_set_bit(0, &soft_lockup_nmi_warn))
++                      if (test_and_set_bit_lock(0, &soft_lockup_nmi_warn))
+                               return HRTIMER_RESTART;
+               }
+@@ -415,14 +416,8 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
+                       dump_stack();
+               if (softlockup_all_cpu_backtrace) {
+-                      /* Avoid generating two back traces for current
+-                       * given that one is already made above
+-                       */
+                       trigger_allbutself_cpu_backtrace();
+-
+-                      clear_bit(0, &soft_lockup_nmi_warn);
+-                      /* Barrier to sync with other cpus */
+-                      smp_mb__after_atomic();
++                      clear_bit_unlock(0, &soft_lockup_nmi_warn);
+               }
+               add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK);
+-- 
+2.30.2
+
diff --git a/queue-5.11/watchdog-rename-__touch_watchdog-to-a-better-descrip.patch b/queue-5.11/watchdog-rename-__touch_watchdog-to-a-better-descrip.patch
new file mode 100644 (file)
index 0000000..b8a75a6
--- /dev/null
@@ -0,0 +1,103 @@
+From dde77a2e344dfedfbc99cbf36775337a280e4cfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 22:54:20 -0700
+Subject: watchdog: rename __touch_watchdog() to a better descriptive name
+
+From: Petr Mladek <pmladek@suse.com>
+
+[ Upstream commit 7c0012f522c802d25be102bafe54f333168e6119 ]
+
+Patch series "watchdog/softlockup: Report overall time and some cleanup", v2.
+
+I dug deep into the softlockup watchdog history when time permitted this
+year.  And reworked the patchset that fixed timestamps and cleaned up the
+code[2].
+
+I split it into very small steps and did even more code clean up.  The
+result looks quite strightforward and I am pretty confident with the
+changes.
+
+[1] v2: https://lore.kernel.org/r/20201210160038.31441-1-pmladek@suse.com
+[2] v1: https://lore.kernel.org/r/20191024114928.15377-1-pmladek@suse.com
+
+This patch (of 6):
+
+There are many touch_*watchdog() functions.  They are called in situations
+where the watchdog could report false positives or create unnecessary
+noise.  For example, when CPU is entering idle mode, a virtual machine is
+stopped, or a lot of messages are printed in the atomic context.
+
+These functions set SOFTLOCKUP_RESET instead of a real timestamp.  It
+allows to call them even in a context where jiffies might be outdated.
+For example, in an atomic context.
+
+The real timestamp is set by __touch_watchdog() that is called from the
+watchdog timer callback.
+
+Rename this callback to update_touch_ts().  It better describes the effect
+and clearly distinguish is from the other touch_*watchdog() functions.
+
+Another motivation is that two timestamps are going to be used.  One will
+be used for the total softlockup time.  The other will be used to measure
+time since the last report.  The new function name will help to
+distinguish which timestamp is being updated.
+
+Link: https://lkml.kernel.org/r/20210311122130.6788-1-pmladek@suse.com
+Link: https://lkml.kernel.org/r/20210311122130.6788-2-pmladek@suse.com
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Laurence Oberman <loberman@redhat.com>
+Cc: Vincent Whitchurch <vincent.whitchurch@axis.com>
+Cc: Michal Hocko <mhocko@suse.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>
+---
+ kernel/watchdog.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/watchdog.c b/kernel/watchdog.c
+index 71109065bd8e..c58244064de8 100644
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -236,7 +236,7 @@ static void set_sample_period(void)
+ }
+ /* Commands for resetting the watchdog */
+-static void __touch_watchdog(void)
++static void update_touch_ts(void)
+ {
+       __this_cpu_write(watchdog_touch_ts, get_timestamp());
+ }
+@@ -331,7 +331,7 @@ static DEFINE_PER_CPU(struct cpu_stop_work, softlockup_stop_work);
+  */
+ static int softlockup_fn(void *data)
+ {
+-      __touch_watchdog();
++      update_touch_ts();
+       complete(this_cpu_ptr(&softlockup_completion));
+       return 0;
+@@ -374,7 +374,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
+               /* Clear the guest paused flag on watchdog reset */
+               kvm_check_and_clear_guest_paused();
+-              __touch_watchdog();
++              update_touch_ts();
+               return HRTIMER_RESTART;
+       }
+@@ -460,7 +460,7 @@ static void watchdog_enable(unsigned int cpu)
+                     HRTIMER_MODE_REL_PINNED_HARD);
+       /* Initialize timestamp */
+-      __touch_watchdog();
++      update_touch_ts();
+       /* Enable the perf event */
+       if (watchdog_enabled & NMI_WATCHDOG_ENABLED)
+               watchdog_nmi_enable(cpu);
+-- 
+2.30.2
+
diff --git a/queue-5.11/watchdog-softlockup-remove-logic-that-tried-to-preve.patch b/queue-5.11/watchdog-softlockup-remove-logic-that-tried-to-preve.patch
new file mode 100644 (file)
index 0000000..61c52c9
--- /dev/null
@@ -0,0 +1,110 @@
+From 01565b56b6754a4e927c7f89be7cbbf3f23a2133 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 22:54:30 -0700
+Subject: watchdog/softlockup: remove logic that tried to prevent repeated
+ reports
+
+From: Petr Mladek <pmladek@suse.com>
+
+[ Upstream commit 1bc503cb4a2638fb1c57801a7796aca57845ce63 ]
+
+The softlockup detector does some gymnastic with the variable
+soft_watchdog_warn.  It was added by the commit 58687acba59266735ad
+("lockup_detector: Combine nmi_watchdog and softlockup detector").
+
+The purpose is not completely clear.  There are the following clues.  They
+describe the situation how it looked after the above mentioned commit:
+
+  1. The variable was checked with a comment "only warn once".
+
+  2. The variable was set when softlockup was reported. It was cleared
+     only when the CPU was not longer in the softlockup state.
+
+  3. watchdog_touch_ts was not explicitly updated when the softlockup
+     was reported. Without this variable, the report would normally
+     be printed again during every following watchdog_timer_fn()
+     invocation.
+
+The logic has got even more tangled up by the commit ed235875e2ca98
+("kernel/watchdog.c: print traces for all cpus on lockup detection").
+After this commit, soft_watchdog_warn is set only when
+softlockup_all_cpu_backtrace is enabled.  But multiple reports from all
+CPUs are prevented by a new variable soft_lockup_nmi_warn.
+
+Conclusion:
+
+The variable probably never worked as intended.  In each case, it has not
+worked last many years because the softlockup was reported repeatedly
+after the full period defined by watchdog_thresh.
+
+The reason is that watchdog gets touched in many known slow paths, for
+example, in printk_stack_address().  This code is called also when
+printing the softlockup report.  It means that the watchdog timestamp gets
+updated after each report.
+
+Solution:
+
+Simply remove the logic. People want the periodic report anyway.
+
+Link: https://lkml.kernel.org/r/20210311122130.6788-5-pmladek@suse.com
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Laurence Oberman <loberman@redhat.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vincent Whitchurch <vincent.whitchurch@axis.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>
+---
+ kernel/watchdog.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/kernel/watchdog.c b/kernel/watchdog.c
+index 7776d53a015c..122e272ad7f2 100644
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -172,7 +172,6 @@ static u64 __read_mostly sample_period;
+ static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts);
+ static DEFINE_PER_CPU(struct hrtimer, watchdog_hrtimer);
+ static DEFINE_PER_CPU(bool, softlockup_touch_sync);
+-static DEFINE_PER_CPU(bool, soft_watchdog_warn);
+ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts);
+ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved);
+ static unsigned long soft_lockup_nmi_warn;
+@@ -394,19 +393,12 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
+               if (kvm_check_and_clear_guest_paused())
+                       return HRTIMER_RESTART;
+-              /* only warn once */
+-              if (__this_cpu_read(soft_watchdog_warn) == true)
+-                      return HRTIMER_RESTART;
+-
+               if (softlockup_all_cpu_backtrace) {
+                       /* Prevent multiple soft-lockup reports if one cpu is already
+                        * engaged in dumping cpu back traces
+                        */
+-                      if (test_and_set_bit(0, &soft_lockup_nmi_warn)) {
+-                              /* Someone else will report us. Let's give up */
+-                              __this_cpu_write(soft_watchdog_warn, true);
++                      if (test_and_set_bit(0, &soft_lockup_nmi_warn))
+                               return HRTIMER_RESTART;
+-                      }
+               }
+               /* Start period for the next softlockup warning. */
+@@ -436,9 +428,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
+               add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK);
+               if (softlockup_panic)
+                       panic("softlockup: hung tasks");
+-              __this_cpu_write(soft_watchdog_warn, true);
+-      } else
+-              __this_cpu_write(soft_watchdog_warn, false);
++      }
+       return HRTIMER_RESTART;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/wilc1000-bring-mac-address-setting-in-line-with-typi.patch b/queue-5.11/wilc1000-bring-mac-address-setting-in-line-with-typi.patch
new file mode 100644 (file)
index 0000000..81ff94f
--- /dev/null
@@ -0,0 +1,94 @@
+From 914817f83ff3df3ebaeacf9ca7a6790559345ca8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 19:50:07 +0000
+Subject: wilc1000: Bring MAC address setting in line with typical Linux
+ behavior
+
+From: David Mosberger-Tang <davidm@egauge.net>
+
+[ Upstream commit a381b78a1598dde34a6e40dae2842024308a6ef2 ]
+
+Linux network drivers normally disallow changing the MAC address when
+the interface is up.  This driver has been different in that it allows
+to change the MAC address *only* when it's up.  This patch brings
+wilc1000 behavior more in line with other network drivers.  We could
+have replaced wilc_set_mac_addr() with eth_mac_addr() but that would
+break existing documentation on how to change the MAC address.
+Likewise, return -EADDRNOTAVAIL (not -EINVAL) when the specified MAC
+address is invalid or unavailable.
+
+Signed-off-by: David Mosberger-Tang <davidm@egauge.net>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210303194846.1823596-1-davidm@egauge.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/microchip/wilc1000/netdev.c  | 25 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
+index 0c188310919e..acf7ed4bfe57 100644
+--- a/drivers/net/wireless/microchip/wilc1000/netdev.c
++++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
+@@ -575,7 +575,6 @@ static int wilc_mac_open(struct net_device *ndev)
+ {
+       struct wilc_vif *vif = netdev_priv(ndev);
+       struct wilc *wl = vif->wilc;
+-      unsigned char mac_add[ETH_ALEN] = {0};
+       int ret = 0;
+       struct mgmt_frame_regs mgmt_regs = {};
+@@ -598,9 +597,12 @@ static int wilc_mac_open(struct net_device *ndev)
+       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype,
+                               vif->idx);
+-      wilc_get_mac_address(vif, mac_add);
+-      netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
+-      ether_addr_copy(ndev->dev_addr, mac_add);
++
++      if (is_valid_ether_addr(ndev->dev_addr))
++              wilc_set_mac_address(vif, ndev->dev_addr);
++      else
++              wilc_get_mac_address(vif, ndev->dev_addr);
++      netdev_dbg(ndev, "Mac address: %pM\n", ndev->dev_addr);
+       if (!is_valid_ether_addr(ndev->dev_addr)) {
+               netdev_err(ndev, "Wrong MAC address\n");
+@@ -639,7 +641,14 @@ static int wilc_set_mac_addr(struct net_device *dev, void *p)
+       int srcu_idx;
+       if (!is_valid_ether_addr(addr->sa_data))
+-              return -EINVAL;
++              return -EADDRNOTAVAIL;
++
++      if (!vif->mac_opened) {
++              eth_commit_mac_addr_change(dev, p);
++              return 0;
++      }
++
++      /* Verify MAC Address is not already in use: */
+       srcu_idx = srcu_read_lock(&wilc->srcu);
+       list_for_each_entry_rcu(tmp_vif, &wilc->vif_list, list) {
+@@ -647,7 +656,7 @@ static int wilc_set_mac_addr(struct net_device *dev, void *p)
+               if (ether_addr_equal(addr->sa_data, mac_addr)) {
+                       if (vif != tmp_vif) {
+                               srcu_read_unlock(&wilc->srcu, srcu_idx);
+-                              return -EINVAL;
++                              return -EADDRNOTAVAIL;
+                       }
+                       srcu_read_unlock(&wilc->srcu, srcu_idx);
+                       return 0;
+@@ -659,9 +668,7 @@ static int wilc_set_mac_addr(struct net_device *dev, void *p)
+       if (result)
+               return result;
+-      ether_addr_copy(vif->bssid, addr->sa_data);
+-      ether_addr_copy(vif->ndev->dev_addr, addr->sa_data);
+-
++      eth_commit_mac_addr_change(dev, p);
+       return result;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/wl3501_cs-fix-out-of-bounds-warnings-in-wl3501_mgmt_.patch b/queue-5.11/wl3501_cs-fix-out-of-bounds-warnings-in-wl3501_mgmt_.patch
new file mode 100644 (file)
index 0000000..f5f6723
--- /dev/null
@@ -0,0 +1,286 @@
+From 67c698e21e4160d47eb9ce91638a47281eef1c38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Apr 2021 18:45:15 -0500
+Subject: wl3501_cs: Fix out-of-bounds warnings in wl3501_mgmt_join
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit bb43e5718d8f1b46e7a77e7b39be3c691f293050 ]
+
+Fix the following out-of-bounds warnings by adding a new structure
+wl3501_req instead of duplicating the same members in structure
+wl3501_join_req and wl3501_scan_confirm:
+
+arch/x86/include/asm/string_32.h:182:25: warning: '__builtin_memcpy' offset [39, 108] from the object at 'sig' is out of the bounds of referenced subobject 'beacon_period' with type 'short unsigned int' at offset 36 [-Warray-bounds]
+arch/x86/include/asm/string_32.h:182:25: warning: '__builtin_memcpy' offset [25, 95] from the object at 'sig' is out of the bounds of referenced subobject 'beacon_period' with type 'short unsigned int' at offset 22 [-Warray-bounds]
+
+Refactor the code, accordingly:
+
+$ pahole -C wl3501_req drivers/net/wireless/wl3501_cs.o
+struct wl3501_req {
+        u16                        beacon_period;        /*     0     2 */
+        u16                        dtim_period;          /*     2     2 */
+        u16                        cap_info;             /*     4     2 */
+        u8                         bss_type;             /*     6     1 */
+        u8                         bssid[6];             /*     7     6 */
+        struct iw_mgmt_essid_pset  ssid;                 /*    13    34 */
+        struct iw_mgmt_ds_pset     ds_pset;              /*    47     3 */
+        struct iw_mgmt_cf_pset     cf_pset;              /*    50     8 */
+        struct iw_mgmt_ibss_pset   ibss_pset;            /*    58     4 */
+        struct iw_mgmt_data_rset   bss_basic_rset;       /*    62    10 */
+
+        /* size: 72, cachelines: 2, members: 10 */
+        /* last cacheline: 8 bytes */
+};
+
+$ pahole -C wl3501_join_req drivers/net/wireless/wl3501_cs.o
+struct wl3501_join_req {
+        u16                        next_blk;             /*     0     2 */
+        u8                         sig_id;               /*     2     1 */
+        u8                         reserved;             /*     3     1 */
+        struct iw_mgmt_data_rset   operational_rset;     /*     4    10 */
+        u16                        reserved2;            /*    14     2 */
+        u16                        timeout;              /*    16     2 */
+        u16                        probe_delay;          /*    18     2 */
+        u8                         timestamp[8];         /*    20     8 */
+        u8                         local_time[8];        /*    28     8 */
+        struct wl3501_req          req;                  /*    36    72 */
+
+        /* size: 108, cachelines: 2, members: 10 */
+        /* last cacheline: 44 bytes */
+};
+
+$ pahole -C wl3501_scan_confirm drivers/net/wireless/wl3501_cs.o
+struct wl3501_scan_confirm {
+        u16                        next_blk;             /*     0     2 */
+        u8                         sig_id;               /*     2     1 */
+        u8                         reserved;             /*     3     1 */
+        u16                        status;               /*     4     2 */
+        char                       timestamp[8];         /*     6     8 */
+        char                       localtime[8];         /*    14     8 */
+        struct wl3501_req          req;                  /*    22    72 */
+        /* --- cacheline 1 boundary (64 bytes) was 30 bytes ago --- */
+        u8                         rssi;                 /*    94     1 */
+
+        /* size: 96, cachelines: 2, members: 8 */
+        /* padding: 1 */
+        /* last cacheline: 32 bytes */
+};
+
+The problem is that the original code is trying to copy data into a
+bunch of struct members adjacent to each other in a single call to
+memcpy(). Now that a new struct wl3501_req enclosing all those adjacent
+members is introduced, memcpy() doesn't overrun the length of
+&sig.beacon_period and &this->bss_set[i].beacon_period, because the
+address of the new struct object _req_ is used as the destination,
+instead.
+
+This helps with the ongoing efforts to globally enable -Warray-bounds
+and get us closer to being able to tighten the FORTIFY_SOURCE routines
+on memcpy().
+
+Link: https://github.com/KSPP/linux/issues/109
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/1fbaf516da763b50edac47d792a9145aa4482e29.1618442265.git.gustavoars@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/wl3501.h    | 35 +++++++++++--------------
+ drivers/net/wireless/wl3501_cs.c | 44 +++++++++++++++++---------------
+ 2 files changed, 38 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
+index 31ebef3e7ed4..87195c1dadf2 100644
+--- a/drivers/net/wireless/wl3501.h
++++ b/drivers/net/wireless/wl3501.h
+@@ -379,16 +379,7 @@ struct wl3501_get_confirm {
+       u8      mib_value[100];
+ };
+-struct wl3501_join_req {
+-      u16                         next_blk;
+-      u8                          sig_id;
+-      u8                          reserved;
+-      struct iw_mgmt_data_rset    operational_rset;
+-      u16                         reserved2;
+-      u16                         timeout;
+-      u16                         probe_delay;
+-      u8                          timestamp[8];
+-      u8                          local_time[8];
++struct wl3501_req {
+       u16                         beacon_period;
+       u16                         dtim_period;
+       u16                         cap_info;
+@@ -401,6 +392,19 @@ struct wl3501_join_req {
+       struct iw_mgmt_data_rset    bss_basic_rset;
+ };
++struct wl3501_join_req {
++      u16                         next_blk;
++      u8                          sig_id;
++      u8                          reserved;
++      struct iw_mgmt_data_rset    operational_rset;
++      u16                         reserved2;
++      u16                         timeout;
++      u16                         probe_delay;
++      u8                          timestamp[8];
++      u8                          local_time[8];
++      struct wl3501_req           req;
++};
++
+ struct wl3501_join_confirm {
+       u16     next_blk;
+       u8      sig_id;
+@@ -443,16 +447,7 @@ struct wl3501_scan_confirm {
+       u16                         status;
+       char                        timestamp[8];
+       char                        localtime[8];
+-      u16                         beacon_period;
+-      u16                         dtim_period;
+-      u16                         cap_info;
+-      u8                          bss_type;
+-      u8                          bssid[ETH_ALEN];
+-      struct iw_mgmt_essid_pset   ssid;
+-      struct iw_mgmt_ds_pset      ds_pset;
+-      struct iw_mgmt_cf_pset      cf_pset;
+-      struct iw_mgmt_ibss_pset    ibss_pset;
+-      struct iw_mgmt_data_rset    bss_basic_rset;
++      struct wl3501_req           req;
+       u8                          rssi;
+ };
+diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
+index 70307308635f..672f5d5f3f2c 100644
+--- a/drivers/net/wireless/wl3501_cs.c
++++ b/drivers/net/wireless/wl3501_cs.c
+@@ -590,7 +590,7 @@ static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas)
+       struct wl3501_join_req sig = {
+               .sig_id           = WL3501_SIG_JOIN_REQ,
+               .timeout          = 10,
+-              .ds_pset = {
++              .req.ds_pset = {
+                       .el = {
+                               .id  = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
+                               .len = 1,
+@@ -599,7 +599,7 @@ static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas)
+               },
+       };
+-      memcpy(&sig.beacon_period, &this->bss_set[stas].beacon_period, 72);
++      memcpy(&sig.req, &this->bss_set[stas].req, sizeof(sig.req));
+       return wl3501_esbq_exec(this, &sig, sizeof(sig));
+ }
+@@ -667,35 +667,37 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
+       if (sig.status == WL3501_STATUS_SUCCESS) {
+               pr_debug("success");
+               if ((this->net_type == IW_MODE_INFRA &&
+-                   (sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
++                   (sig.req.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
+                   (this->net_type == IW_MODE_ADHOC &&
+-                   (sig.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) ||
++                   (sig.req.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) ||
+                   this->net_type == IW_MODE_AUTO) {
+                       if (!this->essid.el.len)
+                               matchflag = 1;
+                       else if (this->essid.el.len == 3 &&
+                                !memcmp(this->essid.essid, "ANY", 3))
+                               matchflag = 1;
+-                      else if (this->essid.el.len != sig.ssid.el.len)
++                      else if (this->essid.el.len != sig.req.ssid.el.len)
+                               matchflag = 0;
+-                      else if (memcmp(this->essid.essid, sig.ssid.essid,
++                      else if (memcmp(this->essid.essid, sig.req.ssid.essid,
+                                       this->essid.el.len))
+                               matchflag = 0;
+                       else
+                               matchflag = 1;
+                       if (matchflag) {
+                               for (i = 0; i < this->bss_cnt; i++) {
+-                                      if (ether_addr_equal_unaligned(this->bss_set[i].bssid, sig.bssid)) {
++                                      if (ether_addr_equal_unaligned(this->bss_set[i].req.bssid,
++                                                                     sig.req.bssid)) {
+                                               matchflag = 0;
+                                               break;
+                                       }
+                               }
+                       }
+                       if (matchflag && (i < 20)) {
+-                              memcpy(&this->bss_set[i].beacon_period,
+-                                     &sig.beacon_period, 73);
++                              memcpy(&this->bss_set[i].req,
++                                     &sig.req, sizeof(sig.req));
+                               this->bss_cnt++;
+                               this->rssi = sig.rssi;
++                              this->bss_set[i].rssi = sig.rssi;
+                       }
+               }
+       } else if (sig.status == WL3501_STATUS_TIMEOUT) {
+@@ -887,19 +889,19 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
+                       if (this->join_sta_bss < this->bss_cnt) {
+                               const int i = this->join_sta_bss;
+                               memcpy(this->bssid,
+-                                     this->bss_set[i].bssid, ETH_ALEN);
+-                              this->chan = this->bss_set[i].ds_pset.chan;
++                                     this->bss_set[i].req.bssid, ETH_ALEN);
++                              this->chan = this->bss_set[i].req.ds_pset.chan;
+                               iw_copy_mgmt_info_element(&this->keep_essid.el,
+-                                                   &this->bss_set[i].ssid.el);
++                                                   &this->bss_set[i].req.ssid.el);
+                               wl3501_mgmt_auth(this);
+                       }
+               } else {
+                       const int i = this->join_sta_bss;
+-                      memcpy(&this->bssid, &this->bss_set[i].bssid, ETH_ALEN);
+-                      this->chan = this->bss_set[i].ds_pset.chan;
++                      memcpy(&this->bssid, &this->bss_set[i].req.bssid, ETH_ALEN);
++                      this->chan = this->bss_set[i].req.ds_pset.chan;
+                       iw_copy_mgmt_info_element(&this->keep_essid.el,
+-                                                &this->bss_set[i].ssid.el);
++                                                &this->bss_set[i].req.ssid.el);
+                       wl3501_online(dev);
+               }
+       } else {
+@@ -1573,30 +1575,30 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
+       for (i = 0; i < this->bss_cnt; ++i) {
+               iwe.cmd                 = SIOCGIWAP;
+               iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+-              memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
++              memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].req.bssid, ETH_ALEN);
+               current_ev = iwe_stream_add_event(info, current_ev,
+                                                 extra + IW_SCAN_MAX_DATA,
+                                                 &iwe, IW_EV_ADDR_LEN);
+               iwe.cmd           = SIOCGIWESSID;
+               iwe.u.data.flags  = 1;
+-              iwe.u.data.length = this->bss_set[i].ssid.el.len;
++              iwe.u.data.length = this->bss_set[i].req.ssid.el.len;
+               current_ev = iwe_stream_add_point(info, current_ev,
+                                                 extra + IW_SCAN_MAX_DATA,
+                                                 &iwe,
+-                                                this->bss_set[i].ssid.essid);
++                                                this->bss_set[i].req.ssid.essid);
+               iwe.cmd    = SIOCGIWMODE;
+-              iwe.u.mode = this->bss_set[i].bss_type;
++              iwe.u.mode = this->bss_set[i].req.bss_type;
+               current_ev = iwe_stream_add_event(info, current_ev,
+                                                 extra + IW_SCAN_MAX_DATA,
+                                                 &iwe, IW_EV_UINT_LEN);
+               iwe.cmd = SIOCGIWFREQ;
+-              iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
++              iwe.u.freq.m = this->bss_set[i].req.ds_pset.chan;
+               iwe.u.freq.e = 0;
+               current_ev = iwe_stream_add_event(info, current_ev,
+                                                 extra + IW_SCAN_MAX_DATA,
+                                                 &iwe, IW_EV_FREQ_LEN);
+               iwe.cmd = SIOCGIWENCODE;
+-              if (this->bss_set[i].cap_info & WL3501_MGMT_CAPABILITY_PRIVACY)
++              if (this->bss_set[i].req.cap_info & WL3501_MGMT_CAPABILITY_PRIVACY)
+                       iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+               else
+                       iwe.u.data.flags = IW_ENCODE_DISABLED;
+-- 
+2.30.2
+
diff --git a/queue-5.11/wl3501_cs-fix-out-of-bounds-warnings-in-wl3501_send_.patch b/queue-5.11/wl3501_cs-fix-out-of-bounds-warnings-in-wl3501_send_.patch
new file mode 100644 (file)
index 0000000..7159552
--- /dev/null
@@ -0,0 +1,147 @@
+From 5c4a5d4e20febb6e77d3cb7e8bc0b868dff97ab8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Apr 2021 18:43:19 -0500
+Subject: wl3501_cs: Fix out-of-bounds warnings in wl3501_send_pkt
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 820aa37638a252b57967bdf4038a514b1ab85d45 ]
+
+Fix the following out-of-bounds warnings by enclosing structure members
+daddr and saddr into new struct addr, in structures wl3501_md_req and
+wl3501_md_ind:
+
+arch/x86/include/asm/string_32.h:182:25: warning: '__builtin_memcpy' offset [18, 23] from the object at 'sig' is out of the bounds of referenced subobject 'daddr' with type 'u8[6]' {aka 'unsigned char[6]'} at offset 11 [-Warray-bounds]
+arch/x86/include/asm/string_32.h:182:25: warning: '__builtin_memcpy' offset [18, 23] from the object at 'sig' is out of the bounds of referenced subobject 'daddr' with type 'u8[6]' {aka 'unsigned char[6]'} at offset 11 [-Warray-bounds]
+
+Refactor the code, accordingly:
+
+$ pahole -C wl3501_md_req drivers/net/wireless/wl3501_cs.o
+struct wl3501_md_req {
+       u16                        next_blk;             /*     0     2 */
+       u8                         sig_id;               /*     2     1 */
+       u8                         routing;              /*     3     1 */
+       u16                        data;                 /*     4     2 */
+       u16                        size;                 /*     6     2 */
+       u8                         pri;                  /*     8     1 */
+       u8                         service_class;        /*     9     1 */
+       struct {
+               u8                 daddr[6];             /*    10     6 */
+               u8                 saddr[6];             /*    16     6 */
+       } addr;                                          /*    10    12 */
+
+       /* size: 22, cachelines: 1, members: 8 */
+       /* last cacheline: 22 bytes */
+};
+
+$ pahole -C wl3501_md_ind drivers/net/wireless/wl3501_cs.o
+struct wl3501_md_ind {
+       u16                        next_blk;             /*     0     2 */
+       u8                         sig_id;               /*     2     1 */
+       u8                         routing;              /*     3     1 */
+       u16                        data;                 /*     4     2 */
+       u16                        size;                 /*     6     2 */
+       u8                         reception;            /*     8     1 */
+       u8                         pri;                  /*     9     1 */
+       u8                         service_class;        /*    10     1 */
+       struct {
+               u8                 daddr[6];             /*    11     6 */
+               u8                 saddr[6];             /*    17     6 */
+       } addr;                                          /*    11    12 */
+
+       /* size: 24, cachelines: 1, members: 9 */
+       /* padding: 1 */
+       /* last cacheline: 24 bytes */
+};
+
+The problem is that the original code is trying to copy data into a
+couple of arrays adjacent to each other in a single call to memcpy().
+Now that a new struct _addr_ enclosing those two adjacent arrays
+is introduced, memcpy() doesn't overrun the length of &sig.daddr[0]
+and &sig.daddr, because the address of the new struct object _addr_
+is used, instead.
+
+This helps with the ongoing efforts to globally enable -Warray-bounds
+and get us closer to being able to tighten the FORTIFY_SOURCE routines
+on memcpy().
+
+Link: https://github.com/KSPP/linux/issues/109
+Reported-by: kernel test robot <lkp@intel.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/d260fe56aed7112bff2be5b4d152d03ad7b78e78.1618442265.git.gustavoars@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/wl3501.h    | 12 ++++++++----
+ drivers/net/wireless/wl3501_cs.c | 10 ++++++----
+ 2 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
+index b446cb369557..31ebef3e7ed4 100644
+--- a/drivers/net/wireless/wl3501.h
++++ b/drivers/net/wireless/wl3501.h
+@@ -471,8 +471,10 @@ struct wl3501_md_req {
+       u16     size;
+       u8      pri;
+       u8      service_class;
+-      u8      daddr[ETH_ALEN];
+-      u8      saddr[ETH_ALEN];
++      struct {
++              u8      daddr[ETH_ALEN];
++              u8      saddr[ETH_ALEN];
++      } addr;
+ };
+ struct wl3501_md_ind {
+@@ -484,8 +486,10 @@ struct wl3501_md_ind {
+       u8      reception;
+       u8      pri;
+       u8      service_class;
+-      u8      daddr[ETH_ALEN];
+-      u8      saddr[ETH_ALEN];
++      struct {
++              u8      daddr[ETH_ALEN];
++              u8      saddr[ETH_ALEN];
++      } addr;
+ };
+ struct wl3501_md_confirm {
+diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
+index 8ca5789c7b37..70307308635f 100644
+--- a/drivers/net/wireless/wl3501_cs.c
++++ b/drivers/net/wireless/wl3501_cs.c
+@@ -469,6 +469,7 @@ static int wl3501_send_pkt(struct wl3501_card *this, u8 *data, u16 len)
+       struct wl3501_md_req sig = {
+               .sig_id = WL3501_SIG_MD_REQ,
+       };
++      size_t sig_addr_len = sizeof(sig.addr);
+       u8 *pdata = (char *)data;
+       int rc = -EIO;
+@@ -484,9 +485,9 @@ static int wl3501_send_pkt(struct wl3501_card *this, u8 *data, u16 len)
+                       goto out;
+               }
+               rc = 0;
+-              memcpy(&sig.daddr[0], pdata, 12);
+-              pktlen = len - 12;
+-              pdata += 12;
++              memcpy(&sig.addr, pdata, sig_addr_len);
++              pktlen = len - sig_addr_len;
++              pdata += sig_addr_len;
+               sig.data = bf;
+               if (((*pdata) * 256 + (*(pdata + 1))) > 1500) {
+                       u8 addr4[ETH_ALEN] = {
+@@ -980,7 +981,8 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
+       } else {
+               skb->dev = dev;
+               skb_reserve(skb, 2); /* IP headers on 16 bytes boundaries */
+-              skb_copy_to_linear_data(skb, (unsigned char *)&sig.daddr, 12);
++              skb_copy_to_linear_data(skb, (unsigned char *)&sig.addr,
++                                      sizeof(sig.addr));
+               wl3501_receive(this, skb->data, pkt_len);
+               skb_put(skb, pkt_len);
+               skb->protocol   = eth_type_trans(skb, dev);
+-- 
+2.30.2
+
diff --git a/queue-5.11/xprtrdma-avoid-receive-queue-wrapping.patch b/queue-5.11/xprtrdma-avoid-receive-queue-wrapping.patch
new file mode 100644 (file)
index 0000000..36d10d2
--- /dev/null
@@ -0,0 +1,42 @@
+From 82810f1b0fc4ba05460859dd0cc982afa7332cda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 14:02:03 -0400
+Subject: xprtrdma: Avoid Receive Queue wrapping
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 32e6b68167f1d446111c973d57e6f52aee11897a ]
+
+Commit e340c2d6ef2a ("xprtrdma: Reduce the doorbell rate (Receive)")
+increased the number of Receive WRs that are posted by the client,
+but did not increase the size of the Receive Queue allocated during
+transport set-up.
+
+This is usually not an issue because RPCRDMA_BACKWARD_WRS is defined
+as (32) when SUNRPC_BACKCHANNEL is defined. In cases where it isn't,
+there is a real risk of Receive Queue wrapping.
+
+Fixes: e340c2d6ef2a ("xprtrdma: Reduce the doorbell rate (Receive)")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Tom Talpey <tom@talpey.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/xprtrdma/frwr_ops.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
+index baca49fe83af..e8b25f9290ab 100644
+--- a/net/sunrpc/xprtrdma/frwr_ops.c
++++ b/net/sunrpc/xprtrdma/frwr_ops.c
+@@ -257,6 +257,7 @@ int frwr_query_device(struct rpcrdma_ep *ep, const struct ib_device *device)
+       ep->re_attr.cap.max_send_wr += 1; /* for ib_drain_sq */
+       ep->re_attr.cap.max_recv_wr = ep->re_max_requests;
+       ep->re_attr.cap.max_recv_wr += RPCRDMA_BACKWARD_WRS;
++      ep->re_attr.cap.max_recv_wr += RPCRDMA_MAX_RECV_BATCH;
+       ep->re_attr.cap.max_recv_wr += 1; /* for ib_drain_rq */
+       ep->re_max_rdma_segs =
+-- 
+2.30.2
+
diff --git a/queue-5.11/xprtrdma-fix-cwnd-update-ordering.patch b/queue-5.11/xprtrdma-fix-cwnd-update-ordering.patch
new file mode 100644 (file)
index 0000000..249d567
--- /dev/null
@@ -0,0 +1,100 @@
+From 113bf9cbb4f9687840e0e0cb06e5ba6d3800bd2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 14:02:41 -0400
+Subject: xprtrdma: Fix cwnd update ordering
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 35d8b10a25884050bb3b0149b62c3818ec59f77c ]
+
+After a reconnect, the reply handler is opening the cwnd (and thus
+enabling more RPC Calls to be sent) /before/ rpcrdma_post_recvs()
+can post enough Receive WRs to receive their replies. This causes an
+RNR and the new connection is lost immediately.
+
+The race is most clearly exposed when KASAN and disconnect injection
+are enabled. This slows down rpcrdma_rep_create() enough to allow
+the send side to post a bunch of RPC Calls before the Receive
+completion handler can invoke ib_post_recv().
+
+Fixes: 2ae50ad68cd7 ("xprtrdma: Close window between waking RPC senders and posting Receives")
+Signed-off-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/xprtrdma/rpc_rdma.c  |  3 ++-
+ net/sunrpc/xprtrdma/verbs.c     | 10 +++++-----
+ net/sunrpc/xprtrdma/xprt_rdma.h |  2 +-
+ 3 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
+index 8f5d0cb68360..d40ace8a973d 100644
+--- a/net/sunrpc/xprtrdma/rpc_rdma.c
++++ b/net/sunrpc/xprtrdma/rpc_rdma.c
+@@ -1459,9 +1459,10 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
+               credits = 1;    /* don't deadlock */
+       else if (credits > r_xprt->rx_ep->re_max_requests)
+               credits = r_xprt->rx_ep->re_max_requests;
++      rpcrdma_post_recvs(r_xprt, credits + (buf->rb_bc_srv_max_requests << 1),
++                         false);
+       if (buf->rb_credits != credits)
+               rpcrdma_update_cwnd(r_xprt, credits);
+-      rpcrdma_post_recvs(r_xprt, false);
+       req = rpcr_to_rdmar(rqst);
+       if (unlikely(req->rl_reply))
+diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
+index ec912cf9c618..f3fffc74ab0f 100644
+--- a/net/sunrpc/xprtrdma/verbs.c
++++ b/net/sunrpc/xprtrdma/verbs.c
+@@ -535,7 +535,7 @@ int rpcrdma_xprt_connect(struct rpcrdma_xprt *r_xprt)
+        * outstanding Receives.
+        */
+       rpcrdma_ep_get(ep);
+-      rpcrdma_post_recvs(r_xprt, true);
++      rpcrdma_post_recvs(r_xprt, 1, true);
+       rc = rdma_connect(ep->re_id, &ep->re_remote_cma);
+       if (rc)
+@@ -1364,21 +1364,21 @@ int rpcrdma_post_sends(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
+ /**
+  * rpcrdma_post_recvs - Refill the Receive Queue
+  * @r_xprt: controlling transport instance
+- * @temp: mark Receive buffers to be deleted after use
++ * @needed: current credit grant
++ * @temp: mark Receive buffers to be deleted after one use
+  *
+  */
+-void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
++void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp)
+ {
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+       struct rpcrdma_ep *ep = r_xprt->rx_ep;
+       struct ib_recv_wr *wr, *bad_wr;
+       struct rpcrdma_rep *rep;
+-      int needed, count, rc;
++      int count, rc;
+       rc = 0;
+       count = 0;
+-      needed = buf->rb_credits + (buf->rb_bc_srv_max_requests << 1);
+       if (likely(ep->re_receive_count > needed))
+               goto out;
+       needed -= ep->re_receive_count;
+diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
+index 94b28657aeeb..c3bcc84c16c4 100644
+--- a/net/sunrpc/xprtrdma/xprt_rdma.h
++++ b/net/sunrpc/xprtrdma/xprt_rdma.h
+@@ -460,7 +460,7 @@ int rpcrdma_xprt_connect(struct rpcrdma_xprt *r_xprt);
+ void rpcrdma_xprt_disconnect(struct rpcrdma_xprt *r_xprt);
+ int rpcrdma_post_sends(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);
+-void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp);
++void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp);
+ /*
+  * Buffer calls - xprtrdma/verbs.c
+-- 
+2.30.2
+
diff --git a/queue-5.11/xprtrdma-rpcrdma_mr_pop-already-does-list_del_init.patch b/queue-5.11/xprtrdma-rpcrdma_mr_pop-already-does-list_del_init.patch
new file mode 100644 (file)
index 0000000..4c9d8f6
--- /dev/null
@@ -0,0 +1,35 @@
+From 2a7a1c5fdd57b306b4ef07dcd8e61b449b1a1e7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 14:02:54 -0400
+Subject: xprtrdma: rpcrdma_mr_pop() already does list_del_init()
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 1363e6388c363d0433f9aa4e2f33efe047572687 ]
+
+The rpcrdma_mr_pop() earlier in the function has already cleared
+out mr_list, so it must not be done again in the error path.
+
+Fixes: 847568942f93 ("xprtrdma: Remove fr_state")
+Signed-off-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/xprtrdma/frwr_ops.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
+index e8b25f9290ab..0104430e4c8e 100644
+--- a/net/sunrpc/xprtrdma/frwr_ops.c
++++ b/net/sunrpc/xprtrdma/frwr_ops.c
+@@ -582,7 +582,6 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
+               mr = container_of(frwr, struct rpcrdma_mr, frwr);
+               bad_wr = bad_wr->next;
+-              list_del_init(&mr->mr_list);
+               frwr_mr_recycle(mr);
+       }
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.11/xsk-fix-for-xp_aligned_validate_desc-when-len-chunk_.patch b/queue-5.11/xsk-fix-for-xp_aligned_validate_desc-when-len-chunk_.patch
new file mode 100644 (file)
index 0000000..ed7709a
--- /dev/null
@@ -0,0 +1,54 @@
+From 4a3ad89bf5364f190e41c0d5397eb7aa07c2d836 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 17:44:24 +0800
+Subject: xsk: Fix for xp_aligned_validate_desc() when len == chunk_size
+
+From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+
+[ Upstream commit ac31565c21937eee9117e43c9cd34f557f6f1cb8 ]
+
+When desc->len is equal to chunk_size, it is legal. But when the
+xp_aligned_validate_desc() got chunk_end from desc->addr + desc->len
+pointing to the next chunk during the check, it caused the check to
+fail.
+
+This problem was first introduced in bbff2f321a86 ("xsk: new descriptor
+addressing scheme"). Later in 2b43470add8c ("xsk: Introduce AF_XDP buffer
+allocation API") this piece of code was moved into the new function called
+xp_aligned_validate_desc(). This function was then moved into xsk_queue.h
+via 26062b185eee ("xsk: Explicitly inline functions and move definitions").
+
+Fixes: bbff2f321a86 ("xsk: new descriptor addressing scheme")
+Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Link: https://lore.kernel.org/bpf/20210428094424.54435-1-xuanzhuo@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xdp/xsk_queue.h | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h
+index 2823b7c3302d..40f359bf2044 100644
+--- a/net/xdp/xsk_queue.h
++++ b/net/xdp/xsk_queue.h
+@@ -128,13 +128,12 @@ static inline bool xskq_cons_read_addr_unchecked(struct xsk_queue *q, u64 *addr)
+ static inline bool xp_aligned_validate_desc(struct xsk_buff_pool *pool,
+                                           struct xdp_desc *desc)
+ {
+-      u64 chunk, chunk_end;
++      u64 chunk;
+-      chunk = xp_aligned_extract_addr(pool, desc->addr);
+-      chunk_end = xp_aligned_extract_addr(pool, desc->addr + desc->len);
+-      if (chunk != chunk_end)
++      if (desc->len > pool->chunk_size)
+               return false;
++      chunk = xp_aligned_extract_addr(pool, desc->addr);
+       if (chunk >= pool->addrs_cnt)
+               return false;
+-- 
+2.30.2
+