From 69596b2c60ac7bf3c970d9ffc899eaedfa6a081b Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 20 Nov 2023 09:23:29 -0500 Subject: [PATCH] Fixes for 5.15 Signed-off-by: Sasha Levin --- ...tate-data-racy-writes-to-file-f_flag.patch | 94 + ...istxattr-fix-s-null-argument-warning.patch | 77 + ...after-free-in-unix_stream_read_actor.patch | 219 ++ ...sible-null-ptr-deref-when-assigning-.patch | 42 + ...0-1-fix-stack-depot-irq-stack-filter.patch | 45 + ...a-use-a-pseudo-bus-to-constrain-usb-.patch | 94 + ...oc-soc-card-add-storage-for-pci-ssid.patch | 122 + ...sp-fix-runtime-pm-underflow-warnings.patch | 47 + ...ork-around-the-dma-rx-overflow-issue.patch | 173 + ...hase-do-pci-error-checks-on-own-line.patch | 68 + ...btusb-add-date-evt_skb-is-null-check.patch | 71 + ...-fix-double-free-in-hci_conn_cleanup.patch | 139 + ...op-the-device-in-bond_setup_by_slave.patch | 133 + ...t-ip-ksym.end-as-part-of-bpf-program.patch | 97 + ...f-rc-in-function-generate_smb3signin.patch | 52 + .../cifs-spnego-add-in-host_key_len.patch | 43 + ...ers-timer-atmel-tcb-fix-initializati.patch | 56 + ...ers-timer-imx-gpt-fix-potential-memo.patch | 66 + ...pcrypt-fix-hungtask-for-padata_reset.patch | 106 + ...avoid-null-dereference-of-timing-gen.patch | 48 + ...use-full-update-for-clip-size-increa.patch | 93 + ...n-array-index-out-of-bounds-for-pola.patch | 81 + ...n-array-index-out-of-bounds-for-smu7.patch | 69 + ...-null-pointer-access-when-the-smc_rr.patch | 105 + ...ix-potential-null-pointer-derefernce.patch | 37 + ...ix-software-pci_unplug-on-some-chips.patch | 103 + ...fix-a-possible-null-pointer-derefere.patch | 37 + ...-race-condition-of-vram-buffer-unref.patch | 48 + ...amdkfd-fix-shift-out-of-bounds-issue.patch | 60 + ...all-currently-held-locks-if-deadlock.patch | 184 ++ ...validity-check-for-dp-cts-edid-check.patch | 79 + ...-a-possible-null-pointer-dereference.patch | 39 + ...tpo-tpg110-fix-a-possible-null-point.patch | 39 + ...st7703-pick-different-reset-sequence.patch | 86 + queue-5.15/drm-qxl-prevent-memory-leak.patch | 41 + ...gfx_surface.c-copy-user-array-safely.patch | 44 + ...t-support-handle-zero-size-directory.patch | 103 + ...dd-check-for-negative-db_l2nbperpage.patch | 46 + ...ity-check-for-db_maxag-and-db_agpref.patch | 50 + .../gfs2-fix-an-oops-in-gfs2_permission.patch | 67 + .../gfs2-ignore-negated-quota-changes.patch | 91 + ...picious-rcu-usage-in-gfs2_permission.patch | 59 + ...-to-ease-the-transition-towards-immu.patch | 54 + ...le-with-irqchips-marked-as-immutable.patch | 89 + ...e-the-gpiochip_irq_re-ql-res-helpers.patch | 70 + ...r-dell-pro-wireless-keyboard-and-mou.patch | 47 + ...t-quirk-free-fw-on-cptkbd-and-stop-a.patch | 127 + .../i2c-dev-copy-userspace-array-safely.patch | 40 + ...i-prevent-potential-division-by-zero.patch | 39 + ...i3c-hci-fix-a-kernel-panic-for-acces.patch | 82 + ...-fix-out-of-bounds-access-in-hci_dma.patch | 38 + ...-add-ipvlan_route_v6_outbound-helper.patch | 272 ++ ...ay-index-out-of-bounds-in-dbfindleaf.patch | 87 + ...array-index-out-of-bounds-in-dialloc.patch | 48 + .../kernel-kexec-copy-user-array-safely.patch | 42 + ...l-watch_queue-copy-user-array-safely.patch | 41 + ...onsole-before-entering-kgdb-on-panic.patch | 59 + ...-test-fix-potential-workqueue-corrup.patch | 119 + ...opagate-promisc-change-to-lower-dev-.patch | 61 + ...si2rx-unregister-v4l2-async-notifier.patch | 67 + ...ix-driver-quirk-struct-documentation.patch | 42 + ...always-include-meson-sub-directory-i.patch | 37 + ...-use-field_get-to-extract-link-width.patch | 77 + ...1-shift-out-of-bounds-in-set_flicker.patch | 53 + ...ccess-to-invalid-resource-for-the-se.patch | 54 + ...improve-async-notifier-cleanup-paths.patch | 130 + ...a-rcar-vin-move-group-async-notifier.patch | 520 +++ ...efactor-controls-creation-for-video-.patch | 164 + ...ename-array-storing-subdevice-inform.patch | 165 + ...rename-async-nf-functions-clean-up-l.patch | 2923 +++++++++++++++++ .../media-vivid-avoid-integer-overflow.patch | 47 + ...t_test-add-device-id-for-r-car-s4-8-.patch | 49 + ...tcp-diag-switch-to-context-structure.patch | 67 + .../mptcp-listen-diag-dump-support.patch | 154 + ...a-races-around-sk-sk_dst_pending_con.patch | 82 + ...a-races-around-sk-sk_tx_queue_mappin.patch | 65 + ...rnet-cortina-fix-max-rx-frame-define.patch | 55 + ...ethernet-cortina-fix-mtu-max-setting.patch | 91 + ...ethernet-cortina-handle-large-frames.patch | 111 + ...-barrier-in-vf-mailbox-reply-process.patch | 51 + ...e-order-conversion-for-pf-to-vf-mail.patch | 516 +++ .../net-hns3-fix-add-vlan-fail-issue.patch | 192 ++ ...orrect-capability-bit-display-for-co.patch | 38 + ...iable-may-not-initialized-problem-in.patch | 38 + .../net-hns3-fix-vf-reset-fail-issue.patch | 83 + ...-fix-vf-wrong-speed-and-duplex-issue.patch | 57 + ...the-definition-for-struct-hclge_pf_t.patch | 69 + ...pen-code-inet_hash2-and-inet_unhash2.patch | 189 ++ ...ve-count-from-inet_listen_hashbucket.patch | 90 + ...inet-retire-port-only-listening_hash.patch | 447 +++ ...return-value-of-snprintf-writing-to-.patch | 74 + ...uble-free-of-encap_header-in-update-.patch | 102 + ...lx5e-fix-double-free-of-encap_header.patch | 82 + .../net-mlx5e-fix-pedit-endianness.patch | 174 + ...mod-hdr-allocation-to-a-single-place.patch | 147 + ...t-mlx5e-reduce-the-size-of-icosq_str.patch | 73 + ...e-refactor-mod-header-management-api.patch | 467 +++ ...-incorrect-addition-of-action-fwd-fl.patch | 39 + ..._free-before-inserting-socket-into-h.patch | 88 + ...net-stmmac-fix-rx-budget-limit-check.patch | 46 + ...conntrack_bridge-initialize-err-to-0.patch | 43 + ...les-add-and-use-be-register-load-sto.patch | 101 + ...les-fix-pointer-math-issue-in-nft_by.patch | 91 + ...bles-use-the-correct-get-put-helpers.patch | 130 + ...sp4_mach_cred-protection-for-pnfs-io.patch | 48 + ...for-specific-intel-ipu-e2000-devices.patch | 60 + ...t-ats-disabling-to-a-helper-function.patch | 60 + ...-field_get-field_prep-with-link-widt.patch | 72 + ...t-in-sapphire-rx-5600-xt-pulse-quirk.patch | 57 + ...-use-field_get-to-extract-link-width.patch | 75 + ...ut-early-if-the-request-aux-area-is-.patch | 76 + ...nkpad_acpi-add-battery-quirk-for-thi.patch | 38 + queue-5.15/ppp-limit-mru-to-64k.patch | 76 + ...e-data-race-around-q-head-and-q-tail.patch | 98 + queue-5.15/pwm-fix-double-shift-bug.patch | 45 + ...-use-field_get-to-extract-link-width.patch | 63 + ...imize-in_task-and-in_interrupt-a-bit.patch | 100 + ...t-debugfs_dir-pointer-to-null-after-.patch | 110 + ...ve-bug_on-in-the-case-of-an-empty-ev.patch | 322 ++ ...otential-null-pointer-dereference-in.patch | 44 + ...arfs-create-read-fix-a-resource-leak.patch | 37 + queue-5.15/series | 160 + ...add-array-wrappers-for-v-memdup_user.patch | 94 + ...an-is_err-check-back-to-where-it-was.patch | 44 + ...pc-econnreset-might-require-a-rebind.patch | 43 + ...lient-cleaned-up-the-freed-pipefs-de.patch | 121 + ...infoleak-due-to-uninitialized-tlv-va.patch | 113 + ...ostat-enable-the-c-state-pre-wake-pr.patch | 36 + .../tools-power-turbostat-fix-a-knl-bug.patch | 41 + ...f-add-interrupt_context_level-helper.patch | 117 + ...gic-from-perf-s-get_recursion_contex.patch | 75 + ...nit-value-access-in-ppp_sync_receive.patch | 82 + ...c-add-check-for-kstrdup-in-vcc_probe.patch | 76 + ...-always-set-current-gadget-in-ncm_bi.patch | 137 + ...mplicit-overflow-on-virtio_max_dma_s.patch | 49 + ...t-touch-the-ce-interrupt-registers-a.patch | 122 + ...k-fix-clang-specific-fortify-warning.patch | 62 + ...-fix-clang-specific-fortify-warnings.patch | 102 + ...wifi-use-fw-rate-for-non-data-frames.patch | 64 + ...n-t-return-unset-power-in-ieee80211_.patch | 58 + ...sim-fix-clang-specific-fortify-warni.patch | 64 + ...e-one-lock-class-key-per-work_on_cpu.patch | 299 ++ ...4-mb-restriction-on-minimal-numa-nod.patch | 112 + ...events-fix-delayed-eoi-list-handling.patch | 47 + ...ng-cmap-br_state-xfs_ext_norm-update.patch | 45 + ...-when-log-intent-item-recovery-fails.patch | 168 + ...cancel_table-allocation-to-kmalloc_a.patch | 92 + ...-memory-when-attr-fork-loading-fails.patch | 97 + ...fs_buf_cancel-structures-when-recove.patch | 78 + ...n-caused-by-unexpected-illegal-bestc.patch | 159 + ...ospc-when-performing-direct-write-on.patch | 348 ++ ...servation-space-for-removing-transac.patch | 60 + ...-intermittent-hang-during-quotacheck.patch | 92 + ...fix-memory-leak-in-xfs_errortag_init.patch | 70 + ...l-pointer-dereference-in-xfs_getbmap.patch | 105 + ...nced-object-reported-by-kmemleak-in-.patch | 70 + ...r-free-in-xattr-node-block-inactivat.patch | 160 + ...gc-workqueue-before-clearing-agi-buc.patch | 51 + ...f-when-log-io-errors-race-with-unmou.patch | 160 + ...buffer-cancellation-table-allocation.patch | 198 ++ ...te_lock-to-check-the-state-of-mmap_l.patch | 43 + 161 files changed, 18543 insertions(+) create mode 100644 queue-5.15/9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch create mode 100644 queue-5.15/9p-v9fs_listxattr-fix-s-null-argument-warning.patch create mode 100644 queue-5.15/af_unix-fix-use-after-free-in-unix_stream_read_actor.patch create mode 100644 queue-5.15/alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch create mode 100644 queue-5.15/arm-9320-1-fix-stack-depot-irq-stack-filter.patch create mode 100644 queue-5.15/arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch create mode 100644 queue-5.15/asoc-soc-card-add-storage-for-pci-ssid.patch create mode 100644 queue-5.15/asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch create mode 100644 queue-5.15/atl1c-work-around-the-dma-rx-overflow-issue.patch create mode 100644 queue-5.15/atm-iphase-do-pci-error-checks-on-own-line.patch create mode 100644 queue-5.15/bluetooth-btusb-add-date-evt_skb-is-null-check.patch create mode 100644 queue-5.15/bluetooth-fix-double-free-in-hci_conn_cleanup.patch create mode 100644 queue-5.15/bonding-stop-the-device-in-bond_setup_by_slave.patch create mode 100644 queue-5.15/bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch create mode 100644 queue-5.15/cifs-fix-check-of-rc-in-function-generate_smb3signin.patch create mode 100644 queue-5.15/cifs-spnego-add-in-host_key_len.patch create mode 100644 queue-5.15/clocksource-drivers-timer-atmel-tcb-fix-initializati.patch create mode 100644 queue-5.15/clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch create mode 100644 queue-5.15/crypto-pcrypt-fix-hungtask-for-padata_reset.patch create mode 100644 queue-5.15/drm-amd-display-avoid-null-dereference-of-timing-gen.patch create mode 100644 queue-5.15/drm-amd-display-use-full-update-for-clip-size-increa.patch create mode 100644 queue-5.15/drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch create mode 100644 queue-5.15/drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch create mode 100644 queue-5.15/drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch create mode 100644 queue-5.15/drm-amdgpu-fix-potential-null-pointer-derefernce.patch create mode 100644 queue-5.15/drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch create mode 100644 queue-5.15/drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch create mode 100644 queue-5.15/drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch create mode 100644 queue-5.15/drm-amdkfd-fix-shift-out-of-bounds-issue.patch create mode 100644 queue-5.15/drm-komeda-drop-all-currently-held-locks-if-deadlock.patch create mode 100644 queue-5.15/drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch create mode 100644 queue-5.15/drm-panel-fix-a-possible-null-pointer-dereference.patch create mode 100644 queue-5.15/drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch create mode 100644 queue-5.15/drm-panel-st7703-pick-different-reset-sequence.patch create mode 100644 queue-5.15/drm-qxl-prevent-memory-leak.patch create mode 100644 queue-5.15/drm-vmwgfx_surface.c-copy-user-array-safely.patch create mode 100644 queue-5.15/exfat-support-handle-zero-size-directory.patch create mode 100644 queue-5.15/fs-jfs-add-check-for-negative-db_l2nbperpage.patch create mode 100644 queue-5.15/fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch create mode 100644 queue-5.15/gfs2-fix-an-oops-in-gfs2_permission.patch create mode 100644 queue-5.15/gfs2-ignore-negated-quota-changes.patch create mode 100644 queue-5.15/gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch create mode 100644 queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch create mode 100644 queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch create mode 100644 queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch create mode 100644 queue-5.15/hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch create mode 100644 queue-5.15/hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch create mode 100644 queue-5.15/i2c-dev-copy-userspace-array-safely.patch create mode 100644 queue-5.15/i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch create mode 100644 queue-5.15/i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch create mode 100644 queue-5.15/i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch create mode 100644 queue-5.15/ipvlan-add-ipvlan_route_v6_outbound-helper.patch create mode 100644 queue-5.15/jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch create mode 100644 queue-5.15/jfs-fix-array-index-out-of-bounds-in-dialloc.patch create mode 100644 queue-5.15/kernel-kexec-copy-user-array-safely.patch create mode 100644 queue-5.15/kernel-watch_queue-copy-user-array-safely.patch create mode 100644 queue-5.15/kgdb-flush-console-before-entering-kgdb-on-panic.patch create mode 100644 queue-5.15/locking-ww_mutex-test-fix-potential-workqueue-corrup.patch create mode 100644 queue-5.15/macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch create mode 100644 queue-5.15/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch create mode 100644 queue-5.15/media-ccs-fix-driver-quirk-struct-documentation.patch create mode 100644 queue-5.15/media-cec-meson-always-include-meson-sub-directory-i.patch create mode 100644 queue-5.15/media-cobalt-use-field_get-to-extract-link-width.patch create mode 100644 queue-5.15/media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch create mode 100644 queue-5.15/media-imon-fix-access-to-invalid-resource-for-the-se.patch create mode 100644 queue-5.15/media-rcar-vin-improve-async-notifier-cleanup-paths.patch create mode 100644 queue-5.15/media-rcar-vin-move-group-async-notifier.patch create mode 100644 queue-5.15/media-rcar-vin-refactor-controls-creation-for-video-.patch create mode 100644 queue-5.15/media-rcar-vin-rename-array-storing-subdevice-inform.patch create mode 100644 queue-5.15/media-v4l-async-rename-async-nf-functions-clean-up-l.patch create mode 100644 queue-5.15/media-vivid-avoid-integer-overflow.patch create mode 100644 queue-5.15/misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch create mode 100644 queue-5.15/mptcp-diag-switch-to-context-structure.patch create mode 100644 queue-5.15/mptcp-listen-diag-dump-support.patch create mode 100644 queue-5.15/net-annotate-data-races-around-sk-sk_dst_pending_con.patch create mode 100644 queue-5.15/net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch create mode 100644 queue-5.15/net-ethernet-cortina-fix-max-rx-frame-define.patch create mode 100644 queue-5.15/net-ethernet-cortina-fix-mtu-max-setting.patch create mode 100644 queue-5.15/net-ethernet-cortina-handle-large-frames.patch create mode 100644 queue-5.15/net-hns3-add-barrier-in-vf-mailbox-reply-process.patch create mode 100644 queue-5.15/net-hns3-add-byte-order-conversion-for-pf-to-vf-mail.patch create mode 100644 queue-5.15/net-hns3-fix-add-vlan-fail-issue.patch create mode 100644 queue-5.15/net-hns3-fix-incorrect-capability-bit-display-for-co.patch create mode 100644 queue-5.15/net-hns3-fix-variable-may-not-initialized-problem-in.patch create mode 100644 queue-5.15/net-hns3-fix-vf-reset-fail-issue.patch create mode 100644 queue-5.15/net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch create mode 100644 queue-5.15/net-hns3-refine-the-definition-for-struct-hclge_pf_t.patch create mode 100644 queue-5.15/net-inet-open-code-inet_hash2-and-inet_unhash2.patch create mode 100644 queue-5.15/net-inet-remove-count-from-inet_listen_hashbucket.patch create mode 100644 queue-5.15/net-inet-retire-port-only-listening_hash.patch create mode 100644 queue-5.15/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch create mode 100644 queue-5.15/net-mlx5e-fix-double-free-of-encap_header-in-update-.patch create mode 100644 queue-5.15/net-mlx5e-fix-double-free-of-encap_header.patch create mode 100644 queue-5.15/net-mlx5e-fix-pedit-endianness.patch create mode 100644 queue-5.15/net-mlx5e-move-mod-hdr-allocation-to-a-single-place.patch create mode 100644 queue-5.15/net-mlx5e-reduce-the-size-of-icosq_str.patch create mode 100644 queue-5.15/net-mlx5e-refactor-mod-header-management-api.patch create mode 100644 queue-5.15/net-mlx5e-remove-incorrect-addition-of-action-fwd-fl.patch create mode 100644 queue-5.15/net-set-sock_rcu_free-before-inserting-socket-into-h.patch create mode 100644 queue-5.15/net-stmmac-fix-rx-budget-limit-check.patch create mode 100644 queue-5.15/netfilter-nf_conntrack_bridge-initialize-err-to-0.patch create mode 100644 queue-5.15/netfilter-nf_tables-add-and-use-be-register-load-sto.patch create mode 100644 queue-5.15/netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch create mode 100644 queue-5.15/netfilter-nf_tables-use-the-correct-get-put-helpers.patch create mode 100644 queue-5.15/nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch create mode 100644 queue-5.15/pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch create mode 100644 queue-5.15/pci-extract-ats-disabling-to-a-helper-function.patch create mode 100644 queue-5.15/pci-tegra194-use-field_get-field_prep-with-link-widt.patch create mode 100644 queue-5.15/pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch create mode 100644 queue-5.15/pci-use-field_get-to-extract-link-width.patch create mode 100644 queue-5.15/perf-core-bail-out-early-if-the-request-aux-area-is-.patch create mode 100644 queue-5.15/platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch create mode 100644 queue-5.15/ppp-limit-mru-to-64k.patch create mode 100644 queue-5.15/ptp-annotate-data-race-around-q-head-and-q-tail.patch create mode 100644 queue-5.15/pwm-fix-double-shift-bug.patch create mode 100644 queue-5.15/rdma-hfi1-use-field_get-to-extract-link-width.patch create mode 100644 queue-5.15/sched-core-optimize-in_task-and-in_interrupt-a-bit.patch create mode 100644 queue-5.15/scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch create mode 100644 queue-5.15/scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch create mode 100644 queue-5.15/scsi-libfc-fix-potential-null-pointer-dereference-in.patch create mode 100644 queue-5.15/selftests-efivarfs-create-read-fix-a-resource-leak.patch create mode 100644 queue-5.15/series create mode 100644 queue-5.15/string.h-add-array-wrappers-for-v-memdup_user.patch create mode 100644 queue-5.15/sunrpc-add-an-is_err-check-back-to-where-it-was.patch create mode 100644 queue-5.15/sunrpc-econnreset-might-require-a-rebind.patch create mode 100644 queue-5.15/sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch create mode 100644 queue-5.15/tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch create mode 100644 queue-5.15/tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch create mode 100644 queue-5.15/tools-power-turbostat-fix-a-knl-bug.patch create mode 100644 queue-5.15/tracing-perf-add-interrupt_context_level-helper.patch create mode 100644 queue-5.15/tracing-reuse-logic-from-perf-s-get_recursion_contex.patch create mode 100644 queue-5.15/tty-fix-uninit-value-access-in-ppp_sync_receive.patch create mode 100644 queue-5.15/tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch create mode 100644 queue-5.15/usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch create mode 100644 queue-5.15/virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch create mode 100644 queue-5.15/wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch create mode 100644 queue-5.15/wifi-ath10k-fix-clang-specific-fortify-warning.patch create mode 100644 queue-5.15/wifi-ath9k-fix-clang-specific-fortify-warnings.patch create mode 100644 queue-5.15/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch create mode 100644 queue-5.15/wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch create mode 100644 queue-5.15/wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch create mode 100644 queue-5.15/workqueue-provide-one-lock-class-key-per-work_on_cpu.patch create mode 100644 queue-5.15/x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch create mode 100644 queue-5.15/xen-events-fix-delayed-eoi-list-handling.patch create mode 100644 queue-5.15/xfs-add-missing-cmap-br_state-xfs_ext_norm-update.patch create mode 100644 queue-5.15/xfs-avoid-a-uaf-when-log-intent-item-recovery-fails.patch create mode 100644 queue-5.15/xfs-convert-buf_cancel_table-allocation-to-kmalloc_a.patch create mode 100644 queue-5.15/xfs-don-t-leak-memory-when-attr-fork-loading-fails.patch create mode 100644 queue-5.15/xfs-don-t-leak-xfs_buf_cancel-structures-when-recove.patch create mode 100644 queue-5.15/xfs-fix-exception-caused-by-unexpected-illegal-bestc.patch create mode 100644 queue-5.15/xfs-fix-false-enospc-when-performing-direct-write-on.patch create mode 100644 queue-5.15/xfs-fix-inode-reservation-space-for-removing-transac.patch create mode 100644 queue-5.15/xfs-fix-intermittent-hang-during-quotacheck.patch create mode 100644 queue-5.15/xfs-fix-memory-leak-in-xfs_errortag_init.patch create mode 100644 queue-5.15/xfs-fix-null-pointer-dereference-in-xfs_getbmap.patch create mode 100644 queue-5.15/xfs-fix-unreferenced-object-reported-by-kmemleak-in-.patch create mode 100644 queue-5.15/xfs-fix-use-after-free-in-xattr-node-block-inactivat.patch create mode 100644 queue-5.15/xfs-flush-inode-gc-workqueue-before-clearing-agi-buc.patch create mode 100644 queue-5.15/xfs-prevent-a-uaf-when-log-io-errors-race-with-unmou.patch create mode 100644 queue-5.15/xfs-refactor-buffer-cancellation-table-allocation.patch create mode 100644 queue-5.15/xfs-use-invalidate_lock-to-check-the-state-of-mmap_l.patch diff --git a/queue-5.15/9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch b/queue-5.15/9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch new file mode 100644 index 00000000000..9d59a588e97 --- /dev/null +++ b/queue-5.15/9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch @@ -0,0 +1,94 @@ +From bd49bc3da15a4c30b67b84c125c5e57a2e875087 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 19:34:43 +0900 +Subject: 9p/trans_fd: Annotate data-racy writes to file::f_flags + +From: Marco Elver + +[ Upstream commit 355f074609dbf3042900ea9d30fcd2b0c323a365 ] + +syzbot reported: + + | BUG: KCSAN: data-race in p9_fd_create / p9_fd_create + | + | read-write to 0xffff888130fb3d48 of 4 bytes by task 15599 on cpu 0: + | p9_fd_open net/9p/trans_fd.c:842 [inline] + | p9_fd_create+0x210/0x250 net/9p/trans_fd.c:1092 + | p9_client_create+0x595/0xa70 net/9p/client.c:1010 + | v9fs_session_init+0xf9/0xd90 fs/9p/v9fs.c:410 + | v9fs_mount+0x69/0x630 fs/9p/vfs_super.c:123 + | legacy_get_tree+0x74/0xd0 fs/fs_context.c:611 + | vfs_get_tree+0x51/0x190 fs/super.c:1519 + | do_new_mount+0x203/0x660 fs/namespace.c:3335 + | path_mount+0x496/0xb30 fs/namespace.c:3662 + | do_mount fs/namespace.c:3675 [inline] + | __do_sys_mount fs/namespace.c:3884 [inline] + | [...] + | + | read-write to 0xffff888130fb3d48 of 4 bytes by task 15563 on cpu 1: + | p9_fd_open net/9p/trans_fd.c:842 [inline] + | p9_fd_create+0x210/0x250 net/9p/trans_fd.c:1092 + | p9_client_create+0x595/0xa70 net/9p/client.c:1010 + | v9fs_session_init+0xf9/0xd90 fs/9p/v9fs.c:410 + | v9fs_mount+0x69/0x630 fs/9p/vfs_super.c:123 + | legacy_get_tree+0x74/0xd0 fs/fs_context.c:611 + | vfs_get_tree+0x51/0x190 fs/super.c:1519 + | do_new_mount+0x203/0x660 fs/namespace.c:3335 + | path_mount+0x496/0xb30 fs/namespace.c:3662 + | do_mount fs/namespace.c:3675 [inline] + | __do_sys_mount fs/namespace.c:3884 [inline] + | [...] + | + | value changed: 0x00008002 -> 0x00008802 + +Within p9_fd_open(), O_NONBLOCK is added to f_flags of the read and +write files. This may happen concurrently if e.g. mounting process +modifies the fd in another thread. + +Mark the plain read-modify-writes as intentional data-races, with the +assumption that the result of executing the accesses concurrently will +always result in the same result despite the accesses themselves not +being atomic. + +Reported-by: syzbot+e441aeeb422763cc5511@syzkaller.appspotmail.com +Signed-off-by: Marco Elver +Link: https://lore.kernel.org/r/ZO38mqkS0TYUlpFp@elver.google.com +Signed-off-by: Dominique Martinet +Message-ID: <20231025103445.1248103-1-asmadeus@codewreck.org> +Signed-off-by: Sasha Levin +--- + net/9p/trans_fd.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c +index f359cfdc1858f..b44b77d3b35d1 100644 +--- a/net/9p/trans_fd.c ++++ b/net/9p/trans_fd.c +@@ -835,14 +835,21 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd) + goto out_free_ts; + if (!(ts->rd->f_mode & FMODE_READ)) + goto out_put_rd; +- /* prevent workers from hanging on IO when fd is a pipe */ +- ts->rd->f_flags |= O_NONBLOCK; ++ /* Prevent workers from hanging on IO when fd is a pipe. ++ * It's technically possible for userspace or concurrent mounts to ++ * modify this flag concurrently, which will likely result in a ++ * broken filesystem. However, just having bad flags here should ++ * not crash the kernel or cause any other sort of bug, so mark this ++ * particular data race as intentional so that tooling (like KCSAN) ++ * can allow it and detect further problems. ++ */ ++ data_race(ts->rd->f_flags |= O_NONBLOCK); + ts->wr = fget(wfd); + if (!ts->wr) + goto out_put_rd; + if (!(ts->wr->f_mode & FMODE_WRITE)) + goto out_put_wr; +- ts->wr->f_flags |= O_NONBLOCK; ++ data_race(ts->wr->f_flags |= O_NONBLOCK); + + client->trans = ts; + client->status = Connected; +-- +2.42.0 + diff --git a/queue-5.15/9p-v9fs_listxattr-fix-s-null-argument-warning.patch b/queue-5.15/9p-v9fs_listxattr-fix-s-null-argument-warning.patch new file mode 100644 index 00000000000..233c1301824 --- /dev/null +++ b/queue-5.15/9p-v9fs_listxattr-fix-s-null-argument-warning.patch @@ -0,0 +1,77 @@ +From c8a1e55f2607ab4c43da46f79ddadd86923bd6ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 19:34:44 +0900 +Subject: 9p: v9fs_listxattr: fix %s null argument warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dominique Martinet + +[ Upstream commit 9b5c6281838fc84683dd99b47302d81fce399918 ] + +W=1 warns about null argument to kprintf: +In file included from fs/9p/xattr.c:12: +In function ‘v9fs_xattr_get’, + inlined from ‘v9fs_listxattr’ at fs/9p/xattr.c:142:9: +include/net/9p/9p.h:55:2: error: ‘%s’ directive argument is null +[-Werror=format-overflow=] + 55 | _p9_debug(level, __func__, fmt, ##__VA_ARGS__) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use an empty string instead of : + - this is ok 9p-wise because p9pdu_vwritef serializes a null string +and an empty string the same way (one '0' word for length) + - since this degrades the print statements, add new single quotes for +xattr's name delimter (Old: "file = (null)", new: "file = ''") + +Link: https://lore.kernel.org/r/20231008060138.517057-1-suhui@nfschina.com +Suggested-by: Su Hui +Signed-off-by: Dominique Martinet +Acked-by: Christian Schoenebeck +Message-ID: <20231025103445.1248103-2-asmadeus@codewreck.org> +Signed-off-by: Sasha Levin +--- + fs/9p/xattr.c | 5 +++-- + net/9p/client.c | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c +index ee331845e2c7a..31799ac10e33a 100644 +--- a/fs/9p/xattr.c ++++ b/fs/9p/xattr.c +@@ -73,7 +73,7 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name, + struct p9_fid *fid; + int ret; + +- p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n", ++ p9_debug(P9_DEBUG_VFS, "name = '%s' value_len = %zu\n", + name, buffer_size); + fid = v9fs_fid_lookup(dentry); + if (IS_ERR(fid)) +@@ -144,7 +144,8 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name, + + ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) + { +- return v9fs_xattr_get(dentry, NULL, buffer, buffer_size); ++ /* Txattrwalk with an empty string lists xattrs instead */ ++ return v9fs_xattr_get(dentry, "", buffer, buffer_size); + } + + static int v9fs_xattr_handler_get(const struct xattr_handler *handler, +diff --git a/net/9p/client.c b/net/9p/client.c +index 9fdcaa956c008..ead458486fdcf 100644 +--- a/net/9p/client.c ++++ b/net/9p/client.c +@@ -2020,7 +2020,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid, + goto error; + } + p9_debug(P9_DEBUG_9P, +- ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n", ++ ">>> TXATTRWALK file_fid %d, attr_fid %d name '%s'\n", + file_fid->fid, attr_fid->fid, attr_name); + + req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds", +-- +2.42.0 + diff --git a/queue-5.15/af_unix-fix-use-after-free-in-unix_stream_read_actor.patch b/queue-5.15/af_unix-fix-use-after-free-in-unix_stream_read_actor.patch new file mode 100644 index 00000000000..019ef7dd4bd --- /dev/null +++ b/queue-5.15/af_unix-fix-use-after-free-in-unix_stream_read_actor.patch @@ -0,0 +1,219 @@ +From 9b69b753ee380bc53cc38a33c759a723fb057463 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 13:49:38 +0000 +Subject: af_unix: fix use-after-free in unix_stream_read_actor() + +From: Eric Dumazet + +[ Upstream commit 4b7b492615cf3017190f55444f7016812b66611d ] + +syzbot reported the following crash [1] + +After releasing unix socket lock, u->oob_skb can be changed +by another thread. We must temporarily increase skb refcount +to make sure this other thread will not free the skb under us. + +[1] + +BUG: KASAN: slab-use-after-free in unix_stream_read_actor+0xa7/0xc0 net/unix/af_unix.c:2866 +Read of size 4 at addr ffff88801f3b9cc4 by task syz-executor107/5297 + +CPU: 1 PID: 5297 Comm: syz-executor107 Not tainted 6.6.0-syzkaller-15910-gb8e3a87a627b #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/2023 +Call Trace: + +__dump_stack lib/dump_stack.c:88 [inline] +dump_stack_lvl+0xd9/0x1b0 lib/dump_stack.c:106 +print_address_description mm/kasan/report.c:364 [inline] +print_report+0xc4/0x620 mm/kasan/report.c:475 +kasan_report+0xda/0x110 mm/kasan/report.c:588 +unix_stream_read_actor+0xa7/0xc0 net/unix/af_unix.c:2866 +unix_stream_recv_urg net/unix/af_unix.c:2587 [inline] +unix_stream_read_generic+0x19a5/0x2480 net/unix/af_unix.c:2666 +unix_stream_recvmsg+0x189/0x1b0 net/unix/af_unix.c:2903 +sock_recvmsg_nosec net/socket.c:1044 [inline] +sock_recvmsg+0xe2/0x170 net/socket.c:1066 +____sys_recvmsg+0x21f/0x5c0 net/socket.c:2803 +___sys_recvmsg+0x115/0x1a0 net/socket.c:2845 +__sys_recvmsg+0x114/0x1e0 net/socket.c:2875 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82 +entry_SYSCALL_64_after_hwframe+0x63/0x6b +RIP: 0033:0x7fc67492c559 +Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007fc6748ab228 EFLAGS: 00000246 ORIG_RAX: 000000000000002f +RAX: ffffffffffffffda RBX: 000000000000001c RCX: 00007fc67492c559 +RDX: 0000000040010083 RSI: 0000000020000140 RDI: 0000000000000004 +RBP: 00007fc6749b6348 R08: 00007fc6748ab6c0 R09: 00007fc6748ab6c0 +R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc6749b6340 +R13: 00007fc6749b634c R14: 00007ffe9fac52a0 R15: 00007ffe9fac5388 + + +Allocated by task 5295: +kasan_save_stack+0x33/0x50 mm/kasan/common.c:45 +kasan_set_track+0x25/0x30 mm/kasan/common.c:52 +__kasan_slab_alloc+0x81/0x90 mm/kasan/common.c:328 +kasan_slab_alloc include/linux/kasan.h:188 [inline] +slab_post_alloc_hook mm/slab.h:763 [inline] +slab_alloc_node mm/slub.c:3478 [inline] +kmem_cache_alloc_node+0x180/0x3c0 mm/slub.c:3523 +__alloc_skb+0x287/0x330 net/core/skbuff.c:641 +alloc_skb include/linux/skbuff.h:1286 [inline] +alloc_skb_with_frags+0xe4/0x710 net/core/skbuff.c:6331 +sock_alloc_send_pskb+0x7e4/0x970 net/core/sock.c:2780 +sock_alloc_send_skb include/net/sock.h:1884 [inline] +queue_oob net/unix/af_unix.c:2147 [inline] +unix_stream_sendmsg+0xb5f/0x10a0 net/unix/af_unix.c:2301 +sock_sendmsg_nosec net/socket.c:730 [inline] +__sock_sendmsg+0xd5/0x180 net/socket.c:745 +____sys_sendmsg+0x6ac/0x940 net/socket.c:2584 +___sys_sendmsg+0x135/0x1d0 net/socket.c:2638 +__sys_sendmsg+0x117/0x1e0 net/socket.c:2667 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82 +entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Freed by task 5295: +kasan_save_stack+0x33/0x50 mm/kasan/common.c:45 +kasan_set_track+0x25/0x30 mm/kasan/common.c:52 +kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:522 +____kasan_slab_free mm/kasan/common.c:236 [inline] +____kasan_slab_free+0x15b/0x1b0 mm/kasan/common.c:200 +kasan_slab_free include/linux/kasan.h:164 [inline] +slab_free_hook mm/slub.c:1800 [inline] +slab_free_freelist_hook+0x114/0x1e0 mm/slub.c:1826 +slab_free mm/slub.c:3809 [inline] +kmem_cache_free+0xf8/0x340 mm/slub.c:3831 +kfree_skbmem+0xef/0x1b0 net/core/skbuff.c:1015 +__kfree_skb net/core/skbuff.c:1073 [inline] +consume_skb net/core/skbuff.c:1288 [inline] +consume_skb+0xdf/0x170 net/core/skbuff.c:1282 +queue_oob net/unix/af_unix.c:2178 [inline] +unix_stream_sendmsg+0xd49/0x10a0 net/unix/af_unix.c:2301 +sock_sendmsg_nosec net/socket.c:730 [inline] +__sock_sendmsg+0xd5/0x180 net/socket.c:745 +____sys_sendmsg+0x6ac/0x940 net/socket.c:2584 +___sys_sendmsg+0x135/0x1d0 net/socket.c:2638 +__sys_sendmsg+0x117/0x1e0 net/socket.c:2667 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82 +entry_SYSCALL_64_after_hwframe+0x63/0x6b + +The buggy address belongs to the object at ffff88801f3b9c80 +which belongs to the cache skbuff_head_cache of size 240 +The buggy address is located 68 bytes inside of +freed 240-byte region [ffff88801f3b9c80, ffff88801f3b9d70) + +The buggy address belongs to the physical page: +page:ffffea00007cee40 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1f3b9 +flags: 0xfff00000000800(slab|node=0|zone=1|lastcpupid=0x7ff) +page_type: 0xffffffff() +raw: 00fff00000000800 ffff888142a60640 dead000000000122 0000000000000000 +raw: 0000000000000000 00000000000c000c 00000001ffffffff 0000000000000000 +page dumped because: kasan: bad access detected +page_owner tracks the page as allocated +page last allocated via order 0, migratetype Unmovable, gfp_mask 0x12cc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY), pid 5299, tgid 5283 (syz-executor107), ts 103803840339, free_ts 103600093431 +set_page_owner include/linux/page_owner.h:31 [inline] +post_alloc_hook+0x2cf/0x340 mm/page_alloc.c:1537 +prep_new_page mm/page_alloc.c:1544 [inline] +get_page_from_freelist+0xa25/0x36c0 mm/page_alloc.c:3312 +__alloc_pages+0x1d0/0x4a0 mm/page_alloc.c:4568 +alloc_pages_mpol+0x258/0x5f0 mm/mempolicy.c:2133 +alloc_slab_page mm/slub.c:1870 [inline] +allocate_slab+0x251/0x380 mm/slub.c:2017 +new_slab mm/slub.c:2070 [inline] +___slab_alloc+0x8c7/0x1580 mm/slub.c:3223 +__slab_alloc.constprop.0+0x56/0xa0 mm/slub.c:3322 +__slab_alloc_node mm/slub.c:3375 [inline] +slab_alloc_node mm/slub.c:3468 [inline] +kmem_cache_alloc_node+0x132/0x3c0 mm/slub.c:3523 +__alloc_skb+0x287/0x330 net/core/skbuff.c:641 +alloc_skb include/linux/skbuff.h:1286 [inline] +alloc_skb_with_frags+0xe4/0x710 net/core/skbuff.c:6331 +sock_alloc_send_pskb+0x7e4/0x970 net/core/sock.c:2780 +sock_alloc_send_skb include/net/sock.h:1884 [inline] +queue_oob net/unix/af_unix.c:2147 [inline] +unix_stream_sendmsg+0xb5f/0x10a0 net/unix/af_unix.c:2301 +sock_sendmsg_nosec net/socket.c:730 [inline] +__sock_sendmsg+0xd5/0x180 net/socket.c:745 +____sys_sendmsg+0x6ac/0x940 net/socket.c:2584 +___sys_sendmsg+0x135/0x1d0 net/socket.c:2638 +__sys_sendmsg+0x117/0x1e0 net/socket.c:2667 +page last free stack trace: +reset_page_owner include/linux/page_owner.h:24 [inline] +free_pages_prepare mm/page_alloc.c:1137 [inline] +free_unref_page_prepare+0x4f8/0xa90 mm/page_alloc.c:2347 +free_unref_page+0x33/0x3b0 mm/page_alloc.c:2487 +__unfreeze_partials+0x21d/0x240 mm/slub.c:2655 +qlink_free mm/kasan/quarantine.c:168 [inline] +qlist_free_all+0x6a/0x170 mm/kasan/quarantine.c:187 +kasan_quarantine_reduce+0x18e/0x1d0 mm/kasan/quarantine.c:294 +__kasan_slab_alloc+0x65/0x90 mm/kasan/common.c:305 +kasan_slab_alloc include/linux/kasan.h:188 [inline] +slab_post_alloc_hook mm/slab.h:763 [inline] +slab_alloc_node mm/slub.c:3478 [inline] +slab_alloc mm/slub.c:3486 [inline] +__kmem_cache_alloc_lru mm/slub.c:3493 [inline] +kmem_cache_alloc+0x15d/0x380 mm/slub.c:3502 +vm_area_dup+0x21/0x2f0 kernel/fork.c:500 +__split_vma+0x17d/0x1070 mm/mmap.c:2365 +split_vma mm/mmap.c:2437 [inline] +vma_modify+0x25d/0x450 mm/mmap.c:2472 +vma_modify_flags include/linux/mm.h:3271 [inline] +mprotect_fixup+0x228/0xc80 mm/mprotect.c:635 +do_mprotect_pkey+0x852/0xd60 mm/mprotect.c:809 +__do_sys_mprotect mm/mprotect.c:830 [inline] +__se_sys_mprotect mm/mprotect.c:827 [inline] +__x64_sys_mprotect+0x78/0xb0 mm/mprotect.c:827 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82 +entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Memory state around the buggy address: +ffff88801f3b9b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +ffff88801f3b9c00: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc +>ffff88801f3b9c80: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +^ +ffff88801f3b9d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc +ffff88801f3b9d80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb + +Fixes: 876c14ad014d ("af_unix: fix holding spinlock in oob handling") +Reported-and-tested-by: syzbot+7a2d546fa43e49315ed3@syzkaller.appspotmail.com +Signed-off-by: Eric Dumazet +Cc: Rao Shoaib +Reviewed-by: Rao shoaib +Link: https://lore.kernel.org/r/20231113134938.168151-1-edumazet@google.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 748769f4ba058..16b04e553a6c8 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2529,15 +2529,16 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state) + + if (!(state->flags & MSG_PEEK)) + WRITE_ONCE(u->oob_skb, NULL); +- ++ else ++ skb_get(oob_skb); + unix_state_unlock(sk); + + chunk = state->recv_actor(oob_skb, 0, chunk, state); + +- if (!(state->flags & MSG_PEEK)) { ++ if (!(state->flags & MSG_PEEK)) + UNIXCB(oob_skb).consumed += 1; +- kfree_skb(oob_skb); +- } ++ ++ consume_skb(oob_skb); + + mutex_unlock(&u->iolock); + +-- +2.42.0 + diff --git a/queue-5.15/alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch b/queue-5.15/alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch new file mode 100644 index 00000000000..2bd855c46f8 --- /dev/null +++ b/queue-5.15/alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch @@ -0,0 +1,42 @@ +From 0db635981d0ec9fe5c562031eca31ae4f399fc18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Oct 2023 12:28:55 +0200 +Subject: ALSA: hda: Fix possible null-ptr-deref when assigning a stream + +From: Cezary Rojewski + +[ Upstream commit f93dc90c2e8ed664985e366aa6459ac83cdab236 ] + +While AudioDSP drivers assign streams exclusively of HOST or LINK type, +nothing blocks a user to attempt to assign a COUPLED stream. As +supplied substream instance may be a stub, what is the case when +code-loading, such scenario ends with null-ptr-deref. + +Signed-off-by: Cezary Rojewski +Link: https://lore.kernel.org/r/20231006102857.749143-2-cezary.rojewski@intel.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/hdac_stream.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c +index eea22cf72aefd..ec95d0449bfe9 100644 +--- a/sound/hda/hdac_stream.c ++++ b/sound/hda/hdac_stream.c +@@ -320,8 +320,10 @@ struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus, + struct hdac_stream *res = NULL; + + /* make a non-zero unique key for the substream */ +- int key = (substream->pcm->device << 16) | (substream->number << 2) | +- (substream->stream + 1); ++ int key = (substream->number << 2) | (substream->stream + 1); ++ ++ if (substream->pcm) ++ key |= (substream->pcm->device << 16); + + spin_lock_irq(&bus->reg_lock); + list_for_each_entry(azx_dev, &bus->stream_list, list) { +-- +2.42.0 + diff --git a/queue-5.15/arm-9320-1-fix-stack-depot-irq-stack-filter.patch b/queue-5.15/arm-9320-1-fix-stack-depot-irq-stack-filter.patch new file mode 100644 index 00000000000..6baa4efcca8 --- /dev/null +++ b/queue-5.15/arm-9320-1-fix-stack-depot-irq-stack-filter.patch @@ -0,0 +1,45 @@ +From 2f8c81480995da7bd9e7618c7550fd856581cb8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Aug 2023 08:45:21 +0100 +Subject: ARM: 9320/1: fix stack depot IRQ stack filter + +From: Vincent Whitchurch + +[ Upstream commit b0150014878c32197cfa66e3e2f79e57f66babc0 ] + +Place IRQ handlers such as gic_handle_irq() in the irqentry section even +if FUNCTION_GRAPH_TRACER is not enabled. Without this, the stack +depot's filter_irq_stacks() does not correctly filter out IRQ stacks in +those configurations, which hampers deduplication and eventually leads +to "Stack depot reached limit capacity" splats with KASAN. + +A similar fix was done for arm64 in commit f6794950f0e5ba37e3bbed +("arm64: set __exception_irq_entry with __irq_entry as a default"). + +Link: https://lore.kernel.org/r/20230803-arm-irqentry-v1-1-8aad8e260b1c@axis.com + +Signed-off-by: Vincent Whitchurch +Signed-off-by: Russell King (Oracle) +Signed-off-by: Sasha Levin +--- + arch/arm/include/asm/exception.h | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h +index 58e039a851af0..3c82975d46db3 100644 +--- a/arch/arm/include/asm/exception.h ++++ b/arch/arm/include/asm/exception.h +@@ -10,10 +10,6 @@ + + #include + +-#ifdef CONFIG_FUNCTION_GRAPH_TRACER + #define __exception_irq_entry __irq_entry +-#else +-#define __exception_irq_entry +-#endif + + #endif /* __ASM_ARM_EXCEPTION_H */ +-- +2.42.0 + diff --git a/queue-5.15/arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch b/queue-5.15/arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch new file mode 100644 index 00000000000..a4a48c10569 --- /dev/null +++ b/queue-5.15/arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch @@ -0,0 +1,94 @@ +From 3b016e0916be283995e88f111021068d1a0d3920 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 18:10:15 +0300 +Subject: arm64: dts: ls208xa: use a pseudo-bus to constrain usb dma size + +From: Laurentiu Tudor + +[ Upstream commit b39d5016456871a88f5cd141914a5043591b46f3 ] + +Wrap the usb controllers in an intermediate simple-bus and use it to +constrain the dma address size of these usb controllers to the 40b +that they generate toward the interconnect. This is required because +the SoC uses 48b address sizes and this mismatch would lead to smmu +context faults [1] because the usb generates 40b addresses while the +smmu page tables are populated with 48b wide addresses. + +[1] +xhci-hcd xhci-hcd.0.auto: xHCI Host Controller +xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1 +xhci-hcd xhci-hcd.0.auto: hcc params 0x0220f66d hci version 0x100 quirks 0x0000000002000010 +xhci-hcd xhci-hcd.0.auto: irq 108, io mem 0x03100000 +xhci-hcd xhci-hcd.0.auto: xHCI Host Controller +xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2 +xhci-hcd xhci-hcd.0.auto: Host supports USB 3.0 SuperSpeed +arm-smmu 5000000.iommu: Unhandled context fault: fsr=0x402, iova=0xffffffb000, fsynr=0x0, cbfrsynra=0xc01, cb=3 + +Signed-off-by: Laurentiu Tudor +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 46 +++++++++++-------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +index 12e59777363fe..9bb360db6b195 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +@@ -1179,26 +1179,34 @@ sata1: sata@3210000 { + dma-coherent; + }; + +- usb0: usb@3100000 { +- status = "disabled"; +- compatible = "snps,dwc3"; +- reg = <0x0 0x3100000 0x0 0x10000>; +- interrupts = <0 80 0x4>; /* Level high type */ +- dr_mode = "host"; +- snps,quirk-frame-length-adjustment = <0x20>; +- snps,dis_rxdet_inp3_quirk; +- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; +- }; ++ bus: bus { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ compatible = "simple-bus"; ++ ranges; ++ dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; ++ ++ usb0: usb@3100000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0x3100000 0x0 0x10000>; ++ interrupts = <0 80 0x4>; /* Level high type */ ++ dr_mode = "host"; ++ snps,quirk-frame-length-adjustment = <0x20>; ++ snps,dis_rxdet_inp3_quirk; ++ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; ++ status = "disabled"; ++ }; + +- usb1: usb@3110000 { +- status = "disabled"; +- compatible = "snps,dwc3"; +- reg = <0x0 0x3110000 0x0 0x10000>; +- interrupts = <0 81 0x4>; /* Level high type */ +- dr_mode = "host"; +- snps,quirk-frame-length-adjustment = <0x20>; +- snps,dis_rxdet_inp3_quirk; +- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; ++ usb1: usb@3110000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0x3110000 0x0 0x10000>; ++ interrupts = <0 81 0x4>; /* Level high type */ ++ dr_mode = "host"; ++ snps,quirk-frame-length-adjustment = <0x20>; ++ snps,dis_rxdet_inp3_quirk; ++ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; ++ status = "disabled"; ++ }; + }; + + ccn@4000000 { +-- +2.42.0 + diff --git a/queue-5.15/asoc-soc-card-add-storage-for-pci-ssid.patch b/queue-5.15/asoc-soc-card-add-storage-for-pci-ssid.patch new file mode 100644 index 00000000000..841b420cc36 --- /dev/null +++ b/queue-5.15/asoc-soc-card-add-storage-for-pci-ssid.patch @@ -0,0 +1,122 @@ +From 76572d40c14d94fac2bc6b0f3b3d65c54b580c23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:32:04 +0100 +Subject: ASoC: soc-card: Add storage for PCI SSID + +From: Richard Fitzgerald + +[ Upstream commit 47f56e38a199bd45514b8e0142399cba4feeaf1a ] + +Add members to struct snd_soc_card to store the PCI subsystem ID (SSID) +of the soundcard. + +The PCI specification provides two registers to store a vendor-specific +SSID that can be read by drivers to uniquely identify a particular +"soundcard". This is defined in the PCI specification to distinguish +products that use the same silicon (and therefore have the same silicon +ID) so that product-specific differences can be applied. + +PCI only defines 0xFFFF as an invalid value. 0x0000 is not defined as +invalid. So the usual pattern of zero-filling the struct and then +assuming a zero value unset will not work. A flag is included to +indicate when the SSID information has been filled in. + +Unlike DMI information, which has a free-format entirely up to the vendor, +the PCI SSID has a strictly defined format and a registry of vendor IDs. + +It is usual in Windows drivers that the SSID is used as the sole identifier +of the specific end-product and the Windows driver contains tables mapping +that to information about the hardware setup, rather than using ACPI +properties. + +This SSID is important information for ASoC components that need to apply +hardware-specific configuration on PCI-based systems. + +As the SSID is a generic part of the PCI specification and is treated as +identifying the "soundcard", it is reasonable to include this information +in struct snd_soc_card, instead of components inventing their own custom +ways to pass this information around. + +Signed-off-by: Richard Fitzgerald +Reviewed-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20230912163207.3498161-2-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/sound/soc-card.h | 37 +++++++++++++++++++++++++++++++++++++ + include/sound/soc.h | 11 +++++++++++ + 2 files changed, 48 insertions(+) + +diff --git a/include/sound/soc-card.h b/include/sound/soc-card.h +index 4f2cc4fb56b7f..9a5429260ece5 100644 +--- a/include/sound/soc-card.h ++++ b/include/sound/soc-card.h +@@ -40,6 +40,43 @@ int snd_soc_card_add_dai_link(struct snd_soc_card *card, + void snd_soc_card_remove_dai_link(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link); + ++#ifdef CONFIG_PCI ++static inline void snd_soc_card_set_pci_ssid(struct snd_soc_card *card, ++ unsigned short vendor, ++ unsigned short device) ++{ ++ card->pci_subsystem_vendor = vendor; ++ card->pci_subsystem_device = device; ++ card->pci_subsystem_set = true; ++} ++ ++static inline int snd_soc_card_get_pci_ssid(struct snd_soc_card *card, ++ unsigned short *vendor, ++ unsigned short *device) ++{ ++ if (!card->pci_subsystem_set) ++ return -ENOENT; ++ ++ *vendor = card->pci_subsystem_vendor; ++ *device = card->pci_subsystem_device; ++ ++ return 0; ++} ++#else /* !CONFIG_PCI */ ++static inline void snd_soc_card_set_pci_ssid(struct snd_soc_card *card, ++ unsigned short vendor, ++ unsigned short device) ++{ ++} ++ ++static inline int snd_soc_card_get_pci_ssid(struct snd_soc_card *card, ++ unsigned short *vendor, ++ unsigned short *device) ++{ ++ return -ENOENT; ++} ++#endif /* CONFIG_PCI */ ++ + /* device driver data */ + static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, + void *data) +diff --git a/include/sound/soc.h b/include/sound/soc.h +index 5872a8864f3b6..3f0369aae2faf 100644 +--- a/include/sound/soc.h ++++ b/include/sound/soc.h +@@ -880,6 +880,17 @@ struct snd_soc_card { + #ifdef CONFIG_DMI + char dmi_longname[80]; + #endif /* CONFIG_DMI */ ++ ++#ifdef CONFIG_PCI ++ /* ++ * PCI does not define 0 as invalid, so pci_subsystem_set indicates ++ * whether a value has been written to these fields. ++ */ ++ unsigned short pci_subsystem_vendor; ++ unsigned short pci_subsystem_device; ++ bool pci_subsystem_set; ++#endif /* CONFIG_PCI */ ++ + char topology_shortname[32]; + + struct device *dev; +-- +2.42.0 + diff --git a/queue-5.15/asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch b/queue-5.15/asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch new file mode 100644 index 00000000000..abdd98ce862 --- /dev/null +++ b/queue-5.15/asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch @@ -0,0 +1,47 @@ +From 64fdf47874006f875abbe465f02339f2c2d5676a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 07:23:38 +0200 +Subject: ASoC: ti: omap-mcbsp: Fix runtime PM underflow warnings + +From: Tony Lindgren + +[ Upstream commit fbb74e56378d8306f214658e3d525a8b3f000c5a ] + +We need to check for an active device as otherwise we get warnings +for some mcbsp instances for "Runtime PM usage count underflow!". + +Reported-by: Andreas Kemnade +Signed-off-by: Tony Lindgren +Link: https://lore.kernel.org/r/20231030052340.13415-1-tony@atomide.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/ti/omap-mcbsp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/ti/omap-mcbsp.c b/sound/soc/ti/omap-mcbsp.c +index 4479d74f0a458..81d2be87e9739 100644 +--- a/sound/soc/ti/omap-mcbsp.c ++++ b/sound/soc/ti/omap-mcbsp.c +@@ -74,14 +74,16 @@ static int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) + return -EINVAL; + } + +- pm_runtime_put_sync(mcbsp->dev); ++ if (mcbsp->active) ++ pm_runtime_put_sync(mcbsp->dev); + + r = clk_set_parent(mcbsp->fclk, fck_src); + if (r) + dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n", + src); + +- pm_runtime_get_sync(mcbsp->dev); ++ if (mcbsp->active) ++ pm_runtime_get_sync(mcbsp->dev); + + clk_put(fck_src); + +-- +2.42.0 + diff --git a/queue-5.15/atl1c-work-around-the-dma-rx-overflow-issue.patch b/queue-5.15/atl1c-work-around-the-dma-rx-overflow-issue.patch new file mode 100644 index 00000000000..dd4961d83e8 --- /dev/null +++ b/queue-5.15/atl1c-work-around-the-dma-rx-overflow-issue.patch @@ -0,0 +1,173 @@ +From 0e4b85d984b3d6f676e74d6c12536a0adae4a1e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:07:11 +0800 +Subject: atl1c: Work around the DMA RX overflow issue + +From: Sieng-Piaw Liew + +[ Upstream commit 86565682e9053e5deb128193ea9e88531bbae9cf ] + +This is based on alx driver commit 881d0327db37 ("net: alx: Work around +the DMA RX overflow issue"). + +The alx and atl1c drivers had RX overflow error which was why a custom +allocator was created to avoid certain addresses. The simpler workaround +then created for alx driver, but not for atl1c due to lack of tester. + +Instead of using a custom allocator, check the allocated skb address and +use skb_reserve() to move away from problematic 0x...fc0 address. + +Tested on AR8131 on Acer 4540. + +Signed-off-by: Sieng-Piaw Liew +Link: https://lore.kernel.org/r/20230912010711.12036-1-liew.s.piaw@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/atheros/atl1c/atl1c.h | 3 - + .../net/ethernet/atheros/atl1c/atl1c_main.c | 67 +++++-------------- + 2 files changed, 16 insertions(+), 54 deletions(-) + +diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h +index 43d821fe7a542..63ba64dbb7310 100644 +--- a/drivers/net/ethernet/atheros/atl1c/atl1c.h ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h +@@ -504,15 +504,12 @@ struct atl1c_rrd_ring { + u16 next_to_use; + u16 next_to_clean; + struct napi_struct napi; +- struct page *rx_page; +- unsigned int rx_page_offset; + }; + + /* board specific private data structure */ + struct atl1c_adapter { + struct net_device *netdev; + struct pci_dev *pdev; +- unsigned int rx_frag_size; + struct atl1c_hw hw; + struct atl1c_hw_stats hw_stats; + struct mii_if_info mii; /* MII interface info */ +diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +index dad21b4fbc0bc..c6f621c0ca836 100644 +--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +@@ -493,15 +493,10 @@ static int atl1c_set_mac_addr(struct net_device *netdev, void *p) + static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, + struct net_device *dev) + { +- unsigned int head_size; + int mtu = dev->mtu; + + adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ? + roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; +- +- head_size = SKB_DATA_ALIGN(adapter->rx_buffer_len + NET_SKB_PAD + NET_IP_ALIGN) + +- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +- adapter->rx_frag_size = roundup_pow_of_two(head_size); + } + + static netdev_features_t atl1c_fix_features(struct net_device *netdev, +@@ -974,7 +969,6 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter) + static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) + { + struct pci_dev *pdev = adapter->pdev; +- int i; + + dma_free_coherent(&pdev->dev, adapter->ring_header.size, + adapter->ring_header.desc, adapter->ring_header.dma); +@@ -987,12 +981,6 @@ static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) + kfree(adapter->tpd_ring[0].buffer_info); + adapter->tpd_ring[0].buffer_info = NULL; + } +- for (i = 0; i < adapter->rx_queue_count; ++i) { +- if (adapter->rrd_ring[i].rx_page) { +- put_page(adapter->rrd_ring[i].rx_page); +- adapter->rrd_ring[i].rx_page = NULL; +- } +- } + } + + /** +@@ -1764,48 +1752,11 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter, + skb_checksum_none_assert(skb); + } + +-static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter, +- u32 queue, bool napi_mode) +-{ +- struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[queue]; +- struct sk_buff *skb; +- struct page *page; +- +- if (adapter->rx_frag_size > PAGE_SIZE) { +- if (likely(napi_mode)) +- return napi_alloc_skb(&rrd_ring->napi, +- adapter->rx_buffer_len); +- else +- return netdev_alloc_skb_ip_align(adapter->netdev, +- adapter->rx_buffer_len); +- } +- +- page = rrd_ring->rx_page; +- if (!page) { +- page = alloc_page(GFP_ATOMIC); +- if (unlikely(!page)) +- return NULL; +- rrd_ring->rx_page = page; +- rrd_ring->rx_page_offset = 0; +- } +- +- skb = build_skb(page_address(page) + rrd_ring->rx_page_offset, +- adapter->rx_frag_size); +- if (likely(skb)) { +- skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); +- rrd_ring->rx_page_offset += adapter->rx_frag_size; +- if (rrd_ring->rx_page_offset >= PAGE_SIZE) +- rrd_ring->rx_page = NULL; +- else +- get_page(page); +- } +- return skb; +-} +- + static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, u32 queue, + bool napi_mode) + { + struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[queue]; ++ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[queue]; + struct pci_dev *pdev = adapter->pdev; + struct atl1c_buffer *buffer_info, *next_info; + struct sk_buff *skb; +@@ -1824,13 +1775,27 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, u32 queue, + while (next_info->flags & ATL1C_BUFFER_FREE) { + rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); + +- skb = atl1c_alloc_skb(adapter, queue, napi_mode); ++ /* When DMA RX address is set to something like ++ * 0x....fc0, it will be very likely to cause DMA ++ * RFD overflow issue. ++ * ++ * To work around it, we apply rx skb with 64 bytes ++ * longer space, and offset the address whenever ++ * 0x....fc0 is detected. ++ */ ++ if (likely(napi_mode)) ++ skb = napi_alloc_skb(&rrd_ring->napi, adapter->rx_buffer_len + 64); ++ else ++ skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len + 64); + if (unlikely(!skb)) { + if (netif_msg_rx_err(adapter)) + dev_warn(&pdev->dev, "alloc rx buffer failed\n"); + break; + } + ++ if (((unsigned long)skb->data & 0xfff) == 0xfc0) ++ skb_reserve(skb, 64); ++ + /* + * Make buffer alignment 2 beyond a 16 byte boundary + * this will result in a 16 byte aligned IP header after +-- +2.42.0 + diff --git a/queue-5.15/atm-iphase-do-pci-error-checks-on-own-line.patch b/queue-5.15/atm-iphase-do-pci-error-checks-on-own-line.patch new file mode 100644 index 00000000000..f92b02e73a0 --- /dev/null +++ b/queue-5.15/atm-iphase-do-pci-error-checks-on-own-line.patch @@ -0,0 +1,68 @@ +From cadd3af6deb7b5c51b3a7806fa144eca7899daa6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 15:53:51 +0300 +Subject: atm: iphase: Do PCI error checks on own line +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit c28742447ca9879b52fbaf022ad844f0ffcd749c ] + +In get_esi() PCI errors are checked inside line-split "if" conditions (in +addition to the file not following the coding style). To make the code in +get_esi() more readable, fix the coding style and use the usual error +handling pattern with a separate variable. + +In addition, initialization of 'error' variable at declaration is not +needed. + +No functional changes intended. + +Link: https://lore.kernel.org/r/20230911125354.25501-4-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/atm/iphase.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c +index bc8e8d9f176b2..ce56306eeb6ce 100644 +--- a/drivers/atm/iphase.c ++++ b/drivers/atm/iphase.c +@@ -2293,19 +2293,21 @@ static int get_esi(struct atm_dev *dev) + static int reset_sar(struct atm_dev *dev) + { + IADEV *iadev; +- int i, error = 1; ++ int i, error; + unsigned int pci[64]; + + iadev = INPH_IA_DEV(dev); +- for(i=0; i<64; i++) +- if ((error = pci_read_config_dword(iadev->pci, +- i*4, &pci[i])) != PCIBIOS_SUCCESSFUL) +- return error; ++ for (i = 0; i < 64; i++) { ++ error = pci_read_config_dword(iadev->pci, i * 4, &pci[i]); ++ if (error != PCIBIOS_SUCCESSFUL) ++ return error; ++ } + writel(0, iadev->reg+IPHASE5575_EXT_RESET); +- for(i=0; i<64; i++) +- if ((error = pci_write_config_dword(iadev->pci, +- i*4, pci[i])) != PCIBIOS_SUCCESSFUL) +- return error; ++ for (i = 0; i < 64; i++) { ++ error = pci_write_config_dword(iadev->pci, i * 4, pci[i]); ++ if (error != PCIBIOS_SUCCESSFUL) ++ return error; ++ } + udelay(5); + return 0; + } +-- +2.42.0 + diff --git a/queue-5.15/bluetooth-btusb-add-date-evt_skb-is-null-check.patch b/queue-5.15/bluetooth-btusb-add-date-evt_skb-is-null-check.patch new file mode 100644 index 00000000000..57e7f195015 --- /dev/null +++ b/queue-5.15/bluetooth-btusb-add-date-evt_skb-is-null-check.patch @@ -0,0 +1,71 @@ +From 0bc4dda05506920581e583865e02db47b273cdf8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 13:14:47 +0800 +Subject: Bluetooth: btusb: Add date->evt_skb is NULL check + +From: youwan Wang + +[ Upstream commit 624820f7c8826dd010e8b1963303c145f99816e9 ] + +fix crash because of null pointers + +[ 6104.969662] BUG: kernel NULL pointer dereference, address: 00000000000000c8 +[ 6104.969667] #PF: supervisor read access in kernel mode +[ 6104.969668] #PF: error_code(0x0000) - not-present page +[ 6104.969670] PGD 0 P4D 0 +[ 6104.969673] Oops: 0000 [#1] SMP NOPTI +[ 6104.969684] RIP: 0010:btusb_mtk_hci_wmt_sync+0x144/0x220 [btusb] +[ 6104.969688] RSP: 0018:ffffb8d681533d48 EFLAGS: 00010246 +[ 6104.969689] RAX: 0000000000000000 RBX: ffff8ad560bb2000 RCX: 0000000000000006 +[ 6104.969691] RDX: 0000000000000000 RSI: ffffb8d681533d08 RDI: 0000000000000000 +[ 6104.969692] RBP: ffffb8d681533d70 R08: 0000000000000001 R09: 0000000000000001 +[ 6104.969694] R10: 0000000000000001 R11: 00000000fa83b2da R12: ffff8ad461d1d7c0 +[ 6104.969695] R13: 0000000000000000 R14: ffff8ad459618c18 R15: ffffb8d681533d90 +[ 6104.969697] FS: 00007f5a1cab9d40(0000) GS:ffff8ad578200000(0000) knlGS:00000 +[ 6104.969699] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 6104.969700] CR2: 00000000000000c8 CR3: 000000018620c001 CR4: 0000000000760ef0 +[ 6104.969701] PKRU: 55555554 +[ 6104.969702] Call Trace: +[ 6104.969708] btusb_mtk_shutdown+0x44/0x80 [btusb] +[ 6104.969732] hci_dev_do_close+0x470/0x5c0 [bluetooth] +[ 6104.969748] hci_rfkill_set_block+0x56/0xa0 [bluetooth] +[ 6104.969753] rfkill_set_block+0x92/0x160 +[ 6104.969755] rfkill_fop_write+0x136/0x1e0 +[ 6104.969759] __vfs_write+0x18/0x40 +[ 6104.969761] vfs_write+0xdf/0x1c0 +[ 6104.969763] ksys_write+0xb1/0xe0 +[ 6104.969765] __x64_sys_write+0x1a/0x20 +[ 6104.969769] do_syscall_64+0x51/0x180 +[ 6104.969771] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 6104.969773] RIP: 0033:0x7f5a21f18fef +[ 6104.9] RSP: 002b:00007ffeefe39010 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 +[ 6104.969780] RAX: ffffffffffffffda RBX: 000055c10a7560a0 RCX: 00007f5a21f18fef +[ 6104.969781] RDX: 0000000000000008 RSI: 00007ffeefe39060 RDI: 0000000000000012 +[ 6104.969782] RBP: 00007ffeefe39060 R08: 0000000000000000 R09: 0000000000000017 +[ 6104.969784] R10: 00007ffeefe38d97 R11: 0000000000000293 R12: 0000000000000002 +[ 6104.969785] R13: 00007ffeefe39220 R14: 00007ffeefe391a0 R15: 000055c10a72acf0 + +Signed-off-by: youwan Wang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index c01d02f41bcb3..91a08892df223 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -2497,6 +2497,9 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, + goto err_free_wc; + } + ++ if (data->evt_skb == NULL) ++ goto err_free_wc; ++ + /* Parse and handle the return WMT event */ + wmt_evt = (struct btmtk_hci_wmt_evt *)data->evt_skb->data; + if (wmt_evt->whdr.op != hdr->op) { +-- +2.42.0 + diff --git a/queue-5.15/bluetooth-fix-double-free-in-hci_conn_cleanup.patch b/queue-5.15/bluetooth-fix-double-free-in-hci_conn_cleanup.patch new file mode 100644 index 00000000000..f709a083b0f --- /dev/null +++ b/queue-5.15/bluetooth-fix-double-free-in-hci_conn_cleanup.patch @@ -0,0 +1,139 @@ +From f6baadf0aee475aad4114b3d2478e237f8d81d2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 12:30:55 +0200 +Subject: Bluetooth: Fix double free in hci_conn_cleanup + +From: ZhengHan Wang + +[ Upstream commit a85fb91e3d728bdfc80833167e8162cce8bc7004 ] + +syzbot reports a slab use-after-free in hci_conn_hash_flush [1]. +After releasing an object using hci_conn_del_sysfs in the +hci_conn_cleanup function, releasing the same object again +using the hci_dev_put and hci_conn_put functions causes a double free. +Here's a simplified flow: + +hci_conn_del_sysfs: + hci_dev_put + put_device + kobject_put + kref_put + kobject_release + kobject_cleanup + kfree_const + kfree(name) + +hci_dev_put: + ... + kfree(name) + +hci_conn_put: + put_device + ... + kfree(name) + +This patch drop the hci_dev_put and hci_conn_put function +call in hci_conn_cleanup function, because the object is +freed in hci_conn_del_sysfs function. + +This patch also fixes the refcounting in hci_conn_add_sysfs() and +hci_conn_del_sysfs() to take into account device_add() failures. + +This fixes CVE-2023-28464. + +Link: https://syzkaller.appspot.com/bug?id=1bb51491ca5df96a5f724899d1dbb87afda61419 [1] + +Signed-off-by: ZhengHan Wang +Co-developed-by: Luiz Augusto von Dentz +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_conn.c | 6 ++---- + net/bluetooth/hci_sysfs.c | 23 ++++++++++++----------- + 2 files changed, 14 insertions(+), 15 deletions(-) + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 5f1e388c2b951..ce538dbe89d13 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -135,13 +135,11 @@ static void hci_conn_cleanup(struct hci_conn *conn) + hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); + } + +- hci_conn_del_sysfs(conn); +- + debugfs_remove_recursive(conn->debugfs); + +- hci_dev_put(hdev); ++ hci_conn_del_sysfs(conn); + +- hci_conn_put(conn); ++ hci_dev_put(hdev); + } + + static void le_scan_cleanup(struct work_struct *work) +diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c +index 08542dfc2dc53..633b82d542728 100644 +--- a/net/bluetooth/hci_sysfs.c ++++ b/net/bluetooth/hci_sysfs.c +@@ -33,7 +33,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn) + { + struct hci_dev *hdev = conn->hdev; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + conn->dev.type = &bt_link; + conn->dev.class = bt_class; +@@ -46,27 +46,30 @@ void hci_conn_add_sysfs(struct hci_conn *conn) + { + struct hci_dev *hdev = conn->hdev; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + if (device_is_registered(&conn->dev)) + return; + + dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); + +- if (device_add(&conn->dev) < 0) { ++ if (device_add(&conn->dev) < 0) + bt_dev_err(hdev, "failed to register connection device"); +- return; +- } +- +- hci_dev_hold(hdev); + } + + void hci_conn_del_sysfs(struct hci_conn *conn) + { + struct hci_dev *hdev = conn->hdev; + +- if (!device_is_registered(&conn->dev)) ++ bt_dev_dbg(hdev, "conn %p", conn); ++ ++ if (!device_is_registered(&conn->dev)) { ++ /* If device_add() has *not* succeeded, use *only* put_device() ++ * to drop the reference count. ++ */ ++ put_device(&conn->dev); + return; ++ } + + while (1) { + struct device *dev; +@@ -78,9 +81,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn) + put_device(dev); + } + +- device_del(&conn->dev); +- +- hci_dev_put(hdev); ++ device_unregister(&conn->dev); + } + + static void bt_host_release(struct device *dev) +-- +2.42.0 + diff --git a/queue-5.15/bonding-stop-the-device-in-bond_setup_by_slave.patch b/queue-5.15/bonding-stop-the-device-in-bond_setup_by_slave.patch new file mode 100644 index 00000000000..0c0e08c590e --- /dev/null +++ b/queue-5.15/bonding-stop-the-device-in-bond_setup_by_slave.patch @@ -0,0 +1,133 @@ +From 515c1da30b2bd299c29fa29cc6ce9ac39dc0aec6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 18:01:02 +0000 +Subject: bonding: stop the device in bond_setup_by_slave() + +From: Eric Dumazet + +[ Upstream commit 3cffa2ddc4d3fcf70cde361236f5a614f81a09b2 ] + +Commit 9eed321cde22 ("net: lapbether: only support ethernet devices") +has been able to keep syzbot away from net/lapb, until today. + +In the following splat [1], the issue is that a lapbether device has +been created on a bonding device without members. Then adding a non +ARPHRD_ETHER member forced the bonding master to change its type. + +The fix is to make sure we call dev_close() in bond_setup_by_slave() +so that the potential linked lapbether devices (or any other devices +having assumptions on the physical device) are removed. + +A similar bug has been addressed in commit 40baec225765 +("bonding: fix panic on non-ARPHRD_ETHER enslave failure") + +[1] +skbuff: skb_under_panic: text:ffff800089508810 len:44 put:40 head:ffff0000c78e7c00 data:ffff0000c78e7bea tail:0x16 end:0x140 dev:bond0 +kernel BUG at net/core/skbuff.c:192 ! +Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP +Modules linked in: +CPU: 0 PID: 6007 Comm: syz-executor383 Not tainted 6.6.0-rc3-syzkaller-gbf6547d8715b #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/04/2023 +pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : skb_panic net/core/skbuff.c:188 [inline] +pc : skb_under_panic+0x13c/0x140 net/core/skbuff.c:202 +lr : skb_panic net/core/skbuff.c:188 [inline] +lr : skb_under_panic+0x13c/0x140 net/core/skbuff.c:202 +sp : ffff800096a06aa0 +x29: ffff800096a06ab0 x28: ffff800096a06ba0 x27: dfff800000000000 +x26: ffff0000ce9b9b50 x25: 0000000000000016 x24: ffff0000c78e7bea +x23: ffff0000c78e7c00 x22: 000000000000002c x21: 0000000000000140 +x20: 0000000000000028 x19: ffff800089508810 x18: ffff800096a06100 +x17: 0000000000000000 x16: ffff80008a629a3c x15: 0000000000000001 +x14: 1fffe00036837a32 x13: 0000000000000000 x12: 0000000000000000 +x11: 0000000000000201 x10: 0000000000000000 x9 : cb50b496c519aa00 +x8 : cb50b496c519aa00 x7 : 0000000000000001 x6 : 0000000000000001 +x5 : ffff800096a063b8 x4 : ffff80008e280f80 x3 : ffff8000805ad11c +x2 : 0000000000000001 x1 : 0000000100000201 x0 : 0000000000000086 +Call trace: +skb_panic net/core/skbuff.c:188 [inline] +skb_under_panic+0x13c/0x140 net/core/skbuff.c:202 +skb_push+0xf0/0x108 net/core/skbuff.c:2446 +ip6gre_header+0xbc/0x738 net/ipv6/ip6_gre.c:1384 +dev_hard_header include/linux/netdevice.h:3136 [inline] +lapbeth_data_transmit+0x1c4/0x298 drivers/net/wan/lapbether.c:257 +lapb_data_transmit+0x8c/0xb0 net/lapb/lapb_iface.c:447 +lapb_transmit_buffer+0x178/0x204 net/lapb/lapb_out.c:149 +lapb_send_control+0x220/0x320 net/lapb/lapb_subr.c:251 +__lapb_disconnect_request+0x9c/0x17c net/lapb/lapb_iface.c:326 +lapb_device_event+0x288/0x4e0 net/lapb/lapb_iface.c:492 +notifier_call_chain+0x1a4/0x510 kernel/notifier.c:93 +raw_notifier_call_chain+0x3c/0x50 kernel/notifier.c:461 +call_netdevice_notifiers_info net/core/dev.c:1970 [inline] +call_netdevice_notifiers_extack net/core/dev.c:2008 [inline] +call_netdevice_notifiers net/core/dev.c:2022 [inline] +__dev_close_many+0x1b8/0x3c4 net/core/dev.c:1508 +dev_close_many+0x1e0/0x470 net/core/dev.c:1559 +dev_close+0x174/0x250 net/core/dev.c:1585 +lapbeth_device_event+0x2e4/0x958 drivers/net/wan/lapbether.c:466 +notifier_call_chain+0x1a4/0x510 kernel/notifier.c:93 +raw_notifier_call_chain+0x3c/0x50 kernel/notifier.c:461 +call_netdevice_notifiers_info net/core/dev.c:1970 [inline] +call_netdevice_notifiers_extack net/core/dev.c:2008 [inline] +call_netdevice_notifiers net/core/dev.c:2022 [inline] +__dev_close_many+0x1b8/0x3c4 net/core/dev.c:1508 +dev_close_many+0x1e0/0x470 net/core/dev.c:1559 +dev_close+0x174/0x250 net/core/dev.c:1585 +bond_enslave+0x2298/0x30cc drivers/net/bonding/bond_main.c:2332 +bond_do_ioctl+0x268/0xc64 drivers/net/bonding/bond_main.c:4539 +dev_ifsioc+0x754/0x9ac +dev_ioctl+0x4d8/0xd34 net/core/dev_ioctl.c:786 +sock_do_ioctl+0x1d4/0x2d0 net/socket.c:1217 +sock_ioctl+0x4e8/0x834 net/socket.c:1322 +vfs_ioctl fs/ioctl.c:51 [inline] +__do_sys_ioctl fs/ioctl.c:871 [inline] +__se_sys_ioctl fs/ioctl.c:857 [inline] +__arm64_sys_ioctl+0x14c/0x1c8 fs/ioctl.c:857 +__invoke_syscall arch/arm64/kernel/syscall.c:37 [inline] +invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:51 +el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:136 +do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:155 +el0_svc+0x58/0x16c arch/arm64/kernel/entry-common.c:678 +el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:696 +el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:591 +Code: aa1803e6 aa1903e7 a90023f5 94785b8b (d4210000) + +Fixes: 872254dd6b1f ("net/bonding: Enable bonding to enslave non ARPHRD_ETHER") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Acked-by: Jay Vosburgh +Reviewed-by: Hangbin Liu +Link: https://lore.kernel.org/r/20231109180102.4085183-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 80e42852ffefb..9aed194d308d6 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1473,6 +1473,10 @@ static void bond_compute_features(struct bonding *bond) + static void bond_setup_by_slave(struct net_device *bond_dev, + struct net_device *slave_dev) + { ++ bool was_up = !!(bond_dev->flags & IFF_UP); ++ ++ dev_close(bond_dev); ++ + bond_dev->header_ops = slave_dev->header_ops; + + bond_dev->type = slave_dev->type; +@@ -1487,6 +1491,8 @@ static void bond_setup_by_slave(struct net_device *bond_dev, + bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); + bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); + } ++ if (was_up) ++ dev_open(bond_dev, NULL); + } + + /* On bonding slaves other than the currently active slave, suppress +-- +2.42.0 + diff --git a/queue-5.15/bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch b/queue-5.15/bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch new file mode 100644 index 00000000000..c329830eb1d --- /dev/null +++ b/queue-5.15/bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch @@ -0,0 +1,97 @@ +From 0159060cf34c52a9c19af4c10190b2b73abbfea2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 01:32:08 +0200 +Subject: bpf: Detect IP == ksym.end as part of BPF program + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 66d9111f3517f85ef2af0337ece02683ce0faf21 ] + +Now that bpf_throw kfunc is the first such call instruction that has +noreturn semantics within the verifier, this also kicks in dead code +elimination in unprecedented ways. For one, any instruction following +a bpf_throw call will never be marked as seen. Moreover, if a callchain +ends up throwing, any instructions after the call instruction to the +eventually throwing subprog in callers will also never be marked as +seen. + +The tempting way to fix this would be to emit extra 'int3' instructions +which bump the jited_len of a program, and ensure that during runtime +when a program throws, we can discover its boundaries even if the call +instruction to bpf_throw (or to subprogs that always throw) is emitted +as the final instruction in the program. + +An example of such a program would be this: + +do_something(): + ... + r0 = 0 + exit + +foo(): + r1 = 0 + call bpf_throw + r0 = 0 + exit + +bar(cond): + if r1 != 0 goto pc+2 + call do_something + exit + call foo + r0 = 0 // Never seen by verifier + exit // + +main(ctx): + r1 = ... + call bar + r0 = 0 + exit + +Here, if we do end up throwing, the stacktrace would be the following: + +bpf_throw +foo +bar +main + +In bar, the final instruction emitted will be the call to foo, as such, +the return address will be the subsequent instruction (which the JIT +emits as int3 on x86). This will end up lying outside the jited_len of +the program, thus, when unwinding, we will fail to discover the return +address as belonging to any program and end up in a panic due to the +unreliable stack unwinding of BPF programs that we never expect. + +To remedy this case, make bpf_prog_ksym_find treat IP == ksym.end as +part of the BPF program, so that is_bpf_text_address returns true when +such a case occurs, and we are able to unwind reliably when the final +instruction ends up being a call instruction. + +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20230912233214.1518551-12-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index f7c27c1cc593b..36c2896ee45f4 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -605,7 +605,11 @@ static __always_inline int bpf_tree_comp(void *key, struct latch_tree_node *n) + + if (val < ksym->start) + return -1; +- if (val >= ksym->end) ++ /* Ensure that we detect return addresses as part of the program, when ++ * the final instruction is a call for a program part of the stack ++ * trace. Therefore, do val > ksym->end instead of val >= ksym->end. ++ */ ++ if (val > ksym->end) + return 1; + + return 0; +-- +2.42.0 + diff --git a/queue-5.15/cifs-fix-check-of-rc-in-function-generate_smb3signin.patch b/queue-5.15/cifs-fix-check-of-rc-in-function-generate_smb3signin.patch new file mode 100644 index 00000000000..d1b5d0a1e84 --- /dev/null +++ b/queue-5.15/cifs-fix-check-of-rc-in-function-generate_smb3signin.patch @@ -0,0 +1,52 @@ +From cd854ddf30b3b09ecb043f01c4dbbee6d6a0e08d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 19:42:41 +0300 +Subject: cifs: fix check of rc in function generate_smb3signingkey + +From: Ekaterina Esina + +[ Upstream commit 181724fc72486dec2bec8803459be05b5162aaa8 ] + +Remove extra check after condition, add check after generating key +for encryption. The check is needed to return non zero rc before +rewriting it with generating key for decryption. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Reviewed-by: Paulo Alcantara (SUSE) +Fixes: d70e9fa55884 ("cifs: try opening channels after mounting") +Signed-off-by: Ekaterina Esina +Co-developed-by: Anastasia Belova +Signed-off-by: Anastasia Belova +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/cifs/smb2transport.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c +index 390cc5e8c7467..0f2e0ce84a03f 100644 +--- a/fs/cifs/smb2transport.c ++++ b/fs/cifs/smb2transport.c +@@ -430,6 +430,8 @@ generate_smb3signingkey(struct cifs_ses *ses, + ptriplet->encryption.context, + ses->smb3encryptionkey, + SMB3_ENC_DEC_KEY_SIZE); ++ if (rc) ++ return rc; + rc = generate_key(ses, ptriplet->decryption.label, + ptriplet->decryption.context, + ses->smb3decryptionkey, +@@ -438,9 +440,6 @@ generate_smb3signingkey(struct cifs_ses *ses, + return rc; + } + +- if (rc) +- return rc; +- + #ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS + cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__); + /* +-- +2.42.0 + diff --git a/queue-5.15/cifs-spnego-add-in-host_key_len.patch b/queue-5.15/cifs-spnego-add-in-host_key_len.patch new file mode 100644 index 00000000000..a9044efd405 --- /dev/null +++ b/queue-5.15/cifs-spnego-add-in-host_key_len.patch @@ -0,0 +1,43 @@ +From 9652700c054a14dc811854d693c884e4141e9afe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 17:52:32 +0300 +Subject: cifs: spnego: add ';' in HOST_KEY_LEN + +From: Anastasia Belova + +[ Upstream commit ff31ba19d732efb9aca3633935d71085e68d5076 ] + +"host=" should start with ';' (as in cifs_get_spnego_key) +So its length should be 6. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Reviewed-by: Paulo Alcantara (SUSE) +Fixes: 7c9c3760b3a5 ("[CIFS] add constants for string lengths of keynames in SPNEGO upcall string") +Signed-off-by: Anastasia Belova +Co-developed-by: Ekaterina Esina +Signed-off-by: Ekaterina Esina +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/cifs/cifs_spnego.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c +index 353bd0dd70260..66b4413b94f7f 100644 +--- a/fs/cifs/cifs_spnego.c ++++ b/fs/cifs/cifs_spnego.c +@@ -64,8 +64,8 @@ struct key_type cifs_spnego_key_type = { + * strlen(";sec=ntlmsspi") */ + #define MAX_MECH_STR_LEN 13 + +-/* strlen of "host=" */ +-#define HOST_KEY_LEN 5 ++/* strlen of ";host=" */ ++#define HOST_KEY_LEN 6 + + /* strlen of ";ip4=" or ";ip6=" */ + #define IP_KEY_LEN 5 +-- +2.42.0 + diff --git a/queue-5.15/clocksource-drivers-timer-atmel-tcb-fix-initializati.patch b/queue-5.15/clocksource-drivers-timer-atmel-tcb-fix-initializati.patch new file mode 100644 index 00000000000..51ca70bd9a8 --- /dev/null +++ b/queue-5.15/clocksource-drivers-timer-atmel-tcb-fix-initializati.patch @@ -0,0 +1,56 @@ +From f4658a97e95519289aba2120e89908dbd0043d82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 18:17:13 +0200 +Subject: clocksource/drivers/timer-atmel-tcb: Fix initialization on SAM9 + hardware + +From: Ronald Wahl + +[ Upstream commit 6d3bc4c02d59996d1d3180d8ed409a9d7d5900e0 ] + +On SAM9 hardware two cascaded 16 bit timers are used to form a 32 bit +high resolution timer that is used as scheduler clock when the kernel +has been configured that way (CONFIG_ATMEL_CLOCKSOURCE_TCB). + +The driver initially triggers a reset-to-zero of the two timers but this +reset is only performed on the next rising clock. For the first timer +this is ok - it will be in the next 60ns (16MHz clock). For the chained +second timer this will only happen after the first timer overflows, i.e. +after 2^16 clocks (~4ms with a 16MHz clock). So with other words the +scheduler clock resets to 0 after the first 2^16 clock cycles. + +It looks like that the scheduler does not like this and behaves wrongly +over its lifetime, e.g. some tasks are scheduled with a long delay. Why +that is and if there are additional requirements for this behaviour has +not been further analysed. + +There is a simple fix for resetting the second timer as well when the +first timer is reset and this is to set the ATMEL_TC_ASWTRG_SET bit in +the Channel Mode register (CMR) of the first timer. This will also rise +the TIOA line (clock input of the second timer) when a software trigger +respective SYNC is issued. + +Signed-off-by: Ronald Wahl +Acked-by: Alexandre Belloni +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20231007161803.31342-1-rwahl@gmx.de +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-atmel-tcb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c +index 27af17c995900..2a90c92a9182a 100644 +--- a/drivers/clocksource/timer-atmel-tcb.c ++++ b/drivers/clocksource/timer-atmel-tcb.c +@@ -315,6 +315,7 @@ static void __init tcb_setup_dual_chan(struct atmel_tc *tc, int mck_divisor_idx) + writel(mck_divisor_idx /* likely divide-by-8 */ + | ATMEL_TC_WAVE + | ATMEL_TC_WAVESEL_UP /* free-run */ ++ | ATMEL_TC_ASWTRG_SET /* TIOA0 rises at software trigger */ + | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ + | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ + tcaddr + ATMEL_TC_REG(0, CMR)); +-- +2.42.0 + diff --git a/queue-5.15/clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch b/queue-5.15/clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch new file mode 100644 index 00000000000..fbd78599779 --- /dev/null +++ b/queue-5.15/clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch @@ -0,0 +1,66 @@ +From c09286724d2ba9ef1e3b0f9a30e54f6638419f12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 16:39:22 +0800 +Subject: clocksource/drivers/timer-imx-gpt: Fix potential memory leak + +From: Jacky Bai + +[ Upstream commit 8051a993ce222a5158bccc6ac22ace9253dd71cb ] + +Fix coverity Issue CID 250382: Resource leak (RESOURCE_LEAK). +Add kfree when error return. + +Signed-off-by: Jacky Bai +Reviewed-by: Peng Fan +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20231009083922.1942971-1-ping.bai@nxp.com +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-imx-gpt.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c +index 7b2c70f2f353b..fabff69e52e58 100644 +--- a/drivers/clocksource/timer-imx-gpt.c ++++ b/drivers/clocksource/timer-imx-gpt.c +@@ -454,12 +454,16 @@ static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type t + return -ENOMEM; + + imxtm->base = of_iomap(np, 0); +- if (!imxtm->base) +- return -ENXIO; ++ if (!imxtm->base) { ++ ret = -ENXIO; ++ goto err_kfree; ++ } + + imxtm->irq = irq_of_parse_and_map(np, 0); +- if (imxtm->irq <= 0) +- return -EINVAL; ++ if (imxtm->irq <= 0) { ++ ret = -EINVAL; ++ goto err_kfree; ++ } + + imxtm->clk_ipg = of_clk_get_by_name(np, "ipg"); + +@@ -472,11 +476,15 @@ static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type t + + ret = _mxc_timer_init(imxtm); + if (ret) +- return ret; ++ goto err_kfree; + + initialized = 1; + + return 0; ++ ++err_kfree: ++ kfree(imxtm); ++ return ret; + } + + static int __init imx1_timer_init_dt(struct device_node *np) +-- +2.42.0 + diff --git a/queue-5.15/crypto-pcrypt-fix-hungtask-for-padata_reset.patch b/queue-5.15/crypto-pcrypt-fix-hungtask-for-padata_reset.patch new file mode 100644 index 00000000000..b694bcd6c65 --- /dev/null +++ b/queue-5.15/crypto-pcrypt-fix-hungtask-for-padata_reset.patch @@ -0,0 +1,106 @@ +From ff5a523ae2ddf3f3c7c293f5570c1b848a78e848 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 13:33:41 +0000 +Subject: crypto: pcrypt - Fix hungtask for PADATA_RESET + +From: Lu Jialin + +[ Upstream commit 8f4f68e788c3a7a696546291258bfa5fdb215523 ] + +We found a hungtask bug in test_aead_vec_cfg as follows: + +INFO: task cryptomgr_test:391009 blocked for more than 120 seconds. +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +Call trace: + __switch_to+0x98/0xe0 + __schedule+0x6c4/0xf40 + schedule+0xd8/0x1b4 + schedule_timeout+0x474/0x560 + wait_for_common+0x368/0x4e0 + wait_for_completion+0x20/0x30 + wait_for_completion+0x20/0x30 + test_aead_vec_cfg+0xab4/0xd50 + test_aead+0x144/0x1f0 + alg_test_aead+0xd8/0x1e0 + alg_test+0x634/0x890 + cryptomgr_test+0x40/0x70 + kthread+0x1e0/0x220 + ret_from_fork+0x10/0x18 + Kernel panic - not syncing: hung_task: blocked tasks + +For padata_do_parallel, when the return err is 0 or -EBUSY, it will call +wait_for_completion(&wait->completion) in test_aead_vec_cfg. In normal +case, aead_request_complete() will be called in pcrypt_aead_serial and the +return err is 0 for padata_do_parallel. But, when pinst->flags is +PADATA_RESET, the return err is -EBUSY for padata_do_parallel, and it +won't call aead_request_complete(). Therefore, test_aead_vec_cfg will +hung at wait_for_completion(&wait->completion), which will cause +hungtask. + +The problem comes as following: +(padata_do_parallel) | + rcu_read_lock_bh(); | + err = -EINVAL; | (padata_replace) + | pinst->flags |= PADATA_RESET; + err = -EBUSY | + if (pinst->flags & PADATA_RESET) | + rcu_read_unlock_bh() | + return err + +In order to resolve the problem, we replace the return err -EBUSY with +-EAGAIN, which means parallel_data is changing, and the caller should call +it again. + +v3: +remove retry and just change the return err. +v2: +introduce padata_try_do_parallel() in pcrypt_aead_encrypt and +pcrypt_aead_decrypt to solve the hungtask. + +Signed-off-by: Lu Jialin +Signed-off-by: Guo Zihua +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/pcrypt.c | 4 ++++ + kernel/padata.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c +index 9d10b846ccf73..005a36cb21bc4 100644 +--- a/crypto/pcrypt.c ++++ b/crypto/pcrypt.c +@@ -117,6 +117,8 @@ static int pcrypt_aead_encrypt(struct aead_request *req) + err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu); + if (!err) + return -EINPROGRESS; ++ if (err == -EBUSY) ++ return -EAGAIN; + + return err; + } +@@ -164,6 +166,8 @@ static int pcrypt_aead_decrypt(struct aead_request *req) + err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu); + if (!err) + return -EINPROGRESS; ++ if (err == -EBUSY) ++ return -EAGAIN; + + return err; + } +diff --git a/kernel/padata.c b/kernel/padata.c +index c6025a48fb49e..47f146f061fb1 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -194,7 +194,7 @@ int padata_do_parallel(struct padata_shell *ps, + *cb_cpu = cpu; + } + +- err = -EBUSY; ++ err = -EBUSY; + if ((pinst->flags & PADATA_RESET)) + goto out; + +-- +2.42.0 + diff --git a/queue-5.15/drm-amd-display-avoid-null-dereference-of-timing-gen.patch b/queue-5.15/drm-amd-display-avoid-null-dereference-of-timing-gen.patch new file mode 100644 index 00000000000..55499678076 --- /dev/null +++ b/queue-5.15/drm-amd-display-avoid-null-dereference-of-timing-gen.patch @@ -0,0 +1,48 @@ +From 71db9790ea9a89a5829265d76d6921a443fa254f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 10:14:49 +0800 +Subject: drm/amd/display: Avoid NULL dereference of timing generator + +From: Wayne Lin + +[ Upstream commit b1904ed480cee3f9f4036ea0e36d139cb5fee2d6 ] + +[Why & How] +Check whether assigned timing generator is NULL or not before +accessing its funcs to prevent NULL dereference. + +Reviewed-by: Jun Lei +Acked-by: Hersen Wu +Signed-off-by: Wayne Lin +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +index f0f54f4d3d9bc..5dd57cf170f51 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +@@ -562,7 +562,7 @@ uint32_t dc_stream_get_vblank_counter(const struct dc_stream_state *stream) + for (i = 0; i < MAX_PIPES; i++) { + struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; + +- if (res_ctx->pipe_ctx[i].stream != stream) ++ if (res_ctx->pipe_ctx[i].stream != stream || !tg) + continue; + + return tg->funcs->get_frame_count(tg); +@@ -621,7 +621,7 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream, + for (i = 0; i < MAX_PIPES; i++) { + struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; + +- if (res_ctx->pipe_ctx[i].stream != stream) ++ if (res_ctx->pipe_ctx[i].stream != stream || !tg) + continue; + + tg->funcs->get_scanoutpos(tg, +-- +2.42.0 + diff --git a/queue-5.15/drm-amd-display-use-full-update-for-clip-size-increa.patch b/queue-5.15/drm-amd-display-use-full-update-for-clip-size-increa.patch new file mode 100644 index 00000000000..ae303659632 --- /dev/null +++ b/queue-5.15/drm-amd-display-use-full-update-for-clip-size-increa.patch @@ -0,0 +1,93 @@ +From 30babe06b691821909e41375430932e9aec9f49d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 14:43:21 -0400 +Subject: drm/amd/display: use full update for clip size increase of large + plane source + +From: Wenjing Liu + +[ Upstream commit 05b78277ef0efc1deebc8a22384fffec29a3676e ] + +[why] +Clip size increase will increase viewport, which could cause us to +switch to MPC combine. +If we skip full update, we are not able to change to MPC combine in +fast update. This will cause corruption showing on the video plane. + +[how] +treat clip size increase of a surface larger than 5k as a full update. + +Reviewed-by: Jun Lei +Acked-by: Aurabindo Pillai +Signed-off-by: Wenjing Liu +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 12 ++++++++++-- + drivers/gpu/drm/amd/display/dc/dc.h | 5 +++++ + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index ffe7479a047d8..3919e75fec16d 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -886,7 +886,8 @@ static bool dc_construct(struct dc *dc, + /* set i2c speed if not done by the respective dcnxxx__resource.c */ + if (dc->caps.i2c_speed_in_khz_hdcp == 0) + dc->caps.i2c_speed_in_khz_hdcp = dc->caps.i2c_speed_in_khz; +- ++ if (dc->caps.max_optimizable_video_width == 0) ++ dc->caps.max_optimizable_video_width = 5120; + dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); + if (!dc->clk_mgr) + goto fail; +@@ -2053,6 +2054,7 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa + } + + static enum surface_update_type get_scaling_info_update_type( ++ const struct dc *dc, + const struct dc_surface_update *u) + { + union surface_update_flags *update_flags = &u->surface->update_flags; +@@ -2087,6 +2089,12 @@ static enum surface_update_type get_scaling_info_update_type( + update_flags->bits.clock_change = 1; + } + ++ if (u->scaling_info->src_rect.width > dc->caps.max_optimizable_video_width && ++ (u->scaling_info->clip_rect.width > u->surface->clip_rect.width || ++ u->scaling_info->clip_rect.height > u->surface->clip_rect.height)) ++ /* Changing clip size of a large surface may result in MPC slice count change */ ++ update_flags->bits.bandwidth_change = 1; ++ + if (u->scaling_info->src_rect.x != u->surface->src_rect.x + || u->scaling_info->src_rect.y != u->surface->src_rect.y + || u->scaling_info->clip_rect.x != u->surface->clip_rect.x +@@ -2124,7 +2132,7 @@ static enum surface_update_type det_surface_update(const struct dc *dc, + type = get_plane_info_update_type(u); + elevate_update_type(&overall_type, type); + +- type = get_scaling_info_update_type(u); ++ type = get_scaling_info_update_type(dc, u); + elevate_update_type(&overall_type, type); + + if (u->flip_addr) +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index e0f58fab5e8ed..09a8726c26399 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -164,6 +164,11 @@ struct dc_caps { + uint32_t dmdata_alloc_size; + unsigned int max_cursor_size; + unsigned int max_video_width; ++ /* ++ * max video plane width that can be safely assumed to be always ++ * supported by single DPP pipe. ++ */ ++ unsigned int max_optimizable_video_width; + unsigned int min_horizontal_blanking_period; + int linear_pitch_alignment; + bool dcc_const_color; +-- +2.42.0 + diff --git a/queue-5.15/drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch b/queue-5.15/drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch new file mode 100644 index 00000000000..d539029b8ca --- /dev/null +++ b/queue-5.15/drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch @@ -0,0 +1,81 @@ +From 6742ebe027f8008505e7e6abac8d2ea5f0e334bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 15:46:44 -0500 +Subject: drm/amd: Fix UBSAN array-index-out-of-bounds for Polaris and Tonga + +From: Mario Limonciello + +[ Upstream commit 0f0e59075b5c22f1e871fbd508d6e4f495048356 ] + +For pptable structs that use flexible array sizes, use flexible arrays. + +Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2036742 +Signed-off-by: Mario Limonciello +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +index 41444e27bfc0c..e0e40b054c08b 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +@@ -164,7 +164,7 @@ typedef struct _ATOM_Tonga_State { + typedef struct _ATOM_Tonga_State_Array { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_State entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_State entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_State_Array; + + typedef struct _ATOM_Tonga_MCLK_Dependency_Record { +@@ -210,7 +210,7 @@ typedef struct _ATOM_Polaris_SCLK_Dependency_Record { + typedef struct _ATOM_Polaris_SCLK_Dependency_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Polaris_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Polaris_SCLK_Dependency_Table; + + typedef struct _ATOM_Tonga_PCIE_Record { +@@ -222,7 +222,7 @@ typedef struct _ATOM_Tonga_PCIE_Record { + typedef struct _ATOM_Tonga_PCIE_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_PCIE_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_PCIE_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_PCIE_Table; + + typedef struct _ATOM_Polaris10_PCIE_Record { +@@ -235,7 +235,7 @@ typedef struct _ATOM_Polaris10_PCIE_Record { + typedef struct _ATOM_Polaris10_PCIE_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Polaris10_PCIE_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Polaris10_PCIE_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Polaris10_PCIE_Table; + + +@@ -252,7 +252,7 @@ typedef struct _ATOM_Tonga_MM_Dependency_Record { + typedef struct _ATOM_Tonga_MM_Dependency_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_MM_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_MM_Dependency_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_MM_Dependency_Table; + + typedef struct _ATOM_Tonga_Voltage_Lookup_Record { +@@ -265,7 +265,7 @@ typedef struct _ATOM_Tonga_Voltage_Lookup_Record { + typedef struct _ATOM_Tonga_Voltage_Lookup_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_Voltage_Lookup_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_Voltage_Lookup_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_Voltage_Lookup_Table; + + typedef struct _ATOM_Tonga_Fan_Table { +-- +2.42.0 + diff --git a/queue-5.15/drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch b/queue-5.15/drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch new file mode 100644 index 00000000000..713d4067a31 --- /dev/null +++ b/queue-5.15/drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch @@ -0,0 +1,69 @@ +From 64a7e91c4a7184b126365806476d4cecf037b02f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 15:22:52 -0500 +Subject: drm/amd: Fix UBSAN array-index-out-of-bounds for SMU7 + +From: Mario Limonciello + +[ Upstream commit 760efbca74a405dc439a013a5efaa9fadc95a8c3 ] + +For pptable structs that use flexible array sizes, use flexible arrays. + +Suggested-by: Felix Held +Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2874 +Signed-off-by: Mario Limonciello +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/include/pptable.h | 4 ++-- + drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/include/pptable.h b/drivers/gpu/drm/amd/include/pptable.h +index 0b6a057e0a4c4..5aac8d545bdc6 100644 +--- a/drivers/gpu/drm/amd/include/pptable.h ++++ b/drivers/gpu/drm/amd/include/pptable.h +@@ -78,7 +78,7 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER + typedef struct _ATOM_PPLIB_STATE + { + UCHAR ucNonClockStateIndex; +- UCHAR ucClockStateIndices[1]; // variable-sized ++ UCHAR ucClockStateIndices[]; // variable-sized + } ATOM_PPLIB_STATE; + + +@@ -473,7 +473,7 @@ typedef struct _ATOM_PPLIB_STATE_V2 + /** + * Driver will read the first ucNumDPMLevels in this array + */ +- UCHAR clockInfoIndex[1]; ++ UCHAR clockInfoIndex[]; + } ATOM_PPLIB_STATE_V2; + + typedef struct _StateArray{ +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +index b0ac4d121adca..41444e27bfc0c 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +@@ -179,7 +179,7 @@ typedef struct _ATOM_Tonga_MCLK_Dependency_Record { + typedef struct _ATOM_Tonga_MCLK_Dependency_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_MCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_MCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_MCLK_Dependency_Table; + + typedef struct _ATOM_Tonga_SCLK_Dependency_Record { +@@ -194,7 +194,7 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Record { + typedef struct _ATOM_Tonga_SCLK_Dependency_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_SCLK_Dependency_Table; + + typedef struct _ATOM_Polaris_SCLK_Dependency_Record { +-- +2.42.0 + diff --git a/queue-5.15/drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch b/queue-5.15/drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch new file mode 100644 index 00000000000..b745729162c --- /dev/null +++ b/queue-5.15/drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch @@ -0,0 +1,105 @@ +From 4130ef7d4183a6fe9c726d3231a3cc9e192da70b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 12:56:37 +0000 +Subject: drm/amdgpu: Fix a null pointer access when the smc_rreg pointer is + NULL + +From: Qu Huang + +[ Upstream commit 5104fdf50d326db2c1a994f8b35dcd46e63ae4ad ] + +In certain types of chips, such as VEGA20, reading the amdgpu_regs_smc file could result in an abnormal null pointer access when the smc_rreg pointer is NULL. Below are the steps to reproduce this issue and the corresponding exception log: + +1. Navigate to the directory: /sys/kernel/debug/dri/0 +2. Execute command: cat amdgpu_regs_smc +3. Exception Log:: +[4005007.702554] BUG: kernel NULL pointer dereference, address: 0000000000000000 +[4005007.702562] #PF: supervisor instruction fetch in kernel mode +[4005007.702567] #PF: error_code(0x0010) - not-present page +[4005007.702570] PGD 0 P4D 0 +[4005007.702576] Oops: 0010 [#1] SMP NOPTI +[4005007.702581] CPU: 4 PID: 62563 Comm: cat Tainted: G OE 5.15.0-43-generic #46-Ubunt u +[4005007.702590] RIP: 0010:0x0 +[4005007.702598] Code: Unable to access opcode bytes at RIP 0xffffffffffffffd6. +[4005007.702600] RSP: 0018:ffffa82b46d27da0 EFLAGS: 00010206 +[4005007.702605] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffa82b46d27e68 +[4005007.702609] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9940656e0000 +[4005007.702612] RBP: ffffa82b46d27dd8 R08: 0000000000000000 R09: ffff994060c07980 +[4005007.702615] R10: 0000000000020000 R11: 0000000000000000 R12: 00007f5e06753000 +[4005007.702618] R13: ffff9940656e0000 R14: ffffa82b46d27e68 R15: 00007f5e06753000 +[4005007.702622] FS: 00007f5e0755b740(0000) GS:ffff99479d300000(0000) knlGS:0000000000000000 +[4005007.702626] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[4005007.702629] CR2: ffffffffffffffd6 CR3: 00000003253fc000 CR4: 00000000003506e0 +[4005007.702633] Call Trace: +[4005007.702636] +[4005007.702640] amdgpu_debugfs_regs_smc_read+0xb0/0x120 [amdgpu] +[4005007.703002] full_proxy_read+0x5c/0x80 +[4005007.703011] vfs_read+0x9f/0x1a0 +[4005007.703019] ksys_read+0x67/0xe0 +[4005007.703023] __x64_sys_read+0x19/0x20 +[4005007.703028] do_syscall_64+0x5c/0xc0 +[4005007.703034] ? do_user_addr_fault+0x1e3/0x670 +[4005007.703040] ? exit_to_user_mode_prepare+0x37/0xb0 +[4005007.703047] ? irqentry_exit_to_user_mode+0x9/0x20 +[4005007.703052] ? irqentry_exit+0x19/0x30 +[4005007.703057] ? exc_page_fault+0x89/0x160 +[4005007.703062] ? asm_exc_page_fault+0x8/0x30 +[4005007.703068] entry_SYSCALL_64_after_hwframe+0x44/0xae +[4005007.703075] RIP: 0033:0x7f5e07672992 +[4005007.703079] Code: c0 e9 b2 fe ff ff 50 48 8d 3d fa b2 0c 00 e8 c5 1d 02 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 e c 28 48 89 54 24 +[4005007.703083] RSP: 002b:00007ffe03097898 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 +[4005007.703088] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007f5e07672992 +[4005007.703091] RDX: 0000000000020000 RSI: 00007f5e06753000 RDI: 0000000000000003 +[4005007.703094] RBP: 00007f5e06753000 R08: 00007f5e06752010 R09: 00007f5e06752010 +[4005007.703096] R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000022000 +[4005007.703099] R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000 +[4005007.703105] +[4005007.703107] Modules linked in: nf_tables libcrc32c nfnetlink algif_hash af_alg binfmt_misc nls_ iso8859_1 ipmi_ssif ast intel_rapl_msr intel_rapl_common drm_vram_helper drm_ttm_helper amd64_edac t tm edac_mce_amd kvm_amd ccp mac_hid k10temp kvm acpi_ipmi ipmi_si rapl sch_fq_codel ipmi_devintf ipm i_msghandler msr parport_pc ppdev lp parport mtd pstore_blk efi_pstore ramoops pstore_zone reed_solo mon ip_tables x_tables autofs4 ib_uverbs ib_core amdgpu(OE) amddrm_ttm_helper(OE) amdttm(OE) iommu_v 2 amd_sched(OE) amdkcl(OE) drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec rc_core drm igb ahci xhci_pci libahci i2c_piix4 i2c_algo_bit xhci_pci_renesas dca +[4005007.703184] CR2: 0000000000000000 +[4005007.703188] ---[ end trace ac65a538d240da39 ]--- +[4005007.800865] RIP: 0010:0x0 +[4005007.800871] Code: Unable to access opcode bytes at RIP 0xffffffffffffffd6. +[4005007.800874] RSP: 0018:ffffa82b46d27da0 EFLAGS: 00010206 +[4005007.800878] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffa82b46d27e68 +[4005007.800881] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9940656e0000 +[4005007.800883] RBP: ffffa82b46d27dd8 R08: 0000000000000000 R09: ffff994060c07980 +[4005007.800886] R10: 0000000000020000 R11: 0000000000000000 R12: 00007f5e06753000 +[4005007.800888] R13: ffff9940656e0000 R14: ffffa82b46d27e68 R15: 00007f5e06753000 +[4005007.800891] FS: 00007f5e0755b740(0000) GS:ffff99479d300000(0000) knlGS:0000000000000000 +[4005007.800895] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[4005007.800898] CR2: ffffffffffffffd6 CR3: 00000003253fc000 CR4: 00000000003506e0 + +Signed-off-by: Qu Huang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +index 348629ea0e153..beb199d13451b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -458,6 +458,9 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, + ssize_t result = 0; + int r; + ++ if (!adev->smc_rreg) ++ return -EPERM; ++ + if (size & 0x3 || *pos & 0x3) + return -EINVAL; + +@@ -517,6 +520,9 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * + ssize_t result = 0; + int r; + ++ if (!adev->smc_wreg) ++ return -EPERM; ++ + if (size & 0x3 || *pos & 0x3) + return -EINVAL; + +-- +2.42.0 + diff --git a/queue-5.15/drm-amdgpu-fix-potential-null-pointer-derefernce.patch b/queue-5.15/drm-amdgpu-fix-potential-null-pointer-derefernce.patch new file mode 100644 index 00000000000..1f76405df2c --- /dev/null +++ b/queue-5.15/drm-amdgpu-fix-potential-null-pointer-derefernce.patch @@ -0,0 +1,37 @@ +From 471538063f6504a52529cf5304ebf301eac70a4b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 16:22:29 +0800 +Subject: drm/amdgpu: Fix potential null pointer derefernce + +From: Stanley.Yang + +[ Upstream commit 80285ae1ec8717b597b20de38866c29d84d321a1 ] + +The amdgpu_ras_get_context may return NULL if device +not support ras feature, so add check before using. + +Signed-off-by: Stanley.Yang +Reviewed-by: Tao Zhou +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index f57334fff7fc8..19e32f38a4c45 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -5116,7 +5116,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, + * Flush RAM to disk so that after reboot + * the user can read log and see why the system rebooted. + */ +- if (need_emergency_restart && amdgpu_ras_get_context(adev)->reboot) { ++ if (need_emergency_restart && amdgpu_ras_get_context(adev) && ++ amdgpu_ras_get_context(adev)->reboot) { + DRM_WARN("Emergency reboot."); + + ksys_sync_helper(); +-- +2.42.0 + diff --git a/queue-5.15/drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch b/queue-5.15/drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch new file mode 100644 index 00000000000..a8b653ec58e --- /dev/null +++ b/queue-5.15/drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch @@ -0,0 +1,103 @@ +From 8c65a3d7faaaa87fe97127a3206f6c42da20d1b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 19:31:48 -0400 +Subject: drm/amdgpu: fix software pci_unplug on some chips + +From: Vitaly Prosyak + +[ Upstream commit 4638e0c29a3f2294d5de0d052a4b8c9f33ccb957 ] + +When software 'pci unplug' using IGT is executed we got a sysfs directory +entry is NULL for differant ras blocks like hdp, umc, etc. +Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group' +check that 'sd' is not NULL. + +[ +0.000001] RIP: 0010:sysfs_remove_group+0x83/0x90 +[ +0.000002] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 ff ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b eb cc 66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 +[ +0.000001] RSP: 0018:ffffc90002067c90 EFLAGS: 00010246 +[ +0.000002] RAX: 0000000000000000 RBX: ffffffff824ea180 RCX: 0000000000000000 +[ +0.000001] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[ +0.000001] RBP: ffffc90002067ca8 R08: 0000000000000000 R09: 0000000000000000 +[ +0.000001] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +[ +0.000001] R13: ffff88810a395f48 R14: ffff888101aab0d0 R15: 0000000000000000 +[ +0.000001] FS: 00007f5ddaa43a00(0000) GS:ffff88841e800000(0000) knlGS:0000000000000000 +[ +0.000002] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ +0.000001] CR2: 00007f8ffa61ba50 CR3: 0000000106432000 CR4: 0000000000350ef0 +[ +0.000001] Call Trace: +[ +0.000001] +[ +0.000001] ? show_regs+0x72/0x90 +[ +0.000002] ? sysfs_remove_group+0x83/0x90 +[ +0.000002] ? __warn+0x8d/0x160 +[ +0.000001] ? sysfs_remove_group+0x83/0x90 +[ +0.000001] ? report_bug+0x1bb/0x1d0 +[ +0.000003] ? handle_bug+0x46/0x90 +[ +0.000001] ? exc_invalid_op+0x19/0x80 +[ +0.000002] ? asm_exc_invalid_op+0x1b/0x20 +[ +0.000003] ? sysfs_remove_group+0x83/0x90 +[ +0.000001] dpm_sysfs_remove+0x61/0x70 +[ +0.000002] device_del+0xa3/0x3d0 +[ +0.000002] ? ktime_get_mono_fast_ns+0x46/0xb0 +[ +0.000002] device_unregister+0x18/0x70 +[ +0.000001] i2c_del_adapter+0x26d/0x330 +[ +0.000002] arcturus_i2c_control_fini+0x25/0x50 [amdgpu] +[ +0.000236] smu_sw_fini+0x38/0x260 [amdgpu] +[ +0.000241] amdgpu_device_fini_sw+0x116/0x670 [amdgpu] +[ +0.000186] ? mutex_lock+0x13/0x50 +[ +0.000003] amdgpu_driver_release_kms+0x16/0x40 [amdgpu] +[ +0.000192] drm_minor_release+0x4f/0x80 [drm] +[ +0.000025] drm_release+0xfe/0x150 [drm] +[ +0.000027] __fput+0x9f/0x290 +[ +0.000002] ____fput+0xe/0x20 +[ +0.000002] task_work_run+0x61/0xa0 +[ +0.000002] exit_to_user_mode_prepare+0x150/0x170 +[ +0.000002] syscall_exit_to_user_mode+0x2a/0x50 + +Cc: Hawking Zhang +Cc: Luben Tuikov +Cc: Alex Deucher +Cc: Christian Koenig +Signed-off-by: Vitaly Prosyak +Reviewed-by: Luben Tuikov +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index 96a8fd0ca1df3..439ea256ed252 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -1192,7 +1192,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) + { + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); + +- sysfs_remove_file_from_group(&adev->dev->kobj, ++ if (adev->dev->kobj.sd) ++ sysfs_remove_file_from_group(&adev->dev->kobj, + &con->badpages_attr.attr, + RAS_FS_NAME); + } +@@ -1209,7 +1210,8 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct amdgpu_device *adev) + .attrs = attrs, + }; + +- sysfs_remove_group(&adev->dev->kobj, &group); ++ if (adev->dev->kobj.sd) ++ sysfs_remove_group(&adev->dev->kobj, &group); + + return 0; + } +@@ -1257,7 +1259,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev, + if (!obj || !obj->attr_inuse) + return -EINVAL; + +- sysfs_remove_file_from_group(&adev->dev->kobj, ++ if (adev->dev->kobj.sd) ++ sysfs_remove_file_from_group(&adev->dev->kobj, + &obj->sysfs_attr.attr, + RAS_FS_NAME); + obj->attr_inuse = 0; +-- +2.42.0 + diff --git a/queue-5.15/drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch b/queue-5.15/drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch new file mode 100644 index 00000000000..43a71af63a4 --- /dev/null +++ b/queue-5.15/drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch @@ -0,0 +1,37 @@ +From 5e736d71f38d1893d013eef5c89768e556ddb48e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 09:53:43 +0800 +Subject: drm/amdgpu/vkms: fix a possible null pointer dereference + +From: Ma Ke + +[ Upstream commit cd90511557fdfb394bb4ac4c3b539b007383914c ] + +In amdgpu_vkms_conn_get_modes(), the return value of drm_cvt_mode() +is assigned to mode, which will lead to a NULL pointer dereference +on failure of drm_cvt_mode(). Add a check to avoid null pointer +dereference. + +Signed-off-by: Ma Ke +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +index 4e8274de8fc0c..083f9c637a82e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +@@ -238,6 +238,8 @@ static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector) + + for (i = 0; i < ARRAY_SIZE(common_modes); i++) { + mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false); ++ if (!mode) ++ continue; + drm_mode_probed_add(connector, mode); + } + +-- +2.42.0 + diff --git a/queue-5.15/drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch b/queue-5.15/drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch new file mode 100644 index 00000000000..bfa6bd28953 --- /dev/null +++ b/queue-5.15/drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch @@ -0,0 +1,48 @@ +From e4db7cf6fee4bbd787b1f5226535bd08781e0c87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 11:20:28 -0500 +Subject: drm/amdkfd: Fix a race condition of vram buffer unref in svm code + +From: Xiaogang Chen + +[ Upstream commit 709c348261618da7ed89d6c303e2ceb9e453ba74 ] + +prange->svm_bo unref can happen in both mmu callback and a callback after +migrate to system ram. Both are async call in different tasks. Sync svm_bo +unref operation to avoid random "use-after-free". + +Signed-off-by: Xiaogang Chen +Reviewed-by: Philip Yang +Reviewed-by: Jesse Zhang +Tested-by: Jesse Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index 86135ca33e5be..5ffbf9ab643b8 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -550,8 +550,15 @@ svm_range_vram_node_new(struct amdgpu_device *adev, struct svm_range *prange, + + void svm_range_vram_node_free(struct svm_range *prange) + { +- svm_range_bo_unref(prange->svm_bo); +- prange->ttm_res = NULL; ++ /* serialize prange->svm_bo unref */ ++ mutex_lock(&prange->lock); ++ /* prange->svm_bo has not been unref */ ++ if (prange->ttm_res) { ++ prange->ttm_res = NULL; ++ mutex_unlock(&prange->lock); ++ svm_range_bo_unref(prange->svm_bo); ++ } else ++ mutex_unlock(&prange->lock); + } + + struct amdgpu_device * +-- +2.42.0 + diff --git a/queue-5.15/drm-amdkfd-fix-shift-out-of-bounds-issue.patch b/queue-5.15/drm-amdkfd-fix-shift-out-of-bounds-issue.patch new file mode 100644 index 00000000000..7fede802a0b --- /dev/null +++ b/queue-5.15/drm-amdkfd-fix-shift-out-of-bounds-issue.patch @@ -0,0 +1,60 @@ +From d551a0a273ce4145269db74c4ff4d02ba54343b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 09:43:51 +0800 +Subject: drm/amdkfd: Fix shift out-of-bounds issue + +From: Jesse Zhang + +[ Upstream commit 282c1d793076c2edac6c3db51b7e8ed2b41d60a5 ] + +[ 567.613292] shift exponent 255 is too large for 64-bit type 'long unsigned int' +[ 567.614498] CPU: 5 PID: 238 Comm: kworker/5:1 Tainted: G OE 6.2.0-34-generic #34~22.04.1-Ubuntu +[ 567.614502] Hardware name: AMD Splinter/Splinter-RPL, BIOS WS43927N_871 09/25/2023 +[ 567.614504] Workqueue: events send_exception_work_handler [amdgpu] +[ 567.614748] Call Trace: +[ 567.614750] +[ 567.614753] dump_stack_lvl+0x48/0x70 +[ 567.614761] dump_stack+0x10/0x20 +[ 567.614763] __ubsan_handle_shift_out_of_bounds+0x156/0x310 +[ 567.614769] ? srso_alias_return_thunk+0x5/0x7f +[ 567.614773] ? update_sd_lb_stats.constprop.0+0xf2/0x3c0 +[ 567.614780] svm_range_split_by_granularity.cold+0x2b/0x34 [amdgpu] +[ 567.615047] ? srso_alias_return_thunk+0x5/0x7f +[ 567.615052] svm_migrate_to_ram+0x185/0x4d0 [amdgpu] +[ 567.615286] do_swap_page+0x7b6/0xa30 +[ 567.615291] ? srso_alias_return_thunk+0x5/0x7f +[ 567.615294] ? __free_pages+0x119/0x130 +[ 567.615299] handle_pte_fault+0x227/0x280 +[ 567.615303] __handle_mm_fault+0x3c0/0x720 +[ 567.615311] handle_mm_fault+0x119/0x330 +[ 567.615314] ? lock_mm_and_find_vma+0x44/0x250 +[ 567.615318] do_user_addr_fault+0x1a9/0x640 +[ 567.615323] exc_page_fault+0x81/0x1b0 +[ 567.615328] asm_exc_page_fault+0x27/0x30 +[ 567.615332] RIP: 0010:__get_user_8+0x1c/0x30 + +Signed-off-by: Jesse Zhang +Suggested-by: Philip Yang +Reviewed-by: Yifan Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index 5ffbf9ab643b8..2cbe8ea16f24a 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -698,7 +698,7 @@ svm_range_apply_attrs(struct kfd_process *p, struct svm_range *prange, + prange->flags &= ~attrs[i].value; + break; + case KFD_IOCTL_SVM_ATTR_GRANULARITY: +- prange->granularity = attrs[i].value; ++ prange->granularity = min_t(uint32_t, attrs[i].value, 0x3F); + break; + default: + WARN_ONCE(1, "svm_range_check_attrs wasn't called?"); +-- +2.42.0 + diff --git a/queue-5.15/drm-komeda-drop-all-currently-held-locks-if-deadlock.patch b/queue-5.15/drm-komeda-drop-all-currently-held-locks-if-deadlock.patch new file mode 100644 index 00000000000..60aa86772f3 --- /dev/null +++ b/queue-5.15/drm-komeda-drop-all-currently-held-locks-if-deadlock.patch @@ -0,0 +1,184 @@ +From 4685cb29a7c1e14187c7ecf6986649dff8c37339 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Aug 2023 10:05:53 +0800 +Subject: drm/komeda: drop all currently held locks if deadlock happens + +From: baozhu.liu + +[ Upstream commit 19ecbe8325a2a7ffda5ff4790955b84eaccba49f ] + +If komeda_pipeline_unbound_components() returns -EDEADLK, +it means that a deadlock happened in the locking context. +Currently, komeda is not dealing with the deadlock properly,producing the +following output when CONFIG_DEBUG_WW_MUTEX_SLOWPATH is enabled: + + ------------[ cut here ]------------ +[ 26.103984] WARNING: CPU: 2 PID: 345 at drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c:1248 + komeda_release_unclaimed_resources+0x13c/0x170 +[ 26.117453] Modules linked in: +[ 26.120511] CPU: 2 PID: 345 Comm: composer@2.1-se Kdump: loaded Tainted: G W 5.10.110-SE-SDK1.8-dirty #16 +[ 26.131374] Hardware name: Siengine Se1000 Evaluation board (DT) +[ 26.137379] pstate: 20400009 (nzCv daif +PAN -UAO -TCO BTYPE=--) +[ 26.143385] pc : komeda_release_unclaimed_resources+0x13c/0x170 +[ 26.149301] lr : komeda_release_unclaimed_resources+0xbc/0x170 +[ 26.155130] sp : ffff800017b8b8d0 +[ 26.158442] pmr_save: 000000e0 +[ 26.161493] x29: ffff800017b8b8d0 x28: ffff000cf2f96200 +[ 26.166805] x27: ffff000c8f5a8800 x26: 0000000000000000 +[ 26.172116] x25: 0000000000000038 x24: ffff8000116a0140 +[ 26.177428] x23: 0000000000000038 x22: ffff000cf2f96200 +[ 26.182739] x21: ffff000cfc300300 x20: ffff000c8ab77080 +[ 26.188051] x19: 0000000000000003 x18: 0000000000000000 +[ 26.193362] x17: 0000000000000000 x16: 0000000000000000 +[ 26.198672] x15: b400e638f738ba38 x14: 0000000000000000 +[ 26.203983] x13: 0000000106400a00 x12: 0000000000000000 +[ 26.209294] x11: 0000000000000000 x10: 0000000000000000 +[ 26.214604] x9 : ffff800012f80000 x8 : ffff000ca3308000 +[ 26.219915] x7 : 0000000ff3000000 x6 : ffff80001084034c +[ 26.225226] x5 : ffff800017b8bc40 x4 : 000000000000000f +[ 26.230536] x3 : ffff000ca3308000 x2 : 0000000000000000 +[ 26.235847] x1 : 0000000000000000 x0 : ffffffffffffffdd +[ 26.241158] Call trace: +[ 26.243604] komeda_release_unclaimed_resources+0x13c/0x170 +[ 26.249175] komeda_crtc_atomic_check+0x68/0xf0 +[ 26.253706] drm_atomic_helper_check_planes+0x138/0x1f4 +[ 26.258929] komeda_kms_check+0x284/0x36c +[ 26.262939] drm_atomic_check_only+0x40c/0x714 +[ 26.267381] drm_atomic_nonblocking_commit+0x1c/0x60 +[ 26.272344] drm_mode_atomic_ioctl+0xa3c/0xb8c +[ 26.276787] drm_ioctl_kernel+0xc4/0x120 +[ 26.280708] drm_ioctl+0x268/0x534 +[ 26.284109] __arm64_sys_ioctl+0xa8/0xf0 +[ 26.288030] el0_svc_common.constprop.0+0x80/0x240 +[ 26.292817] do_el0_svc+0x24/0x90 +[ 26.296132] el0_svc+0x20/0x30 +[ 26.299185] el0_sync_handler+0xe8/0xf0 +[ 26.303018] el0_sync+0x1a4/0x1c0 +[ 26.306330] irq event stamp: 0 +[ 26.309384] hardirqs last enabled at (0): [<0000000000000000>] 0x0 +[ 26.315650] hardirqs last disabled at (0): [] copy_process+0x5d0/0x183c +[ 26.323825] softirqs last enabled at (0): [] copy_process+0x5d0/0x183c +[ 26.331997] softirqs last disabled at (0): [<0000000000000000>] 0x0 +[ 26.338261] ---[ end trace 20ae984fa860184a ]--- +[ 26.343021] ------------[ cut here ]------------ +[ 26.347646] WARNING: CPU: 3 PID: 345 at drivers/gpu/drm/drm_modeset_lock.c:228 drm_modeset_drop_locks+0x84/0x90 +[ 26.357727] Modules linked in: +[ 26.360783] CPU: 3 PID: 345 Comm: composer@2.1-se Kdump: loaded Tainted: G W 5.10.110-SE-SDK1.8-dirty #16 +[ 26.371645] Hardware name: Siengine Se1000 Evaluation board (DT) +[ 26.377647] pstate: 20400009 (nzCv daif +PAN -UAO -TCO BTYPE=--) +[ 26.383649] pc : drm_modeset_drop_locks+0x84/0x90 +[ 26.388351] lr : drm_mode_atomic_ioctl+0x860/0xb8c +[ 26.393137] sp : ffff800017b8bb10 +[ 26.396447] pmr_save: 000000e0 +[ 26.399497] x29: ffff800017b8bb10 x28: 0000000000000001 +[ 26.404807] x27: 0000000000000038 x26: 0000000000000002 +[ 26.410115] x25: ffff000cecbefa00 x24: ffff000cf2f96200 +[ 26.415423] x23: 0000000000000001 x22: 0000000000000018 +[ 26.420731] x21: 0000000000000001 x20: ffff800017b8bc10 +[ 26.426039] x19: 0000000000000000 x18: 0000000000000000 +[ 26.431347] x17: 0000000002e8bf2c x16: 0000000002e94c6b +[ 26.436655] x15: 0000000002ea48b9 x14: ffff8000121f0300 +[ 26.441963] x13: 0000000002ee2ca8 x12: ffff80001129cae0 +[ 26.447272] x11: ffff800012435000 x10: ffff000ed46b5e88 +[ 26.452580] x9 : ffff000c9935e600 x8 : 0000000000000000 +[ 26.457888] x7 : 000000008020001e x6 : 000000008020001f +[ 26.463196] x5 : ffff80001085fbe0 x4 : fffffe0033a59f20 +[ 26.468504] x3 : 000000008020001e x2 : 0000000000000000 +[ 26.473813] x1 : 0000000000000000 x0 : ffff000c8f596090 +[ 26.479122] Call trace: +[ 26.481566] drm_modeset_drop_locks+0x84/0x90 +[ 26.485918] drm_mode_atomic_ioctl+0x860/0xb8c +[ 26.490359] drm_ioctl_kernel+0xc4/0x120 +[ 26.494278] drm_ioctl+0x268/0x534 +[ 26.497677] __arm64_sys_ioctl+0xa8/0xf0 +[ 26.501598] el0_svc_common.constprop.0+0x80/0x240 +[ 26.506384] do_el0_svc+0x24/0x90 +[ 26.509697] el0_svc+0x20/0x30 +[ 26.512748] el0_sync_handler+0xe8/0xf0 +[ 26.516580] el0_sync+0x1a4/0x1c0 +[ 26.519891] irq event stamp: 0 +[ 26.522943] hardirqs last enabled at (0): [<0000000000000000>] 0x0 +[ 26.529207] hardirqs last disabled at (0): [] copy_process+0x5d0/0x183c +[ 26.537379] softirqs last enabled at (0): [] copy_process+0x5d0/0x183c +[ 26.545550] softirqs last disabled at (0): [<0000000000000000>] 0x0 +[ 26.551812] ---[ end trace 20ae984fa860184b ]--- + +According to the call trace information,it can be located to be +WARN_ON(IS_ERR(c_st)) in the komeda_pipeline_unbound_components function; +Then follow the function. +komeda_pipeline_unbound_components +-> komeda_component_get_state_and_set_user + -> komeda_pipeline_get_state_and_set_crtc + -> komeda_pipeline_get_state + ->drm_atomic_get_private_obj_state + -> drm_atomic_get_private_obj_state + -> drm_modeset_lock + +komeda_pipeline_unbound_components +-> komeda_component_get_state_and_set_user + -> komeda_component_get_state + -> drm_atomic_get_private_obj_state + -> drm_modeset_lock + +ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); if (ret) + return ERR_PTR(ret); +Here it return -EDEADLK. + +deal with the deadlock as suggested by [1], using the +function drm_modeset_backoff(). +[1] https://docs.kernel.org/gpu/drm-kms.html?highlight=kms#kms-locking + +Therefore, handling this problem can be solved +by adding return -EDEADLK back to the drm_modeset_backoff processing flow +in the drm_mode_atomic_ioctl function. + +Signed-off-by: baozhu.liu +Signed-off-by: menghui.huang +Reviewed-by: Liviu Dudau +Signed-off-by: Liviu Dudau +Link: https://patchwork.freedesktop.org/patch/msgid/20230804013117.6870-1-menghui.huang@siengine.com +Signed-off-by: Sasha Levin +--- + .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +index e672b9cffee3c..88b58153f9d66 100644 +--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c ++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +@@ -1223,7 +1223,7 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, + return 0; + } + +-static void ++static int + komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, + struct komeda_pipeline_state *new) + { +@@ -1243,8 +1243,12 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, + c = komeda_pipeline_get_component(pipe, id); + c_st = komeda_component_get_state_and_set_user(c, + drm_st, NULL, new->crtc); ++ if (PTR_ERR(c_st) == -EDEADLK) ++ return -EDEADLK; + WARN_ON(IS_ERR(c_st)); + } ++ ++ return 0; + } + + /* release unclaimed pipeline resource */ +@@ -1266,9 +1270,8 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, + if (WARN_ON(IS_ERR_OR_NULL(st))) + return -EINVAL; + +- komeda_pipeline_unbound_components(pipe, st); ++ return komeda_pipeline_unbound_components(pipe, st); + +- return 0; + } + + /* Since standalong disabled components must be disabled separately and in the +-- +2.42.0 + diff --git a/queue-5.15/drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch b/queue-5.15/drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch new file mode 100644 index 00000000000..8822b7446c4 --- /dev/null +++ b/queue-5.15/drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch @@ -0,0 +1,79 @@ +From acbc4f5d20defb46b0edc956826ac657903418d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 17:20:34 +0300 +Subject: drm/msm/dp: skip validity check for DP CTS EDID checksum + +From: Jani Nikula + +[ Upstream commit a251c9d8e30833b260101edb9383b176ee2b7cb1 ] + +The DP CTS test for EDID last block checksum expects the checksum for +the last block, invalid or not. Skip the validity check. + +For the most part (*), the EDIDs returned by drm_get_edid() will be +valid anyway, and there's the CTS workaround to get the checksum for +completely invalid EDIDs. See commit 7948fe12d47a ("drm/msm/dp: return +correct edid checksum after corrupted edid checksum read"). + +This lets us remove one user of drm_edid_block_valid() with hopes the +function can be removed altogether in the future. + +(*) drm_get_edid() ignores checksum errors on CTA extensions. + +Cc: Abhinav Kumar +Cc: Dmitry Baryshkov +Cc: Kuogee Hsieh +Cc: Marijn Suijten +Cc: Rob Clark +Cc: Sean Paul +Cc: Stephen Boyd +Cc: linux-arm-msm@vger.kernel.org +Cc: freedreno@lists.freedesktop.org +Signed-off-by: Jani Nikula +Reviewed-by: Stephen Boyd +Reviewed-by: Abhinav Kumar +Reviewed-by: Kuogee Hsieh +Patchwork: https://patchwork.freedesktop.org/patch/555361/ +Link: https://lore.kernel.org/r/20230901142034.580802-1-jani.nikula@intel.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dp/dp_panel.c | 21 ++------------------- + 1 file changed, 2 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c +index 62b742e701d2c..f9d31069f4848 100644 +--- a/drivers/gpu/drm/msm/dp/dp_panel.c ++++ b/drivers/gpu/drm/msm/dp/dp_panel.c +@@ -263,26 +263,9 @@ int dp_panel_get_modes(struct dp_panel *dp_panel, + + static u8 dp_panel_get_edid_checksum(struct edid *edid) + { +- struct edid *last_block; +- u8 *raw_edid; +- bool is_edid_corrupt = false; ++ edid += edid->extensions; + +- if (!edid) { +- DRM_ERROR("invalid edid input\n"); +- return 0; +- } +- +- raw_edid = (u8 *)edid; +- raw_edid += (edid->extensions * EDID_LENGTH); +- last_block = (struct edid *)raw_edid; +- +- /* block type extension */ +- drm_edid_block_valid(raw_edid, 1, false, &is_edid_corrupt); +- if (!is_edid_corrupt) +- return last_block->checksum; +- +- DRM_ERROR("Invalid block, no checksum\n"); +- return 0; ++ return edid->checksum; + } + + void dp_panel_handle_sink_request(struct dp_panel *dp_panel) +-- +2.42.0 + diff --git a/queue-5.15/drm-panel-fix-a-possible-null-pointer-dereference.patch b/queue-5.15/drm-panel-fix-a-possible-null-pointer-dereference.patch new file mode 100644 index 00000000000..c592818b2e3 --- /dev/null +++ b/queue-5.15/drm-panel-fix-a-possible-null-pointer-dereference.patch @@ -0,0 +1,39 @@ +From 426fb2fea7a7126fff1a1b2bfedea460a3d7aa70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 11:31:05 +0800 +Subject: drm/panel: fix a possible null pointer dereference + +From: Ma Ke + +[ Upstream commit 924e5814d1f84e6fa5cb19c6eceb69f066225229 ] + +In versatile_panel_get_modes(), the return value of drm_mode_duplicate() +is assigned to mode, which will lead to a NULL pointer dereference +on failure of drm_mode_duplicate(). Add a check to avoid npd. + +Signed-off-by: Ma Ke +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20231007033105.3997998-1-make_ruc2021@163.com +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20231007033105.3997998-1-make_ruc2021@163.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-arm-versatile.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/panel/panel-arm-versatile.c b/drivers/gpu/drm/panel/panel-arm-versatile.c +index abb0788843c60..503ecea72c5ea 100644 +--- a/drivers/gpu/drm/panel/panel-arm-versatile.c ++++ b/drivers/gpu/drm/panel/panel-arm-versatile.c +@@ -267,6 +267,8 @@ static int versatile_panel_get_modes(struct drm_panel *panel, + connector->display_info.bus_flags = vpanel->panel_type->bus_flags; + + mode = drm_mode_duplicate(connector->dev, &vpanel->panel_type->mode); ++ if (!mode) ++ return -ENOMEM; + drm_mode_set_name(mode); + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + +-- +2.42.0 + diff --git a/queue-5.15/drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch b/queue-5.15/drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch new file mode 100644 index 00000000000..ab11c5c5ce2 --- /dev/null +++ b/queue-5.15/drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch @@ -0,0 +1,39 @@ +From 4eae05efba7c77eb9e60b2f96f363cf844075e4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 17:04:46 +0800 +Subject: drm/panel/panel-tpo-tpg110: fix a possible null pointer dereference + +From: Ma Ke + +[ Upstream commit f22def5970c423ea7f87d5247bd0ef91416b0658 ] + +In tpg110_get_modes(), the return value of drm_mode_duplicate() is +assigned to mode, which will lead to a NULL pointer dereference on +failure of drm_mode_duplicate(). Add a check to avoid npd. + +Signed-off-by: Ma Ke +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20231009090446.4043798-1-make_ruc2021@163.com +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20231009090446.4043798-1-make_ruc2021@163.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-tpo-tpg110.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/panel/panel-tpo-tpg110.c b/drivers/gpu/drm/panel/panel-tpo-tpg110.c +index e3791dad6830c..3360e7ccb0a7d 100644 +--- a/drivers/gpu/drm/panel/panel-tpo-tpg110.c ++++ b/drivers/gpu/drm/panel/panel-tpo-tpg110.c +@@ -379,6 +379,8 @@ static int tpg110_get_modes(struct drm_panel *panel, + connector->display_info.bus_flags = tpg->panel_mode->bus_flags; + + mode = drm_mode_duplicate(connector->dev, &tpg->panel_mode->mode); ++ if (!mode) ++ return -ENOMEM; + drm_mode_set_name(mode); + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + +-- +2.42.0 + diff --git a/queue-5.15/drm-panel-st7703-pick-different-reset-sequence.patch b/queue-5.15/drm-panel-st7703-pick-different-reset-sequence.patch new file mode 100644 index 00000000000..672d4f1d92c --- /dev/null +++ b/queue-5.15/drm-panel-st7703-pick-different-reset-sequence.patch @@ -0,0 +1,86 @@ +From 145a8c7e6563e5656597ae02750903ac61521b74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 11 Feb 2023 18:17:48 +0100 +Subject: drm/panel: st7703: Pick different reset sequence +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ondrej Jirman + +[ Upstream commit d12d635bb03c7cb4830acb641eb176ee9ff2aa89 ] + +Switching to a different reset sequence, enabling IOVCC before enabling +VCC. + +There also needs to be a delay after enabling the supplies and before +deasserting the reset. The datasheet specifies 1ms after the supplies +reach the required voltage. Use 10-20ms to also give the power supplies +some time to reach the required voltage, too. + +This fixes intermittent panel initialization failures and screen +corruption during resume from sleep on panel xingbangda,xbd599 (e.g. +used in PinePhone). + +Signed-off-by: Ondrej Jirman +Signed-off-by: Frank Oltmanns +Reported-by: Samuel Holland +Reviewed-by: Guido Günther +Tested-by: Guido Günther +Signed-off-by: Guido Günther +Link: https://patchwork.freedesktop.org/patch/msgid/20230211171748.36692-2-frank@oltmanns.dev +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-sitronix-st7703.c | 25 ++++++++++--------- + 1 file changed, 13 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c +index a2c303e5732c0..f50cc70e6337c 100644 +--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c ++++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c +@@ -428,29 +428,30 @@ static int st7703_prepare(struct drm_panel *panel) + return 0; + + dev_dbg(ctx->dev, "Resetting the panel\n"); +- ret = regulator_enable(ctx->vcc); ++ gpiod_set_value_cansleep(ctx->reset_gpio, 1); ++ ++ ret = regulator_enable(ctx->iovcc); + if (ret < 0) { +- dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); ++ dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); + return ret; + } +- ret = regulator_enable(ctx->iovcc); ++ ++ ret = regulator_enable(ctx->vcc); + if (ret < 0) { +- dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); +- goto disable_vcc; ++ dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); ++ regulator_disable(ctx->iovcc); ++ return ret; + } + +- gpiod_set_value_cansleep(ctx->reset_gpio, 1); +- usleep_range(20, 40); ++ /* Give power supplies time to stabilize before deasserting reset. */ ++ usleep_range(10000, 20000); ++ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); +- msleep(20); ++ usleep_range(15000, 20000); + + ctx->prepared = true; + + return 0; +- +-disable_vcc: +- regulator_disable(ctx->vcc); +- return ret; + } + + static int st7703_get_modes(struct drm_panel *panel, +-- +2.42.0 + diff --git a/queue-5.15/drm-qxl-prevent-memory-leak.patch b/queue-5.15/drm-qxl-prevent-memory-leak.patch new file mode 100644 index 00000000000..422ac41abcd --- /dev/null +++ b/queue-5.15/drm-qxl-prevent-memory-leak.patch @@ -0,0 +1,41 @@ +From b5e327780d56903165ba44e43b0c1b6a74a686da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Aug 2023 10:53:09 +0800 +Subject: drm/qxl: prevent memory leak + +From: Zongmin Zhou + +[ Upstream commit 0e8b9f258baed25f1c5672613699247c76b007b5 ] + +The allocated memory for qdev->dumb_heads should be released +in qxl_destroy_monitors_object before qxl suspend. +otherwise,qxl_create_monitors_object will be called to +reallocate memory for qdev->dumb_heads after qxl resume, +it will cause memory leak. + +Signed-off-by: Zongmin Zhou +Link: https://lore.kernel.org/r/20230801025309.4049813-1-zhouzongmin@kylinos.cn +Reviewed-by: Dave Airlie +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/qxl/qxl_display.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c +index 9e0a1e8360117..dc04412784a0d 100644 +--- a/drivers/gpu/drm/qxl/qxl_display.c ++++ b/drivers/gpu/drm/qxl/qxl_display.c +@@ -1221,6 +1221,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev) + if (!qdev->monitors_config_bo) + return 0; + ++ kfree(qdev->dumb_heads); ++ qdev->dumb_heads = NULL; ++ + qdev->monitors_config = NULL; + qdev->ram_header->monitors_config = 0; + +-- +2.42.0 + diff --git a/queue-5.15/drm-vmwgfx_surface.c-copy-user-array-safely.patch b/queue-5.15/drm-vmwgfx_surface.c-copy-user-array-safely.patch new file mode 100644 index 00000000000..668dd82d1d3 --- /dev/null +++ b/queue-5.15/drm-vmwgfx_surface.c-copy-user-array-safely.patch @@ -0,0 +1,44 @@ +From 4e6d9928f8b439ebaa2b57e3889cd16dfc4822e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:13 +0200 +Subject: drm: vmwgfx_surface.c: copy user-array safely + +From: Philipp Stanner + +[ Upstream commit 06ab64a0d836ac430c5f94669710a78aa43942cb ] + +Currently, there is no overflow-check with memdup_user(). + +Use the new function memdup_array_user() instead of memdup_user() for +duplicating the user-space array safely. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-7-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index 5d53a5f9d1237..872af7d4b3fc9 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -807,9 +807,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, + metadata->num_sizes = num_sizes; + user_srf->size = size; + metadata->sizes = +- memdup_user((struct drm_vmw_size __user *)(unsigned long) ++ memdup_array_user((struct drm_vmw_size __user *)(unsigned long) + req->size_addr, +- sizeof(*metadata->sizes) * metadata->num_sizes); ++ metadata->num_sizes, sizeof(*metadata->sizes)); + if (IS_ERR(metadata->sizes)) { + ret = PTR_ERR(metadata->sizes); + goto out_no_sizes; +-- +2.42.0 + diff --git a/queue-5.15/exfat-support-handle-zero-size-directory.patch b/queue-5.15/exfat-support-handle-zero-size-directory.patch new file mode 100644 index 00000000000..523017b7a54 --- /dev/null +++ b/queue-5.15/exfat-support-handle-zero-size-directory.patch @@ -0,0 +1,103 @@ +From 42622fd08589488a7afec78465de03ec47684c70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jul 2023 14:23:08 +0800 +Subject: exfat: support handle zero-size directory + +From: Yuezhang Mo + +[ Upstream commit dab48b8f2fe7264d51ec9eed0adea0fe3c78830a ] + +After repairing a corrupted file system with exfatprogs' fsck.exfat, +zero-size directories may result. It is also possible to create +zero-size directories in other exFAT implementation, such as Paragon +ufsd dirver. + +As described in the specification, the lower directory size limits +is 0 bytes. + +Without this commit, sub-directories and files cannot be created +under a zero-size directory, and it cannot be removed. + +Signed-off-by: Yuezhang Mo +Reviewed-by: Andy Wu +Reviewed-by: Aoyama Wataru +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/namei.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c +index b22d6c984f8c7..cfa46d8cf5b39 100644 +--- a/fs/exfat/namei.c ++++ b/fs/exfat/namei.c +@@ -330,14 +330,20 @@ static int exfat_find_empty_entry(struct inode *inode, + if (exfat_check_max_dentries(inode)) + return -ENOSPC; + +- /* we trust p_dir->size regardless of FAT type */ +- if (exfat_find_last_cluster(sb, p_dir, &last_clu)) +- return -EIO; +- + /* + * Allocate new cluster to this directory + */ +- exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags); ++ if (ei->start_clu != EXFAT_EOF_CLUSTER) { ++ /* we trust p_dir->size regardless of FAT type */ ++ if (exfat_find_last_cluster(sb, p_dir, &last_clu)) ++ return -EIO; ++ ++ exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags); ++ } else { ++ /* This directory is empty */ ++ exfat_chain_set(&clu, EXFAT_EOF_CLUSTER, 0, ++ ALLOC_NO_FAT_CHAIN); ++ } + + /* allocate a cluster */ + ret = exfat_alloc_cluster(inode, 1, &clu, IS_DIRSYNC(inode)); +@@ -347,6 +353,11 @@ static int exfat_find_empty_entry(struct inode *inode, + if (exfat_zeroed_cluster(inode, clu.dir)) + return -EIO; + ++ if (ei->start_clu == EXFAT_EOF_CLUSTER) { ++ ei->start_clu = clu.dir; ++ p_dir->dir = clu.dir; ++ } ++ + /* append to the FAT chain */ + if (clu.flags != p_dir->flags) { + /* no-fat-chain bit is disabled, +@@ -644,7 +655,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, + info->type = exfat_get_entry_type(ep); + info->attr = le16_to_cpu(ep->dentry.file.attr); + info->size = le64_to_cpu(ep2->dentry.stream.valid_size); +- if ((info->type == TYPE_FILE) && (info->size == 0)) { ++ if (info->size == 0) { + info->flags = ALLOC_NO_FAT_CHAIN; + info->start_clu = EXFAT_EOF_CLUSTER; + } else { +@@ -891,6 +902,9 @@ static int exfat_check_dir_empty(struct super_block *sb, + + dentries_per_clu = sbi->dentries_per_clu; + ++ if (p_dir->dir == EXFAT_EOF_CLUSTER) ++ return 0; ++ + exfat_chain_dup(&clu, p_dir); + + while (clu.dir != EXFAT_EOF_CLUSTER) { +@@ -1274,7 +1288,8 @@ static int __exfat_rename(struct inode *old_parent_inode, + } + + /* Free the clusters if new_inode is a dir(as if exfat_rmdir) */ +- if (new_entry_type == TYPE_DIR) { ++ if (new_entry_type == TYPE_DIR && ++ new_ei->start_clu != EXFAT_EOF_CLUSTER) { + /* new_ei, new_clu_to_free */ + struct exfat_chain new_clu_to_free; + +-- +2.42.0 + diff --git a/queue-5.15/fs-jfs-add-check-for-negative-db_l2nbperpage.patch b/queue-5.15/fs-jfs-add-check-for-negative-db_l2nbperpage.patch new file mode 100644 index 00000000000..487ef4ba51e --- /dev/null +++ b/queue-5.15/fs-jfs-add-check-for-negative-db_l2nbperpage.patch @@ -0,0 +1,46 @@ +From 6e51303e85c6d675e8bc83d9ae9235e6fc90b7e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 17:56:58 +0800 +Subject: fs/jfs: Add check for negative db_l2nbperpage + +From: Juntong Deng + +[ Upstream commit 525b861a008143048535011f3816d407940f4bfa ] + +l2nbperpage is log2(number of blks per page), and the minimum legal +value should be 0, not negative. + +In the case of l2nbperpage being negative, an error will occur +when subsequently used as shift exponent. + +Syzbot reported this bug: + +UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:799:12 +shift exponent -16777216 is negative + +Reported-by: syzbot+debee9ab7ae2b34b0307@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=debee9ab7ae2b34b0307 +Signed-off-by: Juntong Deng +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_dmap.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index da4f9c3b714fe..a700950429c5f 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -180,7 +180,8 @@ int dbMount(struct inode *ipbmap) + bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); + + bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); +- if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) { ++ if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE || ++ bmp->db_l2nbperpage < 0) { + err = -EINVAL; + goto err_release_metapage; + } +-- +2.42.0 + diff --git a/queue-5.15/fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch b/queue-5.15/fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch new file mode 100644 index 00000000000..5195dba5b5d --- /dev/null +++ b/queue-5.15/fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch @@ -0,0 +1,50 @@ +From 8a45d3c9feaf9f187c402ee93646b5cd055989ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 02:06:41 +0800 +Subject: fs/jfs: Add validity check for db_maxag and db_agpref + +From: Juntong Deng + +[ Upstream commit 64933ab7b04881c6c18b21ff206c12278341c72e ] + +Both db_maxag and db_agpref are used as the index of the +db_agfree array, but there is currently no validity check for +db_maxag and db_agpref, which can lead to errors. + +The following is related bug reported by Syzbot: + +UBSAN: array-index-out-of-bounds in fs/jfs/jfs_dmap.c:639:20 +index 7936 is out of range for type 'atomic_t[128]' + +Add checking that the values of db_maxag and db_agpref are valid +indexes for the db_agfree array. + +Reported-by: syzbot+38e876a8aa44b7115c76@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=38e876a8aa44b7115c76 +Signed-off-by: Juntong Deng +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_dmap.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index a700950429c5f..217a673b751ef 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -195,6 +195,12 @@ int dbMount(struct inode *ipbmap) + bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel); + bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); + bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); ++ if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 || ++ bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) { ++ err = -EINVAL; ++ goto err_release_metapage; ++ } ++ + bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); + bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight); + bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); +-- +2.42.0 + diff --git a/queue-5.15/gfs2-fix-an-oops-in-gfs2_permission.patch b/queue-5.15/gfs2-fix-an-oops-in-gfs2_permission.patch new file mode 100644 index 00000000000..56671d09a78 --- /dev/null +++ b/queue-5.15/gfs2-fix-an-oops-in-gfs2_permission.patch @@ -0,0 +1,67 @@ +From 31854e05a9f2aca3e62f210376488a15a67959d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 03:33:44 +0100 +Subject: gfs2: fix an oops in gfs2_permission + +From: Al Viro + +[ Upstream commit 0abd1557e21c617bd13fc18f7725fc6363c05913 ] + +In RCU mode, we might race with gfs2_evict_inode(), which zeroes +->i_gl. Freeing of the object it points to is RCU-delayed, so +if we manage to fetch the pointer before it's been replaced with +NULL, we are fine. Check if we'd fetched NULL and treat that +as "bail out and tell the caller to get out of RCU mode". + +Signed-off-by: Al Viro +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/inode.c | 11 +++++++++-- + fs/gfs2/super.c | 2 +- + 2 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index 97ee17843b4d0..682418d9c8e72 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1850,14 +1850,21 @@ int gfs2_permission(struct user_namespace *mnt_userns, struct inode *inode, + { + struct gfs2_inode *ip; + struct gfs2_holder i_gh; ++ struct gfs2_glock *gl; + int error; + + gfs2_holder_mark_uninitialized(&i_gh); + ip = GFS2_I(inode); +- if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { ++ gl = rcu_dereference(ip->i_gl); ++ if (unlikely(!gl)) { ++ /* inode is getting torn down, must be RCU mode */ ++ WARN_ON_ONCE(!(mask & MAY_NOT_BLOCK)); ++ return -ECHILD; ++ } ++ if (gfs2_glock_is_locked_by_me(gl) == NULL) { + if (mask & MAY_NOT_BLOCK) + return -ECHILD; +- error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); ++ error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return error; + } +diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c +index 51b44da4a0d64..268651ac9fc84 100644 +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -1436,7 +1436,7 @@ static void gfs2_evict_inode(struct inode *inode) + wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE); + gfs2_glock_add_to_lru(ip->i_gl); + gfs2_glock_put_eventually(ip->i_gl); +- ip->i_gl = NULL; ++ rcu_assign_pointer(ip->i_gl, NULL); + } + } + +-- +2.42.0 + diff --git a/queue-5.15/gfs2-ignore-negated-quota-changes.patch b/queue-5.15/gfs2-ignore-negated-quota-changes.patch new file mode 100644 index 00000000000..a440717ab23 --- /dev/null +++ b/queue-5.15/gfs2-ignore-negated-quota-changes.patch @@ -0,0 +1,91 @@ +From 95db4083e51b3169099d4adcf3a1d222fc80f5c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:46:43 -0500 +Subject: gfs2: ignore negated quota changes + +From: Bob Peterson + +[ Upstream commit 4c6a08125f2249531ec01783a5f4317d7342add5 ] + +When lots of quota changes are made, there may be cases in which an +inode's quota information is increased and then decreased, such as when +blocks are added to a file, then deleted from it. If the timing is +right, function do_qc can add pending quota changes to a transaction, +then later, another call to do_qc can negate those changes, resulting +in a net gain of 0. The quota_change information is recorded in the qc +buffer (and qd element of the inode as well). The buffer is added to the +transaction by the first call to do_qc, but a subsequent call changes +the value from non-zero back to zero. At that point it's too late to +remove the buffer_head from the transaction. Later, when the quota sync +code is called, the zero-change qd element is discovered and flagged as +an assert warning. If the fs is mounted with errors=panic, the kernel +will panic. + +This is usually seen when files are truncated and the quota changes are +negated by punch_hole/truncate which uses gfs2_quota_hold and +gfs2_quota_unhold rather than block allocations that use gfs2_quota_lock +and gfs2_quota_unlock which automatically do quota sync. + +This patch solves the problem by adding a check to qd_check_sync such +that net-zero quota changes already added to the transaction are no +longer deemed necessary to be synced, and skipped. + +In this case references are taken for the qd and the slot from do_qc +so those need to be put. The normal sequence of events for a normal +non-zero quota change is as follows: + +gfs2_quota_change + do_qc + qd_hold + slot_hold + +Later, when the changes are to be synced: + +gfs2_quota_sync + qd_fish + qd_check_sync + gets qd ref via lockref_get_not_dead + do_sync + do_qc(QC_SYNC) + qd_put + lockref_put_or_lock + qd_unlock + qd_put + lockref_put_or_lock + +In the net-zero change case, we add a check to qd_check_sync so it puts +the qd and slot references acquired in gfs2_quota_change and skip the +unneeded sync. + +Signed-off-by: Bob Peterson +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/quota.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c +index dc77080a82bbf..c381580095baf 100644 +--- a/fs/gfs2/quota.c ++++ b/fs/gfs2/quota.c +@@ -431,6 +431,17 @@ static int qd_check_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd, + (sync_gen && (qd->qd_sync_gen >= *sync_gen))) + return 0; + ++ /* ++ * If qd_change is 0 it means a pending quota change was negated. ++ * We should not sync it, but we still have a qd reference and slot ++ * reference taken by gfs2_quota_change -> do_qc that need to be put. ++ */ ++ if (!qd->qd_change && test_and_clear_bit(QDF_CHANGE, &qd->qd_flags)) { ++ slot_put(qd); ++ qd_put(qd); ++ return 0; ++ } ++ + if (!lockref_get_not_dead(&qd->qd_lockref)) + return 0; + +-- +2.42.0 + diff --git a/queue-5.15/gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch b/queue-5.15/gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch new file mode 100644 index 00000000000..4ce23f01930 --- /dev/null +++ b/queue-5.15/gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch @@ -0,0 +1,59 @@ +From ee73eb8bf55ba15807e915aa22a56958288b7a7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 22:06:05 +0100 +Subject: gfs2: Silence "suspicious RCU usage in gfs2_permission" warning + +From: Andreas Gruenbacher + +[ Upstream commit 074d7306a4fe22fcac0b53f699f92757ab1cee99 ] + +Commit 0abd1557e21c added rcu_dereference() for dereferencing ip->i_gl +in gfs2_permission. This now causes lockdep to complain when +gfs2_permission is called in non-RCU context: + + WARNING: suspicious RCU usage in gfs2_permission + +Switch to rcu_dereference_check() and check for the MAY_NOT_BLOCK flag +to shut up lockdep when we know that dereferencing ip->i_gl is safe. + +Fixes: 0abd1557e21c ("gfs2: fix an oops in gfs2_permission") +Reported-by: syzbot+3e5130844b0c0e2b4948@syzkaller.appspotmail.com +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/inode.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index 682418d9c8e72..462e957eda8be 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1848,6 +1848,7 @@ static const char *gfs2_get_link(struct dentry *dentry, + int gfs2_permission(struct user_namespace *mnt_userns, struct inode *inode, + int mask) + { ++ int may_not_block = mask & MAY_NOT_BLOCK; + struct gfs2_inode *ip; + struct gfs2_holder i_gh; + struct gfs2_glock *gl; +@@ -1855,14 +1856,14 @@ int gfs2_permission(struct user_namespace *mnt_userns, struct inode *inode, + + gfs2_holder_mark_uninitialized(&i_gh); + ip = GFS2_I(inode); +- gl = rcu_dereference(ip->i_gl); ++ gl = rcu_dereference_check(ip->i_gl, !may_not_block); + if (unlikely(!gl)) { + /* inode is getting torn down, must be RCU mode */ +- WARN_ON_ONCE(!(mask & MAY_NOT_BLOCK)); ++ WARN_ON_ONCE(!may_not_block); + return -ECHILD; + } + if (gfs2_glock_is_locked_by_me(gl) == NULL) { +- if (mask & MAY_NOT_BLOCK) ++ if (may_not_block) + return -ECHILD; + error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) +-- +2.42.0 + diff --git a/queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch b/queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch new file mode 100644 index 00000000000..58d4dd1ace7 --- /dev/null +++ b/queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch @@ -0,0 +1,54 @@ +From 648511402a487ae3bc6b1ddcb752a4c959ee7db4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Apr 2022 15:18:39 +0100 +Subject: gpio: Add helpers to ease the transition towards immutable irq_chip + +From: Marc Zyngier + +[ Upstream commit 36b78aae4bfee749bbde73be570796bfd0f56bec ] + +Add a couple of new helpers to make it slightly simpler to convert +drivers to immutable irq_chip structures: + +- GPIOCHIP_IRQ_RESOURCE_HELPERS populates the irq_chip structure + with the resource management callbacks + +- gpio_irq_chip_set_chip() populates the gpio_irq_chip.chip + structure, avoiding the proliferation of ugly casts + +Reviewed-by: Andy Shevchenko +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20220419141846.598305-4-maz@kernel.org +Stable-dep-of: dc3115e6c5d9 ("hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip") +Signed-off-by: Sasha Levin +--- + include/linux/gpio/driver.h | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h +index b241fc23ff3a2..91f60d1e3eb31 100644 +--- a/include/linux/gpio/driver.h ++++ b/include/linux/gpio/driver.h +@@ -599,6 +599,18 @@ void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset); + int gpiochip_irq_reqres(struct irq_data *data); + void gpiochip_irq_relres(struct irq_data *data); + ++/* Paste this in your irq_chip structure */ ++#define GPIOCHIP_IRQ_RESOURCE_HELPERS \ ++ .irq_request_resources = gpiochip_irq_reqres, \ ++ .irq_release_resources = gpiochip_irq_relres ++ ++static inline void gpio_irq_chip_set_chip(struct gpio_irq_chip *girq, ++ const struct irq_chip *chip) ++{ ++ /* Yes, dropping const is ugly, but it isn't like we have a choice */ ++ girq->chip = (struct irq_chip *)chip; ++} ++ + /* Line status inquiry for drivers */ + bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset); + bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset); +-- +2.42.0 + diff --git a/queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch b/queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch new file mode 100644 index 00000000000..fe4a568691c --- /dev/null +++ b/queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch @@ -0,0 +1,89 @@ +From 5c68c9877264b17dca331aa86e2b95804bce1334 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Apr 2022 15:18:37 +0100 +Subject: gpio: Don't fiddle with irqchips marked as immutable + +From: Marc Zyngier + +[ Upstream commit 6c846d026d490b2383d395bc8e7b06336219667b ] + +In order to move away from gpiolib messing with the internals of +unsuspecting irqchips, add a flag by which irqchips advertise +that they are not to be messed with, and do solemnly swear that +they correctly call into the gpiolib helpers when required. + +Also nudge the users into converting their drivers to the +new model. + +Reviewed-by: Andy Shevchenko +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20220419141846.598305-2-maz@kernel.org +Stable-dep-of: dc3115e6c5d9 ("hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip") +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib.c | 7 ++++++- + include/linux/irq.h | 2 ++ + kernel/irq/debugfs.c | 1 + + 3 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index f9fdd117c654c..e572c30a202ad 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -1483,6 +1483,11 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gc) + { + struct irq_chip *irqchip = gc->irq.chip; + ++ if (irqchip->flags & IRQCHIP_IMMUTABLE) ++ return; ++ ++ chip_warn(gc, "not an immutable chip, please consider fixing it!\n"); ++ + if (!irqchip->irq_request_resources && + !irqchip->irq_release_resources) { + irqchip->irq_request_resources = gpiochip_irq_reqres; +@@ -1650,7 +1655,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gc) + irq_domain_remove(gc->irq.domain); + } + +- if (irqchip) { ++ if (irqchip && !(irqchip->flags & IRQCHIP_IMMUTABLE)) { + if (irqchip->irq_request_resources == gpiochip_irq_reqres) { + irqchip->irq_request_resources = NULL; + irqchip->irq_release_resources = NULL; +diff --git a/include/linux/irq.h b/include/linux/irq.h +index f9e6449fbbbae..296ef3b7d7afa 100644 +--- a/include/linux/irq.h ++++ b/include/linux/irq.h +@@ -570,6 +570,7 @@ struct irq_chip { + * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND: Invokes __enable_irq()/__disable_irq() for wake irqs + * in the suspend path if they are in disabled state + * IRQCHIP_AFFINITY_PRE_STARTUP: Default affinity update before startup ++ * IRQCHIP_IMMUTABLE: Don't ever change anything in this chip + */ + enum { + IRQCHIP_SET_TYPE_MASKED = (1 << 0), +@@ -583,6 +584,7 @@ enum { + IRQCHIP_SUPPORTS_NMI = (1 << 8), + IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND = (1 << 9), + IRQCHIP_AFFINITY_PRE_STARTUP = (1 << 10), ++ IRQCHIP_IMMUTABLE = (1 << 11), + }; + + #include +diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c +index e4cff358b437e..7ff52d94b42c0 100644 +--- a/kernel/irq/debugfs.c ++++ b/kernel/irq/debugfs.c +@@ -58,6 +58,7 @@ static const struct irq_bit_descr irqchip_flags[] = { + BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI), + BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI), + BIT_MASK_DESCR(IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND), ++ BIT_MASK_DESCR(IRQCHIP_IMMUTABLE), + }; + + static void +-- +2.42.0 + diff --git a/queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch b/queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch new file mode 100644 index 00000000000..b2defd09ab9 --- /dev/null +++ b/queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch @@ -0,0 +1,70 @@ +From 485d6fb9783fc780f3118060147eaf8598b09ce5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Apr 2022 15:18:38 +0100 +Subject: gpio: Expose the gpiochip_irq_re[ql]res helpers + +From: Marc Zyngier + +[ Upstream commit 704f08753b6dcd0e08c1953af0b2c7f3fac87111 ] + +The GPIO subsystem has a couple of internal helpers to manage +resources on behalf of the irqchip. Expose them so that GPIO +drivers can use them directly. + +Reviewed-by: Andy Shevchenko +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20220419141846.598305-3-maz@kernel.org +Stable-dep-of: dc3115e6c5d9 ("hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip") +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib.c | 6 ++++-- + include/linux/gpio/driver.h | 4 ++++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index e572c30a202ad..57e726d65904b 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -1431,19 +1431,21 @@ static int gpiochip_to_irq(struct gpio_chip *gc, unsigned int offset) + return irq_create_mapping(domain, offset); + } + +-static int gpiochip_irq_reqres(struct irq_data *d) ++int gpiochip_irq_reqres(struct irq_data *d) + { + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + + return gpiochip_reqres_irq(gc, d->hwirq); + } ++EXPORT_SYMBOL(gpiochip_irq_reqres); + +-static void gpiochip_irq_relres(struct irq_data *d) ++void gpiochip_irq_relres(struct irq_data *d) + { + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + + gpiochip_relres_irq(gc, d->hwirq); + } ++EXPORT_SYMBOL(gpiochip_irq_relres); + + static void gpiochip_irq_mask(struct irq_data *d) + { +diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h +index 65df2ce96f0b1..b241fc23ff3a2 100644 +--- a/include/linux/gpio/driver.h ++++ b/include/linux/gpio/driver.h +@@ -595,6 +595,10 @@ void gpiochip_relres_irq(struct gpio_chip *gc, unsigned int offset); + void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset); + void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset); + ++/* irq_data versions of the above */ ++int gpiochip_irq_reqres(struct irq_data *data); ++void gpiochip_irq_relres(struct irq_data *data); ++ + /* Line status inquiry for drivers */ + bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset); + bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset); +-- +2.42.0 + diff --git a/queue-5.15/hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch b/queue-5.15/hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch new file mode 100644 index 00000000000..c442673ee9e --- /dev/null +++ b/queue-5.15/hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch @@ -0,0 +1,47 @@ +From 5041350d84deab8f412bd369572d89cda7a946e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 15:32:09 +0200 +Subject: HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W + +From: Jiri Kosina + +[ Upstream commit 62cc9c3cb3ec1bf31cc116146185ed97b450836a ] + +This device needs ALWAYS_POLL quirk, otherwise it keeps reconnecting +indefinitely. + +Reported-by: Robert Ayrapetyan +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 5fceefb3c707e..caca5d6e95d64 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -349,6 +349,7 @@ + + #define USB_VENDOR_ID_DELL 0x413c + #define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE 0x301a ++#define USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W 0x4503 + + #define USB_VENDOR_ID_DELORME 0x1163 + #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 96ca7d981ee20..225138a39d323 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -66,6 +66,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT }, +-- +2.42.0 + diff --git a/queue-5.15/hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch b/queue-5.15/hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch new file mode 100644 index 00000000000..6c2d790620a --- /dev/null +++ b/queue-5.15/hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch @@ -0,0 +1,127 @@ +From 379245706fe823c997177e7e67d8ea6b539c2d19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 01:58:30 +0300 +Subject: HID: lenovo: Detect quirk-free fw on cptkbd and stop applying + workaround + +From: Mikhail Khvainitski + +[ Upstream commit 46a0a2c96f0f47628190f122c2e3d879e590bcbe ] + +Built-in firmware of cptkbd handles scrolling by itself (when middle +button is pressed) but with issues: it does not support horizontal and +hi-res scrolling and upon middle button release it sends middle button +click even if there was a scrolling event. Commit 3cb5ff0220e3 ("HID: +lenovo: Hide middle-button press until release") workarounds last +issue but it's impossible to workaround scrolling-related issues +without firmware modification. + +Likely, Dennis Schneider has reverse engineered the firmware and +provided an instruction on how to patch it [1]. However, +aforementioned workaround prevents userspace (libinput) from knowing +exact moment when middle button has been pressed down and performing +"On-Button scrolling". This commit detects correctly-behaving patched +firmware if cursor movement events has been received during middle +button being pressed and stops applying workaround for this device. + +Link: https://hohlerde.org/rauch/en/elektronik/projekte/tpkbd-fix/ [1] + +Signed-off-by: Mikhail Khvainitski +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-lenovo.c | 68 ++++++++++++++++++++++++++-------------- + 1 file changed, 45 insertions(+), 23 deletions(-) + +diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c +index 93b1f935e526e..901c1959efed4 100644 +--- a/drivers/hid/hid-lenovo.c ++++ b/drivers/hid/hid-lenovo.c +@@ -50,7 +50,12 @@ struct lenovo_drvdata { + int select_right; + int sensitivity; + int press_speed; +- u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ ++ /* 0: Up ++ * 1: Down (undecided) ++ * 2: Scrolling ++ * 3: Patched firmware, disable workaround ++ */ ++ u8 middlebutton_state; + bool fn_lock; + }; + +@@ -529,31 +534,48 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, + { + struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); + +- /* "wheel" scroll events */ +- if (usage->type == EV_REL && (usage->code == REL_WHEEL || +- usage->code == REL_HWHEEL)) { +- /* Scroll events disable middle-click event */ +- cptkbd_data->middlebutton_state = 2; +- return 0; +- } ++ if (cptkbd_data->middlebutton_state != 3) { ++ /* REL_X and REL_Y events during middle button pressed ++ * are only possible on patched, bug-free firmware ++ * so set middlebutton_state to 3 ++ * to never apply workaround anymore ++ */ ++ if (cptkbd_data->middlebutton_state == 1 && ++ usage->type == EV_REL && ++ (usage->code == REL_X || usage->code == REL_Y)) { ++ cptkbd_data->middlebutton_state = 3; ++ /* send middle button press which was hold before */ ++ input_event(field->hidinput->input, ++ EV_KEY, BTN_MIDDLE, 1); ++ input_sync(field->hidinput->input); ++ } + +- /* Middle click events */ +- if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { +- if (value == 1) { +- cptkbd_data->middlebutton_state = 1; +- } else if (value == 0) { +- if (cptkbd_data->middlebutton_state == 1) { +- /* No scrolling inbetween, send middle-click */ +- input_event(field->hidinput->input, +- EV_KEY, BTN_MIDDLE, 1); +- input_sync(field->hidinput->input); +- input_event(field->hidinput->input, +- EV_KEY, BTN_MIDDLE, 0); +- input_sync(field->hidinput->input); ++ /* "wheel" scroll events */ ++ if (usage->type == EV_REL && (usage->code == REL_WHEEL || ++ usage->code == REL_HWHEEL)) { ++ /* Scroll events disable middle-click event */ ++ cptkbd_data->middlebutton_state = 2; ++ return 0; ++ } ++ ++ /* Middle click events */ ++ if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { ++ if (value == 1) { ++ cptkbd_data->middlebutton_state = 1; ++ } else if (value == 0) { ++ if (cptkbd_data->middlebutton_state == 1) { ++ /* No scrolling inbetween, send middle-click */ ++ input_event(field->hidinput->input, ++ EV_KEY, BTN_MIDDLE, 1); ++ input_sync(field->hidinput->input); ++ input_event(field->hidinput->input, ++ EV_KEY, BTN_MIDDLE, 0); ++ input_sync(field->hidinput->input); ++ } ++ cptkbd_data->middlebutton_state = 0; + } +- cptkbd_data->middlebutton_state = 0; ++ return 1; + } +- return 1; + } + + return 0; +-- +2.42.0 + diff --git a/queue-5.15/i2c-dev-copy-userspace-array-safely.patch b/queue-5.15/i2c-dev-copy-userspace-array-safely.patch new file mode 100644 index 00000000000..375552934fb --- /dev/null +++ b/queue-5.15/i2c-dev-copy-userspace-array-safely.patch @@ -0,0 +1,40 @@ +From ffddbc7712e143524a392068d9fbd628b7f4c095 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Nov 2023 20:26:13 +0100 +Subject: i2c: dev: copy userspace array safely + +From: Philipp Stanner + +[ Upstream commit cc9c54232f04aef3a5d7f64a0ece7df00f1aaa3d ] + +i2c-dev.c utilizes memdup_user() to copy a userspace array. This is done +without an overflow check. + +Use the new wrapper memdup_array_user() to copy the array more safely. + +Suggested-by: Dave Airlie +Signed-off-by: Philipp Stanner +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/i2c-dev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c +index 6fd2b6718b086..9fefceb3a95d4 100644 +--- a/drivers/i2c/i2c-dev.c ++++ b/drivers/i2c/i2c-dev.c +@@ -450,8 +450,8 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) + return -EINVAL; + +- rdwr_pa = memdup_user(rdwr_arg.msgs, +- rdwr_arg.nmsgs * sizeof(struct i2c_msg)); ++ rdwr_pa = memdup_array_user(rdwr_arg.msgs, ++ rdwr_arg.nmsgs, sizeof(struct i2c_msg)); + if (IS_ERR(rdwr_pa)) + return PTR_ERR(rdwr_pa); + +-- +2.42.0 + diff --git a/queue-5.15/i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch b/queue-5.15/i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch new file mode 100644 index 00000000000..224a375eec2 --- /dev/null +++ b/queue-5.15/i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch @@ -0,0 +1,39 @@ +From 6e6856ae43a20b112c2639266e684f0ef19d8c01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Apr 2016 08:54:30 +0800 +Subject: i2c: sun6i-p2wi: Prevent potential division by zero + +From: Axel Lin + +[ Upstream commit 5ac61d26b8baff5b2e5a9f3dc1ef63297e4b53e7 ] + +Make sure we don't OOPS in case clock-frequency is set to 0 in a DT. The +variable set here is later used as a divisor. + +Signed-off-by: Axel Lin +Acked-by: Boris Brezillon +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-sun6i-p2wi.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c +index 9e3483f507ff5..f2ed13b551088 100644 +--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c ++++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c +@@ -201,6 +201,11 @@ static int p2wi_probe(struct platform_device *pdev) + return -EINVAL; + } + ++ if (clk_freq == 0) { ++ dev_err(dev, "clock-frequency is set to 0 in DT\n"); ++ return -EINVAL; ++ } ++ + if (of_get_child_count(np) > 1) { + dev_err(dev, "P2WI only supports one slave device\n"); + return -EINVAL; +-- +2.42.0 + diff --git a/queue-5.15/i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch b/queue-5.15/i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch new file mode 100644 index 00000000000..1b13cd76ee7 --- /dev/null +++ b/queue-5.15/i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch @@ -0,0 +1,82 @@ +From 227e0a27436a6bdbe2de832f14c7a8b25cb1d63b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 16:02:37 +0800 +Subject: i3c: master: mipi-i3c-hci: Fix a kernel panic for accessing DAT_data. + +From: Billy Tsai + +[ Upstream commit b53e9758a31c683fc8615df930262192ed5f034b ] + +The `i3c_master_bus_init` function may attach the I2C devices before the +I3C bus initialization. In this flow, the DAT `alloc_entry`` will be used +before the DAT `init`. Additionally, if the `i3c_master_bus_init` fails, +the DAT `cleanup` will execute before the device is detached, which will +execue DAT `free_entry` function. The above scenario can cause the driver +to use DAT_data when it is NULL. + +Signed-off-by: Billy Tsai +Link: https://lore.kernel.org/r/20231023080237.560936-1-billy_tsai@aspeedtech.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/mipi-i3c-hci/dat_v1.c | 29 ++++++++++++++++-------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/drivers/i3c/master/mipi-i3c-hci/dat_v1.c b/drivers/i3c/master/mipi-i3c-hci/dat_v1.c +index 97bb49ff5b53b..47b9b4d4ed3fc 100644 +--- a/drivers/i3c/master/mipi-i3c-hci/dat_v1.c ++++ b/drivers/i3c/master/mipi-i3c-hci/dat_v1.c +@@ -64,15 +64,17 @@ static int hci_dat_v1_init(struct i3c_hci *hci) + return -EOPNOTSUPP; + } + +- /* use a bitmap for faster free slot search */ +- hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL); +- if (!hci->DAT_data) +- return -ENOMEM; +- +- /* clear them */ +- for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) { +- dat_w0_write(dat_idx, 0); +- dat_w1_write(dat_idx, 0); ++ if (!hci->DAT_data) { ++ /* use a bitmap for faster free slot search */ ++ hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL); ++ if (!hci->DAT_data) ++ return -ENOMEM; ++ ++ /* clear them */ ++ for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) { ++ dat_w0_write(dat_idx, 0); ++ dat_w1_write(dat_idx, 0); ++ } + } + + return 0; +@@ -87,7 +89,13 @@ static void hci_dat_v1_cleanup(struct i3c_hci *hci) + static int hci_dat_v1_alloc_entry(struct i3c_hci *hci) + { + unsigned int dat_idx; ++ int ret; + ++ if (!hci->DAT_data) { ++ ret = hci_dat_v1_init(hci); ++ if (ret) ++ return ret; ++ } + dat_idx = find_first_zero_bit(hci->DAT_data, hci->DAT_entries); + if (dat_idx >= hci->DAT_entries) + return -ENOENT; +@@ -103,7 +111,8 @@ static void hci_dat_v1_free_entry(struct i3c_hci *hci, unsigned int dat_idx) + { + dat_w0_write(dat_idx, 0); + dat_w1_write(dat_idx, 0); +- __clear_bit(dat_idx, hci->DAT_data); ++ if (hci->DAT_data) ++ __clear_bit(dat_idx, hci->DAT_data); + } + + static void hci_dat_v1_set_dynamic_addr(struct i3c_hci *hci, +-- +2.42.0 + diff --git a/queue-5.15/i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch b/queue-5.15/i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch new file mode 100644 index 00000000000..fa98e9f66c6 --- /dev/null +++ b/queue-5.15/i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch @@ -0,0 +1,38 @@ +From 829485de2d9409930bd9531921b4c693b2a046e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:56:56 +0300 +Subject: i3c: mipi-i3c-hci: Fix out of bounds access in hci_dma_irq_handler + +From: Jarkko Nikula + +[ Upstream commit 45a832f989e520095429589d5b01b0c65da9b574 ] + +Do not loop over ring headers in hci_dma_irq_handler() that are not +allocated and enabled in hci_dma_init(). Otherwise out of bounds access +will occur from rings->headers[i] access when i >= number of allocated +ring headers. + +Signed-off-by: Jarkko Nikula +Link: https://lore.kernel.org/r/20230921055704.1087277-5-jarkko.nikula@linux.intel.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/mipi-i3c-hci/dma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c +index af873a9be0507..dd2dc00399600 100644 +--- a/drivers/i3c/master/mipi-i3c-hci/dma.c ++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c +@@ -734,7 +734,7 @@ static bool hci_dma_irq_handler(struct i3c_hci *hci, unsigned int mask) + unsigned int i; + bool handled = false; + +- for (i = 0; mask && i < 8; i++) { ++ for (i = 0; mask && i < rings->total; i++) { + struct hci_rh_data *rh; + u32 status; + +-- +2.42.0 + diff --git a/queue-5.15/ipvlan-add-ipvlan_route_v6_outbound-helper.patch b/queue-5.15/ipvlan-add-ipvlan_route_v6_outbound-helper.patch new file mode 100644 index 00000000000..c7356f09f48 --- /dev/null +++ b/queue-5.15/ipvlan-add-ipvlan_route_v6_outbound-helper.patch @@ -0,0 +1,272 @@ +From b164816a54a877860fc365b955a87c6d4258ff3b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 15:22:41 +0000 +Subject: ipvlan: add ipvlan_route_v6_outbound() helper + +From: Eric Dumazet + +[ Upstream commit 18f039428c7df183b09c69ebf10ffd4e521035d2 ] + +Inspired by syzbot reports using a stack of multiple ipvlan devices. + +Reduce stack size needed in ipvlan_process_v6_outbound() by moving +the flowi6 struct used for the route lookup in an non inlined +helper. ipvlan_route_v6_outbound() needs 120 bytes on the stack, +immediately reclaimed. + +Also make sure ipvlan_process_v4_outbound() is not inlined. + +We might also have to lower MAX_NEST_DEV, because only syzbot uses +setups with more than four stacked devices. + +BUG: TASK stack guard page was hit at ffffc9000e803ff8 (stack is ffffc9000e804000..ffffc9000e808000) +stack guard page: 0000 [#1] SMP KASAN +CPU: 0 PID: 13442 Comm: syz-executor.4 Not tainted 6.1.52-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/2023 +RIP: 0010:kasan_check_range+0x4/0x2a0 mm/kasan/generic.c:188 +Code: 48 01 c6 48 89 c7 e8 db 4e c1 03 31 c0 5d c3 cc 0f 0b eb 02 0f 0b b8 ea ff ff ff 5d c3 cc 00 00 cc cc 00 00 cc cc 55 48 89 e5 <41> 57 41 56 41 55 41 54 53 b0 01 48 85 f6 0f 84 a4 01 00 00 48 89 +RSP: 0018:ffffc9000e804000 EFLAGS: 00010246 +RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff817e5bf2 +RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffff887c6568 +RBP: ffffc9000e804000 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: dffffc0000000001 R12: 1ffff92001d0080c +R13: dffffc0000000000 R14: ffffffff87e6b100 R15: 0000000000000000 +FS: 00007fd0c55826c0(0000) GS:ffff8881f6800000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: ffffc9000e803ff8 CR3: 0000000170ef7000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: +<#DF> + + +[] __kasan_check_read+0x11/0x20 mm/kasan/shadow.c:31 +[] instrument_atomic_read include/linux/instrumented.h:72 [inline] +[] _test_bit include/asm-generic/bitops/instrumented-non-atomic.h:141 [inline] +[] cpumask_test_cpu include/linux/cpumask.h:506 [inline] +[] cpu_online include/linux/cpumask.h:1092 [inline] +[] trace_lock_acquire include/trace/events/lock.h:24 [inline] +[] lock_acquire+0xe2/0x590 kernel/locking/lockdep.c:5632 +[] rcu_lock_acquire+0x2e/0x40 include/linux/rcupdate.h:306 +[] rcu_read_lock include/linux/rcupdate.h:747 [inline] +[] ip6_pol_route+0x15d/0x1440 net/ipv6/route.c:2221 +[] ip6_pol_route_output+0x50/0x80 net/ipv6/route.c:2606 +[] pol_lookup_func include/net/ip6_fib.h:584 [inline] +[] fib6_rule_lookup+0x265/0x620 net/ipv6/fib6_rules.c:116 +[] ip6_route_output_flags_noref+0x2d9/0x3a0 net/ipv6/route.c:2638 +[] ip6_route_output_flags+0xca/0x340 net/ipv6/route.c:2651 +[] ip6_route_output include/net/ip6_route.h:100 [inline] +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:473 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0xc33/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_hh_output include/net/neighbour.h:529 [inline] +[] neigh_output include/net/neighbour.h:543 [inline] +[] ip6_finish_output2+0x160d/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161 +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:483 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0x1174/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_hh_output include/net/neighbour.h:529 [inline] +[] neigh_output include/net/neighbour.h:543 [inline] +[] ip6_finish_output2+0x160d/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161 +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:483 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0x1174/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_hh_output include/net/neighbour.h:529 [inline] +[] neigh_output include/net/neighbour.h:543 [inline] +[] ip6_finish_output2+0x160d/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161 +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:483 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0x1174/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_hh_output include/net/neighbour.h:529 [inline] +[] neigh_output include/net/neighbour.h:543 [inline] +[] ip6_finish_output2+0x160d/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161 +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:483 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0x1174/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_resolve_output+0x64e/0x750 net/core/neighbour.c:1560 +[] neigh_output include/net/neighbour.h:545 [inline] +[] ip6_finish_output2+0x1643/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] NF_HOOK include/linux/netfilter.h:309 [inline] +[] ip6_xmit+0x11a4/0x1b20 net/ipv6/ip6_output.c:352 +[] sctp_v6_xmit+0x9ae/0x1230 net/sctp/ipv6.c:250 +[] sctp_packet_transmit+0x25de/0x2bc0 net/sctp/output.c:653 +[] sctp_packet_singleton+0x202/0x310 net/sctp/outqueue.c:783 +[] sctp_outq_flush_ctrl net/sctp/outqueue.c:914 [inline] +[] sctp_outq_flush+0x661/0x3d40 net/sctp/outqueue.c:1212 +[] sctp_outq_uncork+0x79/0xb0 net/sctp/outqueue.c:764 +[] sctp_side_effects net/sctp/sm_sideeffect.c:1199 [inline] +[] sctp_do_sm+0x55c0/0x5c30 net/sctp/sm_sideeffect.c:1170 +[] sctp_primitive_ASSOCIATE+0x97/0xc0 net/sctp/primitive.c:73 +[] sctp_sendmsg_to_asoc+0xf62/0x17b0 net/sctp/socket.c:1839 +[] sctp_sendmsg+0x212e/0x33b0 net/sctp/socket.c:2029 +[] inet_sendmsg+0x149/0x310 net/ipv4/af_inet.c:849 +[] sock_sendmsg_nosec net/socket.c:716 [inline] +[] sock_sendmsg net/socket.c:736 [inline] +[] ____sys_sendmsg+0x572/0x8c0 net/socket.c:2504 +[] ___sys_sendmsg net/socket.c:2558 [inline] +[] __sys_sendmsg+0x271/0x360 net/socket.c:2587 +[] __do_sys_sendmsg net/socket.c:2596 [inline] +[] __se_sys_sendmsg net/socket.c:2594 [inline] +[] __x64_sys_sendmsg+0x7f/0x90 net/socket.c:2594 +[] do_syscall_x64 arch/x86/entry/common.c:51 [inline] +[] do_syscall_64+0x53/0x80 arch/x86/entry/common.c:84 +[] entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Mahesh Bandewar +Cc: Willem de Bruijn +Reviewed-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ipvlan/ipvlan_core.c | 41 +++++++++++++++++++------------- + 1 file changed, 25 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index 905542df3b682..5aa9217240d53 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -412,7 +412,7 @@ struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h, + return addr; + } + +-static int ipvlan_process_v4_outbound(struct sk_buff *skb) ++static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb) + { + const struct iphdr *ip4h = ip_hdr(skb); + struct net_device *dev = skb->dev; +@@ -454,13 +454,11 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) + } + + #if IS_ENABLED(CONFIG_IPV6) +-static int ipvlan_process_v6_outbound(struct sk_buff *skb) ++ ++static noinline_for_stack int ++ipvlan_route_v6_outbound(struct net_device *dev, struct sk_buff *skb) + { + const struct ipv6hdr *ip6h = ipv6_hdr(skb); +- struct net_device *dev = skb->dev; +- struct net *net = dev_net(dev); +- struct dst_entry *dst; +- int err, ret = NET_XMIT_DROP; + struct flowi6 fl6 = { + .flowi6_oif = dev->ifindex, + .daddr = ip6h->daddr, +@@ -470,27 +468,38 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) + .flowi6_mark = skb->mark, + .flowi6_proto = ip6h->nexthdr, + }; ++ struct dst_entry *dst; ++ int err; + +- dst = ip6_route_output(net, NULL, &fl6); +- if (dst->error) { +- ret = dst->error; ++ dst = ip6_route_output(dev_net(dev), NULL, &fl6); ++ err = dst->error; ++ if (err) { + dst_release(dst); +- goto err; ++ return err; + } + skb_dst_set(skb, dst); ++ return 0; ++} ++ ++static int ipvlan_process_v6_outbound(struct sk_buff *skb) ++{ ++ struct net_device *dev = skb->dev; ++ int err, ret = NET_XMIT_DROP; ++ ++ err = ipvlan_route_v6_outbound(dev, skb); ++ if (unlikely(err)) { ++ DEV_STATS_INC(dev, tx_errors); ++ kfree_skb(skb); ++ return err; ++ } + + memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); + +- err = ip6_local_out(net, skb->sk, skb); ++ err = ip6_local_out(dev_net(dev), skb->sk, skb); + if (unlikely(net_xmit_eval(err))) + DEV_STATS_INC(dev, tx_errors); + else + ret = NET_XMIT_SUCCESS; +- goto out; +-err: +- DEV_STATS_INC(dev, tx_errors); +- kfree_skb(skb); +-out: + return ret; + } + #else +-- +2.42.0 + diff --git a/queue-5.15/jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch b/queue-5.15/jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch new file mode 100644 index 00000000000..f7a7572565c --- /dev/null +++ b/queue-5.15/jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch @@ -0,0 +1,87 @@ +From 81d7cb444f745b5cc38a9ce267741bd4919af806 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 11:17:18 +0530 +Subject: jfs: fix array-index-out-of-bounds in dbFindLeaf + +From: Manas Ghandat + +[ Upstream commit 22cad8bc1d36547cdae0eef316c47d917ce3147c ] + +Currently while searching for dmtree_t for sufficient free blocks there +is an array out of bounds while getting element in tp->dm_stree. To add +the required check for out of bound we first need to determine the type +of dmtree. Thus added an extra parameter to dbFindLeaf so that the type +of tree can be determined and the required check can be applied. + +Reported-by: syzbot+aea1ad91e854d0a83e04@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=aea1ad91e854d0a83e04 +Signed-off-by: Manas Ghandat +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_dmap.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 217a673b751ef..5b01026fff9bf 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -87,7 +87,7 @@ static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, + static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); + static int dbFindBits(u32 word, int l2nb); + static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); +-static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); ++static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl); + static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, + int nblocks); + static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, +@@ -1785,7 +1785,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) + * dbFindLeaf() returns the index of the leaf at which + * free space was found. + */ +- rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx); ++ rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true); + + /* release the buffer. + */ +@@ -2032,7 +2032,7 @@ dbAllocDmapLev(struct bmap * bmp, + * free space. if sufficient free space is found, dbFindLeaf() + * returns the index of the leaf at which free space was found. + */ +- if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx)) ++ if (dbFindLeaf((dmtree_t *) &dp->tree, l2nb, &leafidx, false)) + return -ENOSPC; + + if (leafidx < 0) +@@ -2996,14 +2996,18 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval) + * leafidx - return pointer to be set to the index of the leaf + * describing at least l2nb free blocks if sufficient + * free blocks are found. ++ * is_ctl - determines if the tree is of type ctl + * + * RETURN VALUES: + * 0 - success + * -ENOSPC - insufficient free blocks. + */ +-static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) ++static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl) + { + int ti, n = 0, k, x = 0; ++ int max_size; ++ ++ max_size = is_ctl ? CTLTREESIZE : TREESIZE; + + /* first check the root of the tree to see if there is + * sufficient free space. +@@ -3024,6 +3028,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) + /* sufficient free space found. move to the next + * level (or quit if this is the last level). + */ ++ if (x + n > max_size) ++ return -ENOSPC; + if (l2nb <= tp->dmt_stree[x + n]) + break; + } +-- +2.42.0 + diff --git a/queue-5.15/jfs-fix-array-index-out-of-bounds-in-dialloc.patch b/queue-5.15/jfs-fix-array-index-out-of-bounds-in-dialloc.patch new file mode 100644 index 00000000000..d7b13b0f388 --- /dev/null +++ b/queue-5.15/jfs-fix-array-index-out-of-bounds-in-dialloc.patch @@ -0,0 +1,48 @@ +From 094a474d4b55f0d0322025179899edc3f8ad05de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 13:10:40 +0530 +Subject: jfs: fix array-index-out-of-bounds in diAlloc + +From: Manas Ghandat + +[ Upstream commit 05d9ea1ceb62a55af6727a69269a4fd310edf483 ] + +Currently there is not check against the agno of the iag while +allocating new inodes to avoid fragmentation problem. Added the check +which is required. + +Reported-by: syzbot+79d792676d8ac050949f@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=79d792676d8ac050949f +Signed-off-by: Manas Ghandat +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_imap.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c +index 4899663996d81..6ed2e1d4c894f 100644 +--- a/fs/jfs/jfs_imap.c ++++ b/fs/jfs/jfs_imap.c +@@ -1320,7 +1320,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) + int diAlloc(struct inode *pip, bool dir, struct inode *ip) + { + int rc, ino, iagno, addext, extno, bitno, sword; +- int nwords, rem, i, agno; ++ int nwords, rem, i, agno, dn_numag; + u32 mask, inosmap, extsmap; + struct inode *ipimap; + struct metapage *mp; +@@ -1356,6 +1356,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) + + /* get the ag number of this iag */ + agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb)); ++ dn_numag = JFS_SBI(pip->i_sb)->bmap->db_numag; ++ if (agno < 0 || agno > dn_numag) ++ return -EIO; + + if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) { + /* +-- +2.42.0 + diff --git a/queue-5.15/kernel-kexec-copy-user-array-safely.patch b/queue-5.15/kernel-kexec-copy-user-array-safely.patch new file mode 100644 index 00000000000..90594e1acbf --- /dev/null +++ b/queue-5.15/kernel-kexec-copy-user-array-safely.patch @@ -0,0 +1,42 @@ +From 52c83eb0ecfc252bb321f33d27320878849bd020 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:10 +0200 +Subject: kernel: kexec: copy user-array safely + +From: Philipp Stanner + +[ Upstream commit 569c8d82f95eb5993c84fb61a649a9c4ddd208b3 ] + +Currently, there is no overflow-check with memdup_user(). + +Use the new function memdup_array_user() instead of memdup_user() for +duplicating the user-space array safely. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Acked-by: Baoquan He +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-4-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + kernel/kexec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/kexec.c b/kernel/kexec.c +index cb8e6e6f983c7..5ff1dcc4acb78 100644 +--- a/kernel/kexec.c ++++ b/kernel/kexec.c +@@ -240,7 +240,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, + ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT)) + return -EINVAL; + +- ksegments = memdup_user(segments, nr_segments * sizeof(ksegments[0])); ++ ksegments = memdup_array_user(segments, nr_segments, sizeof(ksegments[0])); + if (IS_ERR(ksegments)) + return PTR_ERR(ksegments); + +-- +2.42.0 + diff --git a/queue-5.15/kernel-watch_queue-copy-user-array-safely.patch b/queue-5.15/kernel-watch_queue-copy-user-array-safely.patch new file mode 100644 index 00000000000..f2e850a3b79 --- /dev/null +++ b/queue-5.15/kernel-watch_queue-copy-user-array-safely.patch @@ -0,0 +1,41 @@ +From d35f2bf2f9630305c78bc2e69e62a7ea826b5c7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:11 +0200 +Subject: kernel: watch_queue: copy user-array safely + +From: Philipp Stanner + +[ Upstream commit ca0776571d3163bd03b3e8c9e3da936abfaecbf6 ] + +Currently, there is no overflow-check with memdup_user(). + +Use the new function memdup_array_user() instead of memdup_user() for +duplicating the user-space array safely. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-5-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + kernel/watch_queue.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c +index 54cbaa9711398..ae31bf8d2feb1 100644 +--- a/kernel/watch_queue.c ++++ b/kernel/watch_queue.c +@@ -338,7 +338,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe, + filter.__reserved != 0) + return -EINVAL; + +- tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf)); ++ tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf)); + if (IS_ERR(tf)) + return PTR_ERR(tf); + +-- +2.42.0 + diff --git a/queue-5.15/kgdb-flush-console-before-entering-kgdb-on-panic.patch b/queue-5.15/kgdb-flush-console-before-entering-kgdb-on-panic.patch new file mode 100644 index 00000000000..d28fe3a7be7 --- /dev/null +++ b/queue-5.15/kgdb-flush-console-before-entering-kgdb-on-panic.patch @@ -0,0 +1,59 @@ +From df76faaef0d40044571dbce1ad648d019d1302b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Aug 2023 13:19:46 -0700 +Subject: kgdb: Flush console before entering kgdb on panic + +From: Douglas Anderson + +[ Upstream commit dd712d3d45807db9fcae28a522deee85c1f2fde6 ] + +When entering kdb/kgdb on a kernel panic, it was be observed that the +console isn't flushed before the `kdb` prompt came up. Specifically, +when using the buddy lockup detector on arm64 and running: + echo HARDLOCKUP > /sys/kernel/debug/provoke-crash/DIRECT + +I could see: + [ 26.161099] lkdtm: Performing direct entry HARDLOCKUP + [ 32.499881] watchdog: Watchdog detected hard LOCKUP on cpu 6 + [ 32.552865] Sending NMI from CPU 5 to CPUs 6: + [ 32.557359] NMI backtrace for cpu 6 + ... [backtrace for cpu 6] ... + [ 32.558353] NMI backtrace for cpu 5 + ... [backtrace for cpu 5] ... + [ 32.867471] Sending NMI from CPU 5 to CPUs 0-4,7: + [ 32.872321] NMI backtrace forP cpuANC: Hard LOCKUP + + Entering kdb (current=..., pid 0) on processor 5 due to Keyboard Entry + [5]kdb> + +As you can see, backtraces for the other CPUs start printing and get +interleaved with the kdb PANIC print. + +Let's replicate the commands to flush the console in the kdb panic +entry point to avoid this. + +Signed-off-by: Douglas Anderson +Link: https://lore.kernel.org/r/20230822131945.1.I5b460ae8f954e4c4f628a373d6e74713c06dd26f@changeid +Signed-off-by: Daniel Thompson +Signed-off-by: Sasha Levin +--- + kernel/debug/debug_core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c +index 7beceb447211d..f40ca4f09afce 100644 +--- a/kernel/debug/debug_core.c ++++ b/kernel/debug/debug_core.c +@@ -1018,6 +1018,9 @@ void kgdb_panic(const char *msg) + if (panic_timeout) + return; + ++ debug_locks_off(); ++ console_flush_on_panic(CONSOLE_FLUSH_PENDING); ++ + if (dbg_kdb_mode) + kdb_printf("PANIC: %s\n", msg); + +-- +2.42.0 + diff --git a/queue-5.15/locking-ww_mutex-test-fix-potential-workqueue-corrup.patch b/queue-5.15/locking-ww_mutex-test-fix-potential-workqueue-corrup.patch new file mode 100644 index 00000000000..74403550647 --- /dev/null +++ b/queue-5.15/locking-ww_mutex-test-fix-potential-workqueue-corrup.patch @@ -0,0 +1,119 @@ +From 8790925dff30ae4c22e6ad54c2f790cef18fc20d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 04:36:00 +0000 +Subject: locking/ww_mutex/test: Fix potential workqueue corruption + +From: John Stultz + +[ Upstream commit bccdd808902f8c677317cec47c306e42b93b849e ] + +In some cases running with the test-ww_mutex code, I was seeing +odd behavior where sometimes it seemed flush_workqueue was +returning before all the work threads were finished. + +Often this would cause strange crashes as the mutexes would be +freed while they were being used. + +Looking at the code, there is a lifetime problem as the +controlling thread that spawns the work allocates the +"struct stress" structures that are passed to the workqueue +threads. Then when the workqueue threads are finished, +they free the stress struct that was passed to them. + +Unfortunately the workqueue work_struct node is in the stress +struct. Which means the work_struct is freed before the work +thread returns and while flush_workqueue is waiting. + +It seems like a better idea to have the controlling thread +both allocate and free the stress structures, so that we can +be sure we don't corrupt the workqueue by freeing the structure +prematurely. + +So this patch reworks the test to do so, and with this change +I no longer see the early flush_workqueue returns. + +Signed-off-by: John Stultz +Signed-off-by: Ingo Molnar +Link: https://lore.kernel.org/r/20230922043616.19282-3-jstultz@google.com +Signed-off-by: Sasha Levin +--- + kernel/locking/test-ww_mutex.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c +index 3e82f449b4ff7..da36997d8742c 100644 +--- a/kernel/locking/test-ww_mutex.c ++++ b/kernel/locking/test-ww_mutex.c +@@ -426,7 +426,6 @@ static void stress_inorder_work(struct work_struct *work) + } while (!time_after(jiffies, stress->timeout)); + + kfree(order); +- kfree(stress); + } + + struct reorder_lock { +@@ -491,7 +490,6 @@ static void stress_reorder_work(struct work_struct *work) + list_for_each_entry_safe(ll, ln, &locks, link) + kfree(ll); + kfree(order); +- kfree(stress); + } + + static void stress_one_work(struct work_struct *work) +@@ -512,8 +510,6 @@ static void stress_one_work(struct work_struct *work) + break; + } + } while (!time_after(jiffies, stress->timeout)); +- +- kfree(stress); + } + + #define STRESS_INORDER BIT(0) +@@ -524,15 +520,24 @@ static void stress_one_work(struct work_struct *work) + static int stress(int nlocks, int nthreads, unsigned int flags) + { + struct ww_mutex *locks; +- int n; ++ struct stress *stress_array; ++ int n, count; + + locks = kmalloc_array(nlocks, sizeof(*locks), GFP_KERNEL); + if (!locks) + return -ENOMEM; + ++ stress_array = kmalloc_array(nthreads, sizeof(*stress_array), ++ GFP_KERNEL); ++ if (!stress_array) { ++ kfree(locks); ++ return -ENOMEM; ++ } ++ + for (n = 0; n < nlocks; n++) + ww_mutex_init(&locks[n], &ww_class); + ++ count = 0; + for (n = 0; nthreads; n++) { + struct stress *stress; + void (*fn)(struct work_struct *work); +@@ -556,9 +561,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags) + if (!fn) + continue; + +- stress = kmalloc(sizeof(*stress), GFP_KERNEL); +- if (!stress) +- break; ++ stress = &stress_array[count++]; + + INIT_WORK(&stress->work, fn); + stress->locks = locks; +@@ -573,6 +576,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags) + + for (n = 0; n < nlocks; n++) + ww_mutex_destroy(&locks[n]); ++ kfree(stress_array); + kfree(locks); + + return 0; +-- +2.42.0 + diff --git a/queue-5.15/macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch b/queue-5.15/macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch new file mode 100644 index 00000000000..90978709cee --- /dev/null +++ b/queue-5.15/macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch @@ -0,0 +1,61 @@ +From d670f80a6f307899e86637f60323adce1b469a30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 18:59:15 +0100 +Subject: macvlan: Don't propagate promisc change to lower dev in passthru + +From: Vlad Buslov + +[ Upstream commit 7e1caeace0418381f36b3aa8403dfd82fc57fc53 ] + +Macvlan device in passthru mode sets its lower device promiscuous mode +according to its MACVLAN_FLAG_NOPROMISC flag instead of synchronizing it to +its own promiscuity setting. However, macvlan_change_rx_flags() function +doesn't check the mode before propagating such changes to the lower device +which can cause net_device->promiscuity counter overflow as illustrated by +reproduction example [0] and resulting dmesg log [1]. Fix the issue by +first verifying the mode in macvlan_change_rx_flags() function before +propagating promiscuous mode change to the lower device. + +[0]: +ip link add macvlan1 link enp8s0f0 type macvlan mode passthru +ip link set macvlan1 promisc on +ip l set dev macvlan1 up +ip link set macvlan1 promisc off +ip l set dev macvlan1 down +ip l set dev macvlan1 up + +[1]: +[ 5156.281724] macvlan1: entered promiscuous mode +[ 5156.285467] mlx5_core 0000:08:00.0 enp8s0f0: entered promiscuous mode +[ 5156.287639] macvlan1: left promiscuous mode +[ 5156.288339] mlx5_core 0000:08:00.0 enp8s0f0: left promiscuous mode +[ 5156.290907] mlx5_core 0000:08:00.0 enp8s0f0: entered promiscuous mode +[ 5156.317197] mlx5_core 0000:08:00.0 enp8s0f0: promiscuity touches roof, set promiscuity failed. promiscuity feature of device might be broken. + +Fixes: efdbd2b30caa ("macvlan: Propagate promiscuity setting to lower devices.") +Reviewed-by: Gal Pressman +Signed-off-by: Vlad Buslov +Reviewed-by: Jiri Pirko +Link: https://lore.kernel.org/r/20231114175915.1649154-1-vladbu@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index 3dd1528dde028..6f0b6c924d724 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -770,7 +770,7 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change) + if (dev->flags & IFF_UP) { + if (change & IFF_ALLMULTI) + dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1); +- if (change & IFF_PROMISC) ++ if (!macvlan_passthru(vlan->port) && change & IFF_PROMISC) + dev_set_promiscuity(lowerdev, + dev->flags & IFF_PROMISC ? 1 : -1); + +-- +2.42.0 + diff --git a/queue-5.15/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch b/queue-5.15/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch new file mode 100644 index 00000000000..78db29f4aee --- /dev/null +++ b/queue-5.15/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch @@ -0,0 +1,67 @@ +From e778f3de1b4be782706d4dda24ab58056431996e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 18:39:29 +0530 +Subject: media: cadence: csi2rx: Unregister v4l2 async notifier + +From: Pratyush Yadav + +[ Upstream commit b2701715301a49b53d05c7d43f3fedc3b8743bfc ] + +The notifier is added to the global notifier list when registered. When +the module is removed, the struct csi2rx_priv in which the notifier is +embedded, is destroyed. As a result the notifier list has a reference to +a notifier that no longer exists. This causes invalid memory accesses +when the list is iterated over. Similar for when the probe fails. +Unregister and clean up the notifier to avoid this. + +Fixes: 1fc3b37f34f6 ("media: v4l: cadence: Add Cadence MIPI-CSI2 RX driver") + +Signed-off-by: Pratyush Yadav +Tested-by: Julien Massot +Reviewed-by: Laurent Pinchart +Reviewed-by: Tomi Valkeinen +Reviewed-by: Maxime Ripard +Signed-off-by: Jai Luthra +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/cadence/cdns-csi2rx.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c +index 7b44ab2b8c9ad..292044588ae2c 100644 +--- a/drivers/media/platform/cadence/cdns-csi2rx.c ++++ b/drivers/media/platform/cadence/cdns-csi2rx.c +@@ -406,8 +406,10 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) + asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh, + struct v4l2_async_subdev); + of_node_put(ep); +- if (IS_ERR(asd)) ++ if (IS_ERR(asd)) { ++ v4l2_async_nf_cleanup(&csi2rx->notifier); + return PTR_ERR(asd); ++ } + + csi2rx->notifier.ops = &csi2rx_notifier_ops; + +@@ -469,6 +471,7 @@ static int csi2rx_probe(struct platform_device *pdev) + return 0; + + err_cleanup: ++ v4l2_async_nf_unregister(&csi2rx->notifier); + v4l2_async_nf_cleanup(&csi2rx->notifier); + err_free_priv: + kfree(csi2rx); +@@ -479,6 +482,8 @@ static int csi2rx_remove(struct platform_device *pdev) + { + struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev); + ++ v4l2_async_nf_unregister(&csi2rx->notifier); ++ v4l2_async_nf_cleanup(&csi2rx->notifier); + v4l2_async_unregister_subdev(&csi2rx->subdev); + kfree(csi2rx); + +-- +2.42.0 + diff --git a/queue-5.15/media-ccs-fix-driver-quirk-struct-documentation.patch b/queue-5.15/media-ccs-fix-driver-quirk-struct-documentation.patch new file mode 100644 index 00000000000..36498500a0c --- /dev/null +++ b/queue-5.15/media-ccs-fix-driver-quirk-struct-documentation.patch @@ -0,0 +1,42 @@ +From d8274c1501681b6558d9a7ffb04e8163cda43728 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 15:18:18 +0300 +Subject: media: ccs: Fix driver quirk struct documentation + +From: Sakari Ailus + +[ Upstream commit 441b5c63d71ec9ec5453328f7e83384ecc1dddd9 ] + +Fix documentation for struct ccs_quirk, a device specific struct for +managing deviations from the standard. The flags field was drifted away +from where it should have been. + +Signed-off-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/ccs/ccs-quirk.h | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/media/i2c/ccs/ccs-quirk.h b/drivers/media/i2c/ccs/ccs-quirk.h +index 5838fcda92fd4..0b1a64958d714 100644 +--- a/drivers/media/i2c/ccs/ccs-quirk.h ++++ b/drivers/media/i2c/ccs/ccs-quirk.h +@@ -32,12 +32,10 @@ struct ccs_sensor; + * @reg: Pointer to the register to access + * @value: Register value, set by the caller on write, or + * by the quirk on read +- * +- * @flags: Quirk flags +- * + * @return: 0 on success, -ENOIOCTLCMD if no register + * access may be done by the caller (default read + * value is zero), else negative error code on error ++ * @flags: Quirk flags + */ + struct ccs_quirk { + int (*limits)(struct ccs_sensor *sensor); +-- +2.42.0 + diff --git a/queue-5.15/media-cec-meson-always-include-meson-sub-directory-i.patch b/queue-5.15/media-cec-meson-always-include-meson-sub-directory-i.patch new file mode 100644 index 00000000000..9161821d200 --- /dev/null +++ b/queue-5.15/media-cec-meson-always-include-meson-sub-directory-i.patch @@ -0,0 +1,37 @@ +From 946d6cbf8d751392eda50e4ac73aac8bed7008aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 12:35:25 +0200 +Subject: media: cec: meson: always include meson sub-directory in Makefile + +From: Marek Szyprowski + +[ Upstream commit 94e27fbeca27d8c772fc2bc807730aaee5886055 ] + +'meson' directory contains two separate drivers, so it should be added +to Makefile compilation hierarchy unconditionally, because otherwise the +meson-ao-cec-g12a won't be compiled if meson-ao-cec is not selected. + +Signed-off-by: Marek Szyprowski +Fixes: 4be5e8648b0c ("media: move CEC platform drivers to a separate directory") +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/cec/platform/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/cec/platform/Makefile b/drivers/media/cec/platform/Makefile +index ea6f8ee8161c9..e5e441faa0baa 100644 +--- a/drivers/media/cec/platform/Makefile ++++ b/drivers/media/cec/platform/Makefile +@@ -6,7 +6,7 @@ + # Please keep it in alphabetic order + obj-$(CONFIG_CEC_CROS_EC) += cros-ec/ + obj-$(CONFIG_CEC_GPIO) += cec-gpio/ +-obj-$(CONFIG_CEC_MESON_AO) += meson/ ++obj-y += meson/ + obj-$(CONFIG_CEC_SAMSUNG_S5P) += s5p/ + obj-$(CONFIG_CEC_SECO) += seco/ + obj-$(CONFIG_CEC_STI) += sti/ +-- +2.42.0 + diff --git a/queue-5.15/media-cobalt-use-field_get-to-extract-link-width.patch b/queue-5.15/media-cobalt-use-field_get-to-extract-link-width.patch new file mode 100644 index 00000000000..20c26b2ad5c --- /dev/null +++ b/queue-5.15/media-cobalt-use-field_get-to-extract-link-width.patch @@ -0,0 +1,77 @@ +From 9f8c32e21679dd5c604a680656fb523f3bc0960b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 15:27:40 +0300 +Subject: media: cobalt: Use FIELD_GET() to extract Link Width +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit f301fedbeecfdce91cb898d6fa5e62f269801fee ] + +Use FIELD_GET() to extract PCIe Negotiated and Maximum Link Width fields +instead of custom masking and shifting. + +Signed-off-by: Ilpo Järvinen +Reviewed-by: Jonathan Cameron +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/pci/cobalt/cobalt-driver.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c +index 16af58f2f93cc..f9cee061517bd 100644 +--- a/drivers/media/pci/cobalt/cobalt-driver.c ++++ b/drivers/media/pci/cobalt/cobalt-driver.c +@@ -8,6 +8,7 @@ + * All rights reserved. + */ + ++#include + #include + #include + #include +@@ -210,17 +211,17 @@ void cobalt_pcie_status_show(struct cobalt *cobalt) + pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &stat); + cobalt_info("PCIe link capability 0x%08x: %s per lane and %u lanes\n", + capa, get_link_speed(capa), +- (capa & PCI_EXP_LNKCAP_MLW) >> 4); ++ FIELD_GET(PCI_EXP_LNKCAP_MLW, capa)); + cobalt_info("PCIe link control 0x%04x\n", ctrl); + cobalt_info("PCIe link status 0x%04x: %s per lane and %u lanes\n", + stat, get_link_speed(stat), +- (stat & PCI_EXP_LNKSTA_NLW) >> 4); ++ FIELD_GET(PCI_EXP_LNKSTA_NLW, stat)); + + /* Bus */ + pcie_capability_read_dword(pci_bus_dev, PCI_EXP_LNKCAP, &capa); + cobalt_info("PCIe bus link capability 0x%08x: %s per lane and %u lanes\n", + capa, get_link_speed(capa), +- (capa & PCI_EXP_LNKCAP_MLW) >> 4); ++ FIELD_GET(PCI_EXP_LNKCAP_MLW, capa)); + + /* Slot */ + pcie_capability_read_dword(pci_dev, PCI_EXP_SLTCAP, &capa); +@@ -239,7 +240,7 @@ static unsigned pcie_link_get_lanes(struct cobalt *cobalt) + if (!pci_is_pcie(pci_dev)) + return 0; + pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &link); +- return (link & PCI_EXP_LNKSTA_NLW) >> 4; ++ return FIELD_GET(PCI_EXP_LNKSTA_NLW, link); + } + + static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt) +@@ -250,7 +251,7 @@ static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt) + if (!pci_is_pcie(pci_dev)) + return 0; + pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &link); +- return (link & PCI_EXP_LNKCAP_MLW) >> 4; ++ return FIELD_GET(PCI_EXP_LNKCAP_MLW, link); + } + + static void msi_config_show(struct cobalt *cobalt, struct pci_dev *pci_dev) +-- +2.42.0 + diff --git a/queue-5.15/media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch b/queue-5.15/media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch new file mode 100644 index 00000000000..6f45027d625 --- /dev/null +++ b/queue-5.15/media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch @@ -0,0 +1,53 @@ +From 22020f57035b28ece1eac58e50bc1f74bcaf0276 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 13:14:01 +0530 +Subject: media: gspca: cpia1: shift-out-of-bounds in set_flicker + +From: Rajeshwar R Shinde + +[ Upstream commit 099be1822d1f095433f4b08af9cc9d6308ec1953 ] + +Syzkaller reported the following issue: +UBSAN: shift-out-of-bounds in drivers/media/usb/gspca/cpia1.c:1031:27 +shift exponent 245 is too large for 32-bit type 'int' + +When the value of the variable "sd->params.exposure.gain" exceeds the +number of bits in an integer, a shift-out-of-bounds error is reported. It +is triggered because the variable "currentexp" cannot be left-shifted by +more than the number of bits in an integer. In order to avoid invalid +range during left-shift, the conditional expression is added. + +Reported-by: syzbot+e27f3dbdab04e43b9f73@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/20230818164522.12806-1-coolrrsh@gmail.com +Link: https://syzkaller.appspot.com/bug?extid=e27f3dbdab04e43b9f73 +Signed-off-by: Rajeshwar R Shinde +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/usb/gspca/cpia1.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c +index 46ed95483e222..5f5fa851ca640 100644 +--- a/drivers/media/usb/gspca/cpia1.c ++++ b/drivers/media/usb/gspca/cpia1.c +@@ -18,6 +18,7 @@ + + #include + #include ++#include + + #include "gspca.h" + +@@ -1028,6 +1029,8 @@ static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) + sd->params.exposure.expMode = 2; + sd->exposure_status = EXPOSURE_NORMAL; + } ++ if (sd->params.exposure.gain >= BITS_PER_TYPE(currentexp)) ++ return -EINVAL; + currentexp = currentexp << sd->params.exposure.gain; + sd->params.exposure.gain = 0; + /* round down current exposure to nearest value */ +-- +2.42.0 + diff --git a/queue-5.15/media-imon-fix-access-to-invalid-resource-for-the-se.patch b/queue-5.15/media-imon-fix-access-to-invalid-resource-for-the-se.patch new file mode 100644 index 00000000000..48ec5cb1329 --- /dev/null +++ b/queue-5.15/media-imon-fix-access-to-invalid-resource-for-the-se.patch @@ -0,0 +1,54 @@ +From 80c60c0448788b8b3317c82630965d296f94f1be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 14:38:07 +0200 +Subject: media: imon: fix access to invalid resource for the second interface + +From: Takashi Iwai + +[ Upstream commit a1766a4fd83befa0b34d932d532e7ebb7fab1fa7 ] + +imon driver probes two USB interfaces, and at the probe of the second +interface, the driver assumes blindly that the first interface got +bound with the same imon driver. It's usually true, but it's still +possible that the first interface is bound with another driver via a +malformed descriptor. Then it may lead to a memory corruption, as +spotted by syzkaller; imon driver accesses the data from drvdata as +struct imon_context object although it's a completely different one +that was assigned by another driver. + +This patch adds a sanity check -- whether the first interface is +really bound with the imon driver or not -- for avoiding the problem +above at the probe time. + +Reported-by: syzbot+59875ffef5cb9c9b29e9@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/000000000000a838aa0603cc74d6@google.com/ +Tested-by: Ricardo B. Marliere +Link: https://lore.kernel.org/r/20230922005152.163640-1-ricardo@marliere.net +Signed-off-by: Takashi Iwai +Signed-off-by: Sean Young +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/rc/imon.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c +index 72e4bb0fb71ec..4e7c3d889d5ce 100644 +--- a/drivers/media/rc/imon.c ++++ b/drivers/media/rc/imon.c +@@ -2427,6 +2427,12 @@ static int imon_probe(struct usb_interface *interface, + goto fail; + } + ++ if (first_if->dev.driver != interface->dev.driver) { ++ dev_err(&interface->dev, "inconsistent driver matching\n"); ++ ret = -EINVAL; ++ goto fail; ++ } ++ + if (ifnum == 0) { + ictx = imon_init_intf0(interface, id); + if (!ictx) { +-- +2.42.0 + diff --git a/queue-5.15/media-rcar-vin-improve-async-notifier-cleanup-paths.patch b/queue-5.15/media-rcar-vin-improve-async-notifier-cleanup-paths.patch new file mode 100644 index 00000000000..4458a8140e8 --- /dev/null +++ b/queue-5.15/media-rcar-vin-improve-async-notifier-cleanup-paths.patch @@ -0,0 +1,130 @@ +From 56370af019c3e6536cc9de74e73cce0df64b733c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jul 2021 16:25:52 +0200 +Subject: media: rcar-vin: Improve async notifier cleanup paths +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Söderlund + +[ Upstream commit 6df3057792911c59032327886599d9625534958a ] + +The cleanup code for the async notifiers can be refactored to own +functions to reduce code duplication and improve readability. While at +it rename the CSI-2 initialization function _csi2_ instead of _mc_ to +match. + +Signed-off-by: Niklas Söderlund +Reviewed-by: Jacopo Mondi +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier") +Signed-off-by: Sasha Levin +--- + drivers/media/platform/rcar-vin/rcar-core.c | 51 ++++++++++++--------- + 1 file changed, 30 insertions(+), 21 deletions(-) + +diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c +index 6ea561fcd7a39..93a32be692e9a 100644 +--- a/drivers/media/platform/rcar-vin/rcar-core.c ++++ b/drivers/media/platform/rcar-vin/rcar-core.c +@@ -383,6 +383,16 @@ static void rvin_group_put(struct rvin_dev *vin) + kref_put(&group->refcount, rvin_group_release); + } + ++static void rvin_group_notifier_cleanup(struct rvin_dev *vin) ++{ ++ mutex_lock(&vin->group->lock); ++ if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) { ++ v4l2_async_notifier_unregister(&vin->group->notifier); ++ v4l2_async_notifier_cleanup(&vin->group->notifier); ++ } ++ mutex_unlock(&vin->group->lock); ++} ++ + /* ----------------------------------------------------------------------------- + * Controls + */ +@@ -676,6 +686,12 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin) + return ret; + } + ++static void rvin_parallel_cleanup(struct rvin_dev *vin) ++{ ++ v4l2_async_notifier_unregister(&vin->notifier); ++ v4l2_async_notifier_cleanup(&vin->notifier); ++} ++ + static int rvin_parallel_init(struct rvin_dev *vin) + { + int ret; +@@ -937,7 +953,16 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin) + return 0; + } + +-static int rvin_mc_init(struct rvin_dev *vin) ++static void rvin_csi2_cleanup(struct rvin_dev *vin) ++{ ++ if (!vin->info->use_mc) ++ return; ++ ++ rvin_group_notifier_cleanup(vin); ++ rvin_group_put(vin); ++} ++ ++static int rvin_csi2_init(struct rvin_dev *vin) + { + int ret; + +@@ -1443,7 +1468,7 @@ static int rcar_vin_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, vin); + + if (vin->info->use_mc) { +- ret = rvin_mc_init(vin); ++ ret = rvin_csi2_init(vin); + if (ret) + goto error_dma_unregister; + } +@@ -1456,20 +1481,9 @@ static int rcar_vin_probe(struct platform_device *pdev) + pm_runtime_enable(&pdev->dev); + + return 0; +- + error_group_unregister: + rvin_free_controls(vin); +- +- if (vin->info->use_mc) { +- mutex_lock(&vin->group->lock); +- if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) { +- v4l2_async_notifier_unregister(&vin->group->notifier); +- v4l2_async_notifier_cleanup(&vin->group->notifier); +- } +- mutex_unlock(&vin->group->lock); +- rvin_group_put(vin); +- } +- ++ rvin_csi2_cleanup(vin); + error_dma_unregister: + rvin_dma_unregister(vin); + +@@ -1484,14 +1498,9 @@ static int rcar_vin_remove(struct platform_device *pdev) + + rvin_v4l2_unregister(vin); + +- v4l2_async_notifier_unregister(&vin->notifier); +- v4l2_async_notifier_cleanup(&vin->notifier); ++ rvin_parallel_cleanup(vin); + +- if (vin->info->use_mc) { +- v4l2_async_notifier_unregister(&vin->group->notifier); +- v4l2_async_notifier_cleanup(&vin->group->notifier); +- rvin_group_put(vin); +- } ++ rvin_csi2_cleanup(vin); + + rvin_free_controls(vin); + +-- +2.42.0 + diff --git a/queue-5.15/media-rcar-vin-move-group-async-notifier.patch b/queue-5.15/media-rcar-vin-move-group-async-notifier.patch new file mode 100644 index 00000000000..b67e4d1bc55 --- /dev/null +++ b/queue-5.15/media-rcar-vin-move-group-async-notifier.patch @@ -0,0 +1,520 @@ +From e82410d305ebbf854ca798a56edaa3e2e74e0d95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jul 2021 16:25:55 +0200 +Subject: media: rcar-vin: Move group async notifier +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Söderlund + +[ Upstream commit 2070893aed113338f80350bd76e5956c9a8cf07f ] + +The VIN group notifier code is intertwined with the media graph layout +code for R-Car CSI-2 subdevices, this makes it hard to extend the group +to also support the R-Car ISP channel selector. + +Before breaking the two concepts apart and extending it move the group +code to its final location. There is no functional change and all +functions are moved verbatim. + +Signed-off-by: Niklas Söderlund +Reviewed-by: Jacopo Mondi +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier") +Signed-off-by: Sasha Levin +--- + drivers/media/platform/rcar-vin/rcar-core.c | 460 ++++++++++---------- + 1 file changed, 230 insertions(+), 230 deletions(-) + +diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c +index 867d8fd7a77d3..5a280d8ff7dd0 100644 +--- a/drivers/media/platform/rcar-vin/rcar-core.c ++++ b/drivers/media/platform/rcar-vin/rcar-core.c +@@ -383,6 +383,176 @@ static void rvin_group_put(struct rvin_dev *vin) + kref_put(&group->refcount, rvin_group_release); + } + ++static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) ++{ ++ struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); ++ const struct rvin_group_route *route; ++ unsigned int i; ++ int ret; ++ ++ ret = media_device_register(&vin->group->mdev); ++ if (ret) ++ return ret; ++ ++ ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev); ++ if (ret) { ++ vin_err(vin, "Failed to register subdev nodes\n"); ++ return ret; ++ } ++ ++ /* Register all video nodes for the group. */ ++ for (i = 0; i < RCAR_VIN_NUM; i++) { ++ if (vin->group->vin[i] && ++ !video_is_registered(&vin->group->vin[i]->vdev)) { ++ ret = rvin_v4l2_register(vin->group->vin[i]); ++ if (ret) ++ return ret; ++ } ++ } ++ ++ /* Create all media device links between VINs and CSI-2's. */ ++ mutex_lock(&vin->group->lock); ++ for (route = vin->info->routes; route->mask; route++) { ++ struct media_pad *source_pad, *sink_pad; ++ struct media_entity *source, *sink; ++ unsigned int source_idx; ++ ++ /* Check that VIN is part of the group. */ ++ if (!vin->group->vin[route->vin]) ++ continue; ++ ++ /* Check that VIN' master is part of the group. */ ++ if (!vin->group->vin[rvin_group_id_to_master(route->vin)]) ++ continue; ++ ++ /* Check that CSI-2 is part of the group. */ ++ if (!vin->group->remotes[route->csi].subdev) ++ continue; ++ ++ source = &vin->group->remotes[route->csi].subdev->entity; ++ source_idx = rvin_group_csi_channel_to_pad(route->channel); ++ source_pad = &source->pads[source_idx]; ++ ++ sink = &vin->group->vin[route->vin]->vdev.entity; ++ sink_pad = &sink->pads[0]; ++ ++ /* Skip if link already exists. */ ++ if (media_entity_find_link(source_pad, sink_pad)) ++ continue; ++ ++ ret = media_create_pad_link(source, source_idx, sink, 0, 0); ++ if (ret) { ++ vin_err(vin, "Error adding link from %s to %s\n", ++ source->name, sink->name); ++ break; ++ } ++ } ++ mutex_unlock(&vin->group->lock); ++ ++ return ret; ++} ++ ++static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, ++ struct v4l2_subdev *subdev, ++ struct v4l2_async_subdev *asd) ++{ ++ struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); ++ unsigned int i; ++ ++ for (i = 0; i < RCAR_VIN_NUM; i++) ++ if (vin->group->vin[i]) ++ rvin_v4l2_unregister(vin->group->vin[i]); ++ ++ mutex_lock(&vin->group->lock); ++ ++ for (i = 0; i < RVIN_CSI_MAX; i++) { ++ if (vin->group->remotes[i].asd != asd) ++ continue; ++ vin->group->remotes[i].subdev = NULL; ++ vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i); ++ break; ++ } ++ ++ mutex_unlock(&vin->group->lock); ++ ++ media_device_unregister(&vin->group->mdev); ++} ++ ++static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, ++ struct v4l2_subdev *subdev, ++ struct v4l2_async_subdev *asd) ++{ ++ struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); ++ unsigned int i; ++ ++ mutex_lock(&vin->group->lock); ++ ++ for (i = 0; i < RVIN_CSI_MAX; i++) { ++ if (vin->group->remotes[i].asd != asd) ++ continue; ++ vin->group->remotes[i].subdev = subdev; ++ vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i); ++ break; ++ } ++ ++ mutex_unlock(&vin->group->lock); ++ ++ return 0; ++} ++ ++static const struct v4l2_async_notifier_operations rvin_group_notify_ops = { ++ .bound = rvin_group_notify_bound, ++ .unbind = rvin_group_notify_unbind, ++ .complete = rvin_group_notify_complete, ++}; ++ ++static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id) ++{ ++ struct fwnode_handle *ep, *fwnode; ++ struct v4l2_fwnode_endpoint vep = { ++ .bus_type = V4L2_MBUS_CSI2_DPHY, ++ }; ++ struct v4l2_async_subdev *asd; ++ int ret; ++ ++ ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 1, id, 0); ++ if (!ep) ++ return 0; ++ ++ fwnode = fwnode_graph_get_remote_endpoint(ep); ++ ret = v4l2_fwnode_endpoint_parse(ep, &vep); ++ fwnode_handle_put(ep); ++ if (ret) { ++ vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode)); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (!of_device_is_available(to_of_node(fwnode))) { ++ vin_dbg(vin, "OF device %pOF disabled, ignoring\n", ++ to_of_node(fwnode)); ++ ret = -ENOTCONN; ++ goto out; ++ } ++ ++ asd = v4l2_async_notifier_add_fwnode_subdev(&vin->group->notifier, ++ fwnode, ++ struct v4l2_async_subdev); ++ if (IS_ERR(asd)) { ++ ret = PTR_ERR(asd); ++ goto out; ++ } ++ ++ vin->group->remotes[vep.base.id].asd = asd; ++ ++ vin_dbg(vin, "Add group OF device %pOF to slot %u\n", ++ to_of_node(fwnode), vep.base.id); ++out: ++ fwnode_handle_put(fwnode); ++ ++ return ret; ++} ++ + static void rvin_group_notifier_cleanup(struct rvin_dev *vin) + { + mutex_lock(&vin->group->lock); +@@ -393,6 +563,65 @@ static void rvin_group_notifier_cleanup(struct rvin_dev *vin) + mutex_unlock(&vin->group->lock); + } + ++static int rvin_mc_parse_of_graph(struct rvin_dev *vin) ++{ ++ unsigned int count = 0, vin_mask = 0; ++ unsigned int i, id; ++ int ret; ++ ++ mutex_lock(&vin->group->lock); ++ ++ /* If not all VIN's are registered don't register the notifier. */ ++ for (i = 0; i < RCAR_VIN_NUM; i++) { ++ if (vin->group->vin[i]) { ++ count++; ++ vin_mask |= BIT(i); ++ } ++ } ++ ++ if (vin->group->count != count) { ++ mutex_unlock(&vin->group->lock); ++ return 0; ++ } ++ ++ mutex_unlock(&vin->group->lock); ++ ++ v4l2_async_notifier_init(&vin->group->notifier); ++ ++ /* ++ * Have all VIN's look for CSI-2 subdevices. Some subdevices will ++ * overlap but the parser function can handle it, so each subdevice ++ * will only be registered once with the group notifier. ++ */ ++ for (i = 0; i < RCAR_VIN_NUM; i++) { ++ if (!(vin_mask & BIT(i))) ++ continue; ++ ++ for (id = 0; id < RVIN_CSI_MAX; id++) { ++ if (vin->group->remotes[id].asd) ++ continue; ++ ++ ret = rvin_mc_parse_of(vin->group->vin[i], id); ++ if (ret) ++ return ret; ++ } ++ } ++ ++ if (list_empty(&vin->group->notifier.asd_list)) ++ return 0; ++ ++ vin->group->notifier.ops = &rvin_group_notify_ops; ++ ret = v4l2_async_notifier_register(&vin->v4l2_dev, ++ &vin->group->notifier); ++ if (ret < 0) { ++ vin_err(vin, "Notifier registration failed\n"); ++ v4l2_async_notifier_cleanup(&vin->group->notifier); ++ return ret; ++ } ++ ++ return 0; ++} ++ + /* ----------------------------------------------------------------------------- + * Controls + */ +@@ -721,238 +950,9 @@ static int rvin_parallel_init(struct rvin_dev *vin) + } + + /* ----------------------------------------------------------------------------- +- * Group async notifier ++ * CSI-2 + */ + +-static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) +-{ +- struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); +- const struct rvin_group_route *route; +- unsigned int i; +- int ret; +- +- ret = media_device_register(&vin->group->mdev); +- if (ret) +- return ret; +- +- ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev); +- if (ret) { +- vin_err(vin, "Failed to register subdev nodes\n"); +- return ret; +- } +- +- /* Register all video nodes for the group. */ +- for (i = 0; i < RCAR_VIN_NUM; i++) { +- if (vin->group->vin[i] && +- !video_is_registered(&vin->group->vin[i]->vdev)) { +- ret = rvin_v4l2_register(vin->group->vin[i]); +- if (ret) +- return ret; +- } +- } +- +- /* Create all media device links between VINs and CSI-2's. */ +- mutex_lock(&vin->group->lock); +- for (route = vin->info->routes; route->mask; route++) { +- struct media_pad *source_pad, *sink_pad; +- struct media_entity *source, *sink; +- unsigned int source_idx; +- +- /* Check that VIN is part of the group. */ +- if (!vin->group->vin[route->vin]) +- continue; +- +- /* Check that VIN' master is part of the group. */ +- if (!vin->group->vin[rvin_group_id_to_master(route->vin)]) +- continue; +- +- /* Check that CSI-2 is part of the group. */ +- if (!vin->group->remotes[route->csi].subdev) +- continue; +- +- source = &vin->group->remotes[route->csi].subdev->entity; +- source_idx = rvin_group_csi_channel_to_pad(route->channel); +- source_pad = &source->pads[source_idx]; +- +- sink = &vin->group->vin[route->vin]->vdev.entity; +- sink_pad = &sink->pads[0]; +- +- /* Skip if link already exists. */ +- if (media_entity_find_link(source_pad, sink_pad)) +- continue; +- +- ret = media_create_pad_link(source, source_idx, sink, 0, 0); +- if (ret) { +- vin_err(vin, "Error adding link from %s to %s\n", +- source->name, sink->name); +- break; +- } +- } +- mutex_unlock(&vin->group->lock); +- +- return ret; +-} +- +-static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, +- struct v4l2_subdev *subdev, +- struct v4l2_async_subdev *asd) +-{ +- struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); +- unsigned int i; +- +- for (i = 0; i < RCAR_VIN_NUM; i++) +- if (vin->group->vin[i]) +- rvin_v4l2_unregister(vin->group->vin[i]); +- +- mutex_lock(&vin->group->lock); +- +- for (i = 0; i < RVIN_CSI_MAX; i++) { +- if (vin->group->remotes[i].asd != asd) +- continue; +- vin->group->remotes[i].subdev = NULL; +- vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i); +- break; +- } +- +- mutex_unlock(&vin->group->lock); +- +- media_device_unregister(&vin->group->mdev); +-} +- +-static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, +- struct v4l2_subdev *subdev, +- struct v4l2_async_subdev *asd) +-{ +- struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); +- unsigned int i; +- +- mutex_lock(&vin->group->lock); +- +- for (i = 0; i < RVIN_CSI_MAX; i++) { +- if (vin->group->remotes[i].asd != asd) +- continue; +- vin->group->remotes[i].subdev = subdev; +- vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i); +- break; +- } +- +- mutex_unlock(&vin->group->lock); +- +- return 0; +-} +- +-static const struct v4l2_async_notifier_operations rvin_group_notify_ops = { +- .bound = rvin_group_notify_bound, +- .unbind = rvin_group_notify_unbind, +- .complete = rvin_group_notify_complete, +-}; +- +-static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id) +-{ +- struct fwnode_handle *ep, *fwnode; +- struct v4l2_fwnode_endpoint vep = { +- .bus_type = V4L2_MBUS_CSI2_DPHY, +- }; +- struct v4l2_async_subdev *asd; +- int ret; +- +- ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 1, id, 0); +- if (!ep) +- return 0; +- +- fwnode = fwnode_graph_get_remote_endpoint(ep); +- ret = v4l2_fwnode_endpoint_parse(ep, &vep); +- fwnode_handle_put(ep); +- if (ret) { +- vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode)); +- ret = -EINVAL; +- goto out; +- } +- +- if (!of_device_is_available(to_of_node(fwnode))) { +- vin_dbg(vin, "OF device %pOF disabled, ignoring\n", +- to_of_node(fwnode)); +- ret = -ENOTCONN; +- goto out; +- } +- +- asd = v4l2_async_notifier_add_fwnode_subdev(&vin->group->notifier, +- fwnode, +- struct v4l2_async_subdev); +- if (IS_ERR(asd)) { +- ret = PTR_ERR(asd); +- goto out; +- } +- +- vin->group->remotes[vep.base.id].asd = asd; +- +- vin_dbg(vin, "Add group OF device %pOF to slot %u\n", +- to_of_node(fwnode), vep.base.id); +-out: +- fwnode_handle_put(fwnode); +- +- return ret; +-} +- +-static int rvin_mc_parse_of_graph(struct rvin_dev *vin) +-{ +- unsigned int count = 0, vin_mask = 0; +- unsigned int i, id; +- int ret; +- +- mutex_lock(&vin->group->lock); +- +- /* If not all VIN's are registered don't register the notifier. */ +- for (i = 0; i < RCAR_VIN_NUM; i++) { +- if (vin->group->vin[i]) { +- count++; +- vin_mask |= BIT(i); +- } +- } +- +- if (vin->group->count != count) { +- mutex_unlock(&vin->group->lock); +- return 0; +- } +- +- mutex_unlock(&vin->group->lock); +- +- v4l2_async_notifier_init(&vin->group->notifier); +- +- /* +- * Have all VIN's look for CSI-2 subdevices. Some subdevices will +- * overlap but the parser function can handle it, so each subdevice +- * will only be registered once with the group notifier. +- */ +- for (i = 0; i < RCAR_VIN_NUM; i++) { +- if (!(vin_mask & BIT(i))) +- continue; +- +- for (id = 0; id < RVIN_CSI_MAX; id++) { +- if (vin->group->remotes[id].asd) +- continue; +- +- ret = rvin_mc_parse_of(vin->group->vin[i], id); +- if (ret) +- return ret; +- } +- } +- +- if (list_empty(&vin->group->notifier.asd_list)) +- return 0; +- +- vin->group->notifier.ops = &rvin_group_notify_ops; +- ret = v4l2_async_notifier_register(&vin->v4l2_dev, +- &vin->group->notifier); +- if (ret < 0) { +- vin_err(vin, "Notifier registration failed\n"); +- v4l2_async_notifier_cleanup(&vin->group->notifier); +- return ret; +- } +- +- return 0; +-} +- + static void rvin_csi2_cleanup(struct rvin_dev *vin) + { + if (!vin->info->use_mc) +-- +2.42.0 + diff --git a/queue-5.15/media-rcar-vin-refactor-controls-creation-for-video-.patch b/queue-5.15/media-rcar-vin-refactor-controls-creation-for-video-.patch new file mode 100644 index 00000000000..5f814de9a70 --- /dev/null +++ b/queue-5.15/media-rcar-vin-refactor-controls-creation-for-video-.patch @@ -0,0 +1,164 @@ +From 2d93e5d19bdbb4fec5c360da61157ecff7eea120 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jul 2021 16:25:50 +0200 +Subject: media: rcar-vin: Refactor controls creation for video device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Söderlund + +[ Upstream commit b2dc5680aeb418deeacbe9628697fa0b0f2dc54a ] + +The controls for the video device are created in different code paths +depending on if the driver is using the media graph centric model (Gen3) +or the device centric model (Gen2 and earlier). This have lead to code +duplication that can be consolidated. + +Signed-off-by: Niklas Söderlund +Reviewed-by: Jacopo Mondi +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier") +Signed-off-by: Sasha Levin +--- + drivers/media/platform/rcar-vin/rcar-core.c | 82 +++++++++++---------- + 1 file changed, 45 insertions(+), 37 deletions(-) + +diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c +index 33957cc9118ca..6ea561fcd7a39 100644 +--- a/drivers/media/platform/rcar-vin/rcar-core.c ++++ b/drivers/media/platform/rcar-vin/rcar-core.c +@@ -405,6 +405,45 @@ static const struct v4l2_ctrl_ops rvin_ctrl_ops = { + .s_ctrl = rvin_s_ctrl, + }; + ++static void rvin_free_controls(struct rvin_dev *vin) ++{ ++ v4l2_ctrl_handler_free(&vin->ctrl_handler); ++ vin->vdev.ctrl_handler = NULL; ++} ++ ++static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev) ++{ ++ int ret; ++ ++ ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16); ++ if (ret < 0) ++ return ret; ++ ++ /* The VIN directly deals with alpha component. */ ++ v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops, ++ V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); ++ ++ if (vin->ctrl_handler.error) { ++ ret = vin->ctrl_handler.error; ++ rvin_free_controls(vin); ++ return ret; ++ } ++ ++ /* For the non-MC mode add controls from the subdevice. */ ++ if (subdev) { ++ ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, ++ subdev->ctrl_handler, NULL, true); ++ if (ret < 0) { ++ rvin_free_controls(vin); ++ return ret; ++ } ++ } ++ ++ vin->vdev.ctrl_handler = &vin->ctrl_handler; ++ ++ return 0; ++} ++ + /* ----------------------------------------------------------------------------- + * Async notifier + */ +@@ -490,28 +529,10 @@ static int rvin_parallel_subdevice_attach(struct rvin_dev *vin, + return ret; + + /* Add the controls */ +- ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16); ++ ret = rvin_create_controls(vin, subdev); + if (ret < 0) + return ret; + +- v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops, +- V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); +- +- if (vin->ctrl_handler.error) { +- ret = vin->ctrl_handler.error; +- v4l2_ctrl_handler_free(&vin->ctrl_handler); +- return ret; +- } +- +- ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler, +- NULL, true); +- if (ret < 0) { +- v4l2_ctrl_handler_free(&vin->ctrl_handler); +- return ret; +- } +- +- vin->vdev.ctrl_handler = &vin->ctrl_handler; +- + vin->parallel.subdev = subdev; + + return 0; +@@ -522,10 +543,8 @@ static void rvin_parallel_subdevice_detach(struct rvin_dev *vin) + rvin_v4l2_unregister(vin); + vin->parallel.subdev = NULL; + +- if (!vin->info->use_mc) { +- v4l2_ctrl_handler_free(&vin->ctrl_handler); +- vin->vdev.ctrl_handler = NULL; +- } ++ if (!vin->info->use_mc) ++ rvin_free_controls(vin); + } + + static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier) +@@ -935,21 +954,10 @@ static int rvin_mc_init(struct rvin_dev *vin) + if (ret) + rvin_group_put(vin); + +- ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1); ++ ret = rvin_create_controls(vin, NULL); + if (ret < 0) + return ret; + +- v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops, +- V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); +- +- if (vin->ctrl_handler.error) { +- ret = vin->ctrl_handler.error; +- v4l2_ctrl_handler_free(&vin->ctrl_handler); +- return ret; +- } +- +- vin->vdev.ctrl_handler = &vin->ctrl_handler; +- + return ret; + } + +@@ -1450,7 +1458,7 @@ static int rcar_vin_probe(struct platform_device *pdev) + return 0; + + error_group_unregister: +- v4l2_ctrl_handler_free(&vin->ctrl_handler); ++ rvin_free_controls(vin); + + if (vin->info->use_mc) { + mutex_lock(&vin->group->lock); +@@ -1485,7 +1493,7 @@ static int rcar_vin_remove(struct platform_device *pdev) + rvin_group_put(vin); + } + +- v4l2_ctrl_handler_free(&vin->ctrl_handler); ++ rvin_free_controls(vin); + + rvin_dma_unregister(vin); + +-- +2.42.0 + diff --git a/queue-5.15/media-rcar-vin-rename-array-storing-subdevice-inform.patch b/queue-5.15/media-rcar-vin-rename-array-storing-subdevice-inform.patch new file mode 100644 index 00000000000..f48369d98c6 --- /dev/null +++ b/queue-5.15/media-rcar-vin-rename-array-storing-subdevice-inform.patch @@ -0,0 +1,165 @@ +From 3cb36d1692f30bcf8d2e12aaf126c76f639c79ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jul 2021 16:25:54 +0200 +Subject: media: rcar-vin: Rename array storing subdevice information +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Söderlund + +[ Upstream commit 161b56a82dba29c70fd92c5eb1a8502731a0c832 ] + +The VIN group have always been connected to CSI-2 receivers and this +have spilled over to the naming of the array storing the subdevice +information. In preparation for connecting other types of subdevices +rename the array to remotes. + +Signed-off-by: Niklas Söderlund +Reviewed-by: Jacopo Mondi +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier") +Signed-off-by: Sasha Levin +--- + drivers/media/platform/rcar-vin/rcar-core.c | 32 ++++++++++----------- + drivers/media/platform/rcar-vin/rcar-vin.h | 8 ++++-- + 2 files changed, 21 insertions(+), 19 deletions(-) + +diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c +index 93a32be692e9a..867d8fd7a77d3 100644 +--- a/drivers/media/platform/rcar-vin/rcar-core.c ++++ b/drivers/media/platform/rcar-vin/rcar-core.c +@@ -49,16 +49,16 @@ + */ + + /* group lock should be held when calling this function. */ +-static int rvin_group_entity_to_csi_id(struct rvin_group *group, +- struct media_entity *entity) ++static int rvin_group_entity_to_remote_id(struct rvin_group *group, ++ struct media_entity *entity) + { + struct v4l2_subdev *sd; + unsigned int i; + + sd = media_entity_to_v4l2_subdev(entity); + +- for (i = 0; i < RVIN_CSI_MAX; i++) +- if (group->csi[i].subdev == sd) ++ for (i = 0; i < RVIN_REMOTES_MAX; i++) ++ if (group->remotes[i].subdev == sd) + return i; + + return -ENODEV; +@@ -163,14 +163,14 @@ static int rvin_group_link_notify(struct media_link *link, u32 flags, + if (!csi_pad) + continue; + +- csi_id = rvin_group_entity_to_csi_id(group, csi_pad->entity); ++ csi_id = rvin_group_entity_to_remote_id(group, csi_pad->entity); + channel = rvin_group_csi_pad_to_channel(csi_pad->index); + + mask &= rvin_group_get_mask(group->vin[i], csi_id, channel); + } + + /* Add the new link to the existing mask and check if it works. */ +- csi_id = rvin_group_entity_to_csi_id(group, link->source->entity); ++ csi_id = rvin_group_entity_to_remote_id(group, link->source->entity); + + if (csi_id == -ENODEV) { + struct v4l2_subdev *sd; +@@ -767,10 +767,10 @@ static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) + continue; + + /* Check that CSI-2 is part of the group. */ +- if (!vin->group->csi[route->csi].subdev) ++ if (!vin->group->remotes[route->csi].subdev) + continue; + +- source = &vin->group->csi[route->csi].subdev->entity; ++ source = &vin->group->remotes[route->csi].subdev->entity; + source_idx = rvin_group_csi_channel_to_pad(route->channel); + source_pad = &source->pads[source_idx]; + +@@ -807,10 +807,10 @@ static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, + mutex_lock(&vin->group->lock); + + for (i = 0; i < RVIN_CSI_MAX; i++) { +- if (vin->group->csi[i].asd != asd) ++ if (vin->group->remotes[i].asd != asd) + continue; +- vin->group->csi[i].subdev = NULL; +- vin_dbg(vin, "Unbind CSI-2 %s from slot %u\n", subdev->name, i); ++ vin->group->remotes[i].subdev = NULL; ++ vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i); + break; + } + +@@ -829,10 +829,10 @@ static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, + mutex_lock(&vin->group->lock); + + for (i = 0; i < RVIN_CSI_MAX; i++) { +- if (vin->group->csi[i].asd != asd) ++ if (vin->group->remotes[i].asd != asd) + continue; +- vin->group->csi[i].subdev = subdev; +- vin_dbg(vin, "Bound CSI-2 %s to slot %u\n", subdev->name, i); ++ vin->group->remotes[i].subdev = subdev; ++ vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i); + break; + } + +@@ -884,7 +884,7 @@ static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id) + goto out; + } + +- vin->group->csi[vep.base.id].asd = asd; ++ vin->group->remotes[vep.base.id].asd = asd; + + vin_dbg(vin, "Add group OF device %pOF to slot %u\n", + to_of_node(fwnode), vep.base.id); +@@ -929,7 +929,7 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin) + continue; + + for (id = 0; id < RVIN_CSI_MAX; id++) { +- if (vin->group->csi[id].asd) ++ if (vin->group->remotes[id].asd) + continue; + + ret = rvin_mc_parse_of(vin->group->vin[i], id); +diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h +index b263ead4db2bf..39207aaf39ef9 100644 +--- a/drivers/media/platform/rcar-vin/rcar-vin.h ++++ b/drivers/media/platform/rcar-vin/rcar-vin.h +@@ -48,6 +48,8 @@ enum rvin_csi_id { + RVIN_CSI_MAX, + }; + ++#define RVIN_REMOTES_MAX RVIN_CSI_MAX ++ + /** + * enum rvin_dma_state - DMA states + * @STOPPED: No operation in progress +@@ -267,8 +269,8 @@ struct rvin_dev { + * @count: number of enabled VIN instances found in DT + * @notifier: group notifier for CSI-2 async subdevices + * @vin: VIN instances which are part of the group +- * @csi: array of pairs of fwnode and subdev pointers +- * to all CSI-2 subdevices. ++ * @remotes: array of pairs of fwnode and subdev pointers ++ * to all remote subdevices. + */ + struct rvin_group { + struct kref refcount; +@@ -283,7 +285,7 @@ struct rvin_group { + struct { + struct v4l2_async_subdev *asd; + struct v4l2_subdev *subdev; +- } csi[RVIN_CSI_MAX]; ++ } remotes[RVIN_REMOTES_MAX]; + }; + + int rvin_dma_register(struct rvin_dev *vin, int irq); +-- +2.42.0 + diff --git a/queue-5.15/media-v4l-async-rename-async-nf-functions-clean-up-l.patch b/queue-5.15/media-v4l-async-rename-async-nf-functions-clean-up-l.patch new file mode 100644 index 00000000000..7d1ab679f64 --- /dev/null +++ b/queue-5.15/media-v4l-async-rename-async-nf-functions-clean-up-l.patch @@ -0,0 +1,2923 @@ +From 3464203cfff9f4f40ce445a7be3175ddbf41e21d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Mar 2021 18:13:12 +0100 +Subject: media: v4l: async: Rename async nf functions, clean up long lines + +From: Sakari Ailus + +[ Upstream commit 3c8c153914812a98eaa0b5a6cf09c511a06aafbe ] + +Rename V4L2 async notifier functions, replacing "notifier" with "nf" and +removing "_subdev" at the end of the function names adding subdevs as you +can only add subdevs to a notifier. Also wrap and otherwise clean up long +lines. + +Signed-off-by: Sakari Ailus +Reviewed-by: Jacopo Mondi +Reviewed-by: Rui Miguel Silva (imx7) +Signed-off-by: Mauro Carvalho Chehab +Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier") +Signed-off-by: Sasha Levin +--- + .../driver-api/media/v4l2-subdev.rst | 14 +- + drivers/media/i2c/max9286.c | 17 +- + drivers/media/i2c/st-mipid02.c | 22 ++- + drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 17 +- + drivers/media/platform/am437x/am437x-vpfe.c | 19 +- + drivers/media/platform/atmel/atmel-isc-base.c | 4 +- + drivers/media/platform/atmel/atmel-isi.c | 17 +- + .../media/platform/atmel/atmel-sama5d2-isc.c | 15 +- + .../media/platform/atmel/atmel-sama7g5-isc.c | 15 +- + drivers/media/platform/cadence/cdns-csi2rx.c | 14 +- + drivers/media/platform/davinci/vpif_capture.c | 21 +-- + drivers/media/platform/exynos4-is/media-dev.c | 20 +-- + .../media/platform/marvell-ccic/cafe-driver.c | 9 +- + .../media/platform/marvell-ccic/mcam-core.c | 10 +- + .../media/platform/marvell-ccic/mmp-driver.c | 6 +- + drivers/media/platform/omap3isp/isp.c | 21 ++- + drivers/media/platform/pxa_camera.c | 26 ++- + drivers/media/platform/qcom/camss/camss.c | 18 +- + drivers/media/platform/rcar-vin/rcar-core.c | 30 ++-- + drivers/media/platform/rcar-vin/rcar-csi2.c | 19 +- + drivers/media/platform/rcar_drif.c | 14 +- + drivers/media/platform/renesas-ceu.c | 29 ++- + .../platform/rockchip/rkisp1/rkisp1-dev.c | 17 +- + drivers/media/platform/stm32/stm32-dcmi.c | 18 +- + .../platform/sunxi/sun4i-csi/sun4i_csi.c | 12 +- + .../platform/sunxi/sun6i-csi/sun6i_csi.c | 19 +- + drivers/media/platform/ti-vpe/cal.c | 16 +- + drivers/media/platform/video-mux.c | 17 +- + drivers/media/platform/xilinx/xilinx-vipp.c | 17 +- + drivers/media/v4l2-core/v4l2-async.c | 168 +++++++++--------- + drivers/media/v4l2-core/v4l2-fwnode.c | 74 ++++---- + drivers/staging/media/imx/imx-media-csi.c | 17 +- + .../staging/media/imx/imx-media-dev-common.c | 7 +- + drivers/staging/media/imx/imx-media-dev.c | 6 +- + drivers/staging/media/imx/imx-media-of.c | 6 +- + drivers/staging/media/imx/imx6-mipi-csi2.c | 17 +- + drivers/staging/media/imx/imx7-media-csi.c | 24 +-- + drivers/staging/media/imx/imx7-mipi-csis.c | 16 +- + drivers/staging/media/imx/imx8mq-mipi-csi2.c | 16 +- + drivers/staging/media/tegra-video/vi.c | 17 +- + include/media/v4l2-async.h | 105 ++++++----- + include/media/v4l2-fwnode.h | 12 +- + 42 files changed, 479 insertions(+), 499 deletions(-) + +diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst +index 7736da077fb87..08ea2673b19e3 100644 +--- a/Documentation/driver-api/media/v4l2-subdev.rst ++++ b/Documentation/driver-api/media/v4l2-subdev.rst +@@ -191,21 +191,21 @@ registered this way are stored in a global list of subdevices, ready to be + picked up by bridge drivers. + + Bridge drivers in turn have to register a notifier object. This is +-performed using the :c:func:`v4l2_async_notifier_register` call. To ++performed using the :c:func:`v4l2_async_nf_register` call. To + unregister the notifier the driver has to call +-:c:func:`v4l2_async_notifier_unregister`. The former of the two functions ++:c:func:`v4l2_async_nf_unregister`. The former of the two functions + takes two arguments: a pointer to struct :c:type:`v4l2_device` and a + pointer to struct :c:type:`v4l2_async_notifier`. + + Before registering the notifier, bridge drivers must do two things: first, the +-notifier must be initialized using the :c:func:`v4l2_async_notifier_init`. ++notifier must be initialized using the :c:func:`v4l2_async_nf_init`. + Second, bridge drivers can then begin to form a list of subdevice descriptors + that the bridge device needs for its operation. Several functions are available + to add subdevice descriptors to a notifier, depending on the type of device and + the needs of the driver. + +-:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and +-:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for ++:c:func:`v4l2_async_nf_add_fwnode_remote` and ++:c:func:`v4l2_async_nf_add_i2c` are for bridge and ISP drivers for + registering their async sub-devices with the notifier. + + :c:func:`v4l2_async_register_subdev_sensor` is a helper function for +@@ -230,8 +230,8 @@ These functions allocate an async sub-device descriptor which is of type struct + + ... + +- my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(¬ifier, ep, +- struct my_async_subdev); ++ my_asd = v4l2_async_nf_add_fwnode_remote(¬ifier, ep, ++ struct my_async_subdev); + fwnode_handle_put(ep); + + if (IS_ERR(asd)) +diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c +index 1b9beaee6bea7..b5fed8a52c44b 100644 +--- a/drivers/media/i2c/max9286.c ++++ b/drivers/media/i2c/max9286.c +@@ -609,19 +609,18 @@ static int max9286_v4l2_notifier_register(struct max9286_priv *priv) + if (!priv->nsources) + return 0; + +- v4l2_async_notifier_init(&priv->notifier); ++ v4l2_async_nf_init(&priv->notifier); + + for_each_source(priv, source) { + unsigned int i = to_index(priv, source); + struct max9286_asd *mas; + +- mas = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier, +- source->fwnode, +- struct max9286_asd); ++ mas = v4l2_async_nf_add_fwnode(&priv->notifier, source->fwnode, ++ struct max9286_asd); + if (IS_ERR(mas)) { + dev_err(dev, "Failed to add subdev for source %u: %ld", + i, PTR_ERR(mas)); +- v4l2_async_notifier_cleanup(&priv->notifier); ++ v4l2_async_nf_cleanup(&priv->notifier); + return PTR_ERR(mas); + } + +@@ -630,10 +629,10 @@ static int max9286_v4l2_notifier_register(struct max9286_priv *priv) + + priv->notifier.ops = &max9286_notify_ops; + +- ret = v4l2_async_subdev_notifier_register(&priv->sd, &priv->notifier); ++ ret = v4l2_async_subdev_nf_register(&priv->sd, &priv->notifier); + if (ret) { + dev_err(dev, "Failed to register subdev_notifier"); +- v4l2_async_notifier_cleanup(&priv->notifier); ++ v4l2_async_nf_cleanup(&priv->notifier); + return ret; + } + +@@ -645,8 +644,8 @@ static void max9286_v4l2_notifier_unregister(struct max9286_priv *priv) + if (!priv->nsources) + return; + +- v4l2_async_notifier_unregister(&priv->notifier); +- v4l2_async_notifier_cleanup(&priv->notifier); ++ v4l2_async_nf_unregister(&priv->notifier); ++ v4l2_async_nf_cleanup(&priv->notifier); + } + + static int max9286_s_stream(struct v4l2_subdev *sd, int enable) +diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c +index cf55c57a79707..f8615d95b4826 100644 +--- a/drivers/media/i2c/st-mipid02.c ++++ b/drivers/media/i2c/st-mipid02.c +@@ -881,11 +881,10 @@ static int mipid02_parse_rx_ep(struct mipid02_dev *bridge) + bridge->rx = ep; + + /* register async notifier so we get noticed when sensor is connected */ +- v4l2_async_notifier_init(&bridge->notifier); +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &bridge->notifier, +- of_fwnode_handle(ep_node), +- struct v4l2_async_subdev); ++ v4l2_async_nf_init(&bridge->notifier); ++ asd = v4l2_async_nf_add_fwnode_remote(&bridge->notifier, ++ of_fwnode_handle(ep_node), ++ struct v4l2_async_subdev); + of_node_put(ep_node); + + if (IS_ERR(asd)) { +@@ -895,10 +894,9 @@ static int mipid02_parse_rx_ep(struct mipid02_dev *bridge) + } + bridge->notifier.ops = &mipid02_notifier_ops; + +- ret = v4l2_async_subdev_notifier_register(&bridge->sd, +- &bridge->notifier); ++ ret = v4l2_async_subdev_nf_register(&bridge->sd, &bridge->notifier); + if (ret) +- v4l2_async_notifier_cleanup(&bridge->notifier); ++ v4l2_async_nf_cleanup(&bridge->notifier); + + return ret; + +@@ -1036,8 +1034,8 @@ static int mipid02_probe(struct i2c_client *client) + return 0; + + unregister_notifier: +- v4l2_async_notifier_unregister(&bridge->notifier); +- v4l2_async_notifier_cleanup(&bridge->notifier); ++ v4l2_async_nf_unregister(&bridge->notifier); ++ v4l2_async_nf_cleanup(&bridge->notifier); + power_off: + mipid02_set_power_off(bridge); + entity_cleanup: +@@ -1053,8 +1051,8 @@ static int mipid02_remove(struct i2c_client *client) + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct mipid02_dev *bridge = to_mipid02_dev(sd); + +- v4l2_async_notifier_unregister(&bridge->notifier); +- v4l2_async_notifier_cleanup(&bridge->notifier); ++ v4l2_async_nf_unregister(&bridge->notifier); ++ v4l2_async_nf_cleanup(&bridge->notifier); + v4l2_async_unregister_subdev(&bridge->sd); + mipid02_set_power_off(bridge); + media_entity_cleanup(&bridge->sd.entity); +diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +index 162ab089124f3..00e2225f1ea3d 100644 +--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c ++++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +@@ -1478,8 +1478,9 @@ static int cio2_parse_firmware(struct cio2_device *cio2) + if (ret) + goto err_parse; + +- s_asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &cio2->notifier, ep, struct sensor_async_subdev); ++ s_asd = v4l2_async_nf_add_fwnode_remote(&cio2->notifier, ep, ++ struct ++ sensor_async_subdev); + if (IS_ERR(s_asd)) { + ret = PTR_ERR(s_asd); + goto err_parse; +@@ -1502,7 +1503,7 @@ static int cio2_parse_firmware(struct cio2_device *cio2) + * suspend. + */ + cio2->notifier.ops = &cio2_async_ops; +- ret = v4l2_async_notifier_register(&cio2->v4l2_dev, &cio2->notifier); ++ ret = v4l2_async_nf_register(&cio2->v4l2_dev, &cio2->notifier); + if (ret) + dev_err(&cio2->pci_dev->dev, + "failed to register async notifier : %d\n", ret); +@@ -1804,7 +1805,7 @@ static int cio2_pci_probe(struct pci_dev *pci_dev, + if (r) + goto fail_v4l2_device_unregister; + +- v4l2_async_notifier_init(&cio2->notifier); ++ v4l2_async_nf_init(&cio2->notifier); + + /* Register notifier for subdevices we care */ + r = cio2_parse_firmware(cio2); +@@ -1824,8 +1825,8 @@ static int cio2_pci_probe(struct pci_dev *pci_dev, + return 0; + + fail_clean_notifier: +- v4l2_async_notifier_unregister(&cio2->notifier); +- v4l2_async_notifier_cleanup(&cio2->notifier); ++ v4l2_async_nf_unregister(&cio2->notifier); ++ v4l2_async_nf_cleanup(&cio2->notifier); + cio2_queues_exit(cio2); + fail_v4l2_device_unregister: + v4l2_device_unregister(&cio2->v4l2_dev); +@@ -1844,8 +1845,8 @@ static void cio2_pci_remove(struct pci_dev *pci_dev) + struct cio2_device *cio2 = pci_get_drvdata(pci_dev); + + media_device_unregister(&cio2->media_dev); +- v4l2_async_notifier_unregister(&cio2->notifier); +- v4l2_async_notifier_cleanup(&cio2->notifier); ++ v4l2_async_nf_unregister(&cio2->notifier); ++ v4l2_async_nf_cleanup(&cio2->notifier); + cio2_queues_exit(cio2); + cio2_fbpt_exit_dummy(cio2); + v4l2_device_unregister(&cio2->v4l2_dev); +diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c +index c1ce93efc6559..38fe7f67d51e5 100644 +--- a/drivers/media/platform/am437x/am437x-vpfe.c ++++ b/drivers/media/platform/am437x/am437x-vpfe.c +@@ -2298,7 +2298,7 @@ vpfe_get_pdata(struct vpfe_device *vpfe) + + dev_dbg(dev, "vpfe_get_pdata\n"); + +- v4l2_async_notifier_init(&vpfe->notifier); ++ v4l2_async_nf_init(&vpfe->notifier); + + if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) + return dev->platform_data; +@@ -2366,9 +2366,10 @@ vpfe_get_pdata(struct vpfe_device *vpfe) + goto cleanup; + } + +- pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev( +- &vpfe->notifier, of_fwnode_handle(rem), +- struct v4l2_async_subdev); ++ pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpfe->notifier, ++ of_fwnode_handle(rem), ++ struct ++ v4l2_async_subdev); + of_node_put(rem); + if (IS_ERR(pdata->asd[i])) + goto cleanup; +@@ -2378,7 +2379,7 @@ vpfe_get_pdata(struct vpfe_device *vpfe) + return pdata; + + cleanup: +- v4l2_async_notifier_cleanup(&vpfe->notifier); ++ v4l2_async_nf_cleanup(&vpfe->notifier); + of_node_put(endpoint); + return NULL; + } +@@ -2466,7 +2467,7 @@ static int vpfe_probe(struct platform_device *pdev) + } + + vpfe->notifier.ops = &vpfe_async_ops; +- ret = v4l2_async_notifier_register(&vpfe->v4l2_dev, &vpfe->notifier); ++ ret = v4l2_async_nf_register(&vpfe->v4l2_dev, &vpfe->notifier); + if (ret) { + vpfe_err(vpfe, "Error registering async notifier\n"); + ret = -EINVAL; +@@ -2478,7 +2479,7 @@ static int vpfe_probe(struct platform_device *pdev) + probe_out_v4l2_unregister: + v4l2_device_unregister(&vpfe->v4l2_dev); + probe_out_cleanup: +- v4l2_async_notifier_cleanup(&vpfe->notifier); ++ v4l2_async_nf_cleanup(&vpfe->notifier); + return ret; + } + +@@ -2491,8 +2492,8 @@ static int vpfe_remove(struct platform_device *pdev) + + pm_runtime_disable(&pdev->dev); + +- v4l2_async_notifier_unregister(&vpfe->notifier); +- v4l2_async_notifier_cleanup(&vpfe->notifier); ++ v4l2_async_nf_unregister(&vpfe->notifier); ++ v4l2_async_nf_cleanup(&vpfe->notifier); + v4l2_device_unregister(&vpfe->v4l2_dev); + video_unregister_device(&vpfe->video_dev); + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index f768be3c40595..24807782c9e50 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -2217,8 +2217,8 @@ void isc_subdev_cleanup(struct isc_device *isc) + struct isc_subdev_entity *subdev_entity; + + list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { +- v4l2_async_notifier_unregister(&subdev_entity->notifier); +- v4l2_async_notifier_cleanup(&subdev_entity->notifier); ++ v4l2_async_nf_unregister(&subdev_entity->notifier); ++ v4l2_async_nf_cleanup(&subdev_entity->notifier); + } + + INIT_LIST_HEAD(&isc->subdev_entities); +diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c +index 095d80c4f59e7..4d15814e4481c 100644 +--- a/drivers/media/platform/atmel/atmel-isi.c ++++ b/drivers/media/platform/atmel/atmel-isi.c +@@ -1159,12 +1159,11 @@ static int isi_graph_init(struct atmel_isi *isi) + if (!ep) + return -EINVAL; + +- v4l2_async_notifier_init(&isi->notifier); ++ v4l2_async_nf_init(&isi->notifier); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &isi->notifier, +- of_fwnode_handle(ep), +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&isi->notifier, ++ of_fwnode_handle(ep), ++ struct v4l2_async_subdev); + of_node_put(ep); + + if (IS_ERR(asd)) +@@ -1172,10 +1171,10 @@ static int isi_graph_init(struct atmel_isi *isi) + + isi->notifier.ops = &isi_graph_notify_ops; + +- ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier); ++ ret = v4l2_async_nf_register(&isi->v4l2_dev, &isi->notifier); + if (ret < 0) { + dev_err(isi->dev, "Notifier registration failed\n"); +- v4l2_async_notifier_cleanup(&isi->notifier); ++ v4l2_async_nf_cleanup(&isi->notifier); + return ret; + } + +@@ -1327,8 +1326,8 @@ static int atmel_isi_remove(struct platform_device *pdev) + isi->p_fb_descriptors, + isi->fb_descriptors_phys); + pm_runtime_disable(&pdev->dev); +- v4l2_async_notifier_unregister(&isi->notifier); +- v4l2_async_notifier_cleanup(&isi->notifier); ++ v4l2_async_nf_unregister(&isi->notifier); ++ v4l2_async_nf_cleanup(&isi->notifier); + v4l2_device_unregister(&isi->v4l2_dev); + + return 0; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 7421bc51709c4..a1fd240c6aeb8 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -499,13 +499,14 @@ static int atmel_isc_probe(struct platform_device *pdev) + + list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { + struct v4l2_async_subdev *asd; ++ struct fwnode_handle *fwnode = ++ of_fwnode_handle(subdev_entity->epn); + +- v4l2_async_notifier_init(&subdev_entity->notifier); ++ v4l2_async_nf_init(&subdev_entity->notifier); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &subdev_entity->notifier, +- of_fwnode_handle(subdev_entity->epn), +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier, ++ fwnode, ++ struct v4l2_async_subdev); + + of_node_put(subdev_entity->epn); + subdev_entity->epn = NULL; +@@ -517,8 +518,8 @@ static int atmel_isc_probe(struct platform_device *pdev) + + subdev_entity->notifier.ops = &isc_async_ops; + +- ret = v4l2_async_notifier_register(&isc->v4l2_dev, +- &subdev_entity->notifier); ++ ret = v4l2_async_nf_register(&isc->v4l2_dev, ++ &subdev_entity->notifier); + if (ret) { + dev_err(dev, "fail to register async notifier\n"); + goto cleanup_subdev; +diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c +index a4defc30cf412..366f2afcda193 100644 +--- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c +@@ -493,13 +493,14 @@ static int microchip_xisc_probe(struct platform_device *pdev) + + list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { + struct v4l2_async_subdev *asd; ++ struct fwnode_handle *fwnode = ++ of_fwnode_handle(subdev_entity->epn); + +- v4l2_async_notifier_init(&subdev_entity->notifier); ++ v4l2_async_nf_init(&subdev_entity->notifier); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &subdev_entity->notifier, +- of_fwnode_handle(subdev_entity->epn), +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier, ++ fwnode, ++ struct v4l2_async_subdev); + + of_node_put(subdev_entity->epn); + subdev_entity->epn = NULL; +@@ -511,8 +512,8 @@ static int microchip_xisc_probe(struct platform_device *pdev) + + subdev_entity->notifier.ops = &isc_async_ops; + +- ret = v4l2_async_notifier_register(&isc->v4l2_dev, +- &subdev_entity->notifier); ++ ret = v4l2_async_nf_register(&isc->v4l2_dev, ++ &subdev_entity->notifier); + if (ret) { + dev_err(dev, "fail to register async notifier\n"); + goto cleanup_subdev; +diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c +index f2b4ddd31177b..7b44ab2b8c9ad 100644 +--- a/drivers/media/platform/cadence/cdns-csi2rx.c ++++ b/drivers/media/platform/cadence/cdns-csi2rx.c +@@ -401,21 +401,19 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) + return -EINVAL; + } + +- v4l2_async_notifier_init(&csi2rx->notifier); ++ v4l2_async_nf_init(&csi2rx->notifier); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi2rx->notifier, +- fwh, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh, ++ struct v4l2_async_subdev); + of_node_put(ep); + if (IS_ERR(asd)) + return PTR_ERR(asd); + + csi2rx->notifier.ops = &csi2rx_notifier_ops; + +- ret = v4l2_async_subdev_notifier_register(&csi2rx->subdev, +- &csi2rx->notifier); ++ ret = v4l2_async_subdev_nf_register(&csi2rx->subdev, &csi2rx->notifier); + if (ret) +- v4l2_async_notifier_cleanup(&csi2rx->notifier); ++ v4l2_async_nf_cleanup(&csi2rx->notifier); + + return ret; + } +@@ -471,7 +469,7 @@ static int csi2rx_probe(struct platform_device *pdev) + return 0; + + err_cleanup: +- v4l2_async_notifier_cleanup(&csi2rx->notifier); ++ v4l2_async_nf_cleanup(&csi2rx->notifier); + err_free_priv: + kfree(csi2rx); + return ret; +diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c +index c034e25dd9aae..ae92e2c206d04 100644 +--- a/drivers/media/platform/davinci/vpif_capture.c ++++ b/drivers/media/platform/davinci/vpif_capture.c +@@ -1506,7 +1506,7 @@ vpif_capture_get_pdata(struct platform_device *pdev) + struct vpif_capture_chan_config *chan; + unsigned int i; + +- v4l2_async_notifier_init(&vpif_obj.notifier); ++ v4l2_async_nf_init(&vpif_obj.notifier); + + /* + * DT boot: OF node from parent device contains +@@ -1582,9 +1582,10 @@ vpif_capture_get_pdata(struct platform_device *pdev) + dev_dbg(&pdev->dev, "Remote device %pOF found\n", rem); + sdinfo->name = rem->full_name; + +- pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev( +- &vpif_obj.notifier, of_fwnode_handle(rem), +- struct v4l2_async_subdev); ++ pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpif_obj.notifier, ++ of_fwnode_handle(rem), ++ struct ++ v4l2_async_subdev); + if (IS_ERR(pdata->asd[i])) + goto err_cleanup; + +@@ -1602,7 +1603,7 @@ vpif_capture_get_pdata(struct platform_device *pdev) + err_cleanup: + of_node_put(rem); + of_node_put(endpoint); +- v4l2_async_notifier_cleanup(&vpif_obj.notifier); ++ v4l2_async_nf_cleanup(&vpif_obj.notifier); + + return NULL; + } +@@ -1692,8 +1693,8 @@ static __init int vpif_probe(struct platform_device *pdev) + goto probe_subdev_out; + } else { + vpif_obj.notifier.ops = &vpif_async_ops; +- err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev, +- &vpif_obj.notifier); ++ err = v4l2_async_nf_register(&vpif_obj.v4l2_dev, ++ &vpif_obj.notifier); + if (err) { + vpif_err("Error registering async notifier\n"); + err = -EINVAL; +@@ -1711,7 +1712,7 @@ static __init int vpif_probe(struct platform_device *pdev) + vpif_free: + free_vpif_objs(); + cleanup: +- v4l2_async_notifier_cleanup(&vpif_obj.notifier); ++ v4l2_async_nf_cleanup(&vpif_obj.notifier); + + return err; + } +@@ -1727,8 +1728,8 @@ static int vpif_remove(struct platform_device *device) + struct channel_obj *ch; + int i; + +- v4l2_async_notifier_unregister(&vpif_obj.notifier); +- v4l2_async_notifier_cleanup(&vpif_obj.notifier); ++ v4l2_async_nf_unregister(&vpif_obj.notifier); ++ v4l2_async_nf_cleanup(&vpif_obj.notifier); + v4l2_device_unregister(&vpif_obj.v4l2_dev); + + kfree(vpif_obj.sd); +diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c +index b19d7c8ddc06b..b2d8b2c0ab4d6 100644 +--- a/drivers/media/platform/exynos4-is/media-dev.c ++++ b/drivers/media/platform/exynos4-is/media-dev.c +@@ -464,9 +464,9 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd, + return -EINVAL; + } + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &fmd->subdev_notifier, of_fwnode_handle(ep), +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&fmd->subdev_notifier, ++ of_fwnode_handle(ep), ++ struct v4l2_async_subdev); + + of_node_put(ep); + +@@ -557,7 +557,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) + + cleanup: + of_node_put(ports); +- v4l2_async_notifier_cleanup(&fmd->subdev_notifier); ++ v4l2_async_nf_cleanup(&fmd->subdev_notifier); + pm_runtime_put(fmd->pmf); + return ret; + } +@@ -1479,7 +1479,7 @@ static int fimc_md_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, fmd); + +- v4l2_async_notifier_init(&fmd->subdev_notifier); ++ v4l2_async_nf_init(&fmd->subdev_notifier); + + ret = fimc_md_register_platform_entities(fmd, dev->of_node); + if (ret) +@@ -1507,8 +1507,8 @@ static int fimc_md_probe(struct platform_device *pdev) + fmd->subdev_notifier.ops = &subdev_notifier_ops; + fmd->num_sensors = 0; + +- ret = v4l2_async_notifier_register(&fmd->v4l2_dev, +- &fmd->subdev_notifier); ++ ret = v4l2_async_nf_register(&fmd->v4l2_dev, ++ &fmd->subdev_notifier); + if (ret) + goto err_clk_p; + } +@@ -1520,7 +1520,7 @@ static int fimc_md_probe(struct platform_device *pdev) + err_attr: + device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); + err_cleanup: +- v4l2_async_notifier_cleanup(&fmd->subdev_notifier); ++ v4l2_async_nf_cleanup(&fmd->subdev_notifier); + err_m_ent: + fimc_md_unregister_entities(fmd); + err_clk: +@@ -1540,8 +1540,8 @@ static int fimc_md_remove(struct platform_device *pdev) + return 0; + + fimc_md_unregister_clk_provider(fmd); +- v4l2_async_notifier_unregister(&fmd->subdev_notifier); +- v4l2_async_notifier_cleanup(&fmd->subdev_notifier); ++ v4l2_async_nf_unregister(&fmd->subdev_notifier); ++ v4l2_async_nf_cleanup(&fmd->subdev_notifier); + + v4l2_device_unregister(&fmd->v4l2_dev); + device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); +diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c +index 9aa374fa8b364..b61b9d9551af5 100644 +--- a/drivers/media/platform/marvell-ccic/cafe-driver.c ++++ b/drivers/media/platform/marvell-ccic/cafe-driver.c +@@ -544,12 +544,11 @@ static int cafe_pci_probe(struct pci_dev *pdev, + if (ret) + goto out_pdown; + +- v4l2_async_notifier_init(&mcam->notifier); ++ v4l2_async_nf_init(&mcam->notifier); + +- asd = v4l2_async_notifier_add_i2c_subdev(&mcam->notifier, +- i2c_adapter_id(cam->i2c_adapter), +- ov7670_info.addr, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_i2c(&mcam->notifier, ++ i2c_adapter_id(cam->i2c_adapter), ++ ov7670_info.addr, struct v4l2_async_subdev); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto out_smbus_shutdown; +diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c +index 58f9463f3b8ce..ad4a7922d0d74 100644 +--- a/drivers/media/platform/marvell-ccic/mcam-core.c ++++ b/drivers/media/platform/marvell-ccic/mcam-core.c +@@ -1877,7 +1877,7 @@ int mccic_register(struct mcam_camera *cam) + cam->mbus_code = mcam_def_mbus_code; + + cam->notifier.ops = &mccic_notify_ops; +- ret = v4l2_async_notifier_register(&cam->v4l2_dev, &cam->notifier); ++ ret = v4l2_async_nf_register(&cam->v4l2_dev, &cam->notifier); + if (ret < 0) { + cam_warn(cam, "failed to register a sensor notifier"); + goto out; +@@ -1914,9 +1914,9 @@ int mccic_register(struct mcam_camera *cam) + return 0; + + out: +- v4l2_async_notifier_unregister(&cam->notifier); ++ v4l2_async_nf_unregister(&cam->notifier); + v4l2_device_unregister(&cam->v4l2_dev); +- v4l2_async_notifier_cleanup(&cam->notifier); ++ v4l2_async_nf_cleanup(&cam->notifier); + return ret; + } + EXPORT_SYMBOL_GPL(mccic_register); +@@ -1936,9 +1936,9 @@ void mccic_shutdown(struct mcam_camera *cam) + if (cam->buffer_mode == B_vmalloc) + mcam_free_dma_bufs(cam); + v4l2_ctrl_handler_free(&cam->ctrl_handler); +- v4l2_async_notifier_unregister(&cam->notifier); ++ v4l2_async_nf_unregister(&cam->notifier); + v4l2_device_unregister(&cam->v4l2_dev); +- v4l2_async_notifier_cleanup(&cam->notifier); ++ v4l2_async_nf_cleanup(&cam->notifier); + } + EXPORT_SYMBOL_GPL(mccic_shutdown); + +diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c +index f2f09cea751d8..343ab4f7d807b 100644 +--- a/drivers/media/platform/marvell-ccic/mmp-driver.c ++++ b/drivers/media/platform/marvell-ccic/mmp-driver.c +@@ -239,10 +239,10 @@ static int mmpcam_probe(struct platform_device *pdev) + if (!ep) + return -ENODEV; + +- v4l2_async_notifier_init(&mcam->notifier); ++ v4l2_async_nf_init(&mcam->notifier); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev(&mcam->notifier, ep, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&mcam->notifier, ep, ++ struct v4l2_async_subdev); + fwnode_handle_put(ep); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); +diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c +index 3222c98b83630..beafe85f28cca 100644 +--- a/drivers/media/platform/omap3isp/isp.c ++++ b/drivers/media/platform/omap3isp/isp.c +@@ -2003,7 +2003,7 @@ static int isp_remove(struct platform_device *pdev) + { + struct isp_device *isp = platform_get_drvdata(pdev); + +- v4l2_async_notifier_unregister(&isp->notifier); ++ v4l2_async_nf_unregister(&isp->notifier); + isp_unregister_entities(isp); + isp_cleanup_modules(isp); + isp_xclk_cleanup(isp); +@@ -2013,7 +2013,7 @@ static int isp_remove(struct platform_device *pdev) + __omap3isp_put(isp, false); + + media_entity_enum_cleanup(&isp->crashed); +- v4l2_async_notifier_cleanup(&isp->notifier); ++ v4l2_async_nf_cleanup(&isp->notifier); + + kfree(isp); + +@@ -2172,8 +2172,9 @@ static int isp_parse_of_endpoints(struct isp_device *isp) + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + + if (!ret) { +- isd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &isp->notifier, ep, struct isp_async_subdev); ++ isd = v4l2_async_nf_add_fwnode_remote(&isp->notifier, ++ ep, struct ++ isp_async_subdev); + if (!IS_ERR(isd)) + isp_parse_of_parallel_endpoint(isp->dev, &vep, &isd->bus); + } +@@ -2211,8 +2212,10 @@ static int isp_parse_of_endpoints(struct isp_device *isp) + } + + if (!ret) { +- isd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &isp->notifier, ep, struct isp_async_subdev); ++ isd = v4l2_async_nf_add_fwnode_remote(&isp->notifier, ++ ep, ++ struct ++ isp_async_subdev); + + if (!IS_ERR(isd)) { + switch (vep.bus_type) { +@@ -2289,7 +2292,7 @@ static int isp_probe(struct platform_device *pdev) + + mutex_init(&isp->isp_mutex); + spin_lock_init(&isp->stat_lock); +- v4l2_async_notifier_init(&isp->notifier); ++ v4l2_async_nf_init(&isp->notifier); + isp->dev = &pdev->dev; + + ret = isp_parse_of_endpoints(isp); +@@ -2427,7 +2430,7 @@ static int isp_probe(struct platform_device *pdev) + + isp->notifier.ops = &isp_subdev_notifier_ops; + +- ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier); ++ ret = v4l2_async_nf_register(&isp->v4l2_dev, &isp->notifier); + if (ret) + goto error_register_entities; + +@@ -2446,7 +2449,7 @@ static int isp_probe(struct platform_device *pdev) + isp_xclk_cleanup(isp); + __omap3isp_put(isp, false); + error: +- v4l2_async_notifier_cleanup(&isp->notifier); ++ v4l2_async_nf_cleanup(&isp->notifier); + mutex_destroy(&isp->isp_mutex); + error_release_isp: + kfree(isp); +diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c +index ec4c010644cae..3ba00b0f93200 100644 +--- a/drivers/media/platform/pxa_camera.c ++++ b/drivers/media/platform/pxa_camera.c +@@ -2249,10 +2249,9 @@ static int pxa_camera_pdata_from_dt(struct device *dev, + if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) + pcdev->platform_flags |= PXA_CAMERA_PCLK_EN; + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &pcdev->notifier, +- of_fwnode_handle(np), +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&pcdev->notifier, ++ of_fwnode_handle(np), ++ struct v4l2_async_subdev); + if (IS_ERR(asd)) + err = PTR_ERR(asd); + out: +@@ -2289,7 +2288,7 @@ static int pxa_camera_probe(struct platform_device *pdev) + if (IS_ERR(pcdev->clk)) + return PTR_ERR(pcdev->clk); + +- v4l2_async_notifier_init(&pcdev->notifier); ++ v4l2_async_nf_init(&pcdev->notifier); + pcdev->res = res; + pcdev->pdata = pdev->dev.platform_data; + if (pcdev->pdata) { +@@ -2297,11 +2296,10 @@ static int pxa_camera_probe(struct platform_device *pdev) + + pcdev->platform_flags = pcdev->pdata->flags; + pcdev->mclk = pcdev->pdata->mclk_10khz * 10000; +- asd = v4l2_async_notifier_add_i2c_subdev( +- &pcdev->notifier, +- pcdev->pdata->sensor_i2c_adapter_id, +- pcdev->pdata->sensor_i2c_address, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_i2c(&pcdev->notifier, ++ pcdev->pdata->sensor_i2c_adapter_id, ++ pcdev->pdata->sensor_i2c_address, ++ struct v4l2_async_subdev); + if (IS_ERR(asd)) + err = PTR_ERR(asd); + } else if (pdev->dev.of_node) { +@@ -2402,13 +2400,13 @@ static int pxa_camera_probe(struct platform_device *pdev) + goto exit_notifier_cleanup; + + pcdev->notifier.ops = &pxa_camera_sensor_ops; +- err = v4l2_async_notifier_register(&pcdev->v4l2_dev, &pcdev->notifier); ++ err = v4l2_async_nf_register(&pcdev->v4l2_dev, &pcdev->notifier); + if (err) + goto exit_notifier_cleanup; + + return 0; + exit_notifier_cleanup: +- v4l2_async_notifier_cleanup(&pcdev->notifier); ++ v4l2_async_nf_cleanup(&pcdev->notifier); + v4l2_device_unregister(&pcdev->v4l2_dev); + exit_deactivate: + pxa_camera_deactivate(pcdev); +@@ -2432,8 +2430,8 @@ static int pxa_camera_remove(struct platform_device *pdev) + dma_release_channel(pcdev->dma_chans[1]); + dma_release_channel(pcdev->dma_chans[2]); + +- v4l2_async_notifier_unregister(&pcdev->notifier); +- v4l2_async_notifier_cleanup(&pcdev->notifier); ++ v4l2_async_nf_unregister(&pcdev->notifier); ++ v4l2_async_nf_cleanup(&pcdev->notifier); + + v4l2_device_unregister(&pcdev->v4l2_dev); + +diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c +index ef100d5f77636..be091c50a3c0c 100644 +--- a/drivers/media/platform/qcom/camss/camss.c ++++ b/drivers/media/platform/qcom/camss/camss.c +@@ -886,9 +886,9 @@ static int camss_of_parse_ports(struct camss *camss) + goto err_cleanup; + } + +- csd = v4l2_async_notifier_add_fwnode_subdev( +- &camss->notifier, of_fwnode_handle(remote), +- struct camss_async_subdev); ++ csd = v4l2_async_nf_add_fwnode(&camss->notifier, ++ of_fwnode_handle(remote), ++ struct camss_async_subdev); + of_node_put(remote); + if (IS_ERR(csd)) { + ret = PTR_ERR(csd); +@@ -1361,7 +1361,7 @@ static int camss_probe(struct platform_device *pdev) + goto err_free; + } + +- v4l2_async_notifier_init(&camss->notifier); ++ v4l2_async_nf_init(&camss->notifier); + + num_subdevs = camss_of_parse_ports(camss); + if (num_subdevs < 0) { +@@ -1397,8 +1397,8 @@ static int camss_probe(struct platform_device *pdev) + if (num_subdevs) { + camss->notifier.ops = &camss_subdev_notifier_ops; + +- ret = v4l2_async_notifier_register(&camss->v4l2_dev, +- &camss->notifier); ++ ret = v4l2_async_nf_register(&camss->v4l2_dev, ++ &camss->notifier); + if (ret) { + dev_err(dev, + "Failed to register async subdev nodes: %d\n", +@@ -1436,7 +1436,7 @@ static int camss_probe(struct platform_device *pdev) + err_register_entities: + v4l2_device_unregister(&camss->v4l2_dev); + err_cleanup: +- v4l2_async_notifier_cleanup(&camss->notifier); ++ v4l2_async_nf_cleanup(&camss->notifier); + err_free: + kfree(camss); + +@@ -1478,8 +1478,8 @@ static int camss_remove(struct platform_device *pdev) + { + struct camss *camss = platform_get_drvdata(pdev); + +- v4l2_async_notifier_unregister(&camss->notifier); +- v4l2_async_notifier_cleanup(&camss->notifier); ++ v4l2_async_nf_unregister(&camss->notifier); ++ v4l2_async_nf_cleanup(&camss->notifier); + camss_unregister_entities(camss); + + if (atomic_read(&camss->ref_count) == 0) +diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c +index 5a280d8ff7dd0..d1786aa8a7ecd 100644 +--- a/drivers/media/platform/rcar-vin/rcar-core.c ++++ b/drivers/media/platform/rcar-vin/rcar-core.c +@@ -535,9 +535,8 @@ static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id) + goto out; + } + +- asd = v4l2_async_notifier_add_fwnode_subdev(&vin->group->notifier, +- fwnode, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode, ++ struct v4l2_async_subdev); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto out; +@@ -557,8 +556,8 @@ static void rvin_group_notifier_cleanup(struct rvin_dev *vin) + { + mutex_lock(&vin->group->lock); + if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) { +- v4l2_async_notifier_unregister(&vin->group->notifier); +- v4l2_async_notifier_cleanup(&vin->group->notifier); ++ v4l2_async_nf_unregister(&vin->group->notifier); ++ v4l2_async_nf_cleanup(&vin->group->notifier); + } + mutex_unlock(&vin->group->lock); + } +@@ -586,7 +585,7 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin) + + mutex_unlock(&vin->group->lock); + +- v4l2_async_notifier_init(&vin->group->notifier); ++ v4l2_async_nf_init(&vin->group->notifier); + + /* + * Have all VIN's look for CSI-2 subdevices. Some subdevices will +@@ -611,11 +610,10 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin) + return 0; + + vin->group->notifier.ops = &rvin_group_notify_ops; +- ret = v4l2_async_notifier_register(&vin->v4l2_dev, +- &vin->group->notifier); ++ ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->group->notifier); + if (ret < 0) { + vin_err(vin, "Notifier registration failed\n"); +- v4l2_async_notifier_cleanup(&vin->group->notifier); ++ v4l2_async_nf_cleanup(&vin->group->notifier); + return ret; + } + +@@ -899,8 +897,8 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin) + goto out; + } + +- asd = v4l2_async_notifier_add_fwnode_subdev(&vin->notifier, fwnode, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode, ++ struct v4l2_async_subdev); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto out; +@@ -917,15 +915,15 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin) + + static void rvin_parallel_cleanup(struct rvin_dev *vin) + { +- v4l2_async_notifier_unregister(&vin->notifier); +- v4l2_async_notifier_cleanup(&vin->notifier); ++ v4l2_async_nf_unregister(&vin->notifier); ++ v4l2_async_nf_cleanup(&vin->notifier); + } + + static int rvin_parallel_init(struct rvin_dev *vin) + { + int ret; + +- v4l2_async_notifier_init(&vin->notifier); ++ v4l2_async_nf_init(&vin->notifier); + + ret = rvin_parallel_parse_of(vin); + if (ret) +@@ -939,10 +937,10 @@ static int rvin_parallel_init(struct rvin_dev *vin) + to_of_node(vin->parallel.asd->match.fwnode)); + + vin->notifier.ops = &rvin_parallel_notify_ops; +- ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier); ++ ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->notifier); + if (ret < 0) { + vin_err(vin, "Notifier registration failed\n"); +- v4l2_async_notifier_cleanup(&vin->notifier); ++ v4l2_async_nf_cleanup(&vin->notifier); + return ret; + } + +diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c +index 0c5e2f7e04beb..5e9cb72676e39 100644 +--- a/drivers/media/platform/rcar-vin/rcar-csi2.c ++++ b/drivers/media/platform/rcar-vin/rcar-csi2.c +@@ -926,19 +926,18 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv) + + dev_dbg(priv->dev, "Found '%pOF'\n", to_of_node(fwnode)); + +- v4l2_async_notifier_init(&priv->notifier); ++ v4l2_async_nf_init(&priv->notifier); + priv->notifier.ops = &rcar_csi2_notify_ops; + +- asd = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier, fwnode, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode(&priv->notifier, fwnode, ++ struct v4l2_async_subdev); + fwnode_handle_put(fwnode); + if (IS_ERR(asd)) + return PTR_ERR(asd); + +- ret = v4l2_async_subdev_notifier_register(&priv->subdev, +- &priv->notifier); ++ ret = v4l2_async_subdev_nf_register(&priv->subdev, &priv->notifier); + if (ret) +- v4l2_async_notifier_cleanup(&priv->notifier); ++ v4l2_async_nf_cleanup(&priv->notifier); + + return ret; + } +@@ -1301,8 +1300,8 @@ static int rcsi2_probe(struct platform_device *pdev) + return 0; + + error: +- v4l2_async_notifier_unregister(&priv->notifier); +- v4l2_async_notifier_cleanup(&priv->notifier); ++ v4l2_async_nf_unregister(&priv->notifier); ++ v4l2_async_nf_cleanup(&priv->notifier); + + return ret; + } +@@ -1311,8 +1310,8 @@ static int rcsi2_remove(struct platform_device *pdev) + { + struct rcar_csi2 *priv = platform_get_drvdata(pdev); + +- v4l2_async_notifier_unregister(&priv->notifier); +- v4l2_async_notifier_cleanup(&priv->notifier); ++ v4l2_async_nf_unregister(&priv->notifier); ++ v4l2_async_nf_cleanup(&priv->notifier); + v4l2_async_unregister_subdev(&priv->subdev); + + pm_runtime_disable(&pdev->dev); +diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c +index 1e3b68a8743af..a505d991548bb 100644 +--- a/drivers/media/platform/rcar_drif.c ++++ b/drivers/media/platform/rcar_drif.c +@@ -1212,7 +1212,7 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr) + struct fwnode_handle *fwnode, *ep; + struct v4l2_async_subdev *asd; + +- v4l2_async_notifier_init(notifier); ++ v4l2_async_nf_init(notifier); + + ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(sdr->dev->of_node), + NULL); +@@ -1229,8 +1229,8 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr) + return -EINVAL; + } + +- asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode(notifier, fwnode, ++ struct v4l2_async_subdev); + fwnode_handle_put(fwnode); + if (IS_ERR(asd)) + return PTR_ERR(asd); +@@ -1346,7 +1346,7 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr) + sdr->notifier.ops = &rcar_drif_notify_ops; + + /* Register notifier */ +- ret = v4l2_async_notifier_register(&sdr->v4l2_dev, &sdr->notifier); ++ ret = v4l2_async_nf_register(&sdr->v4l2_dev, &sdr->notifier); + if (ret < 0) { + dev_err(sdr->dev, "failed: notifier register ret %d\n", ret); + goto cleanup; +@@ -1355,7 +1355,7 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr) + return ret; + + cleanup: +- v4l2_async_notifier_cleanup(&sdr->notifier); ++ v4l2_async_nf_cleanup(&sdr->notifier); + error: + v4l2_device_unregister(&sdr->v4l2_dev); + +@@ -1365,8 +1365,8 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr) + /* V4L2 SDR device remove */ + static void rcar_drif_sdr_remove(struct rcar_drif_sdr *sdr) + { +- v4l2_async_notifier_unregister(&sdr->notifier); +- v4l2_async_notifier_cleanup(&sdr->notifier); ++ v4l2_async_nf_unregister(&sdr->notifier); ++ v4l2_async_nf_cleanup(&sdr->notifier); + v4l2_device_unregister(&sdr->v4l2_dev); + } + +diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c +index f432032c7084f..9376eb363748b 100644 +--- a/drivers/media/platform/renesas-ceu.c ++++ b/drivers/media/platform/renesas-ceu.c +@@ -1513,12 +1513,12 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev, + + /* Setup the ceu subdevice and the async subdevice. */ + async_sd = &pdata->subdevs[i]; +- ceu_sd = v4l2_async_notifier_add_i2c_subdev(&ceudev->notifier, +- async_sd->i2c_adapter_id, +- async_sd->i2c_address, +- struct ceu_subdev); ++ ceu_sd = v4l2_async_nf_add_i2c(&ceudev->notifier, ++ async_sd->i2c_adapter_id, ++ async_sd->i2c_address, ++ struct ceu_subdev); + if (IS_ERR(ceu_sd)) { +- v4l2_async_notifier_cleanup(&ceudev->notifier); ++ v4l2_async_nf_cleanup(&ceudev->notifier); + return PTR_ERR(ceu_sd); + } + ceu_sd->mbus_flags = async_sd->flags; +@@ -1576,9 +1576,9 @@ static int ceu_parse_dt(struct ceu_device *ceudev) + } + + /* Setup the ceu subdevice and the async subdevice. */ +- ceu_sd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &ceudev->notifier, of_fwnode_handle(ep), +- struct ceu_subdev); ++ ceu_sd = v4l2_async_nf_add_fwnode_remote(&ceudev->notifier, ++ of_fwnode_handle(ep), ++ struct ceu_subdev); + if (IS_ERR(ceu_sd)) { + ret = PTR_ERR(ceu_sd); + goto error_cleanup; +@@ -1592,7 +1592,7 @@ static int ceu_parse_dt(struct ceu_device *ceudev) + return num_ep; + + error_cleanup: +- v4l2_async_notifier_cleanup(&ceudev->notifier); ++ v4l2_async_nf_cleanup(&ceudev->notifier); + of_node_put(ep); + return ret; + } +@@ -1669,7 +1669,7 @@ static int ceu_probe(struct platform_device *pdev) + if (ret) + goto error_pm_disable; + +- v4l2_async_notifier_init(&ceudev->notifier); ++ v4l2_async_nf_init(&ceudev->notifier); + + if (IS_ENABLED(CONFIG_OF) && dev->of_node) { + ceu_data = of_device_get_match_data(dev); +@@ -1691,8 +1691,7 @@ static int ceu_probe(struct platform_device *pdev) + + ceudev->notifier.v4l2_dev = &ceudev->v4l2_dev; + ceudev->notifier.ops = &ceu_notify_ops; +- ret = v4l2_async_notifier_register(&ceudev->v4l2_dev, +- &ceudev->notifier); ++ ret = v4l2_async_nf_register(&ceudev->v4l2_dev, &ceudev->notifier); + if (ret) + goto error_cleanup; + +@@ -1701,7 +1700,7 @@ static int ceu_probe(struct platform_device *pdev) + return 0; + + error_cleanup: +- v4l2_async_notifier_cleanup(&ceudev->notifier); ++ v4l2_async_nf_cleanup(&ceudev->notifier); + error_v4l2_unregister: + v4l2_device_unregister(&ceudev->v4l2_dev); + error_pm_disable: +@@ -1718,9 +1717,9 @@ static int ceu_remove(struct platform_device *pdev) + + pm_runtime_disable(ceudev->dev); + +- v4l2_async_notifier_unregister(&ceudev->notifier); ++ v4l2_async_nf_unregister(&ceudev->notifier); + +- v4l2_async_notifier_cleanup(&ceudev->notifier); ++ v4l2_async_nf_cleanup(&ceudev->notifier); + + v4l2_device_unregister(&ceudev->v4l2_dev); + +diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +index 560f928c37520..b6a4522c2970d 100644 +--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c ++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +@@ -246,7 +246,7 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1) + unsigned int next_id = 0; + int ret; + +- v4l2_async_notifier_init(ntf); ++ v4l2_async_nf_init(ntf); + + while (1) { + struct v4l2_fwnode_endpoint vep = { +@@ -265,8 +265,9 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1) + if (ret) + goto err_parse; + +- rk_asd = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep, +- struct rkisp1_sensor_async); ++ rk_asd = v4l2_async_nf_add_fwnode_remote(ntf, ep, ++ struct ++ rkisp1_sensor_async); + if (IS_ERR(rk_asd)) { + ret = PTR_ERR(rk_asd); + goto err_parse; +@@ -286,16 +287,16 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1) + continue; + err_parse: + fwnode_handle_put(ep); +- v4l2_async_notifier_cleanup(ntf); ++ v4l2_async_nf_cleanup(ntf); + return ret; + } + + if (next_id == 0) + dev_dbg(rkisp1->dev, "no remote subdevice found\n"); + ntf->ops = &rkisp1_subdev_notifier_ops; +- ret = v4l2_async_notifier_register(&rkisp1->v4l2_dev, ntf); ++ ret = v4l2_async_nf_register(&rkisp1->v4l2_dev, ntf); + if (ret) { +- v4l2_async_notifier_cleanup(ntf); ++ v4l2_async_nf_cleanup(ntf); + return ret; + } + return 0; +@@ -542,8 +543,8 @@ static int rkisp1_remove(struct platform_device *pdev) + { + struct rkisp1_device *rkisp1 = platform_get_drvdata(pdev); + +- v4l2_async_notifier_unregister(&rkisp1->notifier); +- v4l2_async_notifier_cleanup(&rkisp1->notifier); ++ v4l2_async_nf_unregister(&rkisp1->notifier); ++ v4l2_async_nf_cleanup(&rkisp1->notifier); + + rkisp1_params_unregister(rkisp1); + rkisp1_stats_unregister(rkisp1); +diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c +index 6110718645a4f..e1b17c05229cf 100644 +--- a/drivers/media/platform/stm32/stm32-dcmi.c ++++ b/drivers/media/platform/stm32/stm32-dcmi.c +@@ -1833,11 +1833,11 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) + return -EINVAL; + } + +- v4l2_async_notifier_init(&dcmi->notifier); ++ v4l2_async_nf_init(&dcmi->notifier); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &dcmi->notifier, of_fwnode_handle(ep), +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&dcmi->notifier, ++ of_fwnode_handle(ep), ++ struct v4l2_async_subdev); + + of_node_put(ep); + +@@ -1848,10 +1848,10 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) + + dcmi->notifier.ops = &dcmi_graph_notify_ops; + +- ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier); ++ ret = v4l2_async_nf_register(&dcmi->v4l2_dev, &dcmi->notifier); + if (ret < 0) { + dev_err(dcmi->dev, "Failed to register notifier\n"); +- v4l2_async_notifier_cleanup(&dcmi->notifier); ++ v4l2_async_nf_cleanup(&dcmi->notifier); + return ret; + } + +@@ -2063,7 +2063,7 @@ static int dcmi_probe(struct platform_device *pdev) + return 0; + + err_cleanup: +- v4l2_async_notifier_cleanup(&dcmi->notifier); ++ v4l2_async_nf_cleanup(&dcmi->notifier); + err_media_entity_cleanup: + media_entity_cleanup(&dcmi->vdev->entity); + err_device_release: +@@ -2083,8 +2083,8 @@ static int dcmi_remove(struct platform_device *pdev) + + pm_runtime_disable(&pdev->dev); + +- v4l2_async_notifier_unregister(&dcmi->notifier); +- v4l2_async_notifier_cleanup(&dcmi->notifier); ++ v4l2_async_nf_unregister(&dcmi->notifier); ++ v4l2_async_nf_cleanup(&dcmi->notifier); + media_entity_cleanup(&dcmi->vdev->entity); + v4l2_device_unregister(&dcmi->v4l2_dev); + media_device_cleanup(&dcmi->mdev); +diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +index 8d40a7acba9c4..94e98e470aff7 100644 +--- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c ++++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +@@ -122,7 +122,7 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi) + struct fwnode_handle *ep; + int ret; + +- v4l2_async_notifier_init(&csi->notifier); ++ v4l2_async_nf_init(&csi->notifier); + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); +@@ -135,8 +135,8 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi) + + csi->bus = vep.bus.parallel; + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier, ep, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep, ++ struct v4l2_async_subdev); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto out; +@@ -244,7 +244,7 @@ static int sun4i_csi_probe(struct platform_device *pdev) + if (ret) + goto err_unregister_media; + +- ret = v4l2_async_notifier_register(&csi->v4l, &csi->notifier); ++ ret = v4l2_async_nf_register(&csi->v4l, &csi->notifier); + if (ret) { + dev_err(csi->dev, "Couldn't register our notifier.\n"); + goto err_unregister_media; +@@ -268,8 +268,8 @@ static int sun4i_csi_remove(struct platform_device *pdev) + { + struct sun4i_csi *csi = platform_get_drvdata(pdev); + +- v4l2_async_notifier_unregister(&csi->notifier); +- v4l2_async_notifier_cleanup(&csi->notifier); ++ v4l2_async_nf_unregister(&csi->notifier); ++ v4l2_async_nf_cleanup(&csi->notifier); + vb2_video_unregister_device(&csi->vdev); + media_device_unregister(&csi->mdev); + sun4i_csi_dma_unregister(csi); +diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +index 27935f1e9555e..08df0c833423b 100644 +--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c ++++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +@@ -717,8 +717,8 @@ static int sun6i_csi_fwnode_parse(struct device *dev, + static void sun6i_csi_v4l2_cleanup(struct sun6i_csi *csi) + { + media_device_unregister(&csi->media_dev); +- v4l2_async_notifier_unregister(&csi->notifier); +- v4l2_async_notifier_cleanup(&csi->notifier); ++ v4l2_async_nf_unregister(&csi->notifier); ++ v4l2_async_nf_cleanup(&csi->notifier); + sun6i_video_cleanup(&csi->video); + v4l2_device_unregister(&csi->v4l2_dev); + v4l2_ctrl_handler_free(&csi->ctrl_handler); +@@ -737,7 +737,7 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi) + "platform:%s", dev_name(csi->dev)); + + media_device_init(&csi->media_dev); +- v4l2_async_notifier_init(&csi->notifier); ++ v4l2_async_nf_init(&csi->notifier); + + ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 0); + if (ret) { +@@ -759,16 +759,17 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi) + if (ret) + goto unreg_v4l2; + +- ret = v4l2_async_notifier_parse_fwnode_endpoints(csi->dev, +- &csi->notifier, +- sizeof(struct v4l2_async_subdev), +- sun6i_csi_fwnode_parse); ++ ret = v4l2_async_nf_parse_fwnode_endpoints(csi->dev, ++ &csi->notifier, ++ sizeof(struct ++ v4l2_async_subdev), ++ sun6i_csi_fwnode_parse); + if (ret) + goto clean_video; + + csi->notifier.ops = &sun6i_csi_async_ops; + +- ret = v4l2_async_notifier_register(&csi->v4l2_dev, &csi->notifier); ++ ret = v4l2_async_nf_register(&csi->v4l2_dev, &csi->notifier); + if (ret) { + dev_err(csi->dev, "notifier registration failed\n"); + goto clean_video; +@@ -783,7 +784,7 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi) + free_ctrl: + v4l2_ctrl_handler_free(&csi->ctrl_handler); + clean_media: +- v4l2_async_notifier_cleanup(&csi->notifier); ++ v4l2_async_nf_cleanup(&csi->notifier); + media_device_cleanup(&csi->media_dev); + + return ret; +diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c +index 35d62eb1321fb..0e583120266ff 100644 +--- a/drivers/media/platform/ti-vpe/cal.c ++++ b/drivers/media/platform/ti-vpe/cal.c +@@ -781,7 +781,7 @@ static int cal_async_notifier_register(struct cal_dev *cal) + unsigned int i; + int ret; + +- v4l2_async_notifier_init(&cal->notifier); ++ v4l2_async_nf_init(&cal->notifier); + cal->notifier.ops = &cal_async_notifier_ops; + + for (i = 0; i < cal->data->num_csi2_phy; ++i) { +@@ -793,9 +793,9 @@ static int cal_async_notifier_register(struct cal_dev *cal) + continue; + + fwnode = of_fwnode_handle(phy->source_node); +- casd = v4l2_async_notifier_add_fwnode_subdev(&cal->notifier, +- fwnode, +- struct cal_v4l2_async_subdev); ++ casd = v4l2_async_nf_add_fwnode(&cal->notifier, ++ fwnode, ++ struct cal_v4l2_async_subdev); + if (IS_ERR(casd)) { + phy_err(phy, "Failed to add subdev to notifier\n"); + ret = PTR_ERR(casd); +@@ -805,7 +805,7 @@ static int cal_async_notifier_register(struct cal_dev *cal) + casd->phy = phy; + } + +- ret = v4l2_async_notifier_register(&cal->v4l2_dev, &cal->notifier); ++ ret = v4l2_async_nf_register(&cal->v4l2_dev, &cal->notifier); + if (ret) { + cal_err(cal, "Error registering async notifier\n"); + goto error; +@@ -814,14 +814,14 @@ static int cal_async_notifier_register(struct cal_dev *cal) + return 0; + + error: +- v4l2_async_notifier_cleanup(&cal->notifier); ++ v4l2_async_nf_cleanup(&cal->notifier); + return ret; + } + + static void cal_async_notifier_unregister(struct cal_dev *cal) + { +- v4l2_async_notifier_unregister(&cal->notifier); +- v4l2_async_notifier_cleanup(&cal->notifier); ++ v4l2_async_nf_unregister(&cal->notifier); ++ v4l2_async_nf_cleanup(&cal->notifier); + } + + /* ------------------------------------------------------------------ +diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c +index 905005e271ca9..fda8fc0e48143 100644 +--- a/drivers/media/platform/video-mux.c ++++ b/drivers/media/platform/video-mux.c +@@ -360,7 +360,7 @@ static int video_mux_async_register(struct video_mux *vmux, + unsigned int i; + int ret; + +- v4l2_async_notifier_init(&vmux->notifier); ++ v4l2_async_nf_init(&vmux->notifier); + + for (i = 0; i < num_input_pads; i++) { + struct v4l2_async_subdev *asd; +@@ -380,8 +380,8 @@ static int video_mux_async_register(struct video_mux *vmux, + } + fwnode_handle_put(remote_ep); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &vmux->notifier, ep, struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&vmux->notifier, ep, ++ struct v4l2_async_subdev); + + fwnode_handle_put(ep); + +@@ -395,8 +395,7 @@ static int video_mux_async_register(struct video_mux *vmux, + + vmux->notifier.ops = &video_mux_notify_ops; + +- ret = v4l2_async_subdev_notifier_register(&vmux->subdev, +- &vmux->notifier); ++ ret = v4l2_async_subdev_nf_register(&vmux->subdev, &vmux->notifier); + if (ret) + return ret; + +@@ -477,8 +476,8 @@ static int video_mux_probe(struct platform_device *pdev) + + ret = video_mux_async_register(vmux, num_pads - 1); + if (ret) { +- v4l2_async_notifier_unregister(&vmux->notifier); +- v4l2_async_notifier_cleanup(&vmux->notifier); ++ v4l2_async_nf_unregister(&vmux->notifier); ++ v4l2_async_nf_cleanup(&vmux->notifier); + } + + return ret; +@@ -489,8 +488,8 @@ static int video_mux_remove(struct platform_device *pdev) + struct video_mux *vmux = platform_get_drvdata(pdev); + struct v4l2_subdev *sd = &vmux->subdev; + +- v4l2_async_notifier_unregister(&vmux->notifier); +- v4l2_async_notifier_cleanup(&vmux->notifier); ++ v4l2_async_nf_unregister(&vmux->notifier); ++ v4l2_async_nf_cleanup(&vmux->notifier); + v4l2_async_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + +diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c +index 5896a662da3ba..0a16c218a50a7 100644 +--- a/drivers/media/platform/xilinx/xilinx-vipp.c ++++ b/drivers/media/platform/xilinx/xilinx-vipp.c +@@ -382,9 +382,8 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev, + continue; + } + +- xge = v4l2_async_notifier_add_fwnode_subdev( +- &xdev->notifier, remote, +- struct xvip_graph_entity); ++ xge = v4l2_async_nf_add_fwnode(&xdev->notifier, remote, ++ struct xvip_graph_entity); + fwnode_handle_put(remote); + if (IS_ERR(xge)) { + ret = PTR_ERR(xge); +@@ -395,7 +394,7 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev, + return 0; + + err_notifier_cleanup: +- v4l2_async_notifier_cleanup(&xdev->notifier); ++ v4l2_async_nf_cleanup(&xdev->notifier); + fwnode_handle_put(ep); + return ret; + } +@@ -420,7 +419,7 @@ static int xvip_graph_parse(struct xvip_composite_device *xdev) + entity = to_xvip_entity(asd); + ret = xvip_graph_parse_one(xdev, entity->asd.match.fwnode); + if (ret < 0) { +- v4l2_async_notifier_cleanup(&xdev->notifier); ++ v4l2_async_nf_cleanup(&xdev->notifier); + break; + } + } +@@ -497,8 +496,8 @@ static void xvip_graph_cleanup(struct xvip_composite_device *xdev) + struct xvip_dma *dmap; + struct xvip_dma *dma; + +- v4l2_async_notifier_unregister(&xdev->notifier); +- v4l2_async_notifier_cleanup(&xdev->notifier); ++ v4l2_async_nf_unregister(&xdev->notifier); ++ v4l2_async_nf_cleanup(&xdev->notifier); + + list_for_each_entry_safe(dma, dmap, &xdev->dmas, list) { + xvip_dma_cleanup(dma); +@@ -533,7 +532,7 @@ static int xvip_graph_init(struct xvip_composite_device *xdev) + /* Register the subdevices notifier. */ + xdev->notifier.ops = &xvip_graph_notify_ops; + +- ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier); ++ ret = v4l2_async_nf_register(&xdev->v4l2_dev, &xdev->notifier); + if (ret < 0) { + dev_err(xdev->dev, "notifier registration failed\n"); + goto done; +@@ -597,7 +596,7 @@ static int xvip_composite_probe(struct platform_device *pdev) + + xdev->dev = &pdev->dev; + INIT_LIST_HEAD(&xdev->dmas); +- v4l2_async_notifier_init(&xdev->notifier); ++ v4l2_async_nf_init(&xdev->notifier); + + ret = xvip_composite_v4l2_init(xdev); + if (ret < 0) +diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c +index cd9e78c63791b..0404267f1ae4f 100644 +--- a/drivers/media/v4l2-core/v4l2-async.c ++++ b/drivers/media/v4l2-core/v4l2-async.c +@@ -24,9 +24,9 @@ + #include + #include + +-static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n, +- struct v4l2_subdev *subdev, +- struct v4l2_async_subdev *asd) ++static int v4l2_async_nf_call_bound(struct v4l2_async_notifier *n, ++ struct v4l2_subdev *subdev, ++ struct v4l2_async_subdev *asd) + { + if (!n->ops || !n->ops->bound) + return 0; +@@ -34,9 +34,9 @@ static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n, + return n->ops->bound(n, subdev, asd); + } + +-static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n, +- struct v4l2_subdev *subdev, +- struct v4l2_async_subdev *asd) ++static void v4l2_async_nf_call_unbind(struct v4l2_async_notifier *n, ++ struct v4l2_subdev *subdev, ++ struct v4l2_async_subdev *asd) + { + if (!n->ops || !n->ops->unbind) + return; +@@ -44,7 +44,7 @@ static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n, + n->ops->unbind(n, subdev, asd); + } + +-static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n) ++static int v4l2_async_nf_call_complete(struct v4l2_async_notifier *n) + { + if (!n->ops || !n->ops->complete) + return 0; +@@ -215,7 +215,7 @@ v4l2_async_find_subdev_notifier(struct v4l2_subdev *sd) + + /* Get v4l2_device related to the notifier if one can be found. */ + static struct v4l2_device * +-v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier) ++v4l2_async_nf_find_v4l2_dev(struct v4l2_async_notifier *notifier) + { + while (notifier->parent) + notifier = notifier->parent; +@@ -227,7 +227,7 @@ v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier) + * Return true if all child sub-device notifiers are complete, false otherwise. + */ + static bool +-v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier) ++v4l2_async_nf_can_complete(struct v4l2_async_notifier *notifier) + { + struct v4l2_subdev *sd; + +@@ -239,7 +239,7 @@ v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier) + v4l2_async_find_subdev_notifier(sd); + + if (subdev_notifier && +- !v4l2_async_notifier_can_complete(subdev_notifier)) ++ !v4l2_async_nf_can_complete(subdev_notifier)) + return false; + } + +@@ -251,7 +251,7 @@ v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier) + * sub-devices have been bound; v4l2_device is also available then. + */ + static int +-v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier) ++v4l2_async_nf_try_complete(struct v4l2_async_notifier *notifier) + { + /* Quick check whether there are still more sub-devices here. */ + if (!list_empty(¬ifier->waiting)) +@@ -266,14 +266,14 @@ v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier) + return 0; + + /* Is everything ready? */ +- if (!v4l2_async_notifier_can_complete(notifier)) ++ if (!v4l2_async_nf_can_complete(notifier)) + return 0; + +- return v4l2_async_notifier_call_complete(notifier); ++ return v4l2_async_nf_call_complete(notifier); + } + + static int +-v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier); ++v4l2_async_nf_try_all_subdevs(struct v4l2_async_notifier *notifier); + + static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, + struct v4l2_device *v4l2_dev, +@@ -287,7 +287,7 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, + if (ret < 0) + return ret; + +- ret = v4l2_async_notifier_call_bound(notifier, sd, asd); ++ ret = v4l2_async_nf_call_bound(notifier, sd, asd); + if (ret < 0) { + v4l2_device_unregister_subdev(sd); + return ret; +@@ -315,15 +315,15 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, + */ + subdev_notifier->parent = notifier; + +- return v4l2_async_notifier_try_all_subdevs(subdev_notifier); ++ return v4l2_async_nf_try_all_subdevs(subdev_notifier); + } + + /* Test all async sub-devices in a notifier for a match. */ + static int +-v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier) ++v4l2_async_nf_try_all_subdevs(struct v4l2_async_notifier *notifier) + { + struct v4l2_device *v4l2_dev = +- v4l2_async_notifier_find_v4l2_dev(notifier); ++ v4l2_async_nf_find_v4l2_dev(notifier); + struct v4l2_subdev *sd; + + if (!v4l2_dev) +@@ -367,7 +367,7 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd) + + /* Unbind all sub-devices in the notifier tree. */ + static void +-v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier) ++v4l2_async_nf_unbind_all_subdevs(struct v4l2_async_notifier *notifier) + { + struct v4l2_subdev *sd, *tmp; + +@@ -376,9 +376,9 @@ v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier) + v4l2_async_find_subdev_notifier(sd); + + if (subdev_notifier) +- v4l2_async_notifier_unbind_all_subdevs(subdev_notifier); ++ v4l2_async_nf_unbind_all_subdevs(subdev_notifier); + +- v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); ++ v4l2_async_nf_call_unbind(notifier, sd, sd->asd); + v4l2_async_cleanup(sd); + + list_move(&sd->async_list, &subdev_list); +@@ -389,8 +389,8 @@ v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier) + + /* See if an async sub-device can be found in a notifier's lists. */ + static bool +-__v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, +- struct v4l2_async_subdev *asd) ++__v4l2_async_nf_has_async_subdev(struct v4l2_async_notifier *notifier, ++ struct v4l2_async_subdev *asd) + { + struct v4l2_async_subdev *asd_y; + struct v4l2_subdev *sd; +@@ -416,9 +416,8 @@ __v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, + * If @this_index < 0, search the notifier's entire @asd_list. + */ + static bool +-v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, +- struct v4l2_async_subdev *asd, +- int this_index) ++v4l2_async_nf_has_async_subdev(struct v4l2_async_notifier *notifier, ++ struct v4l2_async_subdev *asd, int this_index) + { + struct v4l2_async_subdev *asd_y; + int j = 0; +@@ -435,15 +434,15 @@ v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, + + /* Check that an asd does not exist in other notifiers. */ + list_for_each_entry(notifier, ¬ifier_list, list) +- if (__v4l2_async_notifier_has_async_subdev(notifier, asd)) ++ if (__v4l2_async_nf_has_async_subdev(notifier, asd)) + return true; + + return false; + } + +-static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier, +- struct v4l2_async_subdev *asd, +- int this_index) ++static int v4l2_async_nf_asd_valid(struct v4l2_async_notifier *notifier, ++ struct v4l2_async_subdev *asd, ++ int this_index) + { + struct device *dev = + notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL; +@@ -454,8 +453,7 @@ static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier, + switch (asd->match_type) { + case V4L2_ASYNC_MATCH_I2C: + case V4L2_ASYNC_MATCH_FWNODE: +- if (v4l2_async_notifier_has_async_subdev(notifier, asd, +- this_index)) { ++ if (v4l2_async_nf_has_async_subdev(notifier, asd, this_index)) { + dev_dbg(dev, "subdev descriptor already listed in this or other notifiers\n"); + return -EEXIST; + } +@@ -469,13 +467,13 @@ static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier, + return 0; + } + +-void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier) ++void v4l2_async_nf_init(struct v4l2_async_notifier *notifier) + { + INIT_LIST_HEAD(¬ifier->asd_list); + } +-EXPORT_SYMBOL(v4l2_async_notifier_init); ++EXPORT_SYMBOL(v4l2_async_nf_init); + +-static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) ++static int __v4l2_async_nf_register(struct v4l2_async_notifier *notifier) + { + struct v4l2_async_subdev *asd; + int ret, i = 0; +@@ -486,18 +484,18 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) + mutex_lock(&list_lock); + + list_for_each_entry(asd, ¬ifier->asd_list, asd_list) { +- ret = v4l2_async_notifier_asd_valid(notifier, asd, i++); ++ ret = v4l2_async_nf_asd_valid(notifier, asd, i++); + if (ret) + goto err_unlock; + + list_add_tail(&asd->list, ¬ifier->waiting); + } + +- ret = v4l2_async_notifier_try_all_subdevs(notifier); ++ ret = v4l2_async_nf_try_all_subdevs(notifier); + if (ret < 0) + goto err_unbind; + +- ret = v4l2_async_notifier_try_complete(notifier); ++ ret = v4l2_async_nf_try_complete(notifier); + if (ret < 0) + goto err_unbind; + +@@ -512,7 +510,7 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) + /* + * On failure, unbind all sub-devices registered through this notifier. + */ +- v4l2_async_notifier_unbind_all_subdevs(notifier); ++ v4l2_async_nf_unbind_all_subdevs(notifier); + + err_unlock: + mutex_unlock(&list_lock); +@@ -520,8 +518,8 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) + return ret; + } + +-int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, +- struct v4l2_async_notifier *notifier) ++int v4l2_async_nf_register(struct v4l2_device *v4l2_dev, ++ struct v4l2_async_notifier *notifier) + { + int ret; + +@@ -530,16 +528,16 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, + + notifier->v4l2_dev = v4l2_dev; + +- ret = __v4l2_async_notifier_register(notifier); ++ ret = __v4l2_async_nf_register(notifier); + if (ret) + notifier->v4l2_dev = NULL; + + return ret; + } +-EXPORT_SYMBOL(v4l2_async_notifier_register); ++EXPORT_SYMBOL(v4l2_async_nf_register); + +-int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, +- struct v4l2_async_notifier *notifier) ++int v4l2_async_subdev_nf_register(struct v4l2_subdev *sd, ++ struct v4l2_async_notifier *notifier) + { + int ret; + +@@ -548,21 +546,21 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, + + notifier->sd = sd; + +- ret = __v4l2_async_notifier_register(notifier); ++ ret = __v4l2_async_nf_register(notifier); + if (ret) + notifier->sd = NULL; + + return ret; + } +-EXPORT_SYMBOL(v4l2_async_subdev_notifier_register); ++EXPORT_SYMBOL(v4l2_async_subdev_nf_register); + + static void +-__v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) ++__v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier) + { + if (!notifier || (!notifier->v4l2_dev && !notifier->sd)) + return; + +- v4l2_async_notifier_unbind_all_subdevs(notifier); ++ v4l2_async_nf_unbind_all_subdevs(notifier); + + notifier->sd = NULL; + notifier->v4l2_dev = NULL; +@@ -570,17 +568,17 @@ __v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) + list_del(¬ifier->list); + } + +-void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) ++void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier) + { + mutex_lock(&list_lock); + +- __v4l2_async_notifier_unregister(notifier); ++ __v4l2_async_nf_unregister(notifier); + + mutex_unlock(&list_lock); + } +-EXPORT_SYMBOL(v4l2_async_notifier_unregister); ++EXPORT_SYMBOL(v4l2_async_nf_unregister); + +-static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) ++static void __v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier) + { + struct v4l2_async_subdev *asd, *tmp; + +@@ -601,24 +599,24 @@ static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) + } + } + +-void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) ++void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier) + { + mutex_lock(&list_lock); + +- __v4l2_async_notifier_cleanup(notifier); ++ __v4l2_async_nf_cleanup(notifier); + + mutex_unlock(&list_lock); + } +-EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup); ++EXPORT_SYMBOL_GPL(v4l2_async_nf_cleanup); + +-int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, +- struct v4l2_async_subdev *asd) ++int __v4l2_async_nf_add_subdev(struct v4l2_async_notifier *notifier, ++ struct v4l2_async_subdev *asd) + { + int ret; + + mutex_lock(&list_lock); + +- ret = v4l2_async_notifier_asd_valid(notifier, asd, -1); ++ ret = v4l2_async_nf_asd_valid(notifier, asd, -1); + if (ret) + goto unlock; + +@@ -628,12 +626,12 @@ int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, + mutex_unlock(&list_lock); + return ret; + } +-EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_subdev); ++EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_subdev); + + struct v4l2_async_subdev * +-__v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, +- struct fwnode_handle *fwnode, +- unsigned int asd_struct_size) ++__v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier, ++ struct fwnode_handle *fwnode, ++ unsigned int asd_struct_size) + { + struct v4l2_async_subdev *asd; + int ret; +@@ -645,7 +643,7 @@ __v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, + asd->match_type = V4L2_ASYNC_MATCH_FWNODE; + asd->match.fwnode = fwnode_handle_get(fwnode); + +- ret = __v4l2_async_notifier_add_subdev(notifier, asd); ++ ret = __v4l2_async_nf_add_subdev(notifier, asd); + if (ret) { + fwnode_handle_put(fwnode); + kfree(asd); +@@ -654,12 +652,12 @@ __v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, + + return asd; + } +-EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_subdev); ++EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_fwnode); + + struct v4l2_async_subdev * +-__v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif, +- struct fwnode_handle *endpoint, +- unsigned int asd_struct_size) ++__v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif, ++ struct fwnode_handle *endpoint, ++ unsigned int asd_struct_size) + { + struct v4l2_async_subdev *asd; + struct fwnode_handle *remote; +@@ -668,21 +666,19 @@ __v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif + if (!remote) + return ERR_PTR(-ENOTCONN); + +- asd = __v4l2_async_notifier_add_fwnode_subdev(notif, remote, +- asd_struct_size); ++ asd = __v4l2_async_nf_add_fwnode(notif, remote, asd_struct_size); + /* +- * Calling __v4l2_async_notifier_add_fwnode_subdev grabs a refcount, ++ * Calling __v4l2_async_nf_add_fwnode grabs a refcount, + * so drop the one we got in fwnode_graph_get_remote_port_parent. + */ + fwnode_handle_put(remote); + return asd; + } +-EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_remote_subdev); ++EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_fwnode_remote); + + struct v4l2_async_subdev * +-__v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, +- int adapter_id, unsigned short address, +- unsigned int asd_struct_size) ++__v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier, int adapter_id, ++ unsigned short address, unsigned int asd_struct_size) + { + struct v4l2_async_subdev *asd; + int ret; +@@ -695,7 +691,7 @@ __v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, + asd->match.i2c.adapter_id = adapter_id; + asd->match.i2c.address = address; + +- ret = __v4l2_async_notifier_add_subdev(notifier, asd); ++ ret = __v4l2_async_nf_add_subdev(notifier, asd); + if (ret) { + kfree(asd); + return ERR_PTR(ret); +@@ -703,7 +699,7 @@ __v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, + + return asd; + } +-EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_i2c_subdev); ++EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_i2c); + + int v4l2_async_register_subdev(struct v4l2_subdev *sd) + { +@@ -725,7 +721,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) + + list_for_each_entry(notifier, ¬ifier_list, list) { + struct v4l2_device *v4l2_dev = +- v4l2_async_notifier_find_v4l2_dev(notifier); ++ v4l2_async_nf_find_v4l2_dev(notifier); + struct v4l2_async_subdev *asd; + + if (!v4l2_dev) +@@ -739,7 +735,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) + if (ret) + goto err_unbind; + +- ret = v4l2_async_notifier_try_complete(notifier); ++ ret = v4l2_async_nf_try_complete(notifier); + if (ret) + goto err_unbind; + +@@ -761,10 +757,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) + */ + subdev_notifier = v4l2_async_find_subdev_notifier(sd); + if (subdev_notifier) +- v4l2_async_notifier_unbind_all_subdevs(subdev_notifier); ++ v4l2_async_nf_unbind_all_subdevs(subdev_notifier); + + if (sd->asd) +- v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); ++ v4l2_async_nf_call_unbind(notifier, sd, sd->asd); + v4l2_async_cleanup(sd); + + mutex_unlock(&list_lock); +@@ -780,8 +776,8 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) + + mutex_lock(&list_lock); + +- __v4l2_async_notifier_unregister(sd->subdev_notifier); +- __v4l2_async_notifier_cleanup(sd->subdev_notifier); ++ __v4l2_async_nf_unregister(sd->subdev_notifier); ++ __v4l2_async_nf_cleanup(sd->subdev_notifier); + kfree(sd->subdev_notifier); + sd->subdev_notifier = NULL; + +@@ -790,7 +786,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) + + list_add(&sd->asd->list, ¬ifier->waiting); + +- v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); ++ v4l2_async_nf_call_unbind(notifier, sd, sd->asd); + } + + v4l2_async_cleanup(sd); +@@ -825,7 +821,7 @@ static void print_waiting_subdev(struct seq_file *s, + } + + static const char * +-v4l2_async_notifier_name(struct v4l2_async_notifier *notifier) ++v4l2_async_nf_name(struct v4l2_async_notifier *notifier) + { + if (notifier->v4l2_dev) + return notifier->v4l2_dev->name; +@@ -843,7 +839,7 @@ static int pending_subdevs_show(struct seq_file *s, void *data) + mutex_lock(&list_lock); + + list_for_each_entry(notif, ¬ifier_list, list) { +- seq_printf(s, "%s:\n", v4l2_async_notifier_name(notif)); ++ seq_printf(s, "%s:\n", v4l2_async_nf_name(notif)); + list_for_each_entry(asd, ¬if->waiting, list) + print_waiting_subdev(s, asd); + } +diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c +index 5d2eaad1fa684..eb14193cc5aed 100644 +--- a/drivers/media/v4l2-core/v4l2-fwnode.c ++++ b/drivers/media/v4l2-core/v4l2-fwnode.c +@@ -790,11 +790,11 @@ int v4l2_fwnode_device_parse(struct device *dev, + EXPORT_SYMBOL_GPL(v4l2_fwnode_device_parse); + + static int +-v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev, +- struct v4l2_async_notifier *notifier, +- struct fwnode_handle *endpoint, +- unsigned int asd_struct_size, +- parse_endpoint_func parse_endpoint) ++v4l2_async_nf_fwnode_parse_endpoint(struct device *dev, ++ struct v4l2_async_notifier *notifier, ++ struct fwnode_handle *endpoint, ++ unsigned int asd_struct_size, ++ parse_endpoint_func parse_endpoint) + { + struct v4l2_fwnode_endpoint vep = { .bus_type = 0 }; + struct v4l2_async_subdev *asd; +@@ -832,7 +832,7 @@ v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev, + if (ret < 0) + goto out_err; + +- ret = __v4l2_async_notifier_add_subdev(notifier, asd); ++ ret = __v4l2_async_nf_add_subdev(notifier, asd); + if (ret < 0) { + /* not an error if asd already exists */ + if (ret == -EEXIST) +@@ -850,12 +850,11 @@ v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev, + } + + static int +-__v4l2_async_notifier_parse_fwnode_ep(struct device *dev, +- struct v4l2_async_notifier *notifier, +- size_t asd_struct_size, +- unsigned int port, +- bool has_port, +- parse_endpoint_func parse_endpoint) ++__v4l2_async_nf_parse_fwnode_ep(struct device *dev, ++ struct v4l2_async_notifier *notifier, ++ size_t asd_struct_size, unsigned int port, ++ bool has_port, ++ parse_endpoint_func parse_endpoint) + { + struct fwnode_handle *fwnode; + int ret = 0; +@@ -884,11 +883,10 @@ __v4l2_async_notifier_parse_fwnode_ep(struct device *dev, + continue; + } + +- ret = v4l2_async_notifier_fwnode_parse_endpoint(dev, +- notifier, +- fwnode, +- asd_struct_size, +- parse_endpoint); ++ ret = v4l2_async_nf_fwnode_parse_endpoint(dev, notifier, ++ fwnode, ++ asd_struct_size, ++ parse_endpoint); + if (ret < 0) + break; + } +@@ -899,16 +897,15 @@ __v4l2_async_notifier_parse_fwnode_ep(struct device *dev, + } + + int +-v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, +- struct v4l2_async_notifier *notifier, +- size_t asd_struct_size, +- parse_endpoint_func parse_endpoint) ++v4l2_async_nf_parse_fwnode_endpoints(struct device *dev, ++ struct v4l2_async_notifier *notifier, ++ size_t asd_struct_size, ++ parse_endpoint_func parse_endpoint) + { +- return __v4l2_async_notifier_parse_fwnode_ep(dev, notifier, +- asd_struct_size, 0, +- false, parse_endpoint); ++ return __v4l2_async_nf_parse_fwnode_ep(dev, notifier, asd_struct_size, ++ 0, false, parse_endpoint); + } +-EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints); ++EXPORT_SYMBOL_GPL(v4l2_async_nf_parse_fwnode_endpoints); + + /* + * v4l2_fwnode_reference_parse - parse references for async sub-devices +@@ -952,9 +949,8 @@ static int v4l2_fwnode_reference_parse(struct device *dev, + index++) { + struct v4l2_async_subdev *asd; + +- asd = v4l2_async_notifier_add_fwnode_subdev(notifier, +- args.fwnode, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode(notifier, args.fwnode, ++ struct v4l2_async_subdev); + fwnode_handle_put(args.fwnode); + if (IS_ERR(asd)) { + /* not an error if asd already exists */ +@@ -1253,8 +1249,8 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev, + index++) { + struct v4l2_async_subdev *asd; + +- asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode(notifier, fwnode, ++ struct v4l2_async_subdev); + fwnode_handle_put(fwnode); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); +@@ -1270,7 +1266,7 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev, + } + + /** +- * v4l2_async_notifier_parse_fwnode_sensor - parse common references on ++ * v4l2_async_nf_parse_fwnode_sensor - parse common references on + * sensors for async sub-devices + * @dev: the device node the properties of which are parsed for references + * @notifier: the async notifier where the async subdevs will be added +@@ -1279,7 +1275,7 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev, + * sensor and set up async sub-devices for them. + * + * Any notifier populated using this function must be released with a call to +- * v4l2_async_notifier_release() after it has been unregistered and the async ++ * v4l2_async_nf_release() after it has been unregistered and the async + * sub-devices are no longer in use, even in the case the function returned an + * error. + * +@@ -1288,8 +1284,8 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev, + * -EINVAL if property parsing failed + */ + static int +-v4l2_async_notifier_parse_fwnode_sensor(struct device *dev, +- struct v4l2_async_notifier *notifier) ++v4l2_async_nf_parse_fwnode_sensor(struct device *dev, ++ struct v4l2_async_notifier *notifier) + { + static const char * const led_props[] = { "led" }; + static const struct v4l2_fwnode_int_props props[] = { +@@ -1330,13 +1326,13 @@ int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd) + if (!notifier) + return -ENOMEM; + +- v4l2_async_notifier_init(notifier); ++ v4l2_async_nf_init(notifier); + +- ret = v4l2_async_notifier_parse_fwnode_sensor(sd->dev, notifier); ++ ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier); + if (ret < 0) + goto out_cleanup; + +- ret = v4l2_async_subdev_notifier_register(sd, notifier); ++ ret = v4l2_async_subdev_nf_register(sd, notifier); + if (ret < 0) + goto out_cleanup; + +@@ -1349,10 +1345,10 @@ int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd) + return 0; + + out_unregister: +- v4l2_async_notifier_unregister(notifier); ++ v4l2_async_nf_unregister(notifier); + + out_cleanup: +- v4l2_async_notifier_cleanup(notifier); ++ v4l2_async_nf_cleanup(notifier); + kfree(notifier); + + return ret; +diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c +index bb1305c9daaf5..45f9d797b9da6 100644 +--- a/drivers/staging/media/imx/imx-media-csi.c ++++ b/drivers/staging/media/imx/imx-media-csi.c +@@ -1924,7 +1924,7 @@ static int imx_csi_async_register(struct csi_priv *priv) + unsigned int port; + int ret; + +- v4l2_async_notifier_init(&priv->notifier); ++ v4l2_async_nf_init(&priv->notifier); + + /* get this CSI's port id */ + ret = fwnode_property_read_u32(dev_fwnode(priv->dev), "reg", &port); +@@ -1935,8 +1935,8 @@ static int imx_csi_async_register(struct csi_priv *priv) + port, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + if (ep) { +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &priv->notifier, ep, struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep, ++ struct v4l2_async_subdev); + + fwnode_handle_put(ep); + +@@ -1950,8 +1950,7 @@ static int imx_csi_async_register(struct csi_priv *priv) + + priv->notifier.ops = &csi_notify_ops; + +- ret = v4l2_async_subdev_notifier_register(&priv->sd, +- &priv->notifier); ++ ret = v4l2_async_subdev_nf_register(&priv->sd, &priv->notifier); + if (ret) + return ret; + +@@ -2040,8 +2039,8 @@ static int imx_csi_probe(struct platform_device *pdev) + return 0; + + cleanup: +- v4l2_async_notifier_unregister(&priv->notifier); +- v4l2_async_notifier_cleanup(&priv->notifier); ++ v4l2_async_nf_unregister(&priv->notifier); ++ v4l2_async_nf_cleanup(&priv->notifier); + free: + v4l2_ctrl_handler_free(&priv->ctrl_hdlr); + mutex_destroy(&priv->lock); +@@ -2055,8 +2054,8 @@ static int imx_csi_remove(struct platform_device *pdev) + + v4l2_ctrl_handler_free(&priv->ctrl_hdlr); + mutex_destroy(&priv->lock); +- v4l2_async_notifier_unregister(&priv->notifier); +- v4l2_async_notifier_cleanup(&priv->notifier); ++ v4l2_async_nf_unregister(&priv->notifier); ++ v4l2_async_nf_cleanup(&priv->notifier); + v4l2_async_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + +diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c +index 4d873726a461b..80b69a9a752cb 100644 +--- a/drivers/staging/media/imx/imx-media-dev-common.c ++++ b/drivers/staging/media/imx/imx-media-dev-common.c +@@ -381,7 +381,7 @@ struct imx_media_dev *imx_media_dev_init(struct device *dev, + + INIT_LIST_HEAD(&imxmd->vdev_list); + +- v4l2_async_notifier_init(&imxmd->notifier); ++ v4l2_async_nf_init(&imxmd->notifier); + + return imxmd; + +@@ -405,11 +405,10 @@ int imx_media_dev_notifier_register(struct imx_media_dev *imxmd, + + /* prepare the async subdev notifier and register it */ + imxmd->notifier.ops = ops ? ops : &imx_media_notifier_ops; +- ret = v4l2_async_notifier_register(&imxmd->v4l2_dev, +- &imxmd->notifier); ++ ret = v4l2_async_nf_register(&imxmd->v4l2_dev, &imxmd->notifier); + if (ret) { + v4l2_err(&imxmd->v4l2_dev, +- "v4l2_async_notifier_register failed with %d\n", ret); ++ "v4l2_async_nf_register failed with %d\n", ret); + return ret; + } + +diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c +index 338b8bd0bb076..f85462214e221 100644 +--- a/drivers/staging/media/imx/imx-media-dev.c ++++ b/drivers/staging/media/imx/imx-media-dev.c +@@ -94,7 +94,7 @@ static int imx_media_probe(struct platform_device *pdev) + return 0; + + cleanup: +- v4l2_async_notifier_cleanup(&imxmd->notifier); ++ v4l2_async_nf_cleanup(&imxmd->notifier); + v4l2_device_unregister(&imxmd->v4l2_dev); + media_device_cleanup(&imxmd->md); + +@@ -113,9 +113,9 @@ static int imx_media_remove(struct platform_device *pdev) + imxmd->m2m_vdev = NULL; + } + +- v4l2_async_notifier_unregister(&imxmd->notifier); ++ v4l2_async_nf_unregister(&imxmd->notifier); + imx_media_unregister_ipu_internal_subdevs(imxmd); +- v4l2_async_notifier_cleanup(&imxmd->notifier); ++ v4l2_async_nf_cleanup(&imxmd->notifier); + media_device_unregister(&imxmd->md); + v4l2_device_unregister(&imxmd->v4l2_dev); + media_device_cleanup(&imxmd->md); +diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c +index b677cf0e0c849..59f1eb7b62bcd 100644 +--- a/drivers/staging/media/imx/imx-media-of.c ++++ b/drivers/staging/media/imx/imx-media-of.c +@@ -29,9 +29,9 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd, + } + + /* add CSI fwnode to async notifier */ +- asd = v4l2_async_notifier_add_fwnode_subdev(&imxmd->notifier, +- of_fwnode_handle(csi_np), +- struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode(&imxmd->notifier, ++ of_fwnode_handle(csi_np), ++ struct v4l2_async_subdev); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + if (ret == -EEXIST) +diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c +index 9de0ebd439dc6..a0941fc2907b7 100644 +--- a/drivers/staging/media/imx/imx6-mipi-csi2.c ++++ b/drivers/staging/media/imx/imx6-mipi-csi2.c +@@ -647,7 +647,7 @@ static int csi2_async_register(struct csi2_dev *csi2) + struct fwnode_handle *ep; + int ret; + +- v4l2_async_notifier_init(&csi2->notifier); ++ v4l2_async_nf_init(&csi2->notifier); + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); +@@ -663,8 +663,8 @@ static int csi2_async_register(struct csi2_dev *csi2) + dev_dbg(csi2->dev, "data lanes: %d\n", vep.bus.mipi_csi2.num_data_lanes); + dev_dbg(csi2->dev, "flags: 0x%08x\n", vep.bus.mipi_csi2.flags); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &csi2->notifier, ep, struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&csi2->notifier, ep, ++ struct v4l2_async_subdev); + fwnode_handle_put(ep); + + if (IS_ERR(asd)) +@@ -672,8 +672,7 @@ static int csi2_async_register(struct csi2_dev *csi2) + + csi2->notifier.ops = &csi2_notify_ops; + +- ret = v4l2_async_subdev_notifier_register(&csi2->sd, +- &csi2->notifier); ++ ret = v4l2_async_subdev_nf_register(&csi2->sd, &csi2->notifier); + if (ret) + return ret; + +@@ -768,8 +767,8 @@ static int csi2_probe(struct platform_device *pdev) + return 0; + + clean_notifier: +- v4l2_async_notifier_unregister(&csi2->notifier); +- v4l2_async_notifier_cleanup(&csi2->notifier); ++ v4l2_async_nf_unregister(&csi2->notifier); ++ v4l2_async_nf_cleanup(&csi2->notifier); + clk_disable_unprepare(csi2->dphy_clk); + pllref_off: + clk_disable_unprepare(csi2->pllref_clk); +@@ -783,8 +782,8 @@ static int csi2_remove(struct platform_device *pdev) + struct v4l2_subdev *sd = platform_get_drvdata(pdev); + struct csi2_dev *csi2 = sd_to_dev(sd); + +- v4l2_async_notifier_unregister(&csi2->notifier); +- v4l2_async_notifier_cleanup(&csi2->notifier); ++ v4l2_async_nf_unregister(&csi2->notifier); ++ v4l2_async_nf_cleanup(&csi2->notifier); + v4l2_async_unregister_subdev(sd); + clk_disable_unprepare(csi2->dphy_clk); + clk_disable_unprepare(csi2->pllref_clk); +diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c +index 1271837329124..2288dadb2683a 100644 +--- a/drivers/staging/media/imx/imx7-media-csi.c ++++ b/drivers/staging/media/imx/imx7-media-csi.c +@@ -1099,13 +1099,13 @@ static int imx7_csi_async_register(struct imx7_csi *csi) + struct fwnode_handle *ep; + int ret; + +- v4l2_async_notifier_init(&csi->notifier); ++ v4l2_async_nf_init(&csi->notifier); + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + if (ep) { +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &csi->notifier, ep, struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep, ++ struct v4l2_async_subdev); + + fwnode_handle_put(ep); + +@@ -1119,7 +1119,7 @@ static int imx7_csi_async_register(struct imx7_csi *csi) + + csi->notifier.ops = &imx7_csi_notify_ops; + +- ret = v4l2_async_subdev_notifier_register(&csi->sd, &csi->notifier); ++ ret = v4l2_async_subdev_nf_register(&csi->sd, &csi->notifier); + if (ret) + return ret; + +@@ -1210,12 +1210,12 @@ static int imx7_csi_probe(struct platform_device *pdev) + return 0; + + subdev_notifier_cleanup: +- v4l2_async_notifier_unregister(&csi->notifier); +- v4l2_async_notifier_cleanup(&csi->notifier); ++ v4l2_async_nf_unregister(&csi->notifier); ++ v4l2_async_nf_cleanup(&csi->notifier); + + cleanup: +- v4l2_async_notifier_unregister(&imxmd->notifier); +- v4l2_async_notifier_cleanup(&imxmd->notifier); ++ v4l2_async_nf_unregister(&imxmd->notifier); ++ v4l2_async_nf_cleanup(&imxmd->notifier); + v4l2_device_unregister(&imxmd->v4l2_dev); + media_device_unregister(&imxmd->md); + media_device_cleanup(&imxmd->md); +@@ -1232,15 +1232,15 @@ static int imx7_csi_remove(struct platform_device *pdev) + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct imx_media_dev *imxmd = csi->imxmd; + +- v4l2_async_notifier_unregister(&imxmd->notifier); +- v4l2_async_notifier_cleanup(&imxmd->notifier); ++ v4l2_async_nf_unregister(&imxmd->notifier); ++ v4l2_async_nf_cleanup(&imxmd->notifier); + + media_device_unregister(&imxmd->md); + v4l2_device_unregister(&imxmd->v4l2_dev); + media_device_cleanup(&imxmd->md); + +- v4l2_async_notifier_unregister(&csi->notifier); +- v4l2_async_notifier_cleanup(&csi->notifier); ++ v4l2_async_nf_unregister(&csi->notifier); ++ v4l2_async_nf_cleanup(&csi->notifier); + v4l2_async_unregister_subdev(sd); + + mutex_destroy(&csi->lock); +diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c +index d35e523741168..9ea723bb5f209 100644 +--- a/drivers/staging/media/imx/imx7-mipi-csis.c ++++ b/drivers/staging/media/imx/imx7-mipi-csis.c +@@ -1160,7 +1160,7 @@ static int mipi_csis_async_register(struct csi_state *state) + unsigned int i; + int ret; + +- v4l2_async_notifier_init(&state->notifier); ++ v4l2_async_nf_init(&state->notifier); + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); +@@ -1185,8 +1185,8 @@ static int mipi_csis_async_register(struct csi_state *state) + dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes); + dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev( +- &state->notifier, ep, struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep, ++ struct v4l2_async_subdev); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto err_parse; +@@ -1196,7 +1196,7 @@ static int mipi_csis_async_register(struct csi_state *state) + + state->notifier.ops = &mipi_csis_notify_ops; + +- ret = v4l2_async_subdev_notifier_register(&state->sd, &state->notifier); ++ ret = v4l2_async_subdev_nf_register(&state->sd, &state->notifier); + if (ret) + return ret; + +@@ -1427,8 +1427,8 @@ static int mipi_csis_probe(struct platform_device *pdev) + mipi_csis_debugfs_exit(state); + cleanup: + media_entity_cleanup(&state->sd.entity); +- v4l2_async_notifier_unregister(&state->notifier); +- v4l2_async_notifier_cleanup(&state->notifier); ++ v4l2_async_nf_unregister(&state->notifier); ++ v4l2_async_nf_cleanup(&state->notifier); + v4l2_async_unregister_subdev(&state->sd); + disable_clock: + mipi_csis_clk_disable(state); +@@ -1443,8 +1443,8 @@ static int mipi_csis_remove(struct platform_device *pdev) + struct csi_state *state = mipi_sd_to_csis_state(sd); + + mipi_csis_debugfs_exit(state); +- v4l2_async_notifier_unregister(&state->notifier); +- v4l2_async_notifier_cleanup(&state->notifier); ++ v4l2_async_nf_unregister(&state->notifier); ++ v4l2_async_nf_cleanup(&state->notifier); + v4l2_async_unregister_subdev(&state->sd); + + pm_runtime_disable(&pdev->dev); +diff --git a/drivers/staging/media/imx/imx8mq-mipi-csi2.c b/drivers/staging/media/imx/imx8mq-mipi-csi2.c +index 1d28313dbed7d..3b9fa75efac6b 100644 +--- a/drivers/staging/media/imx/imx8mq-mipi-csi2.c ++++ b/drivers/staging/media/imx/imx8mq-mipi-csi2.c +@@ -640,7 +640,7 @@ static int imx8mq_mipi_csi_async_register(struct csi_state *state) + unsigned int i; + int ret; + +- v4l2_async_notifier_init(&state->notifier); ++ v4l2_async_nf_init(&state->notifier); + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); +@@ -666,8 +666,8 @@ static int imx8mq_mipi_csi_async_register(struct csi_state *state) + state->bus.num_data_lanes, + state->bus.flags); + +- asd = v4l2_async_notifier_add_fwnode_remote_subdev(&state->notifier, +- ep, struct v4l2_async_subdev); ++ asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep, ++ struct v4l2_async_subdev); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto err_parse; +@@ -677,7 +677,7 @@ static int imx8mq_mipi_csi_async_register(struct csi_state *state) + + state->notifier.ops = &imx8mq_mipi_csi_notify_ops; + +- ret = v4l2_async_subdev_notifier_register(&state->sd, &state->notifier); ++ ret = v4l2_async_subdev_nf_register(&state->sd, &state->notifier); + if (ret) + return ret; + +@@ -957,8 +957,8 @@ static int imx8mq_mipi_csi_probe(struct platform_device *pdev) + imx8mq_mipi_csi_runtime_suspend(&pdev->dev); + + media_entity_cleanup(&state->sd.entity); +- v4l2_async_notifier_unregister(&state->notifier); +- v4l2_async_notifier_cleanup(&state->notifier); ++ v4l2_async_nf_unregister(&state->notifier); ++ v4l2_async_nf_cleanup(&state->notifier); + v4l2_async_unregister_subdev(&state->sd); + icc: + imx8mq_mipi_csi_release_icc(pdev); +@@ -973,8 +973,8 @@ static int imx8mq_mipi_csi_remove(struct platform_device *pdev) + struct v4l2_subdev *sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csi2_state(sd); + +- v4l2_async_notifier_unregister(&state->notifier); +- v4l2_async_notifier_cleanup(&state->notifier); ++ v4l2_async_nf_unregister(&state->notifier); ++ v4l2_async_nf_cleanup(&state->notifier); + v4l2_async_unregister_subdev(&state->sd); + + pm_runtime_disable(&pdev->dev); +diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c +index d321790b07d95..69d9787d53384 100644 +--- a/drivers/staging/media/tegra-video/vi.c ++++ b/drivers/staging/media/tegra-video/vi.c +@@ -1272,7 +1272,7 @@ static int tegra_channel_init(struct tegra_vi_channel *chan) + } + + if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)) +- v4l2_async_notifier_init(&chan->notifier); ++ v4l2_async_nf_init(&chan->notifier); + + return 0; + +@@ -1811,8 +1811,8 @@ static int tegra_vi_graph_parse_one(struct tegra_vi_channel *chan, + continue; + } + +- tvge = v4l2_async_notifier_add_fwnode_subdev(&chan->notifier, remote, +- struct tegra_vi_graph_entity); ++ tvge = v4l2_async_nf_add_fwnode(&chan->notifier, remote, ++ struct tegra_vi_graph_entity); + if (IS_ERR(tvge)) { + ret = PTR_ERR(tvge); + dev_err(vi->dev, +@@ -1834,7 +1834,7 @@ static int tegra_vi_graph_parse_one(struct tegra_vi_channel *chan, + + cleanup: + dev_err(vi->dev, "failed parsing the graph: %d\n", ret); +- v4l2_async_notifier_cleanup(&chan->notifier); ++ v4l2_async_nf_cleanup(&chan->notifier); + of_node_put(node); + return ret; + } +@@ -1868,13 +1868,12 @@ static int tegra_vi_graph_init(struct tegra_vi *vi) + continue; + + chan->notifier.ops = &tegra_vi_async_ops; +- ret = v4l2_async_notifier_register(&vid->v4l2_dev, +- &chan->notifier); ++ ret = v4l2_async_nf_register(&vid->v4l2_dev, &chan->notifier); + if (ret < 0) { + dev_err(vi->dev, + "failed to register channel %d notifier: %d\n", + chan->portnos[0], ret); +- v4l2_async_notifier_cleanup(&chan->notifier); ++ v4l2_async_nf_cleanup(&chan->notifier); + } + } + +@@ -1887,8 +1886,8 @@ static void tegra_vi_graph_cleanup(struct tegra_vi *vi) + + list_for_each_entry(chan, &vi->vi_chans, list) { + vb2_video_unregister_device(&chan->video); +- v4l2_async_notifier_unregister(&chan->notifier); +- v4l2_async_notifier_cleanup(&chan->notifier); ++ v4l2_async_nf_unregister(&chan->notifier); ++ v4l2_async_nf_cleanup(&chan->notifier); + } + } + +diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h +index fa4901162663b..13ff3ad948f43 100644 +--- a/include/media/v4l2-async.h ++++ b/include/media/v4l2-async.h +@@ -123,45 +123,45 @@ struct v4l2_async_notifier { + void v4l2_async_debug_init(struct dentry *debugfs_dir); + + /** +- * v4l2_async_notifier_init - Initialize a notifier. ++ * v4l2_async_nf_init - Initialize a notifier. + * + * @notifier: pointer to &struct v4l2_async_notifier + * + * This function initializes the notifier @asd_list. It must be called + * before adding a subdevice to a notifier, using one of: +- * v4l2_async_notifier_add_fwnode_remote_subdev(), +- * v4l2_async_notifier_add_fwnode_subdev(), +- * v4l2_async_notifier_add_i2c_subdev(), +- * __v4l2_async_notifier_add_subdev() or +- * v4l2_async_notifier_parse_fwnode_endpoints(). ++ * v4l2_async_nf_add_fwnode_remote(), ++ * v4l2_async_nf_add_fwnode(), ++ * v4l2_async_nf_add_i2c(), ++ * __v4l2_async_nf_add_subdev() or ++ * v4l2_async_nf_parse_fwnode_endpoints(). + */ +-void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier); ++void v4l2_async_nf_init(struct v4l2_async_notifier *notifier); + + /** +- * __v4l2_async_notifier_add_subdev - Add an async subdev to the ++ * __v4l2_async_nf_add_subdev - Add an async subdev to the + * notifier's master asd list. + * + * @notifier: pointer to &struct v4l2_async_notifier + * @asd: pointer to &struct v4l2_async_subdev + * + * \warning: Drivers should avoid using this function and instead use one of: +- * v4l2_async_notifier_add_fwnode_subdev(), +- * v4l2_async_notifier_add_fwnode_remote_subdev() or +- * v4l2_async_notifier_add_i2c_subdev(). ++ * v4l2_async_nf_add_fwnode(), ++ * v4l2_async_nf_add_fwnode_remote() or ++ * v4l2_async_nf_add_i2c(). + * + * Call this function before registering a notifier to link the provided @asd to + * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as + * it will be freed by the framework when the notifier is destroyed. + */ +-int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, +- struct v4l2_async_subdev *asd); ++int __v4l2_async_nf_add_subdev(struct v4l2_async_notifier *notifier, ++ struct v4l2_async_subdev *asd); + + struct v4l2_async_subdev * +-__v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, +- struct fwnode_handle *fwnode, +- unsigned int asd_struct_size); ++__v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier, ++ struct fwnode_handle *fwnode, ++ unsigned int asd_struct_size); + /** +- * v4l2_async_notifier_add_fwnode_subdev - Allocate and add a fwnode async ++ * v4l2_async_nf_add_fwnode - Allocate and add a fwnode async + * subdev to the notifier's master asd_list. + * + * @notifier: pointer to &struct v4l2_async_notifier +@@ -175,16 +175,15 @@ __v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, + * notifiers @asd_list. The function also gets a reference of the fwnode which + * is released later at notifier cleanup time. + */ +-#define v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, type) \ +- ((type *)__v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, \ +- sizeof(type))) ++#define v4l2_async_nf_add_fwnode(notifier, fwnode, type) \ ++ ((type *)__v4l2_async_nf_add_fwnode(notifier, fwnode, sizeof(type))) + + struct v4l2_async_subdev * +-__v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif, +- struct fwnode_handle *endpoint, +- unsigned int asd_struct_size); ++__v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif, ++ struct fwnode_handle *endpoint, ++ unsigned int asd_struct_size); + /** +- * v4l2_async_notifier_add_fwnode_remote_subdev - Allocate and add a fwnode ++ * v4l2_async_nf_add_fwnode_remote - Allocate and add a fwnode + * remote async subdev to the + * notifier's master asd_list. + * +@@ -200,20 +199,18 @@ __v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif + * function also gets a reference of the fwnode which is released later at + * notifier cleanup time. + * +- * This is just like v4l2_async_notifier_add_fwnode_subdev(), but with the ++ * This is just like v4l2_async_nf_add_fwnode(), but with the + * exception that the fwnode refers to a local endpoint, not the remote one. + */ +-#define v4l2_async_notifier_add_fwnode_remote_subdev(notifier, ep, type) \ +- ((type *) \ +- __v4l2_async_notifier_add_fwnode_remote_subdev(notifier, ep, \ +- sizeof(type))) ++#define v4l2_async_nf_add_fwnode_remote(notifier, ep, type) \ ++ ((type *)__v4l2_async_nf_add_fwnode_remote(notifier, ep, sizeof(type))) + + struct v4l2_async_subdev * +-__v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, +- int adapter_id, unsigned short address, +- unsigned int asd_struct_size); ++__v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier, ++ int adapter_id, unsigned short address, ++ unsigned int asd_struct_size); + /** +- * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async ++ * v4l2_async_nf_add_i2c - Allocate and add an i2c async + * subdev to the notifier's master asd_list. + * + * @notifier: pointer to &struct v4l2_async_notifier +@@ -223,59 +220,59 @@ __v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, + * v4l2_async_subdev shall be the first member of the driver's async + * sub-device struct, i.e. both begin at the same memory address. + * +- * Same as v4l2_async_notifier_add_fwnode_subdev() but for I2C matched ++ * Same as v4l2_async_nf_add_fwnode() but for I2C matched + * sub-devices. + */ +-#define v4l2_async_notifier_add_i2c_subdev(notifier, adapter, address, type) \ +- ((type *)__v4l2_async_notifier_add_i2c_subdev(notifier, adapter, \ +- address, sizeof(type))) ++#define v4l2_async_nf_add_i2c(notifier, adapter, address, type) \ ++ ((type *)__v4l2_async_nf_add_i2c(notifier, adapter, address, \ ++ sizeof(type))) + + /** +- * v4l2_async_notifier_register - registers a subdevice asynchronous notifier ++ * v4l2_async_nf_register - registers a subdevice asynchronous notifier + * + * @v4l2_dev: pointer to &struct v4l2_device + * @notifier: pointer to &struct v4l2_async_notifier + */ +-int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, +- struct v4l2_async_notifier *notifier); ++int v4l2_async_nf_register(struct v4l2_device *v4l2_dev, ++ struct v4l2_async_notifier *notifier); + + /** +- * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous ++ * v4l2_async_subdev_nf_register - registers a subdevice asynchronous + * notifier for a sub-device + * + * @sd: pointer to &struct v4l2_subdev + * @notifier: pointer to &struct v4l2_async_notifier + */ +-int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, +- struct v4l2_async_notifier *notifier); ++int v4l2_async_subdev_nf_register(struct v4l2_subdev *sd, ++ struct v4l2_async_notifier *notifier); + + /** +- * v4l2_async_notifier_unregister - unregisters a subdevice ++ * v4l2_async_nf_unregister - unregisters a subdevice + * asynchronous notifier + * + * @notifier: pointer to &struct v4l2_async_notifier + */ +-void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); ++void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier); + + /** +- * v4l2_async_notifier_cleanup - clean up notifier resources ++ * v4l2_async_nf_cleanup - clean up notifier resources + * @notifier: the notifier the resources of which are to be cleaned up + * + * Release memory resources related to a notifier, including the async + * sub-devices allocated for the purposes of the notifier but not the notifier + * itself. The user is responsible for calling this function to clean up the + * notifier after calling +- * v4l2_async_notifier_add_fwnode_remote_subdev(), +- * v4l2_async_notifier_add_fwnode_subdev(), +- * v4l2_async_notifier_add_i2c_subdev(), +- * __v4l2_async_notifier_add_subdev() or +- * v4l2_async_notifier_parse_fwnode_endpoints(). ++ * v4l2_async_nf_add_fwnode_remote(), ++ * v4l2_async_nf_add_fwnode(), ++ * v4l2_async_nf_add_i2c(), ++ * __v4l2_async_nf_add_subdev() or ++ * v4l2_async_nf_parse_fwnode_endpoints(). + * +- * There is no harm from calling v4l2_async_notifier_cleanup() in other ++ * There is no harm from calling v4l2_async_nf_cleanup() in other + * cases as long as its memory has been zeroed after it has been + * allocated. + */ +-void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier); ++void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier); + + /** + * v4l2_async_register_subdev - registers a sub-device to the asynchronous +@@ -295,7 +292,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd); + * + * This function is just like v4l2_async_register_subdev() with the exception + * that calling it will also parse firmware interfaces for remote references +- * using v4l2_async_notifier_parse_fwnode_sensor() and registers the ++ * using v4l2_async_nf_parse_fwnode_sensor() and registers the + * async sub-devices. The sub-device is similarly unregistered by calling + * v4l2_async_unregister_subdev(). + * +diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h +index 7ab033b819eb0..9c97f1dbd1c68 100644 +--- a/include/media/v4l2-fwnode.h ++++ b/include/media/v4l2-fwnode.h +@@ -463,7 +463,7 @@ typedef int (*parse_endpoint_func)(struct device *dev, + struct v4l2_async_subdev *asd); + + /** +- * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a ++ * v4l2_async_nf_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a + * device node + * @dev: the device the endpoints of which are to be parsed + * @notifier: notifier for @dev +@@ -496,7 +496,7 @@ typedef int (*parse_endpoint_func)(struct device *dev, + * to retain that configuration, the user needs to allocate memory for it. + * + * Any notifier populated using this function must be released with a call to +- * v4l2_async_notifier_cleanup() after it has been unregistered and the async ++ * v4l2_async_nf_cleanup() after it has been unregistered and the async + * sub-devices are no longer in use, even if the function returned an error. + * + * Return: %0 on success, including when no async sub-devices are found +@@ -505,10 +505,10 @@ typedef int (*parse_endpoint_func)(struct device *dev, + * Other error codes as returned by @parse_endpoint + */ + int +-v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, +- struct v4l2_async_notifier *notifier, +- size_t asd_struct_size, +- parse_endpoint_func parse_endpoint); ++v4l2_async_nf_parse_fwnode_endpoints(struct device *dev, ++ struct v4l2_async_notifier *notifier, ++ size_t asd_struct_size, ++ parse_endpoint_func parse_endpoint); + + /* Helper macros to access the connector links. */ + +-- +2.42.0 + diff --git a/queue-5.15/media-vivid-avoid-integer-overflow.patch b/queue-5.15/media-vivid-avoid-integer-overflow.patch new file mode 100644 index 00000000000..9864079fcdf --- /dev/null +++ b/queue-5.15/media-vivid-avoid-integer-overflow.patch @@ -0,0 +1,47 @@ +From b82562584ad19a9de2894dc3bb1085453c99599a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Sep 2023 17:20:48 +0200 +Subject: media: vivid: avoid integer overflow + +From: Hans Verkuil + +[ Upstream commit 4567ebf8e8f9546b373e78e3b7d584cc30b62028 ] + +Fixes these compiler warnings: + +drivers/media/test-drivers/vivid/vivid-rds-gen.c: In function 'vivid_rds_gen_fill': +drivers/media/test-drivers/vivid/vivid-rds-gen.c:147:56: warning: '.' directive output may be truncated writing 1 byte into a region of size between 0 and 3 [-Wformat-truncation=] + 147 | snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", + | ^ +drivers/media/test-drivers/vivid/vivid-rds-gen.c:147:52: note: directive argument in the range [0, 9] + 147 | snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", + | ^~~~~~~~~ +drivers/media/test-drivers/vivid/vivid-rds-gen.c:147:9: note: 'snprintf' output between 9 and 12 bytes into a destination of size 9 + 147 | snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 148 | freq / 16, ((freq & 0xf) * 10) / 16); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Hans Verkuil +Acked-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + drivers/media/test-drivers/vivid/vivid-rds-gen.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/test-drivers/vivid/vivid-rds-gen.c b/drivers/media/test-drivers/vivid/vivid-rds-gen.c +index b5b104ee64c99..c57771119a34b 100644 +--- a/drivers/media/test-drivers/vivid/vivid-rds-gen.c ++++ b/drivers/media/test-drivers/vivid/vivid-rds-gen.c +@@ -145,7 +145,7 @@ void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq, + rds->ta = alt; + rds->ms = true; + snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", +- freq / 16, ((freq & 0xf) * 10) / 16); ++ (freq / 16) % 1000000, (((freq & 0xf) * 10) / 16) % 10); + if (alt) + strscpy(rds->radiotext, + " The Radio Data System can switch between different Radio Texts ", +-- +2.42.0 + diff --git a/queue-5.15/misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch b/queue-5.15/misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch new file mode 100644 index 00000000000..27350f3abbc --- /dev/null +++ b/queue-5.15/misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch @@ -0,0 +1,49 @@ +From ec62def15c15e8026ef29c8f38855899e15d9471 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 17:56:31 +0900 +Subject: misc: pci_endpoint_test: Add Device ID for R-Car S4-8 PCIe controller +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yoshihiro Shimoda + +[ Upstream commit 6c4b39937f4e65688ea294725ae432b2565821ff ] + +Add Renesas R8A779F0 in pci_device_id table so that pci-epf-test +can be used for testing PCIe EP on R-Car S4-8. + +Link: https://lore.kernel.org/linux-pci/20231018085631.1121289-16-yoshihiro.shimoda.uh@renesas.com +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Krzysztof Wilczyński +Acked-by: Manivannan Sadhasivam +Signed-off-by: Sasha Levin +--- + drivers/misc/pci_endpoint_test.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c +index 3382cf4905ded..0223e96aae47c 100644 +--- a/drivers/misc/pci_endpoint_test.c ++++ b/drivers/misc/pci_endpoint_test.c +@@ -81,6 +81,7 @@ + #define PCI_DEVICE_ID_RENESAS_R8A774B1 0x002b + #define PCI_DEVICE_ID_RENESAS_R8A774C0 0x002d + #define PCI_DEVICE_ID_RENESAS_R8A774E1 0x0025 ++#define PCI_DEVICE_ID_RENESAS_R8A779F0 0x0031 + + static DEFINE_IDA(pci_endpoint_test_ida); + +@@ -996,6 +997,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774B1),}, + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774C0),}, + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774E1),}, ++ { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A779F0), ++ .driver_data = (kernel_ulong_t)&default_data, ++ }, + { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E), + .driver_data = (kernel_ulong_t)&j721e_data, + }, +-- +2.42.0 + diff --git a/queue-5.15/mptcp-diag-switch-to-context-structure.patch b/queue-5.15/mptcp-diag-switch-to-context-structure.patch new file mode 100644 index 00000000000..a775a7ec0df --- /dev/null +++ b/queue-5.15/mptcp-diag-switch-to-context-structure.patch @@ -0,0 +1,67 @@ +From 2482ba8f5be230a53a8b5f0392878c7ec331a4a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Apr 2022 12:45:58 -0700 +Subject: mptcp: diag: switch to context structure + +From: Florian Westphal + +[ Upstream commit 6b9ea5c81ea2bed80dc98a38d475124a87e7ab5d ] + +Raw access to cb->arg[] is deprecated, use a context structure. + +Signed-off-by: Florian Westphal +Signed-off-by: Mat Martineau +Signed-off-by: David S. Miller +Stable-dep-of: 871019b22d1b ("net: set SOCK_RCU_FREE before inserting socket into hashtable") +Signed-off-by: Sasha Levin +--- + net/mptcp/mptcp_diag.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/net/mptcp/mptcp_diag.c b/net/mptcp/mptcp_diag.c +index 292374fb07792..fb98b438b2c90 100644 +--- a/net/mptcp/mptcp_diag.c ++++ b/net/mptcp/mptcp_diag.c +@@ -66,20 +66,28 @@ static int mptcp_diag_dump_one(struct netlink_callback *cb, + return err; + } + ++struct mptcp_diag_ctx { ++ long s_slot; ++ long s_num; ++}; ++ + static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, + const struct inet_diag_req_v2 *r) + { + bool net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN); ++ struct mptcp_diag_ctx *diag_ctx = (void *)cb->ctx; + struct net *net = sock_net(skb->sk); + struct inet_diag_dump_data *cb_data; + struct mptcp_sock *msk; + struct nlattr *bc; + ++ BUILD_BUG_ON(sizeof(cb->ctx) < sizeof(*diag_ctx)); ++ + cb_data = cb->data; + bc = cb_data->inet_diag_nla_bc; + +- while ((msk = mptcp_token_iter_next(net, &cb->args[0], &cb->args[1])) != +- NULL) { ++ while ((msk = mptcp_token_iter_next(net, &diag_ctx->s_slot, ++ &diag_ctx->s_num)) != NULL) { + struct inet_sock *inet = (struct inet_sock *)msk; + struct sock *sk = (struct sock *)msk; + int ret = 0; +@@ -101,7 +109,7 @@ static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, + sock_put(sk); + if (ret < 0) { + /* will retry on the same position */ +- cb->args[1]--; ++ diag_ctx->s_num--; + break; + } + cond_resched(); +-- +2.42.0 + diff --git a/queue-5.15/mptcp-listen-diag-dump-support.patch b/queue-5.15/mptcp-listen-diag-dump-support.patch new file mode 100644 index 00000000000..d9b3fc169b5 --- /dev/null +++ b/queue-5.15/mptcp-listen-diag-dump-support.patch @@ -0,0 +1,154 @@ +From c22fba7e0f7e1bc8702bb0c3b4d956076344dc14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Apr 2022 12:46:00 -0700 +Subject: mptcp: listen diag dump support + +From: Florian Westphal + +[ Upstream commit 4fa39b701ce9be7ec2169f7fba4f8dc1a3b92aac ] + +makes 'ss -Ml' show mptcp listen sockets. + +Iterate over the tcp listen sockets and pick those that have mptcp ulp +info attached. + +mptcp_diag_get_info() is modified to prefer msk->first for mptcp sockets +in listen state. This reports accurate number for recv and send queue +(pending / max connection backlog counters). + +Sample output: +ss -Mil +State Recv-Q Send-Q Local Address:Port Peer Address:Port +LISTEN 0 20 127.0.0.1:12000 0.0.0.0:* + subflows_max:2 + +Signed-off-by: Florian Westphal +Signed-off-by: Mat Martineau +Signed-off-by: David S. Miller +Stable-dep-of: 871019b22d1b ("net: set SOCK_RCU_FREE before inserting socket into hashtable") +Signed-off-by: Sasha Levin +--- + net/mptcp/mptcp_diag.c | 91 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 91 insertions(+) + +diff --git a/net/mptcp/mptcp_diag.c b/net/mptcp/mptcp_diag.c +index fb98b438b2c90..4d8625d0b179a 100644 +--- a/net/mptcp/mptcp_diag.c ++++ b/net/mptcp/mptcp_diag.c +@@ -69,8 +69,83 @@ static int mptcp_diag_dump_one(struct netlink_callback *cb, + struct mptcp_diag_ctx { + long s_slot; + long s_num; ++ unsigned int l_slot; ++ unsigned int l_num; + }; + ++static void mptcp_diag_dump_listeners(struct sk_buff *skb, struct netlink_callback *cb, ++ const struct inet_diag_req_v2 *r, ++ bool net_admin) ++{ ++ struct inet_diag_dump_data *cb_data = cb->data; ++ struct mptcp_diag_ctx *diag_ctx = (void *)cb->ctx; ++ struct nlattr *bc = cb_data->inet_diag_nla_bc; ++ struct net *net = sock_net(skb->sk); ++ int i; ++ ++ for (i = diag_ctx->l_slot; i < INET_LHTABLE_SIZE; i++) { ++ struct inet_listen_hashbucket *ilb; ++ struct hlist_nulls_node *node; ++ struct sock *sk; ++ int num = 0; ++ ++ ilb = &tcp_hashinfo.listening_hash[i]; ++ ++ rcu_read_lock(); ++ spin_lock(&ilb->lock); ++ sk_nulls_for_each(sk, node, &ilb->nulls_head) { ++ const struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(sk); ++ struct inet_sock *inet = inet_sk(sk); ++ int ret; ++ ++ if (num < diag_ctx->l_num) ++ goto next_listen; ++ ++ if (!ctx || strcmp(inet_csk(sk)->icsk_ulp_ops->name, "mptcp")) ++ goto next_listen; ++ ++ sk = ctx->conn; ++ if (!sk || !net_eq(sock_net(sk), net)) ++ goto next_listen; ++ ++ if (r->sdiag_family != AF_UNSPEC && ++ sk->sk_family != r->sdiag_family) ++ goto next_listen; ++ ++ if (r->id.idiag_sport != inet->inet_sport && ++ r->id.idiag_sport) ++ goto next_listen; ++ ++ if (!refcount_inc_not_zero(&sk->sk_refcnt)) ++ goto next_listen; ++ ++ ret = sk_diag_dump(sk, skb, cb, r, bc, net_admin); ++ ++ sock_put(sk); ++ ++ if (ret < 0) { ++ spin_unlock(&ilb->lock); ++ rcu_read_unlock(); ++ diag_ctx->l_slot = i; ++ diag_ctx->l_num = num; ++ return; ++ } ++ diag_ctx->l_num = num + 1; ++ num = 0; ++next_listen: ++ ++num; ++ } ++ spin_unlock(&ilb->lock); ++ rcu_read_unlock(); ++ ++ cond_resched(); ++ diag_ctx->l_num = 0; ++ } ++ ++ diag_ctx->l_num = 0; ++ diag_ctx->l_slot = i; ++} ++ + static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, + const struct inet_diag_req_v2 *r) + { +@@ -114,6 +189,9 @@ static void mptcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, + } + cond_resched(); + } ++ ++ if ((r->idiag_states & TCPF_LISTEN) && r->id.idiag_dport == 0) ++ mptcp_diag_dump_listeners(skb, cb, r, net_admin); + } + + static void mptcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, +@@ -127,6 +205,19 @@ static void mptcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, + + r->idiag_rqueue = sk_rmem_alloc_get(sk); + r->idiag_wqueue = sk_wmem_alloc_get(sk); ++ ++ if (inet_sk_state_load(sk) == TCP_LISTEN) { ++ struct sock *lsk = READ_ONCE(msk->first); ++ ++ if (lsk) { ++ /* override with settings from tcp listener, ++ * so Send-Q will show accept queue. ++ */ ++ r->idiag_rqueue = READ_ONCE(lsk->sk_ack_backlog); ++ r->idiag_wqueue = READ_ONCE(lsk->sk_max_ack_backlog); ++ } ++ } ++ + if (!info) + return; + +-- +2.42.0 + diff --git a/queue-5.15/net-annotate-data-races-around-sk-sk_dst_pending_con.patch b/queue-5.15/net-annotate-data-races-around-sk-sk_dst_pending_con.patch new file mode 100644 index 00000000000..503b0ab994d --- /dev/null +++ b/queue-5.15/net-annotate-data-races-around-sk-sk_dst_pending_con.patch @@ -0,0 +1,82 @@ +From 3b1c2d6b75b5f10ded03e367c860a0430fa57cec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 20:28:18 +0000 +Subject: net: annotate data-races around sk->sk_dst_pending_confirm + +From: Eric Dumazet + +[ Upstream commit eb44ad4e635132754bfbcb18103f1dcb7058aedd ] + +This field can be read or written without socket lock being held. + +Add annotations to avoid load-store tearing. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 6 +++--- + net/core/sock.c | 2 +- + net/ipv4/tcp_output.c | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index d148dc95c9e9c..e19eebaf59f73 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2083,7 +2083,7 @@ static inline void __dst_negative_advice(struct sock *sk) + if (ndst != dst) { + rcu_assign_pointer(sk->sk_dst_cache, ndst); + sk_tx_queue_clear(sk); +- sk->sk_dst_pending_confirm = 0; ++ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); + } + } + } +@@ -2100,7 +2100,7 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst) + struct dst_entry *old_dst; + + sk_tx_queue_clear(sk); +- sk->sk_dst_pending_confirm = 0; ++ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); + old_dst = rcu_dereference_protected(sk->sk_dst_cache, + lockdep_sock_is_held(sk)); + rcu_assign_pointer(sk->sk_dst_cache, dst); +@@ -2113,7 +2113,7 @@ sk_dst_set(struct sock *sk, struct dst_entry *dst) + struct dst_entry *old_dst; + + sk_tx_queue_clear(sk); +- sk->sk_dst_pending_confirm = 0; ++ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); + old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst); + dst_release(old_dst); + } +diff --git a/net/core/sock.c b/net/core/sock.c +index 8faa0f9cc0839..662cd6d54ac70 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -557,7 +557,7 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) + INDIRECT_CALL_INET(dst->ops->check, ip6_dst_check, ipv4_dst_check, + dst, cookie) == NULL) { + sk_tx_queue_clear(sk); +- sk->sk_dst_pending_confirm = 0; ++ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); + RCU_INIT_POINTER(sk->sk_dst_cache, NULL); + dst_release(dst); + return NULL; +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 9d5e652c9bba1..8032ccb69463e 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1318,7 +1318,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, + skb->destructor = skb_is_tcp_pure_ack(skb) ? __sock_wfree : tcp_wfree; + refcount_add(skb->truesize, &sk->sk_wmem_alloc); + +- skb_set_dst_pending_confirm(skb, sk->sk_dst_pending_confirm); ++ skb_set_dst_pending_confirm(skb, READ_ONCE(sk->sk_dst_pending_confirm)); + + /* Build TCP header and checksum it. */ + th = (struct tcphdr *)skb->data; +-- +2.42.0 + diff --git a/queue-5.15/net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch b/queue-5.15/net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch new file mode 100644 index 00000000000..eaf7a8183ff --- /dev/null +++ b/queue-5.15/net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch @@ -0,0 +1,65 @@ +From cb888d3dd8ea845b15298f791f5e9a0d496a4116 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 20:28:17 +0000 +Subject: net: annotate data-races around sk->sk_tx_queue_mapping + +From: Eric Dumazet + +[ Upstream commit 0bb4d124d34044179b42a769a0c76f389ae973b6 ] + +This field can be read or written without socket lock being held. + +Add annotations to avoid load-store tearing. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index 640bd7a367779..d148dc95c9e9c 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1923,21 +1923,33 @@ static inline void sk_tx_queue_set(struct sock *sk, int tx_queue) + /* sk_tx_queue_mapping accept only upto a 16-bit value */ + if (WARN_ON_ONCE((unsigned short)tx_queue >= USHRT_MAX)) + return; +- sk->sk_tx_queue_mapping = tx_queue; ++ /* Paired with READ_ONCE() in sk_tx_queue_get() and ++ * other WRITE_ONCE() because socket lock might be not held. ++ */ ++ WRITE_ONCE(sk->sk_tx_queue_mapping, tx_queue); + } + + #define NO_QUEUE_MAPPING USHRT_MAX + + static inline void sk_tx_queue_clear(struct sock *sk) + { +- sk->sk_tx_queue_mapping = NO_QUEUE_MAPPING; ++ /* Paired with READ_ONCE() in sk_tx_queue_get() and ++ * other WRITE_ONCE() because socket lock might be not held. ++ */ ++ WRITE_ONCE(sk->sk_tx_queue_mapping, NO_QUEUE_MAPPING); + } + + static inline int sk_tx_queue_get(const struct sock *sk) + { +- if (sk && sk->sk_tx_queue_mapping != NO_QUEUE_MAPPING) +- return sk->sk_tx_queue_mapping; ++ if (sk) { ++ /* Paired with WRITE_ONCE() in sk_tx_queue_clear() ++ * and sk_tx_queue_set(). ++ */ ++ int val = READ_ONCE(sk->sk_tx_queue_mapping); + ++ if (val != NO_QUEUE_MAPPING) ++ return val; ++ } + return -1; + } + +-- +2.42.0 + diff --git a/queue-5.15/net-ethernet-cortina-fix-max-rx-frame-define.patch b/queue-5.15/net-ethernet-cortina-fix-max-rx-frame-define.patch new file mode 100644 index 00000000000..456782e4638 --- /dev/null +++ b/queue-5.15/net-ethernet-cortina-fix-max-rx-frame-define.patch @@ -0,0 +1,55 @@ +From a7360bc2a763c795cb93cf65a98f6dda92ae2943 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 10:03:12 +0100 +Subject: net: ethernet: cortina: Fix max RX frame define + +From: Linus Walleij + +[ Upstream commit 510e35fb931ffc3b100e5d5ae4595cd3beca9f1a ] + +Enumerator 3 is 1548 bytes according to the datasheet. +Not 1542. + +Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet") +Reviewed-by: Andrew Lunn +Signed-off-by: Linus Walleij +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20231109-gemini-largeframe-fix-v4-1-6e611528db08@linaro.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cortina/gemini.c | 4 ++-- + drivers/net/ethernet/cortina/gemini.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c +index d0ba5ca862cf5..daab31e5bcbae 100644 +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -432,8 +432,8 @@ static const struct gmac_max_framelen gmac_maxlens[] = { + .val = CONFIG0_MAXLEN_1536, + }, + { +- .max_l3_len = 1542, +- .val = CONFIG0_MAXLEN_1542, ++ .max_l3_len = 1548, ++ .val = CONFIG0_MAXLEN_1548, + }, + { + .max_l3_len = 9212, +diff --git a/drivers/net/ethernet/cortina/gemini.h b/drivers/net/ethernet/cortina/gemini.h +index 9fdf77d5eb374..99efb11557436 100644 +--- a/drivers/net/ethernet/cortina/gemini.h ++++ b/drivers/net/ethernet/cortina/gemini.h +@@ -787,7 +787,7 @@ union gmac_config0 { + #define CONFIG0_MAXLEN_1536 0 + #define CONFIG0_MAXLEN_1518 1 + #define CONFIG0_MAXLEN_1522 2 +-#define CONFIG0_MAXLEN_1542 3 ++#define CONFIG0_MAXLEN_1548 3 + #define CONFIG0_MAXLEN_9k 4 /* 9212 */ + #define CONFIG0_MAXLEN_10k 5 /* 10236 */ + #define CONFIG0_MAXLEN_1518__6 6 +-- +2.42.0 + diff --git a/queue-5.15/net-ethernet-cortina-fix-mtu-max-setting.patch b/queue-5.15/net-ethernet-cortina-fix-mtu-max-setting.patch new file mode 100644 index 00000000000..c52c5083154 --- /dev/null +++ b/queue-5.15/net-ethernet-cortina-fix-mtu-max-setting.patch @@ -0,0 +1,91 @@ +From 0332797bfe0bcb3947de7ad7837db211271be9a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 10:03:14 +0100 +Subject: net: ethernet: cortina: Fix MTU max setting + +From: Linus Walleij + +[ Upstream commit dc6c0bfbaa947dd7976e30e8c29b10c868b6fa42 ] + +The RX max frame size is over 10000 for the Gemini ethernet, +but the TX max frame size is actually just 2047 (0x7ff after +checking the datasheet). Reflect this in what we offer to Linux, +cap the MTU at the TX max frame minus ethernet headers. + +We delete the code disabling the hardware checksum for large +MTUs as netdev->mtu can no longer be larger than +netdev->max_mtu meaning the if()-clause in gmac_fix_features() +is never true. + +Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet") +Reviewed-by: Andrew Lunn +Signed-off-by: Linus Walleij +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20231109-gemini-largeframe-fix-v4-3-6e611528db08@linaro.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cortina/gemini.c | 17 ++++------------- + drivers/net/ethernet/cortina/gemini.h | 2 +- + 2 files changed, 5 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c +index fbd83330ca787..675c6dda45e24 100644 +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -2000,15 +2000,6 @@ static int gmac_change_mtu(struct net_device *netdev, int new_mtu) + return 0; + } + +-static netdev_features_t gmac_fix_features(struct net_device *netdev, +- netdev_features_t features) +-{ +- if (netdev->mtu + ETH_HLEN + VLAN_HLEN > MTU_SIZE_BIT_MASK) +- features &= ~GMAC_OFFLOAD_FEATURES; +- +- return features; +-} +- + static int gmac_set_features(struct net_device *netdev, + netdev_features_t features) + { +@@ -2230,7 +2221,6 @@ static const struct net_device_ops gmac_351x_ops = { + .ndo_set_mac_address = gmac_set_mac_address, + .ndo_get_stats64 = gmac_get_stats64, + .ndo_change_mtu = gmac_change_mtu, +- .ndo_fix_features = gmac_fix_features, + .ndo_set_features = gmac_set_features, + }; + +@@ -2480,11 +2470,12 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev) + + netdev->hw_features = GMAC_OFFLOAD_FEATURES; + netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; +- /* We can handle jumbo frames up to 10236 bytes so, let's accept +- * payloads of 10236 bytes minus VLAN and ethernet header ++ /* We can receive jumbo frames up to 10236 bytes but only ++ * transmit 2047 bytes so, let's accept payloads of 2047 ++ * bytes minus VLAN and ethernet header + */ + netdev->min_mtu = ETH_MIN_MTU; +- netdev->max_mtu = 10236 - VLAN_ETH_HLEN; ++ netdev->max_mtu = MTU_SIZE_BIT_MASK - VLAN_ETH_HLEN; + + port->freeq_refill = 0; + netif_napi_add(netdev, &port->napi, gmac_napi_poll, NAPI_POLL_WEIGHT); +diff --git a/drivers/net/ethernet/cortina/gemini.h b/drivers/net/ethernet/cortina/gemini.h +index 99efb11557436..24bb989981f23 100644 +--- a/drivers/net/ethernet/cortina/gemini.h ++++ b/drivers/net/ethernet/cortina/gemini.h +@@ -502,7 +502,7 @@ union gmac_txdesc_3 { + #define SOF_BIT 0x80000000 + #define EOF_BIT 0x40000000 + #define EOFIE_BIT BIT(29) +-#define MTU_SIZE_BIT_MASK 0x1fff ++#define MTU_SIZE_BIT_MASK 0x7ff /* Max MTU 2047 bytes */ + + /* GMAC Tx Descriptor */ + struct gmac_txdesc { +-- +2.42.0 + diff --git a/queue-5.15/net-ethernet-cortina-handle-large-frames.patch b/queue-5.15/net-ethernet-cortina-handle-large-frames.patch new file mode 100644 index 00000000000..c54627e0624 --- /dev/null +++ b/queue-5.15/net-ethernet-cortina-handle-large-frames.patch @@ -0,0 +1,111 @@ +From 63c2f3664f1cf8068c9075ed6165ff84ef63bb76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 10:03:13 +0100 +Subject: net: ethernet: cortina: Handle large frames + +From: Linus Walleij + +[ Upstream commit d4d0c5b4d279bfe3585fbd806efefd3e51c82afa ] + +The Gemini ethernet controller provides hardware checksumming +for frames up to 1514 bytes including ethernet headers but not +FCS. + +If we start sending bigger frames (after first bumping up the MTU +on both interfaces sending and receiving the frames), truncated +packets start to appear on the target such as in this tcpdump +resulting from ping -s 1474: + +23:34:17.241983 14:d6:4d:a8:3c:4f (oui Unknown) > bc:ae:c5:6b:a8:3d (oui Unknown), +ethertype IPv4 (0x0800), length 1514: truncated-ip - 2 bytes missing! +(tos 0x0, ttl 64, id 32653, offset 0, flags [DF], proto ICMP (1), length 1502) +OpenWrt.lan > Fecusia: ICMP echo request, id 1672, seq 50, length 1482 + +If we bypass the hardware checksumming and provide a software +fallback, everything starts working fine up to the max TX MTU +of 2047 bytes, for example ping -s2000 192.168.1.2: + +00:44:29.587598 bc:ae:c5:6b:a8:3d (oui Unknown) > 14:d6:4d:a8:3c:4f (oui Unknown), +ethertype IPv4 (0x0800), length 2042: +(tos 0x0, ttl 64, id 51828, offset 0, flags [none], proto ICMP (1), length 2028) +Fecusia > OpenWrt.lan: ICMP echo reply, id 1683, seq 4, length 2008 + +The bit enabling to bypass hardware checksum (or any of the +"TSS" bits) are undocumented in the hardware reference manual. +The entire hardware checksum unit appears undocumented. The +conclusion that we need to use the "bypass" bit was found by +trial-and-error. + +Since no hardware checksum will happen, we slot in a software +checksum fallback. + +Check for the condition where we need to compute checksum on the +skb with either hardware or software using == CHECKSUM_PARTIAL instead +of != CHECKSUM_NONE which is an incomplete check according to +. + +On the D-Link DIR-685 router this fixes a bug on the conduit +interface to the RTL8366RB DSA switch: as the switch needs to add +space for its tag it increases the MTU on the conduit interface +to 1504 and that means that when the router sends packages +of 1500 bytes these get an extra 4 bytes of DSA tag and the +transfer fails because of the erroneous hardware checksumming, +affecting such basic functionality as the LuCI web interface. + +Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet") +Signed-off-by: Linus Walleij +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20231109-gemini-largeframe-fix-v4-2-6e611528db08@linaro.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cortina/gemini.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c +index daab31e5bcbae..fbd83330ca787 100644 +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -1145,6 +1145,7 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, + dma_addr_t mapping; + unsigned short mtu; + void *buffer; ++ int ret; + + mtu = ETH_HLEN; + mtu += netdev->mtu; +@@ -1159,9 +1160,30 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, + word3 |= mtu; + } + +- if (skb->ip_summed != CHECKSUM_NONE) { ++ if (skb->len >= ETH_FRAME_LEN) { ++ /* Hardware offloaded checksumming isn't working on frames ++ * bigger than 1514 bytes. A hypothesis about this is that the ++ * checksum buffer is only 1518 bytes, so when the frames get ++ * bigger they get truncated, or the last few bytes get ++ * overwritten by the FCS. ++ * ++ * Just use software checksumming and bypass on bigger frames. ++ */ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ ret = skb_checksum_help(skb); ++ if (ret) ++ return ret; ++ } ++ word1 |= TSS_BYPASS_BIT; ++ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + int tcp = 0; + ++ /* We do not switch off the checksumming on non TCP/UDP ++ * frames: as is shown from tests, the checksumming engine ++ * is smart enough to see that a frame is not actually TCP ++ * or UDP and then just pass it through without any changes ++ * to the frame. ++ */ + if (skb->protocol == htons(ETH_P_IP)) { + word1 |= TSS_IP_CHKSUM_BIT; + tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; +-- +2.42.0 + diff --git a/queue-5.15/net-hns3-add-barrier-in-vf-mailbox-reply-process.patch b/queue-5.15/net-hns3-add-barrier-in-vf-mailbox-reply-process.patch new file mode 100644 index 00000000000..fcaa5e466b2 --- /dev/null +++ b/queue-5.15/net-hns3-add-barrier-in-vf-mailbox-reply-process.patch @@ -0,0 +1,51 @@ +From f2040fbd216a4ac4c7cfc1ea0cd52662e35f7598 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:08 +0800 +Subject: net: hns3: add barrier in vf mailbox reply process + +From: Yonglong Liu + +[ Upstream commit ac92c0a9a0603fb448e60f38e63302e4eebb8035 ] + +In hclgevf_mbx_handler() and hclgevf_get_mbx_resp() functions, +there is a typical store-store and load-load scenario between +received_resp and additional_info. This patch adds barrier +to fix the problem. + +Fixes: 4671042f1ef0 ("net: hns3: add match_id to check mailbox response from PF to VF") +Signed-off-by: Yonglong Liu +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +index df6e9b8b26e0f..608a14fc27acc 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +@@ -60,6 +60,9 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1, + i++; + } + ++ /* ensure additional_info will be seen after received_resp */ ++ smp_rmb(); ++ + if (i >= HCLGEVF_MAX_TRY_TIMES) { + dev_err(&hdev->pdev->dev, + "VF could not get mbx(%u,%u) resp(=%d) from PF in %d tries\n", +@@ -175,6 +178,10 @@ static void hclgevf_handle_mbx_response(struct hclgevf_dev *hdev, + resp->resp_status = hclgevf_resp_to_errno(resp_status); + memcpy(resp->additional_info, req->msg.resp_data, + HCLGE_MBX_MAX_RESP_DATA_SIZE * sizeof(u8)); ++ ++ /* ensure additional_info will be seen before setting received_resp */ ++ smp_wmb(); ++ + if (match_id) { + /* If match_id is not zero, it means PF support match_id. + * if the match_id is right, VF get the right response, or +-- +2.42.0 + diff --git a/queue-5.15/net-hns3-add-byte-order-conversion-for-pf-to-vf-mail.patch b/queue-5.15/net-hns3-add-byte-order-conversion-for-pf-to-vf-mail.patch new file mode 100644 index 00000000000..d9a4ef81050 --- /dev/null +++ b/queue-5.15/net-hns3-add-byte-order-conversion-for-pf-to-vf-mail.patch @@ -0,0 +1,516 @@ +From f3483158408cbd61325c7223c3c77dec4380cabc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 May 2022 15:55:29 +0800 +Subject: net: hns3: add byte order conversion for PF to VF mailbox message + +From: Jie Wang + +[ Upstream commit 767975e582c50b39d633f6e1c4bb99cc1f156efb ] + +Currently, hns3 mailbox processing between PF and VF missed to convert +message byte order and use data type u16 instead of __le16 for mailbox +data process. These processes may cause problems between different +architectures. + +So this patch uses __le16/__le32 data type to define mailbox data +structures. To be compatible with old hns3 driver, these structures use +one-byte alignment. Then byte order conversions are added to mailbox +messages from PF to VF. + +Signed-off-by: Jie Wang +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Stable-dep-of: ac92c0a9a060 ("net: hns3: add barrier in vf mailbox reply process") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/hisilicon/hns3/hclge_mbx.h | 36 +++++++-- + .../hisilicon/hns3/hns3pf/hclge_mbx.c | 60 +++++++------- + .../hisilicon/hns3/hns3pf/hclge_trace.h | 2 +- + .../hisilicon/hns3/hns3vf/hclgevf_main.c | 4 +- + .../hisilicon/hns3/hns3vf/hclgevf_main.h | 2 +- + .../hisilicon/hns3/hns3vf/hclgevf_mbx.c | 80 +++++++++++-------- + .../hisilicon/hns3/hns3vf/hclgevf_trace.h | 2 +- + 7 files changed, 109 insertions(+), 77 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +index c4603a70ed60b..277d6d657c429 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +@@ -131,13 +131,13 @@ struct hclge_vf_to_pf_msg { + }; + + struct hclge_pf_to_vf_msg { +- u16 code; ++ __le16 code; + union { + /* used for mbx response */ + struct { +- u16 vf_mbx_msg_code; +- u16 vf_mbx_msg_subcode; +- u16 resp_status; ++ __le16 vf_mbx_msg_code; ++ __le16 vf_mbx_msg_subcode; ++ __le16 resp_status; + u8 resp_data[HCLGE_MBX_MAX_RESP_DATA_SIZE]; + }; + /* used for general mbx */ +@@ -154,7 +154,7 @@ struct hclge_mbx_vf_to_pf_cmd { + u8 rsv1[1]; + u8 msg_len; + u8 rsv2; +- u16 match_id; ++ __le16 match_id; + struct hclge_vf_to_pf_msg msg; + }; + +@@ -165,7 +165,7 @@ struct hclge_mbx_pf_to_vf_cmd { + u8 rsv[3]; + u8 msg_len; + u8 rsv1; +- u16 match_id; ++ __le16 match_id; + struct hclge_pf_to_vf_msg msg; + }; + +@@ -175,6 +175,28 @@ struct hclge_vf_rst_cmd { + u8 rsv[22]; + }; + ++#pragma pack(1) ++struct hclge_mbx_link_status { ++ __le16 link_status; ++ __le32 speed; ++ __le16 duplex; ++ u8 flag; ++}; ++ ++struct hclge_mbx_link_mode { ++ __le16 idx; ++ __le64 link_mode; ++}; ++ ++struct hclge_mbx_port_base_vlan { ++ __le16 state; ++ __le16 vlan_proto; ++ __le16 qos; ++ __le16 vlan_tag; ++}; ++ ++#pragma pack() ++ + /* used by VF to store the received Async responses from PF */ + struct hclgevf_mbx_arq_ring { + #define HCLGE_MBX_MAX_ARQ_MSG_SIZE 8 +@@ -183,7 +205,7 @@ struct hclgevf_mbx_arq_ring { + u32 head; + u32 tail; + atomic_t count; +- u16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE]; ++ __le16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE]; + }; + + #define hclge_mbx_ring_ptr_move_crq(crq) \ +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +index dac4ac425481c..5182051e5414d 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +@@ -56,17 +56,19 @@ static int hclge_gen_resp_to_vf(struct hclge_vport *vport, + resp_pf_to_vf->msg_len = vf_to_pf_req->msg_len; + resp_pf_to_vf->match_id = vf_to_pf_req->match_id; + +- resp_pf_to_vf->msg.code = HCLGE_MBX_PF_VF_RESP; +- resp_pf_to_vf->msg.vf_mbx_msg_code = vf_to_pf_req->msg.code; +- resp_pf_to_vf->msg.vf_mbx_msg_subcode = vf_to_pf_req->msg.subcode; ++ resp_pf_to_vf->msg.code = cpu_to_le16(HCLGE_MBX_PF_VF_RESP); ++ resp_pf_to_vf->msg.vf_mbx_msg_code = ++ cpu_to_le16(vf_to_pf_req->msg.code); ++ resp_pf_to_vf->msg.vf_mbx_msg_subcode = ++ cpu_to_le16(vf_to_pf_req->msg.subcode); + resp = hclge_errno_to_resp(resp_msg->status); + if (resp < SHRT_MAX) { +- resp_pf_to_vf->msg.resp_status = resp; ++ resp_pf_to_vf->msg.resp_status = cpu_to_le16(resp); + } else { + dev_warn(&hdev->pdev->dev, + "failed to send response to VF, response status %u is out-of-bound\n", + resp); +- resp_pf_to_vf->msg.resp_status = EIO; ++ resp_pf_to_vf->msg.resp_status = cpu_to_le16(EIO); + } + + if (resp_msg->len > 0) +@@ -106,7 +108,7 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len, + + resp_pf_to_vf->dest_vfid = dest_vfid; + resp_pf_to_vf->msg_len = msg_len; +- resp_pf_to_vf->msg.code = mbx_opcode; ++ resp_pf_to_vf->msg.code = cpu_to_le16(mbx_opcode); + + memcpy(resp_pf_to_vf->msg.msg_data, msg, msg_len); + +@@ -124,8 +126,8 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len, + int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport) + { + struct hclge_dev *hdev = vport->back; ++ __le16 msg_data; + u16 reset_type; +- u8 msg_data[2]; + u8 dest_vfid; + + BUILD_BUG_ON(HNAE3_MAX_RESET > U16_MAX); +@@ -139,10 +141,10 @@ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport) + else + reset_type = HNAE3_VF_FUNC_RESET; + +- memcpy(&msg_data[0], &reset_type, sizeof(u16)); ++ msg_data = cpu_to_le16(reset_type); + + /* send this requested info to VF */ +- return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), ++ return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data), + HCLGE_MBX_ASSERTING_RESET, dest_vfid); + } + +@@ -338,16 +340,14 @@ int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid, + u16 state, + struct hclge_vlan_info *vlan_info) + { +-#define MSG_DATA_SIZE 8 ++ struct hclge_mbx_port_base_vlan base_vlan; + +- u8 msg_data[MSG_DATA_SIZE]; ++ base_vlan.state = cpu_to_le16(state); ++ base_vlan.vlan_proto = cpu_to_le16(vlan_info->vlan_proto); ++ base_vlan.qos = cpu_to_le16(vlan_info->qos); ++ base_vlan.vlan_tag = cpu_to_le16(vlan_info->vlan_tag); + +- memcpy(&msg_data[0], &state, sizeof(u16)); +- memcpy(&msg_data[2], &vlan_info->vlan_proto, sizeof(u16)); +- memcpy(&msg_data[4], &vlan_info->qos, sizeof(u16)); +- memcpy(&msg_data[6], &vlan_info->vlan_tag, sizeof(u16)); +- +- return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), ++ return hclge_send_mbx_msg(vport, (u8 *)&base_vlan, sizeof(base_vlan), + HCLGE_MBX_PUSH_VLAN_INFO, vfid); + } + +@@ -487,10 +487,9 @@ int hclge_push_vf_link_status(struct hclge_vport *vport) + #define HCLGE_VF_LINK_STATE_UP 1U + #define HCLGE_VF_LINK_STATE_DOWN 0U + ++ struct hclge_mbx_link_status link_info; + struct hclge_dev *hdev = vport->back; + u16 link_status; +- u8 msg_data[9]; +- u16 duplex; + + /* mac.link can only be 0 or 1 */ + switch (vport->vf_info.link_state) { +@@ -506,14 +505,13 @@ int hclge_push_vf_link_status(struct hclge_vport *vport) + break; + } + +- duplex = hdev->hw.mac.duplex; +- memcpy(&msg_data[0], &link_status, sizeof(u16)); +- memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32)); +- memcpy(&msg_data[6], &duplex, sizeof(u16)); +- msg_data[8] = HCLGE_MBX_PUSH_LINK_STATUS_EN; ++ link_info.link_status = cpu_to_le16(link_status); ++ link_info.speed = cpu_to_le32(hdev->hw.mac.speed); ++ link_info.duplex = cpu_to_le16(hdev->hw.mac.duplex); ++ link_info.flag = HCLGE_MBX_PUSH_LINK_STATUS_EN; + + /* send this requested info to VF */ +- return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), ++ return hclge_send_mbx_msg(vport, (u8 *)&link_info, sizeof(link_info), + HCLGE_MBX_LINK_STAT_CHANGE, vport->vport_id); + } + +@@ -521,22 +519,22 @@ static void hclge_get_link_mode(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req) + { + #define HCLGE_SUPPORTED 1 ++ struct hclge_mbx_link_mode link_mode; + struct hclge_dev *hdev = vport->back; + unsigned long advertising; + unsigned long supported; + unsigned long send_data; +- u8 msg_data[10] = {}; + u8 dest_vfid; + + advertising = hdev->hw.mac.advertising[0]; + supported = hdev->hw.mac.supported[0]; + dest_vfid = mbx_req->mbx_src_vfid; +- msg_data[0] = mbx_req->msg.data[0]; +- +- send_data = msg_data[0] == HCLGE_SUPPORTED ? supported : advertising; ++ send_data = mbx_req->msg.data[0] == HCLGE_SUPPORTED ? supported : ++ advertising; ++ link_mode.idx = cpu_to_le16((u16)mbx_req->msg.data[0]); ++ link_mode.link_mode = cpu_to_le64(send_data); + +- memcpy(&msg_data[2], &send_data, sizeof(unsigned long)); +- hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), ++ hclge_send_mbx_msg(vport, (u8 *)&link_mode, sizeof(link_mode), + HCLGE_MBX_LINK_STAT_MODE, dest_vfid); + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h +index 5b0b71bd61200..8510b88d49820 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h +@@ -62,7 +62,7 @@ TRACE_EVENT(hclge_pf_mbx_send, + + TP_fast_assign( + __entry->vfid = req->dest_vfid; +- __entry->code = req->msg.code; ++ __entry->code = le16_to_cpu(req->msg.code); + __assign_str(pciname, pci_name(hdev->pdev)); + __assign_str(devname, &hdev->vport[0].nic.kinfo.netdev->name); + memcpy(__entry->mbx_data, req, +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index 8adc682f624f9..69913af880a40 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -3816,7 +3816,7 @@ static void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, + } + + void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state, +- u8 *port_base_vlan_info, u8 data_size) ++ struct hclge_mbx_port_base_vlan *port_base_vlan) + { + struct hnae3_handle *nic = &hdev->nic; + struct hclge_vf_to_pf_msg send_msg; +@@ -3841,7 +3841,7 @@ void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state, + /* send msg to PF and wait update port based vlan info */ + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, + HCLGE_MBX_PORT_BASE_VLAN_CFG); +- memcpy(send_msg.data, port_base_vlan_info, data_size); ++ memcpy(send_msg.data, port_base_vlan, sizeof(*port_base_vlan)); + ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); + if (!ret) { + if (state == HNAE3_PORT_BASE_VLAN_DISABLE) +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +index f6f736c0091c0..e16068264fa77 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +@@ -355,5 +355,5 @@ void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed, + void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev); + void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev); + void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state, +- u8 *port_base_vlan_info, u8 data_size); ++ struct hclge_mbx_port_base_vlan *port_base_vlan); + #endif +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +index c5ac6ecf36e10..df6e9b8b26e0f 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +@@ -121,7 +121,7 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, + if (need_resp) { + mutex_lock(&hdev->mbx_resp.mbx_mutex); + hclgevf_reset_mbx_resp_status(hdev); +- req->match_id = hdev->mbx_resp.match_id; ++ req->match_id = cpu_to_le16(hdev->mbx_resp.match_id); + status = hclgevf_cmd_send(&hdev->hw, &desc, 1); + if (status) { + dev_err(&hdev->pdev->dev, +@@ -159,27 +159,29 @@ static bool hclgevf_cmd_crq_empty(struct hclgevf_hw *hw) + static void hclgevf_handle_mbx_response(struct hclgevf_dev *hdev, + struct hclge_mbx_pf_to_vf_cmd *req) + { ++ u16 vf_mbx_msg_subcode = le16_to_cpu(req->msg.vf_mbx_msg_subcode); ++ u16 vf_mbx_msg_code = le16_to_cpu(req->msg.vf_mbx_msg_code); + struct hclgevf_mbx_resp_status *resp = &hdev->mbx_resp; ++ u16 resp_status = le16_to_cpu(req->msg.resp_status); ++ u16 match_id = le16_to_cpu(req->match_id); + + if (resp->received_resp) + dev_warn(&hdev->pdev->dev, +- "VF mbx resp flag not clear(%u)\n", +- req->msg.vf_mbx_msg_code); +- +- resp->origin_mbx_msg = +- (req->msg.vf_mbx_msg_code << 16); +- resp->origin_mbx_msg |= req->msg.vf_mbx_msg_subcode; +- resp->resp_status = +- hclgevf_resp_to_errno(req->msg.resp_status); ++ "VF mbx resp flag not clear(%u)\n", ++ vf_mbx_msg_code); ++ ++ resp->origin_mbx_msg = (vf_mbx_msg_code << 16); ++ resp->origin_mbx_msg |= vf_mbx_msg_subcode; ++ resp->resp_status = hclgevf_resp_to_errno(resp_status); + memcpy(resp->additional_info, req->msg.resp_data, + HCLGE_MBX_MAX_RESP_DATA_SIZE * sizeof(u8)); +- if (req->match_id) { ++ if (match_id) { + /* If match_id is not zero, it means PF support match_id. + * if the match_id is right, VF get the right response, or + * ignore the response. and driver will clear hdev->mbx_resp + * when send next message which need response. + */ +- if (req->match_id == resp->match_id) ++ if (match_id == resp->match_id) + resp->received_resp = true; + } else { + resp->received_resp = true; +@@ -196,7 +198,7 @@ static void hclgevf_handle_mbx_msg(struct hclgevf_dev *hdev, + HCLGE_MBX_MAX_ARQ_MSG_NUM) { + dev_warn(&hdev->pdev->dev, + "Async Q full, dropping msg(%u)\n", +- req->msg.code); ++ le16_to_cpu(req->msg.code)); + return; + } + +@@ -215,6 +217,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) + struct hclgevf_cmq_ring *crq; + struct hclgevf_desc *desc; + u16 flag; ++ u16 code; + + crq = &hdev->hw.cmq.crq; + +@@ -228,10 +231,11 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) + req = (struct hclge_mbx_pf_to_vf_cmd *)desc->data; + + flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); ++ code = le16_to_cpu(req->msg.code); + if (unlikely(!hnae3_get_bit(flag, HCLGEVF_CMDQ_RX_OUTVLD_B))) { + dev_warn(&hdev->pdev->dev, + "dropped invalid mailbox message, code = %u\n", +- req->msg.code); ++ code); + + /* dropping/not processing this invalid message */ + crq->desc[crq->next_to_use].flag = 0; +@@ -247,7 +251,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) + * timeout and simultaneously queue the async messages for later + * prcessing in context of mailbox task i.e. the slow path. + */ +- switch (req->msg.code) { ++ switch (code) { + case HCLGE_MBX_PF_VF_RESP: + hclgevf_handle_mbx_response(hdev, req); + break; +@@ -261,7 +265,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) + default: + dev_err(&hdev->pdev->dev, + "VF received unsupported(%u) mbx msg from PF\n", +- req->msg.code); ++ code); + break; + } + crq->desc[crq->next_to_use].flag = 0; +@@ -283,14 +287,18 @@ static void hclgevf_parse_promisc_info(struct hclgevf_dev *hdev, + + void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev) + { ++ struct hclge_mbx_port_base_vlan *vlan_info; ++ struct hclge_mbx_link_status *link_info; ++ struct hclge_mbx_link_mode *link_mode; + enum hnae3_reset_type reset_type; + u16 link_status, state; +- u16 *msg_q, *vlan_info; ++ __le16 *msg_q; ++ u16 opcode; + u8 duplex; + u32 speed; + u32 tail; + u8 flag; +- u8 idx; ++ u16 idx; + + tail = hdev->arq.tail; + +@@ -303,13 +311,14 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev) + } + + msg_q = hdev->arq.msg_q[hdev->arq.head]; +- +- switch (msg_q[0]) { ++ opcode = le16_to_cpu(msg_q[0]); ++ switch (opcode) { + case HCLGE_MBX_LINK_STAT_CHANGE: +- link_status = msg_q[1]; +- memcpy(&speed, &msg_q[2], sizeof(speed)); +- duplex = (u8)msg_q[4]; +- flag = (u8)msg_q[5]; ++ link_info = (struct hclge_mbx_link_status *)(msg_q + 1); ++ link_status = le16_to_cpu(link_info->link_status); ++ speed = le32_to_cpu(link_info->speed); ++ duplex = (u8)le16_to_cpu(link_info->duplex); ++ flag = link_info->flag; + + /* update upper layer with new link link status */ + hclgevf_update_speed_duplex(hdev, speed, duplex); +@@ -321,13 +330,14 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev) + + break; + case HCLGE_MBX_LINK_STAT_MODE: +- idx = (u8)msg_q[1]; ++ link_mode = (struct hclge_mbx_link_mode *)(msg_q + 1); ++ idx = le16_to_cpu(link_mode->idx); + if (idx) +- memcpy(&hdev->hw.mac.supported, &msg_q[2], +- sizeof(unsigned long)); ++ hdev->hw.mac.supported = ++ le64_to_cpu(link_mode->link_mode); + else +- memcpy(&hdev->hw.mac.advertising, &msg_q[2], +- sizeof(unsigned long)); ++ hdev->hw.mac.advertising = ++ le64_to_cpu(link_mode->link_mode); + break; + case HCLGE_MBX_ASSERTING_RESET: + /* PF has asserted reset hence VF should go in pending +@@ -335,25 +345,27 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev) + * has been completely reset. After this stack should + * eventually be re-initialized. + */ +- reset_type = (enum hnae3_reset_type)msg_q[1]; ++ reset_type = ++ (enum hnae3_reset_type)le16_to_cpu(msg_q[1]); + set_bit(reset_type, &hdev->reset_pending); + set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); + hclgevf_reset_task_schedule(hdev); + + break; + case HCLGE_MBX_PUSH_VLAN_INFO: +- state = msg_q[1]; +- vlan_info = &msg_q[1]; ++ vlan_info = ++ (struct hclge_mbx_port_base_vlan *)(msg_q + 1); ++ state = le16_to_cpu(vlan_info->state); + hclgevf_update_port_base_vlan_info(hdev, state, +- (u8 *)vlan_info, 8); ++ vlan_info); + break; + case HCLGE_MBX_PUSH_PROMISC_INFO: +- hclgevf_parse_promisc_info(hdev, msg_q[1]); ++ hclgevf_parse_promisc_info(hdev, le16_to_cpu(msg_q[1])); + break; + default: + dev_err(&hdev->pdev->dev, + "fetched unsupported(%u) message from arq\n", +- msg_q[0]); ++ opcode); + break; + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h +index e4bfb6191fef5..5d4895bb57a17 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h +@@ -29,7 +29,7 @@ TRACE_EVENT(hclge_vf_mbx_get, + + TP_fast_assign( + __entry->vfid = req->dest_vfid; +- __entry->code = req->msg.code; ++ __entry->code = le16_to_cpu(req->msg.code); + __assign_str(pciname, pci_name(hdev->pdev)); + __assign_str(devname, &hdev->nic.kinfo.netdev->name); + memcpy(__entry->mbx_data, req, +-- +2.42.0 + diff --git a/queue-5.15/net-hns3-fix-add-vlan-fail-issue.patch b/queue-5.15/net-hns3-fix-add-vlan-fail-issue.patch new file mode 100644 index 00000000000..175566751a4 --- /dev/null +++ b/queue-5.15/net-hns3-fix-add-vlan-fail-issue.patch @@ -0,0 +1,192 @@ +From 5e9c42355906b46605dc0e9b74ed098de3e19a4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:07 +0800 +Subject: net: hns3: fix add VLAN fail issue +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jian Shen + +[ Upstream commit 472a2ff63efb30234cbf6b2cdaf8117f21b4f8bc ] + +The hclge_sync_vlan_filter is called in periodic task, +trying to remove VLAN from vlan_del_fail_bmap. It can +be concurrence with VLAN adding operation from user. +So once user failed to delete a VLAN id, and add it +again soon, it may be removed by the periodic task, +which may cause the software configuration being +inconsistent with hardware. So add mutex handling +to avoid this. + + user hns3 driver + + periodic task + │ + add vlan 10 ───── hns3_vlan_rx_add_vid │ + │ (suppose success) │ + │ │ + del vlan 10 ───── hns3_vlan_rx_kill_vid │ + │ (suppose fail,add to │ + │ vlan_del_fail_bmap) │ + │ │ + add vlan 10 ───── hns3_vlan_rx_add_vid │ + (suppose success) │ + foreach vlan_del_fail_bmp + del vlan 10 + +Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed") +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../hisilicon/hns3/hns3pf/hclge_main.c | 28 +++++++++++++------ + .../hisilicon/hns3/hns3vf/hclgevf_main.c | 11 ++++++-- + 2 files changed, 29 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index ca59e1cd992e5..dba3cf15b48e1 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -10196,8 +10196,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, + struct hclge_vport_vlan_cfg *vlan, *tmp; + struct hclge_dev *hdev = vport->back; + +- mutex_lock(&hdev->vport_lock); +- + list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) { + if (vlan->vlan_id == vlan_id) { + if (is_write_tbl && vlan->hd_tbl_status) +@@ -10212,8 +10210,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, + break; + } + } +- +- mutex_unlock(&hdev->vport_lock); + } + + void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list) +@@ -10618,11 +10614,16 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, + * handle mailbox. Just record the vlan id, and remove it after + * reset finished. + */ ++ mutex_lock(&hdev->vport_lock); + if ((test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || + test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) && is_kill) { + set_bit(vlan_id, vport->vlan_del_fail_bmap); ++ mutex_unlock(&hdev->vport_lock); + return -EBUSY; ++ } else if (!is_kill && test_bit(vlan_id, vport->vlan_del_fail_bmap)) { ++ clear_bit(vlan_id, vport->vlan_del_fail_bmap); + } ++ mutex_unlock(&hdev->vport_lock); + + /* when port base vlan enabled, we use port base vlan as the vlan + * filter entry. In this case, we don't update vlan filter table +@@ -10637,17 +10638,22 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, + } + + if (!ret) { +- if (!is_kill) ++ if (!is_kill) { + hclge_add_vport_vlan_table(vport, vlan_id, + writen_to_tbl); +- else if (is_kill && vlan_id != 0) ++ } else if (is_kill && vlan_id != 0) { ++ mutex_lock(&hdev->vport_lock); + hclge_rm_vport_vlan_table(vport, vlan_id, false); ++ mutex_unlock(&hdev->vport_lock); ++ } + } else if (is_kill) { + /* when remove hw vlan filter failed, record the vlan id, + * and try to remove it from hw later, to be consistence + * with stack + */ ++ mutex_lock(&hdev->vport_lock); + set_bit(vlan_id, vport->vlan_del_fail_bmap); ++ mutex_unlock(&hdev->vport_lock); + } + + hclge_set_vport_vlan_fltr_change(vport); +@@ -10687,6 +10693,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) + int i, ret, sync_cnt = 0; + u16 vlan_id; + ++ mutex_lock(&hdev->vport_lock); + /* start from vport 1 for PF is always alive */ + for (i = 0; i < hdev->num_alloc_vport; i++) { + struct hclge_vport *vport = &hdev->vport[i]; +@@ -10697,21 +10704,26 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) + ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), + vport->vport_id, vlan_id, + true); +- if (ret && ret != -EINVAL) ++ if (ret && ret != -EINVAL) { ++ mutex_unlock(&hdev->vport_lock); + return; ++ } + + clear_bit(vlan_id, vport->vlan_del_fail_bmap); + hclge_rm_vport_vlan_table(vport, vlan_id, false); + hclge_set_vport_vlan_fltr_change(vport); + + sync_cnt++; +- if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) ++ if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) { ++ mutex_unlock(&hdev->vport_lock); + return; ++ } + + vlan_id = find_first_bit(vport->vlan_del_fail_bmap, + VLAN_N_VID); + } + } ++ mutex_unlock(&hdev->vport_lock); + + hclge_sync_vlan_fltr_state(hdev); + } +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index bc140e3620d6c..8adc682f624f9 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -1710,6 +1710,8 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, + test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) && is_kill) { + set_bit(vlan_id, hdev->vlan_del_fail_bmap); + return -EBUSY; ++ } else if (!is_kill && test_bit(vlan_id, hdev->vlan_del_fail_bmap)) { ++ clear_bit(vlan_id, hdev->vlan_del_fail_bmap); + } + + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, +@@ -1737,20 +1739,25 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) + int ret, sync_cnt = 0; + u16 vlan_id; + ++ if (bitmap_empty(hdev->vlan_del_fail_bmap, VLAN_N_VID)) ++ return; ++ ++ rtnl_lock(); + vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); + while (vlan_id != VLAN_N_VID) { + ret = hclgevf_set_vlan_filter(handle, htons(ETH_P_8021Q), + vlan_id, true); + if (ret) +- return; ++ break; + + clear_bit(vlan_id, hdev->vlan_del_fail_bmap); + sync_cnt++; + if (sync_cnt >= HCLGEVF_MAX_SYNC_COUNT) +- return; ++ break; + + vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); + } ++ rtnl_unlock(); + } + + static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) +-- +2.42.0 + diff --git a/queue-5.15/net-hns3-fix-incorrect-capability-bit-display-for-co.patch b/queue-5.15/net-hns3-fix-incorrect-capability-bit-display-for-co.patch new file mode 100644 index 00000000000..35bf6275c77 --- /dev/null +++ b/queue-5.15/net-hns3-fix-incorrect-capability-bit-display-for-co.patch @@ -0,0 +1,38 @@ +From 27451f7605235ede2c9eb12c98f3a6ca9d252958 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:09 +0800 +Subject: net: hns3: fix incorrect capability bit display for copper port + +From: Jian Shen + +[ Upstream commit 75b247b57d8b71bcb679e4cb37d0db104848806c ] + +Currently, the FEC capability bit is default set for device version V2. +It's incorrect for the copper port. Eventhough it doesn't make the nic +work abnormal, but the capability information display in debugfs may +confuse user. So clear it when driver get the port type inforamtion. + +Fixes: 433ccce83504 ("net: hns3: use FEC capability queried from firmware") +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index dba3cf15b48e1..7c28c74c1de92 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -11713,6 +11713,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) + goto err_msi_irq_uninit; + + if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) { ++ clear_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps); + if (hnae3_dev_phy_imp_supported(hdev)) + ret = hclge_update_tp_port_info(hdev); + else +-- +2.42.0 + diff --git a/queue-5.15/net-hns3-fix-variable-may-not-initialized-problem-in.patch b/queue-5.15/net-hns3-fix-variable-may-not-initialized-problem-in.patch new file mode 100644 index 00000000000..b66400d6a16 --- /dev/null +++ b/queue-5.15/net-hns3-fix-variable-may-not-initialized-problem-in.patch @@ -0,0 +1,38 @@ +From 2741363ab0a3170cec241ea5abaf663494c9edaa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:11 +0800 +Subject: net: hns3: fix variable may not initialized problem in + hns3_init_mac_addr() + +From: Yonglong Liu + +[ Upstream commit dbd2f3b20c6ae425665b6975d766e3653d453e73 ] + +When a VF is calling hns3_init_mac_addr(), get_mac_addr() may +return fail, then the value of mac_addr_temp is not initialized. + +Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC") +Signed-off-by: Yonglong Liu +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 fde1ff3580458..60e610ab976d4 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -4915,7 +4915,7 @@ static int hns3_init_mac_addr(struct net_device *netdev) + struct hns3_nic_priv *priv = netdev_priv(netdev); + char format_mac_addr[HNAE3_FORMAT_MAC_ADDR_LEN]; + struct hnae3_handle *h = priv->ae_handle; +- u8 mac_addr_temp[ETH_ALEN]; ++ u8 mac_addr_temp[ETH_ALEN] = {0}; + int ret = 0; + + if (h->ae_algo->ops->get_mac_addr) +-- +2.42.0 + diff --git a/queue-5.15/net-hns3-fix-vf-reset-fail-issue.patch b/queue-5.15/net-hns3-fix-vf-reset-fail-issue.patch new file mode 100644 index 00000000000..02f320818f4 --- /dev/null +++ b/queue-5.15/net-hns3-fix-vf-reset-fail-issue.patch @@ -0,0 +1,83 @@ +From a532a0b3a0ab46fa2f120d8bf4057bf8622dfcda Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:12 +0800 +Subject: net: hns3: fix VF reset fail issue + +From: Jijie Shao + +[ Upstream commit 65e98bb56fa3ce2edb400930c05238c9b380500e ] + +Currently the reset process in hns3 and firmware watchdog init process is +asynchronous. We think firmware watchdog initialization is completed +before VF clear the interrupt source. However, firmware initialization +may not complete early. So VF will receive multiple reset interrupts +and fail to reset. + +So we add delay before VF interrupt source and 5 ms delay +is enough to avoid second reset interrupt. + +Fixes: 427900d27d86 ("net: hns3: fix the timing issue of VF clearing interrupt sources") +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 14 +++++++++++++- + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 1 + + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index 69913af880a40..880feeac06375 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -2487,8 +2487,18 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, + return HCLGEVF_VECTOR0_EVENT_OTHER; + } + ++static void hclgevf_reset_timer(struct timer_list *t) ++{ ++ struct hclgevf_dev *hdev = from_timer(hdev, t, reset_timer); ++ ++ hclgevf_clear_event_cause(hdev, HCLGEVF_VECTOR0_EVENT_RST); ++ hclgevf_reset_task_schedule(hdev); ++} ++ + static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) + { ++#define HCLGEVF_RESET_DELAY 5 ++ + enum hclgevf_evt_cause event_cause; + struct hclgevf_dev *hdev = data; + u32 clearval; +@@ -2500,7 +2510,8 @@ static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) + + switch (event_cause) { + case HCLGEVF_VECTOR0_EVENT_RST: +- hclgevf_reset_task_schedule(hdev); ++ mod_timer(&hdev->reset_timer, ++ jiffies + msecs_to_jiffies(HCLGEVF_RESET_DELAY)); + break; + case HCLGEVF_VECTOR0_EVENT_MBX: + hclgevf_mbx_handler(hdev); +@@ -3477,6 +3488,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) + HCLGEVF_DRIVER_NAME); + + hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); ++ timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); + + return 0; + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +index e16068264fa77..5c7538ca36a76 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +@@ -281,6 +281,7 @@ struct hclgevf_dev { + enum hnae3_reset_type reset_level; + unsigned long reset_pending; + enum hnae3_reset_type reset_type; ++ struct timer_list reset_timer; + + #define HCLGEVF_RESET_REQUESTED 0 + #define HCLGEVF_RESET_PENDING 1 +-- +2.42.0 + diff --git a/queue-5.15/net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch b/queue-5.15/net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch new file mode 100644 index 00000000000..a647a2d982f --- /dev/null +++ b/queue-5.15/net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch @@ -0,0 +1,57 @@ +From c12575deb5a4ab1d42e3006c78399b2bde08fb4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:13 +0800 +Subject: net: hns3: fix VF wrong speed and duplex issue + +From: Jijie Shao + +[ Upstream commit dff655e82faffc287d4a72a59f66fa120bf904e4 ] + +If PF is down, firmware will returns 10 Mbit/s rate and half-duplex mode +when PF queries the port information from firmware. + +After imp reset command is executed, PF status changes to down, +and PF will query link status and updates port information +from firmware in a periodic scheduled task. + +However, there is a low probability that port information is updated +when PF is down, and then PF link status changes to up. +In this case, PF synchronizes incorrect rate and duplex mode to VF. + +This patch fixes it by updating port information before +PF synchronizes the rate and duplex to the VF +when PF changes to up. + +Fixes: 18b6e31f8bf4 ("net: hns3: PF add support for pushing link status to VFs") +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 7c28c74c1de92..9e33f0f0b75dd 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -72,6 +72,7 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev); + static void hclge_sync_fd_table(struct hclge_dev *hdev); + static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, + int wait_cnt); ++static int hclge_update_port_info(struct hclge_dev *hdev); + + static struct hnae3_ae_algo ae_algo; + +@@ -2950,6 +2951,9 @@ static void hclge_update_link_status(struct hclge_dev *hdev) + + if (state != hdev->hw.mac.link) { + hdev->hw.mac.link = state; ++ if (state == HCLGE_LINK_STATUS_UP) ++ hclge_update_port_info(hdev); ++ + client->ops->link_status_change(handle, state); + hclge_config_mac_tnl_int(hdev, state); + if (rclient && rclient->ops->link_status_change) +-- +2.42.0 + diff --git a/queue-5.15/net-hns3-refine-the-definition-for-struct-hclge_pf_t.patch b/queue-5.15/net-hns3-refine-the-definition-for-struct-hclge_pf_t.patch new file mode 100644 index 00000000000..e047237d23f --- /dev/null +++ b/queue-5.15/net-hns3-refine-the-definition-for-struct-hclge_pf_t.patch @@ -0,0 +1,69 @@ +From f48c35bc49a6e8d7e8871cb8ae767b7974bc494a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Apr 2022 11:27:03 +0800 +Subject: net: hns3: refine the definition for struct hclge_pf_to_vf_msg + +From: Jian Shen + +[ Upstream commit 6fde96df0447a29ab785de4fcb229e5543f0cbf7 ] + +The struct hclge_pf_to_vf_msg is used for mailbox message from +PF to VF, including both response and request. But its definition +can only indicate respone, which makes the message data copy in +function hclge_send_mbx_msg() unreadable. So refine it by edding +a general message definition into it. + +Signed-off-by: Jian Shen +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Stable-dep-of: ac92c0a9a060 ("net: hns3: add barrier in vf mailbox reply process") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h | 17 +++++++++++++---- + .../ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 2 +- + 2 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +index c2bd2584201f8..c4603a70ed60b 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +@@ -132,10 +132,19 @@ struct hclge_vf_to_pf_msg { + + struct hclge_pf_to_vf_msg { + u16 code; +- u16 vf_mbx_msg_code; +- u16 vf_mbx_msg_subcode; +- u16 resp_status; +- u8 resp_data[HCLGE_MBX_MAX_RESP_DATA_SIZE]; ++ union { ++ /* used for mbx response */ ++ struct { ++ u16 vf_mbx_msg_code; ++ u16 vf_mbx_msg_subcode; ++ u16 resp_status; ++ u8 resp_data[HCLGE_MBX_MAX_RESP_DATA_SIZE]; ++ }; ++ /* used for general mbx */ ++ struct { ++ u8 msg_data[HCLGE_MBX_MAX_MSG_SIZE]; ++ }; ++ }; + }; + + struct hclge_mbx_vf_to_pf_cmd { +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +index 4a5b11b6fed3f..dac4ac425481c 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +@@ -108,7 +108,7 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len, + resp_pf_to_vf->msg_len = msg_len; + resp_pf_to_vf->msg.code = mbx_opcode; + +- memcpy(&resp_pf_to_vf->msg.vf_mbx_msg_code, msg, msg_len); ++ memcpy(resp_pf_to_vf->msg.msg_data, msg, msg_len); + + trace_hclge_pf_mbx_send(hdev, resp_pf_to_vf); + +-- +2.42.0 + diff --git a/queue-5.15/net-inet-open-code-inet_hash2-and-inet_unhash2.patch b/queue-5.15/net-inet-open-code-inet_hash2-and-inet_unhash2.patch new file mode 100644 index 00000000000..6ab147bc28e --- /dev/null +++ b/queue-5.15/net-inet-open-code-inet_hash2-and-inet_unhash2.patch @@ -0,0 +1,189 @@ +From 33d93ca1767e3bbf364f9316a962cb42d59608f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 May 2022 17:05:58 -0700 +Subject: net: inet: Open code inet_hash2 and inet_unhash2 + +From: Martin KaFai Lau + +[ Upstream commit e8d0059000b20c4745c5b6a713f6adb269cff8ff ] + +This patch folds lhash2 related functions into __inet_hash and +inet_unhash. This will make the removal of the listening_hash +in a latter patch easier to review. + +First, this patch folds inet_hash2 into __inet_hash. + +For unhash, the current call sequence is like +inet_unhash() => __inet_unhash() => inet_unhash2(). +The specific testing cases in __inet_unhash() are mostly related +to TCP_LISTEN sk and its caller inet_unhash() already has +the TCP_LISTEN test, so this patch folds both __inet_unhash() and +inet_unhash2() into inet_unhash(). + +Note that all listening_hash users also have lhash2 initialized, +so the !h->lhash2 check is no longer needed. + +Signed-off-by: Martin KaFai Lau +Reviewed-by: Eric Dumazet +Signed-off-by: Jakub Kicinski +Stable-dep-of: 871019b22d1b ("net: set SOCK_RCU_FREE before inserting socket into hashtable") +Signed-off-by: Sasha Levin +--- + net/ipv4/inet_hashtables.c | 88 ++++++++++++++------------------------ + 1 file changed, 33 insertions(+), 55 deletions(-) + +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 8e0451248fc05..637d806090b00 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -193,40 +193,6 @@ inet_lhash2_bucket_sk(struct inet_hashinfo *h, struct sock *sk) + return inet_lhash2_bucket(h, hash); + } + +-static void inet_hash2(struct inet_hashinfo *h, struct sock *sk) +-{ +- struct inet_listen_hashbucket *ilb2; +- +- if (!h->lhash2) +- return; +- +- ilb2 = inet_lhash2_bucket_sk(h, sk); +- +- spin_lock(&ilb2->lock); +- if (sk->sk_reuseport && sk->sk_family == AF_INET6) +- hlist_add_tail_rcu(&inet_csk(sk)->icsk_listen_portaddr_node, +- &ilb2->head); +- else +- hlist_add_head_rcu(&inet_csk(sk)->icsk_listen_portaddr_node, +- &ilb2->head); +- spin_unlock(&ilb2->lock); +-} +- +-static void inet_unhash2(struct inet_hashinfo *h, struct sock *sk) +-{ +- struct inet_listen_hashbucket *ilb2; +- +- if (!h->lhash2 || +- WARN_ON_ONCE(hlist_unhashed(&inet_csk(sk)->icsk_listen_portaddr_node))) +- return; +- +- ilb2 = inet_lhash2_bucket_sk(h, sk); +- +- spin_lock(&ilb2->lock); +- hlist_del_init_rcu(&inet_csk(sk)->icsk_listen_portaddr_node); +- spin_unlock(&ilb2->lock); +-} +- + static inline int compute_score(struct sock *sk, struct net *net, + const unsigned short hnum, const __be32 daddr, + const int dif, const int sdif) +@@ -626,6 +592,7 @@ static int inet_reuseport_add_sock(struct sock *sk, + int __inet_hash(struct sock *sk, struct sock *osk) + { + struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; ++ struct inet_listen_hashbucket *ilb2; + struct inet_listen_hashbucket *ilb; + int err = 0; + +@@ -637,22 +604,29 @@ int __inet_hash(struct sock *sk, struct sock *osk) + } + WARN_ON(!sk_unhashed(sk)); + ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; ++ ilb2 = inet_lhash2_bucket_sk(hashinfo, sk); + + spin_lock(&ilb->lock); ++ spin_lock(&ilb2->lock); + if (sk->sk_reuseport) { + err = inet_reuseport_add_sock(sk, ilb); + if (err) + goto unlock; + } + if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && +- sk->sk_family == AF_INET6) ++ sk->sk_family == AF_INET6) { ++ hlist_add_tail_rcu(&inet_csk(sk)->icsk_listen_portaddr_node, ++ &ilb2->head); + __sk_nulls_add_node_tail_rcu(sk, &ilb->nulls_head); +- else ++ } else { ++ hlist_add_head_rcu(&inet_csk(sk)->icsk_listen_portaddr_node, ++ &ilb2->head); + __sk_nulls_add_node_rcu(sk, &ilb->nulls_head); +- inet_hash2(hashinfo, sk); ++ } + sock_set_flag(sk, SOCK_RCU_FREE); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + unlock: ++ spin_unlock(&ilb2->lock); + spin_unlock(&ilb->lock); + + return err; +@@ -670,22 +644,6 @@ int inet_hash(struct sock *sk) + } + EXPORT_SYMBOL_GPL(inet_hash); + +-static void __inet_unhash(struct sock *sk, struct inet_listen_hashbucket *ilb) +-{ +- if (sk_unhashed(sk)) +- return; +- +- if (rcu_access_pointer(sk->sk_reuseport_cb)) +- reuseport_stop_listen_sock(sk); +- if (ilb) { +- struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; +- +- inet_unhash2(hashinfo, sk); +- } +- __sk_nulls_del_node_init_rcu(sk); +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); +-} +- + void inet_unhash(struct sock *sk) + { + struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; +@@ -694,20 +652,40 @@ void inet_unhash(struct sock *sk) + return; + + if (sk->sk_state == TCP_LISTEN) { ++ struct inet_listen_hashbucket *ilb2; + struct inet_listen_hashbucket *ilb; + + ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; ++ ilb2 = inet_lhash2_bucket_sk(hashinfo, sk); + /* Don't disable bottom halves while acquiring the lock to + * avoid circular locking dependency on PREEMPT_RT. + */ + spin_lock(&ilb->lock); +- __inet_unhash(sk, ilb); ++ spin_lock(&ilb2->lock); ++ if (sk_unhashed(sk)) { ++ spin_unlock(&ilb2->lock); ++ spin_unlock(&ilb->lock); ++ return; ++ } ++ ++ if (rcu_access_pointer(sk->sk_reuseport_cb)) ++ reuseport_stop_listen_sock(sk); ++ ++ hlist_del_init_rcu(&inet_csk(sk)->icsk_listen_portaddr_node); ++ __sk_nulls_del_node_init_rcu(sk); ++ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ spin_unlock(&ilb2->lock); + spin_unlock(&ilb->lock); + } else { + spinlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash); + + spin_lock_bh(lock); +- __inet_unhash(sk, NULL); ++ if (sk_unhashed(sk)) { ++ spin_unlock_bh(lock); ++ return; ++ } ++ __sk_nulls_del_node_init_rcu(sk); ++ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + spin_unlock_bh(lock); + } + } +-- +2.42.0 + diff --git a/queue-5.15/net-inet-remove-count-from-inet_listen_hashbucket.patch b/queue-5.15/net-inet-remove-count-from-inet_listen_hashbucket.patch new file mode 100644 index 00000000000..d96ab92df3b --- /dev/null +++ b/queue-5.15/net-inet-remove-count-from-inet_listen_hashbucket.patch @@ -0,0 +1,90 @@ +From 6836d9ea0707dc78096b913279ac3cd3fc1d1c19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 May 2022 17:05:52 -0700 +Subject: net: inet: Remove count from inet_listen_hashbucket + +From: Martin KaFai Lau + +[ Upstream commit 8ea1eebb49a2dfee1dce621a638cc1626e542392 ] + +After commit 0ee58dad5b06 ("net: tcp6: prefer listeners bound to an address") +and commit d9fbc7f6431f ("net: tcp: prefer listeners bound to an address"), +the count is no longer used. This patch removes it. + +Signed-off-by: Martin KaFai Lau +Reviewed-by: Eric Dumazet +Signed-off-by: Jakub Kicinski +Stable-dep-of: 871019b22d1b ("net: set SOCK_RCU_FREE before inserting socket into hashtable") +Signed-off-by: Sasha Levin +--- + include/net/inet_hashtables.h | 1 - + net/ipv4/inet_hashtables.c | 6 ------ + 2 files changed, 7 deletions(-) + +diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h +index 53c22b64e9724..405670d7661da 100644 +--- a/include/net/inet_hashtables.h ++++ b/include/net/inet_hashtables.h +@@ -111,7 +111,6 @@ struct inet_bind_hashbucket { + #define LISTENING_NULLS_BASE (1U << 29) + struct inet_listen_hashbucket { + spinlock_t lock; +- unsigned int count; + union { + struct hlist_head head; + struct hlist_nulls_head nulls_head; +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 2936676f86eb8..8e0451248fc05 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -209,7 +209,6 @@ static void inet_hash2(struct inet_hashinfo *h, struct sock *sk) + else + hlist_add_head_rcu(&inet_csk(sk)->icsk_listen_portaddr_node, + &ilb2->head); +- ilb2->count++; + spin_unlock(&ilb2->lock); + } + +@@ -225,7 +224,6 @@ static void inet_unhash2(struct inet_hashinfo *h, struct sock *sk) + + spin_lock(&ilb2->lock); + hlist_del_init_rcu(&inet_csk(sk)->icsk_listen_portaddr_node); +- ilb2->count--; + spin_unlock(&ilb2->lock); + } + +@@ -652,7 +650,6 @@ int __inet_hash(struct sock *sk, struct sock *osk) + else + __sk_nulls_add_node_rcu(sk, &ilb->nulls_head); + inet_hash2(hashinfo, sk); +- ilb->count++; + sock_set_flag(sk, SOCK_RCU_FREE); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + unlock: +@@ -684,7 +681,6 @@ static void __inet_unhash(struct sock *sk, struct inet_listen_hashbucket *ilb) + struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; + + inet_unhash2(hashinfo, sk); +- ilb->count--; + } + __sk_nulls_del_node_init_rcu(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); +@@ -867,7 +863,6 @@ void inet_hashinfo_init(struct inet_hashinfo *h) + spin_lock_init(&h->listening_hash[i].lock); + INIT_HLIST_NULLS_HEAD(&h->listening_hash[i].nulls_head, + i + LISTENING_NULLS_BASE); +- h->listening_hash[i].count = 0; + } + + h->lhash2 = NULL; +@@ -881,7 +876,6 @@ static void init_hashinfo_lhash2(struct inet_hashinfo *h) + for (i = 0; i <= h->lhash2_mask; i++) { + spin_lock_init(&h->lhash2[i].lock); + INIT_HLIST_HEAD(&h->lhash2[i].head); +- h->lhash2[i].count = 0; + } + } + +-- +2.42.0 + diff --git a/queue-5.15/net-inet-retire-port-only-listening_hash.patch b/queue-5.15/net-inet-retire-port-only-listening_hash.patch new file mode 100644 index 00000000000..85204315710 --- /dev/null +++ b/queue-5.15/net-inet-retire-port-only-listening_hash.patch @@ -0,0 +1,447 @@ +From 411413b8bd18624bd6f77d5258b4fb4537f70a91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 May 2022 17:06:05 -0700 +Subject: net: inet: Retire port only listening_hash + +From: Martin KaFai Lau + +[ Upstream commit cae3873c5b3a4fcd9706fb461ff4e91bdf1f0120 ] + +The listen sk is currently stored in two hash tables, +listening_hash (hashed by port) and lhash2 (hashed by port and address). + +After commit 0ee58dad5b06 ("net: tcp6: prefer listeners bound to an address") +and commit d9fbc7f6431f ("net: tcp: prefer listeners bound to an address"), +the TCP-SYN lookup fast path does not use listening_hash. + +The commit 05c0b35709c5 ("tcp: seq_file: Replace listening_hash with lhash2") +also moved the seq_file (/proc/net/tcp) iteration usage from +listening_hash to lhash2. + +There are still a few listening_hash usages left. +One of them is inet_reuseport_add_sock() which uses the listening_hash +to search a listen sk during the listen() system call. This turns +out to be very slow on use cases that listen on many different +VIPs at a popular port (e.g. 443). [ On top of the slowness in +adding to the tail in the IPv6 case ]. The latter patch has a +selftest to demonstrate this case. + +This patch takes this chance to move all remaining listening_hash +usages to lhash2 and then retire listening_hash. + +Since most changes need to be done together, it is hard to cut +the listening_hash to lhash2 switch into small patches. The +changes in this patch is highlighted here for the review +purpose. + +1. Because of the listening_hash removal, lhash2 can use the + sk->sk_nulls_node instead of the icsk->icsk_listen_portaddr_node. + This will also keep the sk_unhashed() check to work as is + after stop adding sk to listening_hash. + + The union is removed from inet_listen_hashbucket because + only nulls_head is needed. + +2. icsk->icsk_listen_portaddr_node and its helpers are removed. + +3. The current lhash2 users needs to iterate with sk_nulls_node + instead of icsk_listen_portaddr_node. + + One case is in the inet[6]_lhash2_lookup(). + + Another case is the seq_file iterator in tcp_ipv4.c. + One thing to note is sk_nulls_next() is needed + because the old inet_lhash2_for_each_icsk_continue() + does a "next" first before iterating. + +4. Move the remaining listening_hash usage to lhash2 + + inet_reuseport_add_sock() which this series is + trying to improve. + + inet_diag.c and mptcp_diag.c are the final two + remaining use cases and is moved to lhash2 now also. + +Signed-off-by: Martin KaFai Lau +Reviewed-by: Eric Dumazet +Signed-off-by: Jakub Kicinski +Stable-dep-of: 871019b22d1b ("net: set SOCK_RCU_FREE before inserting socket into hashtable") +Signed-off-by: Sasha Levin +--- + include/net/inet_connection_sock.h | 2 -- + include/net/inet_hashtables.h | 41 +------------------------- + net/dccp/proto.c | 1 - + net/ipv4/inet_diag.c | 5 ++-- + net/ipv4/inet_hashtables.c | 47 ++++++------------------------ + net/ipv4/tcp.c | 1 - + net/ipv4/tcp_ipv4.c | 21 ++++++------- + net/ipv6/inet6_hashtables.c | 5 ++-- + net/mptcp/mptcp_diag.c | 4 +-- + 9 files changed, 26 insertions(+), 101 deletions(-) + +diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h +index 695ed45841f06..d31a18824cd5c 100644 +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -66,7 +66,6 @@ struct inet_connection_sock_af_ops { + * @icsk_ulp_ops Pluggable ULP control hook + * @icsk_ulp_data ULP private data + * @icsk_clean_acked Clean acked data hook +- * @icsk_listen_portaddr_node hash to the portaddr listener hashtable + * @icsk_ca_state: Congestion control state + * @icsk_retransmits: Number of unrecovered [RTO] timeouts + * @icsk_pending: Scheduled timer event +@@ -96,7 +95,6 @@ struct inet_connection_sock { + const struct tcp_ulp_ops *icsk_ulp_ops; + void __rcu *icsk_ulp_data; + void (*icsk_clean_acked)(struct sock *sk, u32 acked_seq); +- struct hlist_node icsk_listen_portaddr_node; + unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu); + __u8 icsk_ca_state:5, + icsk_ca_initialized:1, +diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h +index 405670d7661da..a7a8e66a1bad0 100644 +--- a/include/net/inet_hashtables.h ++++ b/include/net/inet_hashtables.h +@@ -111,10 +111,7 @@ struct inet_bind_hashbucket { + #define LISTENING_NULLS_BASE (1U << 29) + struct inet_listen_hashbucket { + spinlock_t lock; +- union { +- struct hlist_head head; +- struct hlist_nulls_head nulls_head; +- }; ++ struct hlist_nulls_head nulls_head; + }; + + /* This is for listening sockets, thus all sockets which possess wildcards. */ +@@ -142,32 +139,8 @@ struct inet_hashinfo { + /* The 2nd listener table hashed by local port and address */ + unsigned int lhash2_mask; + struct inet_listen_hashbucket *lhash2; +- +- /* All the above members are written once at bootup and +- * never written again _or_ are predominantly read-access. +- * +- * Now align to a new cache line as all the following members +- * might be often dirty. +- */ +- /* All sockets in TCP_LISTEN state will be in listening_hash. +- * This is the only table where wildcard'd TCP sockets can +- * exist. listening_hash is only hashed by local port number. +- * If lhash2 is initialized, the same socket will also be hashed +- * to lhash2 by port and address. +- */ +- struct inet_listen_hashbucket listening_hash[INET_LHTABLE_SIZE] +- ____cacheline_aligned_in_smp; + }; + +-#define inet_lhash2_for_each_icsk_continue(__icsk) \ +- hlist_for_each_entry_continue(__icsk, icsk_listen_portaddr_node) +- +-#define inet_lhash2_for_each_icsk(__icsk, list) \ +- hlist_for_each_entry(__icsk, list, icsk_listen_portaddr_node) +- +-#define inet_lhash2_for_each_icsk_rcu(__icsk, list) \ +- hlist_for_each_entry_rcu(__icsk, list, icsk_listen_portaddr_node) +- + static inline struct inet_listen_hashbucket * + inet_lhash2_bucket(struct inet_hashinfo *h, u32 hash) + { +@@ -218,23 +191,11 @@ static inline u32 inet_bhashfn(const struct net *net, const __u16 lport, + void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, + const unsigned short snum); + +-/* These can have wildcards, don't try too hard. */ +-static inline u32 inet_lhashfn(const struct net *net, const unsigned short num) +-{ +- return (num + net_hash_mix(net)) & (INET_LHTABLE_SIZE - 1); +-} +- +-static inline int inet_sk_listen_hashfn(const struct sock *sk) +-{ +- return inet_lhashfn(sock_net(sk), inet_sk(sk)->inet_num); +-} +- + /* Caller must disable local BH processing. */ + int __inet_inherit_port(const struct sock *sk, struct sock *child); + + void inet_put_port(struct sock *sk); + +-void inet_hashinfo_init(struct inet_hashinfo *h); + void inet_hashinfo2_init(struct inet_hashinfo *h, const char *name, + unsigned long numentries, int scale, + unsigned long low_limit, +diff --git a/net/dccp/proto.c b/net/dccp/proto.c +index 0b0567a692a8f..1b285a57c7aab 100644 +--- a/net/dccp/proto.c ++++ b/net/dccp/proto.c +@@ -1131,7 +1131,6 @@ static int __init dccp_init(void) + + BUILD_BUG_ON(sizeof(struct dccp_skb_cb) > + sizeof_field(struct sk_buff, cb)); +- inet_hashinfo_init(&dccp_hashinfo); + rc = inet_hashinfo2_init_mod(&dccp_hashinfo); + if (rc) + goto out_fail; +diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c +index ae70e07c52445..09cabed358fd0 100644 +--- a/net/ipv4/inet_diag.c ++++ b/net/ipv4/inet_diag.c +@@ -1028,12 +1028,13 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, + if (!(idiag_states & TCPF_LISTEN) || r->id.idiag_dport) + goto skip_listen_ht; + +- for (i = s_i; i < INET_LHTABLE_SIZE; i++) { ++ for (i = s_i; i <= hashinfo->lhash2_mask; i++) { + struct inet_listen_hashbucket *ilb; + struct hlist_nulls_node *node; + + num = 0; +- ilb = &hashinfo->listening_hash[i]; ++ ilb = &hashinfo->lhash2[i]; ++ + spin_lock(&ilb->lock); + sk_nulls_for_each(sk, node, &ilb->nulls_head) { + struct inet_sock *inet = inet_sk(sk); +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 637d806090b00..a673f4ec1b429 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -246,12 +246,11 @@ static struct sock *inet_lhash2_lookup(struct net *net, + const __be32 daddr, const unsigned short hnum, + const int dif, const int sdif) + { +- struct inet_connection_sock *icsk; + struct sock *sk, *result = NULL; ++ struct hlist_nulls_node *node; + int score, hiscore = 0; + +- inet_lhash2_for_each_icsk_rcu(icsk, &ilb2->head) { +- sk = (struct sock *)icsk; ++ sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) { + score = compute_score(sk, net, hnum, daddr, dif, sdif); + if (score > hiscore) { + result = lookup_reuseport(net, sk, skb, doff, +@@ -593,7 +592,6 @@ int __inet_hash(struct sock *sk, struct sock *osk) + { + struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; + struct inet_listen_hashbucket *ilb2; +- struct inet_listen_hashbucket *ilb; + int err = 0; + + if (sk->sk_state != TCP_LISTEN) { +@@ -603,31 +601,23 @@ int __inet_hash(struct sock *sk, struct sock *osk) + return 0; + } + WARN_ON(!sk_unhashed(sk)); +- ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; + ilb2 = inet_lhash2_bucket_sk(hashinfo, sk); + +- spin_lock(&ilb->lock); + spin_lock(&ilb2->lock); + if (sk->sk_reuseport) { +- err = inet_reuseport_add_sock(sk, ilb); ++ err = inet_reuseport_add_sock(sk, ilb2); + if (err) + goto unlock; + } + if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && +- sk->sk_family == AF_INET6) { +- hlist_add_tail_rcu(&inet_csk(sk)->icsk_listen_portaddr_node, +- &ilb2->head); +- __sk_nulls_add_node_tail_rcu(sk, &ilb->nulls_head); +- } else { +- hlist_add_head_rcu(&inet_csk(sk)->icsk_listen_portaddr_node, +- &ilb2->head); +- __sk_nulls_add_node_rcu(sk, &ilb->nulls_head); +- } ++ sk->sk_family == AF_INET6) ++ __sk_nulls_add_node_tail_rcu(sk, &ilb2->nulls_head); ++ else ++ __sk_nulls_add_node_rcu(sk, &ilb2->nulls_head); + sock_set_flag(sk, SOCK_RCU_FREE); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + unlock: + spin_unlock(&ilb2->lock); +- spin_unlock(&ilb->lock); + + return err; + } +@@ -653,29 +643,23 @@ void inet_unhash(struct sock *sk) + + if (sk->sk_state == TCP_LISTEN) { + struct inet_listen_hashbucket *ilb2; +- struct inet_listen_hashbucket *ilb; + +- ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; + ilb2 = inet_lhash2_bucket_sk(hashinfo, sk); + /* Don't disable bottom halves while acquiring the lock to + * avoid circular locking dependency on PREEMPT_RT. + */ +- spin_lock(&ilb->lock); + spin_lock(&ilb2->lock); + if (sk_unhashed(sk)) { + spin_unlock(&ilb2->lock); +- spin_unlock(&ilb->lock); + return; + } + + if (rcu_access_pointer(sk->sk_reuseport_cb)) + reuseport_stop_listen_sock(sk); + +- hlist_del_init_rcu(&inet_csk(sk)->icsk_listen_portaddr_node); + __sk_nulls_del_node_init_rcu(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + spin_unlock(&ilb2->lock); +- spin_unlock(&ilb->lock); + } else { + spinlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash); + +@@ -833,27 +817,14 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row, + } + EXPORT_SYMBOL_GPL(inet_hash_connect); + +-void inet_hashinfo_init(struct inet_hashinfo *h) +-{ +- int i; +- +- for (i = 0; i < INET_LHTABLE_SIZE; i++) { +- spin_lock_init(&h->listening_hash[i].lock); +- INIT_HLIST_NULLS_HEAD(&h->listening_hash[i].nulls_head, +- i + LISTENING_NULLS_BASE); +- } +- +- h->lhash2 = NULL; +-} +-EXPORT_SYMBOL_GPL(inet_hashinfo_init); +- + static void init_hashinfo_lhash2(struct inet_hashinfo *h) + { + int i; + + for (i = 0; i <= h->lhash2_mask; i++) { + spin_lock_init(&h->lhash2[i].lock); +- INIT_HLIST_HEAD(&h->lhash2[i].head); ++ INIT_HLIST_NULLS_HEAD(&h->lhash2[i].nulls_head, ++ i + LISTENING_NULLS_BASE); + } + } + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 6dcb77a2bde60..86dff7abdfd69 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -4554,7 +4554,6 @@ void __init tcp_init(void) + timer_setup(&tcp_orphan_timer, tcp_orphan_update, TIMER_DEFERRABLE); + mod_timer(&tcp_orphan_timer, jiffies + TCP_ORPHAN_TIMER_PERIOD); + +- inet_hashinfo_init(&tcp_hashinfo); + inet_hashinfo2_init(&tcp_hashinfo, "tcp_listen_portaddr_hash", + thash_entries, 21, /* one slot per 2 MB*/ + 0, 64 * 1024); +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index f89cb184649ec..0666be6b9ec93 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -2343,16 +2343,15 @@ static void *listening_get_first(struct seq_file *seq) + st->offset = 0; + for (; st->bucket <= tcp_hashinfo.lhash2_mask; st->bucket++) { + struct inet_listen_hashbucket *ilb2; +- struct inet_connection_sock *icsk; ++ struct hlist_nulls_node *node; + struct sock *sk; + + ilb2 = &tcp_hashinfo.lhash2[st->bucket]; +- if (hlist_empty(&ilb2->head)) ++ if (hlist_nulls_empty(&ilb2->nulls_head)) + continue; + + spin_lock(&ilb2->lock); +- inet_lhash2_for_each_icsk(icsk, &ilb2->head) { +- sk = (struct sock *)icsk; ++ sk_nulls_for_each(sk, node, &ilb2->nulls_head) { + if (seq_sk_match(seq, sk)) + return sk; + } +@@ -2371,15 +2370,14 @@ static void *listening_get_next(struct seq_file *seq, void *cur) + { + struct tcp_iter_state *st = seq->private; + struct inet_listen_hashbucket *ilb2; +- struct inet_connection_sock *icsk; ++ struct hlist_nulls_node *node; + struct sock *sk = cur; + + ++st->num; + ++st->offset; + +- icsk = inet_csk(sk); +- inet_lhash2_for_each_icsk_continue(icsk) { +- sk = (struct sock *)icsk; ++ sk = sk_nulls_next(sk); ++ sk_nulls_for_each_from(sk, node) { + if (seq_sk_match(seq, sk)) + return sk; + } +@@ -2788,16 +2786,15 @@ static unsigned int bpf_iter_tcp_listening_batch(struct seq_file *seq, + { + struct bpf_tcp_iter_state *iter = seq->private; + struct tcp_iter_state *st = &iter->state; +- struct inet_connection_sock *icsk; ++ struct hlist_nulls_node *node; + unsigned int expected = 1; + struct sock *sk; + + sock_hold(start_sk); + iter->batch[iter->end_sk++] = start_sk; + +- icsk = inet_csk(start_sk); +- inet_lhash2_for_each_icsk_continue(icsk) { +- sk = (struct sock *)icsk; ++ sk = sk_nulls_next(start_sk); ++ sk_nulls_for_each_from(sk, node) { + if (seq_sk_match(seq, sk)) { + if (iter->end_sk < iter->max_sk) { + sock_hold(sk); +diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c +index b4a5e01e12016..c40cbdfc6247f 100644 +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -138,12 +138,11 @@ static struct sock *inet6_lhash2_lookup(struct net *net, + const __be16 sport, const struct in6_addr *daddr, + const unsigned short hnum, const int dif, const int sdif) + { +- struct inet_connection_sock *icsk; + struct sock *sk, *result = NULL; ++ struct hlist_nulls_node *node; + int score, hiscore = 0; + +- inet_lhash2_for_each_icsk_rcu(icsk, &ilb2->head) { +- sk = (struct sock *)icsk; ++ sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) { + score = compute_score(sk, net, hnum, daddr, dif, sdif); + if (score > hiscore) { + result = lookup_reuseport(net, sk, skb, doff, +diff --git a/net/mptcp/mptcp_diag.c b/net/mptcp/mptcp_diag.c +index 4d8625d0b179a..520ee65850553 100644 +--- a/net/mptcp/mptcp_diag.c ++++ b/net/mptcp/mptcp_diag.c +@@ -83,13 +83,13 @@ static void mptcp_diag_dump_listeners(struct sk_buff *skb, struct netlink_callba + struct net *net = sock_net(skb->sk); + int i; + +- for (i = diag_ctx->l_slot; i < INET_LHTABLE_SIZE; i++) { ++ for (i = diag_ctx->l_slot; i <= tcp_hashinfo.lhash2_mask; i++) { + struct inet_listen_hashbucket *ilb; + struct hlist_nulls_node *node; + struct sock *sk; + int num = 0; + +- ilb = &tcp_hashinfo.listening_hash[i]; ++ ilb = &tcp_hashinfo.lhash2[i]; + + rcu_read_lock(); + spin_lock(&ilb->lock); +-- +2.42.0 + diff --git a/queue-5.15/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch b/queue-5.15/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch new file mode 100644 index 00000000000..f56f80598b5 --- /dev/null +++ b/queue-5.15/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch @@ -0,0 +1,74 @@ +From 97d4e533faa4b7fc48264e336aa4e62571966818 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:46 -0800 +Subject: net/mlx5e: Check return value of snprintf writing to fw_version + buffer for representors + +From: Rahul Rameshbabu + +[ Upstream commit 1b2bd0c0264febcd8d47209079a6671c38e6558b ] + +Treat the operation as an error case when the return value is equivalent to +the size of the name buffer. Failed to write null terminator to the name +buffer, making the string malformed and should not be used. Provide a +string with only the firmware version when forming the string with the +board id fails. This logic for representors is identical to normal flow +with ethtool. + +Without check, will trigger -Wformat-truncation with W=1. + + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c: In function 'mlx5e_rep_get_drvinfo': + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c:78:31: warning: '%.16s' directive output may be truncated writing up to 16 bytes into a region of size between 13 and 22 [-Wformat-truncation=] + 78 | "%d.%d.%04d (%.16s)", + | ^~~~~ + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c:77:9: note: 'snprintf' output between 12 and 37 bytes into a destination of size 32 + 77 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 78 | "%d.%d.%04d (%.16s)", + | ~~~~~~~~~~~~~~~~~~~~~ + 79 | fw_rev_maj(mdev), fw_rev_min(mdev), + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 80 | fw_rev_sub(mdev), mdev->board_id); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fixes: cf83c8fdcd47 ("net/mlx5e: Add missing ethtool driver info for representors") +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d4ab2e97dcfbcd748ae71761a9d8e5e41cc732c +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Dragos Tatulea +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-16-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +index 3d614bf5cff9e..7a00faa62d993 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +@@ -66,13 +66,17 @@ static void mlx5e_rep_get_drvinfo(struct net_device *dev, + { + struct mlx5e_priv *priv = netdev_priv(dev); + struct mlx5_core_dev *mdev = priv->mdev; ++ int count; + + strlcpy(drvinfo->driver, mlx5e_rep_driver_name, + sizeof(drvinfo->driver)); +- snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), +- "%d.%d.%04d (%.16s)", +- fw_rev_maj(mdev), fw_rev_min(mdev), +- fw_rev_sub(mdev), mdev->board_id); ++ count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), ++ "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), ++ fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); ++ if (count == sizeof(drvinfo->fw_version)) ++ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), ++ "%d.%d.%04d", fw_rev_maj(mdev), ++ fw_rev_min(mdev), fw_rev_sub(mdev)); + } + + static const struct counter_desc sw_rep_stats_desc[] = { +-- +2.42.0 + diff --git a/queue-5.15/net-mlx5e-fix-double-free-of-encap_header-in-update-.patch b/queue-5.15/net-mlx5e-fix-double-free-of-encap_header-in-update-.patch new file mode 100644 index 00000000000..b4a5efe00b8 --- /dev/null +++ b/queue-5.15/net-mlx5e-fix-double-free-of-encap_header-in-update-.patch @@ -0,0 +1,102 @@ +From 4b7dc94ac23b8a3e9778986707e2ccb250e66855 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:37 -0800 +Subject: net/mlx5e: fix double free of encap_header in update funcs + +From: Gavin Li + +[ Upstream commit 3a4aa3cb83563df942be49d145ee3b7ddf17d6bb ] + +Follow up to the previous patch to fix the same issue for +mlx5e_tc_tun_update_header_ipv4{6} when mlx5_packet_reformat_alloc() +fails. + +When mlx5_packet_reformat_alloc() fails, the encap_header allocated in +mlx5e_tc_tun_update_header_ipv4{6} will be released within it. However, +e->encap_header is already set to the previously freed encap_header +before mlx5_packet_reformat_alloc(). As a result, the later +mlx5e_encap_put() will free e->encap_header again, causing a double free +issue. + +mlx5e_encap_put() + --> mlx5e_encap_dealloc() + --> kfree(e->encap_header) + +This patch fix it by not setting e->encap_header until +mlx5_packet_reformat_alloc() success. + +Fixes: a54e20b4fcae ("net/mlx5e: Add basic TC tunnel set action for SRIOV offloads") +Signed-off-by: Gavin Li +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-7-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/mellanox/mlx5/core/en/tc_tun.c | 20 +++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +index 44071592bd6e2..303e6e7a5c448 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +@@ -397,16 +397,12 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, + if (err) + goto free_encap; + +- e->encap_size = ipv4_encap_size; +- kfree(e->encap_header); +- e->encap_header = encap_header; +- + if (!(nud_state & NUD_VALID)) { + neigh_event_send(attr.n, NULL); + /* the encap entry will be made valid on neigh update event + * and not used before that. + */ +- goto release_neigh; ++ goto free_encap; + } + + memset(&reformat_params, 0, sizeof(reformat_params)); +@@ -420,6 +416,10 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, + goto free_encap; + } + ++ e->encap_size = ipv4_encap_size; ++ kfree(e->encap_header); ++ e->encap_header = encap_header; ++ + e->flags |= MLX5_ENCAP_ENTRY_VALID; + mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); + mlx5e_route_lookup_ipv4_put(&attr); +@@ -660,16 +660,12 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, + if (err) + goto free_encap; + +- e->encap_size = ipv6_encap_size; +- kfree(e->encap_header); +- e->encap_header = encap_header; +- + if (!(nud_state & NUD_VALID)) { + neigh_event_send(attr.n, NULL); + /* the encap entry will be made valid on neigh update event + * and not used before that. + */ +- goto release_neigh; ++ goto free_encap; + } + + memset(&reformat_params, 0, sizeof(reformat_params)); +@@ -683,6 +679,10 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, + goto free_encap; + } + ++ e->encap_size = ipv6_encap_size; ++ kfree(e->encap_header); ++ e->encap_header = encap_header; ++ + e->flags |= MLX5_ENCAP_ENTRY_VALID; + mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); + mlx5e_route_lookup_ipv6_put(&attr); +-- +2.42.0 + diff --git a/queue-5.15/net-mlx5e-fix-double-free-of-encap_header.patch b/queue-5.15/net-mlx5e-fix-double-free-of-encap_header.patch new file mode 100644 index 00000000000..651b1d068a1 --- /dev/null +++ b/queue-5.15/net-mlx5e-fix-double-free-of-encap_header.patch @@ -0,0 +1,82 @@ +From 9ca4efe8edbb3655282eaa6a6278f6a723828257 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:36 -0800 +Subject: net/mlx5e: fix double free of encap_header + +From: Dust Li + +[ Upstream commit 6f9b1a0731662648949a1c0587f6acb3b7f8acf1 ] + +When mlx5_packet_reformat_alloc() fails, the encap_header allocated in +mlx5e_tc_tun_create_header_ipv4{6} will be released within it. However, +e->encap_header is already set to the previously freed encap_header +before mlx5_packet_reformat_alloc(). As a result, the later +mlx5e_encap_put() will free e->encap_header again, causing a double free +issue. + +mlx5e_encap_put() + --> mlx5e_encap_dealloc() + --> kfree(e->encap_header) + +This happens when cmd: MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT fail. + +This patch fix it by not setting e->encap_header until +mlx5_packet_reformat_alloc() success. + +Fixes: d589e785baf5e ("net/mlx5e: Allow concurrent creation of encap entries") +Reported-by: Cruz Zhao +Reported-by: Tianchen Ding +Signed-off-by: Dust Li +Reviewed-by: Wojciech Drewek +Signed-off-by: Saeed Mahameed +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +index d90c6dc41c9f4..44071592bd6e2 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +@@ -294,9 +294,6 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, + if (err) + goto destroy_neigh_entry; + +- e->encap_size = ipv4_encap_size; +- e->encap_header = encap_header; +- + if (!(nud_state & NUD_VALID)) { + neigh_event_send(attr.n, NULL); + /* the encap entry will be made valid on neigh update event +@@ -316,6 +313,8 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, + goto destroy_neigh_entry; + } + ++ e->encap_size = ipv4_encap_size; ++ e->encap_header = encap_header; + e->flags |= MLX5_ENCAP_ENTRY_VALID; + mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); + mlx5e_route_lookup_ipv4_put(&attr); +@@ -559,9 +558,6 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, + if (err) + goto destroy_neigh_entry; + +- e->encap_size = ipv6_encap_size; +- e->encap_header = encap_header; +- + if (!(nud_state & NUD_VALID)) { + neigh_event_send(attr.n, NULL); + /* the encap entry will be made valid on neigh update event +@@ -581,6 +577,8 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, + goto destroy_neigh_entry; + } + ++ e->encap_size = ipv6_encap_size; ++ e->encap_header = encap_header; + e->flags |= MLX5_ENCAP_ENTRY_VALID; + mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); + mlx5e_route_lookup_ipv6_put(&attr); +-- +2.42.0 + diff --git a/queue-5.15/net-mlx5e-fix-pedit-endianness.patch b/queue-5.15/net-mlx5e-fix-pedit-endianness.patch new file mode 100644 index 00000000000..ae1875014dd --- /dev/null +++ b/queue-5.15/net-mlx5e-fix-pedit-endianness.patch @@ -0,0 +1,174 @@ +From fb1525a352853f1a8219b21f92daa0cf350006d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:38 -0800 +Subject: net/mlx5e: Fix pedit endianness + +From: Vlad Buslov + +[ Upstream commit 0c101a23ca7eaf00eef1328eefb04b3a93401cc8 ] + +Referenced commit addressed endianness issue in mlx5 pedit implementation +in ad hoc manner instead of systematically treating integer values +according to their types which left pedit fields of sizes not equal to 4 +and where the bytes being modified are not least significant ones broken on +big endian machines since wrong bits will be consumed during parsing which +leads to following example error when applying pedit to source and +destination MAC addresses: + +[Wed Oct 18 12:52:42 2023] mlx5_core 0001:00:00.1 p1v3_r: attempt to offload an unsupported field (cmd 0) +[Wed Oct 18 12:52:42 2023] mask: 00000000330c5b68: 00 00 00 00 ff ff 00 00 00 00 ff ff 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 0000000017d22fd9: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 000000008186d717: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 0000000029eb6149: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 000000007ed103e4: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 00000000db8101a6: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 00000000ec3c08a9: 00 00 00 00 00 00 00 00 00 00 00 00 ............ + +Treat masks and values of pedit and filter match as network byte order, +refactor pointers to them to void pointers instead of confusing u32 +pointers and only cast to pointer-to-integer when reading a value from +them. Treat pedit mlx5_fields->field_mask as host byte order according to +its type u32, change the constants in fields array accordingly. + +Fixes: 82198d8bcdef ("net/mlx5e: Fix endianness when calculating pedit mask first bit") +Signed-off-by: Vlad Buslov +Reviewed-by: Gal Pressman +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-8-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en_tc.c | 60 ++++++++++--------- + 1 file changed, 32 insertions(+), 28 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 39fa0fa21e33c..78538a15c097a 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -2764,7 +2764,7 @@ static struct mlx5_fields fields[] = { + OFFLOAD(DIPV6_31_0, 32, U32_MAX, ip6.daddr.s6_addr32[3], 0, + dst_ipv4_dst_ipv6.ipv6_layout.ipv6[12]), + OFFLOAD(IPV6_HOPLIMIT, 8, U8_MAX, ip6.hop_limit, 0, ttl_hoplimit), +- OFFLOAD(IP_DSCP, 16, 0xc00f, ip6, 0, ip_dscp), ++ OFFLOAD(IP_DSCP, 16, 0x0fc0, ip6, 0, ip_dscp), + + OFFLOAD(TCP_SPORT, 16, U16_MAX, tcp.source, 0, tcp_sport), + OFFLOAD(TCP_DPORT, 16, U16_MAX, tcp.dest, 0, tcp_dport), +@@ -2775,21 +2775,31 @@ static struct mlx5_fields fields[] = { + OFFLOAD(UDP_DPORT, 16, U16_MAX, udp.dest, 0, udp_dport), + }; + +-static unsigned long mask_to_le(unsigned long mask, int size) ++static u32 mask_field_get(void *mask, struct mlx5_fields *f) + { +- __be32 mask_be32; +- __be16 mask_be16; +- +- if (size == 32) { +- mask_be32 = (__force __be32)(mask); +- mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); +- } else if (size == 16) { +- mask_be32 = (__force __be32)(mask); +- mask_be16 = *(__be16 *)&mask_be32; +- mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16)); ++ switch (f->field_bsize) { ++ case 32: ++ return be32_to_cpu(*(__be32 *)mask) & f->field_mask; ++ case 16: ++ return be16_to_cpu(*(__be16 *)mask) & (u16)f->field_mask; ++ default: ++ return *(u8 *)mask & (u8)f->field_mask; + } ++} + +- return mask; ++static void mask_field_clear(void *mask, struct mlx5_fields *f) ++{ ++ switch (f->field_bsize) { ++ case 32: ++ *(__be32 *)mask &= ~cpu_to_be32(f->field_mask); ++ break; ++ case 16: ++ *(__be16 *)mask &= ~cpu_to_be16((u16)f->field_mask); ++ break; ++ default: ++ *(u8 *)mask &= ~(u8)f->field_mask; ++ break; ++ } + } + static int offload_pedit_fields(struct mlx5e_priv *priv, + int namespace, +@@ -2800,11 +2810,12 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + { + struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals; + void *headers_c, *headers_v, *action, *vals_p; +- u32 *s_masks_p, *a_masks_p, s_mask, a_mask; + struct mlx5e_tc_mod_hdr_acts *mod_acts; +- unsigned long mask, field_mask; ++ void *s_masks_p, *a_masks_p; + int i, first, last, next_z; + struct mlx5_fields *f; ++ unsigned long mask; ++ u32 s_mask, a_mask; + u8 cmd; + + mod_acts = &parse_attr->mod_hdr_acts; +@@ -2820,15 +2831,11 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + bool skip; + + f = &fields[i]; +- /* avoid seeing bits set from previous iterations */ +- s_mask = 0; +- a_mask = 0; +- + s_masks_p = (void *)set_masks + f->offset; + a_masks_p = (void *)add_masks + f->offset; + +- s_mask = *s_masks_p & f->field_mask; +- a_mask = *a_masks_p & f->field_mask; ++ s_mask = mask_field_get(s_masks_p, f); ++ a_mask = mask_field_get(a_masks_p, f); + + if (!s_mask && !a_mask) /* nothing to offload here */ + continue; +@@ -2855,22 +2862,20 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + match_mask, f->field_bsize)) + skip = true; + /* clear to denote we consumed this field */ +- *s_masks_p &= ~f->field_mask; ++ mask_field_clear(s_masks_p, f); + } else { + cmd = MLX5_ACTION_TYPE_ADD; + mask = a_mask; + vals_p = (void *)add_vals + f->offset; + /* add 0 is no change */ +- if ((*(u32 *)vals_p & f->field_mask) == 0) ++ if (!mask_field_get(vals_p, f)) + skip = true; + /* clear to denote we consumed this field */ +- *a_masks_p &= ~f->field_mask; ++ mask_field_clear(a_masks_p, f); + } + if (skip) + continue; + +- mask = mask_to_le(mask, f->field_bsize); +- + first = find_first_bit(&mask, f->field_bsize); + next_z = find_next_zero_bit(&mask, f->field_bsize, first); + last = find_last_bit(&mask, f->field_bsize); +@@ -2897,10 +2902,9 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + MLX5_SET(set_action_in, action, field, f->field); + + if (cmd == MLX5_ACTION_TYPE_SET) { ++ unsigned long field_mask = f->field_mask; + int start; + +- field_mask = mask_to_le(f->field_mask, f->field_bsize); +- + /* if field is bit sized it can start not from first bit */ + start = find_first_bit(&field_mask, f->field_bsize); + +-- +2.42.0 + diff --git a/queue-5.15/net-mlx5e-move-mod-hdr-allocation-to-a-single-place.patch b/queue-5.15/net-mlx5e-move-mod-hdr-allocation-to-a-single-place.patch new file mode 100644 index 00000000000..669fc22f97a --- /dev/null +++ b/queue-5.15/net-mlx5e-move-mod-hdr-allocation-to-a-single-place.patch @@ -0,0 +1,147 @@ +From 70ea1ca2e02513f11840b6d719357f00f70341ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Aug 2021 15:46:34 +0300 +Subject: net/mlx5e: Move mod hdr allocation to a single place + +From: Roi Dayan + +[ Upstream commit d9581e2fa73fadba187b2e62e05306e24e8a1ded ] + +Move mod hdr allocation chunk from parse_tc_fdb_actions() and +parse_tc_nic_actions() to a shared function. + +Signed-off-by: Roi Dayan +Reviewed-by: Maor Dickman +Reviewed-by: Oz Shlomo +Signed-off-by: Saeed Mahameed +Stable-dep-of: 0c101a23ca7e ("net/mlx5e: Fix pedit endianness") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en_tc.c | 87 +++++++++++-------- + 1 file changed, 51 insertions(+), 36 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index d13ffba138934..433602f871bd4 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -3502,10 +3502,50 @@ static int validate_goto_chain(struct mlx5e_priv *priv, + return 0; + } + +-static int parse_tc_nic_actions(struct mlx5e_priv *priv, +- struct flow_action *flow_action, ++static int ++actions_prepare_mod_hdr_actions(struct mlx5e_priv *priv, + struct mlx5e_tc_flow *flow, ++ struct mlx5_flow_attr *attr, ++ struct pedit_headers_action *hdrs, + struct netlink_ext_ack *extack) ++{ ++ struct mlx5e_tc_flow_parse_attr *parse_attr = attr->parse_attr; ++ enum mlx5_flow_namespace_type ns_type; ++ int err; ++ ++ if (!hdrs[TCA_PEDIT_KEY_EX_CMD_SET].pedits && ++ !hdrs[TCA_PEDIT_KEY_EX_CMD_ADD].pedits) ++ return 0; ++ ++ ns_type = get_flow_name_space(flow); ++ ++ err = alloc_tc_pedit_action(priv, ns_type, parse_attr, hdrs, ++ &attr->action, extack); ++ if (err) ++ return err; ++ ++ /* In case all pedit actions are skipped, remove the MOD_HDR flag. */ ++ if (parse_attr->mod_hdr_acts.num_actions > 0) ++ return 0; ++ ++ attr->action &= ~MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; ++ dealloc_mod_hdr_actions(&parse_attr->mod_hdr_acts); ++ ++ if (ns_type != MLX5_FLOW_NAMESPACE_FDB) ++ return 0; ++ ++ if (!((attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_POP) || ++ (attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH))) ++ attr->esw_attr->split_count = 0; ++ ++ return 0; ++} ++ ++static int ++parse_tc_nic_actions(struct mlx5e_priv *priv, ++ struct flow_action *flow_action, ++ struct mlx5e_tc_flow *flow, ++ struct netlink_ext_ack *extack) + { + struct mlx5e_tc_flow_parse_attr *parse_attr; + struct mlx5_flow_attr *attr = flow->attr; +@@ -3617,21 +3657,6 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, + } + } + +- if (hdrs[TCA_PEDIT_KEY_EX_CMD_SET].pedits || +- hdrs[TCA_PEDIT_KEY_EX_CMD_ADD].pedits) { +- err = alloc_tc_pedit_action(priv, MLX5_FLOW_NAMESPACE_KERNEL, +- parse_attr, hdrs, &action, extack); +- if (err) +- return err; +- /* in case all pedit actions are skipped, remove the MOD_HDR +- * flag. +- */ +- if (parse_attr->mod_hdr_acts.num_actions == 0) { +- action &= ~MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; +- dealloc_mod_hdr_actions(&parse_attr->mod_hdr_acts); +- } +- } +- + attr->action = action; + + if (attr->dest_chain && parse_attr->mirred_ifindex[0]) { +@@ -3639,6 +3664,10 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, + return -EOPNOTSUPP; + } + ++ err = actions_prepare_mod_hdr_actions(priv, flow, attr, hdrs, extack); ++ if (err) ++ return err; ++ + if (!actions_match_supported(priv, flow_action, parse_attr, flow, extack)) + return -EOPNOTSUPP; + +@@ -4192,26 +4221,12 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, + return err; + } + +- if (hdrs[TCA_PEDIT_KEY_EX_CMD_SET].pedits || +- hdrs[TCA_PEDIT_KEY_EX_CMD_ADD].pedits) { +- err = alloc_tc_pedit_action(priv, MLX5_FLOW_NAMESPACE_FDB, +- parse_attr, hdrs, &action, extack); +- if (err) +- return err; +- /* in case all pedit actions are skipped, remove the MOD_HDR +- * flag. we might have set split_count either by pedit or +- * pop/push. if there is no pop/push either, reset it too. +- */ +- if (parse_attr->mod_hdr_acts.num_actions == 0) { +- action &= ~MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; +- dealloc_mod_hdr_actions(&parse_attr->mod_hdr_acts); +- if (!((action & MLX5_FLOW_CONTEXT_ACTION_VLAN_POP) || +- (action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH))) +- esw_attr->split_count = 0; +- } +- } +- + attr->action = action; ++ ++ err = actions_prepare_mod_hdr_actions(priv, flow, attr, hdrs, extack); ++ if (err) ++ return err; ++ + if (!actions_match_supported(priv, flow_action, parse_attr, flow, extack)) + return -EOPNOTSUPP; + +-- +2.42.0 + diff --git a/queue-5.15/net-mlx5e-reduce-the-size-of-icosq_str.patch b/queue-5.15/net-mlx5e-reduce-the-size-of-icosq_str.patch new file mode 100644 index 00000000000..a7a7916ddb9 --- /dev/null +++ b/queue-5.15/net-mlx5e-reduce-the-size-of-icosq_str.patch @@ -0,0 +1,73 @@ +From 88ffb99d937c75da03536c1617d6ce764813c4e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:44 -0800 +Subject: net/mlx5e: Reduce the size of icosq_str + +From: Saeed Mahameed + +[ Upstream commit dce94142842e119b982c27c1b62bd20890c7fd21 ] + +icosq_str size is unnecessarily too long, and it causes a build warning +-Wformat-truncation with W=1. Looking closely, It doesn't need to be 255B, +hence this patch reduces the size to 32B which should be more than enough +to host the string: "ICOSQ: 0x%x, ". + +While here, add a missing space in the formatted string. + +This fixes the following build warning: + +$ KCFLAGS='-Wall -Werror' +$ make O=/tmp/kbuild/linux W=1 -s -j12 drivers/net/ethernet/mellanox/mlx5/core/ + +drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c: In function 'mlx5e_reporter_rx_timeout': +drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c:718:56: +error: ', CQ: 0x' directive output may be truncated writing 8 bytes into a region of size between 0 and 255 [-Werror=format-truncation=] + 718 | "RX timeout on channel: %d, %sRQ: 0x%x, CQ: 0x%x", + | ^~~~~~~~ +drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c:717:9: note: 'snprintf' output between 43 and 322 bytes into a destination of size 288 + 717 | snprintf(err_str, sizeof(err_str), + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 718 | "RX timeout on channel: %d, %sRQ: 0x%x, CQ: 0x%x", + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 719 | rq->ix, icosq_str, rq->rqn, rq->cq.mcq.cqn); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fixes: 521f31af004a ("net/mlx5e: Allow RQ outside of channel context") +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d4ab2e97dcfbcd748ae71761a9d8e5e41cc732c +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-14-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +index 899a9a73eef68..a4c12c5bb0dc5 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +@@ -655,11 +655,11 @@ static int mlx5e_rx_reporter_dump(struct devlink_health_reporter *reporter, + + void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq) + { +- char icosq_str[MLX5E_REPORTER_PER_Q_MAX_LEN] = {}; + char err_str[MLX5E_REPORTER_PER_Q_MAX_LEN]; + struct mlx5e_icosq *icosq = rq->icosq; + struct mlx5e_priv *priv = rq->priv; + struct mlx5e_err_ctx err_ctx = {}; ++ char icosq_str[32] = {}; + + err_ctx.ctx = rq; + err_ctx.recover = mlx5e_rx_reporter_timeout_recover; +@@ -668,7 +668,7 @@ void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq) + if (icosq) + snprintf(icosq_str, sizeof(icosq_str), "ICOSQ: 0x%x, ", icosq->sqn); + snprintf(err_str, sizeof(err_str), +- "RX timeout on channel: %d, %sRQ: 0x%x, CQ: 0x%x", ++ "RX timeout on channel: %d, %s RQ: 0x%x, CQ: 0x%x", + rq->ix, icosq_str, rq->rqn, rq->cq.mcq.cqn); + + mlx5e_health_report(priv, priv->rx_reporter, err_str, &err_ctx); +-- +2.42.0 + diff --git a/queue-5.15/net-mlx5e-refactor-mod-header-management-api.patch b/queue-5.15/net-mlx5e-refactor-mod-header-management-api.patch new file mode 100644 index 00000000000..b55a101505c --- /dev/null +++ b/queue-5.15/net-mlx5e-refactor-mod-header-management-api.patch @@ -0,0 +1,467 @@ +From f9ad0114d466aafac5d6b20fec8c7f6f5cc18d9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jul 2021 11:31:47 +0300 +Subject: net/mlx5e: Refactor mod header management API + +From: Paul Blakey + +[ Upstream commit 2c0e5cf5206ecd5da3c6bc5799671c2172713d71 ] + +For all mod hdr related functions to reside in a single self contained +component (mod_hdr.c), refactor alloc() and add get_id() so that user +won't rely on internal implementation, and move both to mod_hdr +component. + +Rename the prefix to mlx5e_mod_hdr_* as other mod hdr functions. + +Signed-off-by: Paul Blakey +Reviewed-by: Oz Shlomo +Reviewed-by: Roi Dayan +Signed-off-by: Saeed Mahameed +Stable-dep-of: 0c101a23ca7e ("net/mlx5e: Fix pedit endianness") +Signed-off-by: Sasha Levin +--- + .../ethernet/mellanox/mlx5/core/en/mod_hdr.c | 47 ++++++++++ + .../ethernet/mellanox/mlx5/core/en/mod_hdr.h | 13 +++ + .../mellanox/mlx5/core/en/tc/sample.c | 5 +- + .../ethernet/mellanox/mlx5/core/en/tc_ct.c | 25 ++---- + .../net/ethernet/mellanox/mlx5/core/en_tc.c | 90 ++++--------------- + .../net/ethernet/mellanox/mlx5/core/en_tc.h | 5 -- + .../mellanox/mlx5/core/esw/indir_table.c | 5 +- + 7 files changed, 90 insertions(+), 100 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.c b/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.c +index 7edde4d536fda..19d05fb4aab2e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.c +@@ -155,3 +155,50 @@ struct mlx5_modify_hdr *mlx5e_mod_hdr_get(struct mlx5e_mod_hdr_handle *mh) + return mh->modify_hdr; + } + ++char * ++mlx5e_mod_hdr_alloc(struct mlx5_core_dev *mdev, int namespace, ++ struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts) ++{ ++ int new_num_actions, max_hw_actions; ++ size_t new_sz, old_sz; ++ void *ret; ++ ++ if (mod_hdr_acts->num_actions < mod_hdr_acts->max_actions) ++ goto out; ++ ++ max_hw_actions = mlx5e_mod_hdr_max_actions(mdev, namespace); ++ new_num_actions = min(max_hw_actions, ++ mod_hdr_acts->actions ? ++ mod_hdr_acts->max_actions * 2 : 1); ++ if (mod_hdr_acts->max_actions == new_num_actions) ++ return ERR_PTR(-ENOSPC); ++ ++ new_sz = MLX5_MH_ACT_SZ * new_num_actions; ++ old_sz = mod_hdr_acts->max_actions * MLX5_MH_ACT_SZ; ++ ++ ret = krealloc(mod_hdr_acts->actions, new_sz, GFP_KERNEL); ++ if (!ret) ++ return ERR_PTR(-ENOMEM); ++ ++ memset(ret + old_sz, 0, new_sz - old_sz); ++ mod_hdr_acts->actions = ret; ++ mod_hdr_acts->max_actions = new_num_actions; ++ ++out: ++ return mod_hdr_acts->actions + (mod_hdr_acts->num_actions * MLX5_MH_ACT_SZ); ++} ++ ++void ++mlx5e_mod_hdr_dealloc(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts) ++{ ++ kfree(mod_hdr_acts->actions); ++ mod_hdr_acts->actions = NULL; ++ mod_hdr_acts->num_actions = 0; ++ mod_hdr_acts->max_actions = 0; ++} ++ ++char * ++mlx5e_mod_hdr_get_item(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, int pos) ++{ ++ return mod_hdr_acts->actions + (pos * MLX5_MH_ACT_SZ); ++} +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.h b/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.h +index 33b23d8f91828..b8cd1a7a31be6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.h +@@ -15,6 +15,11 @@ struct mlx5e_tc_mod_hdr_acts { + void *actions; + }; + ++char *mlx5e_mod_hdr_alloc(struct mlx5_core_dev *mdev, int namespace, ++ struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts); ++void mlx5e_mod_hdr_dealloc(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts); ++char *mlx5e_mod_hdr_get_item(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, int pos); ++ + struct mlx5e_mod_hdr_handle * + mlx5e_mod_hdr_attach(struct mlx5_core_dev *mdev, + struct mod_hdr_tbl *tbl, +@@ -28,4 +33,12 @@ struct mlx5_modify_hdr *mlx5e_mod_hdr_get(struct mlx5e_mod_hdr_handle *mh); + void mlx5e_mod_hdr_tbl_init(struct mod_hdr_tbl *tbl); + void mlx5e_mod_hdr_tbl_destroy(struct mod_hdr_tbl *tbl); + ++static inline int mlx5e_mod_hdr_max_actions(struct mlx5_core_dev *mdev, int namespace) ++{ ++ if (namespace == MLX5_FLOW_NAMESPACE_FDB) /* FDB offloading */ ++ return MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, max_modify_header_actions); ++ else /* namespace is MLX5_FLOW_NAMESPACE_KERNEL - NIC offloading */ ++ return MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_modify_header_actions); ++} ++ + #endif /* __MLX5E_EN_MOD_HDR_H__ */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c +index 6552ecee3f9b9..d08723a444e3f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c +@@ -5,6 +5,7 @@ + #include + #include "en/mapping.h" + #include "en/tc/post_act.h" ++#include "en/mod_hdr.h" + #include "sample.h" + #include "eswitch.h" + #include "en_tc.h" +@@ -255,12 +256,12 @@ sample_modify_hdr_get(struct mlx5_core_dev *mdev, u32 obj_id, + goto err_modify_hdr; + } + +- dealloc_mod_hdr_actions(&mod_acts); ++ mlx5e_mod_hdr_dealloc(&mod_acts); + return modify_hdr; + + err_modify_hdr: + err_post_act: +- dealloc_mod_hdr_actions(&mod_acts); ++ mlx5e_mod_hdr_dealloc(&mod_acts); + err_set_regc0: + return ERR_PTR(err); + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c +index 94200f2dd92b0..80a49d7af05d6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c +@@ -609,22 +609,15 @@ mlx5_tc_ct_entry_create_nat(struct mlx5_tc_ct_priv *ct_priv, + struct flow_action *flow_action = &flow_rule->action; + struct mlx5_core_dev *mdev = ct_priv->dev; + struct flow_action_entry *act; +- size_t action_size; + char *modact; + int err, i; + +- action_size = MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto); +- + flow_action_for_each(i, act, flow_action) { + switch (act->id) { + case FLOW_ACTION_MANGLE: { +- err = alloc_mod_hdr_actions(mdev, ct_priv->ns_type, +- mod_acts); +- if (err) +- return err; +- +- modact = mod_acts->actions + +- mod_acts->num_actions * action_size; ++ modact = mlx5e_mod_hdr_alloc(mdev, ct_priv->ns_type, mod_acts); ++ if (IS_ERR(modact)) ++ return PTR_ERR(modact); + + err = mlx5_tc_ct_parse_mangle_to_mod_act(act, modact); + if (err) +@@ -707,11 +700,11 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv, + attr->modify_hdr = mlx5e_mod_hdr_get(*mh); + } + +- dealloc_mod_hdr_actions(&mod_acts); ++ mlx5e_mod_hdr_dealloc(&mod_acts); + return 0; + + err_mapping: +- dealloc_mod_hdr_actions(&mod_acts); ++ mlx5e_mod_hdr_dealloc(&mod_acts); + mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id); + return err; + } +@@ -1463,7 +1456,7 @@ static int tc_ct_pre_ct_add_rules(struct mlx5_ct_ft *ct_ft, + } + pre_ct->miss_rule = rule; + +- dealloc_mod_hdr_actions(&pre_mod_acts); ++ mlx5e_mod_hdr_dealloc(&pre_mod_acts); + kvfree(spec); + return 0; + +@@ -1472,7 +1465,7 @@ static int tc_ct_pre_ct_add_rules(struct mlx5_ct_ft *ct_ft, + err_flow_rule: + mlx5_modify_header_dealloc(dev, pre_ct->modify_hdr); + err_mapping: +- dealloc_mod_hdr_actions(&pre_mod_acts); ++ mlx5e_mod_hdr_dealloc(&pre_mod_acts); + kvfree(spec); + return err; + } +@@ -1872,14 +1865,14 @@ __mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *ct_priv, + } + + attr->ct_attr.ct_flow = ct_flow; +- dealloc_mod_hdr_actions(&pre_mod_acts); ++ mlx5e_mod_hdr_dealloc(&pre_mod_acts); + + return ct_flow->pre_ct_rule; + + err_insert_orig: + mlx5_modify_header_dealloc(priv->mdev, pre_ct_attr->modify_hdr); + err_mapping: +- dealloc_mod_hdr_actions(&pre_mod_acts); ++ mlx5e_mod_hdr_dealloc(&pre_mod_acts); + mlx5_chains_put_chain_mapping(ct_priv->chains, ct_flow->chain_mapping); + err_get_chain: + kfree(ct_flow->pre_ct_attr); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 433602f871bd4..39fa0fa21e33c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -71,7 +71,6 @@ + #include "lag_mp.h" + + #define nic_chains(priv) ((priv)->fs.tc.chains) +-#define MLX5_MH_ACT_SZ MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto) + + #define MLX5E_TC_TABLE_NUM_GROUPS 4 + #define MLX5E_TC_TABLE_MAX_GROUP_SIZE BIT(18) +@@ -209,12 +208,9 @@ mlx5e_tc_match_to_reg_set_and_get_id(struct mlx5_core_dev *mdev, + char *modact; + int err; + +- err = alloc_mod_hdr_actions(mdev, ns, mod_hdr_acts); +- if (err) +- return err; +- +- modact = mod_hdr_acts->actions + +- (mod_hdr_acts->num_actions * MLX5_MH_ACT_SZ); ++ modact = mlx5e_mod_hdr_alloc(mdev, ns, mod_hdr_acts); ++ if (IS_ERR(modact)) ++ return PTR_ERR(modact); + + /* Firmware has 5bit length field and 0 means 32bits */ + if (mlen == 32) +@@ -316,7 +312,7 @@ void mlx5e_tc_match_to_reg_mod_hdr_change(struct mlx5_core_dev *mdev, + int mlen = mlx5e_tc_attr_to_reg_mappings[type].mlen; + char *modact; + +- modact = mod_hdr_acts->actions + (act_id * MLX5_MH_ACT_SZ); ++ modact = mlx5e_mod_hdr_get_item(mod_hdr_acts, act_id); + + /* Firmware has 5bit length field and 0 means 32bits */ + if (mlen == 32) +@@ -1059,7 +1055,7 @@ mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv, + + if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { + err = mlx5e_attach_mod_hdr(priv, flow, parse_attr); +- dealloc_mod_hdr_actions(&parse_attr->mod_hdr_acts); ++ mlx5e_mod_hdr_dealloc(&parse_attr->mod_hdr_acts); + if (err) + return err; + } +@@ -1557,7 +1553,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, + mlx5_tc_ct_match_del(get_ct_priv(priv), &flow->attr->ct_attr); + + if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { +- dealloc_mod_hdr_actions(&attr->parse_attr->mod_hdr_acts); ++ mlx5e_mod_hdr_dealloc(&attr->parse_attr->mod_hdr_acts); + if (vf_tun && attr->modify_hdr) + mlx5_modify_header_dealloc(priv->mdev, attr->modify_hdr); + else +@@ -2803,13 +2799,12 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + struct netlink_ext_ack *extack) + { + struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals; +- int i, action_size, first, last, next_z; + void *headers_c, *headers_v, *action, *vals_p; + u32 *s_masks_p, *a_masks_p, s_mask, a_mask; + struct mlx5e_tc_mod_hdr_acts *mod_acts; +- struct mlx5_fields *f; + unsigned long mask, field_mask; +- int err; ++ int i, first, last, next_z; ++ struct mlx5_fields *f; + u8 cmd; + + mod_acts = &parse_attr->mod_hdr_acts; +@@ -2821,8 +2816,6 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + set_vals = &hdrs[0].vals; + add_vals = &hdrs[1].vals; + +- action_size = MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto); +- + for (i = 0; i < ARRAY_SIZE(fields); i++) { + bool skip; + +@@ -2890,18 +2883,16 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + return -EOPNOTSUPP; + } + +- err = alloc_mod_hdr_actions(priv->mdev, namespace, mod_acts); +- if (err) { ++ action = mlx5e_mod_hdr_alloc(priv->mdev, namespace, mod_acts); ++ if (IS_ERR(action)) { + NL_SET_ERR_MSG_MOD(extack, + "too many pedit actions, can't offload"); + mlx5_core_warn(priv->mdev, + "mlx5: parsed %d pedit actions, can't do more\n", + mod_acts->num_actions); +- return err; ++ return PTR_ERR(action); + } + +- action = mod_acts->actions + +- (mod_acts->num_actions * action_size); + MLX5_SET(set_action_in, action, action_type, cmd); + MLX5_SET(set_action_in, action, field, f->field); + +@@ -2931,57 +2922,6 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + return 0; + } + +-static int mlx5e_flow_namespace_max_modify_action(struct mlx5_core_dev *mdev, +- int namespace) +-{ +- if (namespace == MLX5_FLOW_NAMESPACE_FDB) /* FDB offloading */ +- return MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, max_modify_header_actions); +- else /* namespace is MLX5_FLOW_NAMESPACE_KERNEL - NIC offloading */ +- return MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_modify_header_actions); +-} +- +-int alloc_mod_hdr_actions(struct mlx5_core_dev *mdev, +- int namespace, +- struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts) +-{ +- int action_size, new_num_actions, max_hw_actions; +- size_t new_sz, old_sz; +- void *ret; +- +- if (mod_hdr_acts->num_actions < mod_hdr_acts->max_actions) +- return 0; +- +- action_size = MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto); +- +- max_hw_actions = mlx5e_flow_namespace_max_modify_action(mdev, +- namespace); +- new_num_actions = min(max_hw_actions, +- mod_hdr_acts->actions ? +- mod_hdr_acts->max_actions * 2 : 1); +- if (mod_hdr_acts->max_actions == new_num_actions) +- return -ENOSPC; +- +- new_sz = action_size * new_num_actions; +- old_sz = mod_hdr_acts->max_actions * action_size; +- ret = krealloc(mod_hdr_acts->actions, new_sz, GFP_KERNEL); +- if (!ret) +- return -ENOMEM; +- +- memset(ret + old_sz, 0, new_sz - old_sz); +- mod_hdr_acts->actions = ret; +- mod_hdr_acts->max_actions = new_num_actions; +- +- return 0; +-} +- +-void dealloc_mod_hdr_actions(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts) +-{ +- kfree(mod_hdr_acts->actions); +- mod_hdr_acts->actions = NULL; +- mod_hdr_acts->num_actions = 0; +- mod_hdr_acts->max_actions = 0; +-} +- + static const struct pedit_headers zero_masks = {}; + + static int +@@ -3004,7 +2944,7 @@ parse_pedit_to_modify_hdr(struct mlx5e_priv *priv, + goto out_err; + } + +- if (!mlx5e_flow_namespace_max_modify_action(priv->mdev, namespace)) { ++ if (!mlx5e_mod_hdr_max_actions(priv->mdev, namespace)) { + NL_SET_ERR_MSG_MOD(extack, + "The pedit offload action is not supported"); + goto out_err; +@@ -3096,7 +3036,7 @@ static int alloc_tc_pedit_action(struct mlx5e_priv *priv, int namespace, + return 0; + + out_dealloc_parsed_actions: +- dealloc_mod_hdr_actions(&parse_attr->mod_hdr_acts); ++ mlx5e_mod_hdr_dealloc(&parse_attr->mod_hdr_acts); + return err; + } + +@@ -3529,7 +3469,7 @@ actions_prepare_mod_hdr_actions(struct mlx5e_priv *priv, + return 0; + + attr->action &= ~MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; +- dealloc_mod_hdr_actions(&parse_attr->mod_hdr_acts); ++ mlx5e_mod_hdr_dealloc(&parse_attr->mod_hdr_acts); + + if (ns_type != MLX5_FLOW_NAMESPACE_FDB) + return 0; +@@ -4613,7 +4553,7 @@ mlx5e_add_nic_flow(struct mlx5e_priv *priv, + + err_free: + flow_flag_set(flow, FAILED); +- dealloc_mod_hdr_actions(&parse_attr->mod_hdr_acts); ++ mlx5e_mod_hdr_dealloc(&parse_attr->mod_hdr_acts); + mlx5e_flow_put(priv, flow); + out: + return err; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h +index f48af82781f88..26a85a11eb6ca 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h +@@ -244,11 +244,6 @@ int mlx5e_tc_add_flow_mod_hdr(struct mlx5e_priv *priv, + struct mlx5e_tc_flow *flow, + struct mlx5_flow_attr *attr); + +-int alloc_mod_hdr_actions(struct mlx5_core_dev *mdev, +- int namespace, +- struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts); +-void dealloc_mod_hdr_actions(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts); +- + struct mlx5e_tc_flow; + u32 mlx5e_tc_get_flow_tun_id(struct mlx5e_tc_flow *flow); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c +index 425c91814b34f..c275fe028b6d8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c +@@ -14,6 +14,7 @@ + #include "fs_core.h" + #include "esw/indir_table.h" + #include "lib/fs_chains.h" ++#include "en/mod_hdr.h" + + #define MLX5_ESW_INDIR_TABLE_SIZE 128 + #define MLX5_ESW_INDIR_TABLE_RECIRC_IDX_MAX (MLX5_ESW_INDIR_TABLE_SIZE - 2) +@@ -226,7 +227,7 @@ static int mlx5_esw_indir_table_rule_get(struct mlx5_eswitch *esw, + goto err_handle; + } + +- dealloc_mod_hdr_actions(&mod_acts); ++ mlx5e_mod_hdr_dealloc(&mod_acts); + rule->handle = handle; + rule->vni = esw_attr->rx_tun_attr->vni; + rule->mh = flow_act.modify_hdr; +@@ -243,7 +244,7 @@ static int mlx5_esw_indir_table_rule_get(struct mlx5_eswitch *esw, + mlx5_modify_header_dealloc(esw->dev, flow_act.modify_hdr); + err_mod_hdr_alloc: + err_mod_hdr_regc1: +- dealloc_mod_hdr_actions(&mod_acts); ++ mlx5e_mod_hdr_dealloc(&mod_acts); + err_mod_hdr_regc0: + err_ethertype: + kfree(rule); +-- +2.42.0 + diff --git a/queue-5.15/net-mlx5e-remove-incorrect-addition-of-action-fwd-fl.patch b/queue-5.15/net-mlx5e-remove-incorrect-addition-of-action-fwd-fl.patch new file mode 100644 index 00000000000..e10fd7cb24d --- /dev/null +++ b/queue-5.15/net-mlx5e-remove-incorrect-addition-of-action-fwd-fl.patch @@ -0,0 +1,39 @@ +From 14f0c8f36a2138c7b515add9d6388fe22e4f5066 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Aug 2021 09:37:19 +0300 +Subject: net/mlx5e: Remove incorrect addition of action fwd flag + +From: Roi Dayan + +[ Upstream commit 475fb86ac941f75da127c19d8e8b282d33de9784 ] + +A user is expected to explicit request a fwd or drop action. +It is not correct to implicit add a fwd action for the user, +when modify header action flag exists. + +Signed-off-by: Roi Dayan +Reviewed-by: Maor Dickman +Signed-off-by: Saeed Mahameed +Stable-dep-of: 0c101a23ca7e ("net/mlx5e: Fix pedit endianness") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index d123d9b4adf5e..d13ffba138934 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -3639,9 +3639,6 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, + return -EOPNOTSUPP; + } + +- if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) +- attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; +- + if (!actions_match_supported(priv, flow_action, parse_attr, flow, extack)) + return -EOPNOTSUPP; + +-- +2.42.0 + diff --git a/queue-5.15/net-set-sock_rcu_free-before-inserting-socket-into-h.patch b/queue-5.15/net-set-sock_rcu_free-before-inserting-socket-into-h.patch new file mode 100644 index 00000000000..e68ffe130aa --- /dev/null +++ b/queue-5.15/net-set-sock_rcu_free-before-inserting-socket-into-h.patch @@ -0,0 +1,88 @@ +From a342b4a91b49af7a528030d2edbed2bc9b489220 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Nov 2023 13:13:25 -0800 +Subject: net: set SOCK_RCU_FREE before inserting socket into hashtable + +From: Stanislav Fomichev + +[ Upstream commit 871019b22d1bcc9fab2d1feba1b9a564acbb6e99 ] + +We've started to see the following kernel traces: + + WARNING: CPU: 83 PID: 0 at net/core/filter.c:6641 sk_lookup+0x1bd/0x1d0 + + Call Trace: + + __bpf_skc_lookup+0x10d/0x120 + bpf_sk_lookup+0x48/0xd0 + bpf_sk_lookup_tcp+0x19/0x20 + bpf_prog_+0x37c/0x16a3 + cls_bpf_classify+0x205/0x2e0 + tcf_classify+0x92/0x160 + __netif_receive_skb_core+0xe52/0xf10 + __netif_receive_skb_list_core+0x96/0x2b0 + napi_complete_done+0x7b5/0xb70 + _poll+0x94/0xb0 + net_rx_action+0x163/0x1d70 + __do_softirq+0xdc/0x32e + asm_call_irq_on_stack+0x12/0x20 + + do_softirq_own_stack+0x36/0x50 + do_softirq+0x44/0x70 + +__inet_hash can race with lockless (rcu) readers on the other cpus: + + __inet_hash + __sk_nulls_add_node_rcu + <- (bpf triggers here) + sock_set_flag(SOCK_RCU_FREE) + +Let's move the SOCK_RCU_FREE part up a bit, before we are inserting +the socket into hashtables. Note, that the race is really harmless; +the bpf callers are handling this situation (where listener socket +doesn't have SOCK_RCU_FREE set) correctly, so the only +annoyance is a WARN_ONCE. + +More details from Eric regarding SOCK_RCU_FREE timeline: + +Commit 3b24d854cb35 ("tcp/dccp: do not touch listener sk_refcnt under +synflood") added SOCK_RCU_FREE. At that time, the precise location of +sock_set_flag(sk, SOCK_RCU_FREE) did not matter, because the thread calling +__inet_hash() owns a reference on sk. SOCK_RCU_FREE was only tested +at dismantle time. + +Commit 6acc9b432e67 ("bpf: Add helper to retrieve socket in BPF") +started checking SOCK_RCU_FREE _after_ the lookup to infer whether +the refcount has been taken care of. + +Fixes: 6acc9b432e67 ("bpf: Add helper to retrieve socket in BPF") +Reviewed-by: Eric Dumazet +Signed-off-by: Stanislav Fomichev +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/inet_hashtables.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index a673f4ec1b429..b4e0120af9c2b 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -609,12 +609,12 @@ int __inet_hash(struct sock *sk, struct sock *osk) + if (err) + goto unlock; + } ++ sock_set_flag(sk, SOCK_RCU_FREE); + if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && + sk->sk_family == AF_INET6) + __sk_nulls_add_node_tail_rcu(sk, &ilb2->nulls_head); + else + __sk_nulls_add_node_rcu(sk, &ilb2->nulls_head); +- sock_set_flag(sk, SOCK_RCU_FREE); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + unlock: + spin_unlock(&ilb2->lock); +-- +2.42.0 + diff --git a/queue-5.15/net-stmmac-fix-rx-budget-limit-check.patch b/queue-5.15/net-stmmac-fix-rx-budget-limit-check.patch new file mode 100644 index 00000000000..ac9435b6367 --- /dev/null +++ b/queue-5.15/net-stmmac-fix-rx-budget-limit-check.patch @@ -0,0 +1,46 @@ +From dc48636a49d2407a800d44af3a8cd8a4e502ebf4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 19:42:49 +0200 +Subject: net: stmmac: fix rx budget limit check + +From: Baruch Siach + +[ Upstream commit fa02de9e75889915b554eda1964a631fd019973b ] + +The while loop condition verifies 'count < limit'. Neither value change +before the 'count >= limit' check. As is this check is dead code. But +code inspection reveals a code path that modifies 'count' and then goto +'drain_data' and back to 'read_again'. So there is a need to verify +count value sanity after 'read_again'. + +Move 'read_again' up to fix the count limit check. + +Fixes: ec222003bd94 ("net: stmmac: Prepare to add Split Header support") +Signed-off-by: Baruch Siach +Reviewed-by: Serge Semin +Link: https://lore.kernel.org/r/d9486296c3b6b12ab3a0515fcd47d56447a07bfc.1699897370.git.baruch@tkos.co.il +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index a43628dd1f4c2..2b4c30a5ffcd9 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5165,10 +5165,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) + len = 0; + } + ++read_again: + if (count >= limit) + break; + +-read_again: + buf1_len = 0; + buf2_len = 0; + entry = next_entry; +-- +2.42.0 + diff --git a/queue-5.15/netfilter-nf_conntrack_bridge-initialize-err-to-0.patch b/queue-5.15/netfilter-nf_conntrack_bridge-initialize-err-to-0.patch new file mode 100644 index 00000000000..3b2a726cc6f --- /dev/null +++ b/queue-5.15/netfilter-nf_conntrack_bridge-initialize-err-to-0.patch @@ -0,0 +1,43 @@ +From c5a8d368d03726324b77aeaa223c637f89688f1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Nov 2023 11:20:18 +0800 +Subject: netfilter: nf_conntrack_bridge: initialize err to 0 + +From: Linkui Xiao + +[ Upstream commit a44af08e3d4d7566eeea98d7a29fe06e7b9de944 ] + +K2CI reported a problem: + + consume_skb(skb); + return err; +[nf_br_ip_fragment() error] uninitialized symbol 'err'. + +err is not initialized, because returning 0 is expected, initialize err +to 0. + +Fixes: 3c171f496ef5 ("netfilter: bridge: add connection tracking system") +Reported-by: k2ci +Signed-off-by: Linkui Xiao +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/bridge/netfilter/nf_conntrack_bridge.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c +index fdbed31585553..d14b2dbbd1dfb 100644 +--- a/net/bridge/netfilter/nf_conntrack_bridge.c ++++ b/net/bridge/netfilter/nf_conntrack_bridge.c +@@ -36,7 +36,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk, + ktime_t tstamp = skb->tstamp; + struct ip_frag_state state; + struct iphdr *iph; +- int err; ++ int err = 0; + + /* for offloaded checksums cleanup checksum before fragmentation */ + if (skb->ip_summed == CHECKSUM_PARTIAL && +-- +2.42.0 + diff --git a/queue-5.15/netfilter-nf_tables-add-and-use-be-register-load-sto.patch b/queue-5.15/netfilter-nf_tables-add-and-use-be-register-load-sto.patch new file mode 100644 index 00000000000..49f715bde54 --- /dev/null +++ b/queue-5.15/netfilter-nf_tables-add-and-use-be-register-load-sto.patch @@ -0,0 +1,101 @@ +From b78cf5fd0e1401319e2680cde01c3c452446df7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Jun 2022 15:05:12 +0200 +Subject: netfilter: nf_tables: add and use BE register load-store helpers + +From: Florian Westphal + +[ Upstream commit 7278b3c1e4ebf6f9c4cda07600f19824857c81fe ] + +Same as the existing ones, no conversions. This is just for sparse sake +only so that we no longer mix be16/u16 and be32/u32 types. + +Alternative is to add __force __beX in various places, but this +seems nicer. + +objdiff shows no changes. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: c301f0981fdd ("netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval()") +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 15 +++++++++++++++ + net/bridge/netfilter/nft_meta_bridge.c | 2 +- + net/netfilter/nft_tproxy.c | 6 +++--- + 3 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index a0b47f2b896e1..df91b9f422551 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -144,11 +144,26 @@ static inline void nft_reg_store16(u32 *dreg, u16 val) + *(u16 *)dreg = val; + } + ++static inline void nft_reg_store_be16(u32 *dreg, __be16 val) ++{ ++ nft_reg_store16(dreg, (__force __u16)val); ++} ++ + static inline u16 nft_reg_load16(const u32 *sreg) + { + return *(u16 *)sreg; + } + ++static inline __be16 nft_reg_load_be16(const u32 *sreg) ++{ ++ return (__force __be16)nft_reg_load16(sreg); ++} ++ ++static inline __be32 nft_reg_load_be32(const u32 *sreg) ++{ ++ return *(__force __be32 *)sreg; ++} ++ + static inline void nft_reg_store64(u32 *dreg, u64 val) + { + put_unaligned(val, (u64 *)dreg); +diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c +index 97805ec424c19..1967fd063cfb7 100644 +--- a/net/bridge/netfilter/nft_meta_bridge.c ++++ b/net/bridge/netfilter/nft_meta_bridge.c +@@ -53,7 +53,7 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr, + goto err; + + br_vlan_get_proto(br_dev, &p_proto); +- nft_reg_store16(dest, htons(p_proto)); ++ nft_reg_store_be16(dest, htons(p_proto)); + return; + } + default: +diff --git a/net/netfilter/nft_tproxy.c b/net/netfilter/nft_tproxy.c +index 9fea90ed79d44..e9679cb4afbe6 100644 +--- a/net/netfilter/nft_tproxy.c ++++ b/net/netfilter/nft_tproxy.c +@@ -52,11 +52,11 @@ static void nft_tproxy_eval_v4(const struct nft_expr *expr, + skb->dev, NF_TPROXY_LOOKUP_ESTABLISHED); + + if (priv->sreg_addr) +- taddr = regs->data[priv->sreg_addr]; ++ taddr = nft_reg_load_be32(®s->data[priv->sreg_addr]); + taddr = nf_tproxy_laddr4(skb, taddr, iph->daddr); + + if (priv->sreg_port) +- tport = nft_reg_load16(®s->data[priv->sreg_port]); ++ tport = nft_reg_load_be16(®s->data[priv->sreg_port]); + if (!tport) + tport = hp->dest; + +@@ -124,7 +124,7 @@ static void nft_tproxy_eval_v6(const struct nft_expr *expr, + taddr = *nf_tproxy_laddr6(skb, &taddr, &iph->daddr); + + if (priv->sreg_port) +- tport = nft_reg_load16(®s->data[priv->sreg_port]); ++ tport = nft_reg_load_be16(®s->data[priv->sreg_port]); + if (!tport) + tport = hp->dest; + +-- +2.42.0 + diff --git a/queue-5.15/netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch b/queue-5.15/netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch new file mode 100644 index 00000000000..8a3e4e1f2d2 --- /dev/null +++ b/queue-5.15/netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch @@ -0,0 +1,91 @@ +From 3ee054c732ef1495e9cdf8385c72e1f3f46a38d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Nov 2023 09:42:51 +0300 +Subject: netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval() + +From: Dan Carpenter + +[ Upstream commit c301f0981fdd3fd1ffac6836b423c4d7a8e0eb63 ] + +The problem is in nft_byteorder_eval() where we are iterating through a +loop and writing to dst[0], dst[1], dst[2] and so on... On each +iteration we are writing 8 bytes. But dst[] is an array of u32 so each +element only has space for 4 bytes. That means that every iteration +overwrites part of the previous element. + +I spotted this bug while reviewing commit caf3ef7468f7 ("netfilter: +nf_tables: prevent OOB access in nft_byteorder_eval") which is a related +issue. I think that the reason we have not detected this bug in testing +is that most of time we only write one element. + +Fixes: ce1e7989d989 ("netfilter: nft_byteorder: provide 64bit le/be conversion") +Signed-off-by: Dan Carpenter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 4 ++-- + net/netfilter/nft_byteorder.c | 5 +++-- + net/netfilter/nft_meta.c | 2 +- + 3 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index df91b9f422551..8e9c5bc1a9e69 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -164,9 +164,9 @@ static inline __be32 nft_reg_load_be32(const u32 *sreg) + return *(__force __be32 *)sreg; + } + +-static inline void nft_reg_store64(u32 *dreg, u64 val) ++static inline void nft_reg_store64(u64 *dreg, u64 val) + { +- put_unaligned(val, (u64 *)dreg); ++ put_unaligned(val, dreg); + } + + static inline u64 nft_reg_load64(const u32 *sreg) +diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c +index d3e1467e576fb..adf208b7929fd 100644 +--- a/net/netfilter/nft_byteorder.c ++++ b/net/netfilter/nft_byteorder.c +@@ -38,13 +38,14 @@ void nft_byteorder_eval(const struct nft_expr *expr, + + switch (priv->size) { + case 8: { ++ u64 *dst64 = (void *)dst; + u64 src64; + + switch (priv->op) { + case NFT_BYTEORDER_NTOH: + for (i = 0; i < priv->len / 8; i++) { + src64 = nft_reg_load64(&src[i]); +- nft_reg_store64(&dst[i], ++ nft_reg_store64(&dst64[i], + be64_to_cpu((__force __be64)src64)); + } + break; +@@ -52,7 +53,7 @@ void nft_byteorder_eval(const struct nft_expr *expr, + for (i = 0; i < priv->len / 8; i++) { + src64 = (__force __u64) + cpu_to_be64(nft_reg_load64(&src[i])); +- nft_reg_store64(&dst[i], src64); ++ nft_reg_store64(&dst64[i], src64); + } + break; + } +diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c +index 14412f69a34e8..35aba304a25b9 100644 +--- a/net/netfilter/nft_meta.c ++++ b/net/netfilter/nft_meta.c +@@ -63,7 +63,7 @@ nft_meta_get_eval_time(enum nft_meta_keys key, + { + switch (key) { + case NFT_META_TIME_NS: +- nft_reg_store64(dest, ktime_get_real_ns()); ++ nft_reg_store64((u64 *)dest, ktime_get_real_ns()); + break; + case NFT_META_TIME_DAY: + nft_reg_store8(dest, nft_meta_weekday()); +-- +2.42.0 + diff --git a/queue-5.15/netfilter-nf_tables-use-the-correct-get-put-helpers.patch b/queue-5.15/netfilter-nf_tables-use-the-correct-get-put-helpers.patch new file mode 100644 index 00000000000..85178ed63b2 --- /dev/null +++ b/queue-5.15/netfilter-nf_tables-use-the-correct-get-put-helpers.patch @@ -0,0 +1,130 @@ +From b7f674b71ecff3f2c3f26829238230b07b52ce84 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Jun 2022 15:05:11 +0200 +Subject: netfilter: nf_tables: use the correct get/put helpers + +From: Florian Westphal + +[ Upstream commit d86473bf2ff39c05d4a6701c8aec66a16af0d410 ] + +Switch to be16/32 and u16/32 respectively. No code changes here, +the functions do the same thing, this is just for sparse checkers' sake. + +objdiff shows no changes. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: c301f0981fdd ("netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval()") +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_byteorder.c | 3 ++- + net/netfilter/nft_osf.c | 2 +- + net/netfilter/nft_socket.c | 8 ++++---- + net/netfilter/nft_xfrm.c | 8 ++++---- + 4 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c +index 7b0b8fecb2205..d3e1467e576fb 100644 +--- a/net/netfilter/nft_byteorder.c ++++ b/net/netfilter/nft_byteorder.c +@@ -44,7 +44,8 @@ void nft_byteorder_eval(const struct nft_expr *expr, + case NFT_BYTEORDER_NTOH: + for (i = 0; i < priv->len / 8; i++) { + src64 = nft_reg_load64(&src[i]); +- nft_reg_store64(&dst[i], be64_to_cpu(src64)); ++ nft_reg_store64(&dst[i], ++ be64_to_cpu((__force __be64)src64)); + } + break; + case NFT_BYTEORDER_HTON: +diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c +index 720dc9fba6d4f..c9c124200a4db 100644 +--- a/net/netfilter/nft_osf.c ++++ b/net/netfilter/nft_osf.c +@@ -99,7 +99,7 @@ static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr) + if (nla_put_u8(skb, NFTA_OSF_TTL, priv->ttl)) + goto nla_put_failure; + +- if (nla_put_be32(skb, NFTA_OSF_FLAGS, ntohl(priv->flags))) ++ if (nla_put_u32(skb, NFTA_OSF_FLAGS, ntohl((__force __be32)priv->flags))) + goto nla_put_failure; + + if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg)) +diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c +index 9ad9cc0d1d27c..1725e7349f3d9 100644 +--- a/net/netfilter/nft_socket.c ++++ b/net/netfilter/nft_socket.c +@@ -162,7 +162,7 @@ static int nft_socket_init(const struct nft_ctx *ctx, + return -EOPNOTSUPP; + } + +- priv->key = ntohl(nla_get_u32(tb[NFTA_SOCKET_KEY])); ++ priv->key = ntohl(nla_get_be32(tb[NFTA_SOCKET_KEY])); + switch(priv->key) { + case NFT_SOCKET_TRANSPARENT: + case NFT_SOCKET_WILDCARD: +@@ -178,7 +178,7 @@ static int nft_socket_init(const struct nft_ctx *ctx, + if (!tb[NFTA_SOCKET_LEVEL]) + return -EINVAL; + +- level = ntohl(nla_get_u32(tb[NFTA_SOCKET_LEVEL])); ++ level = ntohl(nla_get_be32(tb[NFTA_SOCKET_LEVEL])); + if (level > 255) + return -EOPNOTSUPP; + +@@ -200,12 +200,12 @@ static int nft_socket_dump(struct sk_buff *skb, + { + const struct nft_socket *priv = nft_expr_priv(expr); + +- if (nla_put_u32(skb, NFTA_SOCKET_KEY, htonl(priv->key))) ++ if (nla_put_be32(skb, NFTA_SOCKET_KEY, htonl(priv->key))) + return -1; + if (nft_dump_register(skb, NFTA_SOCKET_DREG, priv->dreg)) + return -1; + if (priv->key == NFT_SOCKET_CGROUPV2 && +- nla_put_u32(skb, NFTA_SOCKET_LEVEL, htonl(priv->level))) ++ nla_put_be32(skb, NFTA_SOCKET_LEVEL, htonl(priv->level))) + return -1; + return 0; + } +diff --git a/net/netfilter/nft_xfrm.c b/net/netfilter/nft_xfrm.c +index cbbbc4ecad3ae..3553f89fd057f 100644 +--- a/net/netfilter/nft_xfrm.c ++++ b/net/netfilter/nft_xfrm.c +@@ -50,7 +50,7 @@ static int nft_xfrm_get_init(const struct nft_ctx *ctx, + return -EOPNOTSUPP; + } + +- priv->key = ntohl(nla_get_u32(tb[NFTA_XFRM_KEY])); ++ priv->key = ntohl(nla_get_be32(tb[NFTA_XFRM_KEY])); + switch (priv->key) { + case NFT_XFRM_KEY_REQID: + case NFT_XFRM_KEY_SPI: +@@ -132,13 +132,13 @@ static void nft_xfrm_state_get_key(const struct nft_xfrm *priv, + WARN_ON_ONCE(1); + break; + case NFT_XFRM_KEY_DADDR_IP4: +- *dest = state->id.daddr.a4; ++ *dest = (__force __u32)state->id.daddr.a4; + return; + case NFT_XFRM_KEY_DADDR_IP6: + memcpy(dest, &state->id.daddr.in6, sizeof(struct in6_addr)); + return; + case NFT_XFRM_KEY_SADDR_IP4: +- *dest = state->props.saddr.a4; ++ *dest = (__force __u32)state->props.saddr.a4; + return; + case NFT_XFRM_KEY_SADDR_IP6: + memcpy(dest, &state->props.saddr.in6, sizeof(struct in6_addr)); +@@ -147,7 +147,7 @@ static void nft_xfrm_state_get_key(const struct nft_xfrm *priv, + *dest = state->props.reqid; + return; + case NFT_XFRM_KEY_SPI: +- *dest = state->id.spi; ++ *dest = (__force __u32)state->id.spi; + return; + } + +-- +2.42.0 + diff --git a/queue-5.15/nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch b/queue-5.15/nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch new file mode 100644 index 00000000000..5f81bdcbdce --- /dev/null +++ b/queue-5.15/nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch @@ -0,0 +1,48 @@ +From e56a378a44860f5d7c807c7fbe338c679bd3fcb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 11:04:10 -0400 +Subject: NFSv4.1: fix SP4_MACH_CRED protection for pnfs IO + +From: Olga Kornievskaia + +[ Upstream commit 5cc7688bae7f0757c39c1d3dfdd827b724061067 ] + +If the client is doing pnfs IO and Kerberos is configured and EXCHANGEID +successfully negotiated SP4_MACH_CRED and WRITE/COMMIT are on the +list of state protected operations, then we need to make sure to +choose the DS's rpc_client structure instead of the MDS's one. + +Fixes: fb91fb0ee7b2 ("NFS: Move call to nfs4_state_protect_write() to nfs4_write_setup()") +Signed-off-by: Olga Kornievskaia +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4proc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 565d11a21f5e2..d65af9a60c35c 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5608,7 +5608,7 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr, + + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; + nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0); +- nfs4_state_protect_write(server->nfs_client, clnt, msg, hdr); ++ nfs4_state_protect_write(hdr->ds_clp ? hdr->ds_clp : server->nfs_client, clnt, msg, hdr); + } + + static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) +@@ -5649,7 +5649,8 @@ static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_mess + data->res.server = server; + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; + nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, 0); +- nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_COMMIT, clnt, msg); ++ nfs4_state_protect(data->ds_clp ? data->ds_clp : server->nfs_client, ++ NFS_SP4_MACH_CRED_COMMIT, clnt, msg); + } + + static int _nfs4_proc_commit(struct file *dst, struct nfs_commitargs *args, +-- +2.42.0 + diff --git a/queue-5.15/pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch b/queue-5.15/pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch new file mode 100644 index 00000000000..e3545c9ff6e --- /dev/null +++ b/queue-5.15/pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch @@ -0,0 +1,60 @@ +From 085b5baf1da04a0590135ede958e19ec6643845d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 14:36:06 +0000 +Subject: PCI: Disable ATS for specific Intel IPU E2000 devices + +From: Bartosz Pawlowski + +[ Upstream commit a18615b1cfc04f00548c60eb9a77e0ce56e848fd ] + +Due to a hardware issue in A and B steppings of Intel IPU E2000, it expects +wrong endianness in ATS invalidation message body. This problem can lead to +outdated translations being returned as valid and finally cause system +instability. + +To prevent such issues, add quirk_intel_e2000_no_ats() to disable ATS for +vulnerable IPU E2000 devices. + +Link: https://lore.kernel.org/r/20230908143606.685930-3-bartosz.pawlowski@intel.com +Signed-off-by: Bartosz Pawlowski +Signed-off-by: Bjorn Helgaas +Reviewed-by: Andy Shevchenko +Reviewed-by: Alexander Lobakin +Signed-off-by: Sasha Levin +--- + drivers/pci/quirks.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 30efa1ee595d3..5d8768cd7c50a 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5424,6 +5424,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats); + /* AMD Raven platform iGPU */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats); ++ ++/* ++ * Intel IPU E2000 revisions before C0 implement incorrect endianness ++ * in ATS Invalidate Request message body. Disable ATS for those devices. ++ */ ++static void quirk_intel_e2000_no_ats(struct pci_dev *pdev) ++{ ++ if (pdev->revision < 0x20) ++ quirk_no_ats(pdev); ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats); + #endif /* CONFIG_PCI_ATS */ + + /* Freescale PCIe doesn't support MSI in RC mode */ +-- +2.42.0 + diff --git a/queue-5.15/pci-extract-ats-disabling-to-a-helper-function.patch b/queue-5.15/pci-extract-ats-disabling-to-a-helper-function.patch new file mode 100644 index 00000000000..3f9f52e9b13 --- /dev/null +++ b/queue-5.15/pci-extract-ats-disabling-to-a-helper-function.patch @@ -0,0 +1,60 @@ +From ee073d9795b5ceb536dce6b772d9b901b69858e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 14:36:05 +0000 +Subject: PCI: Extract ATS disabling to a helper function + +From: Bartosz Pawlowski + +[ Upstream commit f18b1137d38c091cc8c16365219f0a1d4a30b3d1 ] + +Introduce quirk_no_ats() helper function to provide a standard way to +disable ATS capability in PCI quirks. + +Suggested-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20230908143606.685930-2-bartosz.pawlowski@intel.com +Signed-off-by: Bartosz Pawlowski +Signed-off-by: Bjorn Helgaas +Reviewed-by: Andy Shevchenko +Signed-off-by: Sasha Levin +--- + drivers/pci/quirks.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 5955e682c4348..30efa1ee595d3 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5379,6 +5379,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0420, quirk_no_ext_tags); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags); + + #ifdef CONFIG_PCI_ATS ++static void quirk_no_ats(struct pci_dev *pdev) ++{ ++ pci_info(pdev, "disabling ATS\n"); ++ pdev->ats_cap = 0; ++} ++ + /* + * Some devices require additional driver setup to enable ATS. Don't use + * ATS for those devices as ATS will be enabled before the driver has had a +@@ -5392,14 +5398,10 @@ static void quirk_amd_harvest_no_ats(struct pci_dev *pdev) + (pdev->subsystem_device == 0xce19 || + pdev->subsystem_device == 0xcc10 || + pdev->subsystem_device == 0xcc08)) +- goto no_ats; +- else +- return; ++ quirk_no_ats(pdev); ++ } else { ++ quirk_no_ats(pdev); + } +- +-no_ats: +- pci_info(pdev, "disabling ATS\n"); +- pdev->ats_cap = 0; + } + + /* AMD Stoney platform GPU */ +-- +2.42.0 + diff --git a/queue-5.15/pci-tegra194-use-field_get-field_prep-with-link-widt.patch b/queue-5.15/pci-tegra194-use-field_get-field_prep-with-link-widt.patch new file mode 100644 index 00000000000..71c3053d6c9 --- /dev/null +++ b/queue-5.15/pci-tegra194-use-field_get-field_prep-with-link-widt.patch @@ -0,0 +1,72 @@ +From 780cd13ca0f1dbc2e18a9859a2df40c0160eb19d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 15:56:44 +0300 +Subject: PCI: tegra194: Use FIELD_GET()/FIELD_PREP() with Link Width fields +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 759574abd78e3b47ec45bbd31a64e8832cf73f97 ] + +Use FIELD_GET() to extract PCIe Negotiated Link Width field instead of +custom masking and shifting. + +Similarly, change custom code that misleadingly used +PCI_EXP_LNKSTA_NLW_SHIFT to prepare value for PCI_EXP_LNKCAP write +to use FIELD_PREP() with correct field define (PCI_EXP_LNKCAP_MLW). + +Link: https://lore.kernel.org/r/20230919125648.1920-5-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Reviewed-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-tegra194.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c +index 765abe0732282..2f82da76e3711 100644 +--- a/drivers/pci/controller/dwc/pcie-tegra194.c ++++ b/drivers/pci/controller/dwc/pcie-tegra194.c +@@ -7,6 +7,7 @@ + * Author: Vidya Sagar + */ + ++#include + #include + #include + #include +@@ -328,8 +329,7 @@ static void apply_bad_link_workaround(struct pcie_port *pp) + */ + val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA); + if (val & PCI_EXP_LNKSTA_LBMS) { +- current_link_width = (val & PCI_EXP_LNKSTA_NLW) >> +- PCI_EXP_LNKSTA_NLW_SHIFT; ++ current_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val); + if (pcie->init_link_width > current_link_width) { + dev_warn(pci->dev, "PCIe link is bad, width reduced\n"); + val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + +@@ -731,8 +731,7 @@ static void tegra_pcie_enable_system_interrupts(struct pcie_port *pp) + + val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base + + PCI_EXP_LNKSTA); +- pcie->init_link_width = (val_w & PCI_EXP_LNKSTA_NLW) >> +- PCI_EXP_LNKSTA_NLW_SHIFT; ++ pcie->init_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val_w); + + val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base + + PCI_EXP_LNKCTL); +@@ -889,7 +888,7 @@ static int tegra_pcie_dw_host_init(struct pcie_port *pp) + /* Configure Max lane width from DT */ + val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP); + val &= ~PCI_EXP_LNKCAP_MLW; +- val |= (pcie->num_lanes << PCI_EXP_LNKSTA_NLW_SHIFT); ++ val |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, pcie->num_lanes); + dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, val); + + config_gen3_gen4_eq_presets(pcie); +-- +2.42.0 + diff --git a/queue-5.15/pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch b/queue-5.15/pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch new file mode 100644 index 00000000000..17ab63a08a3 --- /dev/null +++ b/queue-5.15/pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch @@ -0,0 +1,57 @@ +From f8631cba0b061776120e6648b68ca3c3be8b5dd3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 15:44:28 -0500 +Subject: PCI: Use FIELD_GET() in Sapphire RX 5600 XT Pulse quirk +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bjorn Helgaas + +[ Upstream commit 04e82fa5951ca66495d7b05665eff673aa3852b4 ] + +Use FIELD_GET() to remove dependences on the field position, i.e., the +shift value. No functional change intended. + +Separate because this isn't as trivial as the other FIELD_GET() changes. + +See 907830b0fc9e ("PCI: Add a REBAR size quirk for Sapphire RX 5600 XT +Pulse") + +Link: https://lore.kernel.org/r/20231010204436.1000644-3-helgaas@kernel.org +Signed-off-by: Bjorn Helgaas +Reviewed-by: Ilpo Järvinen +Reviewed-by: Jonathan Cameron +Reviewed-by: Kuppuswamy Sathyanarayanan +Cc: Nirmoy Das +Signed-off-by: Sasha Levin +--- + drivers/pci/pci.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 371ba983b4084..cc3f620b73bd7 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -3649,14 +3649,14 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) + return 0; + + pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap); +- cap &= PCI_REBAR_CAP_SIZES; ++ cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap); + + /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ + if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f && +- bar == 0 && cap == 0x7000) +- cap = 0x3f000; ++ bar == 0 && cap == 0x700) ++ return 0x3f00; + +- return cap >> 4; ++ return cap; + } + EXPORT_SYMBOL(pci_rebar_get_possible_sizes); + +-- +2.42.0 + diff --git a/queue-5.15/pci-use-field_get-to-extract-link-width.patch b/queue-5.15/pci-use-field_get-to-extract-link-width.patch new file mode 100644 index 00000000000..fa181fa85f6 --- /dev/null +++ b/queue-5.15/pci-use-field_get-to-extract-link-width.patch @@ -0,0 +1,75 @@ +From 07f95ec83ce0aa16626793cd8dfd3113acee964c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 15:56:46 +0300 +Subject: PCI: Use FIELD_GET() to extract Link Width +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit d1f9b39da4a5347150246871325190018cda8cb3 ] + +Use FIELD_GET() to extract PCIe Negotiated and Maximum Link Width fields +instead of custom masking and shifting. + +Link: https://lore.kernel.org/r/20230919125648.1920-7-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +[bhelgaas: drop duplicate include of ] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/pci/pci-sysfs.c | 5 ++--- + drivers/pci/pci.c | 5 ++--- + 2 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c +index f2909ae93f2f8..c271720c7f86f 100644 +--- a/drivers/pci/pci-sysfs.c ++++ b/drivers/pci/pci-sysfs.c +@@ -12,7 +12,7 @@ + * Modeled after usb's driverfs.c + */ + +- ++#include + #include + #include + #include +@@ -208,8 +208,7 @@ static ssize_t current_link_width_show(struct device *dev, + if (err) + return -EINVAL; + +- return sysfs_emit(buf, "%u\n", +- (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT); ++ return sysfs_emit(buf, "%u\n", FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat)); + } + static DEVICE_ATTR_RO(current_link_width); + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 244c1c2e08767..371ba983b4084 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -6071,8 +6071,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev, + pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta); + + next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS]; +- next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >> +- PCI_EXP_LNKSTA_NLW_SHIFT; ++ next_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta); + + next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed); + +@@ -6144,7 +6143,7 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev) + + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); + if (lnkcap) +- return (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4; ++ return FIELD_GET(PCI_EXP_LNKCAP_MLW, lnkcap); + + return PCIE_LNK_WIDTH_UNKNOWN; + } +-- +2.42.0 + diff --git a/queue-5.15/perf-core-bail-out-early-if-the-request-aux-area-is-.patch b/queue-5.15/perf-core-bail-out-early-if-the-request-aux-area-is-.patch new file mode 100644 index 00000000000..772f1a860d0 --- /dev/null +++ b/queue-5.15/perf-core-bail-out-early-if-the-request-aux-area-is-.patch @@ -0,0 +1,76 @@ +From bf513a0c355dcde76e87d9fbd3135be38a2e703a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 08:43:07 +0800 +Subject: perf/core: Bail out early if the request AUX area is out of bound + +From: Shuai Xue + +[ Upstream commit 54aee5f15b83437f23b2b2469bcf21bdd9823916 ] + +When perf-record with a large AUX area, e.g 4GB, it fails with: + + #perf record -C 0 -m ,4G -e arm_spe_0// -- sleep 1 + failed to mmap with 12 (Cannot allocate memory) + +and it reveals a WARNING with __alloc_pages(): + + ------------[ cut here ]------------ + WARNING: CPU: 44 PID: 17573 at mm/page_alloc.c:5568 __alloc_pages+0x1ec/0x248 + Call trace: + __alloc_pages+0x1ec/0x248 + __kmalloc_large_node+0xc0/0x1f8 + __kmalloc_node+0x134/0x1e8 + rb_alloc_aux+0xe0/0x298 + perf_mmap+0x440/0x660 + mmap_region+0x308/0x8a8 + do_mmap+0x3c0/0x528 + vm_mmap_pgoff+0xf4/0x1b8 + ksys_mmap_pgoff+0x18c/0x218 + __arm64_sys_mmap+0x38/0x58 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0x58/0x188 + do_el0_svc+0x34/0x50 + el0_svc+0x34/0x108 + el0t_64_sync_handler+0xb8/0xc0 + el0t_64_sync+0x1a4/0x1a8 + +'rb->aux_pages' allocated by kcalloc() is a pointer array which is used to +maintains AUX trace pages. The allocated page for this array is physically +contiguous (and virtually contiguous) with an order of 0..MAX_ORDER. If the +size of pointer array crosses the limitation set by MAX_ORDER, it reveals a +WARNING. + +So bail out early with -ENOMEM if the request AUX area is out of bound, +e.g.: + + #perf record -C 0 -m ,4G -e arm_spe_0// -- sleep 1 + failed to mmap with 12 (Cannot allocate memory) + +Signed-off-by: Shuai Xue +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Signed-off-by: Sasha Levin +--- + kernel/events/ring_buffer.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c +index f40da32f5e753..6808873555f0d 100644 +--- a/kernel/events/ring_buffer.c ++++ b/kernel/events/ring_buffer.c +@@ -696,6 +696,12 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event, + watermark = 0; + } + ++ /* ++ * kcalloc_node() is unable to allocate buffer if the size is larger ++ * than: PAGE_SIZE << MAX_ORDER; directly bail out in this case. ++ */ ++ if (get_order((unsigned long)nr_pages * sizeof(void *)) > MAX_ORDER) ++ return -ENOMEM; + rb->aux_pages = kcalloc_node(nr_pages, sizeof(void *), GFP_KERNEL, + node); + if (!rb->aux_pages) +-- +2.42.0 + diff --git a/queue-5.15/platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch b/queue-5.15/platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch new file mode 100644 index 00000000000..bfa5e9ff414 --- /dev/null +++ b/queue-5.15/platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch @@ -0,0 +1,38 @@ +From 23084caa15d21d085e3db98734d69b65a87548af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 22:09:21 +0300 +Subject: platform/x86: thinkpad_acpi: Add battery quirk for Thinkpad X120e +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Olli Asikainen + +[ Upstream commit 916646758aea81a143ce89103910f715ed923346 ] + +Thinkpad X120e also needs this battery quirk. + +Signed-off-by: Olli Asikainen +Link: https://lore.kernel.org/r/20231024190922.2742-1-olli.asikainen@gmail.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/thinkpad_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 3dc055ce6e61b..99c19a0b91513 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -9766,6 +9766,7 @@ static const struct tpacpi_quirk battery_quirk_table[] __initconst = { + * Individual addressing is broken on models that expose the + * primary battery as BAT1. + */ ++ TPACPI_Q_LNV('8', 'F', true), /* Thinkpad X120e */ + TPACPI_Q_LNV('J', '7', true), /* B5400 */ + TPACPI_Q_LNV('J', 'I', true), /* Thinkpad 11e */ + TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */ +-- +2.42.0 + diff --git a/queue-5.15/ppp-limit-mru-to-64k.patch b/queue-5.15/ppp-limit-mru-to-64k.patch new file mode 100644 index 00000000000..37b19be19eb --- /dev/null +++ b/queue-5.15/ppp-limit-mru-to-64k.patch @@ -0,0 +1,76 @@ +From 7c38945defe81e2df79e214a28b8a661210ef3e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Nov 2023 22:16:32 -0500 +Subject: ppp: limit MRU to 64K + +From: Willem de Bruijn + +[ Upstream commit c0a2a1b0d631fc460d830f52d06211838874d655 ] + +ppp_sync_ioctl allows setting device MRU, but does not sanity check +this input. + +Limit to a sane upper bound of 64KB. + +No implementation I could find generates larger than 64KB frames. +RFC 2823 mentions an upper bound of PPP over SDL of 64KB based on the +16-bit length field. Other protocols will be smaller, such as PPPoE +(9KB jumbo frame) and PPPoA (18190 maximum CPCS-SDU size, RFC 2364). +PPTP and L2TP encapsulate in IP. + +Syzbot managed to trigger alloc warning in __alloc_pages: + + if (WARN_ON_ONCE_GFP(order > MAX_ORDER, gfp)) + + WARNING: CPU: 1 PID: 37 at mm/page_alloc.c:4544 __alloc_pages+0x3ab/0x4a0 mm/page_alloc.c:4544 + + __alloc_skb+0x12b/0x330 net/core/skbuff.c:651 + __netdev_alloc_skb+0x72/0x3f0 net/core/skbuff.c:715 + netdev_alloc_skb include/linux/skbuff.h:3225 [inline] + dev_alloc_skb include/linux/skbuff.h:3238 [inline] + ppp_sync_input drivers/net/ppp/ppp_synctty.c:669 [inline] + ppp_sync_receive+0xff/0x680 drivers/net/ppp/ppp_synctty.c:334 + tty_ldisc_receive_buf+0x14c/0x180 drivers/tty/tty_buffer.c:390 + tty_port_default_receive_buf+0x70/0xb0 drivers/tty/tty_port.c:37 + receive_buf drivers/tty/tty_buffer.c:444 [inline] + flush_to_ldisc+0x261/0x780 drivers/tty/tty_buffer.c:494 + process_one_work+0x884/0x15c0 kernel/workqueue.c:2630 + +With call + + ioctl$PPPIOCSMRU1(r1, 0x40047452, &(0x7f0000000100)=0x5e6417a8) + +Similar code exists in other drivers that implement ppp_channel_ops +ioctl PPPIOCSMRU. Those might also be in scope. Notably excluded from +this are pppol2tp_ioctl and pppoe_ioctl. + +This code goes back to the start of git history. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+6177e1f90d92583bcc58@syzkaller.appspotmail.com +Signed-off-by: Willem de Bruijn +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ppp/ppp_synctty.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c +index e37faed81937f..692c558beed54 100644 +--- a/drivers/net/ppp/ppp_synctty.c ++++ b/drivers/net/ppp/ppp_synctty.c +@@ -464,6 +464,10 @@ ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg) + case PPPIOCSMRU: + if (get_user(val, (int __user *) argp)) + break; ++ if (val > U16_MAX) { ++ err = -EINVAL; ++ break; ++ } + if (val < PPP_MRU) + val = PPP_MRU; + ap->mru = val; +-- +2.42.0 + diff --git a/queue-5.15/ptp-annotate-data-race-around-q-head-and-q-tail.patch b/queue-5.15/ptp-annotate-data-race-around-q-head-and-q-tail.patch new file mode 100644 index 00000000000..b98fa9e307e --- /dev/null +++ b/queue-5.15/ptp-annotate-data-race-around-q-head-and-q-tail.patch @@ -0,0 +1,98 @@ +From c7d10269f7e0ac032ee6903df2e8c93a56b5b77f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 17:48:59 +0000 +Subject: ptp: annotate data-race around q->head and q->tail + +From: Eric Dumazet + +[ Upstream commit 73bde5a3294853947252cd9092a3517c7cb0cd2d ] + +As I was working on a syzbot report, I found that KCSAN would +probably complain that reading q->head or q->tail without +barriers could lead to invalid results. + +Add corresponding READ_ONCE() and WRITE_ONCE() to avoid +load-store tearing. + +Fixes: d94ba80ebbea ("ptp: Added a brand new class driver for ptp clocks.") +Signed-off-by: Eric Dumazet +Acked-by: Richard Cochran +Link: https://lore.kernel.org/r/20231109174859.3995880-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/ptp/ptp_chardev.c | 3 ++- + drivers/ptp/ptp_clock.c | 5 +++-- + drivers/ptp/ptp_private.h | 8 ++++++-- + drivers/ptp/ptp_sysfs.c | 3 ++- + 4 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c +index af3bc65c4595d..9311f3d09c8fc 100644 +--- a/drivers/ptp/ptp_chardev.c ++++ b/drivers/ptp/ptp_chardev.c +@@ -487,7 +487,8 @@ ssize_t ptp_read(struct posix_clock *pc, + + for (i = 0; i < cnt; i++) { + event[i] = queue->buf[queue->head]; +- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; ++ /* Paired with READ_ONCE() in queue_cnt() */ ++ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); + } + + spin_unlock_irqrestore(&queue->lock, flags); +diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c +index 8a652a367625b..e70c6dec3a3a3 100644 +--- a/drivers/ptp/ptp_clock.c ++++ b/drivers/ptp/ptp_clock.c +@@ -56,10 +56,11 @@ static void enqueue_external_timestamp(struct timestamp_event_queue *queue, + dst->t.sec = seconds; + dst->t.nsec = remainder; + ++ /* Both WRITE_ONCE() are paired with READ_ONCE() in queue_cnt() */ + if (!queue_free(queue)) +- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; ++ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); + +- queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS; ++ WRITE_ONCE(queue->tail, (queue->tail + 1) % PTP_MAX_TIMESTAMPS); + + spin_unlock_irqrestore(&queue->lock, flags); + } +diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h +index dba6be4770670..b336c12bb6976 100644 +--- a/drivers/ptp/ptp_private.h ++++ b/drivers/ptp/ptp_private.h +@@ -74,9 +74,13 @@ struct ptp_vclock { + * that a writer might concurrently increment the tail does not + * matter, since the queue remains nonempty nonetheless. + */ +-static inline int queue_cnt(struct timestamp_event_queue *q) ++static inline int queue_cnt(const struct timestamp_event_queue *q) + { +- int cnt = q->tail - q->head; ++ /* ++ * Paired with WRITE_ONCE() in enqueue_external_timestamp(), ++ * ptp_read(), extts_fifo_show(). ++ */ ++ int cnt = READ_ONCE(q->tail) - READ_ONCE(q->head); + return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt; + } + +diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c +index 9233bfedeb174..0bdfdd4bb0fa2 100644 +--- a/drivers/ptp/ptp_sysfs.c ++++ b/drivers/ptp/ptp_sysfs.c +@@ -79,7 +79,8 @@ static ssize_t extts_fifo_show(struct device *dev, + qcnt = queue_cnt(queue); + if (qcnt) { + event = queue->buf[queue->head]; +- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; ++ /* Paired with READ_ONCE() in queue_cnt() */ ++ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); + } + spin_unlock_irqrestore(&queue->lock, flags); + +-- +2.42.0 + diff --git a/queue-5.15/pwm-fix-double-shift-bug.patch b/queue-5.15/pwm-fix-double-shift-bug.patch new file mode 100644 index 00000000000..5654c53c0db --- /dev/null +++ b/queue-5.15/pwm-fix-double-shift-bug.patch @@ -0,0 +1,45 @@ +From a3c90b30d0f5db1889b732c2475379cbb36e0674 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 14:58:18 +0300 +Subject: pwm: Fix double shift bug +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dan Carpenter + +[ Upstream commit d27abbfd4888d79dd24baf50e774631046ac4732 ] + +These enums are passed to set/test_bit(). The set/test_bit() functions +take a bit number instead of a shifted value. Passing a shifted value +is a double shift bug like doing BIT(BIT(1)). The double shift bug +doesn't cause a problem here because we are only checking 0 and 1 but +if the value was 5 or above then it can lead to a buffer overflow. + +Signed-off-by: Dan Carpenter +Reviewed-by: Uwe Kleine-König +Reviewed-by: Sam Protsenko +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + include/linux/pwm.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/pwm.h b/include/linux/pwm.h +index c7bfa64aeb142..03c42e742dfe7 100644 +--- a/include/linux/pwm.h ++++ b/include/linux/pwm.h +@@ -44,8 +44,8 @@ struct pwm_args { + }; + + enum { +- PWMF_REQUESTED = 1 << 0, +- PWMF_EXPORTED = 1 << 1, ++ PWMF_REQUESTED = 0, ++ PWMF_EXPORTED = 1, + }; + + /* +-- +2.42.0 + diff --git a/queue-5.15/rdma-hfi1-use-field_get-to-extract-link-width.patch b/queue-5.15/rdma-hfi1-use-field_get-to-extract-link-width.patch new file mode 100644 index 00000000000..ee07fd71fdf --- /dev/null +++ b/queue-5.15/rdma-hfi1-use-field_get-to-extract-link-width.patch @@ -0,0 +1,63 @@ +From 5f5f2dd3275cd0626493bb2ddc21a308063e02da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 15:56:41 +0300 +Subject: RDMA/hfi1: Use FIELD_GET() to extract Link Width +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 8bf7187d978610b9e327a3d92728c8864a575ebd ] + +Use FIELD_GET() to extract PCIe Negotiated Link Width field instead of +custom masking and shifting, and remove extract_width() which only +wraps that FIELD_GET(). + +Signed-off-by: Ilpo Järvinen +Link: https://lore.kernel.org/r/20230919125648.1920-2-ilpo.jarvinen@linux.intel.com +Reviewed-by: Jonathan Cameron +Reviewed-by: Dean Luick +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/pcie.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c +index a0802332c8cb3..5395cf56fbd90 100644 +--- a/drivers/infiniband/hw/hfi1/pcie.c ++++ b/drivers/infiniband/hw/hfi1/pcie.c +@@ -3,6 +3,7 @@ + * Copyright(c) 2015 - 2019 Intel Corporation. + */ + ++#include + #include + #include + #include +@@ -212,12 +213,6 @@ static u32 extract_speed(u16 linkstat) + return speed; + } + +-/* return the PCIe link speed from the given link status */ +-static u32 extract_width(u16 linkstat) +-{ +- return (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; +-} +- + /* read the link status and set dd->{lbus_width,lbus_speed,lbus_info} */ + static void update_lbus_info(struct hfi1_devdata *dd) + { +@@ -230,7 +225,7 @@ static void update_lbus_info(struct hfi1_devdata *dd) + return; + } + +- dd->lbus_width = extract_width(linkstat); ++ dd->lbus_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat); + dd->lbus_speed = extract_speed(linkstat); + snprintf(dd->lbus_info, sizeof(dd->lbus_info), + "PCIe,%uMHz,x%u", dd->lbus_speed, dd->lbus_width); +-- +2.42.0 + diff --git a/queue-5.15/sched-core-optimize-in_task-and-in_interrupt-a-bit.patch b/queue-5.15/sched-core-optimize-in_task-and-in_interrupt-a-bit.patch new file mode 100644 index 00000000000..6cdd77634d1 --- /dev/null +++ b/queue-5.15/sched-core-optimize-in_task-and-in_interrupt-a-bit.patch @@ -0,0 +1,100 @@ +From b57e951012625f61d54bb21d21264ab5153ec081 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 15:47:11 +1000 +Subject: sched/core: Optimize in_task() and in_interrupt() a bit + +From: Finn Thain + +[ Upstream commit 87c3a5893e865739ce78aa7192d36011022e0af7 ] + +Except on x86, preempt_count is always accessed with READ_ONCE(). +Repeated invocations in macros like irq_count() produce repeated loads. +These redundant instructions appear in various fast paths. In the one +shown below, for example, irq_count() is evaluated during kernel entry +if !tick_nohz_full_cpu(smp_processor_id()). + +0001ed0a : + 1ed0a: 4e56 0000 linkw %fp,#0 + 1ed0e: 200f movel %sp,%d0 + 1ed10: 0280 ffff e000 andil #-8192,%d0 + 1ed16: 2040 moveal %d0,%a0 + 1ed18: 2028 0008 movel %a0@(8),%d0 + 1ed1c: 0680 0001 0000 addil #65536,%d0 + 1ed22: 2140 0008 movel %d0,%a0@(8) + 1ed26: 082a 0001 000f btst #1,%a2@(15) + 1ed2c: 670c beqs 1ed3a + 1ed2e: 2028 0008 movel %a0@(8),%d0 + 1ed32: 2028 0008 movel %a0@(8),%d0 + 1ed36: 2028 0008 movel %a0@(8),%d0 + 1ed3a: 4e5e unlk %fp + 1ed3c: 4e75 rts + +This patch doesn't prevent the pointless btst and beqs instructions +above, but it does eliminate 2 of the 3 pointless move instructions +here and elsewhere. + +On x86, preempt_count is per-cpu data and the problem does not arise +presumably because the compiler is free to optimize more effectively. + +This patch was tested on m68k and x86. I was expecting no changes +to object code for x86 and mostly that's what I saw. However, there +were a few places where code generation was perturbed for some reason. + +The performance issue addressed here is minor on uniprocessor m68k. I +got a 0.01% improvement from this patch for a simple "find /sys -false" +benchmark. For architectures and workloads susceptible to cache line bounce +the improvement is expected to be larger. The only SMP architecture I have +is x86, and as x86 unaffected I have not done any further measurements. + +Fixes: 15115830c887 ("preempt: Cleanup the macro maze a bit") +Signed-off-by: Finn Thain +Signed-off-by: Ingo Molnar +Link: https://lore.kernel.org/r/0a403120a682a525e6db2d81d1a3ffcc137c3742.1694756831.git.fthain@linux-m68k.org +Signed-off-by: Sasha Levin +--- + include/linux/preempt.h | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/include/linux/preempt.h b/include/linux/preempt.h +index b32e3dabe28bd..9c4534a69a8f7 100644 +--- a/include/linux/preempt.h ++++ b/include/linux/preempt.h +@@ -98,14 +98,21 @@ static __always_inline unsigned char interrupt_context_level(void) + return level; + } + ++/* ++ * These macro definitions avoid redundant invocations of preempt_count() ++ * because such invocations would result in redundant loads given that ++ * preempt_count() is commonly implemented with READ_ONCE(). ++ */ ++ + #define nmi_count() (preempt_count() & NMI_MASK) + #define hardirq_count() (preempt_count() & HARDIRQ_MASK) + #ifdef CONFIG_PREEMPT_RT + # define softirq_count() (current->softirq_disable_cnt & SOFTIRQ_MASK) ++# define irq_count() ((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) | softirq_count()) + #else + # define softirq_count() (preempt_count() & SOFTIRQ_MASK) ++# define irq_count() (preempt_count() & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK)) + #endif +-#define irq_count() (nmi_count() | hardirq_count() | softirq_count()) + + /* + * Macros to retrieve the current execution context: +@@ -118,7 +125,11 @@ static __always_inline unsigned char interrupt_context_level(void) + #define in_nmi() (nmi_count()) + #define in_hardirq() (hardirq_count()) + #define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) +-#define in_task() (!(in_nmi() | in_hardirq() | in_serving_softirq())) ++#ifdef CONFIG_PREEMPT_RT ++# define in_task() (!((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) | in_serving_softirq())) ++#else ++# define in_task() (!(preempt_count() & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) ++#endif + + /* + * The following macros are deprecated and should not be used in new code: +-- +2.42.0 + diff --git a/queue-5.15/scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch b/queue-5.15/scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch new file mode 100644 index 00000000000..5500cc0d6af --- /dev/null +++ b/queue-5.15/scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch @@ -0,0 +1,110 @@ +From 6937e9722db578585327a6e3f021678c575edcfa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 10:15:25 +0800 +Subject: scsi: hisi_sas: Set debugfs_dir pointer to NULL after removing + debugfs + +From: Yihang Li + +[ Upstream commit 6de426f9276c448e2db7238911c97fb157cb23be ] + +If init debugfs failed during device registration due to memory allocation +failure, debugfs_remove_recursive() is called, after which debugfs_dir is +not set to NULL. debugfs_remove_recursive() will be called again during +device removal. As a result, illegal pointer is accessed. + +[ 1665.467244] hisi_sas_v3_hw 0000:b4:02.0: failed to init debugfs! +... +[ 1669.836708] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a0 +[ 1669.872669] pc : down_write+0x24/0x70 +[ 1669.876315] lr : down_write+0x1c/0x70 +[ 1669.879961] sp : ffff000036f53a30 +[ 1669.883260] x29: ffff000036f53a30 x28: ffffa027c31549f8 +[ 1669.888547] x27: ffffa027c3140000 x26: 0000000000000000 +[ 1669.893834] x25: ffffa027bf37c270 x24: ffffa027bf37c270 +[ 1669.899122] x23: ffff0000095406b8 x22: ffff0000095406a8 +[ 1669.904408] x21: 0000000000000000 x20: ffffa027bf37c310 +[ 1669.909695] x19: 00000000000000a0 x18: ffff8027dcd86f10 +[ 1669.914982] x17: 0000000000000000 x16: 0000000000000000 +[ 1669.920268] x15: 0000000000000000 x14: ffffa0274014f870 +[ 1669.925555] x13: 0000000000000040 x12: 0000000000000228 +[ 1669.930842] x11: 0000000000000020 x10: 0000000000000bb0 +[ 1669.936129] x9 : ffff000036f537f0 x8 : ffff80273088ca10 +[ 1669.941416] x7 : 000000000000001d x6 : 00000000ffffffff +[ 1669.946702] x5 : ffff000008a36310 x4 : ffff80273088be00 +[ 1669.951989] x3 : ffff000009513e90 x2 : 0000000000000000 +[ 1669.957276] x1 : 00000000000000a0 x0 : ffffffff00000001 +[ 1669.962563] Call trace: +[ 1669.965000] down_write+0x24/0x70 +[ 1669.968301] debugfs_remove_recursive+0x5c/0x1b0 +[ 1669.972905] hisi_sas_debugfs_exit+0x24/0x30 [hisi_sas_main] +[ 1669.978541] hisi_sas_v3_remove+0x130/0x150 [hisi_sas_v3_hw] +[ 1669.984175] pci_device_remove+0x48/0xd8 +[ 1669.988082] device_release_driver_internal+0x1b4/0x250 +[ 1669.993282] device_release_driver+0x28/0x38 +[ 1669.997534] pci_stop_bus_device+0x84/0xb8 +[ 1670.001611] pci_stop_and_remove_bus_device_locked+0x24/0x40 +[ 1670.007244] remove_store+0xfc/0x140 +[ 1670.010802] dev_attr_store+0x44/0x60 +[ 1670.014448] sysfs_kf_write+0x58/0x80 +[ 1670.018095] kernfs_fop_write+0xe8/0x1f0 +[ 1670.022000] __vfs_write+0x60/0x190 +[ 1670.025472] vfs_write+0xac/0x1c0 +[ 1670.028771] ksys_write+0x6c/0xd8 +[ 1670.032071] __arm64_sys_write+0x24/0x30 +[ 1670.035977] el0_svc_common+0x78/0x130 +[ 1670.039710] el0_svc_handler+0x38/0x78 +[ 1670.043442] el0_svc+0x8/0xc + +To fix this, set debugfs_dir to NULL after debugfs_remove_recursive(). + +Signed-off-by: Yihang Li +Signed-off-by: Xingui Yang +Signed-off-by: Xiang Chen +Link: https://lore.kernel.org/r/1694571327-78697-2-git-send-email-chenxiang66@hisilicon.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index b8a12d3ad5f27..d1c07e7cb60df 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -4718,6 +4718,12 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba) + hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS; + } + ++static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ debugfs_remove_recursive(hisi_hba->debugfs_dir); ++ hisi_hba->debugfs_dir = NULL; ++} ++ + static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; +@@ -4741,18 +4747,13 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + + for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { + if (debugfs_alloc_v3_hw(hisi_hba, i)) { +- debugfs_remove_recursive(hisi_hba->debugfs_dir); ++ debugfs_exit_v3_hw(hisi_hba); + dev_dbg(dev, "failed to init debugfs!\n"); + break; + } + } + } + +-static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) +-{ +- debugfs_remove_recursive(hisi_hba->debugfs_dir); +-} +- + static int + hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { +-- +2.42.0 + diff --git a/queue-5.15/scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch b/queue-5.15/scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch new file mode 100644 index 00000000000..7d87a8eebbf --- /dev/null +++ b/queue-5.15/scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch @@ -0,0 +1,322 @@ +From 2291cf08098fb0874e759300b0ea46785cbf5351 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 17:54:25 -0500 +Subject: scsi: ibmvfc: Remove BUG_ON in the case of an empty event pool + +From: Tyrel Datwyler + +[ Upstream commit b39f2d10b86d0af353ea339e5815820026bca48f ] + +In practice the driver should never send more commands than are allocated +to a queue's event pool. In the unlikely event that this happens, the code +asserts a BUG_ON, and in the case that the kernel is not configured to +crash on panic returns a junk event pointer from the empty event list +causing things to spiral from there. This BUG_ON is a historical artifact +of the ibmvfc driver first being upstreamed, and it is well known now that +the use of BUG_ON is bad practice except in the most unrecoverable +scenario. There is nothing about this scenario that prevents the driver +from recovering and carrying on. + +Remove the BUG_ON in question from ibmvfc_get_event() and return a NULL +pointer in the case of an empty event pool. Update all call sites to +ibmvfc_get_event() to check for a NULL pointer and perfrom the appropriate +failure or recovery action. + +Signed-off-by: Tyrel Datwyler +Link: https://lore.kernel.org/r/20230921225435.3537728-2-tyreld@linux.ibm.com +Reviewed-by: Brian King +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ibmvscsi/ibmvfc.c | 124 ++++++++++++++++++++++++++++++++- + 1 file changed, 122 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c +index d169ba772450f..85444ca1ae21b 100644 +--- a/drivers/scsi/ibmvscsi/ibmvfc.c ++++ b/drivers/scsi/ibmvscsi/ibmvfc.c +@@ -1518,7 +1518,11 @@ static struct ibmvfc_event *ibmvfc_get_event(struct ibmvfc_queue *queue) + unsigned long flags; + + spin_lock_irqsave(&queue->l_lock, flags); +- BUG_ON(list_empty(&queue->free)); ++ if (list_empty(&queue->free)) { ++ ibmvfc_log(queue->vhost, 4, "empty event pool on queue:%ld\n", queue->hwq_id); ++ spin_unlock_irqrestore(&queue->l_lock, flags); ++ return NULL; ++ } + evt = list_entry(queue->free.next, struct ibmvfc_event, queue_list); + atomic_set(&evt->free, 0); + list_del(&evt->queue_list); +@@ -1947,9 +1951,15 @@ static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) + if (vhost->using_channels) { + scsi_channel = hwq % vhost->scsi_scrqs.active_queues; + evt = ibmvfc_get_event(&vhost->scsi_scrqs.scrqs[scsi_channel]); ++ if (!evt) ++ return SCSI_MLQUEUE_HOST_BUSY; ++ + evt->hwq = hwq % vhost->scsi_scrqs.active_queues; +- } else ++ } else { + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) ++ return SCSI_MLQUEUE_HOST_BUSY; ++ } + + ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT); + evt->cmnd = cmnd; +@@ -2037,6 +2047,11 @@ static int ibmvfc_bsg_timeout(struct bsg_job *job) + + vhost->aborting_passthru = 1; + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return -ENOMEM; ++ } ++ + ibmvfc_init_event(evt, ibmvfc_bsg_timeout_done, IBMVFC_MAD_FORMAT); + + tmf = &evt->iu.tmf; +@@ -2095,6 +2110,10 @@ static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id) + goto unlock_out; + + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ rc = -ENOMEM; ++ goto unlock_out; ++ } + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); + plogi = &evt->iu.plogi; + memset(plogi, 0, sizeof(*plogi)); +@@ -2213,6 +2232,11 @@ static int ibmvfc_bsg_request(struct bsg_job *job) + } + + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ rc = -ENOMEM; ++ goto out; ++ } + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); + mad = &evt->iu.passthru; + +@@ -2301,6 +2325,11 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) + else + evt = ibmvfc_get_event(&vhost->crq); + ++ if (!evt) { ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return -ENOMEM; ++ } ++ + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); + tmf = ibmvfc_init_vfc_cmd(evt, sdev); + iu = ibmvfc_get_fcp_iu(vhost, tmf); +@@ -2504,6 +2533,8 @@ static struct ibmvfc_event *ibmvfc_init_tmf(struct ibmvfc_queue *queue, + struct ibmvfc_tmf *tmf; + + evt = ibmvfc_get_event(queue); ++ if (!evt) ++ return NULL; + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); + + tmf = &evt->iu.tmf; +@@ -2560,6 +2591,11 @@ static int ibmvfc_cancel_all_mq(struct scsi_device *sdev, int type) + + if (found_evt && vhost->logged_in) { + evt = ibmvfc_init_tmf(&queues[i], sdev, type); ++ if (!evt) { ++ spin_unlock(queues[i].q_lock); ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return -ENOMEM; ++ } + evt->sync_iu = &queues[i].cancel_rsp; + ibmvfc_send_event(evt, vhost, default_timeout); + list_add_tail(&evt->cancel, &cancelq); +@@ -2773,6 +2809,10 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) + + if (vhost->state == IBMVFC_ACTIVE) { + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return -ENOMEM; ++ } + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); + tmf = ibmvfc_init_vfc_cmd(evt, sdev); + iu = ibmvfc_get_fcp_iu(vhost, tmf); +@@ -4029,6 +4069,12 @@ static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt) + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + ibmvfc_init_event(evt, ibmvfc_tgt_prli_done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; +@@ -4136,6 +4182,12 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt) + kref_get(&tgt->kref); + tgt->logo_rcvd = 0; + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + ibmvfc_init_event(evt, ibmvfc_tgt_plogi_done, IBMVFC_MAD_FORMAT); +@@ -4212,6 +4264,8 @@ static struct ibmvfc_event *__ibmvfc_tgt_get_implicit_logout_evt(struct ibmvfc_t + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) ++ return NULL; + ibmvfc_init_event(evt, done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; + mad = &evt->iu.implicit_logout; +@@ -4239,6 +4293,13 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) + vhost->discovery_threads++; + evt = __ibmvfc_tgt_get_implicit_logout_evt(tgt, + ibmvfc_tgt_implicit_logout_done); ++ if (!evt) { ++ vhost->discovery_threads--; ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + if (ibmvfc_send_event(evt, vhost, default_timeout)) { +@@ -4378,6 +4439,12 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *tgt) + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + ibmvfc_init_event(evt, ibmvfc_tgt_move_login_done, IBMVFC_MAD_FORMAT); +@@ -4544,6 +4611,14 @@ static void ibmvfc_adisc_timeout(struct timer_list *t) + vhost->abort_threads++; + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ tgt_err(tgt, "Failed to get cancel event for ADISC.\n"); ++ vhost->abort_threads--; ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return; ++ } + ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT); + + evt->tgt = tgt; +@@ -4594,6 +4669,12 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt) + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + ibmvfc_init_event(evt, ibmvfc_tgt_adisc_done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; +@@ -4697,6 +4778,12 @@ static void ibmvfc_tgt_query_target(struct ibmvfc_target *tgt) + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + evt->tgt = tgt; + ibmvfc_init_event(evt, ibmvfc_tgt_query_target_done, IBMVFC_MAD_FORMAT); +@@ -4869,6 +4956,13 @@ static void ibmvfc_discover_targets(struct ibmvfc_host *vhost) + { + struct ibmvfc_discover_targets *mad; + struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); ++ int level = IBMVFC_DEFAULT_LOG_LEVEL; ++ ++ if (!evt) { ++ ibmvfc_log(vhost, level, "Discover Targets failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } + + ibmvfc_init_event(evt, ibmvfc_discover_targets_done, IBMVFC_MAD_FORMAT); + mad = &evt->iu.discover_targets; +@@ -4946,8 +5040,15 @@ static void ibmvfc_channel_setup(struct ibmvfc_host *vhost) + struct ibmvfc_scsi_channels *scrqs = &vhost->scsi_scrqs; + unsigned int num_channels = + min(vhost->client_scsi_channels, vhost->max_vios_scsi_channels); ++ int level = IBMVFC_DEFAULT_LOG_LEVEL; + int i; + ++ if (!evt) { ++ ibmvfc_log(vhost, level, "Channel Setup failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } ++ + memset(setup_buf, 0, sizeof(*setup_buf)); + if (num_channels == 0) + setup_buf->flags = cpu_to_be32(IBMVFC_CANCEL_CHANNELS); +@@ -5009,6 +5110,13 @@ static void ibmvfc_channel_enquiry(struct ibmvfc_host *vhost) + { + struct ibmvfc_channel_enquiry *mad; + struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); ++ int level = IBMVFC_DEFAULT_LOG_LEVEL; ++ ++ if (!evt) { ++ ibmvfc_log(vhost, level, "Channel Enquiry failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } + + ibmvfc_init_event(evt, ibmvfc_channel_enquiry_done, IBMVFC_MAD_FORMAT); + mad = &evt->iu.channel_enquiry; +@@ -5131,6 +5239,12 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost) + struct ibmvfc_npiv_login_mad *mad; + struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); + ++ if (!evt) { ++ ibmvfc_dbg(vhost, "NPIV Login failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } ++ + ibmvfc_gather_partition_info(vhost); + ibmvfc_set_login_info(vhost); + ibmvfc_init_event(evt, ibmvfc_npiv_login_done, IBMVFC_MAD_FORMAT); +@@ -5195,6 +5309,12 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *vhost) + struct ibmvfc_event *evt; + + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_dbg(vhost, "NPIV Logout failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } ++ + ibmvfc_init_event(evt, ibmvfc_npiv_logout_done, IBMVFC_MAD_FORMAT); + + mad = &evt->iu.npiv_logout; +-- +2.42.0 + diff --git a/queue-5.15/scsi-libfc-fix-potential-null-pointer-dereference-in.patch b/queue-5.15/scsi-libfc-fix-potential-null-pointer-dereference-in.patch new file mode 100644 index 00000000000..aae90cedac1 --- /dev/null +++ b/queue-5.15/scsi-libfc-fix-potential-null-pointer-dereference-in.patch @@ -0,0 +1,44 @@ +From c6b23af05ef8e3fc73df1f4931a7cb5a92a7c083 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 21:03:50 +0800 +Subject: scsi: libfc: Fix potential NULL pointer dereference in + fc_lport_ptp_setup() + +From: Wenchao Hao + +[ Upstream commit 4df105f0ce9f6f30cda4e99f577150d23f0c9c5f ] + +fc_lport_ptp_setup() did not check the return value of fc_rport_create() +which can return NULL and would cause a NULL pointer dereference. Address +this issue by checking return value of fc_rport_create() and log error +message on fc_rport_create() failed. + +Signed-off-by: Wenchao Hao +Link: https://lore.kernel.org/r/20231011130350.819571-1-haowenchao2@huawei.com +Reviewed-by: Simon Horman +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/libfc/fc_lport.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c +index 19cd4a95d354d..d158c5eff059b 100644 +--- a/drivers/scsi/libfc/fc_lport.c ++++ b/drivers/scsi/libfc/fc_lport.c +@@ -241,6 +241,12 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, + } + mutex_lock(&lport->disc.disc_mutex); + lport->ptp_rdata = fc_rport_create(lport, remote_fid); ++ if (!lport->ptp_rdata) { ++ printk(KERN_WARNING "libfc: Failed to setup lport 0x%x\n", ++ lport->port_id); ++ mutex_unlock(&lport->disc.disc_mutex); ++ return; ++ } + kref_get(&lport->ptp_rdata->kref); + lport->ptp_rdata->ids.port_name = remote_wwpn; + lport->ptp_rdata->ids.node_name = remote_wwnn; +-- +2.42.0 + diff --git a/queue-5.15/selftests-efivarfs-create-read-fix-a-resource-leak.patch b/queue-5.15/selftests-efivarfs-create-read-fix-a-resource-leak.patch new file mode 100644 index 00000000000..ec7f97fd34f --- /dev/null +++ b/queue-5.15/selftests-efivarfs-create-read-fix-a-resource-leak.patch @@ -0,0 +1,37 @@ +From 4a1d9d51bc80600abd73112d2077ecbe4dbfa521 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 18:59:21 -0700 +Subject: selftests/efivarfs: create-read: fix a resource leak + +From: zhujun2 + +[ Upstream commit 3f6f8a8c5e11a9b384a36df4f40f0c9a653b6975 ] + +The opened file should be closed in main(), otherwise resource +leak will occur that this problem was discovered by code reading + +Signed-off-by: zhujun2 +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/efivarfs/create-read.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/testing/selftests/efivarfs/create-read.c b/tools/testing/selftests/efivarfs/create-read.c +index 9674a19396a32..7bc7af4eb2c17 100644 +--- a/tools/testing/selftests/efivarfs/create-read.c ++++ b/tools/testing/selftests/efivarfs/create-read.c +@@ -32,8 +32,10 @@ int main(int argc, char **argv) + rc = read(fd, buf, sizeof(buf)); + if (rc != 0) { + fprintf(stderr, "Reading a new var should return EOF\n"); ++ close(fd); + return EXIT_FAILURE; + } + ++ close(fd); + return EXIT_SUCCESS; + } +-- +2.42.0 + diff --git a/queue-5.15/series b/queue-5.15/series new file mode 100644 index 00000000000..06d3fb7d03e --- /dev/null +++ b/queue-5.15/series @@ -0,0 +1,160 @@ +locking-ww_mutex-test-fix-potential-workqueue-corrup.patch +perf-core-bail-out-early-if-the-request-aux-area-is-.patch +clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch +clocksource-drivers-timer-atmel-tcb-fix-initializati.patch +workqueue-provide-one-lock-class-key-per-work_on_cpu.patch +x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch +wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch +wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch +atl1c-work-around-the-dma-rx-overflow-issue.patch +bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch +wifi-ath9k-fix-clang-specific-fortify-warnings.patch +wifi-ath10k-fix-clang-specific-fortify-warning.patch +net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch +net-annotate-data-races-around-sk-sk_dst_pending_con.patch +wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch +bluetooth-btusb-add-date-evt_skb-is-null-check.patch +bluetooth-fix-double-free-in-hci_conn_cleanup.patch +platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch +drm-komeda-drop-all-currently-held-locks-if-deadlock.patch +drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch +drm-amd-display-use-full-update-for-clip-size-increa.patch +string.h-add-array-wrappers-for-v-memdup_user.patch +kernel-kexec-copy-user-array-safely.patch +kernel-watch_queue-copy-user-array-safely.patch +drm-vmwgfx_surface.c-copy-user-array-safely.patch +drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch +drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch +drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch +drm-amdgpu-fix-potential-null-pointer-derefernce.patch +drm-panel-fix-a-possible-null-pointer-dereference.patch +drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch +drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch +drm-panel-st7703-pick-different-reset-sequence.patch +drm-amdkfd-fix-shift-out-of-bounds-issue.patch +drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch +arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch +selftests-efivarfs-create-read-fix-a-resource-leak.patch +asoc-soc-card-add-storage-for-pci-ssid.patch +crypto-pcrypt-fix-hungtask-for-padata_reset.patch +rdma-hfi1-use-field_get-to-extract-link-width.patch +scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch +scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch +fs-jfs-add-check-for-negative-db_l2nbperpage.patch +fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch +jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch +jfs-fix-array-index-out-of-bounds-in-dialloc.patch +hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch +arm-9320-1-fix-stack-depot-irq-stack-filter.patch +alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch +pci-tegra194-use-field_get-field_prep-with-link-widt.patch +atm-iphase-do-pci-error-checks-on-own-line.patch +scsi-libfc-fix-potential-null-pointer-dereference-in.patch +pci-use-field_get-to-extract-link-width.patch +pci-extract-ats-disabling-to-a-helper-function.patch +pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch +misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch +pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch +hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch +exfat-support-handle-zero-size-directory.patch +tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch +usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch +9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch +9p-v9fs_listxattr-fix-s-null-argument-warning.patch +i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch +i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch +virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch +i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch +media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch +media-vivid-avoid-integer-overflow.patch +gfs2-ignore-negated-quota-changes.patch +gfs2-fix-an-oops-in-gfs2_permission.patch +media-cobalt-use-field_get-to-extract-link-width.patch +media-ccs-fix-driver-quirk-struct-documentation.patch +media-imon-fix-access-to-invalid-resource-for-the-se.patch +drm-amd-display-avoid-null-dereference-of-timing-gen.patch +kgdb-flush-console-before-entering-kgdb-on-panic.patch +i2c-dev-copy-userspace-array-safely.patch +asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch +drm-qxl-prevent-memory-leak.patch +drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch +pwm-fix-double-shift-bug.patch +wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch +tracing-reuse-logic-from-perf-s-get_recursion_contex.patch +tracing-perf-add-interrupt_context_level-helper.patch +sched-core-optimize-in_task-and-in_interrupt-a-bit.patch +media-rcar-vin-refactor-controls-creation-for-video-.patch +media-rcar-vin-improve-async-notifier-cleanup-paths.patch +media-rcar-vin-rename-array-storing-subdevice-inform.patch +media-rcar-vin-move-group-async-notifier.patch +media-v4l-async-rename-async-nf-functions-clean-up-l.patch +media-cadence-csi2rx-unregister-v4l2-async-notifier.patch +media-cec-meson-always-include-meson-sub-directory-i.patch +sunrpc-econnreset-might-require-a-rebind.patch +gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch +gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch +gpio-add-helpers-to-ease-the-transition-towards-immu.patch +sunrpc-add-an-is_err-check-back-to-where-it-was.patch +nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch +sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch +gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch +mptcp-diag-switch-to-context-structure.patch +mptcp-listen-diag-dump-support.patch +net-inet-remove-count-from-inet_listen_hashbucket.patch +net-inet-open-code-inet_hash2-and-inet_unhash2.patch +net-inet-retire-port-only-listening_hash.patch +net-set-sock_rcu_free-before-inserting-socket-into-h.patch +ipvlan-add-ipvlan_route_v6_outbound-helper.patch +tty-fix-uninit-value-access-in-ppp_sync_receive.patch +net-hns3-fix-add-vlan-fail-issue.patch +net-hns3-refine-the-definition-for-struct-hclge_pf_t.patch +net-hns3-add-byte-order-conversion-for-pf-to-vf-mail.patch +net-hns3-add-barrier-in-vf-mailbox-reply-process.patch +net-hns3-fix-incorrect-capability-bit-display-for-co.patch +net-hns3-fix-variable-may-not-initialized-problem-in.patch +net-hns3-fix-vf-reset-fail-issue.patch +net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch +tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch +ppp-limit-mru-to-64k.patch +xen-events-fix-delayed-eoi-list-handling.patch +ptp-annotate-data-race-around-q-head-and-q-tail.patch +bonding-stop-the-device-in-bond_setup_by_slave.patch +net-ethernet-cortina-fix-max-rx-frame-define.patch +net-ethernet-cortina-handle-large-frames.patch +net-ethernet-cortina-fix-mtu-max-setting.patch +af_unix-fix-use-after-free-in-unix_stream_read_actor.patch +netfilter-nf_conntrack_bridge-initialize-err-to-0.patch +netfilter-nf_tables-use-the-correct-get-put-helpers.patch +netfilter-nf_tables-add-and-use-be-register-load-sto.patch +netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch +net-stmmac-fix-rx-budget-limit-check.patch +net-mlx5e-fix-double-free-of-encap_header.patch +net-mlx5e-fix-double-free-of-encap_header-in-update-.patch +net-mlx5e-remove-incorrect-addition-of-action-fwd-fl.patch +net-mlx5e-move-mod-hdr-allocation-to-a-single-place.patch +net-mlx5e-refactor-mod-header-management-api.patch +net-mlx5e-fix-pedit-endianness.patch +net-mlx5e-reduce-the-size-of-icosq_str.patch +net-mlx5e-check-return-value-of-snprintf-writing-to-.patch +macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch +tools-power-turbostat-fix-a-knl-bug.patch +tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch +cifs-spnego-add-in-host_key_len.patch +cifs-fix-check-of-rc-in-function-generate_smb3signin.patch +xfs-refactor-buffer-cancellation-table-allocation.patch +xfs-don-t-leak-xfs_buf_cancel-structures-when-recove.patch +xfs-convert-buf_cancel_table-allocation-to-kmalloc_a.patch +xfs-use-invalidate_lock-to-check-the-state-of-mmap_l.patch +xfs-prevent-a-uaf-when-log-io-errors-race-with-unmou.patch +xfs-flush-inode-gc-workqueue-before-clearing-agi-buc.patch +xfs-fix-use-after-free-in-xattr-node-block-inactivat.patch +xfs-don-t-leak-memory-when-attr-fork-loading-fails.patch +xfs-fix-null-pointer-dereference-in-xfs_getbmap.patch +xfs-fix-intermittent-hang-during-quotacheck.patch +xfs-add-missing-cmap-br_state-xfs_ext_norm-update.patch +xfs-fix-false-enospc-when-performing-direct-write-on.patch +xfs-fix-inode-reservation-space-for-removing-transac.patch +xfs-avoid-a-uaf-when-log-intent-item-recovery-fails.patch +xfs-fix-exception-caused-by-unexpected-illegal-bestc.patch +xfs-fix-memory-leak-in-xfs_errortag_init.patch +xfs-fix-unreferenced-object-reported-by-kmemleak-in-.patch diff --git a/queue-5.15/string.h-add-array-wrappers-for-v-memdup_user.patch b/queue-5.15/string.h-add-array-wrappers-for-v-memdup_user.patch new file mode 100644 index 00000000000..4145120eb51 --- /dev/null +++ b/queue-5.15/string.h-add-array-wrappers-for-v-memdup_user.patch @@ -0,0 +1,94 @@ +From e1a1b2295ab6d3c2d7874b64ba48f4cefd279822 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:09 +0200 +Subject: string.h: add array-wrappers for (v)memdup_user() + +From: Philipp Stanner + +[ Upstream commit 313ebe47d75558511aa1237b6e35c663b5c0ec6f ] + +Currently, user array duplications are sometimes done without an +overflow check. Sometimes the checks are done manually; sometimes the +array size is calculated with array_size() and sometimes by calculating +n * size directly in code. + +Introduce wrappers for arrays for memdup_user() and vmemdup_user() to +provide a standardized and safe way for duplicating user arrays. + +This is both for new code as well as replacing usage of (v)memdup_user() +in existing code that uses, e.g., n * size to calculate array sizes. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Reviewed-by: Andy Shevchenko +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-3-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + include/linux/string.h | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/include/linux/string.h b/include/linux/string.h +index d68097b4f600b..3b9f5abe5ee83 100644 +--- a/include/linux/string.h ++++ b/include/linux/string.h +@@ -5,7 +5,9 @@ + #include /* for inline */ + #include /* for size_t */ + #include /* for NULL */ ++#include /* for ERR_PTR() */ + #include /* for E2BIG */ ++#include /* for check_mul_overflow() */ + #include + #include + +@@ -14,6 +16,44 @@ extern void *memdup_user(const void __user *, size_t); + extern void *vmemdup_user(const void __user *, size_t); + extern void *memdup_user_nul(const void __user *, size_t); + ++/** ++ * memdup_array_user - duplicate array from user space ++ * @src: source address in user space ++ * @n: number of array members to copy ++ * @size: size of one array member ++ * ++ * Return: an ERR_PTR() on failure. Result is physically ++ * contiguous, to be freed by kfree(). ++ */ ++static inline void *memdup_array_user(const void __user *src, size_t n, size_t size) ++{ ++ size_t nbytes; ++ ++ if (check_mul_overflow(n, size, &nbytes)) ++ return ERR_PTR(-EOVERFLOW); ++ ++ return memdup_user(src, nbytes); ++} ++ ++/** ++ * vmemdup_array_user - duplicate array from user space ++ * @src: source address in user space ++ * @n: number of array members to copy ++ * @size: size of one array member ++ * ++ * Return: an ERR_PTR() on failure. Result may be not ++ * physically contiguous. Use kvfree() to free. ++ */ ++static inline void *vmemdup_array_user(const void __user *src, size_t n, size_t size) ++{ ++ size_t nbytes; ++ ++ if (check_mul_overflow(n, size, &nbytes)) ++ return ERR_PTR(-EOVERFLOW); ++ ++ return vmemdup_user(src, nbytes); ++} ++ + /* + * Include machine specific inline routines + */ +-- +2.42.0 + diff --git a/queue-5.15/sunrpc-add-an-is_err-check-back-to-where-it-was.patch b/queue-5.15/sunrpc-add-an-is_err-check-back-to-where-it-was.patch new file mode 100644 index 00000000000..867f4d5a692 --- /dev/null +++ b/queue-5.15/sunrpc-add-an-is_err-check-back-to-where-it-was.patch @@ -0,0 +1,44 @@ +From f57d62ffb55d9cf1cecee20b13fc88f507c658d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 11:00:22 +0300 +Subject: SUNRPC: Add an IS_ERR() check back to where it was + +From: Dan Carpenter + +[ Upstream commit 4f3ed837186fc0d2722ba8d2457a594322e9c2ef ] + +This IS_ERR() check was deleted during in a cleanup because, at the time, +the rpcb_call_async() function could not return an error pointer. That +changed in commit 25cf32ad5dba ("SUNRPC: Handle allocation failure in +rpc_new_task()") and now it can return an error pointer. Put the check +back. + +A related revert was done in commit 13bd90141804 ("Revert "SUNRPC: +Remove unreachable error condition""). + +Fixes: 037e910b52b0 ("SUNRPC: Remove unreachable error condition in rpcb_getport_async()") +Signed-off-by: Dan Carpenter +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/rpcb_clnt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c +index 647b323cc1d56..638b14f28101e 100644 +--- a/net/sunrpc/rpcb_clnt.c ++++ b/net/sunrpc/rpcb_clnt.c +@@ -746,6 +746,10 @@ void rpcb_getport_async(struct rpc_task *task) + + child = rpcb_call_async(rpcb_clnt, map, proc); + rpc_release_client(rpcb_clnt); ++ if (IS_ERR(child)) { ++ /* rpcb_map_release() has freed the arguments */ ++ return; ++ } + + xprt->stat.bind_count++; + rpc_put_task(child); +-- +2.42.0 + diff --git a/queue-5.15/sunrpc-econnreset-might-require-a-rebind.patch b/queue-5.15/sunrpc-econnreset-might-require-a-rebind.patch new file mode 100644 index 00000000000..ef675d0552e --- /dev/null +++ b/queue-5.15/sunrpc-econnreset-might-require-a-rebind.patch @@ -0,0 +1,43 @@ +From f1b6196eae61740ec1f57512ce64ce558f2ffbce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 09:06:05 -0400 +Subject: SUNRPC: ECONNRESET might require a rebind + +From: Trond Myklebust + +[ Upstream commit 4b09ca1508a60be30b2e3940264e93d7aeb5c97e ] + +If connect() is returning ECONNRESET, it usually means that nothing is +listening on that port. If so, a rebind might be required in order to +obtain the new port on which the RPC service is listening. + +Fixes: fd01b2597941 ("SUNRPC: ECONNREFUSED should cause a rebind.") +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/clnt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 7756c62e0c3ed..fc37f314a09dd 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -2088,6 +2088,7 @@ call_connect_status(struct rpc_task *task) + task->tk_status = 0; + switch (status) { + case -ECONNREFUSED: ++ case -ECONNRESET: + /* A positive refusal suggests a rebind is needed. */ + if (RPC_IS_SOFTCONN(task)) + break; +@@ -2096,7 +2097,6 @@ call_connect_status(struct rpc_task *task) + goto out_retry; + } + fallthrough; +- case -ECONNRESET: + case -ECONNABORTED: + case -ENETDOWN: + case -ENETUNREACH: +-- +2.42.0 + diff --git a/queue-5.15/sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch b/queue-5.15/sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch new file mode 100644 index 00000000000..df49b509677 --- /dev/null +++ b/queue-5.15/sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch @@ -0,0 +1,121 @@ +From 913a7cfa91a74f48174c4127cb60bba36cd542c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 09:40:19 +0800 +Subject: SUNRPC: Fix RPC client cleaned up the freed pipefs dentries + +From: felix + +[ Upstream commit bfca5fb4e97c46503ddfc582335917b0cc228264 ] + +RPC client pipefs dentries cleanup is in separated rpc_remove_pipedir() +workqueue,which takes care about pipefs superblock locking. +In some special scenarios, when kernel frees the pipefs sb of the +current client and immediately alloctes a new pipefs sb, +rpc_remove_pipedir function would misjudge the existence of pipefs +sb which is not the one it used to hold. As a result, +the rpc_remove_pipedir would clean the released freed pipefs dentries. + +To fix this issue, rpc_remove_pipedir should check whether the +current pipefs sb is consistent with the original pipefs sb. + +This error can be catched by KASAN: +========================================================= +[ 250.497700] BUG: KASAN: slab-use-after-free in dget_parent+0x195/0x200 +[ 250.498315] Read of size 4 at addr ffff88800a2ab804 by task kworker/0:18/106503 +[ 250.500549] Workqueue: events rpc_free_client_work +[ 250.501001] Call Trace: +[ 250.502880] kasan_report+0xb6/0xf0 +[ 250.503209] ? dget_parent+0x195/0x200 +[ 250.503561] dget_parent+0x195/0x200 +[ 250.503897] ? __pfx_rpc_clntdir_depopulate+0x10/0x10 +[ 250.504384] rpc_rmdir_depopulate+0x1b/0x90 +[ 250.504781] rpc_remove_client_dir+0xf5/0x150 +[ 250.505195] rpc_free_client_work+0xe4/0x230 +[ 250.505598] process_one_work+0x8ee/0x13b0 +... +[ 22.039056] Allocated by task 244: +[ 22.039390] kasan_save_stack+0x22/0x50 +[ 22.039758] kasan_set_track+0x25/0x30 +[ 22.040109] __kasan_slab_alloc+0x59/0x70 +[ 22.040487] kmem_cache_alloc_lru+0xf0/0x240 +[ 22.040889] __d_alloc+0x31/0x8e0 +[ 22.041207] d_alloc+0x44/0x1f0 +[ 22.041514] __rpc_lookup_create_exclusive+0x11c/0x140 +[ 22.041987] rpc_mkdir_populate.constprop.0+0x5f/0x110 +[ 22.042459] rpc_create_client_dir+0x34/0x150 +[ 22.042874] rpc_setup_pipedir_sb+0x102/0x1c0 +[ 22.043284] rpc_client_register+0x136/0x4e0 +[ 22.043689] rpc_new_client+0x911/0x1020 +[ 22.044057] rpc_create_xprt+0xcb/0x370 +[ 22.044417] rpc_create+0x36b/0x6c0 +... +[ 22.049524] Freed by task 0: +[ 22.049803] kasan_save_stack+0x22/0x50 +[ 22.050165] kasan_set_track+0x25/0x30 +[ 22.050520] kasan_save_free_info+0x2b/0x50 +[ 22.050921] __kasan_slab_free+0x10e/0x1a0 +[ 22.051306] kmem_cache_free+0xa5/0x390 +[ 22.051667] rcu_core+0x62c/0x1930 +[ 22.051995] __do_softirq+0x165/0x52a +[ 22.052347] +[ 22.052503] Last potentially related work creation: +[ 22.052952] kasan_save_stack+0x22/0x50 +[ 22.053313] __kasan_record_aux_stack+0x8e/0xa0 +[ 22.053739] __call_rcu_common.constprop.0+0x6b/0x8b0 +[ 22.054209] dentry_free+0xb2/0x140 +[ 22.054540] __dentry_kill+0x3be/0x540 +[ 22.054900] shrink_dentry_list+0x199/0x510 +[ 22.055293] shrink_dcache_parent+0x190/0x240 +[ 22.055703] do_one_tree+0x11/0x40 +[ 22.056028] shrink_dcache_for_umount+0x61/0x140 +[ 22.056461] generic_shutdown_super+0x70/0x590 +[ 22.056879] kill_anon_super+0x3a/0x60 +[ 22.057234] rpc_kill_sb+0x121/0x200 + +Fixes: 0157d021d23a ("SUNRPC: handle RPC client pipefs dentries by network namespace aware routines") +Signed-off-by: felix +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/clnt.h | 1 + + net/sunrpc/clnt.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h +index 9fcf5ffc4f9ad..71ec22b1df860 100644 +--- a/include/linux/sunrpc/clnt.h ++++ b/include/linux/sunrpc/clnt.h +@@ -83,6 +83,7 @@ struct rpc_clnt { + }; + const struct cred *cl_cred; + unsigned int cl_max_connect; /* max number of transports not to the same IP */ ++ struct super_block *pipefs_sb; + }; + + /* +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index fc37f314a09dd..af1ca707c3d35 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -111,7 +111,8 @@ static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) + + pipefs_sb = rpc_get_sb_net(net); + if (pipefs_sb) { +- __rpc_clnt_remove_pipedir(clnt); ++ if (pipefs_sb == clnt->pipefs_sb) ++ __rpc_clnt_remove_pipedir(clnt); + rpc_put_sb_net(net); + } + } +@@ -151,6 +152,8 @@ rpc_setup_pipedir(struct super_block *pipefs_sb, struct rpc_clnt *clnt) + { + struct dentry *dentry; + ++ clnt->pipefs_sb = pipefs_sb; ++ + if (clnt->cl_program->pipe_dir_name != NULL) { + dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt); + if (IS_ERR(dentry)) +-- +2.42.0 + diff --git a/queue-5.15/tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch b/queue-5.15/tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch new file mode 100644 index 00000000000..2b6e6784181 --- /dev/null +++ b/queue-5.15/tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch @@ -0,0 +1,113 @@ +From 8cbef055ea6872a671ec059732be871ba1606db9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 11 Nov 2023 01:39:47 +0900 +Subject: tipc: Fix kernel-infoleak due to uninitialized TLV value + +From: Shigeru Yoshida + +[ Upstream commit fb317eb23b5ee4c37b0656a9a52a3db58d9dd072 ] + +KMSAN reported the following kernel-infoleak issue: + +===================================================== +BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:114 [inline] +BUG: KMSAN: kernel-infoleak in copy_to_user_iter lib/iov_iter.c:24 [inline] +BUG: KMSAN: kernel-infoleak in iterate_ubuf include/linux/iov_iter.h:29 [inline] +BUG: KMSAN: kernel-infoleak in iterate_and_advance2 include/linux/iov_iter.h:245 [inline] +BUG: KMSAN: kernel-infoleak in iterate_and_advance include/linux/iov_iter.h:271 [inline] +BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x4ec/0x2bc0 lib/iov_iter.c:186 + instrument_copy_to_user include/linux/instrumented.h:114 [inline] + copy_to_user_iter lib/iov_iter.c:24 [inline] + iterate_ubuf include/linux/iov_iter.h:29 [inline] + iterate_and_advance2 include/linux/iov_iter.h:245 [inline] + iterate_and_advance include/linux/iov_iter.h:271 [inline] + _copy_to_iter+0x4ec/0x2bc0 lib/iov_iter.c:186 + copy_to_iter include/linux/uio.h:197 [inline] + simple_copy_to_iter net/core/datagram.c:532 [inline] + __skb_datagram_iter.5+0x148/0xe30 net/core/datagram.c:420 + skb_copy_datagram_iter+0x52/0x210 net/core/datagram.c:546 + skb_copy_datagram_msg include/linux/skbuff.h:3960 [inline] + netlink_recvmsg+0x43d/0x1630 net/netlink/af_netlink.c:1967 + sock_recvmsg_nosec net/socket.c:1044 [inline] + sock_recvmsg net/socket.c:1066 [inline] + __sys_recvfrom+0x476/0x860 net/socket.c:2246 + __do_sys_recvfrom net/socket.c:2264 [inline] + __se_sys_recvfrom net/socket.c:2260 [inline] + __x64_sys_recvfrom+0x130/0x200 net/socket.c:2260 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Uninit was created at: + slab_post_alloc_hook+0x103/0x9e0 mm/slab.h:768 + slab_alloc_node mm/slub.c:3478 [inline] + kmem_cache_alloc_node+0x5f7/0xb50 mm/slub.c:3523 + kmalloc_reserve+0x13c/0x4a0 net/core/skbuff.c:560 + __alloc_skb+0x2fd/0x770 net/core/skbuff.c:651 + alloc_skb include/linux/skbuff.h:1286 [inline] + tipc_tlv_alloc net/tipc/netlink_compat.c:156 [inline] + tipc_get_err_tlv+0x90/0x5d0 net/tipc/netlink_compat.c:170 + tipc_nl_compat_recv+0x1042/0x15d0 net/tipc/netlink_compat.c:1324 + genl_family_rcv_msg_doit net/netlink/genetlink.c:972 [inline] + genl_family_rcv_msg net/netlink/genetlink.c:1052 [inline] + genl_rcv_msg+0x1220/0x12c0 net/netlink/genetlink.c:1067 + netlink_rcv_skb+0x4a4/0x6a0 net/netlink/af_netlink.c:2545 + genl_rcv+0x41/0x60 net/netlink/genetlink.c:1076 + netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline] + netlink_unicast+0xf4b/0x1230 net/netlink/af_netlink.c:1368 + netlink_sendmsg+0x1242/0x1420 net/netlink/af_netlink.c:1910 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg net/socket.c:745 [inline] + ____sys_sendmsg+0x997/0xd60 net/socket.c:2588 + ___sys_sendmsg+0x271/0x3b0 net/socket.c:2642 + __sys_sendmsg net/socket.c:2671 [inline] + __do_sys_sendmsg net/socket.c:2680 [inline] + __se_sys_sendmsg net/socket.c:2678 [inline] + __x64_sys_sendmsg+0x2fa/0x4a0 net/socket.c:2678 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Bytes 34-35 of 36 are uninitialized +Memory access of size 36 starts at ffff88802d464a00 +Data copied to user address 00007ff55033c0a0 + +CPU: 0 PID: 30322 Comm: syz-executor.0 Not tainted 6.6.0-14500-g1c41041124bd #10 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc38 04/01/2014 +===================================================== + +tipc_add_tlv() puts TLV descriptor and value onto `skb`. This size is +calculated with TLV_SPACE() macro. It adds the size of struct tlv_desc and +the length of TLV value passed as an argument, and aligns the result to a +multiple of TLV_ALIGNTO, i.e., a multiple of 4 bytes. + +If the size of struct tlv_desc plus the length of TLV value is not aligned, +the current implementation leaves the remaining bytes uninitialized. This +is the cause of the above kernel-infoleak issue. + +This patch resolves this issue by clearing data up to an aligned size. + +Fixes: d0796d1ef63d ("tipc: convert legacy nl bearer dump to nl compat") +Signed-off-by: Shigeru Yoshida +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/tipc/netlink_compat.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c +index ce00f271ca6b2..116a97e301443 100644 +--- a/net/tipc/netlink_compat.c ++++ b/net/tipc/netlink_compat.c +@@ -101,6 +101,7 @@ static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) + return -EMSGSIZE; + + skb_put(skb, TLV_SPACE(len)); ++ memset(tlv, 0, TLV_SPACE(len)); + tlv->tlv_type = htons(type); + tlv->tlv_len = htons(TLV_LENGTH(len)); + if (len && data) +-- +2.42.0 + diff --git a/queue-5.15/tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch b/queue-5.15/tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch new file mode 100644 index 00000000000..1dde607fc33 --- /dev/null +++ b/queue-5.15/tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch @@ -0,0 +1,36 @@ +From 0c7c7efbcb0cfbc8dc2c50ea34950f6c9fcb38fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Mar 2023 11:17:44 +0800 +Subject: tools/power/turbostat: Enable the C-state Pre-wake printing + +From: Chen Yu + +[ Upstream commit b61b7d8c4c22c4298a50ae5d0ee88facb85ce665 ] + +Currently the C-state Pre-wake will not be printed due to the +probe has not been invoked. Invoke the probe function accordingly. + +Fixes: aeb01e6d71ff ("tools/power turbostat: Print the C-state Pre-wake settings") +Signed-off-by: Chen Yu +Reviewed-by: Zhang Rui +Reviewed-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 045d0db88755f..65ada8065cfc2 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -5543,6 +5543,7 @@ void process_cpuid() + rapl_probe(family, model); + perf_limit_reasons_probe(family, model); + automatic_cstate_conversion_probe(family, model); ++ prewake_cstate_probe(family, model); + + check_tcc_offset(model_orig); + +-- +2.42.0 + diff --git a/queue-5.15/tools-power-turbostat-fix-a-knl-bug.patch b/queue-5.15/tools-power-turbostat-fix-a-knl-bug.patch new file mode 100644 index 00000000000..f2454ad1a92 --- /dev/null +++ b/queue-5.15/tools-power-turbostat-fix-a-knl-bug.patch @@ -0,0 +1,41 @@ +From 9e2cf5919614a3c48bb899e37a18d1ef2ce4a308 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Mar 2023 21:57:07 +0800 +Subject: tools/power/turbostat: Fix a knl bug + +From: Zhang Rui + +[ Upstream commit 137f01b3529d292a68d22e9681e2f903c768f790 ] + +MSR_KNL_CORE_C6_RESIDENCY should be evaluated only if +1. this is KNL platform +AND +2. need to get C6 residency or need to calculate C1 residency + +Fix the broken logic introduced by commit 1e9042b9c8d4 ("tools/power +turbostat: Fix CPU%C1 display value"). + +Fixes: 1e9042b9c8d4 ("tools/power turbostat: Fix CPU%C1 display value") +Signed-off-by: Zhang Rui +Reviewed-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index a3197efe52c63..045d0db88755f 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -2100,7 +2100,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) + if ((DO_BIC(BIC_CPU_c6) || soft_c1_residency_display(BIC_CPU_c6)) && !do_knl_cstates) { + if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) + return -7; +- } else if (do_knl_cstates || soft_c1_residency_display(BIC_CPU_c6)) { ++ } else if (do_knl_cstates && soft_c1_residency_display(BIC_CPU_c6)) { + if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6)) + return -7; + } +-- +2.42.0 + diff --git a/queue-5.15/tracing-perf-add-interrupt_context_level-helper.patch b/queue-5.15/tracing-perf-add-interrupt_context_level-helper.patch new file mode 100644 index 00000000000..20a3ec25a7c --- /dev/null +++ b/queue-5.15/tracing-perf-add-interrupt_context_level-helper.patch @@ -0,0 +1,117 @@ +From e22458140007d732fef998743ee5f9652da738b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Oct 2021 15:01:19 -0400 +Subject: tracing/perf: Add interrupt_context_level() helper + +From: Steven Rostedt (VMware) + +[ Upstream commit 91ebe8bcbff9d2ff21303e73bf7434f39a98b255 ] + +Now that there are three different instances of doing the addition trick +to the preempt_count() and NMI_MASK, HARDIRQ_MASK and SOFTIRQ_OFFSET +macros, it deserves a helper function defined in the preempt.h header. + +Add the interrupt_context_level() helper and replace the three instances +that do that logic with it. + +Link: https://lore.kernel.org/all/20211015142541.4badd8a9@gandalf.local.home/ + +Signed-off-by: Steven Rostedt (VMware) +Stable-dep-of: 87c3a5893e86 ("sched/core: Optimize in_task() and in_interrupt() a bit") +Signed-off-by: Sasha Levin +--- + include/linux/preempt.h | 21 +++++++++++++++++++++ + include/linux/trace_recursion.h | 7 +------ + kernel/events/internal.h | 7 +------ + kernel/trace/ring_buffer.c | 7 +------ + 4 files changed, 24 insertions(+), 18 deletions(-) + +diff --git a/include/linux/preempt.h b/include/linux/preempt.h +index 4d244e295e855..b32e3dabe28bd 100644 +--- a/include/linux/preempt.h ++++ b/include/linux/preempt.h +@@ -77,6 +77,27 @@ + /* preempt_count() and related functions, depends on PREEMPT_NEED_RESCHED */ + #include + ++/** ++ * interrupt_context_level - return interrupt context level ++ * ++ * Returns the current interrupt context level. ++ * 0 - normal context ++ * 1 - softirq context ++ * 2 - hardirq context ++ * 3 - NMI context ++ */ ++static __always_inline unsigned char interrupt_context_level(void) ++{ ++ unsigned long pc = preempt_count(); ++ unsigned char level = 0; ++ ++ level += !!(pc & (NMI_MASK)); ++ level += !!(pc & (NMI_MASK | HARDIRQ_MASK)); ++ level += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)); ++ ++ return level; ++} ++ + #define nmi_count() (preempt_count() & NMI_MASK) + #define hardirq_count() (preempt_count() & HARDIRQ_MASK) + #ifdef CONFIG_PREEMPT_RT +diff --git a/include/linux/trace_recursion.h b/include/linux/trace_recursion.h +index 00acd7dca7a7d..816d7a0d2aad6 100644 +--- a/include/linux/trace_recursion.h ++++ b/include/linux/trace_recursion.h +@@ -116,12 +116,7 @@ enum { + + static __always_inline int trace_get_context_bit(void) + { +- unsigned long pc = preempt_count(); +- unsigned char bit = 0; +- +- bit += !!(pc & (NMI_MASK)); +- bit += !!(pc & (NMI_MASK | HARDIRQ_MASK)); +- bit += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)); ++ unsigned char bit = interrupt_context_level(); + + return TRACE_CTX_NORMAL - bit; + } +diff --git a/kernel/events/internal.h b/kernel/events/internal.h +index aa23ffdaf819f..5150d5f84c033 100644 +--- a/kernel/events/internal.h ++++ b/kernel/events/internal.h +@@ -210,12 +210,7 @@ DEFINE_OUTPUT_COPY(__output_copy_user, arch_perf_out_copy_user) + + static inline int get_recursion_context(int *recursion) + { +- unsigned int pc = preempt_count(); +- unsigned char rctx = 0; +- +- rctx += !!(pc & (NMI_MASK)); +- rctx += !!(pc & (NMI_MASK | HARDIRQ_MASK)); +- rctx += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)); ++ unsigned char rctx = interrupt_context_level(); + + if (recursion[rctx]) + return -1; +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index c3c9960c9f27b..a930a9d7d834d 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -3249,12 +3249,7 @@ static __always_inline int + trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) + { + unsigned int val = cpu_buffer->current_context; +- unsigned long pc = preempt_count(); +- int bit = 0; +- +- bit += !!(pc & (NMI_MASK)); +- bit += !!(pc & (NMI_MASK | HARDIRQ_MASK)); +- bit += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)); ++ int bit = interrupt_context_level(); + + bit = RB_CTX_NORMAL - bit; + +-- +2.42.0 + diff --git a/queue-5.15/tracing-reuse-logic-from-perf-s-get_recursion_contex.patch b/queue-5.15/tracing-reuse-logic-from-perf-s-get_recursion_contex.patch new file mode 100644 index 00000000000..63e532e01ee --- /dev/null +++ b/queue-5.15/tracing-reuse-logic-from-perf-s-get_recursion_contex.patch @@ -0,0 +1,75 @@ +From 8cb02f2bcd2b069555e2d48c61a3a565d308b512 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Oct 2021 13:42:40 -0400 +Subject: tracing: Reuse logic from perf's get_recursion_context() + +From: Steven Rostedt (VMware) + +[ Upstream commit 9b84fadc444de5456ab5f5487e2108311c724c3f ] + +Instead of having branches that adds noise to the branch prediction, use +the addition logic to set the bit for the level of interrupt context that +the state is currently in. This copies the logic from perf's +get_recursion_context() function. + +Link: https://lore.kernel.org/all/20211015161702.GF174703@worktop.programming.kicks-ass.net/ + +Suggested-by: Peter Zijlstra +Signed-off-by: Steven Rostedt (VMware) +Stable-dep-of: 87c3a5893e86 ("sched/core: Optimize in_task() and in_interrupt() a bit") +Signed-off-by: Sasha Levin +--- + include/linux/trace_recursion.h | 11 ++++++----- + kernel/trace/ring_buffer.c | 12 ++++++------ + 2 files changed, 12 insertions(+), 11 deletions(-) + +diff --git a/include/linux/trace_recursion.h b/include/linux/trace_recursion.h +index fe95f09225266..00acd7dca7a7d 100644 +--- a/include/linux/trace_recursion.h ++++ b/include/linux/trace_recursion.h +@@ -117,12 +117,13 @@ enum { + static __always_inline int trace_get_context_bit(void) + { + unsigned long pc = preempt_count(); ++ unsigned char bit = 0; + +- if (!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) +- return TRACE_CTX_NORMAL; +- else +- return pc & NMI_MASK ? TRACE_CTX_NMI : +- pc & HARDIRQ_MASK ? TRACE_CTX_IRQ : TRACE_CTX_SOFTIRQ; ++ bit += !!(pc & (NMI_MASK)); ++ bit += !!(pc & (NMI_MASK | HARDIRQ_MASK)); ++ bit += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)); ++ ++ return TRACE_CTX_NORMAL - bit; + } + + #ifdef CONFIG_FTRACE_RECORD_RECURSION +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index e5dc7b5a261c6..c3c9960c9f27b 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -3250,13 +3250,13 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) + { + unsigned int val = cpu_buffer->current_context; + unsigned long pc = preempt_count(); +- int bit; ++ int bit = 0; + +- if (!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) +- bit = RB_CTX_NORMAL; +- else +- bit = pc & NMI_MASK ? RB_CTX_NMI : +- pc & HARDIRQ_MASK ? RB_CTX_IRQ : RB_CTX_SOFTIRQ; ++ bit += !!(pc & (NMI_MASK)); ++ bit += !!(pc & (NMI_MASK | HARDIRQ_MASK)); ++ bit += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)); ++ ++ bit = RB_CTX_NORMAL - bit; + + if (unlikely(val & (1 << (bit + cpu_buffer->nest)))) { + /* +-- +2.42.0 + diff --git a/queue-5.15/tty-fix-uninit-value-access-in-ppp_sync_receive.patch b/queue-5.15/tty-fix-uninit-value-access-in-ppp_sync_receive.patch new file mode 100644 index 00000000000..1f6075929e2 --- /dev/null +++ b/queue-5.15/tty-fix-uninit-value-access-in-ppp_sync_receive.patch @@ -0,0 +1,82 @@ +From 44ececf32c0b425d909c81ff3b7c69ac2c9621ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 00:44:20 +0900 +Subject: tty: Fix uninit-value access in ppp_sync_receive() + +From: Shigeru Yoshida + +[ Upstream commit 719639853d88071dfdfd8d9971eca9c283ff314c ] + +KMSAN reported the following uninit-value access issue: + +===================================================== +BUG: KMSAN: uninit-value in ppp_sync_input drivers/net/ppp/ppp_synctty.c:690 [inline] +BUG: KMSAN: uninit-value in ppp_sync_receive+0xdc9/0xe70 drivers/net/ppp/ppp_synctty.c:334 + ppp_sync_input drivers/net/ppp/ppp_synctty.c:690 [inline] + ppp_sync_receive+0xdc9/0xe70 drivers/net/ppp/ppp_synctty.c:334 + tiocsti+0x328/0x450 drivers/tty/tty_io.c:2295 + tty_ioctl+0x808/0x1920 drivers/tty/tty_io.c:2694 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:871 [inline] + __se_sys_ioctl+0x211/0x400 fs/ioctl.c:857 + __x64_sys_ioctl+0x97/0xe0 fs/ioctl.c:857 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Uninit was created at: + __alloc_pages+0x75d/0xe80 mm/page_alloc.c:4591 + __alloc_pages_node include/linux/gfp.h:238 [inline] + alloc_pages_node include/linux/gfp.h:261 [inline] + __page_frag_cache_refill+0x9a/0x2c0 mm/page_alloc.c:4691 + page_frag_alloc_align+0x91/0x5d0 mm/page_alloc.c:4722 + page_frag_alloc include/linux/gfp.h:322 [inline] + __netdev_alloc_skb+0x215/0x6d0 net/core/skbuff.c:728 + netdev_alloc_skb include/linux/skbuff.h:3225 [inline] + dev_alloc_skb include/linux/skbuff.h:3238 [inline] + ppp_sync_input drivers/net/ppp/ppp_synctty.c:669 [inline] + ppp_sync_receive+0x237/0xe70 drivers/net/ppp/ppp_synctty.c:334 + tiocsti+0x328/0x450 drivers/tty/tty_io.c:2295 + tty_ioctl+0x808/0x1920 drivers/tty/tty_io.c:2694 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:871 [inline] + __se_sys_ioctl+0x211/0x400 fs/ioctl.c:857 + __x64_sys_ioctl+0x97/0xe0 fs/ioctl.c:857 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +CPU: 0 PID: 12950 Comm: syz-executor.1 Not tainted 6.6.0-14500-g1c41041124bd #10 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc38 04/01/2014 +===================================================== + +ppp_sync_input() checks the first 2 bytes of the data are PPP_ALLSTATIONS +and PPP_UI. However, if the data length is 1 and the first byte is +PPP_ALLSTATIONS, an access to an uninitialized value occurs when checking +PPP_UI. This patch resolves this issue by checking the data length. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Shigeru Yoshida +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ppp/ppp_synctty.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c +index af3e048695b66..e37faed81937f 100644 +--- a/drivers/net/ppp/ppp_synctty.c ++++ b/drivers/net/ppp/ppp_synctty.c +@@ -699,7 +699,7 @@ ppp_sync_input(struct syncppp *ap, const unsigned char *buf, + + /* strip address/control field if present */ + p = skb->data; +- if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { ++ if (skb->len >= 2 && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { + /* chop off address/control */ + if (skb->len < 3) + goto err; +-- +2.42.0 + diff --git a/queue-5.15/tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch b/queue-5.15/tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch new file mode 100644 index 00000000000..f9d3b1d6127 --- /dev/null +++ b/queue-5.15/tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch @@ -0,0 +1,76 @@ +From 55ce60daef092b89e8718c65ede834c30658dc94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 11:52:20 +0800 +Subject: tty: vcc: Add check for kstrdup() in vcc_probe() + +From: Yi Yang + +[ Upstream commit d81ffb87aaa75f842cd7aa57091810353755b3e6 ] + +Add check for the return value of kstrdup() and return the error, if it +fails in order to avoid NULL pointer dereference. + +Signed-off-by: Yi Yang +Reviewed-by: Jiri Slaby +Link: https://lore.kernel.org/r/20230904035220.48164-1-yiyang13@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/vcc.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c +index e11383ae1e7e3..71356d9684bac 100644 +--- a/drivers/tty/vcc.c ++++ b/drivers/tty/vcc.c +@@ -578,18 +578,22 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) + return -ENOMEM; + + name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL); ++ if (!name) { ++ rv = -ENOMEM; ++ goto free_port; ++ } + + rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions, + ARRAY_SIZE(vcc_versions), NULL, name); + if (rv) +- goto free_port; ++ goto free_name; + + port->vio.debug = vcc_dbg_vio; + vcc_ldc_cfg.debug = vcc_dbg_ldc; + + rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port); + if (rv) +- goto free_port; ++ goto free_name; + + spin_lock_init(&port->lock); + +@@ -623,6 +627,11 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) + goto unreg_tty; + } + port->domain = kstrdup(domain, GFP_KERNEL); ++ if (!port->domain) { ++ rv = -ENOMEM; ++ goto unreg_tty; ++ } ++ + + mdesc_release(hp); + +@@ -652,8 +661,9 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) + vcc_table_remove(port->index); + free_ldc: + vio_ldc_free(&port->vio); +-free_port: ++free_name: + kfree(name); ++free_port: + kfree(port); + + return rv; +-- +2.42.0 + diff --git a/queue-5.15/usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch b/queue-5.15/usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch new file mode 100644 index 00000000000..e72e9883fb5 --- /dev/null +++ b/queue-5.15/usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch @@ -0,0 +1,137 @@ +From 615c486ba05c8439dac87f1961c079e242726627 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 17:33:24 +0200 +Subject: usb: gadget: f_ncm: Always set current gadget in ncm_bind() + +From: Hardik Gajjar + +[ Upstream commit a04224da1f3424b2c607b12a3bd1f0e302fb8231 ] + +Previously, gadget assignment to the net device occurred exclusively +during the initial binding attempt. + +Nevertheless, the gadget pointer could change during bind/unbind +cycles due to various conditions, including the unloading/loading +of the UDC device driver or the detachment/reconnection of an +OTG-capable USB hub device. + +This patch relocates the gether_set_gadget() function out from +ncm_opts->bound condition check, ensuring that the correct gadget +is assigned during each bind request. + +The provided logs demonstrate the consistency of ncm_opts throughout +the power cycle, while the gadget may change. + +* OTG hub connected during boot up and assignment of gadget and + ncm_opts pointer + +[ 2.366301] usb 2-1.5: New USB device found, idVendor=2996, idProduct=0105 +[ 2.366304] usb 2-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[ 2.366306] usb 2-1.5: Product: H2H Bridge +[ 2.366308] usb 2-1.5: Manufacturer: Aptiv +[ 2.366309] usb 2-1.5: SerialNumber: 13FEB2021 +[ 2.427989] usb 2-1.5: New USB device found, VID=2996, PID=0105 +[ 2.428959] dabridge 2-1.5:1.0: dabridge 2-4 total endpoints=5, 0000000093a8d681 +[ 2.429710] dabridge 2-1.5:1.0: P(0105) D(22.06.22) F(17.3.16) H(1.1) high-speed +[ 2.429714] dabridge 2-1.5:1.0: Hub 2-2 P(0151) V(06.87) +[ 2.429956] dabridge 2-1.5:1.0: All downstream ports in host mode + +[ 2.430093] gadget 000000003c414d59 ------> gadget pointer + +* NCM opts and associated gadget pointer during First ncm_bind + +[ 34.763929] NCM opts 00000000aa304ac9 +[ 34.763930] NCM gadget 000000003c414d59 + +* OTG capable hub disconnecte or assume driver unload. + +[ 97.203114] usb 2-1: USB disconnect, device number 2 +[ 97.203118] usb 2-1.1: USB disconnect, device number 3 +[ 97.209217] usb 2-1.5: USB disconnect, device number 4 +[ 97.230990] dabr_udc deleted + +* Reconnect the OTG hub or load driver assaign new gadget pointer. + +[ 111.534035] usb 2-1.1: New USB device found, idVendor=2996, idProduct=0120, bcdDevice= 6.87 +[ 111.534038] usb 2-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[ 111.534040] usb 2-1.1: Product: Vendor +[ 111.534041] usb 2-1.1: Manufacturer: Aptiv +[ 111.534042] usb 2-1.1: SerialNumber: Superior +[ 111.535175] usb 2-1.1: New USB device found, VID=2996, PID=0120 +[ 111.610995] usb 2-1.5: new high-speed USB device number 8 using xhci-hcd +[ 111.630052] usb 2-1.5: New USB device found, idVendor=2996, idProduct=0105, bcdDevice=21.02 +[ 111.630055] usb 2-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[ 111.630057] usb 2-1.5: Product: H2H Bridge +[ 111.630058] usb 2-1.5: Manufacturer: Aptiv +[ 111.630059] usb 2-1.5: SerialNumber: 13FEB2021 +[ 111.687464] usb 2-1.5: New USB device found, VID=2996, PID=0105 +[ 111.690375] dabridge 2-1.5:1.0: dabridge 2-8 total endpoints=5, 000000000d87c961 +[ 111.691172] dabridge 2-1.5:1.0: P(0105) D(22.06.22) F(17.3.16) H(1.1) high-speed +[ 111.691176] dabridge 2-1.5:1.0: Hub 2-6 P(0151) V(06.87) +[ 111.691646] dabridge 2-1.5:1.0: All downstream ports in host mode + +[ 111.692298] gadget 00000000dc72f7a9 --------> new gadget ptr on connect + +* NCM opts and associated gadget pointer during second ncm_bind + +[ 113.271786] NCM opts 00000000aa304ac9 -----> same opts ptr used during first bind +[ 113.271788] NCM gadget 00000000dc72f7a9 ----> however new gaget ptr, that will not set + in net_device due to ncm_opts->bound = true + +Signed-off-by: Hardik Gajjar +Link: https://lore.kernel.org/r/20231020153324.82794-1-hgajjar@de.adit-jv.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/function/f_ncm.c | 27 +++++++++++---------------- + 1 file changed, 11 insertions(+), 16 deletions(-) + +diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c +index aabaedb2e0691..bd095ae569edd 100644 +--- a/drivers/usb/gadget/function/f_ncm.c ++++ b/drivers/usb/gadget/function/f_ncm.c +@@ -1429,7 +1429,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) + struct usb_composite_dev *cdev = c->cdev; + struct f_ncm *ncm = func_to_ncm(f); + struct usb_string *us; +- int status; ++ int status = 0; + struct usb_ep *ep; + struct f_ncm_opts *ncm_opts; + +@@ -1447,22 +1447,17 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) + f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; + } + +- /* +- * in drivers/usb/gadget/configfs.c:configfs_composite_bind() +- * configurations are bound in sequence with list_for_each_entry, +- * in each configuration its functions are bound in sequence +- * with list_for_each_entry, so we assume no race condition +- * with regard to ncm_opts->bound access +- */ +- if (!ncm_opts->bound) { +- mutex_lock(&ncm_opts->lock); +- gether_set_gadget(ncm_opts->net, cdev->gadget); ++ mutex_lock(&ncm_opts->lock); ++ gether_set_gadget(ncm_opts->net, cdev->gadget); ++ if (!ncm_opts->bound) + status = gether_register_netdev(ncm_opts->net); +- mutex_unlock(&ncm_opts->lock); +- if (status) +- goto fail; +- ncm_opts->bound = true; +- } ++ mutex_unlock(&ncm_opts->lock); ++ ++ if (status) ++ goto fail; ++ ++ ncm_opts->bound = true; ++ + us = usb_gstrings_attach(cdev, ncm_strings, + ARRAY_SIZE(ncm_string_defs)); + if (IS_ERR(us)) { +-- +2.42.0 + diff --git a/queue-5.15/virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch b/queue-5.15/virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch new file mode 100644 index 00000000000..5f7c1bd831a --- /dev/null +++ b/queue-5.15/virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch @@ -0,0 +1,49 @@ +From bca31ff5bc45b85b2081a424b1095dd57cef0f18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 14:10:45 +0800 +Subject: virtio-blk: fix implicit overflow on virtio_max_dma_size + +From: zhenwei pi + +[ Upstream commit fafb51a67fb883eb2dde352539df939a251851be ] + +The following codes have an implicit conversion from size_t to u32: +(u32)max_size = (size_t)virtio_max_dma_size(vdev); + +This may lead overflow, Ex (size_t)4G -> (u32)0. Once +virtio_max_dma_size() has a larger size than U32_MAX, use U32_MAX +instead. + +Signed-off-by: zhenwei pi +Message-Id: <20230904061045.510460-1-pizhenwei@bytedance.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/block/virtio_blk.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index d2ba849bb8d19..affeca0dbc7ea 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -743,6 +743,7 @@ static int virtblk_probe(struct virtio_device *vdev) + u16 min_io_size; + u8 physical_block_exp, alignment_offset; + unsigned int queue_depth; ++ size_t max_dma_size; + + if (!vdev->config->get) { + dev_err(&vdev->dev, "%s failure: config access disabled\n", +@@ -844,7 +845,8 @@ static int virtblk_probe(struct virtio_device *vdev) + /* No real sector limit. */ + blk_queue_max_hw_sectors(q, -1U); + +- max_size = virtio_max_dma_size(vdev); ++ max_dma_size = virtio_max_dma_size(vdev); ++ max_size = max_dma_size > U32_MAX ? U32_MAX : max_dma_size; + + /* Host can optionally specify maximum segment size and number of + * segments. */ +-- +2.42.0 + diff --git a/queue-5.15/wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch b/queue-5.15/wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch new file mode 100644 index 00000000000..064ace6e2e2 --- /dev/null +++ b/queue-5.15/wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch @@ -0,0 +1,122 @@ +From 279118aa8f0ce9f710ab38a6a639c9d671ea6ac7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Sep 2023 07:54:48 +0300 +Subject: wifi: ath10k: Don't touch the CE interrupt registers after power up + +From: Douglas Anderson + +[ Upstream commit 170c75d43a77dc937c58f07ecf847ba1b42ab74e ] + +As talked about in commit d66d24ac300c ("ath10k: Keep track of which +interrupts fired, don't poll them"), if we access the copy engine +register at a bad time then ath10k can go boom. However, it's not +necessarily easy to know when it's safe to access them. + +The ChromeOS test labs saw a crash that looked like this at +shutdown/reboot time (on a chromeos-5.15 kernel, but likely the +problem could also reproduce upstream): + +Internal error: synchronous external abort: 96000010 [#1] PREEMPT SMP +... +CPU: 4 PID: 6168 Comm: reboot Not tainted 5.15.111-lockdep-19350-g1d624fe6758f #1 010b9b233ab055c27c6dc88efb0be2f4e9e86f51 +Hardware name: Google Kingoftown (DT) +... +pc : ath10k_snoc_read32+0x50/0x74 [ath10k_snoc] +lr : ath10k_snoc_read32+0x24/0x74 [ath10k_snoc] +... +Call trace: +ath10k_snoc_read32+0x50/0x74 [ath10k_snoc ...] +ath10k_ce_disable_interrupt+0x190/0x65c [ath10k_core ...] +ath10k_ce_disable_interrupts+0x8c/0x120 [ath10k_core ...] +ath10k_snoc_hif_stop+0x78/0x660 [ath10k_snoc ...] +ath10k_core_stop+0x13c/0x1ec [ath10k_core ...] +ath10k_halt+0x398/0x5b0 [ath10k_core ...] +ath10k_stop+0xfc/0x1a8 [ath10k_core ...] +drv_stop+0x148/0x6b4 [mac80211 ...] +ieee80211_stop_device+0x70/0x80 [mac80211 ...] +ieee80211_do_stop+0x10d8/0x15b0 [mac80211 ...] +ieee80211_stop+0x144/0x1a0 [mac80211 ...] +__dev_close_many+0x1e8/0x2c0 +dev_close_many+0x198/0x33c +dev_close+0x140/0x210 +cfg80211_shutdown_all_interfaces+0xc8/0x1e0 [cfg80211 ...] +ieee80211_remove_interfaces+0x118/0x5c4 [mac80211 ...] +ieee80211_unregister_hw+0x64/0x1f4 [mac80211 ...] +ath10k_mac_unregister+0x4c/0xf0 [ath10k_core ...] +ath10k_core_unregister+0x80/0xb0 [ath10k_core ...] +ath10k_snoc_free_resources+0xb8/0x1ec [ath10k_snoc ...] +ath10k_snoc_shutdown+0x98/0xd0 [ath10k_snoc ...] +platform_shutdown+0x7c/0xa0 +device_shutdown+0x3e0/0x58c +kernel_restart_prepare+0x68/0xa0 +kernel_restart+0x28/0x7c + +Though there's no known way to reproduce the problem, it makes sense +that it would be the same issue where we're trying to access copy +engine registers when it's not allowed. + +Let's fix this by changing how we "disable" the interrupts. Instead of +tweaking the copy engine registers we'll just use disable_irq() and +enable_irq(). Then we'll configure the interrupts once at power up +time. + +Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1 + +Signed-off-by: Douglas Anderson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230630151842.1.If764ede23c4e09a43a842771c2ddf99608f25f8e@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/snoc.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c +index 73fe77e7824b4..439df8a404d86 100644 +--- a/drivers/net/wireless/ath/ath10k/snoc.c ++++ b/drivers/net/wireless/ath/ath10k/snoc.c +@@ -828,12 +828,20 @@ static void ath10k_snoc_hif_get_default_pipe(struct ath10k *ar, + + static inline void ath10k_snoc_irq_disable(struct ath10k *ar) + { +- ath10k_ce_disable_interrupts(ar); ++ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); ++ int id; ++ ++ for (id = 0; id < CE_COUNT_MAX; id++) ++ disable_irq(ar_snoc->ce_irqs[id].irq_line); + } + + static inline void ath10k_snoc_irq_enable(struct ath10k *ar) + { +- ath10k_ce_enable_interrupts(ar); ++ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); ++ int id; ++ ++ for (id = 0; id < CE_COUNT_MAX; id++) ++ enable_irq(ar_snoc->ce_irqs[id].irq_line); + } + + static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe) +@@ -1089,6 +1097,8 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar, + goto err_free_rri; + } + ++ ath10k_ce_enable_interrupts(ar); ++ + return 0; + + err_free_rri: +@@ -1253,8 +1263,8 @@ static int ath10k_snoc_request_irq(struct ath10k *ar) + + for (id = 0; id < CE_COUNT_MAX; id++) { + ret = request_irq(ar_snoc->ce_irqs[id].irq_line, +- ath10k_snoc_per_engine_handler, 0, +- ce_name[id], ar); ++ ath10k_snoc_per_engine_handler, ++ IRQF_NO_AUTOEN, ce_name[id], ar); + if (ret) { + ath10k_err(ar, + "failed to register IRQ handler for CE %d: %d\n", +-- +2.42.0 + diff --git a/queue-5.15/wifi-ath10k-fix-clang-specific-fortify-warning.patch b/queue-5.15/wifi-ath10k-fix-clang-specific-fortify-warning.patch new file mode 100644 index 00000000000..fe456dd3bab --- /dev/null +++ b/queue-5.15/wifi-ath10k-fix-clang-specific-fortify-warning.patch @@ -0,0 +1,62 @@ +From cd31bfeb156c15f58c251d3ae65ce4de209bb31d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 12:36:02 +0300 +Subject: wifi: ath10k: fix clang-specific fortify warning + +From: Dmitry Antipov + +[ Upstream commit cb4c132ebfeac5962f7258ffc831caa0c4dada1a ] + +When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've +noticed the following (somewhat confusing due to absence of an actual +source code location): + +In file included from drivers/net/wireless/ath/ath10k/debug.c:8: +In file included from ./include/linux/module.h:13: +In file included from ./include/linux/stat.h:19: +In file included from ./include/linux/time.h:60: +In file included from ./include/linux/time32.h:13: +In file included from ./include/linux/timex.h:67: +In file included from ./arch/x86/include/asm/timex.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +The compiler actually complains on 'ath10k_debug_get_et_strings()' where +fortification logic inteprets call to 'memcpy()' as an attempt to copy +the whole 'ath10k_gstrings_stats' array from it's first member and so +issues an overread warning. This warning may be silenced by passing +an address of the whole array and not the first member to 'memcpy()'. + +Signed-off-by: Dmitry Antipov +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230829093652.234537-1-dmantipov@yandex.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/debug.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c +index 39378e3f9b2bb..6e1b65b8ae656 100644 +--- a/drivers/net/wireless/ath/ath10k/debug.c ++++ b/drivers/net/wireless/ath/ath10k/debug.c +@@ -1139,7 +1139,7 @@ void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *ath10k_gstrings_stats, ++ memcpy(data, ath10k_gstrings_stats, + sizeof(ath10k_gstrings_stats)); + } + +-- +2.42.0 + diff --git a/queue-5.15/wifi-ath9k-fix-clang-specific-fortify-warnings.patch b/queue-5.15/wifi-ath9k-fix-clang-specific-fortify-warnings.patch new file mode 100644 index 00000000000..9e5e2109ee7 --- /dev/null +++ b/queue-5.15/wifi-ath9k-fix-clang-specific-fortify-warnings.patch @@ -0,0 +1,102 @@ +From d18dbab3bd8648c47bbec3f0582ad426c434b69c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 12:38:12 +0300 +Subject: wifi: ath9k: fix clang-specific fortify warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dmitry Antipov + +[ Upstream commit 95f97fe0ac974467ab4da215985a32b2fdf48af0 ] + +When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've +noticed the following (somewhat confusing due to absence of an actual +source code location): + +In file included from drivers/net/wireless/ath/ath9k/debug.c:17: +In file included from ./include/linux/slab.h:16: +In file included from ./include/linux/gfp.h:7: +In file included from ./include/linux/mmzone.h:8: +In file included from ./include/linux/spinlock.h:56: +In file included from ./include/linux/preempt.h:79: +In file included from ./arch/x86/include/asm/preempt.h:9: +In file included from ./include/linux/thread_info.h:60: +In file included from ./arch/x86/include/asm/thread_info.h:53: +In file included from ./arch/x86/include/asm/cpufeature.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +In file included from drivers/net/wireless/ath/ath9k/htc_drv_debug.c:17: +In file included from drivers/net/wireless/ath/ath9k/htc.h:20: +In file included from ./include/linux/module.h:13: +In file included from ./include/linux/stat.h:19: +In file included from ./include/linux/time.h:60: +In file included from ./include/linux/time32.h:13: +In file included from ./include/linux/timex.h:67: +In file included from ./arch/x86/include/asm/timex.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +The compiler actually complains on 'ath9k_get_et_strings()' and +'ath9k_htc_get_et_strings()' due to the same reason: fortification logic +inteprets call to 'memcpy()' as an attempt to copy the whole array from +it's first member and so issues an overread warning. These warnings may +be silenced by passing an address of the whole array and not the first +member to 'memcpy()'. + +Signed-off-by: Dmitry Antipov +Acked-by: Toke Høiland-Jørgensen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230829093856.234584-1-dmantipov@yandex.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath9k/debug.c | 2 +- + drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c +index 4c81b1d7f4171..6a043a49dfe6f 100644 +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1284,7 +1284,7 @@ void ath9k_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *ath9k_gstrings_stats, ++ memcpy(data, ath9k_gstrings_stats, + sizeof(ath9k_gstrings_stats)); + } + +diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +index c55aab01fff5d..e79bbcd3279af 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +@@ -428,7 +428,7 @@ void ath9k_htc_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *ath9k_htc_gstrings_stats, ++ memcpy(data, ath9k_htc_gstrings_stats, + sizeof(ath9k_htc_gstrings_stats)); + } + +-- +2.42.0 + diff --git a/queue-5.15/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch b/queue-5.15/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch new file mode 100644 index 00000000000..91ffb9bca86 --- /dev/null +++ b/queue-5.15/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch @@ -0,0 +1,64 @@ +From 1d81e031b1a0f9f7d35b6d73a79ff4151a04418d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 14:56:45 +0300 +Subject: wifi: iwlwifi: Use FW rate for non-data frames + +From: Miri Korenblit + +[ Upstream commit 499d02790495958506a64f37ceda7e97345a50a8 ] + +Currently we are setting the rate in the tx cmd for +mgmt frames (e.g. during connection establishment). +This was problematic when sending mgmt frames in eSR mode, +as we don't know what link this frame will be sent on +(This is decided by the FW), so we don't know what is the +lowest rate. +Fix this by not setting the rate in tx cmd and rely +on FW to choose the right one. +Set rate only for injected frames with fixed rate, +or when no sta is given. +Also set for important frames (EAPOL etc.) the High Priority flag. + +Fixes: 055b22e770dd ("iwlwifi: mvm: Set Tx rate and flags when there is not station") +Signed-off-by: Miri Korenblit +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230913145231.6c7e59620ee0.I6eaed3ccdd6dd62b9e664facc484081fc5275843@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 4375da00f7cf0..08dd227bad4b1 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -479,16 +479,20 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, + flags |= IWL_TX_FLAGS_ENCRYPT_DIS; + + /* +- * For data packets rate info comes from the fw. Only +- * set rate/antenna during connection establishment or in case +- * no station is given. ++ * For data and mgmt packets rate info comes from the fw. Only ++ * set rate/antenna for injected frames with fixed rate, or ++ * when no sta is given. + */ +- if (!sta || !ieee80211_is_data(hdr->frame_control) || +- mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { ++ if (unlikely(!sta || ++ info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) { + flags |= IWL_TX_FLAGS_CMD_RATE; + rate_n_flags = + iwl_mvm_get_tx_rate_n_flags(mvm, info, sta, + hdr->frame_control); ++ } else if (!ieee80211_is_data(hdr->frame_control) || ++ mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { ++ /* These are important frames */ ++ flags |= IWL_TX_FLAGS_HIGH_PRI; + } + + if (mvm->trans->trans_cfg->device_family >= +-- +2.42.0 + diff --git a/queue-5.15/wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch b/queue-5.15/wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch new file mode 100644 index 00000000000..89249f6ae76 --- /dev/null +++ b/queue-5.15/wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch @@ -0,0 +1,58 @@ +From 077f222cd0325ab63067616cb8764730fc15e124 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Feb 2023 10:36:36 +0800 +Subject: wifi: mac80211: don't return unset power in ieee80211_get_tx_power() + +From: Ping-Ke Shih + +[ Upstream commit e160ab85166e77347d0cbe5149045cb25e83937f ] + +We can get a UBSAN warning if ieee80211_get_tx_power() returns the +INT_MIN value mac80211 internally uses for "unset power level". + + UBSAN: signed-integer-overflow in net/wireless/nl80211.c:3816:5 + -2147483648 * 100 cannot be represented in type 'int' + CPU: 0 PID: 20433 Comm: insmod Tainted: G WC OE + Call Trace: + dump_stack+0x74/0x92 + ubsan_epilogue+0x9/0x50 + handle_overflow+0x8d/0xd0 + __ubsan_handle_mul_overflow+0xe/0x10 + nl80211_send_iface+0x688/0x6b0 [cfg80211] + [...] + cfg80211_register_wdev+0x78/0xb0 [cfg80211] + cfg80211_netdev_notifier_call+0x200/0x620 [cfg80211] + [...] + ieee80211_if_add+0x60e/0x8f0 [mac80211] + ieee80211_register_hw+0xda5/0x1170 [mac80211] + +In this case, simply return an error instead, to indicate +that no data is available. + +Cc: Zong-Zhe Yang +Signed-off-by: Ping-Ke Shih +Link: https://lore.kernel.org/r/20230203023636.4418-1-pkshih@realtek.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/cfg.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index 4fa216a108ae8..02bd90a537058 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2762,6 +2762,10 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, + else + *dbm = sdata->vif.bss_conf.txpower; + ++ /* INT_MIN indicates no power level was set yet */ ++ if (*dbm == INT_MIN) ++ return -EINVAL; ++ + return 0; + } + +-- +2.42.0 + diff --git a/queue-5.15/wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch b/queue-5.15/wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch new file mode 100644 index 00000000000..6ebc96470ae --- /dev/null +++ b/queue-5.15/wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch @@ -0,0 +1,64 @@ +From 45b211017acfab95440d159c1255a55cfa570a7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 12:41:01 +0300 +Subject: wifi: mac80211_hwsim: fix clang-specific fortify warning + +From: Dmitry Antipov + +[ Upstream commit cbaccdc42483c65016f1bae89128c08dc17cfb2a ] + +When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've +noticed the following (somewhat confusing due to absence of an actual +source code location): + +In file included from drivers/net/wireless/virtual/mac80211_hwsim.c:18: +In file included from ./include/linux/slab.h:16: +In file included from ./include/linux/gfp.h:7: +In file included from ./include/linux/mmzone.h:8: +In file included from ./include/linux/spinlock.h:56: +In file included from ./include/linux/preempt.h:79: +In file included from ./arch/x86/include/asm/preempt.h:9: +In file included from ./include/linux/thread_info.h:60: +In file included from ./arch/x86/include/asm/thread_info.h:53: +In file included from ./arch/x86/include/asm/cpufeature.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +The compiler actually complains on 'mac80211_hwsim_get_et_strings()' where +fortification logic inteprets call to 'memcpy()' as an attempt to copy the +whole 'mac80211_hwsim_gstrings_stats' array from its first member and so +issues an overread warning. This warning may be silenced by passing +an address of the whole array and not the first member to 'memcpy()'. + +Signed-off-by: Dmitry Antipov +Link: https://lore.kernel.org/r/20230829094140.234636-1-dmantipov@yandex.ru +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mac80211_hwsim.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c +index 6eb3c845640bd..7d73502586839 100644 +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -2615,7 +2615,7 @@ static void mac80211_hwsim_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *mac80211_hwsim_gstrings_stats, ++ memcpy(data, mac80211_hwsim_gstrings_stats, + sizeof(mac80211_hwsim_gstrings_stats)); + } + +-- +2.42.0 + diff --git a/queue-5.15/workqueue-provide-one-lock-class-key-per-work_on_cpu.patch b/queue-5.15/workqueue-provide-one-lock-class-key-per-work_on_cpu.patch new file mode 100644 index 00000000000..dcbdccc4e9c --- /dev/null +++ b/queue-5.15/workqueue-provide-one-lock-class-key-per-work_on_cpu.patch @@ -0,0 +1,299 @@ +From 1bf25d415a96c0ab61763bf9e68db05e6ec21764 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 17:07:02 +0200 +Subject: workqueue: Provide one lock class key per work_on_cpu() callsite + +From: Frederic Weisbecker + +[ Upstream commit 265f3ed077036f053981f5eea0b5b43e7c5b39ff ] + +All callers of work_on_cpu() share the same lock class key for all the +functions queued. As a result the workqueue related locking scenario for +a function A may be spuriously accounted as an inversion against the +locking scenario of function B such as in the following model: + + long A(void *arg) + { + mutex_lock(&mutex); + mutex_unlock(&mutex); + } + + long B(void *arg) + { + } + + void launchA(void) + { + work_on_cpu(0, A, NULL); + } + + void launchB(void) + { + mutex_lock(&mutex); + work_on_cpu(1, B, NULL); + mutex_unlock(&mutex); + } + +launchA and launchB running concurrently have no chance to deadlock. +However the above can be reported by lockdep as a possible locking +inversion because the works containing A() and B() are treated as +belonging to the same locking class. + +The following shows an existing example of such a spurious lockdep splat: + + ====================================================== + WARNING: possible circular locking dependency detected + 6.6.0-rc1-00065-g934ebd6e5359 #35409 Not tainted + ------------------------------------------------------ + kworker/0:1/9 is trying to acquire lock: + ffffffff9bc72f30 (cpu_hotplug_lock){++++}-{0:0}, at: _cpu_down+0x57/0x2b0 + + but task is already holding lock: + ffff9e3bc0057e60 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_scheduled_works+0x216/0x500 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #2 ((work_completion)(&wfc.work)){+.+.}-{0:0}: + __flush_work+0x83/0x4e0 + work_on_cpu+0x97/0xc0 + rcu_nocb_cpu_offload+0x62/0xb0 + rcu_nocb_toggle+0xd0/0x1d0 + kthread+0xe6/0x120 + ret_from_fork+0x2f/0x40 + ret_from_fork_asm+0x1b/0x30 + + -> #1 (rcu_state.barrier_mutex){+.+.}-{3:3}: + __mutex_lock+0x81/0xc80 + rcu_nocb_cpu_deoffload+0x38/0xb0 + rcu_nocb_toggle+0x144/0x1d0 + kthread+0xe6/0x120 + ret_from_fork+0x2f/0x40 + ret_from_fork_asm+0x1b/0x30 + + -> #0 (cpu_hotplug_lock){++++}-{0:0}: + __lock_acquire+0x1538/0x2500 + lock_acquire+0xbf/0x2a0 + percpu_down_write+0x31/0x200 + _cpu_down+0x57/0x2b0 + __cpu_down_maps_locked+0x10/0x20 + work_for_cpu_fn+0x15/0x20 + process_scheduled_works+0x2a7/0x500 + worker_thread+0x173/0x330 + kthread+0xe6/0x120 + ret_from_fork+0x2f/0x40 + ret_from_fork_asm+0x1b/0x30 + + other info that might help us debug this: + + Chain exists of: + cpu_hotplug_lock --> rcu_state.barrier_mutex --> (work_completion)(&wfc.work) + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock((work_completion)(&wfc.work)); + lock(rcu_state.barrier_mutex); + lock((work_completion)(&wfc.work)); + lock(cpu_hotplug_lock); + + *** DEADLOCK *** + + 2 locks held by kworker/0:1/9: + #0: ffff900481068b38 ((wq_completion)events){+.+.}-{0:0}, at: process_scheduled_works+0x212/0x500 + #1: ffff9e3bc0057e60 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_scheduled_works+0x216/0x500 + + stack backtrace: + CPU: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.6.0-rc1-00065-g934ebd6e5359 #35409 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 + Workqueue: events work_for_cpu_fn + Call Trace: + rcu-torture: rcu_torture_read_exit: Start of episode + + dump_stack_lvl+0x4a/0x80 + check_noncircular+0x132/0x150 + __lock_acquire+0x1538/0x2500 + lock_acquire+0xbf/0x2a0 + ? _cpu_down+0x57/0x2b0 + percpu_down_write+0x31/0x200 + ? _cpu_down+0x57/0x2b0 + _cpu_down+0x57/0x2b0 + __cpu_down_maps_locked+0x10/0x20 + work_for_cpu_fn+0x15/0x20 + process_scheduled_works+0x2a7/0x500 + worker_thread+0x173/0x330 + ? __pfx_worker_thread+0x10/0x10 + kthread+0xe6/0x120 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x2f/0x40 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + include/linux/workqueue.h | 46 +++++++++++++++++++++++++++++++++------ + kernel/workqueue.c | 20 ++++++++++------- + 2 files changed, 51 insertions(+), 15 deletions(-) + +diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h +index 20a47eb94b0f3..1e96680f50230 100644 +--- a/include/linux/workqueue.h ++++ b/include/linux/workqueue.h +@@ -222,18 +222,16 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } + * to generate better code. + */ + #ifdef CONFIG_LOCKDEP +-#define __INIT_WORK(_work, _func, _onstack) \ ++#define __INIT_WORK_KEY(_work, _func, _onstack, _key) \ + do { \ +- static struct lock_class_key __key; \ +- \ + __init_work((_work), _onstack); \ + (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ +- lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, &__key, 0); \ ++ lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, (_key), 0); \ + INIT_LIST_HEAD(&(_work)->entry); \ + (_work)->func = (_func); \ + } while (0) + #else +-#define __INIT_WORK(_work, _func, _onstack) \ ++#define __INIT_WORK_KEY(_work, _func, _onstack, _key) \ + do { \ + __init_work((_work), _onstack); \ + (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ +@@ -242,12 +240,22 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } + } while (0) + #endif + ++#define __INIT_WORK(_work, _func, _onstack) \ ++ do { \ ++ static __maybe_unused struct lock_class_key __key; \ ++ \ ++ __INIT_WORK_KEY(_work, _func, _onstack, &__key); \ ++ } while (0) ++ + #define INIT_WORK(_work, _func) \ + __INIT_WORK((_work), (_func), 0) + + #define INIT_WORK_ONSTACK(_work, _func) \ + __INIT_WORK((_work), (_func), 1) + ++#define INIT_WORK_ONSTACK_KEY(_work, _func, _key) \ ++ __INIT_WORK_KEY((_work), (_func), 1, _key) ++ + #define __INIT_DELAYED_WORK(_work, _func, _tflags) \ + do { \ + INIT_WORK(&(_work)->work, (_func)); \ +@@ -632,8 +640,32 @@ static inline long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) + return fn(arg); + } + #else +-long work_on_cpu(int cpu, long (*fn)(void *), void *arg); +-long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg); ++long work_on_cpu_key(int cpu, long (*fn)(void *), ++ void *arg, struct lock_class_key *key); ++/* ++ * A new key is defined for each caller to make sure the work ++ * associated with the function doesn't share its locking class. ++ */ ++#define work_on_cpu(_cpu, _fn, _arg) \ ++({ \ ++ static struct lock_class_key __key; \ ++ \ ++ work_on_cpu_key(_cpu, _fn, _arg, &__key); \ ++}) ++ ++long work_on_cpu_safe_key(int cpu, long (*fn)(void *), ++ void *arg, struct lock_class_key *key); ++ ++/* ++ * A new key is defined for each caller to make sure the work ++ * associated with the function doesn't share its locking class. ++ */ ++#define work_on_cpu_safe(_cpu, _fn, _arg) \ ++({ \ ++ static struct lock_class_key __key; \ ++ \ ++ work_on_cpu_safe_key(_cpu, _fn, _arg, &__key); \ ++}) + #endif /* CONFIG_SMP */ + + #ifdef CONFIG_FREEZER +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 19868cf588779..962ee27ec7d70 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -5209,50 +5209,54 @@ static void work_for_cpu_fn(struct work_struct *work) + } + + /** +- * work_on_cpu - run a function in thread context on a particular cpu ++ * work_on_cpu_key - run a function in thread context on a particular cpu + * @cpu: the cpu to run on + * @fn: the function to run + * @arg: the function arg ++ * @key: The lock class key for lock debugging purposes + * + * It is up to the caller to ensure that the cpu doesn't go offline. + * The caller must not hold any locks which would prevent @fn from completing. + * + * Return: The value @fn returns. + */ +-long work_on_cpu(int cpu, long (*fn)(void *), void *arg) ++long work_on_cpu_key(int cpu, long (*fn)(void *), ++ void *arg, struct lock_class_key *key) + { + struct work_for_cpu wfc = { .fn = fn, .arg = arg }; + +- INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); ++ INIT_WORK_ONSTACK_KEY(&wfc.work, work_for_cpu_fn, key); + schedule_work_on(cpu, &wfc.work); + flush_work(&wfc.work); + destroy_work_on_stack(&wfc.work); + return wfc.ret; + } +-EXPORT_SYMBOL_GPL(work_on_cpu); ++EXPORT_SYMBOL_GPL(work_on_cpu_key); + + /** +- * work_on_cpu_safe - run a function in thread context on a particular cpu ++ * work_on_cpu_safe_key - run a function in thread context on a particular cpu + * @cpu: the cpu to run on + * @fn: the function to run + * @arg: the function argument ++ * @key: The lock class key for lock debugging purposes + * + * Disables CPU hotplug and calls work_on_cpu(). The caller must not hold + * any locks which would prevent @fn from completing. + * + * Return: The value @fn returns. + */ +-long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) ++long work_on_cpu_safe_key(int cpu, long (*fn)(void *), ++ void *arg, struct lock_class_key *key) + { + long ret = -ENODEV; + + cpus_read_lock(); + if (cpu_online(cpu)) +- ret = work_on_cpu(cpu, fn, arg); ++ ret = work_on_cpu_key(cpu, fn, arg, key); + cpus_read_unlock(); + return ret; + } +-EXPORT_SYMBOL_GPL(work_on_cpu_safe); ++EXPORT_SYMBOL_GPL(work_on_cpu_safe_key); + #endif /* CONFIG_SMP */ + + #ifdef CONFIG_FREEZER +-- +2.42.0 + diff --git a/queue-5.15/x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch b/queue-5.15/x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch new file mode 100644 index 00000000000..b34eea2f32f --- /dev/null +++ b/queue-5.15/x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch @@ -0,0 +1,112 @@ +From f79f3caea94be950cbc3a341474dbf70d915791f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 12:42:50 +0200 +Subject: x86/mm: Drop the 4 MB restriction on minimal NUMA node memory size + +From: Mike Rapoport (IBM) + +[ Upstream commit a1e2b8b36820d8c91275f207e77e91645b7c6836 ] + +Qi Zheng reported crashes in a production environment and provided a +simplified example as a reproducer: + + | For example, if we use Qemu to start a two NUMA node kernel, + | one of the nodes has 2M memory (less than NODE_MIN_SIZE), + | and the other node has 2G, then we will encounter the + | following panic: + | + | BUG: kernel NULL pointer dereference, address: 0000000000000000 + | <...> + | RIP: 0010:_raw_spin_lock_irqsave+0x22/0x40 + | <...> + | Call Trace: + | + | deactivate_slab() + | bootstrap() + | kmem_cache_init() + | start_kernel() + | secondary_startup_64_no_verify() + +The crashes happen because of inconsistency between the nodemask that +has nodes with less than 4MB as memoryless, and the actual memory fed +into the core mm. + +The commit: + + 9391a3f9c7f1 ("[PATCH] x86_64: Clear more state when ignoring empty node in SRAT parsing") + +... that introduced minimal size of a NUMA node does not explain why +a node size cannot be less than 4MB and what boot failures this +restriction might fix. + +Fixes have been submitted to the core MM code to tighten up the +memory topologies it accepts and to not crash on weird input: + + mm: page_alloc: skip memoryless nodes entirely + mm: memory_hotplug: drop memoryless node from fallback lists + +Andrew has accepted them into the -mm tree, but there are no +stable SHA1's yet. + +This patch drops the limitation for minimal node size on x86: + + - which works around the crash without the fixes to the core MM. + - makes x86 topologies less weird, + - removes an arbitrary and undocumented limitation on NUMA topologies. + +[ mingo: Improved changelog clarity. ] + +Reported-by: Qi Zheng +Tested-by: Mario Casquero +Signed-off-by: Mike Rapoport (IBM) +Signed-off-by: Ingo Molnar +Acked-by: David Hildenbrand +Acked-by: Michal Hocko +Cc: Dave Hansen +Cc: Rik van Riel +Link: https://lore.kernel.org/r/ZS+2qqjEO5/867br@gmail.com +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/numa.h | 7 ------- + arch/x86/mm/numa.c | 7 ------- + 2 files changed, 14 deletions(-) + +diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h +index e3bae2b60a0db..ef2844d691735 100644 +--- a/arch/x86/include/asm/numa.h ++++ b/arch/x86/include/asm/numa.h +@@ -12,13 +12,6 @@ + + #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) + +-/* +- * Too small node sizes may confuse the VM badly. Usually they +- * result from BIOS bugs. So dont recognize nodes as standalone +- * NUMA entities that have less than this amount of RAM listed: +- */ +-#define NODE_MIN_SIZE (4*1024*1024) +- + extern int numa_off; + + /* +diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c +index e360c6892a584..1a1c0c242f272 100644 +--- a/arch/x86/mm/numa.c ++++ b/arch/x86/mm/numa.c +@@ -601,13 +601,6 @@ static int __init numa_register_memblks(struct numa_meminfo *mi) + if (start >= end) + continue; + +- /* +- * Don't confuse VM with a node that doesn't have the +- * minimum amount of memory: +- */ +- if (end && (end - start) < NODE_MIN_SIZE) +- continue; +- + alloc_node_data(nid); + } + +-- +2.42.0 + diff --git a/queue-5.15/xen-events-fix-delayed-eoi-list-handling.patch b/queue-5.15/xen-events-fix-delayed-eoi-list-handling.patch new file mode 100644 index 00000000000..ebbd38e98d7 --- /dev/null +++ b/queue-5.15/xen-events-fix-delayed-eoi-list-handling.patch @@ -0,0 +1,47 @@ +From 8f83871ff313ed4c7429bdfea09eb6eb53329bb7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 17:54:13 +0200 +Subject: xen/events: fix delayed eoi list handling + +From: Juergen Gross + +[ Upstream commit 47d970204054f859f35a2237baa75c2d84fcf436 ] + +When delaying eoi handling of events, the related elements are queued +into the percpu lateeoi list. In case the list isn't empty, the +elements should be sorted by the time when eoi handling is to happen. + +Unfortunately a new element will never be queued at the start of the +list, even if it has a handling time lower than all other list +elements. + +Fix that by handling that case the same way as for an empty list. + +Fixes: e99502f76271 ("xen/events: defer eoi in case of excessive number of events") +Reported-by: Jan Beulich +Signed-off-by: Juergen Gross +Reviewed-by: Oleksandr Tyshchenko +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/xen/events/events_base.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index 9339f2aad5679..ee691b20d4a3f 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -599,7 +599,9 @@ static void lateeoi_list_add(struct irq_info *info) + + spin_lock_irqsave(&eoi->eoi_list_lock, flags); + +- if (list_empty(&eoi->eoi_list)) { ++ elem = list_first_entry_or_null(&eoi->eoi_list, struct irq_info, ++ eoi_list); ++ if (!elem || info->eoi_time < elem->eoi_time) { + list_add(&info->eoi_list, &eoi->eoi_list); + mod_delayed_work_on(info->eoi_cpu, system_wq, + &eoi->delayed, delay); +-- +2.42.0 + diff --git a/queue-5.15/xfs-add-missing-cmap-br_state-xfs_ext_norm-update.patch b/queue-5.15/xfs-add-missing-cmap-br_state-xfs_ext_norm-update.patch new file mode 100644 index 00000000000..e545e46a789 --- /dev/null +++ b/queue-5.15/xfs-add-missing-cmap-br_state-xfs_ext_norm-update.patch @@ -0,0 +1,45 @@ +From 4cead8923688cf8fff6f3a738cf1f736fa43d3a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:27 -0800 +Subject: xfs: add missing cmap->br_state = XFS_EXT_NORM update + +From: Gao Xiang + +[ Upstream commit 1a39ae415c1be1e46f5b3f97d438c7c4adc22b63 ] + +COW extents are already converted into written real extents after +xfs_reflink_convert_cow_locked(), therefore cmap->br_state should +reflect it. + +Otherwise, there is another necessary unwritten convertion +triggered in xfs_dio_write_end_io() for direct I/O cases. + +Signed-off-by: Gao Xiang +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_reflink.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c +index 36832e4bc803c..628ce65d02bb5 100644 +--- a/fs/xfs/xfs_reflink.c ++++ b/fs/xfs/xfs_reflink.c +@@ -425,7 +425,10 @@ xfs_reflink_allocate_cow( + if (!convert_now || cmap->br_state == XFS_EXT_NORM) + return 0; + trace_xfs_reflink_convert_cow(ip, cmap); +- return xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb); ++ error = xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb); ++ if (!error) ++ cmap->br_state = XFS_EXT_NORM; ++ return error; + + out_trans_cancel: + xfs_trans_cancel(tp); +-- +2.42.0 + diff --git a/queue-5.15/xfs-avoid-a-uaf-when-log-intent-item-recovery-fails.patch b/queue-5.15/xfs-avoid-a-uaf-when-log-intent-item-recovery-fails.patch new file mode 100644 index 00000000000..10dfee94cda --- /dev/null +++ b/queue-5.15/xfs-avoid-a-uaf-when-log-intent-item-recovery-fails.patch @@ -0,0 +1,168 @@ +From 3c6d6ae3f0018c85ecfcb41a3e00beabc318ee9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:30 -0800 +Subject: xfs: avoid a UAF when log intent item recovery fails + +From: Darrick J. Wong + +[ Upstream commit 97cf79677ecb50a38517253ae2fd705849a7e51a ] + +KASAN reported a UAF bug when I was running xfs/235: + + BUG: KASAN: use-after-free in xlog_recover_process_intents+0xa77/0xae0 [xfs] + Read of size 8 at addr ffff88804391b360 by task mount/5680 + + CPU: 2 PID: 5680 Comm: mount Not tainted 6.0.0-xfsx #6.0.0 77e7b52a4943a975441e5ac90a5ad7748b7867f6 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 + Call Trace: + + dump_stack_lvl+0x34/0x44 + print_report.cold+0x2cc/0x682 + kasan_report+0xa3/0x120 + xlog_recover_process_intents+0xa77/0xae0 [xfs fb841c7180aad3f8359438576e27867f5795667e] + xlog_recover_finish+0x7d/0x970 [xfs fb841c7180aad3f8359438576e27867f5795667e] + xfs_log_mount_finish+0x2d7/0x5d0 [xfs fb841c7180aad3f8359438576e27867f5795667e] + xfs_mountfs+0x11d4/0x1d10 [xfs fb841c7180aad3f8359438576e27867f5795667e] + xfs_fs_fill_super+0x13d5/0x1a80 [xfs fb841c7180aad3f8359438576e27867f5795667e] + get_tree_bdev+0x3da/0x6e0 + vfs_get_tree+0x7d/0x240 + path_mount+0xdd3/0x17d0 + __x64_sys_mount+0x1fa/0x270 + do_syscall_64+0x2b/0x80 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + RIP: 0033:0x7ff5bc069eae + Code: 48 8b 0d 85 1f 0f 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 52 1f 0f 00 f7 d8 64 89 01 48 + RSP: 002b:00007ffe433fd448 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5 + RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007ff5bc069eae + RDX: 00005575d7213290 RSI: 00005575d72132d0 RDI: 00005575d72132b0 + RBP: 00005575d7212fd0 R08: 00005575d7213230 R09: 00005575d7213fe0 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 + R13: 00005575d7213290 R14: 00005575d72132b0 R15: 00005575d7212fd0 + + + Allocated by task 5680: + kasan_save_stack+0x1e/0x40 + __kasan_slab_alloc+0x66/0x80 + kmem_cache_alloc+0x152/0x320 + xfs_rui_init+0x17a/0x1b0 [xfs] + xlog_recover_rui_commit_pass2+0xb9/0x2e0 [xfs] + xlog_recover_items_pass2+0xe9/0x220 [xfs] + xlog_recover_commit_trans+0x673/0x900 [xfs] + xlog_recovery_process_trans+0xbe/0x130 [xfs] + xlog_recover_process_data+0x103/0x2a0 [xfs] + xlog_do_recovery_pass+0x548/0xc60 [xfs] + xlog_do_log_recovery+0x62/0xc0 [xfs] + xlog_do_recover+0x73/0x480 [xfs] + xlog_recover+0x229/0x460 [xfs] + xfs_log_mount+0x284/0x640 [xfs] + xfs_mountfs+0xf8b/0x1d10 [xfs] + xfs_fs_fill_super+0x13d5/0x1a80 [xfs] + get_tree_bdev+0x3da/0x6e0 + vfs_get_tree+0x7d/0x240 + path_mount+0xdd3/0x17d0 + __x64_sys_mount+0x1fa/0x270 + do_syscall_64+0x2b/0x80 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + + Freed by task 5680: + kasan_save_stack+0x1e/0x40 + kasan_set_track+0x21/0x30 + kasan_set_free_info+0x20/0x30 + ____kasan_slab_free+0x144/0x1b0 + slab_free_freelist_hook+0xab/0x180 + kmem_cache_free+0x1f1/0x410 + xfs_rud_item_release+0x33/0x80 [xfs] + xfs_trans_free_items+0xc3/0x220 [xfs] + xfs_trans_cancel+0x1fa/0x590 [xfs] + xfs_rui_item_recover+0x913/0xd60 [xfs] + xlog_recover_process_intents+0x24e/0xae0 [xfs] + xlog_recover_finish+0x7d/0x970 [xfs] + xfs_log_mount_finish+0x2d7/0x5d0 [xfs] + xfs_mountfs+0x11d4/0x1d10 [xfs] + xfs_fs_fill_super+0x13d5/0x1a80 [xfs] + get_tree_bdev+0x3da/0x6e0 + vfs_get_tree+0x7d/0x240 + path_mount+0xdd3/0x17d0 + __x64_sys_mount+0x1fa/0x270 + do_syscall_64+0x2b/0x80 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + + The buggy address belongs to the object at ffff88804391b300 + which belongs to the cache xfs_rui_item of size 688 + The buggy address is located 96 bytes inside of + 688-byte region [ffff88804391b300, ffff88804391b5b0) + + The buggy address belongs to the physical page: + page:ffffea00010e4600 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff888043919320 pfn:0x43918 + head:ffffea00010e4600 order:2 compound_mapcount:0 compound_pincount:0 + flags: 0x4fff80000010200(slab|head|node=1|zone=1|lastcpupid=0xfff) + raw: 04fff80000010200 0000000000000000 dead000000000122 ffff88807f0eadc0 + raw: ffff888043919320 0000000080140010 00000001ffffffff 0000000000000000 + page dumped because: kasan: bad access detected + + Memory state around the buggy address: + ffff88804391b200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ffff88804391b280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + >ffff88804391b300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + ffff88804391b380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff88804391b400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ================================================================== + +The test fuzzes an rmap btree block and starts writer threads to induce +a filesystem shutdown on the corrupt block. When the filesystem is +remounted, recovery will try to replay the committed rmap intent item, +but the corruption problem causes the recovery transaction to fail. +Cancelling the transaction frees the RUD, which frees the RUI that we +recovered. + +When we return to xlog_recover_process_intents, @lip is now a dangling +pointer, and we cannot use it to find the iop_recover method for the +tracepoint. Hence we must store the item ops before calling +->iop_recover if we want to give it to the tracepoint so that the trace +data will tell us exactly which intent item failed. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_log_recover.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c +index 04961ebf16ea2..3d844a250b710 100644 +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -2560,6 +2560,7 @@ xlog_recover_process_intents( + for (lip = xfs_trans_ail_cursor_first(ailp, &cur, 0); + lip != NULL; + lip = xfs_trans_ail_cursor_next(ailp, &cur)) { ++ const struct xfs_item_ops *ops; + /* + * We're done when we see something other than an intent. + * There should be no intents left in the AIL now. +@@ -2584,13 +2585,17 @@ xlog_recover_process_intents( + * deferred ops, you /must/ attach them to the capture list in + * the recover routine or else those subsequent intents will be + * replayed in the wrong order! ++ * ++ * The recovery function can free the log item, so we must not ++ * access lip after it returns. + */ + spin_unlock(&ailp->ail_lock); +- error = lip->li_ops->iop_recover(lip, &capture_list); ++ ops = lip->li_ops; ++ error = ops->iop_recover(lip, &capture_list); + spin_lock(&ailp->ail_lock); + if (error) { + trace_xlog_intent_recovery_failed(log->l_mp, error, +- lip->li_ops->iop_recover); ++ ops->iop_recover); + break; + } + } +-- +2.42.0 + diff --git a/queue-5.15/xfs-convert-buf_cancel_table-allocation-to-kmalloc_a.patch b/queue-5.15/xfs-convert-buf_cancel_table-allocation-to-kmalloc_a.patch new file mode 100644 index 00000000000..1eb065a34ab --- /dev/null +++ b/queue-5.15/xfs-convert-buf_cancel_table-allocation-to-kmalloc_a.patch @@ -0,0 +1,92 @@ +From 25461b6bcb248106ca870f521ad17130d139fe42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:19 -0800 +Subject: xfs: convert buf_cancel_table allocation to kmalloc_array + +From: Darrick J. Wong + +[ Upstream commit 910bbdf2f4d7df46781bc9b723048f5ebed3d0d7 ] + +While we're messing around with how recovery allocates and frees the +buffer cancellation table, convert the allocation to use kmalloc_array +instead of the old kmem_alloc APIs, and make it handle a null return, +even though that's not likely. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Reviewed-by: Dave Chinner +Signed-off-by: Dave Chinner +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/libxfs/xfs_log_recover.h | 2 +- + fs/xfs/xfs_buf_item_recover.c | 14 ++++++++++---- + fs/xfs/xfs_log_recover.c | 4 +++- + 3 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h +index b8b65a6e9b1ec..81a065b0b5710 100644 +--- a/fs/xfs/libxfs/xfs_log_recover.h ++++ b/fs/xfs/libxfs/xfs_log_recover.h +@@ -120,7 +120,7 @@ int xlog_recover_iget(struct xfs_mount *mp, xfs_ino_t ino, + struct xfs_inode **ipp); + void xlog_recover_release_intent(struct xlog *log, unsigned short intent_type, + uint64_t intent_id); +-void xlog_alloc_buf_cancel_table(struct xlog *log); ++int xlog_alloc_buf_cancel_table(struct xlog *log); + void xlog_free_buf_cancel_table(struct xlog *log); + + #ifdef DEBUG +diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c +index 635f7f8ed9c2d..31cbe7deebfaf 100644 +--- a/fs/xfs/xfs_buf_item_recover.c ++++ b/fs/xfs/xfs_buf_item_recover.c +@@ -1025,19 +1025,25 @@ xlog_check_buf_cancel_table( + } + #endif + +-void ++int + xlog_alloc_buf_cancel_table( + struct xlog *log) + { ++ void *p; + int i; + + ASSERT(log->l_buf_cancel_table == NULL); + +- log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE * +- sizeof(struct list_head), +- 0); ++ p = kmalloc_array(XLOG_BC_TABLE_SIZE, sizeof(struct list_head), ++ GFP_KERNEL); ++ if (!p) ++ return -ENOMEM; ++ ++ log->l_buf_cancel_table = p; + for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) + INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); ++ ++ return 0; + } + + void +diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c +index 18d8eebc2d445..aeb01d4c0423b 100644 +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -3256,7 +3256,9 @@ xlog_do_log_recovery( + * First do a pass to find all of the cancelled buf log items. + * Store them in the buf_cancel_table for use in the second pass. + */ +- xlog_alloc_buf_cancel_table(log); ++ error = xlog_alloc_buf_cancel_table(log); ++ if (error) ++ return error; + + error = xlog_do_recovery_pass(log, head_blk, tail_blk, + XLOG_RECOVER_PASS1, NULL); +-- +2.42.0 + diff --git a/queue-5.15/xfs-don-t-leak-memory-when-attr-fork-loading-fails.patch b/queue-5.15/xfs-don-t-leak-memory-when-attr-fork-loading-fails.patch new file mode 100644 index 00000000000..6060974cf32 --- /dev/null +++ b/queue-5.15/xfs-don-t-leak-memory-when-attr-fork-loading-fails.patch @@ -0,0 +1,97 @@ +From 0f1496d838c87ffb947b6935392a4ccc2b11429b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:24 -0800 +Subject: xfs: don't leak memory when attr fork loading fails + +From: Darrick J. Wong + +[ Upstream commit c78c2d0903183a41beb90c56a923e30f90fa91b9 ] + +I observed the following evidence of a memory leak while running xfs/399 +from the xfs fsck test suite (edited for brevity): + +XFS (sde): Metadata corruption detected at xfs_attr_shortform_verify_struct.part.0+0x7b/0xb0 [xfs], inode 0x1172 attr fork +XFS: Assertion failed: ip->i_af.if_u1.if_data == NULL, file: fs/xfs/libxfs/xfs_inode_fork.c, line: 315 +------------[ cut here ]------------ +WARNING: CPU: 2 PID: 91635 at fs/xfs/xfs_message.c:104 assfail+0x46/0x4a [xfs] +CPU: 2 PID: 91635 Comm: xfs_scrub Tainted: G W 5.19.0-rc7-xfsx #rc7 6e6475eb29fd9dda3181f81b7ca7ff961d277a40 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 +RIP: 0010:assfail+0x46/0x4a [xfs] +Call Trace: + + xfs_ifork_zap_attr+0x7c/0xb0 + xfs_iformat_attr_fork+0x86/0x110 + xfs_inode_from_disk+0x41d/0x480 + xfs_iget+0x389/0xd70 + xfs_bulkstat_one_int+0x5b/0x540 + xfs_bulkstat_iwalk+0x1e/0x30 + xfs_iwalk_ag_recs+0xd1/0x160 + xfs_iwalk_run_callbacks+0xb9/0x180 + xfs_iwalk_ag+0x1d8/0x2e0 + xfs_iwalk+0x141/0x220 + xfs_bulkstat+0x105/0x180 + xfs_ioc_bulkstat.constprop.0.isra.0+0xc5/0x130 + xfs_file_ioctl+0xa5f/0xef0 + __x64_sys_ioctl+0x82/0xa0 + do_syscall_64+0x2b/0x80 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +This newly-added assertion checks that there aren't any incore data +structures hanging off the incore fork when we're trying to reset its +contents. From the call trace, it is evident that iget was trying to +construct an incore inode from the ondisk inode, but the attr fork +verifier failed and we were trying to undo all the memory allocations +that we had done earlier. + +The three assertions in xfs_ifork_zap_attr check that the caller has +already called xfs_idestroy_fork, which clearly has not been done here. +As the zap function then zeroes the pointers, we've effectively leaked +the memory. + +The shortest change would have been to insert an extra call to +xfs_idestroy_fork, but it makes more sense to bundle the _idestroy_fork +call into _zap_attr, since all other callsites call _idestroy_fork +immediately prior to calling _zap_attr. IOWs, it eliminates one way to +fail. + +Note: This change only applies cleanly to 2ed5b09b3e8f, since we just +reworked the attr fork lifetime. However, I think this memory leak has +existed since 0f45a1b20cd8, since the chain xfs_iformat_attr_fork -> +xfs_iformat_local -> xfs_init_local_fork will allocate +ifp->if_u1.if_data, but if xfs_ifork_verify_local_attr fails, +xfs_iformat_attr_fork will free i_afp without freeing any of the stuff +hanging off i_afp. The solution for older kernels I think is to add the +missing call to xfs_idestroy_fork just prior to calling kmem_cache_free. + +Found by fuzzing a.sfattr.hdr.totsize = lastbit in xfs/399. + +[ backport note: did not include refactoring of xfs_idestroy_fork into +xfs_ifork_zap_attr, simply added the missing call as suggested in the +commit for backports ] + +Fixes: 2ed5b09b3e8f ("xfs: make inode attribute forks a permanent part of struct xfs_inode") +Probably-Fixes: 0f45a1b20cd8 ("xfs: improve local fork verification") +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/libxfs/xfs_inode_fork.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c +index 20095233d7bc0..c1f965af8432d 100644 +--- a/fs/xfs/libxfs/xfs_inode_fork.c ++++ b/fs/xfs/libxfs/xfs_inode_fork.c +@@ -330,6 +330,7 @@ xfs_iformat_attr_fork( + } + + if (error) { ++ xfs_idestroy_fork(ip->i_afp); + kmem_cache_free(xfs_ifork_zone, ip->i_afp); + ip->i_afp = NULL; + } +-- +2.42.0 + diff --git a/queue-5.15/xfs-don-t-leak-xfs_buf_cancel-structures-when-recove.patch b/queue-5.15/xfs-don-t-leak-xfs_buf_cancel-structures-when-recove.patch new file mode 100644 index 00000000000..9a80a591b40 --- /dev/null +++ b/queue-5.15/xfs-don-t-leak-xfs_buf_cancel-structures-when-recove.patch @@ -0,0 +1,78 @@ +From 1aa77db97f2b0dfe00171cb19b4149124e15bfee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:18 -0800 +Subject: xfs: don't leak xfs_buf_cancel structures when recovery fails + +From: Darrick J. Wong + +[ Upstream commit 8db074bd84df5ccc88bff3f8f900f66f4b8349fa ] + +If log recovery fails, we free the memory used by the buffer +cancellation buckets, but we don't actually traverse each bucket list to +free the individual xfs_buf_cancel objects. This leads to a memory +leak, as reported by kmemleak in xfs/051: + +unreferenced object 0xffff888103629560 (size 32): + comm "mount", pid 687045, jiffies 4296935916 (age 10.752s) + hex dump (first 32 bytes): + 08 d3 0a 01 00 00 00 00 08 00 00 00 01 00 00 00 ................ + d0 f5 0b 92 81 88 ff ff 80 64 64 25 81 88 ff ff .........dd%.... + backtrace: + [] kmem_alloc+0x73/0x140 [xfs] + [] xlog_recover_buf_commit_pass1+0x139/0x200 [xfs] + [] xlog_recover_commit_trans+0x307/0x350 [xfs] + [] xlog_recovery_process_trans+0xa5/0xe0 [xfs] + [] xlog_recover_process_data+0x8d/0x140 [xfs] + [] xlog_do_recovery_pass+0x19d/0x740 [xfs] + [] xlog_do_log_recovery+0x6d/0x150 [xfs] + [] xlog_do_recover+0x33/0x1d0 [xfs] + [] xlog_recover+0xda/0x190 [xfs] + [] xfs_log_mount+0x14c/0x360 [xfs] + [] xfs_mountfs+0x50d/0xa60 [xfs] + [] xfs_fs_fill_super+0x6a5/0x950 [xfs] + [] get_tree_bdev+0x175/0x280 + [] vfs_get_tree+0x1a/0x80 + [] path_mount+0x6ff/0xaa0 + [] __x64_sys_mount+0x103/0x140 + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Reviewed-by: Dave Chinner +Signed-off-by: Dave Chinner +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_buf_item_recover.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c +index dc099b2f4984c..635f7f8ed9c2d 100644 +--- a/fs/xfs/xfs_buf_item_recover.c ++++ b/fs/xfs/xfs_buf_item_recover.c +@@ -1044,9 +1044,22 @@ void + xlog_free_buf_cancel_table( + struct xlog *log) + { ++ int i; ++ + if (!log->l_buf_cancel_table) + return; + ++ for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) { ++ struct xfs_buf_cancel *bc; ++ ++ while ((bc = list_first_entry_or_null( ++ &log->l_buf_cancel_table[i], ++ struct xfs_buf_cancel, bc_list))) { ++ list_del(&bc->bc_list); ++ kmem_free(bc); ++ } ++ } ++ + kmem_free(log->l_buf_cancel_table); + log->l_buf_cancel_table = NULL; + } +-- +2.42.0 + diff --git a/queue-5.15/xfs-fix-exception-caused-by-unexpected-illegal-bestc.patch b/queue-5.15/xfs-fix-exception-caused-by-unexpected-illegal-bestc.patch new file mode 100644 index 00000000000..7b74fdbc1eb --- /dev/null +++ b/queue-5.15/xfs-fix-exception-caused-by-unexpected-illegal-bestc.patch @@ -0,0 +1,159 @@ +From 558863d72c75cada9a77a0c417f40bc2258fcaec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:31 -0800 +Subject: xfs: fix exception caused by unexpected illegal bestcount in leaf dir + +From: Guo Xuenan + +[ Upstream commit 13cf24e00665c9751951a422756d975812b71173 ] + +For leaf dir, In most cases, there should be as many bestfree slots +as the dir data blocks that can fit under i_size (except for [1]). + +Root cause is we don't examin the number bestfree slots, when the slots +number less than dir data blocks, if we need to allocate new dir data +block and update the bestfree array, we will use the dir block number as +index to assign bestfree array, while we did not check the leaf buf +boundary which may cause UAF or other memory access problem. This issue +can also triggered with test cases xfs/473 from fstests. + +According to Dave Chinner & Darrick's suggestion, adding buffer verifier +to detect this abnormal situation in time. +Simplify the testcase for fstest xfs/554 [1] + +The error log is shown as follows: +================================================================== +BUG: KASAN: use-after-free in xfs_dir2_leaf_addname+0x1995/0x1ac0 +Write of size 2 at addr ffff88810168b000 by task touch/1552 +CPU: 5 PID: 1552 Comm: touch Not tainted 6.0.0-rc3+ #101 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.13.0-1ubuntu1.1 04/01/2014 +Call Trace: + + dump_stack_lvl+0x4d/0x66 + print_report.cold+0xf6/0x691 + kasan_report+0xa8/0x120 + xfs_dir2_leaf_addname+0x1995/0x1ac0 + xfs_dir_createname+0x58c/0x7f0 + xfs_create+0x7af/0x1010 + xfs_generic_create+0x270/0x5e0 + path_openat+0x270b/0x3450 + do_filp_open+0x1cf/0x2b0 + do_sys_openat2+0x46b/0x7a0 + do_sys_open+0xb7/0x130 + do_syscall_64+0x35/0x80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd +RIP: 0033:0x7fe4d9e9312b +Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0 +75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 +f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25 +RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101 +RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b +RDX: 0000000000000941 RSI: 00007ffda4c17f33 RDI: 00000000ffffff9c +RBP: 00007ffda4c17f33 R08: 0000000000000000 R09: 0000000000000000 +R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941 +R13: 00007fe4d9f631a4 R14: 00007ffda4c17f33 R15: 0000000000000000 + + +The buggy address belongs to the physical page: +page:ffffea000405a2c0 refcount:0 mapcount:0 mapping:0000000000000000 +index:0x0 pfn:0x10168b +flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff) +raw: 002fffff80000000 ffffea0004057788 ffffea000402dbc8 0000000000000000 +raw: 0000000000000000 0000000000170000 00000000ffffffff 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff88810168af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff88810168af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +>ffff88810168b000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ^ + ffff88810168b080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff88810168b100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +================================================================== +Disabling lock debugging due to kernel taint +00000000: 58 44 44 33 5b 53 35 c2 00 00 00 00 00 00 00 78 +XDD3[S5........x +XFS (sdb): Internal error xfs_dir2_data_use_free at line 1200 of file +fs/xfs/libxfs/xfs_dir2_data.c. Caller +xfs_dir2_data_use_free+0x28a/0xeb0 +CPU: 5 PID: 1552 Comm: touch Tainted: G B 6.0.0-rc3+ +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.13.0-1ubuntu1.1 04/01/2014 +Call Trace: + + dump_stack_lvl+0x4d/0x66 + xfs_corruption_error+0x132/0x150 + xfs_dir2_data_use_free+0x198/0xeb0 + xfs_dir2_leaf_addname+0xa59/0x1ac0 + xfs_dir_createname+0x58c/0x7f0 + xfs_create+0x7af/0x1010 + xfs_generic_create+0x270/0x5e0 + path_openat+0x270b/0x3450 + do_filp_open+0x1cf/0x2b0 + do_sys_openat2+0x46b/0x7a0 + do_sys_open+0xb7/0x130 + do_syscall_64+0x35/0x80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd +RIP: 0033:0x7fe4d9e9312b +Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0 +75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 +f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25 +RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101 +RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b +RDX: 0000000000000941 RSI: 00007ffda4c17f46 RDI: 00000000ffffff9c +RBP: 00007ffda4c17f46 R08: 0000000000000000 R09: 0000000000000001 +R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941 +R13: 00007fe4d9f631a4 R14: 00007ffda4c17f46 R15: 0000000000000000 + +XFS (sdb): Corruption detected. Unmount and run xfs_repair + +[1] https://lore.kernel.org/all/20220928095355.2074025-1-guoxuenan@huawei.com/ +Reviewed-by: Hou Tao +Signed-off-by: Guo Xuenan +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/libxfs/xfs_dir2_leaf.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c +index d9b66306a9a77..cb9e950a911d8 100644 +--- a/fs/xfs/libxfs/xfs_dir2_leaf.c ++++ b/fs/xfs/libxfs/xfs_dir2_leaf.c +@@ -146,6 +146,8 @@ xfs_dir3_leaf_check_int( + xfs_dir2_leaf_tail_t *ltp; + int stale; + int i; ++ bool isleaf1 = (hdr->magic == XFS_DIR2_LEAF1_MAGIC || ++ hdr->magic == XFS_DIR3_LEAF1_MAGIC); + + ltp = xfs_dir2_leaf_tail_p(geo, leaf); + +@@ -158,8 +160,7 @@ xfs_dir3_leaf_check_int( + return __this_address; + + /* Leaves and bests don't overlap in leaf format. */ +- if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC || +- hdr->magic == XFS_DIR3_LEAF1_MAGIC) && ++ if (isleaf1 && + (char *)&hdr->ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) + return __this_address; + +@@ -175,6 +176,10 @@ xfs_dir3_leaf_check_int( + } + if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) + stale++; ++ if (isleaf1 && xfs_dir2_dataptr_to_db(geo, ++ be32_to_cpu(hdr->ents[i].address)) >= ++ be32_to_cpu(ltp->bestcount)) ++ return __this_address; + } + if (hdr->stale != stale) + return __this_address; +-- +2.42.0 + diff --git a/queue-5.15/xfs-fix-false-enospc-when-performing-direct-write-on.patch b/queue-5.15/xfs-fix-false-enospc-when-performing-direct-write-on.patch new file mode 100644 index 00000000000..842e4ce3447 --- /dev/null +++ b/queue-5.15/xfs-fix-false-enospc-when-performing-direct-write-on.patch @@ -0,0 +1,348 @@ +From a8c6bde88093cff283ee60cb0338f79d8321d206 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:28 -0800 +Subject: xfs: Fix false ENOSPC when performing direct write on a delalloc + extent in cow fork + +From: Chandan Babu R + +[ Upstream commit d62113303d691bcd8d0675ae4ac63e7769afc56c ] + +On a higly fragmented filesystem a Direct IO write can fail with -ENOSPC error +even though the filesystem has sufficient number of free blocks. + +This occurs if the file offset range on which the write operation is being +performed has a delalloc extent in the cow fork and this delalloc extent +begins much before the Direct IO range. + +In such a scenario, xfs_reflink_allocate_cow() invokes xfs_bmapi_write() to +allocate the blocks mapped by the delalloc extent. The extent thus allocated +may not cover the beginning of file offset range on which the Direct IO write +was issued. Hence xfs_reflink_allocate_cow() ends up returning -ENOSPC. + +The following script reliably recreates the bug described above. + + #!/usr/bin/bash + + device=/dev/loop0 + shortdev=$(basename $device) + + mntpnt=/mnt/ + file1=${mntpnt}/file1 + file2=${mntpnt}/file2 + fragmentedfile=${mntpnt}/fragmentedfile + punchprog=/root/repos/xfstests-dev/src/punch-alternating + + errortag=/sys/fs/xfs/${shortdev}/errortag/bmap_alloc_minlen_extent + + umount $device > /dev/null 2>&1 + + echo "Create FS" + mkfs.xfs -f -m reflink=1 $device > /dev/null 2>&1 + if [[ $? != 0 ]]; then + echo "mkfs failed." + exit 1 + fi + + echo "Mount FS" + mount $device $mntpnt > /dev/null 2>&1 + if [[ $? != 0 ]]; then + echo "mount failed." + exit 1 + fi + + echo "Create source file" + xfs_io -f -c "pwrite 0 32M" $file1 > /dev/null 2>&1 + + sync + + echo "Create Reflinked file" + xfs_io -f -c "reflink $file1" $file2 &>/dev/null + + echo "Set cowextsize" + xfs_io -c "cowextsize 16M" $file1 > /dev/null 2>&1 + + echo "Fragment FS" + xfs_io -f -c "pwrite 0 64M" $fragmentedfile > /dev/null 2>&1 + sync + $punchprog $fragmentedfile + + echo "Allocate block sized extent from now onwards" + echo -n 1 > $errortag + + echo "Create 16MiB delalloc extent in CoW fork" + xfs_io -c "pwrite 0 4k" $file1 > /dev/null 2>&1 + + sync + + echo "Direct I/O write at offset 12k" + xfs_io -d -c "pwrite 12k 8k" $file1 + +This commit fixes the bug by invoking xfs_bmapi_write() in a loop until disk +blocks are allocated for atleast the starting file offset of the Direct IO +write range. + +Fixes: 3c68d44a2b49 ("xfs: allocate direct I/O COW blocks in iomap_begin") +Reported-and-Root-caused-by: Wengang Wang +Signed-off-by: Chandan Babu R +Reviewed-by: Darrick J. Wong +[djwong: slight editing to make the locking less grody, and fix some style things] +Signed-off-by: Darrick J. Wong +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_reflink.c | 198 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 163 insertions(+), 35 deletions(-) + +diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c +index 628ce65d02bb5..793bdf5ac2f76 100644 +--- a/fs/xfs/xfs_reflink.c ++++ b/fs/xfs/xfs_reflink.c +@@ -340,9 +340,41 @@ xfs_find_trim_cow_extent( + return 0; + } + +-/* Allocate all CoW reservations covering a range of blocks in a file. */ +-int +-xfs_reflink_allocate_cow( ++static int ++xfs_reflink_convert_unwritten( ++ struct xfs_inode *ip, ++ struct xfs_bmbt_irec *imap, ++ struct xfs_bmbt_irec *cmap, ++ bool convert_now) ++{ ++ xfs_fileoff_t offset_fsb = imap->br_startoff; ++ xfs_filblks_t count_fsb = imap->br_blockcount; ++ int error; ++ ++ /* ++ * cmap might larger than imap due to cowextsize hint. ++ */ ++ xfs_trim_extent(cmap, offset_fsb, count_fsb); ++ ++ /* ++ * COW fork extents are supposed to remain unwritten until we're ready ++ * to initiate a disk write. For direct I/O we are going to write the ++ * data and need the conversion, but for buffered writes we're done. ++ */ ++ if (!convert_now || cmap->br_state == XFS_EXT_NORM) ++ return 0; ++ ++ trace_xfs_reflink_convert_cow(ip, cmap); ++ ++ error = xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb); ++ if (!error) ++ cmap->br_state = XFS_EXT_NORM; ++ ++ return error; ++} ++ ++static int ++xfs_reflink_fill_cow_hole( + struct xfs_inode *ip, + struct xfs_bmbt_irec *imap, + struct xfs_bmbt_irec *cmap, +@@ -351,25 +383,12 @@ xfs_reflink_allocate_cow( + bool convert_now) + { + struct xfs_mount *mp = ip->i_mount; +- xfs_fileoff_t offset_fsb = imap->br_startoff; +- xfs_filblks_t count_fsb = imap->br_blockcount; + struct xfs_trans *tp; +- int nimaps, error = 0; +- bool found; + xfs_filblks_t resaligned; +- xfs_extlen_t resblks = 0; +- +- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); +- if (!ip->i_cowfp) { +- ASSERT(!xfs_is_reflink_inode(ip)); +- xfs_ifork_init_cow(ip); +- } +- +- error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); +- if (error || !*shared) +- return error; +- if (found) +- goto convert; ++ xfs_extlen_t resblks; ++ int nimaps; ++ int error; ++ bool found; + + resaligned = xfs_aligned_fsb_count(imap->br_startoff, + imap->br_blockcount, xfs_get_cowextsz_hint(ip)); +@@ -385,17 +404,17 @@ xfs_reflink_allocate_cow( + + *lockmode = XFS_ILOCK_EXCL; + +- /* +- * Check for an overlapping extent again now that we dropped the ilock. +- */ + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); + if (error || !*shared) + goto out_trans_cancel; ++ + if (found) { + xfs_trans_cancel(tp); + goto convert; + } + ++ ASSERT(cmap->br_startoff > imap->br_startoff); ++ + /* Allocate the entire reservation as unwritten blocks. */ + nimaps = 1; + error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, +@@ -415,26 +434,135 @@ xfs_reflink_allocate_cow( + */ + if (nimaps == 0) + return -ENOSPC; ++ + convert: +- xfs_trim_extent(cmap, offset_fsb, count_fsb); +- /* +- * COW fork extents are supposed to remain unwritten until we're ready +- * to initiate a disk write. For direct I/O we are going to write the +- * data and need the conversion, but for buffered writes we're done. +- */ +- if (!convert_now || cmap->br_state == XFS_EXT_NORM) +- return 0; +- trace_xfs_reflink_convert_cow(ip, cmap); +- error = xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb); +- if (!error) +- cmap->br_state = XFS_EXT_NORM; ++ return xfs_reflink_convert_unwritten(ip, imap, cmap, convert_now); ++ ++out_trans_cancel: ++ xfs_trans_cancel(tp); + return error; ++} ++ ++static int ++xfs_reflink_fill_delalloc( ++ struct xfs_inode *ip, ++ struct xfs_bmbt_irec *imap, ++ struct xfs_bmbt_irec *cmap, ++ bool *shared, ++ uint *lockmode, ++ bool convert_now) ++{ ++ struct xfs_mount *mp = ip->i_mount; ++ struct xfs_trans *tp; ++ int nimaps; ++ int error; ++ bool found; ++ ++ do { ++ xfs_iunlock(ip, *lockmode); ++ *lockmode = 0; ++ ++ error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write, 0, 0, ++ false, &tp); ++ if (error) ++ return error; ++ ++ *lockmode = XFS_ILOCK_EXCL; ++ ++ error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, ++ &found); ++ if (error || !*shared) ++ goto out_trans_cancel; ++ ++ if (found) { ++ xfs_trans_cancel(tp); ++ break; ++ } ++ ++ ASSERT(isnullstartblock(cmap->br_startblock) || ++ cmap->br_startblock == DELAYSTARTBLOCK); ++ ++ /* ++ * Replace delalloc reservation with an unwritten extent. ++ */ ++ nimaps = 1; ++ error = xfs_bmapi_write(tp, ip, cmap->br_startoff, ++ cmap->br_blockcount, ++ XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, 0, ++ cmap, &nimaps); ++ if (error) ++ goto out_trans_cancel; ++ ++ xfs_inode_set_cowblocks_tag(ip); ++ error = xfs_trans_commit(tp); ++ if (error) ++ return error; ++ ++ /* ++ * Allocation succeeded but the requested range was not even ++ * partially satisfied? Bail out! ++ */ ++ if (nimaps == 0) ++ return -ENOSPC; ++ } while (cmap->br_startoff + cmap->br_blockcount <= imap->br_startoff); ++ ++ return xfs_reflink_convert_unwritten(ip, imap, cmap, convert_now); + + out_trans_cancel: + xfs_trans_cancel(tp); + return error; + } + ++/* Allocate all CoW reservations covering a range of blocks in a file. */ ++int ++xfs_reflink_allocate_cow( ++ struct xfs_inode *ip, ++ struct xfs_bmbt_irec *imap, ++ struct xfs_bmbt_irec *cmap, ++ bool *shared, ++ uint *lockmode, ++ bool convert_now) ++{ ++ int error; ++ bool found; ++ ++ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ++ if (!ip->i_cowfp) { ++ ASSERT(!xfs_is_reflink_inode(ip)); ++ xfs_ifork_init_cow(ip); ++ } ++ ++ error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); ++ if (error || !*shared) ++ return error; ++ ++ /* CoW fork has a real extent */ ++ if (found) ++ return xfs_reflink_convert_unwritten(ip, imap, cmap, ++ convert_now); ++ ++ /* ++ * CoW fork does not have an extent and data extent is shared. ++ * Allocate a real extent in the CoW fork. ++ */ ++ if (cmap->br_startoff > imap->br_startoff) ++ return xfs_reflink_fill_cow_hole(ip, imap, cmap, shared, ++ lockmode, convert_now); ++ ++ /* ++ * CoW fork has a delalloc reservation. Replace it with a real extent. ++ * There may or may not be a data fork mapping. ++ */ ++ if (isnullstartblock(cmap->br_startblock) || ++ cmap->br_startblock == DELAYSTARTBLOCK) ++ return xfs_reflink_fill_delalloc(ip, imap, cmap, shared, ++ lockmode, convert_now); ++ ++ /* Shouldn't get here. */ ++ ASSERT(0); ++ return -EFSCORRUPTED; ++} ++ + /* + * Cancel CoW reservations for some block range of an inode. + * +-- +2.42.0 + diff --git a/queue-5.15/xfs-fix-inode-reservation-space-for-removing-transac.patch b/queue-5.15/xfs-fix-inode-reservation-space-for-removing-transac.patch new file mode 100644 index 00000000000..026d77a7e4b --- /dev/null +++ b/queue-5.15/xfs-fix-inode-reservation-space-for-removing-transac.patch @@ -0,0 +1,60 @@ +From 731e97e945f43f9b12467685ac0b5894781c5ed3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:29 -0800 +Subject: xfs: fix inode reservation space for removing transaction + +From: hexiaole + +[ Upstream commit 031d166f968efba6e4f091ff75d0bb5206bb3918 ] + +In 'fs/xfs/libxfs/xfs_trans_resv.c', the comment for transaction of removing a +directory entry writes: + +/* fs/xfs/libxfs/xfs_trans_resv.c begin */ +/* + * For removing a directory entry we can modify: + * the parent directory inode: inode size + * the removed inode: inode size +... +xfs_calc_remove_reservation( + struct xfs_mount *mp) +{ + return XFS_DQUOT_LOGRES(mp) + + xfs_calc_iunlink_add_reservation(mp) + + max((xfs_calc_inode_res(mp, 1) + +... +/* fs/xfs/libxfs/xfs_trans_resv.c end */ + +There has 2 inode size of space to be reserverd, but the actual code +for inode reservation space writes. + +There only count for 1 inode size to be reserved in +'xfs_calc_inode_res(mp, 1)', rather than 2. + +Signed-off-by: hexiaole +Reviewed-by: Darrick J. Wong +[djwong: remove redundant code citations] +Signed-off-by: Darrick J. Wong +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/libxfs/xfs_trans_resv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c +index 5e300daa25593..2db9d9d123444 100644 +--- a/fs/xfs/libxfs/xfs_trans_resv.c ++++ b/fs/xfs/libxfs/xfs_trans_resv.c +@@ -423,7 +423,7 @@ xfs_calc_remove_reservation( + { + return XFS_DQUOT_LOGRES(mp) + + xfs_calc_iunlink_add_reservation(mp) + +- max((xfs_calc_inode_res(mp, 1) + ++ max((xfs_calc_inode_res(mp, 2) + + xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), + XFS_FSB_TO_B(mp, 1))), + (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + +-- +2.42.0 + diff --git a/queue-5.15/xfs-fix-intermittent-hang-during-quotacheck.patch b/queue-5.15/xfs-fix-intermittent-hang-during-quotacheck.patch new file mode 100644 index 00000000000..894a2c69937 --- /dev/null +++ b/queue-5.15/xfs-fix-intermittent-hang-during-quotacheck.patch @@ -0,0 +1,92 @@ +From 7377595416c727de6fbd74cddd68f9081abf7405 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:26 -0800 +Subject: xfs: fix intermittent hang during quotacheck + +From: Darrick J. Wong + +[ Upstream commit f0c2d7d2abca24d19831c99edea458704fac8087 ] + +Every now and then, I see the following hang during mount time +quotacheck when running fstests. Turning on KASAN seems to make it +happen somewhat more frequently. I've edited the backtrace for brevity. + +XFS (sdd): Quotacheck needed: Please wait. +XFS: Assertion failed: bp->b_flags & _XBF_DELWRI_Q, file: fs/xfs/xfs_buf.c, line: 2411 +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 1831409 at fs/xfs/xfs_message.c:104 assfail+0x46/0x4a [xfs] +CPU: 0 PID: 1831409 Comm: mount Tainted: G W 5.19.0-rc6-xfsx #rc6 09911566947b9f737b036b4af85e399e4b9aef64 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 +RIP: 0010:assfail+0x46/0x4a [xfs] +Code: a0 8f 41 a0 e8 45 fe ff ff 8a 1d 2c 36 10 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 c0 f0 4f a0 e8 10 f0 02 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24 +RSP: 0018:ffffc900078c7b30 EFLAGS: 00010246 +RAX: 0000000000000000 RBX: ffff8880099ac000 RCX: 000000007fffffff +RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffffa0418fa0 +RBP: ffff8880197bc1c0 R08: 0000000000000000 R09: 000000000000000a +R10: 000000000000000a R11: f000000000000000 R12: ffffc900078c7d20 +R13: 00000000fffffff5 R14: ffffc900078c7d20 R15: 0000000000000000 +FS: 00007f0449903800(0000) GS:ffff88803ec00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00005610ada631f0 CR3: 0000000014dd8002 CR4: 00000000001706f0 +Call Trace: + + xfs_buf_delwri_pushbuf+0x150/0x160 [xfs 4561f5b32c9bfb874ec98d58d0719464e1f87368] + xfs_qm_flush_one+0xd6/0x130 [xfs 4561f5b32c9bfb874ec98d58d0719464e1f87368] + xfs_qm_dquot_walk.isra.0+0x109/0x1e0 [xfs 4561f5b32c9bfb874ec98d58d0719464e1f87368] + xfs_qm_quotacheck+0x319/0x490 [xfs 4561f5b32c9bfb874ec98d58d0719464e1f87368] + xfs_qm_mount_quotas+0x65/0x2c0 [xfs 4561f5b32c9bfb874ec98d58d0719464e1f87368] + xfs_mountfs+0x6b5/0xab0 [xfs 4561f5b32c9bfb874ec98d58d0719464e1f87368] + xfs_fs_fill_super+0x781/0x990 [xfs 4561f5b32c9bfb874ec98d58d0719464e1f87368] + get_tree_bdev+0x175/0x280 + vfs_get_tree+0x1a/0x80 + path_mount+0x6f5/0xaa0 + __x64_sys_mount+0x103/0x140 + do_syscall_64+0x2b/0x80 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +I /think/ this can happen if xfs_qm_flush_one is racing with +xfs_qm_dquot_isolate (i.e. dquot reclaim) when the second function has +taken the dquot flush lock but xfs_qm_dqflush hasn't yet locked the +dquot buffer, let alone queued it to the delwri list. In this case, +flush_one will fail to get the dquot flush lock, but it can lock the +incore buffer, but xfs_buf_delwri_pushbuf will then trip over this +ASSERT, which checks that the buffer isn't on a delwri list. The hang +results because the _delwri_submit_buffers ignores non DELWRI_Q buffers, +which means that xfs_buf_iowait waits forever for an IO that has not yet +been scheduled. + +AFAICT, a reasonable solution here is to detect a dquot buffer that is +not on a DELWRI list, drop it, and return -EAGAIN to try the flush +again. It's not /that/ big of a deal if quotacheck writes the dquot +buffer repeatedly before we even set QUOTA_CHKD. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_qm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c +index 623244650a2f0..792736e29a37a 100644 +--- a/fs/xfs/xfs_qm.c ++++ b/fs/xfs/xfs_qm.c +@@ -1244,6 +1244,13 @@ xfs_qm_flush_one( + error = -EINVAL; + goto out_unlock; + } ++ ++ if (!(bp->b_flags & _XBF_DELWRI_Q)) { ++ error = -EAGAIN; ++ xfs_buf_relse(bp); ++ goto out_unlock; ++ } ++ + xfs_buf_unlock(bp); + + xfs_buf_delwri_pushbuf(bp, buffer_list); +-- +2.42.0 + diff --git a/queue-5.15/xfs-fix-memory-leak-in-xfs_errortag_init.patch b/queue-5.15/xfs-fix-memory-leak-in-xfs_errortag_init.patch new file mode 100644 index 00000000000..1b4a667a10b --- /dev/null +++ b/queue-5.15/xfs-fix-memory-leak-in-xfs_errortag_init.patch @@ -0,0 +1,70 @@ +From dff838523cc68600aebc163f1ac6bc8fce775c7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:32 -0800 +Subject: xfs: fix memory leak in xfs_errortag_init + +From: Zeng Heng + +[ Upstream commit cf4f4c12dea7a977a143c8fe5af1740b7f9876f8 ] + +When `xfs_sysfs_init` returns failed, `mp->m_errortag` needs to free. +Otherwise kmemleak would report memory leak after mounting xfs image: + +unreferenced object 0xffff888101364900 (size 192): + comm "mount", pid 13099, jiffies 4294915218 (age 335.207s) + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [<00000000f08ad25c>] __kmalloc+0x41/0x1b0 + [<00000000dca9aeb6>] kmem_alloc+0xfd/0x430 + [<0000000040361882>] xfs_errortag_init+0x20/0x110 + [<00000000b384a0f6>] xfs_mountfs+0x6ea/0x1a30 + [<000000003774395d>] xfs_fs_fill_super+0xe10/0x1a80 + [<000000009cf07b6c>] get_tree_bdev+0x3e7/0x700 + [<00000000046b5426>] vfs_get_tree+0x8e/0x2e0 + [<00000000952ec082>] path_mount+0xf8c/0x1990 + [<00000000beb1f838>] do_mount+0xee/0x110 + [<000000000e9c41bb>] __x64_sys_mount+0x14b/0x1f0 + [<00000000f7bb938e>] do_syscall_64+0x3b/0x90 + [<000000003fcd67a9>] entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fixes: c68401011522 ("xfs: expose errortag knobs via sysfs") +Signed-off-by: Zeng Heng +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_error.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c +index 81c445e9489bd..b0ccec92e015d 100644 +--- a/fs/xfs/xfs_error.c ++++ b/fs/xfs/xfs_error.c +@@ -224,13 +224,18 @@ int + xfs_errortag_init( + struct xfs_mount *mp) + { ++ int ret; ++ + mp->m_errortag = kmem_zalloc(sizeof(unsigned int) * XFS_ERRTAG_MAX, + KM_MAYFAIL); + if (!mp->m_errortag) + return -ENOMEM; + +- return xfs_sysfs_init(&mp->m_errortag_kobj, &xfs_errortag_ktype, +- &mp->m_kobj, "errortag"); ++ ret = xfs_sysfs_init(&mp->m_errortag_kobj, &xfs_errortag_ktype, ++ &mp->m_kobj, "errortag"); ++ if (ret) ++ kmem_free(mp->m_errortag); ++ return ret; + } + + void +-- +2.42.0 + diff --git a/queue-5.15/xfs-fix-null-pointer-dereference-in-xfs_getbmap.patch b/queue-5.15/xfs-fix-null-pointer-dereference-in-xfs_getbmap.patch new file mode 100644 index 00000000000..3dd2f2d8954 --- /dev/null +++ b/queue-5.15/xfs-fix-null-pointer-dereference-in-xfs_getbmap.patch @@ -0,0 +1,105 @@ +From 79cf525cf24d0528b8147c8c6b07b76b953f122f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:25 -0800 +Subject: xfs: fix NULL pointer dereference in xfs_getbmap() + +From: ChenXiaoSong + +[ Upstream commit 001c179c4e26d04db8c9f5e3fef9558b58356be6 ] + +Reproducer: + 1. fallocate -l 100M image + 2. mkfs.xfs -f image + 3. mount image /mnt + 4. setxattr("/mnt", "trusted.overlay.upper", NULL, 0, XATTR_CREATE) + 5. char arg[32] = "\x01\xff\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x08\x00\x00\x00\xc6\x2a\xf7"; + fd = open("/mnt", O_RDONLY|O_DIRECTORY); + ioctl(fd, _IOC(_IOC_READ|_IOC_WRITE, 0x58, 0x2c, 0x20), arg); + +NULL pointer dereference will occur when race happens between xfs_getbmap() +and xfs_bmap_set_attrforkoff(): + + ioctl | setxattr + ----------------------------|--------------------------- + xfs_getbmap | + xfs_ifork_ptr | + xfs_inode_has_attr_fork | + ip->i_forkoff == 0 | + return NULL | + ifp == NULL | + | xfs_bmap_set_attrforkoff + | ip->i_forkoff > 0 + xfs_inode_has_attr_fork | + ip->i_forkoff > 0 | + ifp == NULL | + ifp->if_format | + +Fix this by locking i_lock before xfs_ifork_ptr(). + +Fixes: abbf9e8a4507 ("xfs: rewrite getbmap using the xfs_iext_* helpers") +Signed-off-by: ChenXiaoSong +Signed-off-by: Guo Xuenan +Reviewed-by: Darrick J. Wong +[djwong: added fixes tag] +Signed-off-by: Darrick J. Wong +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_bmap_util.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c +index fd2ad6a3019ca..bea6cc26abf99 100644 +--- a/fs/xfs/xfs_bmap_util.c ++++ b/fs/xfs/xfs_bmap_util.c +@@ -439,29 +439,28 @@ xfs_getbmap( + whichfork = XFS_COW_FORK; + else + whichfork = XFS_DATA_FORK; +- ifp = XFS_IFORK_PTR(ip, whichfork); + + xfs_ilock(ip, XFS_IOLOCK_SHARED); + switch (whichfork) { + case XFS_ATTR_FORK: ++ lock = xfs_ilock_attr_map_shared(ip); + if (!XFS_IFORK_Q(ip)) +- goto out_unlock_iolock; ++ goto out_unlock_ilock; + + max_len = 1LL << 32; +- lock = xfs_ilock_attr_map_shared(ip); + break; + case XFS_COW_FORK: ++ lock = XFS_ILOCK_SHARED; ++ xfs_ilock(ip, lock); ++ + /* No CoW fork? Just return */ +- if (!ifp) +- goto out_unlock_iolock; ++ if (!XFS_IFORK_PTR(ip, whichfork)) ++ goto out_unlock_ilock; + + if (xfs_get_cowextsz_hint(ip)) + max_len = mp->m_super->s_maxbytes; + else + max_len = XFS_ISIZE(ip); +- +- lock = XFS_ILOCK_SHARED; +- xfs_ilock(ip, lock); + break; + case XFS_DATA_FORK: + if (!(iflags & BMV_IF_DELALLOC) && +@@ -491,6 +490,8 @@ xfs_getbmap( + break; + } + ++ ifp = XFS_IFORK_PTR(ip, whichfork); ++ + switch (ifp->if_format) { + case XFS_DINODE_FMT_EXTENTS: + case XFS_DINODE_FMT_BTREE: +-- +2.42.0 + diff --git a/queue-5.15/xfs-fix-unreferenced-object-reported-by-kmemleak-in-.patch b/queue-5.15/xfs-fix-unreferenced-object-reported-by-kmemleak-in-.patch new file mode 100644 index 00000000000..1536ba495ce --- /dev/null +++ b/queue-5.15/xfs-fix-unreferenced-object-reported-by-kmemleak-in-.patch @@ -0,0 +1,70 @@ +From e9c83515c6d0db122e38cf25990d26e63bc560e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:33 -0800 +Subject: xfs: Fix unreferenced object reported by kmemleak in xfs_sysfs_init() + +From: Li Zetao + +[ Upstream commit d08af40340cad0e025d643c3982781a8f99d5032 ] + +kmemleak reported a sequence of memory leaks, and one of them indicated we +failed to free a pointer: + comm "mount", pid 19610, jiffies 4297086464 (age 60.635s) + hex dump (first 8 bytes): + 73 64 61 00 81 88 ff ff sda..... + backtrace: + [<00000000d77f3e04>] kstrdup_const+0x46/0x70 + [<00000000e51fa804>] kobject_set_name_vargs+0x2f/0xb0 + [<00000000247cd595>] kobject_init_and_add+0xb0/0x120 + [<00000000f9139aaf>] xfs_mountfs+0x367/0xfc0 + [<00000000250d3caf>] xfs_fs_fill_super+0xa16/0xdc0 + [<000000008d873d38>] get_tree_bdev+0x256/0x390 + [<000000004881f3fa>] vfs_get_tree+0x41/0xf0 + [<000000008291ab52>] path_mount+0x9b3/0xdd0 + [<0000000022ba8f2d>] __x64_sys_mount+0x190/0x1d0 + +As mentioned in kobject_init_and_add() comment, if this function +returns an error, kobject_put() must be called to properly clean up +the memory associated with the object. Apparently, xfs_sysfs_init() +does not follow such a requirement. When kobject_init_and_add() +returns an error, the space of kobj->kobject.name alloced by +kstrdup_const() is unfree, which will cause the above stack. + +Fix it by adding kobject_put() when kobject_init_and_add returns an +error. + +Fixes: a31b1d3d89e4 ("xfs: add xfs_mount sysfs kobject") +Signed-off-by: Li Zetao +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_sysfs.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/xfs/xfs_sysfs.h b/fs/xfs/xfs_sysfs.h +index 43585850f1546..513095e353a5b 100644 +--- a/fs/xfs/xfs_sysfs.h ++++ b/fs/xfs/xfs_sysfs.h +@@ -33,10 +33,15 @@ xfs_sysfs_init( + const char *name) + { + struct kobject *parent; ++ int err; + + parent = parent_kobj ? &parent_kobj->kobject : NULL; + init_completion(&kobj->complete); +- return kobject_init_and_add(&kobj->kobject, ktype, parent, "%s", name); ++ err = kobject_init_and_add(&kobj->kobject, ktype, parent, "%s", name); ++ if (err) ++ kobject_put(&kobj->kobject); ++ ++ return err; + } + + static inline void +-- +2.42.0 + diff --git a/queue-5.15/xfs-fix-use-after-free-in-xattr-node-block-inactivat.patch b/queue-5.15/xfs-fix-use-after-free-in-xattr-node-block-inactivat.patch new file mode 100644 index 00000000000..c2c723ed77a --- /dev/null +++ b/queue-5.15/xfs-fix-use-after-free-in-xattr-node-block-inactivat.patch @@ -0,0 +1,160 @@ +From ea82a2c4763ca38dcb13d0ce3805a3ea0fb1ff03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:23 -0800 +Subject: xfs: fix use-after-free in xattr node block inactivation + +From: Darrick J. Wong + +[ Upstream commit 95ff0363f3f6ae70c21a0f2b0603e54438e5988b ] + +The kernel build robot reported a UAF error while running xfs/433 +(edited somewhat for brevity): + + BUG: KASAN: use-after-free in xfs_attr3_node_inactive (fs/xfs/xfs_attr_inactive.c:214) xfs + Read of size 4 at addr ffff88820ac2bd44 by task kworker/0:2/139 + + CPU: 0 PID: 139 Comm: kworker/0:2 Tainted: G S 5.19.0-rc2-00004-g7cf2b0f9611b #1 + Hardware name: Hewlett-Packard p6-1451cx/2ADA, BIOS 8.15 02/05/2013 + Workqueue: xfs-inodegc/sdb4 xfs_inodegc_worker [xfs] + Call Trace: + + dump_stack_lvl (lib/dump_stack.c:107 (discriminator 1)) + print_address_description+0x1f/0x200 + print_report.cold (mm/kasan/report.c:430) + kasan_report (mm/kasan/report.c:162 mm/kasan/report.c:493) + xfs_attr3_node_inactive (fs/xfs/xfs_attr_inactive.c:214) xfs + xfs_attr3_root_inactive (fs/xfs/xfs_attr_inactive.c:296) xfs + xfs_attr_inactive (fs/xfs/xfs_attr_inactive.c:371) xfs + xfs_inactive (fs/xfs/xfs_inode.c:1781) xfs + xfs_inodegc_worker (fs/xfs/xfs_icache.c:1837 fs/xfs/xfs_icache.c:1860) xfs + process_one_work + worker_thread + kthread + ret_from_fork + + + Allocated by task 139: + kasan_save_stack (mm/kasan/common.c:39) + __kasan_slab_alloc (mm/kasan/common.c:45 mm/kasan/common.c:436 mm/kasan/common.c:469) + kmem_cache_alloc (mm/slab.h:750 mm/slub.c:3214 mm/slub.c:3222 mm/slub.c:3229 mm/slub.c:3239) + _xfs_buf_alloc (include/linux/instrumented.h:86 include/linux/atomic/atomic-instrumented.h:41 fs/xfs/xfs_buf.c:232) xfs + xfs_buf_get_map (fs/xfs/xfs_buf.c:660) xfs + xfs_buf_read_map (fs/xfs/xfs_buf.c:777) xfs + xfs_trans_read_buf_map (fs/xfs/xfs_trans_buf.c:289) xfs + xfs_da_read_buf (fs/xfs/libxfs/xfs_da_btree.c:2652) xfs + xfs_da3_node_read (fs/xfs/libxfs/xfs_da_btree.c:392) xfs + xfs_attr3_root_inactive (fs/xfs/xfs_attr_inactive.c:272) xfs + xfs_attr_inactive (fs/xfs/xfs_attr_inactive.c:371) xfs + xfs_inactive (fs/xfs/xfs_inode.c:1781) xfs + xfs_inodegc_worker (fs/xfs/xfs_icache.c:1837 fs/xfs/xfs_icache.c:1860) xfs + process_one_work + worker_thread + kthread + ret_from_fork + + Freed by task 139: + kasan_save_stack (mm/kasan/common.c:39) + kasan_set_track (mm/kasan/common.c:45) + kasan_set_free_info (mm/kasan/generic.c:372) + __kasan_slab_free (mm/kasan/common.c:368 mm/kasan/common.c:328 mm/kasan/common.c:374) + kmem_cache_free (mm/slub.c:1753 mm/slub.c:3507 mm/slub.c:3524) + xfs_buf_rele (fs/xfs/xfs_buf.c:1040) xfs + xfs_attr3_node_inactive (fs/xfs/xfs_attr_inactive.c:210) xfs + xfs_attr3_root_inactive (fs/xfs/xfs_attr_inactive.c:296) xfs + xfs_attr_inactive (fs/xfs/xfs_attr_inactive.c:371) xfs + xfs_inactive (fs/xfs/xfs_inode.c:1781) xfs + xfs_inodegc_worker (fs/xfs/xfs_icache.c:1837 fs/xfs/xfs_icache.c:1860) xfs + process_one_work + worker_thread + kthread + ret_from_fork + +I reproduced this for my own satisfaction, and got the same report, +along with an extra morsel: + + The buggy address belongs to the object at ffff88802103a800 + which belongs to the cache xfs_buf of size 432 + The buggy address is located 396 bytes inside of + 432-byte region [ffff88802103a800, ffff88802103a9b0) + +I tracked this code down to: + + error = xfs_trans_get_buf(*trans, mp->m_ddev_targp, + child_blkno, + XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0, + &child_bp); + if (error) + return error; + error = bp->b_error; + +That doesn't look right -- I think this should be dereferencing +child_bp, not bp. Looking through the codebase history, I think this +was added by commit 2911edb653b9 ("xfs: remove the mappedbno argument to +xfs_da_get_buf"), which replaced a call to xfs_da_get_buf with the +current call to xfs_trans_get_buf. Not sure why we trans_brelse'd @bp +earlier in the function, but I'm guessing it's to avoid pinning too many +buffers in memory while we inactivate the bottom of the attr tree. +Hence we now have to get the buffer back. + +I /think/ this was supposed to check child_bp->b_error and fail the rest +of the invalidation if child_bp had experienced any kind of IO or +corruption error. I bet the xfs_da3_node_read earlier in the loop will +catch most cases of incoming on-disk corruption which makes this check +mostly moot unless someone corrupts the buffer and the AIL pushes it out +to disk while the buffer's unlocked. + +In the first case we'll never get to the bad check, and in the second +case the AIL will shut down the log, at which point there's no reason to +check b_error. Remove the check, and null out @bp to avoid this problem +in the future. + +Cc: hch@lst.de +Reported-by: kernel test robot +Fixes: 2911edb653b9 ("xfs: remove the mappedbno argument to xfs_da_get_buf") +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Reviewed-by: Christoph Hellwig +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_attr_inactive.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c +index 2b5da6218977c..2afa6d9a7f8f6 100644 +--- a/fs/xfs/xfs_attr_inactive.c ++++ b/fs/xfs/xfs_attr_inactive.c +@@ -158,6 +158,7 @@ xfs_attr3_node_inactive( + } + child_fsb = be32_to_cpu(ichdr.btree[0].before); + xfs_trans_brelse(*trans, bp); /* no locks for later trans */ ++ bp = NULL; + + /* + * If this is the node level just above the leaves, simply loop +@@ -211,12 +212,8 @@ xfs_attr3_node_inactive( + &child_bp); + if (error) + return error; +- error = bp->b_error; +- if (error) { +- xfs_trans_brelse(*trans, child_bp); +- return error; +- } + xfs_trans_binval(*trans, child_bp); ++ child_bp = NULL; + + /* + * If we're not done, re-read the parent to get the next +@@ -233,6 +230,7 @@ xfs_attr3_node_inactive( + bp->b_addr); + child_fsb = be32_to_cpu(phdr.btree[i + 1].before); + xfs_trans_brelse(*trans, bp); ++ bp = NULL; + } + /* + * Atomically commit the whole invalidate stuff. +-- +2.42.0 + diff --git a/queue-5.15/xfs-flush-inode-gc-workqueue-before-clearing-agi-buc.patch b/queue-5.15/xfs-flush-inode-gc-workqueue-before-clearing-agi-buc.patch new file mode 100644 index 00000000000..f5ae65a2b81 --- /dev/null +++ b/queue-5.15/xfs-flush-inode-gc-workqueue-before-clearing-agi-buc.patch @@ -0,0 +1,51 @@ +From 8f948ad0ae2dd0d2d0f83a858ebb3a9af97215e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:22 -0800 +Subject: xfs: flush inode gc workqueue before clearing agi bucket + +From: Zhang Yi + +[ Upstream commit 04a98a036cf8b810dda172a9dcfcbd783bf63655 ] + +In the procedure of recover AGI unlinked lists, if something bad +happenes on one of the unlinked inode in the bucket list, we would call +xlog_recover_clear_agi_bucket() to clear the whole unlinked bucket list, +not the unlinked inodes after the bad one. If we have already added some +inodes to the gc workqueue before the bad inode in the list, we could +get below error when freeing those inodes, and finaly fail to complete +the log recover procedure. + + XFS (ram0): Internal error xfs_iunlink_remove at line 2456 of file + fs/xfs/xfs_inode.c. Caller xfs_ifree+0xb0/0x360 [xfs] + +The problem is xlog_recover_clear_agi_bucket() clear the bucket list, so +the gc worker fail to check the agino in xfs_verify_agino(). Fix this by +flush workqueue before clearing the bucket. + +Fixes: ab23a7768739 ("xfs: per-cpu deferred inode inactivation queues") +Signed-off-by: Zhang Yi +Reviewed-by: Dave Chinner +Reviewed-by: Darrick J. Wong +Signed-off-by: Dave Chinner +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_log_recover.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c +index aeb01d4c0423b..04961ebf16ea2 100644 +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -2739,6 +2739,7 @@ xlog_recover_process_one_iunlink( + * Call xlog_recover_clear_agi_bucket() to perform a transaction to + * clear the inode pointer in the bucket. + */ ++ xfs_inodegc_flush(mp); + xlog_recover_clear_agi_bucket(mp, agno, bucket); + return NULLAGINO; + } +-- +2.42.0 + diff --git a/queue-5.15/xfs-prevent-a-uaf-when-log-io-errors-race-with-unmou.patch b/queue-5.15/xfs-prevent-a-uaf-when-log-io-errors-race-with-unmou.patch new file mode 100644 index 00000000000..d528ecf28ca --- /dev/null +++ b/queue-5.15/xfs-prevent-a-uaf-when-log-io-errors-race-with-unmou.patch @@ -0,0 +1,160 @@ +From 847095b1164c7b693510e6c0a8616613b780f59d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:21 -0800 +Subject: xfs: prevent a UAF when log IO errors race with unmount + +From: Darrick J. Wong + +[ Upstream commit 7561cea5dbb97fecb952548a0fb74fb105bf4664 ] + +KASAN reported the following use after free bug when running +generic/475: + + XFS (dm-0): Mounting V5 Filesystem + XFS (dm-0): Starting recovery (logdev: internal) + XFS (dm-0): Ending recovery (logdev: internal) + Buffer I/O error on dev dm-0, logical block 20639616, async page read + Buffer I/O error on dev dm-0, logical block 20639617, async page read + XFS (dm-0): log I/O error -5 + XFS (dm-0): Filesystem has been shut down due to log error (0x2). + XFS (dm-0): Unmounting Filesystem + XFS (dm-0): Please unmount the filesystem and rectify the problem(s). + ================================================================== + BUG: KASAN: use-after-free in do_raw_spin_lock+0x246/0x270 + Read of size 4 at addr ffff888109dd84c4 by task 3:1H/136 + + CPU: 3 PID: 136 Comm: 3:1H Not tainted 5.19.0-rc4-xfsx #rc4 8e53ab5ad0fddeb31cee5e7063ff9c361915a9c4 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 + Workqueue: xfs-log/dm-0 xlog_ioend_work [xfs] + Call Trace: + + dump_stack_lvl+0x34/0x44 + print_report.cold+0x2b8/0x661 + ? do_raw_spin_lock+0x246/0x270 + kasan_report+0xab/0x120 + ? do_raw_spin_lock+0x246/0x270 + do_raw_spin_lock+0x246/0x270 + ? rwlock_bug.part.0+0x90/0x90 + xlog_force_shutdown+0xf6/0x370 [xfs 4ad76ae0d6add7e8183a553e624c31e9ed567318] + xlog_ioend_work+0x100/0x190 [xfs 4ad76ae0d6add7e8183a553e624c31e9ed567318] + process_one_work+0x672/0x1040 + worker_thread+0x59b/0xec0 + ? __kthread_parkme+0xc6/0x1f0 + ? process_one_work+0x1040/0x1040 + ? process_one_work+0x1040/0x1040 + kthread+0x29e/0x340 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x1f/0x30 + + + Allocated by task 154099: + kasan_save_stack+0x1e/0x40 + __kasan_kmalloc+0x81/0xa0 + kmem_alloc+0x8d/0x2e0 [xfs] + xlog_cil_init+0x1f/0x540 [xfs] + xlog_alloc_log+0xd1e/0x1260 [xfs] + xfs_log_mount+0xba/0x640 [xfs] + xfs_mountfs+0xf2b/0x1d00 [xfs] + xfs_fs_fill_super+0x10af/0x1910 [xfs] + get_tree_bdev+0x383/0x670 + vfs_get_tree+0x7d/0x240 + path_mount+0xdb7/0x1890 + __x64_sys_mount+0x1fa/0x270 + do_syscall_64+0x2b/0x80 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + + Freed by task 154151: + kasan_save_stack+0x1e/0x40 + kasan_set_track+0x21/0x30 + kasan_set_free_info+0x20/0x30 + ____kasan_slab_free+0x110/0x190 + slab_free_freelist_hook+0xab/0x180 + kfree+0xbc/0x310 + xlog_dealloc_log+0x1b/0x2b0 [xfs] + xfs_unmountfs+0x119/0x200 [xfs] + xfs_fs_put_super+0x6e/0x2e0 [xfs] + generic_shutdown_super+0x12b/0x3a0 + kill_block_super+0x95/0xd0 + deactivate_locked_super+0x80/0x130 + cleanup_mnt+0x329/0x4d0 + task_work_run+0xc5/0x160 + exit_to_user_mode_prepare+0xd4/0xe0 + syscall_exit_to_user_mode+0x1d/0x40 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +This appears to be a race between the unmount process, which frees the +CIL and waits for in-flight iclog IO; and the iclog IO completion. When +generic/475 runs, it starts fsstress in the background, waits a few +seconds, and substitutes a dm-error device to simulate a disk falling +out of a machine. If the fsstress encounters EIO on a pure data write, +it will exit but the filesystem will still be online. + +The next thing the test does is unmount the filesystem, which tries to +clean the log, free the CIL, and wait for iclog IO completion. If an +iclog was being written when the dm-error switch occurred, it can race +with log unmounting as follows: + +Thread 1 Thread 2 + + xfs_log_unmount + xfs_log_clean + xfs_log_quiesce +xlog_ioend_work + +xlog_force_shutdown +test_and_set_bit(XLOG_IOERROR) + xfs_log_force + + xfs_log_umount_write + + xlog_dealloc_log + xlog_cil_destroy + +spin_lock(&log->l_cilp->xc_push_lock) + + +Therefore, free the CIL after waiting for the iclogs to complete. I +/think/ this race has existed for quite a few years now, though I don't +remember the ~2014 era logging code well enough to know if it was a real +threat then or if the actual race was exposed only more recently. + +Fixes: ac983517ec59 ("xfs: don't sleep in xlog_cil_force_lsn on shutdown") +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_log.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c +index 0fb7d05ca308d..eba295f666acc 100644 +--- a/fs/xfs/xfs_log.c ++++ b/fs/xfs/xfs_log.c +@@ -2061,8 +2061,6 @@ xlog_dealloc_log( + xlog_in_core_t *iclog, *next_iclog; + int i; + +- xlog_cil_destroy(log); +- + /* + * Cycle all the iclogbuf locks to make sure all log IO completion + * is done before we tear down these buffers. +@@ -2074,6 +2072,13 @@ xlog_dealloc_log( + iclog = iclog->ic_next; + } + ++ /* ++ * Destroy the CIL after waiting for iclog IO completion because an ++ * iclog EIO error will try to shut down the log, which accesses the ++ * CIL to wake up the waiters. ++ */ ++ xlog_cil_destroy(log); ++ + iclog = log->l_iclog; + for (i = 0; i < log->l_iclog_bufs; i++) { + next_iclog = iclog->ic_next; +-- +2.42.0 + diff --git a/queue-5.15/xfs-refactor-buffer-cancellation-table-allocation.patch b/queue-5.15/xfs-refactor-buffer-cancellation-table-allocation.patch new file mode 100644 index 00000000000..5954ea0d1e9 --- /dev/null +++ b/queue-5.15/xfs-refactor-buffer-cancellation-table-allocation.patch @@ -0,0 +1,198 @@ +From 146025e190fadf44ac95263498a95f323d4f50a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:17 -0800 +Subject: xfs: refactor buffer cancellation table allocation + +From: Darrick J. Wong + +[ Upstream commit 2723234923b3294dbcf6019c288c87465e927ed4 ] + +Move the code that allocates and frees the buffer cancellation tables +used by log recovery into the file that actually uses the tables. This +is a precursor to some cleanups and a memory leak fix. + +( backport: dependency of 8db074bd84df5ccc88bff3f8f900f66f4b8349fa ) + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Reviewed-by: Dave Chinner +Signed-off-by: Dave Chinner +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/libxfs/xfs_log_recover.h | 14 +++++----- + fs/xfs/xfs_buf_item_recover.c | 47 +++++++++++++++++++++++++++++++++ + fs/xfs/xfs_log_priv.h | 3 --- + fs/xfs/xfs_log_recover.c | 32 +++++++--------------- + 4 files changed, 64 insertions(+), 32 deletions(-) + +diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h +index ff69a00008176..b8b65a6e9b1ec 100644 +--- a/fs/xfs/libxfs/xfs_log_recover.h ++++ b/fs/xfs/libxfs/xfs_log_recover.h +@@ -108,12 +108,6 @@ struct xlog_recover { + + #define ITEM_TYPE(i) (*(unsigned short *)(i)->ri_buf[0].i_addr) + +-/* +- * This is the number of entries in the l_buf_cancel_table used during +- * recovery. +- */ +-#define XLOG_BC_TABLE_SIZE 64 +- + #define XLOG_RECOVER_CRCPASS 0 + #define XLOG_RECOVER_PASS1 1 + #define XLOG_RECOVER_PASS2 2 +@@ -126,5 +120,13 @@ int xlog_recover_iget(struct xfs_mount *mp, xfs_ino_t ino, + struct xfs_inode **ipp); + void xlog_recover_release_intent(struct xlog *log, unsigned short intent_type, + uint64_t intent_id); ++void xlog_alloc_buf_cancel_table(struct xlog *log); ++void xlog_free_buf_cancel_table(struct xlog *log); ++ ++#ifdef DEBUG ++void xlog_check_buf_cancel_table(struct xlog *log); ++#else ++#define xlog_check_buf_cancel_table(log) do { } while (0) ++#endif + + #endif /* __XFS_LOG_RECOVER_H__ */ +diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c +index e04e44ef14c6d..dc099b2f4984c 100644 +--- a/fs/xfs/xfs_buf_item_recover.c ++++ b/fs/xfs/xfs_buf_item_recover.c +@@ -23,6 +23,15 @@ + #include "xfs_dir2.h" + #include "xfs_quota.h" + ++/* ++ * This is the number of entries in the l_buf_cancel_table used during ++ * recovery. ++ */ ++#define XLOG_BC_TABLE_SIZE 64 ++ ++#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ ++ ((log)->l_buf_cancel_table + ((uint64_t)blkno % XLOG_BC_TABLE_SIZE)) ++ + /* + * This structure is used during recovery to record the buf log items which + * have been canceled and should not be replayed. +@@ -1003,3 +1012,41 @@ const struct xlog_recover_item_ops xlog_buf_item_ops = { + .commit_pass1 = xlog_recover_buf_commit_pass1, + .commit_pass2 = xlog_recover_buf_commit_pass2, + }; ++ ++#ifdef DEBUG ++void ++xlog_check_buf_cancel_table( ++ struct xlog *log) ++{ ++ int i; ++ ++ for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) ++ ASSERT(list_empty(&log->l_buf_cancel_table[i])); ++} ++#endif ++ ++void ++xlog_alloc_buf_cancel_table( ++ struct xlog *log) ++{ ++ int i; ++ ++ ASSERT(log->l_buf_cancel_table == NULL); ++ ++ log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE * ++ sizeof(struct list_head), ++ 0); ++ for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) ++ INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); ++} ++ ++void ++xlog_free_buf_cancel_table( ++ struct xlog *log) ++{ ++ if (!log->l_buf_cancel_table) ++ return; ++ ++ kmem_free(log->l_buf_cancel_table); ++ log->l_buf_cancel_table = NULL; ++} +diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h +index f3d68ca39f45c..03393595676f4 100644 +--- a/fs/xfs/xfs_log_priv.h ++++ b/fs/xfs/xfs_log_priv.h +@@ -454,9 +454,6 @@ struct xlog { + struct rw_semaphore l_incompat_users; + }; + +-#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ +- ((log)->l_buf_cancel_table + ((uint64_t)blkno % XLOG_BC_TABLE_SIZE)) +- + /* + * Bits for operational state + */ +diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c +index 581aeb288b32b..18d8eebc2d445 100644 +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -3248,7 +3248,7 @@ xlog_do_log_recovery( + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk) + { +- int error, i; ++ int error; + + ASSERT(head_blk != tail_blk); + +@@ -3256,37 +3256,23 @@ xlog_do_log_recovery( + * First do a pass to find all of the cancelled buf log items. + * Store them in the buf_cancel_table for use in the second pass. + */ +- log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE * +- sizeof(struct list_head), +- 0); +- for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) +- INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); ++ xlog_alloc_buf_cancel_table(log); + + error = xlog_do_recovery_pass(log, head_blk, tail_blk, + XLOG_RECOVER_PASS1, NULL); +- if (error != 0) { +- kmem_free(log->l_buf_cancel_table); +- log->l_buf_cancel_table = NULL; +- return error; +- } ++ if (error != 0) ++ goto out_cancel; ++ + /* + * Then do a second pass to actually recover the items in the log. + * When it is complete free the table of buf cancel items. + */ + error = xlog_do_recovery_pass(log, head_blk, tail_blk, + XLOG_RECOVER_PASS2, NULL); +-#ifdef DEBUG +- if (!error) { +- int i; +- +- for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) +- ASSERT(list_empty(&log->l_buf_cancel_table[i])); +- } +-#endif /* DEBUG */ +- +- kmem_free(log->l_buf_cancel_table); +- log->l_buf_cancel_table = NULL; +- ++ if (!error) ++ xlog_check_buf_cancel_table(log); ++out_cancel: ++ xlog_free_buf_cancel_table(log); + return error; + } + +-- +2.42.0 + diff --git a/queue-5.15/xfs-use-invalidate_lock-to-check-the-state-of-mmap_l.patch b/queue-5.15/xfs-use-invalidate_lock-to-check-the-state-of-mmap_l.patch new file mode 100644 index 00000000000..cddf06c674d --- /dev/null +++ b/queue-5.15/xfs-use-invalidate_lock-to-check-the-state-of-mmap_l.patch @@ -0,0 +1,43 @@ +From dcc17bafb325fc2e28d2c320d14ff6b9578a66c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Nov 2023 18:28:20 -0800 +Subject: xfs: use invalidate_lock to check the state of mmap_lock + +From: Kaixu Xia + +[ Upstream commit 82af88063961da9425924d9aec3fb67a4ebade3e ] + +We should use invalidate_lock and XFS_MMAPLOCK_SHARED to check the state +of mmap_lock rw_semaphore in xfs_isilocked(), rather than i_rwsem and +XFS_IOLOCK_SHARED. + +Fixes: 2433480a7e1d ("xfs: Convert to use invalidate_lock") +Signed-off-by: Kaixu Xia +Reviewed-by: Dave Chinner +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Leah Rumancik +Acked-by: Chandan Babu R +Signed-off-by: Sasha Levin +--- + fs/xfs/xfs_inode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c +index b2ea853182141..df64b902842dd 100644 +--- a/fs/xfs/xfs_inode.c ++++ b/fs/xfs/xfs_inode.c +@@ -378,8 +378,8 @@ xfs_isilocked( + } + + if (lock_flags & (XFS_MMAPLOCK_EXCL|XFS_MMAPLOCK_SHARED)) { +- return __xfs_rwsem_islocked(&VFS_I(ip)->i_rwsem, +- (lock_flags & XFS_IOLOCK_SHARED)); ++ return __xfs_rwsem_islocked(&VFS_I(ip)->i_mapping->invalidate_lock, ++ (lock_flags & XFS_MMAPLOCK_SHARED)); + } + + if (lock_flags & (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED)) { +-- +2.42.0 + -- 2.47.3