]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees
authorSasha Levin <sashal@kernel.org>
Fri, 14 Nov 2025 18:59:52 +0000 (13:59 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 14 Nov 2025 18:59:52 +0000 (13:59 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
209 files changed:
queue-5.10/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch [new file with mode: 0644]
queue-5.10/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch [new file with mode: 0644]
queue-5.10/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch [new file with mode: 0644]
queue-5.10/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch [new file with mode: 0644]
queue-5.10/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch [new file with mode: 0644]
queue-5.10/hsr-fix-supervision-frame-sending-on-hsrv0.patch [new file with mode: 0644]
queue-5.10/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch [new file with mode: 0644]
queue-5.10/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch [new file with mode: 0644]
queue-5.10/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch [new file with mode: 0644]
queue-5.10/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch [new file with mode: 0644]
queue-5.10/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch [new file with mode: 0644]
queue-5.10/net-smc-fix-mismatch-between-clc-header-and-proposal.patch [new file with mode: 0644]
queue-5.10/net_sched-limit-try_bulk_dequeue_skb-batches.patch [new file with mode: 0644]
queue-5.10/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch [new file with mode: 0644]
queue-5.10/wifi-mac80211-skip-rate-verification-for-not-capture.patch [new file with mode: 0644]
queue-5.15/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch [new file with mode: 0644]
queue-5.15/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch [new file with mode: 0644]
queue-5.15/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch [new file with mode: 0644]
queue-5.15/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch [new file with mode: 0644]
queue-5.15/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch [new file with mode: 0644]
queue-5.15/hsr-fix-supervision-frame-sending-on-hsrv0.patch [new file with mode: 0644]
queue-5.15/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch [new file with mode: 0644]
queue-5.15/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch [new file with mode: 0644]
queue-5.15/net-sched-act-move-global-static-variable-net_id-to-.patch [new file with mode: 0644]
queue-5.15/net-sched-act_connmark-get-rid-of-tcf_connmark_walke.patch [new file with mode: 0644]
queue-5.15/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch [new file with mode: 0644]
queue-5.15/net-sched-act_connmark-transition-to-percpu-stats-an.patch [new file with mode: 0644]
queue-5.15/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch [new file with mode: 0644]
queue-5.15/net-smc-fix-mismatch-between-clc-header-and-proposal.patch [new file with mode: 0644]
queue-5.15/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch [new file with mode: 0644]
queue-5.15/net_sched-limit-try_bulk_dequeue_skb-batches.patch [new file with mode: 0644]
queue-5.15/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch [new file with mode: 0644]
queue-5.15/wifi-mac80211-skip-rate-verification-for-not-capture.patch [new file with mode: 0644]
queue-5.4/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch [new file with mode: 0644]
queue-5.4/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch [new file with mode: 0644]
queue-5.4/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch [new file with mode: 0644]
queue-5.4/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch [new file with mode: 0644]
queue-5.4/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch [new file with mode: 0644]
queue-5.4/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch [new file with mode: 0644]
queue-5.4/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch [new file with mode: 0644]
queue-5.4/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch [new file with mode: 0644]
queue-5.4/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch [new file with mode: 0644]
queue-5.4/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch [new file with mode: 0644]
queue-5.4/net_sched-limit-try_bulk_dequeue_skb-batches.patch [new file with mode: 0644]
queue-5.4/net_sched-remove-need_resched-from-qdisc_run.patch [new file with mode: 0644]
queue-5.4/sctp-get-netns-from-asoc-and-ep-base.patch [new file with mode: 0644]
queue-5.4/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch [new file with mode: 0644]
queue-5.4/tipc-simplify-the-finalize-work-queue.patch [new file with mode: 0644]
queue-5.4/wifi-mac80211-skip-rate-verification-for-not-capture.patch [new file with mode: 0644]
queue-6.1/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch [new file with mode: 0644]
queue-6.1/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch [new file with mode: 0644]
queue-6.1/acpi-cppc-perform-fast-check-switch-only-for-online-.patch [new file with mode: 0644]
queue-6.1/af_unix-initialise-scc_index-in-unix_add_edge.patch [new file with mode: 0644]
queue-6.1/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch [new file with mode: 0644]
queue-6.1/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch [new file with mode: 0644]
queue-6.1/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch [new file with mode: 0644]
queue-6.1/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch [new file with mode: 0644]
queue-6.1/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch [new file with mode: 0644]
queue-6.1/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch [new file with mode: 0644]
queue-6.1/hsr-fix-supervision-frame-sending-on-hsrv0.patch [new file with mode: 0644]
queue-6.1/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch [new file with mode: 0644]
queue-6.1/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch [new file with mode: 0644]
queue-6.1/net-mlx5-expose-shared-buffer-registers-bits-and-str.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-add-api-to-query-modify-sbpr-and-sbcm-regi.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-consider-internal-buffers-size-in-port-buf.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-fix-potentially-misleading-debug-message.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-remove-mlx5e_dbg-and-msglvl-support.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-update-shared-buffer-along-with-device-buf.patch [new file with mode: 0644]
queue-6.1/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch [new file with mode: 0644]
queue-6.1/net-sched-act_connmark-transition-to-percpu-stats-an.patch [new file with mode: 0644]
queue-6.1/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch [new file with mode: 0644]
queue-6.1/net-smc-fix-mismatch-between-clc-header-and-proposal.patch [new file with mode: 0644]
queue-6.1/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch [new file with mode: 0644]
queue-6.1/net_sched-limit-try_bulk_dequeue_skb-batches.patch [new file with mode: 0644]
queue-6.1/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch [new file with mode: 0644]
queue-6.1/selftests-net-local_termination-wait-for-interfaces-.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch [new file with mode: 0644]
queue-6.1/wifi-ath11k-add-tx-ack-signal-support-for-management.patch [new file with mode: 0644]
queue-6.1/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch [new file with mode: 0644]
queue-6.1/wifi-mac80211-skip-rate-verification-for-not-capture.patch [new file with mode: 0644]
queue-6.12/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch [new file with mode: 0644]
queue-6.12/acpi-cppc-detect-preferred-core-availability-on-onli.patch [new file with mode: 0644]
queue-6.12/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch [new file with mode: 0644]
queue-6.12/acpi-cppc-perform-fast-check-switch-only-for-online-.patch [new file with mode: 0644]
queue-6.12/af_unix-initialise-scc_index-in-unix_add_edge.patch [new file with mode: 0644]
queue-6.12/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch [new file with mode: 0644]
queue-6.12/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch [new file with mode: 0644]
queue-6.12/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch [new file with mode: 0644]
queue-6.12/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch [new file with mode: 0644]
queue-6.12/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch [new file with mode: 0644]
queue-6.12/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch [new file with mode: 0644]
queue-6.12/erofs-avoid-infinite-loop-due-to-incomplete-zstd-com.patch [new file with mode: 0644]
queue-6.12/hsr-fix-supervision-frame-sending-on-hsrv0.patch [new file with mode: 0644]
queue-6.12/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-respons.patch [new file with mode: 0644]
queue-6.12/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-retry-m.patch [new file with mode: 0644]
queue-6.12/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch [new file with mode: 0644]
queue-6.12/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch [new file with mode: 0644]
queue-6.12/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-fix-potentially-misleading-debug-message.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch [new file with mode: 0644]
queue-6.12/net-phy-micrel-introduce-lanphy_modify_page_reg.patch [new file with mode: 0644]
queue-6.12/net-phy-micrel-lan8814-fix-reset-of-the-qsgmii-inter.patch [new file with mode: 0644]
queue-6.12/net-phy-micrel-replace-hardcoded-pages-with-defines.patch [new file with mode: 0644]
queue-6.12/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch [new file with mode: 0644]
queue-6.12/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch [new file with mode: 0644]
queue-6.12/net-smc-fix-mismatch-between-clc-header-and-proposal.patch [new file with mode: 0644]
queue-6.12/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch [new file with mode: 0644]
queue-6.12/net_sched-limit-try_bulk_dequeue_skb-batches.patch [new file with mode: 0644]
queue-6.12/nfsd-skip-close-replay-processing-if-xdr-encoding-fa.patch [new file with mode: 0644]
queue-6.12/rust-add-fno-isolate-erroneous-paths-dereference-to-.patch [new file with mode: 0644]
queue-6.12/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch [new file with mode: 0644]
queue-6.12/selftests-net-local_termination-wait-for-interfaces-.patch [new file with mode: 0644]
queue-6.12/series
queue-6.12/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch [new file with mode: 0644]
queue-6.12/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch [new file with mode: 0644]
queue-6.12/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch [new file with mode: 0644]
queue-6.12/wifi-mac80211-skip-rate-verification-for-not-capture.patch [new file with mode: 0644]
queue-6.17/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch [new file with mode: 0644]
queue-6.17/acpi-cppc-detect-preferred-core-availability-on-onli.patch [new file with mode: 0644]
queue-6.17/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch [new file with mode: 0644]
queue-6.17/acpi-cppc-perform-fast-check-switch-only-for-online-.patch [new file with mode: 0644]
queue-6.17/af_unix-initialise-scc_index-in-unix_add_edge.patch [new file with mode: 0644]
queue-6.17/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch [new file with mode: 0644]
queue-6.17/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch [new file with mode: 0644]
queue-6.17/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch [new file with mode: 0644]
queue-6.17/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch [new file with mode: 0644]
queue-6.17/bluetooth-hci_conn-fix-not-cleaning-up-pa_link-conne.patch [new file with mode: 0644]
queue-6.17/bluetooth-hci_event-fix-not-handling-pa-sync-lost-ev.patch [new file with mode: 0644]
queue-6.17/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch [new file with mode: 0644]
queue-6.17/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch [new file with mode: 0644]
queue-6.17/cpufreq-intel_pstate-check-ida-only-before-msr_ia32_.patch [new file with mode: 0644]
queue-6.17/erofs-avoid-infinite-loop-due-to-incomplete-zstd-com.patch [new file with mode: 0644]
queue-6.17/hsr-fix-supervision-frame-sending-on-hsrv0.patch [new file with mode: 0644]
queue-6.17/hsr-follow-standard-for-hsrv0-supervision-frames.patch [new file with mode: 0644]
queue-6.17/mlx5-fix-default-values-in-create-cq.patch [new file with mode: 0644]
queue-6.17/net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-o.patch [new file with mode: 0644]
queue-6.17/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-respons.patch [new file with mode: 0644]
queue-6.17/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-retry-m.patch [new file with mode: 0644]
queue-6.17/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch [new file with mode: 0644]
queue-6.17/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch [new file with mode: 0644]
queue-6.17/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch [new file with mode: 0644]
queue-6.17/net-mlx5-fix-typo-of-mlx5_eq_doorbel_offset.patch [new file with mode: 0644]
queue-6.17/net-mlx5-store-the-global-doorbell-in-mlx5_priv.patch [new file with mode: 0644]
queue-6.17/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch [new file with mode: 0644]
queue-6.17/net-mlx5e-fix-missing-error-assignment-in-mlx5e_xfrm.patch [new file with mode: 0644]
queue-6.17/net-mlx5e-fix-potentially-misleading-debug-message.patch [new file with mode: 0644]
queue-6.17/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch [new file with mode: 0644]
queue-6.17/net-mlx5e-prepare-for-using-different-cq-doorbells.patch [new file with mode: 0644]
queue-6.17/net-phy-micrel-introduce-lanphy_modify_page_reg.patch [new file with mode: 0644]
queue-6.17/net-phy-micrel-lan8814-fix-reset-of-the-qsgmii-inter.patch [new file with mode: 0644]
queue-6.17/net-phy-micrel-replace-hardcoded-pages-with-defines.patch [new file with mode: 0644]
queue-6.17/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch [new file with mode: 0644]
queue-6.17/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch [new file with mode: 0644]
queue-6.17/net-smc-fix-mismatch-between-clc-header-and-proposal.patch [new file with mode: 0644]
queue-6.17/net_sched-limit-try_bulk_dequeue_skb-batches.patch [new file with mode: 0644]
queue-6.17/netfilter-nft_ct-add-seqadj-extension-for-natted-con.patch [new file with mode: 0644]
queue-6.17/nfsd-skip-close-replay-processing-if-xdr-encoding-fa.patch [new file with mode: 0644]
queue-6.17/rust-add-fno-isolate-erroneous-paths-dereference-to-.patch [new file with mode: 0644]
queue-6.17/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch [new file with mode: 0644]
queue-6.17/selftests-net-local_termination-wait-for-interfaces-.patch [new file with mode: 0644]
queue-6.17/series
queue-6.17/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch [new file with mode: 0644]
queue-6.17/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch [new file with mode: 0644]
queue-6.17/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch [new file with mode: 0644]
queue-6.17/wifi-iwlwifi-mld-always-take-beacon-ies-in-link-grad.patch [new file with mode: 0644]
queue-6.17/wifi-iwlwifi-mvm-fix-beacon-template-fixed-rate.patch [new file with mode: 0644]
queue-6.17/wifi-mac80211-skip-rate-verification-for-not-capture.patch [new file with mode: 0644]
queue-6.6/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch [new file with mode: 0644]
queue-6.6/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch [new file with mode: 0644]
queue-6.6/acpi-cppc-perform-fast-check-switch-only-for-online-.patch [new file with mode: 0644]
queue-6.6/af_unix-initialise-scc_index-in-unix_add_edge.patch [new file with mode: 0644]
queue-6.6/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch [new file with mode: 0644]
queue-6.6/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch [new file with mode: 0644]
queue-6.6/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch [new file with mode: 0644]
queue-6.6/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch [new file with mode: 0644]
queue-6.6/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch [new file with mode: 0644]
queue-6.6/cifs-stop-writeback-extension-when-change-of-size-is.patch [new file with mode: 0644]
queue-6.6/hsr-fix-supervision-frame-sending-on-hsrv0.patch [new file with mode: 0644]
queue-6.6/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch [new file with mode: 0644]
queue-6.6/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch [new file with mode: 0644]
queue-6.6/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch [new file with mode: 0644]
queue-6.6/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch [new file with mode: 0644]
queue-6.6/net-mlx5e-fix-potentially-misleading-debug-message.patch [new file with mode: 0644]
queue-6.6/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch [new file with mode: 0644]
queue-6.6/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch [new file with mode: 0644]
queue-6.6/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch [new file with mode: 0644]
queue-6.6/net-smc-fix-mismatch-between-clc-header-and-proposal.patch [new file with mode: 0644]
queue-6.6/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch [new file with mode: 0644]
queue-6.6/net_sched-limit-try_bulk_dequeue_skb-batches.patch [new file with mode: 0644]
queue-6.6/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch [new file with mode: 0644]
queue-6.6/selftests-net-local_termination-wait-for-interfaces-.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch [new file with mode: 0644]
queue-6.6/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch [new file with mode: 0644]
queue-6.6/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch [new file with mode: 0644]
queue-6.6/wifi-mac80211-skip-rate-verification-for-not-capture.patch [new file with mode: 0644]

diff --git a/queue-5.10/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch b/queue-5.10/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
new file mode 100644 (file)
index 0000000..bad8659
--- /dev/null
@@ -0,0 +1,149 @@
+From e0c6d46992960e3fe5acd2c6db1320898ef1b322 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:49 +0200
+Subject: Bluetooth: 6lowpan: Don't hold spin lock over sleeping functions
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 98454bc812f3611551e4b1f81732da4aa7b9597e ]
+
+disconnect_all_peers() calls sleeping function (l2cap_chan_close) under
+spinlock.  Holding the lock doesn't actually do any good -- we work on a
+local copy of the list, and the lock doesn't protect against peer->chan
+having already been freed.
+
+Fix by taking refcounts of peer->chan instead.  Clean up the code and
+old comments a bit.
+
+Take devices_lock instead of RCU, because the kfree_rcu();
+l2cap_chan_put(); construct in chan_close_cb() does not guarantee
+peer->chan is necessarily valid in RCU.
+
+Also take l2cap_chan_lock() which is required for l2cap_chan_close().
+
+Log: (bluez 6lowpan-tester Client Connect - Disable)
+------
+BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
+...
+<TASK>
+...
+l2cap_send_disconn_req (net/bluetooth/l2cap_core.c:938 net/bluetooth/l2cap_core.c:1495)
+...
+? __pfx_l2cap_chan_close (net/bluetooth/l2cap_core.c:809)
+do_enable_set (net/bluetooth/6lowpan.c:1048 net/bluetooth/6lowpan.c:1068)
+------
+
+Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 68 ++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index d035bb927aec2..9486d66863264 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -52,6 +52,11 @@ static bool enable_6lowpan;
+ static struct l2cap_chan *listen_chan;
+ static DEFINE_MUTEX(set_lock);
++enum {
++      LOWPAN_PEER_CLOSING,
++      LOWPAN_PEER_MAXBITS
++};
++
+ struct lowpan_peer {
+       struct list_head list;
+       struct rcu_head rcu;
+@@ -60,6 +65,8 @@ struct lowpan_peer {
+       /* peer addresses in various formats */
+       unsigned char lladdr[ETH_ALEN];
+       struct in6_addr peer_addr;
++
++      DECLARE_BITMAP(flags, LOWPAN_PEER_MAXBITS);
+ };
+ struct lowpan_btle_dev {
+@@ -1051,41 +1058,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ static void disconnect_all_peers(void)
+ {
+       struct lowpan_btle_dev *entry;
+-      struct lowpan_peer *peer, *tmp_peer, *new_peer;
+-      struct list_head peers;
+-
+-      INIT_LIST_HEAD(&peers);
++      struct lowpan_peer *peer;
++      int nchans;
+-      /* We make a separate list of peers as the close_cb() will
+-       * modify the device peers list so it is better not to mess
+-       * with the same list at the same time.
++      /* l2cap_chan_close() cannot be called from RCU, and lock ordering
++       * chan->lock > devices_lock prevents taking write side lock, so copy
++       * then close.
+        */
+       rcu_read_lock();
++      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list)
++              list_for_each_entry_rcu(peer, &entry->peers, list)
++                      clear_bit(LOWPAN_PEER_CLOSING, peer->flags);
++      rcu_read_unlock();
+-      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
+-              list_for_each_entry_rcu(peer, &entry->peers, list) {
+-                      new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
+-                      if (!new_peer)
+-                              break;
++      do {
++              struct l2cap_chan *chans[32];
++              int i;
+-                      new_peer->chan = peer->chan;
+-                      INIT_LIST_HEAD(&new_peer->list);
++              nchans = 0;
+-                      list_add(&new_peer->list, &peers);
+-              }
+-      }
++              spin_lock(&devices_lock);
+-      rcu_read_unlock();
++              list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
++                      list_for_each_entry_rcu(peer, &entry->peers, list) {
++                              if (test_and_set_bit(LOWPAN_PEER_CLOSING,
++                                                   peer->flags))
++                                      continue;
+-      spin_lock(&devices_lock);
+-      list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
+-              l2cap_chan_close(peer->chan, ENOENT);
++                              l2cap_chan_hold(peer->chan);
++                              chans[nchans++] = peer->chan;
+-              list_del_rcu(&peer->list);
+-              kfree_rcu(peer, rcu);
+-      }
+-      spin_unlock(&devices_lock);
++                              if (nchans >= ARRAY_SIZE(chans))
++                                      goto done;
++                      }
++              }
++
++done:
++              spin_unlock(&devices_lock);
++
++              for (i = 0; i < nchans; ++i) {
++                      l2cap_chan_lock(chans[i]);
++                      l2cap_chan_close(chans[i], ENOENT);
++                      l2cap_chan_unlock(chans[i]);
++                      l2cap_chan_put(chans[i]);
++              }
++      } while (nchans);
+ }
+ struct set_enable {
+-- 
+2.51.0
+
diff --git a/queue-5.10/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch b/queue-5.10/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
new file mode 100644 (file)
index 0000000..7ce929c
--- /dev/null
@@ -0,0 +1,103 @@
+From f17e2d5982671cafa5e72003ca18c32e7f3a7681 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:47 +0200
+Subject: Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type
+ confusion
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit b454505bf57a2e4f5d49951d4deb03730a9348d9 ]
+
+Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types,
+e.g. debugfs "connect" command takes the former, and "disconnect" and
+"connect" to already connected device take the latter.  This is due to
+using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le
+which take different dst_type values.
+
+Fix address type passed to hci_conn_hash_lookup_le().
+
+Retain the debugfs API difference between "connect" and "disconnect"
+commands since it's been like this since 2015 and nobody apparently
+complained.
+
+Fixes: f5ad4ffceba0 ("Bluetooth: 6lowpan: Use hci_conn_hash_lookup_le() when possible")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 32dc74115dcbc..d035bb927aec2 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -994,10 +994,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void)
+ }
+ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+-                        struct l2cap_conn **conn)
++                        struct l2cap_conn **conn, bool disconnect)
+ {
+       struct hci_conn *hcon;
+       struct hci_dev *hdev;
++      int le_addr_type;
+       int n;
+       n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
+@@ -1008,13 +1009,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+       if (n < 7)
+               return -EINVAL;
++      if (disconnect) {
++              /* The "disconnect" debugfs command has used different address
++               * type constants than "connect" since 2015. Let's retain that
++               * for now even though it's obviously buggy...
++               */
++              *addr_type += 1;
++      }
++
++      switch (*addr_type) {
++      case BDADDR_LE_PUBLIC:
++              le_addr_type = ADDR_LE_DEV_PUBLIC;
++              break;
++      case BDADDR_LE_RANDOM:
++              le_addr_type = ADDR_LE_DEV_RANDOM;
++              break;
++      default:
++              return -EINVAL;
++      }
++
+       /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
+       hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
+       if (!hdev)
+               return -ENOENT;
+       hci_dev_lock(hdev);
+-      hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
++      hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+@@ -1141,7 +1161,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       buf[buf_size] = '\0';
+       if (memcmp(buf, "connect ", 8) == 0) {
+-              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false);
+               if (ret == -EINVAL)
+                       return ret;
+@@ -1178,7 +1198,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       }
+       if (memcmp(buf, "disconnect ", 11) == 0) {
+-              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true);
+               if (ret < 0)
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-5.10/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch b/queue-5.10/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
new file mode 100644 (file)
index 0000000..30606fd
--- /dev/null
@@ -0,0 +1,54 @@
+From e9bd6577e7120434851234063ac312ef29c057ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:46 +0200
+Subject: Bluetooth: 6lowpan: reset link-local header on ipv6 recv path
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3b78f50918276ab28fb22eac9aa49401ac436a3b ]
+
+Bluetooth 6lowpan.c netdev has header_ops, so it must set link-local
+header for RX skb, otherwise things crash, eg. with AF_PACKET SOCK_RAW
+
+Add missing skb_reset_mac_header() for uncompressed ipv6 RX path.
+
+For the compressed one, it is done in lowpan_header_decompress().
+
+Log: (BlueZ 6lowpan-tester Client Recv Raw - Success)
+------
+kernel BUG at net/core/skbuff.c:212!
+Call Trace:
+<IRQ>
+...
+packet_rcv (net/packet/af_packet.c:2152)
+...
+<TASK>
+__local_bh_enable_ip (kernel/softirq.c:407)
+netif_rx (net/core/dev.c:5648)
+chan_recv_cb (net/bluetooth/6lowpan.c:294 net/bluetooth/6lowpan.c:359)
+------
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 7e698b0ac7bc7..32dc74115dcbc 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -317,6 +317,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
+               local_skb->pkt_type = PACKET_HOST;
+               local_skb->dev = dev;
++              skb_reset_mac_header(local_skb);
+               skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
+               if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) {
+-- 
+2.51.0
+
diff --git a/queue-5.10/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch b/queue-5.10/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
new file mode 100644 (file)
index 0000000..b267aca
--- /dev/null
@@ -0,0 +1,65 @@
+From c96eea07fa30e016339a73e309743b1f62092de4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:28:41 -0500
+Subject: Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
+
+From: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+
+[ Upstream commit 23d22f2f71768034d6ef86168213843fc49bf550 ]
+
+There is a KASAN: slab-use-after-free read in btusb_disconnect().
+Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will
+free the btusb data associated with the interface. The same data is
+then used later in the function, hence the UAF.
+
+Fix by moving the accesses to btusb data to before the data is free'd.
+
+Reported-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2fc81b50a4f8263a159b
+Tested-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Fixes: fd913ef7ce619 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index cf0a0b3eaf886..155eaaf0485a1 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4391,6 +4391,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+       hci_unregister_dev(hdev);
++      if (data->oob_wake_irq)
++              device_init_wakeup(&data->udev->dev, false);
++      if (data->reset_gpio)
++              gpiod_put(data->reset_gpio);
++
+       if (intf == data->intf) {
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
+@@ -4401,17 +4406,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+                       usb_driver_release_interface(&btusb_driver, data->diag);
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       } else if (intf == data->diag) {
+-              usb_driver_release_interface(&btusb_driver, data->intf);
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
++              usb_driver_release_interface(&btusb_driver, data->intf);
+       }
+-      if (data->oob_wake_irq)
+-              device_init_wakeup(&data->udev->dev, false);
+-
+-      if (data->reset_gpio)
+-              gpiod_put(data->reset_gpio);
+-
+       hci_free_dev(hdev);
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.10/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch b/queue-5.10/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
new file mode 100644 (file)
index 0000000..7605c2d
--- /dev/null
@@ -0,0 +1,37 @@
+From 3b40a4326c92c7f0324f8245aaf46a80b4a9b42e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:48 +0200
+Subject: Bluetooth: L2CAP: export l2cap_chan_hold for modules
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit e060088db0bdf7932e0e3c2d24b7371c4c5b867c ]
+
+l2cap_chan_put() is exported, so export also l2cap_chan_hold() for
+modules.
+
+l2cap_chan_hold() has use case in net/bluetooth/6lowpan.c
+
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index b6345996fc022..166623372d0f5 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -518,6 +518,7 @@ void l2cap_chan_hold(struct l2cap_chan *c)
+       kref_get(&c->kref);
+ }
++EXPORT_SYMBOL_GPL(l2cap_chan_hold);
+ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
+ {
+-- 
+2.51.0
+
diff --git a/queue-5.10/hsr-fix-supervision-frame-sending-on-hsrv0.patch b/queue-5.10/hsr-fix-supervision-frame-sending-on-hsrv0.patch
new file mode 100644 (file)
index 0000000..1b244f2
--- /dev/null
@@ -0,0 +1,50 @@
+From fe87cde8c7ce6d7f18918d0d0a12182c4d576754 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:29:32 +0100
+Subject: hsr: Fix supervision frame sending on HSRv0
+
+From: Felix Maurer <fmaurer@redhat.com>
+
+[ Upstream commit 96a3a03abf3d8cc38cd9cb0d280235fbcf7c3f7f ]
+
+On HSRv0, no supervision frames were sent. The supervison frames were
+generated successfully, but failed the check for a sufficiently long mac
+header, i.e., at least sizeof(struct hsr_ethhdr), in hsr_fill_frame_info()
+because the mac header only contained the ethernet header.
+
+Fix this by including the HSR header in the mac header when generating HSR
+supervision frames. Note that the mac header now also includes the TLV
+fields. This matches how we set the headers on rx and also the size of
+struct hsrv0_ethhdr_sp.
+
+Reported-by: Hangbin Liu <liuhangbin@gmail.com>
+Closes: https://lore.kernel.org/netdev/aMONxDXkzBZZRfE5@fedora/
+Fixes: 9cfb5e7f0ded ("net: hsr: fix hsr_init_sk() vs network/transport headers.")
+Signed-off-by: Felix Maurer <fmaurer@redhat.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://patch.msgid.link/4354114fea9a642fe71f49aeeb6c6159d1d61840.1762876095.git.fmaurer@redhat.com
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 505eb58f7e081..5a54a18892080 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -296,6 +296,9 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       }
+       hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag));
++      skb_set_network_header(skb, ETH_HLEN + HSR_HLEN);
++      skb_reset_mac_len(skb);
++
+       set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf));
+       set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch b/queue-5.10/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
new file mode 100644 (file)
index 0000000..94376a8
--- /dev/null
@@ -0,0 +1,39 @@
+From 384d08113c807c059e18246b77631262d91881be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:14:21 +0800
+Subject: net: fec: correct rx_bytes statistic for the case SHIFT16 is set
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit ad17e7e92a7c52ce70bb764813fcf99464f96903 ]
+
+Two additional bytes in front of each frame received into the RX FIFO if
+SHIFT16 is set, so we need to subtract the extra two bytes from pkt_len
+to correct the statistic of rx_bytes.
+
+Fixes: 3ac72b7b63d5 ("net: fec: align IP header in hardware")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20251106021421.2096585-1-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 9905e65621004..dfe3e7b1fae51 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1525,6 +1525,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               ndev->stats.rx_packets++;
+               pkt_len = fec16_to_cpu(bdp->cbd_datlen);
+               ndev->stats.rx_bytes += pkt_len;
++              if (fep->quirks & FEC_QUIRK_HAS_RACC)
++                      ndev->stats.rx_bytes -= 2;
+               index = fec_enet_get_bd_index(bdp, &rxq->bd);
+               skb = rxq->rx_skbuff[index];
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch b/queue-5.10/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
new file mode 100644 (file)
index 0000000..c667dd9
--- /dev/null
@@ -0,0 +1,45 @@
+From fe561f8ae901065fc596939078f159a85e891956 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 07:49:22 +0100
+Subject: net: mdio: fix resource leak in mdiobus_register_device()
+
+From: Buday Csaba <buday.csaba@prolan.hu>
+
+[ Upstream commit e6ca8f533ed41129fcf052297718f417f021cc7d ]
+
+Fix a possible leak in mdiobus_register_device() when both a
+reset-gpio and a reset-controller are present.
+Clean up the already claimed reset-gpio, when the registration of
+the reset-controller fails, so when an error code is returned, the
+device retains its state before the registration attempt.
+
+Link: https://lore.kernel.org/all/20251106144603.39053c81@kernel.org/
+Fixes: 71dd6c0dff51 ("net: phy: add support for reset-controller")
+Signed-off-by: Buday Csaba <buday.csaba@prolan.hu>
+Link: https://patch.msgid.link/4b419377f8dd7d2f63f919d0f74a336c734f8fff.1762584481.git.buday.csaba@prolan.hu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mdio_bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index d15deb3281edb..d7a65a5c855e5 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -80,8 +80,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
+                       return err;
+               err = mdiobus_register_reset(mdiodev);
+-              if (err)
++              if (err) {
++                      gpiod_put(mdiodev->reset_gpio);
++                      mdiodev->reset_gpio = NULL;
+                       return err;
++              }
+               /* Assert the reset signal */
+               mdio_device_reset(mdiodev, 1);
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch b/queue-5.10/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
new file mode 100644 (file)
index 0000000..8383c4e
--- /dev/null
@@ -0,0 +1,58 @@
+From 3d1d19114ad26f0dfa65137b88ed448785a37722 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:51 +0200
+Subject: net/mlx5e: Fix maxrate wraparound in threshold between units
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit a7bf4d5063c7837096aab2853224eb23628514d9 ]
+
+The previous calculation used roundup() which caused an overflow for
+rates between 25.5Gbps and 26Gbps.
+For example, a rate of 25.6Gbps would result in using 100Mbps units with
+value of 256, which would overflow the 8 bits field.
+
+Simplify the upper_limit_mbps calculation by removing the
+unnecessary roundup, and adjust the comparison to use <= to correctly
+handle the boundary condition.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index c25fb0cbde274..4f1ce1287cdae 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -587,18 +587,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       struct mlx5_core_dev *mdev = priv->mdev;
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+-      __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
++      __u64 upper_limit_mbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
++      upper_limit_mbps = 255 * MLX5E_100MB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+                       max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
+                       continue;
+               }
+-              if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
++              if (maxrate->tc_maxrate[i] <= upper_limit_mbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch b/queue-5.10/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
new file mode 100644 (file)
index 0000000..e5828a7
--- /dev/null
@@ -0,0 +1,62 @@
+From d755938167a6ecc4d6039fc8fdffa3945877d191 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:52 +0200
+Subject: net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 43b27d1bd88a4bce34ec2437d103acfae9655f9e ]
+
+Add validation to reject rates exceeding 255 Gbps that would overflow
+the 8 bits max bandwidth field.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 4f1ce1287cdae..5c48a4872f35d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -588,11 +588,13 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+       __u64 upper_limit_mbps;
++      __u64 upper_limit_gbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+       upper_limit_mbps = 255 * MLX5E_100MB;
++      upper_limit_gbps = 255 * MLX5E_1GB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+@@ -604,10 +606,16 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else {
++              } else if (max_bw_value[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
++              } else {
++                      netdev_err(netdev,
++                                 "tc_%d maxrate %llu Kbps exceeds limit %llu\n",
++                                 i, maxrate->tc_maxrate[i],
++                                 upper_limit_gbps);
++                      return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch b/queue-5.10/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
new file mode 100644 (file)
index 0000000..8211fee
--- /dev/null
@@ -0,0 +1,70 @@
+From 4f72780ed17c95d0bbf5edf6535ce40184eec623 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:36 +0530
+Subject: net: sched: act_ife: initialize struct tc_ife to fix KMSAN
+ kernel-infoleak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit ce50039be49eea9b4cd8873ca6eccded1b4a130a ]
+
+Fix a KMSAN kernel-infoleak detected  by the syzbot .
+
+[net?] KMSAN: kernel-infoleak in __skb_datagram_iter
+
+In tcf_ife_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+This change silences the KMSAN report and prevents potential information
+leaks from the kernel memory.
+
+This fix has been tested and validated by syzbot. This patch closes the
+bug reported at the following syzkaller link and ensures no infoleak.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: ef6980b6becb ("introduce IFE action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-3-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ife.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index 99548b2a1bc83..892d4824d81d5 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -643,13 +643,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_ife_info *ife = to_ife(a);
+       struct tcf_ife_params *p;
+-      struct tc_ife opt = {
+-              .index = ife->tcf_index,
+-              .refcnt = refcount_read(&ife->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
+-      };
++      struct tc_ife opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index = ife->tcf_index,
++      opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref,
++      opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
++
+       spin_lock_bh(&ife->tcf_lock);
+       opt.action = ife->tcf_action;
+       p = rcu_dereference_protected(ife->params,
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-smc-fix-mismatch-between-clc-header-and-proposal.patch b/queue-5.10/net-smc-fix-mismatch-between-clc-header-and-proposal.patch
new file mode 100644 (file)
index 0000000..d7f3ea6
--- /dev/null
@@ -0,0 +1,55 @@
+From 224991e38a78418eb1dceea96ea5a4a8b43ac1f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 10:40:29 +0800
+Subject: net/smc: fix mismatch between CLC header and proposal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit ec33f2e5a2d0dbbfd71435209aee812fdc9369b8 ]
+
+The current CLC proposal message construction uses a mix of
+`ini->smc_type_v1/v2` and `pclc_base->hdr.typev1/v2` to decide whether
+to include optional extensions (IPv6 prefix extension for v1, and v2
+extension). This leads to a critical inconsistency: when
+`smc_clc_prfx_set()` fails - for example, in IPv6-only environments with
+only link-local addresses, or when the local IP address and the outgoing
+interface’s network address are not in the same subnet.
+
+As a result, the proposal message is assembled using the stale
+`ini->smc_type_v1` value—causing the IPv6 prefix extension to be
+included even though the header indicates v1 is not supported.
+The peer then receives a malformed CLC proposal where the header type
+does not match the payload, and immediately resets the connection.
+
+The fix ensures consistency between the CLC header flags and the actual
+payload by synchronizing `ini->smc_type_v1` with `pclc_base->hdr.typev1`
+when prefix setup fails.
+
+Fixes: 8c3dca341aea ("net/smc: build and send V2 CLC proposal")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20251107024029.88753-1-alibuda@linux.alibaba.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/smc_clc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
+index 2aa69e29fa1d5..dca448c98c9de 100644
+--- a/net/smc/smc_clc.c
++++ b/net/smc/smc_clc.c
+@@ -529,6 +529,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
+                               return SMC_CLC_DECL_CNFERR;
+                       }
+                       pclc_base->hdr.typev1 = SMC_TYPE_N;
++                      ini->smc_type_v1 = SMC_TYPE_N;
+               } else {
+                       pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
+                       plen += sizeof(*pclc_prfx) +
+-- 
+2.51.0
+
diff --git a/queue-5.10/net_sched-limit-try_bulk_dequeue_skb-batches.patch b/queue-5.10/net_sched-limit-try_bulk_dequeue_skb-batches.patch
new file mode 100644 (file)
index 0000000..c77fab1
--- /dev/null
@@ -0,0 +1,143 @@
+From ff87e1f0cbff855300fc4a36fe39f505635de971 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:12:15 +0000
+Subject: net_sched: limit try_bulk_dequeue_skb() batches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0345552a653ce5542affeb69ac5aa52177a5199b ]
+
+After commit 100dfa74cad9 ("inet: dev_queue_xmit() llist adoption")
+I started seeing many qdisc requeues on IDPF under high TX workload.
+
+$ tc -s qd sh dev eth1 handle 1: ; sleep 1; tc -s qd sh dev eth1 handle 1:
+qdisc mq 1: root
+ Sent 43534617319319 bytes 268186451819 pkt (dropped 0, overlimits 0 requeues 3532840114)
+ backlog 1056Kb 6675p requeues 3532840114
+qdisc mq 1: root
+ Sent 43554665866695 bytes 268309964788 pkt (dropped 0, overlimits 0 requeues 3537737653)
+ backlog 781164b 4822p requeues 3537737653
+
+This is caused by try_bulk_dequeue_skb() being only limited by BQL budget.
+
+perf record -C120-239 -e qdisc:qdisc_dequeue sleep 1 ; perf script
+...
+ netperf 75332 [146]  2711.138269: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1292 skbaddr=0xff378005a1e9f200
+ netperf 75332 [146]  2711.138953: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1213 skbaddr=0xff378004d607a500
+ netperf 75330 [144]  2711.139631: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1233 skbaddr=0xff3780046be20100
+ netperf 75333 [147]  2711.140356: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1093 skbaddr=0xff37800514845b00
+ netperf 75337 [151]  2711.141037: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1353 skbaddr=0xff37800460753300
+ netperf 75337 [151]  2711.141877: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1367 skbaddr=0xff378004e72c7b00
+ netperf 75330 [144]  2711.142643: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1202 skbaddr=0xff3780045bd60000
+...
+
+This is bad because :
+
+1) Large batches hold one victim cpu for a very long time.
+
+2) Driver often hit their own TX ring limit (all slots are used).
+
+3) We call dev_requeue_skb()
+
+4) Requeues are using a FIFO (q->gso_skb), breaking qdisc ability to
+   implement FQ or priority scheduling.
+
+5) dequeue_skb() gets packets from q->gso_skb one skb at a time
+   with no xmit_more support. This is causing many spinlock games
+   between the qdisc and the device driver.
+
+Requeues were supposed to be very rare, lets keep them this way.
+
+Limit batch sizes to /proc/sys/net/core/dev_weight (default 64) as
+__qdisc_run() was designed to use.
+
+Fixes: 5772e9a3463b ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/20251109161215.2574081-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_generic.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index ecdd9e83f2f49..243a1d6b349c7 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -172,9 +172,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
+ static void try_bulk_dequeue_skb(struct Qdisc *q,
+                                struct sk_buff *skb,
+                                const struct netdev_queue *txq,
+-                               int *packets)
++                               int *packets, int budget)
+ {
+       int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
++      int cnt = 0;
+       while (bytelimit > 0) {
+               struct sk_buff *nskb = q->dequeue(q);
+@@ -185,8 +186,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
+               bytelimit -= nskb->len; /* covers GSO len */
+               skb->next = nskb;
+               skb = nskb;
+-              (*packets)++; /* GSO counts as one pkt */
++              if (++cnt >= budget)
++                      break;
+       }
++      (*packets) += cnt;
+       skb_mark_not_on_list(skb);
+ }
+@@ -220,7 +223,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
+  * A requeued skb (via q->gso_skb) can also be a SKB list.
+  */
+ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+-                                 int *packets)
++                                 int *packets, int budget)
+ {
+       const struct netdev_queue *txq = q->dev_queue;
+       struct sk_buff *skb = NULL;
+@@ -287,7 +290,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+       if (skb) {
+ bulk:
+               if (qdisc_may_bulk(q))
+-                      try_bulk_dequeue_skb(q, skb, txq, packets);
++                      try_bulk_dequeue_skb(q, skb, txq, packets, budget);
+               else
+                       try_bulk_dequeue_skb_slow(q, skb, packets);
+       }
+@@ -379,7 +382,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+  *                            >0 - queue is not empty.
+  *
+  */
+-static inline bool qdisc_restart(struct Qdisc *q, int *packets)
++static inline bool qdisc_restart(struct Qdisc *q, int *packets, int budget)
+ {
+       spinlock_t *root_lock = NULL;
+       struct netdev_queue *txq;
+@@ -388,7 +391,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
+       bool validate;
+       /* Dequeue packet */
+-      skb = dequeue_skb(q, &validate, packets);
++      skb = dequeue_skb(q, &validate, packets, budget);
+       if (unlikely(!skb))
+               return false;
+@@ -406,7 +409,7 @@ void __qdisc_run(struct Qdisc *q)
+       int quota = READ_ONCE(dev_tx_weight);
+       int packets;
+-      while (qdisc_restart(q, &packets)) {
++      while (qdisc_restart(q, &packets, quota)) {
+               quota -= packets;
+               if (quota <= 0) {
+                       __netif_schedule(q);
+-- 
+2.51.0
+
diff --git a/queue-5.10/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch b/queue-5.10/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
new file mode 100644 (file)
index 0000000..6fe7244
--- /dev/null
@@ -0,0 +1,86 @@
+From 64bf65b7ac8bfd167b281c532d3960dbdcebffe8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 11:10:54 +0000
+Subject: sctp: prevent possible shift-out-of-bounds in
+ sctp_transport_update_rto
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 1534ff77757e44bcc4b98d0196bc5c0052fce5fa ]
+
+syzbot reported a possible shift-out-of-bounds [1]
+
+Blamed commit added rto_alpha_max and rto_beta_max set to 1000.
+
+It is unclear if some sctp users are setting very large rto_alpha
+and/or rto_beta.
+
+In order to prevent user regression, perform the test at run time.
+
+Also add READ_ONCE() annotations as sysctl values can change under us.
+
+[1]
+
+UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41
+shift exponent 64 is too large for 32-bit type 'unsigned int'
+CPU: 0 UID: 0 PID: 16704 Comm: syz.2.2320 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:94 [inline]
+  dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120
+  ubsan_epilogue lib/ubsan.c:233 [inline]
+  __ubsan_handle_shift_out_of_bounds+0x27f/0x420 lib/ubsan.c:494
+  sctp_transport_update_rto.cold+0x1c/0x34b net/sctp/transport.c:509
+  sctp_check_transmitted+0x11c4/0x1c30 net/sctp/outqueue.c:1502
+  sctp_outq_sack+0x4ef/0x1b20 net/sctp/outqueue.c:1338
+  sctp_cmd_process_sack net/sctp/sm_sideeffect.c:840 [inline]
+  sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1372 [inline]
+
+Fixes: b58537a1f562 ("net: sctp: fix permissions for rto_alpha and rto_beta knobs")
+Reported-by: syzbot+f8c46c8b2b7f6e076e99@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c81ae.050a0220.3d0d33.014e.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20251106111054.3288127-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/transport.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 9c721d70df9c6..9921041079781 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -337,6 +337,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+       if (tp->rttvar || tp->srtt) {
+               struct net *net = tp->asoc->base.net;
++              unsigned int rto_beta, rto_alpha;
+               /* 6.3.1 C3) When a new RTT measurement R' is made, set
+                * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+                * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+@@ -348,10 +349,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+                * For example, assuming the default value of RTO.Alpha of
+                * 1/8, rto_alpha would be expressed as 3.
+                */
+-              tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
+-                      + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
+-              tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
+-                      + (rtt >> net->sctp.rto_alpha);
++              rto_beta = READ_ONCE(net->sctp.rto_beta);
++              if (rto_beta < 32)
++                      tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta)
++                              + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> rto_beta);
++              rto_alpha = READ_ONCE(net->sctp.rto_alpha);
++              if (rto_alpha < 32)
++                      tp->srtt = tp->srtt - (tp->srtt >> rto_alpha)
++                              + (rtt >> rto_alpha);
+       } else {
+               /* 6.3.1 C2) When the first RTT measurement R is made, set
+                * SRTT <- R, RTTVAR <- R/2.
+-- 
+2.51.0
+
index 1a1ddf827da3d3cd638e20a3c33789f97f64a86b..f6c0ec84209c7ac3bd929856bfa6c7b9f5018113 100644 (file)
@@ -175,3 +175,19 @@ risc-v-clear-hot-unplugged-cores-from-all-task-mm_cp.patch
 nfs4-fix-state-renewals-missing-after-boot.patch
 hid-quirks-avoid-cooler-master-mm712-dongle-wakeup-b.patch
 asoc-max98090-91-fixed-max98091-alsa-widget-powering.patch
+net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
+bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
+bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
+bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
+bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
+sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
+net-smc-fix-mismatch-between-clc-header-and-proposal.patch
+tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
+net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
+wifi-mac80211-skip-rate-verification-for-not-capture.patch
+net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
+net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
+net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
+net_sched-limit-try_bulk_dequeue_skb-batches.patch
+hsr-fix-supervision-frame-sending-on-hsrv0.patch
+bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
diff --git a/queue-5.10/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch b/queue-5.10/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
new file mode 100644 (file)
index 0000000..c38b074
--- /dev/null
@@ -0,0 +1,150 @@
+From 72f27d389b1b404163e4381629e1be685c7ba099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 06:40:25 +0000
+Subject: tipc: Fix use-after-free in tipc_mon_reinit_self().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 0725e6afb55128be21a2ca36e9674f573ccec173 ]
+
+syzbot reported use-after-free of tipc_net(net)->monitors[]
+in tipc_mon_reinit_self(). [0]
+
+The array is protected by RTNL, but tipc_mon_reinit_self()
+iterates over it without RTNL.
+
+tipc_mon_reinit_self() is called from tipc_net_finalize(),
+which is always under RTNL except for tipc_net_finalize_work().
+
+Let's hold RTNL in tipc_net_finalize_work().
+
+[0]:
+BUG: KASAN: slab-use-after-free in __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+Read of size 1 at addr ffff88805eae1030 by task kworker/0:7/5989
+
+CPU: 0 UID: 0 PID: 5989 Comm: kworker/0:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
+Workqueue: events tipc_net_finalize_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xca/0x240 mm/kasan/report.c:482
+ kasan_report+0x118/0x150 mm/kasan/report.c:595
+ __kasan_check_byte+0x2a/0x40 mm/kasan/common.c:568
+ kasan_check_byte include/linux/kasan.h:399 [inline]
+ lock_acquire+0x8d/0x360 kernel/locking/lockdep.c:5842
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+ rtlock_slowlock kernel/locking/rtmutex.c:1894 [inline]
+ rwbase_rtmutex_lock_state kernel/locking/spinlock_rt.c:160 [inline]
+ rwbase_write_lock+0xd3/0x7e0 kernel/locking/rwbase_rt.c:244
+ rt_write_lock+0x76/0x110 kernel/locking/spinlock_rt.c:243
+ write_lock_bh include/linux/rwlock_rt.h:99 [inline]
+ tipc_mon_reinit_self+0x79/0x430 net/tipc/monitor.c:718
+ tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
+ process_one_work kernel/workqueue.c:3236 [inline]
+ process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3319
+ worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
+ kthread+0x70e/0x8a0 kernel/kthread.c:463
+ ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+Allocated by task 6089:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __kmalloc_cache_noprof+0x1a8/0x320 mm/slub.c:4407
+ kmalloc_noprof include/linux/slab.h:905 [inline]
+ kzalloc_noprof include/linux/slab.h:1039 [inline]
+ tipc_mon_create+0xc3/0x4d0 net/tipc/monitor.c:657
+ tipc_enable_bearer net/tipc/bearer.c:357 [inline]
+ __tipc_nl_bearer_enable+0xe16/0x13f0 net/tipc/bearer.c:1047
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:371 [inline]
+ tipc_nl_compat_doit+0x3bc/0x5f0 net/tipc/netlink_compat.c:393
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:-1 [inline]
+ tipc_nl_compat_recv+0x83c/0xbe0 net/tipc/netlink_compat.c:1321
+ genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
+ netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
+ netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:729
+ ____sys_sendmsg+0x508/0x820 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 6088:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
+ poison_slab_object mm/kasan/common.c:243 [inline]
+ __kasan_slab_free+0x5b/0x80 mm/kasan/common.c:275
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2422 [inline]
+ slab_free mm/slub.c:4695 [inline]
+ kfree+0x195/0x550 mm/slub.c:4894
+ tipc_l2_device_event+0x380/0x650 net/tipc/bearer.c:-1
+ notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
+ call_netdevice_notifiers_extack net/core/dev.c:2267 [inline]
+ call_netdevice_notifiers net/core/dev.c:2281 [inline]
+ unregister_netdevice_many_notify+0x14d7/0x1fe0 net/core/dev.c:12166
+ unregister_netdevice_many net/core/dev.c:12229 [inline]
+ unregister_netdevice_queue+0x33c/0x380 net/core/dev.c:12073
+ unregister_netdevice include/linux/netdevice.h:3385 [inline]
+ __tun_detach+0xe4d/0x1620 drivers/net/tun.c:621
+ tun_detach drivers/net/tun.c:637 [inline]
+ tun_chr_close+0x10d/0x1c0 drivers/net/tun.c:3433
+ __fput+0x458/0xa80 fs/file_table.c:468
+ task_work_run+0x1d4/0x260 kernel/task_work.c:227
+ resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
+ exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:43
+ exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
+ syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline]
+ syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline]
+ do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 46cb01eeeb86 ("tipc: update mon's self addr when node addr generated")
+Reported-by: syzbot+d7dad7fd4b3921104957@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c323a.050a0220.baf87.007f.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251107064038.2361188-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/net.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/tipc/net.c b/net/tipc/net.c
+index 671cb4f9d5633..95aa3a97b53a8 100644
+--- a/net/tipc/net.c
++++ b/net/tipc/net.c
+@@ -141,7 +141,9 @@ void tipc_net_finalize_work(struct work_struct *work)
+ {
+       struct tipc_net *tn = container_of(work, struct tipc_net, work);
++      rtnl_lock();
+       tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
++      rtnl_unlock();
+ }
+ void tipc_net_stop(struct net *net)
+-- 
+2.51.0
+
diff --git a/queue-5.10/wifi-mac80211-skip-rate-verification-for-not-capture.patch b/queue-5.10/wifi-mac80211-skip-rate-verification-for-not-capture.patch
new file mode 100644 (file)
index 0000000..20d63cf
--- /dev/null
@@ -0,0 +1,48 @@
+From 0fd012e21ba0a2278925a92592e9590b3cad5e47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 14:26:18 +0200
+Subject: wifi: mac80211: skip rate verification for not captured PSDUs
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 7fe0d21f5633af8c3fab9f0ef0706c6156623484 ]
+
+If for example the sniffer did not follow any AIDs in an MU frame, then
+some of the information may not be filled in or is even expected to be
+invalid. As an example, in that case it is expected that Nss is zero.
+
+Fixes: 2ff5e52e7836 ("radiotap: add 0-length PSDU "not captured" type")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251110142554.83a2858ee15b.I9f78ce7984872f474722f9278691ae16378f0a3e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index b46c4c770608c..98f06563d184c 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -4779,10 +4779,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+       if (WARN_ON(!local->started))
+               goto drop;
+-      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) {
++      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) &&
++                 !(status->flag & RX_FLAG_NO_PSDU &&
++                   status->zero_length_psdu_type ==
++                   IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) {
+               /*
+-               * Validate the rate, unless a PLCP error means that
+-               * we probably can't have a valid rate here anyway.
++               * Validate the rate, unless there was a PLCP error which may
++               * have an invalid rate or the PSDU was not capture and may be
++               * missing rate information.
+                */
+               switch (status->encoding) {
+-- 
+2.51.0
+
diff --git a/queue-5.15/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch b/queue-5.15/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
new file mode 100644 (file)
index 0000000..e67d4e1
--- /dev/null
@@ -0,0 +1,149 @@
+From 33ae781f65ebdcec7f33bc052b61846206ef6038 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:49 +0200
+Subject: Bluetooth: 6lowpan: Don't hold spin lock over sleeping functions
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 98454bc812f3611551e4b1f81732da4aa7b9597e ]
+
+disconnect_all_peers() calls sleeping function (l2cap_chan_close) under
+spinlock.  Holding the lock doesn't actually do any good -- we work on a
+local copy of the list, and the lock doesn't protect against peer->chan
+having already been freed.
+
+Fix by taking refcounts of peer->chan instead.  Clean up the code and
+old comments a bit.
+
+Take devices_lock instead of RCU, because the kfree_rcu();
+l2cap_chan_put(); construct in chan_close_cb() does not guarantee
+peer->chan is necessarily valid in RCU.
+
+Also take l2cap_chan_lock() which is required for l2cap_chan_close().
+
+Log: (bluez 6lowpan-tester Client Connect - Disable)
+------
+BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
+...
+<TASK>
+...
+l2cap_send_disconn_req (net/bluetooth/l2cap_core.c:938 net/bluetooth/l2cap_core.c:1495)
+...
+? __pfx_l2cap_chan_close (net/bluetooth/l2cap_core.c:809)
+do_enable_set (net/bluetooth/6lowpan.c:1048 net/bluetooth/6lowpan.c:1068)
+------
+
+Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 68 ++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index db3e2d5290966..b70d3a38fdedc 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -52,6 +52,11 @@ static bool enable_6lowpan;
+ static struct l2cap_chan *listen_chan;
+ static DEFINE_MUTEX(set_lock);
++enum {
++      LOWPAN_PEER_CLOSING,
++      LOWPAN_PEER_MAXBITS
++};
++
+ struct lowpan_peer {
+       struct list_head list;
+       struct rcu_head rcu;
+@@ -60,6 +65,8 @@ struct lowpan_peer {
+       /* peer addresses in various formats */
+       unsigned char lladdr[ETH_ALEN];
+       struct in6_addr peer_addr;
++
++      DECLARE_BITMAP(flags, LOWPAN_PEER_MAXBITS);
+ };
+ struct lowpan_btle_dev {
+@@ -1012,41 +1019,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ static void disconnect_all_peers(void)
+ {
+       struct lowpan_btle_dev *entry;
+-      struct lowpan_peer *peer, *tmp_peer, *new_peer;
+-      struct list_head peers;
+-
+-      INIT_LIST_HEAD(&peers);
++      struct lowpan_peer *peer;
++      int nchans;
+-      /* We make a separate list of peers as the close_cb() will
+-       * modify the device peers list so it is better not to mess
+-       * with the same list at the same time.
++      /* l2cap_chan_close() cannot be called from RCU, and lock ordering
++       * chan->lock > devices_lock prevents taking write side lock, so copy
++       * then close.
+        */
+       rcu_read_lock();
++      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list)
++              list_for_each_entry_rcu(peer, &entry->peers, list)
++                      clear_bit(LOWPAN_PEER_CLOSING, peer->flags);
++      rcu_read_unlock();
+-      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
+-              list_for_each_entry_rcu(peer, &entry->peers, list) {
+-                      new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
+-                      if (!new_peer)
+-                              break;
++      do {
++              struct l2cap_chan *chans[32];
++              int i;
+-                      new_peer->chan = peer->chan;
+-                      INIT_LIST_HEAD(&new_peer->list);
++              nchans = 0;
+-                      list_add(&new_peer->list, &peers);
+-              }
+-      }
++              spin_lock(&devices_lock);
+-      rcu_read_unlock();
++              list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
++                      list_for_each_entry_rcu(peer, &entry->peers, list) {
++                              if (test_and_set_bit(LOWPAN_PEER_CLOSING,
++                                                   peer->flags))
++                                      continue;
+-      spin_lock(&devices_lock);
+-      list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
+-              l2cap_chan_close(peer->chan, ENOENT);
++                              l2cap_chan_hold(peer->chan);
++                              chans[nchans++] = peer->chan;
+-              list_del_rcu(&peer->list);
+-              kfree_rcu(peer, rcu);
+-      }
+-      spin_unlock(&devices_lock);
++                              if (nchans >= ARRAY_SIZE(chans))
++                                      goto done;
++                      }
++              }
++
++done:
++              spin_unlock(&devices_lock);
++
++              for (i = 0; i < nchans; ++i) {
++                      l2cap_chan_lock(chans[i]);
++                      l2cap_chan_close(chans[i], ENOENT);
++                      l2cap_chan_unlock(chans[i]);
++                      l2cap_chan_put(chans[i]);
++              }
++      } while (nchans);
+ }
+ struct set_enable {
+-- 
+2.51.0
+
diff --git a/queue-5.15/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch b/queue-5.15/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
new file mode 100644 (file)
index 0000000..31eedb9
--- /dev/null
@@ -0,0 +1,103 @@
+From 31a8112f3b92a85d991985e4e71f580b8705760d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:47 +0200
+Subject: Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type
+ confusion
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit b454505bf57a2e4f5d49951d4deb03730a9348d9 ]
+
+Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types,
+e.g. debugfs "connect" command takes the former, and "disconnect" and
+"connect" to already connected device take the latter.  This is due to
+using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le
+which take different dst_type values.
+
+Fix address type passed to hci_conn_hash_lookup_le().
+
+Retain the debugfs API difference between "connect" and "disconnect"
+commands since it's been like this since 2015 and nobody apparently
+complained.
+
+Fixes: f5ad4ffceba0 ("Bluetooth: 6lowpan: Use hci_conn_hash_lookup_le() when possible")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index cfe3753a6f160..db3e2d5290966 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -955,10 +955,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void)
+ }
+ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+-                        struct l2cap_conn **conn)
++                        struct l2cap_conn **conn, bool disconnect)
+ {
+       struct hci_conn *hcon;
+       struct hci_dev *hdev;
++      int le_addr_type;
+       int n;
+       n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
+@@ -969,13 +970,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+       if (n < 7)
+               return -EINVAL;
++      if (disconnect) {
++              /* The "disconnect" debugfs command has used different address
++               * type constants than "connect" since 2015. Let's retain that
++               * for now even though it's obviously buggy...
++               */
++              *addr_type += 1;
++      }
++
++      switch (*addr_type) {
++      case BDADDR_LE_PUBLIC:
++              le_addr_type = ADDR_LE_DEV_PUBLIC;
++              break;
++      case BDADDR_LE_RANDOM:
++              le_addr_type = ADDR_LE_DEV_RANDOM;
++              break;
++      default:
++              return -EINVAL;
++      }
++
+       /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
+       hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
+       if (!hdev)
+               return -ENOENT;
+       hci_dev_lock(hdev);
+-      hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
++      hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+@@ -1102,7 +1122,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       buf[buf_size] = '\0';
+       if (memcmp(buf, "connect ", 8) == 0) {
+-              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false);
+               if (ret == -EINVAL)
+                       return ret;
+@@ -1139,7 +1159,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       }
+       if (memcmp(buf, "disconnect ", 11) == 0) {
+-              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true);
+               if (ret < 0)
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-5.15/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch b/queue-5.15/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
new file mode 100644 (file)
index 0000000..ee28420
--- /dev/null
@@ -0,0 +1,54 @@
+From c3c926410a862887d31f8b914ce05b6ece70d3dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:46 +0200
+Subject: Bluetooth: 6lowpan: reset link-local header on ipv6 recv path
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3b78f50918276ab28fb22eac9aa49401ac436a3b ]
+
+Bluetooth 6lowpan.c netdev has header_ops, so it must set link-local
+header for RX skb, otherwise things crash, eg. with AF_PACKET SOCK_RAW
+
+Add missing skb_reset_mac_header() for uncompressed ipv6 RX path.
+
+For the compressed one, it is done in lowpan_header_decompress().
+
+Log: (BlueZ 6lowpan-tester Client Recv Raw - Success)
+------
+kernel BUG at net/core/skbuff.c:212!
+Call Trace:
+<IRQ>
+...
+packet_rcv (net/packet/af_packet.c:2152)
+...
+<TASK>
+__local_bh_enable_ip (kernel/softirq.c:407)
+netif_rx (net/core/dev.c:5648)
+chan_recv_cb (net/bluetooth/6lowpan.c:294 net/bluetooth/6lowpan.c:359)
+------
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index c4a1b478cf3e9..cfe3753a6f160 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -288,6 +288,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
+               local_skb->pkt_type = PACKET_HOST;
+               local_skb->dev = dev;
++              skb_reset_mac_header(local_skb);
+               skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
+               if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) {
+-- 
+2.51.0
+
diff --git a/queue-5.15/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch b/queue-5.15/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
new file mode 100644 (file)
index 0000000..960e334
--- /dev/null
@@ -0,0 +1,65 @@
+From a101ca3d2bdd1b539cb8a39759837dc51ef30a05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:28:41 -0500
+Subject: Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
+
+From: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+
+[ Upstream commit 23d22f2f71768034d6ef86168213843fc49bf550 ]
+
+There is a KASAN: slab-use-after-free read in btusb_disconnect().
+Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will
+free the btusb data associated with the interface. The same data is
+then used later in the function, hence the UAF.
+
+Fix by moving the accesses to btusb data to before the data is free'd.
+
+Reported-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2fc81b50a4f8263a159b
+Tested-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Fixes: fd913ef7ce619 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 4a5b937f78d91..c8c638aa47262 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4126,6 +4126,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+       hci_unregister_dev(hdev);
++      if (data->oob_wake_irq)
++              device_init_wakeup(&data->udev->dev, false);
++      if (data->reset_gpio)
++              gpiod_put(data->reset_gpio);
++
+       if (intf == data->intf) {
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
+@@ -4136,17 +4141,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+                       usb_driver_release_interface(&btusb_driver, data->diag);
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       } else if (intf == data->diag) {
+-              usb_driver_release_interface(&btusb_driver, data->intf);
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
++              usb_driver_release_interface(&btusb_driver, data->intf);
+       }
+-      if (data->oob_wake_irq)
+-              device_init_wakeup(&data->udev->dev, false);
+-
+-      if (data->reset_gpio)
+-              gpiod_put(data->reset_gpio);
+-
+       hci_free_dev(hdev);
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.15/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch b/queue-5.15/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
new file mode 100644 (file)
index 0000000..9788111
--- /dev/null
@@ -0,0 +1,37 @@
+From 57877b557e6e8cc6b66e5d2e94c9d6039eb31b03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:48 +0200
+Subject: Bluetooth: L2CAP: export l2cap_chan_hold for modules
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit e060088db0bdf7932e0e3c2d24b7371c4c5b867c ]
+
+l2cap_chan_put() is exported, so export also l2cap_chan_hold() for
+modules.
+
+l2cap_chan_hold() has use case in net/bluetooth/6lowpan.c
+
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 1af639f1dd8d1..06be471ce0c04 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -518,6 +518,7 @@ void l2cap_chan_hold(struct l2cap_chan *c)
+       kref_get(&c->kref);
+ }
++EXPORT_SYMBOL_GPL(l2cap_chan_hold);
+ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
+ {
+-- 
+2.51.0
+
diff --git a/queue-5.15/hsr-fix-supervision-frame-sending-on-hsrv0.patch b/queue-5.15/hsr-fix-supervision-frame-sending-on-hsrv0.patch
new file mode 100644 (file)
index 0000000..2f51155
--- /dev/null
@@ -0,0 +1,50 @@
+From 1484479a502adc2bfb3935f72230aa94dbb11cf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:29:32 +0100
+Subject: hsr: Fix supervision frame sending on HSRv0
+
+From: Felix Maurer <fmaurer@redhat.com>
+
+[ Upstream commit 96a3a03abf3d8cc38cd9cb0d280235fbcf7c3f7f ]
+
+On HSRv0, no supervision frames were sent. The supervison frames were
+generated successfully, but failed the check for a sufficiently long mac
+header, i.e., at least sizeof(struct hsr_ethhdr), in hsr_fill_frame_info()
+because the mac header only contained the ethernet header.
+
+Fix this by including the HSR header in the mac header when generating HSR
+supervision frames. Note that the mac header now also includes the TLV
+fields. This matches how we set the headers on rx and also the size of
+struct hsrv0_ethhdr_sp.
+
+Reported-by: Hangbin Liu <liuhangbin@gmail.com>
+Closes: https://lore.kernel.org/netdev/aMONxDXkzBZZRfE5@fedora/
+Fixes: 9cfb5e7f0ded ("net: hsr: fix hsr_init_sk() vs network/transport headers.")
+Signed-off-by: Felix Maurer <fmaurer@redhat.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://patch.msgid.link/4354114fea9a642fe71f49aeeb6c6159d1d61840.1762876095.git.fmaurer@redhat.com
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 503f2064e7323..85537b245aaeb 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -316,6 +316,9 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       }
+       hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag));
++      skb_set_network_header(skb, ETH_HLEN + HSR_HLEN);
++      skb_reset_mac_len(skb);
++
+       set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf));
+       set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch b/queue-5.15/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
new file mode 100644 (file)
index 0000000..d44a3f5
--- /dev/null
@@ -0,0 +1,39 @@
+From be344fdafe7134096abc3cc8c60748791c853cb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:14:21 +0800
+Subject: net: fec: correct rx_bytes statistic for the case SHIFT16 is set
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit ad17e7e92a7c52ce70bb764813fcf99464f96903 ]
+
+Two additional bytes in front of each frame received into the RX FIFO if
+SHIFT16 is set, so we need to subtract the extra two bytes from pkt_len
+to correct the statistic of rx_bytes.
+
+Fixes: 3ac72b7b63d5 ("net: fec: align IP header in hardware")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20251106021421.2096585-1-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index d457af64f8357..263e3755f5c3a 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1566,6 +1566,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               ndev->stats.rx_packets++;
+               pkt_len = fec16_to_cpu(bdp->cbd_datlen);
+               ndev->stats.rx_bytes += pkt_len;
++              if (fep->quirks & FEC_QUIRK_HAS_RACC)
++                      ndev->stats.rx_bytes -= 2;
+               index = fec_enet_get_bd_index(bdp, &rxq->bd);
+               skb = rxq->rx_skbuff[index];
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch b/queue-5.15/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
new file mode 100644 (file)
index 0000000..3696711
--- /dev/null
@@ -0,0 +1,45 @@
+From 21d0d2d6349d33e77147829e1f28547000e0b50b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 07:49:22 +0100
+Subject: net: mdio: fix resource leak in mdiobus_register_device()
+
+From: Buday Csaba <buday.csaba@prolan.hu>
+
+[ Upstream commit e6ca8f533ed41129fcf052297718f417f021cc7d ]
+
+Fix a possible leak in mdiobus_register_device() when both a
+reset-gpio and a reset-controller are present.
+Clean up the already claimed reset-gpio, when the registration of
+the reset-controller fails, so when an error code is returned, the
+device retains its state before the registration attempt.
+
+Link: https://lore.kernel.org/all/20251106144603.39053c81@kernel.org/
+Fixes: 71dd6c0dff51 ("net: phy: add support for reset-controller")
+Signed-off-by: Buday Csaba <buday.csaba@prolan.hu>
+Link: https://patch.msgid.link/4b419377f8dd7d2f63f919d0f74a336c734f8fff.1762584481.git.buday.csaba@prolan.hu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mdio_bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index 95536c5e541da..a8a4cd68f6886 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -80,8 +80,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
+                       return err;
+               err = mdiobus_register_reset(mdiodev);
+-              if (err)
++              if (err) {
++                      gpiod_put(mdiodev->reset_gpio);
++                      mdiodev->reset_gpio = NULL;
+                       return err;
++              }
+               /* Assert the reset signal */
+               mdio_device_reset(mdiodev, 1);
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch b/queue-5.15/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
new file mode 100644 (file)
index 0000000..217e62a
--- /dev/null
@@ -0,0 +1,58 @@
+From fcfc5b8ffd1e1b4a6f2bf528f892a7f86dadb834 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:51 +0200
+Subject: net/mlx5e: Fix maxrate wraparound in threshold between units
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit a7bf4d5063c7837096aab2853224eb23628514d9 ]
+
+The previous calculation used roundup() which caused an overflow for
+rates between 25.5Gbps and 26Gbps.
+For example, a rate of 25.6Gbps would result in using 100Mbps units with
+value of 256, which would overflow the 8 bits field.
+
+Simplify the upper_limit_mbps calculation by removing the
+unnecessary roundup, and adjust the comparison to use <= to correctly
+handle the boundary condition.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index f2862100d1a2e..51fadfcda35a5 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -587,18 +587,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       struct mlx5_core_dev *mdev = priv->mdev;
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+-      __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
++      __u64 upper_limit_mbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
++      upper_limit_mbps = 255 * MLX5E_100MB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+                       max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
+                       continue;
+               }
+-              if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
++              if (maxrate->tc_maxrate[i] <= upper_limit_mbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch b/queue-5.15/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
new file mode 100644 (file)
index 0000000..b6cc9ad
--- /dev/null
@@ -0,0 +1,62 @@
+From 9bf844322946c5e711bdc07e6221e71f399e102a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:52 +0200
+Subject: net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 43b27d1bd88a4bce34ec2437d103acfae9655f9e ]
+
+Add validation to reject rates exceeding 255 Gbps that would overflow
+the 8 bits max bandwidth field.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 51fadfcda35a5..86545554abb4e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -588,11 +588,13 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+       __u64 upper_limit_mbps;
++      __u64 upper_limit_gbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+       upper_limit_mbps = 255 * MLX5E_100MB;
++      upper_limit_gbps = 255 * MLX5E_1GB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+@@ -604,10 +606,16 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else {
++              } else if (max_bw_value[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
++              } else {
++                      netdev_err(netdev,
++                                 "tc_%d maxrate %llu Kbps exceeds limit %llu\n",
++                                 i, maxrate->tc_maxrate[i],
++                                 upper_limit_gbps);
++                      return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-sched-act-move-global-static-variable-net_id-to-.patch b/queue-5.15/net-sched-act-move-global-static-variable-net_id-to-.patch
new file mode 100644 (file)
index 0000000..cae3cfb
--- /dev/null
@@ -0,0 +1,1374 @@
+From 1cae21faf8f608694e9c8b9d05869baa4d755a0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Sep 2022 12:14:33 +0800
+Subject: net: sched: act: move global static variable net_id to tc_action_ops
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit acd0a7ab6334f35c3720120d53f79eb8e9b3ac2e ]
+
+Each tc action module has a corresponding net_id, so put net_id directly
+into the structure tc_action_ops.
+
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/act_api.h      |  1 +
+ net/sched/act_bpf.c        | 13 ++++++-------
+ net/sched/act_connmark.c   | 13 ++++++-------
+ net/sched/act_csum.c       | 13 ++++++-------
+ net/sched/act_ct.c         | 17 ++++++++---------
+ net/sched/act_ctinfo.c     | 13 ++++++-------
+ net/sched/act_gact.c       | 13 ++++++-------
+ net/sched/act_gate.c       | 13 ++++++-------
+ net/sched/act_ife.c        | 13 ++++++-------
+ net/sched/act_ipt.c        | 31 ++++++++++++++-----------------
+ net/sched/act_mirred.c     | 13 ++++++-------
+ net/sched/act_mpls.c       | 13 ++++++-------
+ net/sched/act_nat.c        | 13 ++++++-------
+ net/sched/act_pedit.c      | 13 ++++++-------
+ net/sched/act_police.c     | 13 ++++++-------
+ net/sched/act_sample.c     | 13 ++++++-------
+ net/sched/act_simple.c     | 13 ++++++-------
+ net/sched/act_skbedit.c    | 13 ++++++-------
+ net/sched/act_skbmod.c     | 13 ++++++-------
+ net/sched/act_tunnel_key.c | 13 ++++++-------
+ net/sched/act_vlan.c       | 13 ++++++-------
+ 21 files changed, 131 insertions(+), 152 deletions(-)
+
+diff --git a/include/net/act_api.h b/include/net/act_api.h
+index f19f7f4a463cd..5cd184ae91cc6 100644
+--- a/include/net/act_api.h
++++ b/include/net/act_api.h
+@@ -99,6 +99,7 @@ struct tc_action_ops {
+       struct list_head head;
+       char    kind[IFNAMSIZ];
+       enum tca_id  id; /* identifier should match kind */
++      unsigned int    net_id;
+       size_t  size;
+       struct module           *owner;
+       int     (*act)(struct sk_buff *, const struct tc_action *,
+diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
+index 2a05bad56ef3e..5576eb97d39e0 100644
+--- a/net/sched/act_bpf.c
++++ b/net/sched/act_bpf.c
+@@ -29,7 +29,6 @@ struct tcf_bpf_cfg {
+       bool is_ebpf;
+ };
+-static unsigned int bpf_net_id;
+ static struct tc_action_ops act_bpf_ops;
+ static int tcf_bpf_act(struct sk_buff *skb, const struct tc_action *act,
+@@ -278,7 +277,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
+                       struct tcf_proto *tp, u32 flags,
+                       struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, bpf_net_id);
++      struct tc_action_net *tn = net_generic(net, act_bpf_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
+       struct tcf_chain *goto_ch = NULL;
+@@ -393,14 +392,14 @@ static int tcf_bpf_walker(struct net *net, struct sk_buff *skb,
+                         const struct tc_action_ops *ops,
+                         struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, bpf_net_id);
++      struct tc_action_net *tn = net_generic(net, act_bpf_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, bpf_net_id);
++      struct tc_action_net *tn = net_generic(net, act_bpf_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -420,20 +419,20 @@ static struct tc_action_ops act_bpf_ops __read_mostly = {
+ static __net_init int bpf_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, bpf_net_id);
++      struct tc_action_net *tn = net_generic(net, act_bpf_ops.net_id);
+       return tc_action_net_init(net, tn, &act_bpf_ops);
+ }
+ static void __net_exit bpf_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, bpf_net_id);
++      tc_action_net_exit(net_list, act_bpf_ops.net_id);
+ }
+ static struct pernet_operations bpf_net_ops = {
+       .init = bpf_init_net,
+       .exit_batch = bpf_exit_net,
+-      .id   = &bpf_net_id,
++      .id   = &act_bpf_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 0deb4e96a6c2e..16b3d56ef2f43 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -25,7 +25,6 @@
+ #include <net/netfilter/nf_conntrack_core.h>
+ #include <net/netfilter/nf_conntrack_zones.h>
+-static unsigned int connmark_net_id;
+ static struct tc_action_ops act_connmark_ops;
+ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -99,7 +98,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+                            struct tcf_proto *tp, u32 flags,
+                            struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, connmark_net_id);
++      struct tc_action_net *tn = net_generic(net, act_connmark_ops.net_id);
+       struct nlattr *tb[TCA_CONNMARK_MAX + 1];
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct tcf_chain *goto_ch = NULL;
+@@ -205,14 +204,14 @@ static int tcf_connmark_walker(struct net *net, struct sk_buff *skb,
+                              const struct tc_action_ops *ops,
+                              struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, connmark_net_id);
++      struct tc_action_net *tn = net_generic(net, act_connmark_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, connmark_net_id);
++      struct tc_action_net *tn = net_generic(net, act_connmark_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -231,20 +230,20 @@ static struct tc_action_ops act_connmark_ops = {
+ static __net_init int connmark_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, connmark_net_id);
++      struct tc_action_net *tn = net_generic(net, act_connmark_ops.net_id);
+       return tc_action_net_init(net, tn, &act_connmark_ops);
+ }
+ static void __net_exit connmark_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, connmark_net_id);
++      tc_action_net_exit(net_list, act_connmark_ops.net_id);
+ }
+ static struct pernet_operations connmark_net_ops = {
+       .init = connmark_init_net,
+       .exit_batch = connmark_exit_net,
+-      .id   = &connmark_net_id,
++      .id   = &act_connmark_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
+index a15ec95e69c36..2f2fb0f7cc714 100644
+--- a/net/sched/act_csum.c
++++ b/net/sched/act_csum.c
+@@ -37,7 +37,6 @@ static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = {
+       [TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), },
+ };
+-static unsigned int csum_net_id;
+ static struct tc_action_ops act_csum_ops;
+ static int tcf_csum_init(struct net *net, struct nlattr *nla,
+@@ -45,7 +44,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
+                        struct tcf_proto *tp,
+                        u32 flags, struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, csum_net_id);
++      struct tc_action_net *tn = net_generic(net, act_csum_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct tcf_csum_params *params_new;
+       struct nlattr *tb[TCA_CSUM_MAX + 1];
+@@ -678,14 +677,14 @@ static int tcf_csum_walker(struct net *net, struct sk_buff *skb,
+                          const struct tc_action_ops *ops,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, csum_net_id);
++      struct tc_action_net *tn = net_generic(net, act_csum_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, csum_net_id);
++      struct tc_action_net *tn = net_generic(net, act_csum_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -711,20 +710,20 @@ static struct tc_action_ops act_csum_ops = {
+ static __net_init int csum_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, csum_net_id);
++      struct tc_action_net *tn = net_generic(net, act_csum_ops.net_id);
+       return tc_action_net_init(net, tn, &act_csum_ops);
+ }
+ static void __net_exit csum_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, csum_net_id);
++      tc_action_net_exit(net_list, act_csum_ops.net_id);
+ }
+ static struct pernet_operations csum_net_ops = {
+       .init = csum_init_net,
+       .exit_batch = csum_exit_net,
+-      .id   = &csum_net_id,
++      .id   = &act_csum_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
+index a6c3b7145a105..d50977ef83c67 100644
+--- a/net/sched/act_ct.c
++++ b/net/sched/act_ct.c
+@@ -574,7 +574,6 @@ static void tcf_ct_flow_tables_uninit(void)
+ }
+ static struct tc_action_ops act_ct_ops;
+-static unsigned int ct_net_id;
+ struct tc_ct_action_net {
+       struct tc_action_net tn; /* Must be first */
+@@ -1184,7 +1183,7 @@ static int tcf_ct_fill_params(struct net *net,
+                             struct nlattr **tb,
+                             struct netlink_ext_ack *extack)
+ {
+-      struct tc_ct_action_net *tn = net_generic(net, ct_net_id);
++      struct tc_ct_action_net *tn = net_generic(net, act_ct_ops.net_id);
+       struct nf_conntrack_zone zone;
+       struct nf_conn *tmpl;
+       int err;
+@@ -1259,7 +1258,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla,
+                      struct tcf_proto *tp, u32 flags,
+                      struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, ct_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ct_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct tcf_ct_params *params = NULL;
+       struct nlattr *tb[TCA_CT_MAX + 1];
+@@ -1495,14 +1494,14 @@ static int tcf_ct_walker(struct net *net, struct sk_buff *skb,
+                        const struct tc_action_ops *ops,
+                        struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, ct_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ct_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_ct_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, ct_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ct_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -1533,7 +1532,7 @@ static struct tc_action_ops act_ct_ops = {
+ static __net_init int ct_init_net(struct net *net)
+ {
+       unsigned int n_bits = sizeof_field(struct tcf_ct_params, labels) * 8;
+-      struct tc_ct_action_net *tn = net_generic(net, ct_net_id);
++      struct tc_ct_action_net *tn = net_generic(net, act_ct_ops.net_id);
+       if (nf_connlabels_get(net, n_bits - 1)) {
+               tn->labels = false;
+@@ -1551,20 +1550,20 @@ static void __net_exit ct_exit_net(struct list_head *net_list)
+       rtnl_lock();
+       list_for_each_entry(net, net_list, exit_list) {
+-              struct tc_ct_action_net *tn = net_generic(net, ct_net_id);
++              struct tc_ct_action_net *tn = net_generic(net, act_ct_ops.net_id);
+               if (tn->labels)
+                       nf_connlabels_put(net);
+       }
+       rtnl_unlock();
+-      tc_action_net_exit(net_list, ct_net_id);
++      tc_action_net_exit(net_list, act_ct_ops.net_id);
+ }
+ static struct pernet_operations ct_net_ops = {
+       .init = ct_init_net,
+       .exit_batch = ct_exit_net,
+-      .id   = &ct_net_id,
++      .id   = &act_ct_ops.net_id,
+       .size = sizeof(struct tc_ct_action_net),
+ };
+diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c
+index ddacd4fa442c6..dd6347c4d4eb2 100644
+--- a/net/sched/act_ctinfo.c
++++ b/net/sched/act_ctinfo.c
+@@ -25,7 +25,6 @@
+ #include <net/netfilter/nf_conntrack_zones.h>
+ static struct tc_action_ops act_ctinfo_ops;
+-static unsigned int ctinfo_net_id;
+ static void tcf_ctinfo_dscp_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+                               struct tcf_ctinfo_params *cp,
+@@ -157,7 +156,7 @@ static int tcf_ctinfo_init(struct net *net, struct nlattr *nla,
+                          struct tcf_proto *tp, u32 flags,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ctinfo_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       u32 dscpmask = 0, dscpstatemask, index;
+       struct nlattr *tb[TCA_CTINFO_MAX + 1];
+@@ -350,14 +349,14 @@ static int tcf_ctinfo_walker(struct net *net, struct sk_buff *skb,
+                            const struct tc_action_ops *ops,
+                            struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ctinfo_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_ctinfo_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ctinfo_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -387,20 +386,20 @@ static struct tc_action_ops act_ctinfo_ops = {
+ static __net_init int ctinfo_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ctinfo_ops.net_id);
+       return tc_action_net_init(net, tn, &act_ctinfo_ops);
+ }
+ static void __net_exit ctinfo_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, ctinfo_net_id);
++      tc_action_net_exit(net_list, act_ctinfo_ops.net_id);
+ }
+ static struct pernet_operations ctinfo_net_ops = {
+       .init           = ctinfo_init_net,
+       .exit_batch     = ctinfo_exit_net,
+-      .id             = &ctinfo_net_id,
++      .id             = &act_ctinfo_ops.net_id,
+       .size           = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
+index d8dce173df374..82148ca7d7541 100644
+--- a/net/sched/act_gact.c
++++ b/net/sched/act_gact.c
+@@ -19,7 +19,6 @@
+ #include <linux/tc_act/tc_gact.h>
+ #include <net/tc_act/tc_gact.h>
+-static unsigned int gact_net_id;
+ static struct tc_action_ops act_gact_ops;
+ #ifdef CONFIG_GACT_PROB
+@@ -55,7 +54,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,
+                        struct tcf_proto *tp, u32 flags,
+                        struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, gact_net_id);
++      struct tc_action_net *tn = net_generic(net, act_gact_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_GACT_MAX + 1];
+       struct tcf_chain *goto_ch = NULL;
+@@ -227,14 +226,14 @@ static int tcf_gact_walker(struct net *net, struct sk_buff *skb,
+                          const struct tc_action_ops *ops,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, gact_net_id);
++      struct tc_action_net *tn = net_generic(net, act_gact_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, gact_net_id);
++      struct tc_action_net *tn = net_generic(net, act_gact_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -268,20 +267,20 @@ static struct tc_action_ops act_gact_ops = {
+ static __net_init int gact_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, gact_net_id);
++      struct tc_action_net *tn = net_generic(net, act_gact_ops.net_id);
+       return tc_action_net_init(net, tn, &act_gact_ops);
+ }
+ static void __net_exit gact_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, gact_net_id);
++      tc_action_net_exit(net_list, act_gact_ops.net_id);
+ }
+ static struct pernet_operations gact_net_ops = {
+       .init = gact_init_net,
+       .exit_batch = gact_exit_net,
+-      .id   = &gact_net_id,
++      .id   = &act_gact_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_gate.c b/net/sched/act_gate.c
+index ac985c53ebafe..12b8fdbd9df1f 100644
+--- a/net/sched/act_gate.c
++++ b/net/sched/act_gate.c
+@@ -15,7 +15,6 @@
+ #include <net/pkt_cls.h>
+ #include <net/tc_act/tc_gate.h>
+-static unsigned int gate_net_id;
+ static struct tc_action_ops act_gate_ops;
+ static ktime_t gate_get_time(struct tcf_gate *gact)
+@@ -298,7 +297,7 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla,
+                        struct tcf_proto *tp, u32 flags,
+                        struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, gate_net_id);
++      struct tc_action_net *tn = net_generic(net, act_gate_ops.net_id);
+       enum tk_offsets tk_offset = TK_OFFS_TAI;
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_GATE_MAX + 1];
+@@ -570,7 +569,7 @@ static int tcf_gate_walker(struct net *net, struct sk_buff *skb,
+                          const struct tc_action_ops *ops,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, gate_net_id);
++      struct tc_action_net *tn = net_generic(net, act_gate_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+@@ -587,7 +586,7 @@ static void tcf_gate_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+ static int tcf_gate_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, gate_net_id);
++      struct tc_action_net *tn = net_generic(net, act_gate_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -614,20 +613,20 @@ static struct tc_action_ops act_gate_ops = {
+ static __net_init int gate_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, gate_net_id);
++      struct tc_action_net *tn = net_generic(net, act_gate_ops.net_id);
+       return tc_action_net_init(net, tn, &act_gate_ops);
+ }
+ static void __net_exit gate_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, gate_net_id);
++      tc_action_net_exit(net_list, act_gate_ops.net_id);
+ }
+ static struct pernet_operations gate_net_ops = {
+       .init = gate_init_net,
+       .exit_batch = gate_exit_net,
+-      .id   = &gate_net_id,
++      .id   = &act_gate_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index ec987ec758070..ca53783ea0c4d 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -30,7 +30,6 @@
+ #include <linux/etherdevice.h>
+ #include <net/ife.h>
+-static unsigned int ife_net_id;
+ static int max_metacnt = IFE_META_MAX + 1;
+ static struct tc_action_ops act_ife_ops;
+@@ -482,7 +481,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
+                       struct tcf_proto *tp, u32 flags,
+                       struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, ife_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ife_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_IFE_MAX + 1];
+       struct nlattr *tb2[IFE_META_MAX + 1];
+@@ -883,14 +882,14 @@ static int tcf_ife_walker(struct net *net, struct sk_buff *skb,
+                         const struct tc_action_ops *ops,
+                         struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, ife_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ife_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, ife_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ife_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -910,20 +909,20 @@ static struct tc_action_ops act_ife_ops = {
+ static __net_init int ife_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, ife_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ife_ops.net_id);
+       return tc_action_net_init(net, tn, &act_ife_ops);
+ }
+ static void __net_exit ife_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, ife_net_id);
++      tc_action_net_exit(net_list, act_ife_ops.net_id);
+ }
+ static struct pernet_operations ife_net_ops = {
+       .init = ife_init_net,
+       .exit_batch = ife_exit_net,
+-      .id   = &ife_net_id,
++      .id   = &act_ife_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
+index ebd403f571ea5..6f04b35eb6539 100644
+--- a/net/sched/act_ipt.c
++++ b/net/sched/act_ipt.c
+@@ -24,10 +24,7 @@
+ #include <linux/netfilter_ipv4/ip_tables.h>
+-static unsigned int ipt_net_id;
+ static struct tc_action_ops act_ipt_ops;
+-
+-static unsigned int xt_net_id;
+ static struct tc_action_ops act_xt_ops;
+ static int ipt_init_target(struct net *net, struct xt_entry_target *t,
+@@ -219,8 +216,8 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla,
+                       struct tcf_proto *tp,
+                       u32 flags, struct netlink_ext_ack *extack)
+ {
+-      return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops,
+-                            tp, flags);
++      return __tcf_ipt_init(net, act_ipt_ops.net_id, nla, est,
++                            a, &act_ipt_ops, tp, flags);
+ }
+ static int tcf_xt_init(struct net *net, struct nlattr *nla,
+@@ -228,8 +225,8 @@ static int tcf_xt_init(struct net *net, struct nlattr *nla,
+                      struct tcf_proto *tp,
+                      u32 flags, struct netlink_ext_ack *extack)
+ {
+-      return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops,
+-                            tp, flags);
++      return __tcf_ipt_init(net, act_xt_ops.net_id, nla, est,
++                            a, &act_xt_ops, tp, flags);
+ }
+ static int tcf_ipt_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -334,14 +331,14 @@ static int tcf_ipt_walker(struct net *net, struct sk_buff *skb,
+                         const struct tc_action_ops *ops,
+                         struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, ipt_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ipt_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, ipt_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ipt_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -361,20 +358,20 @@ static struct tc_action_ops act_ipt_ops = {
+ static __net_init int ipt_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, ipt_net_id);
++      struct tc_action_net *tn = net_generic(net, act_ipt_ops.net_id);
+       return tc_action_net_init(net, tn, &act_ipt_ops);
+ }
+ static void __net_exit ipt_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, ipt_net_id);
++      tc_action_net_exit(net_list, act_ipt_ops.net_id);
+ }
+ static struct pernet_operations ipt_net_ops = {
+       .init = ipt_init_net,
+       .exit_batch = ipt_exit_net,
+-      .id   = &ipt_net_id,
++      .id   = &act_ipt_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+@@ -383,14 +380,14 @@ static int tcf_xt_walker(struct net *net, struct sk_buff *skb,
+                        const struct tc_action_ops *ops,
+                        struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, xt_net_id);
++      struct tc_action_net *tn = net_generic(net, act_xt_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, xt_net_id);
++      struct tc_action_net *tn = net_generic(net, act_xt_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -410,20 +407,20 @@ static struct tc_action_ops act_xt_ops = {
+ static __net_init int xt_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, xt_net_id);
++      struct tc_action_net *tn = net_generic(net, act_xt_ops.net_id);
+       return tc_action_net_init(net, tn, &act_xt_ops);
+ }
+ static void __net_exit xt_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, xt_net_id);
++      tc_action_net_exit(net_list, act_xt_ops.net_id);
+ }
+ static struct pernet_operations xt_net_ops = {
+       .init = xt_init_net,
+       .exit_batch = xt_exit_net,
+-      .id   = &xt_net_id,
++      .id   = &act_xt_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index 1aa1d10de30e4..1daa1622c6a0b 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -86,7 +86,6 @@ static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
+       [TCA_MIRRED_PARMS]      = { .len = sizeof(struct tc_mirred) },
+ };
+-static unsigned int mirred_net_id;
+ static struct tc_action_ops act_mirred_ops;
+ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
+@@ -94,7 +93,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
+                          struct tcf_proto *tp,
+                          u32 flags, struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, mirred_net_id);
++      struct tc_action_net *tn = net_generic(net, act_mirred_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_MIRRED_MAX + 1];
+       struct tcf_chain *goto_ch = NULL;
+@@ -387,14 +386,14 @@ static int tcf_mirred_walker(struct net *net, struct sk_buff *skb,
+                            const struct tc_action_ops *ops,
+                            struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, mirred_net_id);
++      struct tc_action_net *tn = net_generic(net, act_mirred_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_mirred_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, mirred_net_id);
++      struct tc_action_net *tn = net_generic(net, act_mirred_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -477,20 +476,20 @@ static struct tc_action_ops act_mirred_ops = {
+ static __net_init int mirred_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, mirred_net_id);
++      struct tc_action_net *tn = net_generic(net, act_mirred_ops.net_id);
+       return tc_action_net_init(net, tn, &act_mirred_ops);
+ }
+ static void __net_exit mirred_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, mirred_net_id);
++      tc_action_net_exit(net_list, act_mirred_ops.net_id);
+ }
+ static struct pernet_operations mirred_net_ops = {
+       .init = mirred_init_net,
+       .exit_batch = mirred_exit_net,
+-      .id   = &mirred_net_id,
++      .id   = &act_mirred_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c
+index d010c5b8e83b1..75a87a068c536 100644
+--- a/net/sched/act_mpls.c
++++ b/net/sched/act_mpls.c
+@@ -15,7 +15,6 @@
+ #include <net/pkt_cls.h>
+ #include <net/tc_act/tc_mpls.h>
+-static unsigned int mpls_net_id;
+ static struct tc_action_ops act_mpls_ops;
+ #define ACT_MPLS_TTL_DEFAULT  255
+@@ -161,7 +160,7 @@ static int tcf_mpls_init(struct net *net, struct nlattr *nla,
+                        struct tcf_proto *tp, u32 flags,
+                        struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, mpls_net_id);
++      struct tc_action_net *tn = net_generic(net, act_mpls_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_MPLS_MAX + 1];
+       struct tcf_chain *goto_ch = NULL;
+@@ -386,14 +385,14 @@ static int tcf_mpls_walker(struct net *net, struct sk_buff *skb,
+                          const struct tc_action_ops *ops,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, mpls_net_id);
++      struct tc_action_net *tn = net_generic(net, act_mpls_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_mpls_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, mpls_net_id);
++      struct tc_action_net *tn = net_generic(net, act_mpls_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -413,20 +412,20 @@ static struct tc_action_ops act_mpls_ops = {
+ static __net_init int mpls_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, mpls_net_id);
++      struct tc_action_net *tn = net_generic(net, act_mpls_ops.net_id);
+       return tc_action_net_init(net, tn, &act_mpls_ops);
+ }
+ static void __net_exit mpls_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, mpls_net_id);
++      tc_action_net_exit(net_list, act_mpls_ops.net_id);
+ }
+ static struct pernet_operations mpls_net_ops = {
+       .init = mpls_init_net,
+       .exit_batch = mpls_exit_net,
+-      .id   = &mpls_net_id,
++      .id   = &act_mpls_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
+index 2a39b3729e844..f5810387ce9ae 100644
+--- a/net/sched/act_nat.c
++++ b/net/sched/act_nat.c
+@@ -26,7 +26,6 @@
+ #include <net/udp.h>
+-static unsigned int nat_net_id;
+ static struct tc_action_ops act_nat_ops;
+ static const struct nla_policy nat_policy[TCA_NAT_MAX + 1] = {
+@@ -37,7 +36,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
+                       struct tc_action **a, struct tcf_proto *tp,
+                       u32 flags, struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, nat_net_id);
++      struct tc_action_net *tn = net_generic(net, act_nat_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_NAT_MAX + 1];
+       struct tcf_chain *goto_ch = NULL;
+@@ -294,14 +293,14 @@ static int tcf_nat_walker(struct net *net, struct sk_buff *skb,
+                         const struct tc_action_ops *ops,
+                         struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, nat_net_id);
++      struct tc_action_net *tn = net_generic(net, act_nat_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, nat_net_id);
++      struct tc_action_net *tn = net_generic(net, act_nat_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -320,20 +319,20 @@ static struct tc_action_ops act_nat_ops = {
+ static __net_init int nat_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, nat_net_id);
++      struct tc_action_net *tn = net_generic(net, act_nat_ops.net_id);
+       return tc_action_net_init(net, tn, &act_nat_ops);
+ }
+ static void __net_exit nat_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, nat_net_id);
++      tc_action_net_exit(net_list, act_nat_ops.net_id);
+ }
+ static struct pernet_operations nat_net_ops = {
+       .init = nat_init_net,
+       .exit_batch = nat_exit_net,
+-      .id   = &nat_net_id,
++      .id   = &act_nat_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
+index df9ff123a7eec..d800e0285d5c2 100644
+--- a/net/sched/act_pedit.c
++++ b/net/sched/act_pedit.c
+@@ -24,7 +24,6 @@
+ #include <uapi/linux/tc_act/tc_pedit.h>
+ #include <net/pkt_cls.h>
+-static unsigned int pedit_net_id;
+ static struct tc_action_ops act_pedit_ops;
+ static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = {
+@@ -154,7 +153,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+                         struct tcf_proto *tp, u32 flags,
+                         struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, pedit_net_id);
++      struct tc_action_net *tn = net_generic(net, act_pedit_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct tcf_chain *goto_ch = NULL;
+       struct tcf_pedit_parms *oparms, *nparms;
+@@ -548,14 +547,14 @@ static int tcf_pedit_walker(struct net *net, struct sk_buff *skb,
+                           const struct tc_action_ops *ops,
+                           struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, pedit_net_id);
++      struct tc_action_net *tn = net_generic(net, act_pedit_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, pedit_net_id);
++      struct tc_action_net *tn = net_generic(net, act_pedit_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -576,20 +575,20 @@ static struct tc_action_ops act_pedit_ops = {
+ static __net_init int pedit_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, pedit_net_id);
++      struct tc_action_net *tn = net_generic(net, act_pedit_ops.net_id);
+       return tc_action_net_init(net, tn, &act_pedit_ops);
+ }
+ static void __net_exit pedit_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, pedit_net_id);
++      tc_action_net_exit(net_list, act_pedit_ops.net_id);
+ }
+ static struct pernet_operations pedit_net_ops = {
+       .init = pedit_init_net,
+       .exit_batch = pedit_exit_net,
+-      .id   = &pedit_net_id,
++      .id   = &act_pedit_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_police.c b/net/sched/act_police.c
+index db1d021c16be8..13878b0520f36 100644
+--- a/net/sched/act_police.c
++++ b/net/sched/act_police.c
+@@ -22,7 +22,6 @@
+ /* Each policer is serialized by its individual spinlock */
+-static unsigned int police_net_id;
+ static struct tc_action_ops act_police_ops;
+ static int tcf_police_walker(struct net *net, struct sk_buff *skb,
+@@ -30,7 +29,7 @@ static int tcf_police_walker(struct net *net, struct sk_buff *skb,
+                                const struct tc_action_ops *ops,
+                                struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, police_net_id);
++      struct tc_action_net *tn = net_generic(net, act_police_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+@@ -58,7 +57,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
+       struct tc_police *parm;
+       struct tcf_police *police;
+       struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL;
+-      struct tc_action_net *tn = net_generic(net, police_net_id);
++      struct tc_action_net *tn = net_generic(net, act_police_ops.net_id);
+       struct tcf_police_params *new;
+       bool exists = false;
+       u32 index;
+@@ -414,7 +413,7 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a,
+ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, police_net_id);
++      struct tc_action_net *tn = net_generic(net, act_police_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -439,20 +438,20 @@ static struct tc_action_ops act_police_ops = {
+ static __net_init int police_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, police_net_id);
++      struct tc_action_net *tn = net_generic(net, act_police_ops.net_id);
+       return tc_action_net_init(net, tn, &act_police_ops);
+ }
+ static void __net_exit police_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, police_net_id);
++      tc_action_net_exit(net_list, act_police_ops.net_id);
+ }
+ static struct pernet_operations police_net_ops = {
+       .init = police_init_net,
+       .exit_batch = police_exit_net,
+-      .id   = &police_net_id,
++      .id   = &act_police_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
+index ca67d96449176..aa0b1215b58f4 100644
+--- a/net/sched/act_sample.c
++++ b/net/sched/act_sample.c
+@@ -23,7 +23,6 @@
+ #include <linux/if_arp.h>
+-static unsigned int sample_net_id;
+ static struct tc_action_ops act_sample_ops;
+ static const struct nla_policy sample_policy[TCA_SAMPLE_MAX + 1] = {
+@@ -38,7 +37,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
+                          struct tcf_proto *tp,
+                          u32 flags, struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, sample_net_id);
++      struct tc_action_net *tn = net_generic(net, act_sample_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_SAMPLE_MAX + 1];
+       struct psample_group *psample_group;
+@@ -253,14 +252,14 @@ static int tcf_sample_walker(struct net *net, struct sk_buff *skb,
+                            const struct tc_action_ops *ops,
+                            struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, sample_net_id);
++      struct tc_action_net *tn = net_generic(net, act_sample_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, sample_net_id);
++      struct tc_action_net *tn = net_generic(net, act_sample_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -306,20 +305,20 @@ static struct tc_action_ops act_sample_ops = {
+ static __net_init int sample_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, sample_net_id);
++      struct tc_action_net *tn = net_generic(net, act_sample_ops.net_id);
+       return tc_action_net_init(net, tn, &act_sample_ops);
+ }
+ static void __net_exit sample_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, sample_net_id);
++      tc_action_net_exit(net_list, act_sample_ops.net_id);
+ }
+ static struct pernet_operations sample_net_ops = {
+       .init = sample_init_net,
+       .exit_batch = sample_exit_net,
+-      .id   = &sample_net_id,
++      .id   = &act_sample_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
+index 7885271540259..2188554dac8d8 100644
+--- a/net/sched/act_simple.c
++++ b/net/sched/act_simple.c
+@@ -18,7 +18,6 @@
+ #include <linux/tc_act/tc_defact.h>
+ #include <net/tc_act/tc_defact.h>
+-static unsigned int simp_net_id;
+ static struct tc_action_ops act_simp_ops;
+ #define SIMP_MAX_DATA 32
+@@ -88,7 +87,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
+                        struct tcf_proto *tp, u32 flags,
+                        struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, simp_net_id);
++      struct tc_action_net *tn = net_generic(net, act_simp_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_DEF_MAX + 1];
+       struct tcf_chain *goto_ch = NULL;
+@@ -202,14 +201,14 @@ static int tcf_simp_walker(struct net *net, struct sk_buff *skb,
+                          const struct tc_action_ops *ops,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, simp_net_id);
++      struct tc_action_net *tn = net_generic(net, act_simp_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, simp_net_id);
++      struct tc_action_net *tn = net_generic(net, act_simp_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -229,20 +228,20 @@ static struct tc_action_ops act_simp_ops = {
+ static __net_init int simp_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, simp_net_id);
++      struct tc_action_net *tn = net_generic(net, act_simp_ops.net_id);
+       return tc_action_net_init(net, tn, &act_simp_ops);
+ }
+ static void __net_exit simp_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, simp_net_id);
++      tc_action_net_exit(net_list, act_simp_ops.net_id);
+ }
+ static struct pernet_operations simp_net_ops = {
+       .init = simp_init_net,
+       .exit_batch = simp_exit_net,
+-      .id   = &simp_net_id,
++      .id   = &act_simp_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
+index 6088ceaf582e8..0c91f88476baf 100644
+--- a/net/sched/act_skbedit.c
++++ b/net/sched/act_skbedit.c
+@@ -20,7 +20,6 @@
+ #include <linux/tc_act/tc_skbedit.h>
+ #include <net/tc_act/tc_skbedit.h>
+-static unsigned int skbedit_net_id;
+ static struct tc_action_ops act_skbedit_ops;
+ static int tcf_skbedit_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -99,7 +98,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
+                           struct tcf_proto *tp, u32 act_flags,
+                           struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, skbedit_net_id);
++      struct tc_action_net *tn = net_generic(net, act_skbedit_ops.net_id);
+       bool bind = act_flags & TCA_ACT_FLAGS_BIND;
+       struct tcf_skbedit_params *params_new;
+       struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
+@@ -304,14 +303,14 @@ static int tcf_skbedit_walker(struct net *net, struct sk_buff *skb,
+                             const struct tc_action_ops *ops,
+                             struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, skbedit_net_id);
++      struct tc_action_net *tn = net_generic(net, act_skbedit_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, skbedit_net_id);
++      struct tc_action_net *tn = net_generic(net, act_skbedit_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -344,20 +343,20 @@ static struct tc_action_ops act_skbedit_ops = {
+ static __net_init int skbedit_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, skbedit_net_id);
++      struct tc_action_net *tn = net_generic(net, act_skbedit_ops.net_id);
+       return tc_action_net_init(net, tn, &act_skbedit_ops);
+ }
+ static void __net_exit skbedit_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, skbedit_net_id);
++      tc_action_net_exit(net_list, act_skbedit_ops.net_id);
+ }
+ static struct pernet_operations skbedit_net_ops = {
+       .init = skbedit_init_net,
+       .exit_batch = skbedit_exit_net,
+-      .id   = &skbedit_net_id,
++      .id   = &act_skbedit_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c
+index d5b421072b998..37395ab1df472 100644
+--- a/net/sched/act_skbmod.c
++++ b/net/sched/act_skbmod.c
+@@ -19,7 +19,6 @@
+ #include <linux/tc_act/tc_skbmod.h>
+ #include <net/tc_act/tc_skbmod.h>
+-static unsigned int skbmod_net_id;
+ static struct tc_action_ops act_skbmod_ops;
+ static int tcf_skbmod_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -103,7 +102,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
+                          struct tcf_proto *tp, u32 flags,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, skbmod_net_id);
++      struct tc_action_net *tn = net_generic(net, act_skbmod_ops.net_id);
+       bool ovr = flags & TCA_ACT_FLAGS_REPLACE;
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_SKBMOD_MAX + 1];
+@@ -281,14 +280,14 @@ static int tcf_skbmod_walker(struct net *net, struct sk_buff *skb,
+                            const struct tc_action_ops *ops,
+                            struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, skbmod_net_id);
++      struct tc_action_net *tn = net_generic(net, act_skbmod_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, skbmod_net_id);
++      struct tc_action_net *tn = net_generic(net, act_skbmod_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -308,20 +307,20 @@ static struct tc_action_ops act_skbmod_ops = {
+ static __net_init int skbmod_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, skbmod_net_id);
++      struct tc_action_net *tn = net_generic(net, act_skbmod_ops.net_id);
+       return tc_action_net_init(net, tn, &act_skbmod_ops);
+ }
+ static void __net_exit skbmod_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, skbmod_net_id);
++      tc_action_net_exit(net_list, act_skbmod_ops.net_id);
+ }
+ static struct pernet_operations skbmod_net_ops = {
+       .init = skbmod_init_net,
+       .exit_batch = skbmod_exit_net,
+-      .id   = &skbmod_net_id,
++      .id   = &act_skbmod_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index 64277ce3c5eb9..c79f23367dfb3 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -20,7 +20,6 @@
+ #include <linux/tc_act/tc_tunnel_key.h>
+ #include <net/tc_act/tc_tunnel_key.h>
+-static unsigned int tunnel_key_net_id;
+ static struct tc_action_ops act_tunnel_key_ops;
+ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -358,7 +357,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
+                          struct tcf_proto *tp, u32 act_flags,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
++      struct tc_action_net *tn = net_generic(net, act_tunnel_key_ops.net_id);
+       bool bind = act_flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
+       struct tcf_tunnel_key_params *params_new;
+@@ -775,14 +774,14 @@ static int tunnel_key_walker(struct net *net, struct sk_buff *skb,
+                            const struct tc_action_ops *ops,
+                            struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
++      struct tc_action_net *tn = net_generic(net, act_tunnel_key_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+ static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
++      struct tc_action_net *tn = net_generic(net, act_tunnel_key_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -802,20 +801,20 @@ static struct tc_action_ops act_tunnel_key_ops = {
+ static __net_init int tunnel_key_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
++      struct tc_action_net *tn = net_generic(net, act_tunnel_key_ops.net_id);
+       return tc_action_net_init(net, tn, &act_tunnel_key_ops);
+ }
+ static void __net_exit tunnel_key_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, tunnel_key_net_id);
++      tc_action_net_exit(net_list, act_tunnel_key_ops.net_id);
+ }
+ static struct pernet_operations tunnel_key_net_ops = {
+       .init = tunnel_key_init_net,
+       .exit_batch = tunnel_key_exit_net,
+-      .id   = &tunnel_key_net_id,
++      .id   = &act_tunnel_key_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
+index e4dc5a555bd85..61a38ae2064ce 100644
+--- a/net/sched/act_vlan.c
++++ b/net/sched/act_vlan.c
+@@ -16,7 +16,6 @@
+ #include <linux/tc_act/tc_vlan.h>
+ #include <net/tc_act/tc_vlan.h>
+-static unsigned int vlan_net_id;
+ static struct tc_action_ops act_vlan_ops;
+ static int tcf_vlan_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -117,7 +116,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
+                        struct tcf_proto *tp, u32 flags,
+                        struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, vlan_net_id);
++      struct tc_action_net *tn = net_generic(net, act_vlan_ops.net_id);
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct nlattr *tb[TCA_VLAN_MAX + 1];
+       struct tcf_chain *goto_ch = NULL;
+@@ -338,7 +337,7 @@ static int tcf_vlan_walker(struct net *net, struct sk_buff *skb,
+                          const struct tc_action_ops *ops,
+                          struct netlink_ext_ack *extack)
+ {
+-      struct tc_action_net *tn = net_generic(net, vlan_net_id);
++      struct tc_action_net *tn = net_generic(net, act_vlan_ops.net_id);
+       return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+ }
+@@ -355,7 +354,7 @@ static void tcf_vlan_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index)
+ {
+-      struct tc_action_net *tn = net_generic(net, vlan_net_id);
++      struct tc_action_net *tn = net_generic(net, act_vlan_ops.net_id);
+       return tcf_idr_search(tn, a, index);
+ }
+@@ -385,20 +384,20 @@ static struct tc_action_ops act_vlan_ops = {
+ static __net_init int vlan_init_net(struct net *net)
+ {
+-      struct tc_action_net *tn = net_generic(net, vlan_net_id);
++      struct tc_action_net *tn = net_generic(net, act_vlan_ops.net_id);
+       return tc_action_net_init(net, tn, &act_vlan_ops);
+ }
+ static void __net_exit vlan_exit_net(struct list_head *net_list)
+ {
+-      tc_action_net_exit(net_list, vlan_net_id);
++      tc_action_net_exit(net_list, act_vlan_ops.net_id);
+ }
+ static struct pernet_operations vlan_net_ops = {
+       .init = vlan_init_net,
+       .exit_batch = vlan_exit_net,
+-      .id   = &vlan_net_id,
++      .id   = &act_vlan_ops.net_id,
+       .size = sizeof(struct tc_action_net),
+ };
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-sched-act_connmark-get-rid-of-tcf_connmark_walke.patch b/queue-5.15/net-sched-act_connmark-get-rid-of-tcf_connmark_walke.patch
new file mode 100644 (file)
index 0000000..741d12f
--- /dev/null
@@ -0,0 +1,62 @@
+From 93929765eff6563550f5752774b3ff53de8888ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Sep 2022 12:14:36 +0800
+Subject: net: sched: act_connmark: get rid of tcf_connmark_walker and
+ tcf_connmark_search
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit c4d2497032ae31d234425648bf2720dfb1688796 ]
+
+tcf_connmark_walker() and tcf_connmark_search() do the same thing as
+generic walk/search function, so remove them.
+
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_connmark.c | 19 -------------------
+ 1 file changed, 19 deletions(-)
+
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 16b3d56ef2f43..d41002e4613ff 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -199,23 +199,6 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       return -1;
+ }
+-static int tcf_connmark_walker(struct net *net, struct sk_buff *skb,
+-                             struct netlink_callback *cb, int type,
+-                             const struct tc_action_ops *ops,
+-                             struct netlink_ext_ack *extack)
+-{
+-      struct tc_action_net *tn = net_generic(net, act_connmark_ops.net_id);
+-
+-      return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+-}
+-
+-static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index)
+-{
+-      struct tc_action_net *tn = net_generic(net, act_connmark_ops.net_id);
+-
+-      return tcf_idr_search(tn, a, index);
+-}
+-
+ static struct tc_action_ops act_connmark_ops = {
+       .kind           =       "connmark",
+       .id             =       TCA_ID_CONNMARK,
+@@ -223,8 +206,6 @@ static struct tc_action_ops act_connmark_ops = {
+       .act            =       tcf_connmark_act,
+       .dump           =       tcf_connmark_dump,
+       .init           =       tcf_connmark_init,
+-      .walk           =       tcf_connmark_walker,
+-      .lookup         =       tcf_connmark_search,
+       .size           =       sizeof(struct tcf_connmark_info),
+ };
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch b/queue-5.15/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
new file mode 100644 (file)
index 0000000..e3baddf
--- /dev/null
@@ -0,0 +1,59 @@
+From f6912c7eee964bbc3cac787806f641c5897f1f06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:35 +0530
+Subject: net: sched: act_connmark: initialize struct tc_ife to fix kernel leak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit 62b656e43eaeae445a39cd8021a4f47065af4389 ]
+
+In tcf_connmark_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: 22a5dc0e5e3e ("net: sched: Introduce connmark action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-2-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_connmark.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 79cfe51a09e74..4d75d2ae0d8ce 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -190,13 +190,15 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+       const struct tcf_connmark_parms *parms;
+-      struct tc_connmark opt = {
+-              .index   = ci->tcf_index,
+-              .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+-      };
++      struct tc_connmark opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index   = ci->tcf_index;
++      opt.refcnt  = refcount_read(&ci->tcf_refcnt) - ref;
++      opt.bindcnt = atomic_read(&ci->tcf_bindcnt) - bind;
++
+       rcu_read_lock();
+       parms = rcu_dereference(ci->parms);
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-sched-act_connmark-transition-to-percpu-stats-an.patch b/queue-5.15/net-sched-act_connmark-transition-to-percpu-stats-an.patch
new file mode 100644 (file)
index 0000000..4a60553
--- /dev/null
@@ -0,0 +1,277 @@
+From 39102d64bf0016236184ff0e564c1c7f4b5a11b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 18:15:32 -0300
+Subject: net/sched: act_connmark: transition to percpu stats and rcu
+
+From: Pedro Tammela <pctammela@mojatatu.com>
+
+[ Upstream commit 288864effe33885988d53faf7830b35cb9a84c7a ]
+
+The tc action act_connmark was using shared stats and taking the per
+action lock in the datapath. Improve it by using percpu stats and rcu.
+
+perf before:
+- 13.55% tcf_connmark_act
+   - 81.18% _raw_spin_lock
+       80.46% native_queued_spin_lock_slowpath
+
+perf after:
+- 2.85% tcf_connmark_act
+
+tdc results:
+1..15
+ok 1 2002 - Add valid connmark action with defaults
+ok 2 56a5 - Add valid connmark action with control pass
+ok 3 7c66 - Add valid connmark action with control drop
+ok 4 a913 - Add valid connmark action with control pipe
+ok 5 bdd8 - Add valid connmark action with control reclassify
+ok 6 b8be - Add valid connmark action with control continue
+ok 7 d8a6 - Add valid connmark action with control jump
+ok 8 aae8 - Add valid connmark action with zone argument
+ok 9 2f0b - Add valid connmark action with invalid zone argument
+ok 10 9305 - Add connmark action with unsupported argument
+ok 11 71ca - Add valid connmark action and replace it
+ok 12 5f8f - Add valid connmark action with cookie
+ok 13 c506 - Replace connmark with invalid goto chain control
+ok 14 6571 - Delete connmark action with valid index
+ok 15 3426 - Delete connmark action with invalid index
+
+Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tc_act/tc_connmark.h |   9 ++-
+ net/sched/act_connmark.c         | 107 ++++++++++++++++++++-----------
+ 2 files changed, 75 insertions(+), 41 deletions(-)
+
+diff --git a/include/net/tc_act/tc_connmark.h b/include/net/tc_act/tc_connmark.h
+index 1f4cb477bb5d6..e8dd77a967480 100644
+--- a/include/net/tc_act/tc_connmark.h
++++ b/include/net/tc_act/tc_connmark.h
+@@ -4,10 +4,15 @@
+ #include <net/act_api.h>
+-struct tcf_connmark_info {
+-      struct tc_action common;
++struct tcf_connmark_parms {
+       struct net *net;
+       u16 zone;
++      struct rcu_head rcu;
++};
++
++struct tcf_connmark_info {
++      struct tc_action common;
++      struct tcf_connmark_parms __rcu *parms;
+ };
+ #define to_connmark(a) ((struct tcf_connmark_info *)a)
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index d41002e4613ff..418d60435b9d4 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -34,13 +34,15 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+       struct nf_conntrack_tuple tuple;
+       enum ip_conntrack_info ctinfo;
+       struct tcf_connmark_info *ca = to_connmark(a);
++      struct tcf_connmark_parms *parms;
+       struct nf_conntrack_zone zone;
+       struct nf_conn *c;
+       int proto;
+-      spin_lock(&ca->tcf_lock);
+       tcf_lastuse_update(&ca->tcf_tm);
+-      bstats_update(&ca->tcf_bstats, skb);
++      tcf_action_update_bstats(&ca->common, skb);
++
++      parms = rcu_dereference_bh(ca->parms);
+       switch (skb_protocol(skb, true)) {
+       case htons(ETH_P_IP):
+@@ -62,31 +64,29 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+       c = nf_ct_get(skb, &ctinfo);
+       if (c) {
+               skb->mark = READ_ONCE(c->mark);
+-              /* using overlimits stats to count how many packets marked */
+-              ca->tcf_qstats.overlimits++;
+-              goto out;
++              goto count;
+       }
+-      if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
+-                             proto, ca->net, &tuple))
++      if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, parms->net,
++                             &tuple))
+               goto out;
+-      zone.id = ca->zone;
++      zone.id = parms->zone;
+       zone.dir = NF_CT_DEFAULT_ZONE_DIR;
+-      thash = nf_conntrack_find_get(ca->net, &zone, &tuple);
++      thash = nf_conntrack_find_get(parms->net, &zone, &tuple);
+       if (!thash)
+               goto out;
+       c = nf_ct_tuplehash_to_ctrack(thash);
+-      /* using overlimits stats to count how many packets marked */
+-      ca->tcf_qstats.overlimits++;
+       skb->mark = READ_ONCE(c->mark);
+       nf_ct_put(c);
++count:
++      /* using overlimits stats to count how many packets marked */
++      tcf_action_inc_overlimit_qstats(&ca->common);
+ out:
+-      spin_unlock(&ca->tcf_lock);
+-      return ca->tcf_action;
++      return READ_ONCE(ca->tcf_action);
+ }
+ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
+@@ -99,6 +99,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+                            struct netlink_ext_ack *extack)
+ {
+       struct tc_action_net *tn = net_generic(net, act_connmark_ops.net_id);
++      struct tcf_connmark_parms *nparms, *oparms;
+       struct nlattr *tb[TCA_CONNMARK_MAX + 1];
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct tcf_chain *goto_ch = NULL;
+@@ -118,52 +119,66 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+       if (!tb[TCA_CONNMARK_PARMS])
+               return -EINVAL;
++      nparms = kzalloc(sizeof(*nparms), GFP_KERNEL);
++      if (!nparms)
++              return -ENOMEM;
++
+       parm = nla_data(tb[TCA_CONNMARK_PARMS]);
+       index = parm->index;
+       ret = tcf_idr_check_alloc(tn, &index, a, bind);
+       if (!ret) {
+-              ret = tcf_idr_create(tn, index, est, a,
+-                                   &act_connmark_ops, bind, false, flags);
++              ret = tcf_idr_create_from_flags(tn, index, est, a,
++                                              &act_connmark_ops, bind, flags);
+               if (ret) {
+                       tcf_idr_cleanup(tn, index);
+-                      return ret;
++                      err = ret;
++                      goto out_free;
+               }
+               ci = to_connmark(*a);
+-              err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch,
+-                                             extack);
+-              if (err < 0)
+-                      goto release_idr;
+-              tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+-              ci->net = net;
+-              ci->zone = parm->zone;
++
++              nparms->net = net;
++              nparms->zone = parm->zone;
+               ret = ACT_P_CREATED;
+       } else if (ret > 0) {
+               ci = to_connmark(*a);
+-              if (bind)
+-                      return 0;
+-              if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
+-                      tcf_idr_release(*a, bind);
+-                      return -EEXIST;
++              if (bind) {
++                      err = 0;
++                      goto out_free;
+               }
+-              err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch,
+-                                             extack);
+-              if (err < 0)
++              if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
++                      err = -EEXIST;
+                       goto release_idr;
+-              /* replacing action and zone */
+-              spin_lock_bh(&ci->tcf_lock);
+-              goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+-              ci->zone = parm->zone;
+-              spin_unlock_bh(&ci->tcf_lock);
+-              if (goto_ch)
+-                      tcf_chain_put_by_act(goto_ch);
++              }
++
++              nparms->net = rtnl_dereference(ci->parms)->net;
++              nparms->zone = parm->zone;
++
+               ret = 0;
+       }
++      err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
++      if (err < 0)
++              goto release_idr;
++
++      spin_lock_bh(&ci->tcf_lock);
++      goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
++      oparms = rcu_replace_pointer(ci->parms, nparms, lockdep_is_held(&ci->tcf_lock));
++      spin_unlock_bh(&ci->tcf_lock);
++
++      if (goto_ch)
++              tcf_chain_put_by_act(goto_ch);
++
++      if (oparms)
++              kfree_rcu(oparms, rcu);
++
+       return ret;
++
+ release_idr:
+       tcf_idr_release(*a, bind);
++out_free:
++      kfree(nparms);
+       return err;
+ }
+@@ -177,11 +192,14 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+               .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+               .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+       };
++      struct tcf_connmark_parms *parms;
+       struct tcf_t t;
+       spin_lock_bh(&ci->tcf_lock);
++      parms = rcu_dereference_protected(ci->parms, lockdep_is_held(&ci->tcf_lock));
++
+       opt.action = ci->tcf_action;
+-      opt.zone = ci->zone;
++      opt.zone = parms->zone;
+       if (nla_put(skb, TCA_CONNMARK_PARMS, sizeof(opt), &opt))
+               goto nla_put_failure;
+@@ -199,6 +217,16 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       return -1;
+ }
++static void tcf_connmark_cleanup(struct tc_action *a)
++{
++      struct tcf_connmark_info *ci = to_connmark(a);
++      struct tcf_connmark_parms *parms;
++
++      parms = rcu_dereference_protected(ci->parms, 1);
++      if (parms)
++              kfree_rcu(parms, rcu);
++}
++
+ static struct tc_action_ops act_connmark_ops = {
+       .kind           =       "connmark",
+       .id             =       TCA_ID_CONNMARK,
+@@ -206,6 +234,7 @@ static struct tc_action_ops act_connmark_ops = {
+       .act            =       tcf_connmark_act,
+       .dump           =       tcf_connmark_dump,
+       .init           =       tcf_connmark_init,
++      .cleanup        =       tcf_connmark_cleanup,
+       .size           =       sizeof(struct tcf_connmark_info),
+ };
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch b/queue-5.15/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
new file mode 100644 (file)
index 0000000..613f940
--- /dev/null
@@ -0,0 +1,70 @@
+From 44f0d2f6df8a78e345222122da2806111441acc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:36 +0530
+Subject: net: sched: act_ife: initialize struct tc_ife to fix KMSAN
+ kernel-infoleak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit ce50039be49eea9b4cd8873ca6eccded1b4a130a ]
+
+Fix a KMSAN kernel-infoleak detected  by the syzbot .
+
+[net?] KMSAN: kernel-infoleak in __skb_datagram_iter
+
+In tcf_ife_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+This change silences the KMSAN report and prevents potential information
+leaks from the kernel memory.
+
+This fix has been tested and validated by syzbot. This patch closes the
+bug reported at the following syzkaller link and ensures no infoleak.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: ef6980b6becb ("introduce IFE action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-3-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ife.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index ca53783ea0c4d..a8a5dbd7221b0 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -643,13 +643,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_ife_info *ife = to_ife(a);
+       struct tcf_ife_params *p;
+-      struct tc_ife opt = {
+-              .index = ife->tcf_index,
+-              .refcnt = refcount_read(&ife->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
+-      };
++      struct tc_ife opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index = ife->tcf_index,
++      opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref,
++      opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
++
+       spin_lock_bh(&ife->tcf_lock);
+       opt.action = ife->tcf_action;
+       p = rcu_dereference_protected(ife->params,
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-smc-fix-mismatch-between-clc-header-and-proposal.patch b/queue-5.15/net-smc-fix-mismatch-between-clc-header-and-proposal.patch
new file mode 100644 (file)
index 0000000..f9b4e3f
--- /dev/null
@@ -0,0 +1,55 @@
+From e7fd45ade724c0773bcf9a85ec67529dc27ddb4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 10:40:29 +0800
+Subject: net/smc: fix mismatch between CLC header and proposal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit ec33f2e5a2d0dbbfd71435209aee812fdc9369b8 ]
+
+The current CLC proposal message construction uses a mix of
+`ini->smc_type_v1/v2` and `pclc_base->hdr.typev1/v2` to decide whether
+to include optional extensions (IPv6 prefix extension for v1, and v2
+extension). This leads to a critical inconsistency: when
+`smc_clc_prfx_set()` fails - for example, in IPv6-only environments with
+only link-local addresses, or when the local IP address and the outgoing
+interface’s network address are not in the same subnet.
+
+As a result, the proposal message is assembled using the stale
+`ini->smc_type_v1` value—causing the IPv6 prefix extension to be
+included even though the header indicates v1 is not supported.
+The peer then receives a malformed CLC proposal where the header type
+does not match the payload, and immediately resets the connection.
+
+The fix ensures consistency between the CLC header flags and the actual
+payload by synchronizing `ini->smc_type_v1` with `pclc_base->hdr.typev1`
+when prefix setup fails.
+
+Fixes: 8c3dca341aea ("net/smc: build and send V2 CLC proposal")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20251107024029.88753-1-alibuda@linux.alibaba.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/smc_clc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
+index 52a0ba939c91c..ec8c4cfdb1471 100644
+--- a/net/smc/smc_clc.c
++++ b/net/smc/smc_clc.c
+@@ -529,6 +529,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
+                               return SMC_CLC_DECL_CNFERR;
+                       }
+                       pclc_base->hdr.typev1 = SMC_TYPE_N;
++                      ini->smc_type_v1 = SMC_TYPE_N;
+               } else {
+                       pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
+                       plen += sizeof(*pclc_prfx) +
+-- 
+2.51.0
+
diff --git a/queue-5.15/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch b/queue-5.15/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch
new file mode 100644 (file)
index 0000000..7673270
--- /dev/null
@@ -0,0 +1,100 @@
+From 8051440b049a5d1a6bf975a6e0dc4c032f21c6a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jul 2025 09:01:54 +0000
+Subject: net_sched: act_connmark: use RCU in tcf_connmark_dump()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0d752877705c0252ef2726e4c63c5573f048951c ]
+
+Also storing tcf_action into struct tcf_connmark_parms
+makes sure there is no discrepancy in tcf_connmark_act().
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250709090204.797558-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tc_act/tc_connmark.h |  1 +
+ net/sched/act_connmark.c         | 18 ++++++++++--------
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/tc_act/tc_connmark.h b/include/net/tc_act/tc_connmark.h
+index e8dd77a967480..a5ce83f3eea4b 100644
+--- a/include/net/tc_act/tc_connmark.h
++++ b/include/net/tc_act/tc_connmark.h
+@@ -7,6 +7,7 @@
+ struct tcf_connmark_parms {
+       struct net *net;
+       u16 zone;
++      int action;
+       struct rcu_head rcu;
+ };
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 418d60435b9d4..79cfe51a09e74 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -86,7 +86,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+       /* using overlimits stats to count how many packets marked */
+       tcf_action_inc_overlimit_qstats(&ca->common);
+ out:
+-      return READ_ONCE(ca->tcf_action);
++      return parms->action;
+ }
+ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
+@@ -162,6 +162,8 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+       if (err < 0)
+               goto release_idr;
++      nparms->action = parm->action;
++
+       spin_lock_bh(&ci->tcf_lock);
+       goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+       oparms = rcu_replace_pointer(ci->parms, nparms, lockdep_is_held(&ci->tcf_lock));
+@@ -185,20 +187,20 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+                                   int bind, int ref)
+ {
++      const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+-      struct tcf_connmark_info *ci = to_connmark(a);
++      const struct tcf_connmark_parms *parms;
+       struct tc_connmark opt = {
+               .index   = ci->tcf_index,
+               .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+               .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+       };
+-      struct tcf_connmark_parms *parms;
+       struct tcf_t t;
+-      spin_lock_bh(&ci->tcf_lock);
+-      parms = rcu_dereference_protected(ci->parms, lockdep_is_held(&ci->tcf_lock));
++      rcu_read_lock();
++      parms = rcu_dereference(ci->parms);
+-      opt.action = ci->tcf_action;
++      opt.action = parms->action;
+       opt.zone = parms->zone;
+       if (nla_put(skb, TCA_CONNMARK_PARMS, sizeof(opt), &opt))
+               goto nla_put_failure;
+@@ -207,12 +209,12 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       if (nla_put_64bit(skb, TCA_CONNMARK_TM, sizeof(t), &t,
+                         TCA_CONNMARK_PAD))
+               goto nla_put_failure;
+-      spin_unlock_bh(&ci->tcf_lock);
++      rcu_read_unlock();
+       return skb->len;
+ nla_put_failure:
+-      spin_unlock_bh(&ci->tcf_lock);
++      rcu_read_unlock();
+       nlmsg_trim(skb, b);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.15/net_sched-limit-try_bulk_dequeue_skb-batches.patch b/queue-5.15/net_sched-limit-try_bulk_dequeue_skb-batches.patch
new file mode 100644 (file)
index 0000000..5bceafe
--- /dev/null
@@ -0,0 +1,143 @@
+From 2a7f9da7ed60a55e9f5d9ff51977105569062c23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:12:15 +0000
+Subject: net_sched: limit try_bulk_dequeue_skb() batches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0345552a653ce5542affeb69ac5aa52177a5199b ]
+
+After commit 100dfa74cad9 ("inet: dev_queue_xmit() llist adoption")
+I started seeing many qdisc requeues on IDPF under high TX workload.
+
+$ tc -s qd sh dev eth1 handle 1: ; sleep 1; tc -s qd sh dev eth1 handle 1:
+qdisc mq 1: root
+ Sent 43534617319319 bytes 268186451819 pkt (dropped 0, overlimits 0 requeues 3532840114)
+ backlog 1056Kb 6675p requeues 3532840114
+qdisc mq 1: root
+ Sent 43554665866695 bytes 268309964788 pkt (dropped 0, overlimits 0 requeues 3537737653)
+ backlog 781164b 4822p requeues 3537737653
+
+This is caused by try_bulk_dequeue_skb() being only limited by BQL budget.
+
+perf record -C120-239 -e qdisc:qdisc_dequeue sleep 1 ; perf script
+...
+ netperf 75332 [146]  2711.138269: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1292 skbaddr=0xff378005a1e9f200
+ netperf 75332 [146]  2711.138953: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1213 skbaddr=0xff378004d607a500
+ netperf 75330 [144]  2711.139631: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1233 skbaddr=0xff3780046be20100
+ netperf 75333 [147]  2711.140356: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1093 skbaddr=0xff37800514845b00
+ netperf 75337 [151]  2711.141037: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1353 skbaddr=0xff37800460753300
+ netperf 75337 [151]  2711.141877: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1367 skbaddr=0xff378004e72c7b00
+ netperf 75330 [144]  2711.142643: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1202 skbaddr=0xff3780045bd60000
+...
+
+This is bad because :
+
+1) Large batches hold one victim cpu for a very long time.
+
+2) Driver often hit their own TX ring limit (all slots are used).
+
+3) We call dev_requeue_skb()
+
+4) Requeues are using a FIFO (q->gso_skb), breaking qdisc ability to
+   implement FQ or priority scheduling.
+
+5) dequeue_skb() gets packets from q->gso_skb one skb at a time
+   with no xmit_more support. This is causing many spinlock games
+   between the qdisc and the device driver.
+
+Requeues were supposed to be very rare, lets keep them this way.
+
+Limit batch sizes to /proc/sys/net/core/dev_weight (default 64) as
+__qdisc_run() was designed to use.
+
+Fixes: 5772e9a3463b ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/20251109161215.2574081-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_generic.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 02299785209c1..565970cca295b 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -178,9 +178,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
+ static void try_bulk_dequeue_skb(struct Qdisc *q,
+                                struct sk_buff *skb,
+                                const struct netdev_queue *txq,
+-                               int *packets)
++                               int *packets, int budget)
+ {
+       int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
++      int cnt = 0;
+       while (bytelimit > 0) {
+               struct sk_buff *nskb = q->dequeue(q);
+@@ -191,8 +192,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
+               bytelimit -= nskb->len; /* covers GSO len */
+               skb->next = nskb;
+               skb = nskb;
+-              (*packets)++; /* GSO counts as one pkt */
++              if (++cnt >= budget)
++                      break;
+       }
++      (*packets) += cnt;
+       skb_mark_not_on_list(skb);
+ }
+@@ -226,7 +229,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
+  * A requeued skb (via q->gso_skb) can also be a SKB list.
+  */
+ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+-                                 int *packets)
++                                 int *packets, int budget)
+ {
+       const struct netdev_queue *txq = q->dev_queue;
+       struct sk_buff *skb = NULL;
+@@ -293,7 +296,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+       if (skb) {
+ bulk:
+               if (qdisc_may_bulk(q))
+-                      try_bulk_dequeue_skb(q, skb, txq, packets);
++                      try_bulk_dequeue_skb(q, skb, txq, packets, budget);
+               else
+                       try_bulk_dequeue_skb_slow(q, skb, packets);
+       }
+@@ -385,7 +388,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+  *                            >0 - queue is not empty.
+  *
+  */
+-static inline bool qdisc_restart(struct Qdisc *q, int *packets)
++static inline bool qdisc_restart(struct Qdisc *q, int *packets, int budget)
+ {
+       spinlock_t *root_lock = NULL;
+       struct netdev_queue *txq;
+@@ -394,7 +397,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
+       bool validate;
+       /* Dequeue packet */
+-      skb = dequeue_skb(q, &validate, packets);
++      skb = dequeue_skb(q, &validate, packets, budget);
+       if (unlikely(!skb))
+               return false;
+@@ -412,7 +415,7 @@ void __qdisc_run(struct Qdisc *q)
+       int quota = READ_ONCE(dev_tx_weight);
+       int packets;
+-      while (qdisc_restart(q, &packets)) {
++      while (qdisc_restart(q, &packets, quota)) {
+               quota -= packets;
+               if (quota <= 0) {
+                       if (q->flags & TCQ_F_NOLOCK)
+-- 
+2.51.0
+
diff --git a/queue-5.15/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch b/queue-5.15/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
new file mode 100644 (file)
index 0000000..fd5d907
--- /dev/null
@@ -0,0 +1,86 @@
+From b2cf18523d1543175325cdc868dcf0b562efc83c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 11:10:54 +0000
+Subject: sctp: prevent possible shift-out-of-bounds in
+ sctp_transport_update_rto
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 1534ff77757e44bcc4b98d0196bc5c0052fce5fa ]
+
+syzbot reported a possible shift-out-of-bounds [1]
+
+Blamed commit added rto_alpha_max and rto_beta_max set to 1000.
+
+It is unclear if some sctp users are setting very large rto_alpha
+and/or rto_beta.
+
+In order to prevent user regression, perform the test at run time.
+
+Also add READ_ONCE() annotations as sysctl values can change under us.
+
+[1]
+
+UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41
+shift exponent 64 is too large for 32-bit type 'unsigned int'
+CPU: 0 UID: 0 PID: 16704 Comm: syz.2.2320 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:94 [inline]
+  dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120
+  ubsan_epilogue lib/ubsan.c:233 [inline]
+  __ubsan_handle_shift_out_of_bounds+0x27f/0x420 lib/ubsan.c:494
+  sctp_transport_update_rto.cold+0x1c/0x34b net/sctp/transport.c:509
+  sctp_check_transmitted+0x11c4/0x1c30 net/sctp/outqueue.c:1502
+  sctp_outq_sack+0x4ef/0x1b20 net/sctp/outqueue.c:1338
+  sctp_cmd_process_sack net/sctp/sm_sideeffect.c:840 [inline]
+  sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1372 [inline]
+
+Fixes: b58537a1f562 ("net: sctp: fix permissions for rto_alpha and rto_beta knobs")
+Reported-by: syzbot+f8c46c8b2b7f6e076e99@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c81ae.050a0220.3d0d33.014e.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20251106111054.3288127-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/transport.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 687e6a43d049d..d279dda07b1ba 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -501,6 +501,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+       if (tp->rttvar || tp->srtt) {
+               struct net *net = tp->asoc->base.net;
++              unsigned int rto_beta, rto_alpha;
+               /* 6.3.1 C3) When a new RTT measurement R' is made, set
+                * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+                * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+@@ -512,10 +513,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+                * For example, assuming the default value of RTO.Alpha of
+                * 1/8, rto_alpha would be expressed as 3.
+                */
+-              tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
+-                      + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
+-              tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
+-                      + (rtt >> net->sctp.rto_alpha);
++              rto_beta = READ_ONCE(net->sctp.rto_beta);
++              if (rto_beta < 32)
++                      tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta)
++                              + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> rto_beta);
++              rto_alpha = READ_ONCE(net->sctp.rto_alpha);
++              if (rto_alpha < 32)
++                      tp->srtt = tp->srtt - (tp->srtt >> rto_alpha)
++                              + (rtt >> rto_alpha);
+       } else {
+               /* 6.3.1 C2) When the first RTT measurement R is made, set
+                * SRTT <- R, RTTVAR <- R/2.
+-- 
+2.51.0
+
index f744700af6f523e4084764337dbea616c1c26ca5..cb445c495b1c6f86e417dd593824ffdb8798d77d 100644 (file)
@@ -235,3 +235,24 @@ nfs4-fix-state-renewals-missing-after-boot.patch
 hid-quirks-avoid-cooler-master-mm712-dongle-wakeup-b.patch
 nfs-check-if-suid-sgid-was-cleared-after-a-write-as-.patch
 asoc-max98090-91-fixed-max98091-alsa-widget-powering.patch
+net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
+bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
+bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
+bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
+bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
+sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
+net-smc-fix-mismatch-between-clc-header-and-proposal.patch
+tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
+net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
+wifi-mac80211-skip-rate-verification-for-not-capture.patch
+net-sched-act-move-global-static-variable-net_id-to-.patch
+net-sched-act_connmark-get-rid-of-tcf_connmark_walke.patch
+net-sched-act_connmark-transition-to-percpu-stats-an.patch
+net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch
+net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
+net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
+net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
+net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
+net_sched-limit-try_bulk_dequeue_skb-batches.patch
+hsr-fix-supervision-frame-sending-on-hsrv0.patch
+bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
diff --git a/queue-5.15/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch b/queue-5.15/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
new file mode 100644 (file)
index 0000000..e0c9409
--- /dev/null
@@ -0,0 +1,150 @@
+From b252125f5438fa7928e0f6f5b5bbcf5c0cf7690f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 06:40:25 +0000
+Subject: tipc: Fix use-after-free in tipc_mon_reinit_self().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 0725e6afb55128be21a2ca36e9674f573ccec173 ]
+
+syzbot reported use-after-free of tipc_net(net)->monitors[]
+in tipc_mon_reinit_self(). [0]
+
+The array is protected by RTNL, but tipc_mon_reinit_self()
+iterates over it without RTNL.
+
+tipc_mon_reinit_self() is called from tipc_net_finalize(),
+which is always under RTNL except for tipc_net_finalize_work().
+
+Let's hold RTNL in tipc_net_finalize_work().
+
+[0]:
+BUG: KASAN: slab-use-after-free in __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+Read of size 1 at addr ffff88805eae1030 by task kworker/0:7/5989
+
+CPU: 0 UID: 0 PID: 5989 Comm: kworker/0:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
+Workqueue: events tipc_net_finalize_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xca/0x240 mm/kasan/report.c:482
+ kasan_report+0x118/0x150 mm/kasan/report.c:595
+ __kasan_check_byte+0x2a/0x40 mm/kasan/common.c:568
+ kasan_check_byte include/linux/kasan.h:399 [inline]
+ lock_acquire+0x8d/0x360 kernel/locking/lockdep.c:5842
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+ rtlock_slowlock kernel/locking/rtmutex.c:1894 [inline]
+ rwbase_rtmutex_lock_state kernel/locking/spinlock_rt.c:160 [inline]
+ rwbase_write_lock+0xd3/0x7e0 kernel/locking/rwbase_rt.c:244
+ rt_write_lock+0x76/0x110 kernel/locking/spinlock_rt.c:243
+ write_lock_bh include/linux/rwlock_rt.h:99 [inline]
+ tipc_mon_reinit_self+0x79/0x430 net/tipc/monitor.c:718
+ tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
+ process_one_work kernel/workqueue.c:3236 [inline]
+ process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3319
+ worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
+ kthread+0x70e/0x8a0 kernel/kthread.c:463
+ ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+Allocated by task 6089:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __kmalloc_cache_noprof+0x1a8/0x320 mm/slub.c:4407
+ kmalloc_noprof include/linux/slab.h:905 [inline]
+ kzalloc_noprof include/linux/slab.h:1039 [inline]
+ tipc_mon_create+0xc3/0x4d0 net/tipc/monitor.c:657
+ tipc_enable_bearer net/tipc/bearer.c:357 [inline]
+ __tipc_nl_bearer_enable+0xe16/0x13f0 net/tipc/bearer.c:1047
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:371 [inline]
+ tipc_nl_compat_doit+0x3bc/0x5f0 net/tipc/netlink_compat.c:393
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:-1 [inline]
+ tipc_nl_compat_recv+0x83c/0xbe0 net/tipc/netlink_compat.c:1321
+ genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
+ netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
+ netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:729
+ ____sys_sendmsg+0x508/0x820 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 6088:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
+ poison_slab_object mm/kasan/common.c:243 [inline]
+ __kasan_slab_free+0x5b/0x80 mm/kasan/common.c:275
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2422 [inline]
+ slab_free mm/slub.c:4695 [inline]
+ kfree+0x195/0x550 mm/slub.c:4894
+ tipc_l2_device_event+0x380/0x650 net/tipc/bearer.c:-1
+ notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
+ call_netdevice_notifiers_extack net/core/dev.c:2267 [inline]
+ call_netdevice_notifiers net/core/dev.c:2281 [inline]
+ unregister_netdevice_many_notify+0x14d7/0x1fe0 net/core/dev.c:12166
+ unregister_netdevice_many net/core/dev.c:12229 [inline]
+ unregister_netdevice_queue+0x33c/0x380 net/core/dev.c:12073
+ unregister_netdevice include/linux/netdevice.h:3385 [inline]
+ __tun_detach+0xe4d/0x1620 drivers/net/tun.c:621
+ tun_detach drivers/net/tun.c:637 [inline]
+ tun_chr_close+0x10d/0x1c0 drivers/net/tun.c:3433
+ __fput+0x458/0xa80 fs/file_table.c:468
+ task_work_run+0x1d4/0x260 kernel/task_work.c:227
+ resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
+ exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:43
+ exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
+ syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline]
+ syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline]
+ do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 46cb01eeeb86 ("tipc: update mon's self addr when node addr generated")
+Reported-by: syzbot+d7dad7fd4b3921104957@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c323a.050a0220.baf87.007f.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251107064038.2361188-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/net.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/tipc/net.c b/net/tipc/net.c
+index 0e95572e56b41..7e65d0b0c4a8d 100644
+--- a/net/tipc/net.c
++++ b/net/tipc/net.c
+@@ -145,7 +145,9 @@ void tipc_net_finalize_work(struct work_struct *work)
+ {
+       struct tipc_net *tn = container_of(work, struct tipc_net, work);
++      rtnl_lock();
+       tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
++      rtnl_unlock();
+ }
+ void tipc_net_stop(struct net *net)
+-- 
+2.51.0
+
diff --git a/queue-5.15/wifi-mac80211-skip-rate-verification-for-not-capture.patch b/queue-5.15/wifi-mac80211-skip-rate-verification-for-not-capture.patch
new file mode 100644 (file)
index 0000000..eacc9a9
--- /dev/null
@@ -0,0 +1,48 @@
+From 78339150625c94d4fccbc43c57c1364f8c27a50f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 14:26:18 +0200
+Subject: wifi: mac80211: skip rate verification for not captured PSDUs
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 7fe0d21f5633af8c3fab9f0ef0706c6156623484 ]
+
+If for example the sniffer did not follow any AIDs in an MU frame, then
+some of the information may not be filled in or is even expected to be
+invalid. As an example, in that case it is expected that Nss is zero.
+
+Fixes: 2ff5e52e7836 ("radiotap: add 0-length PSDU "not captured" type")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251110142554.83a2858ee15b.I9f78ce7984872f474722f9278691ae16378f0a3e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 6c160ff2aab90..aa3442761ad05 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -4911,10 +4911,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+       if (WARN_ON(!local->started))
+               goto drop;
+-      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) {
++      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) &&
++                 !(status->flag & RX_FLAG_NO_PSDU &&
++                   status->zero_length_psdu_type ==
++                   IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) {
+               /*
+-               * Validate the rate, unless a PLCP error means that
+-               * we probably can't have a valid rate here anyway.
++               * Validate the rate, unless there was a PLCP error which may
++               * have an invalid rate or the PSDU was not capture and may be
++               * missing rate information.
+                */
+               switch (status->encoding) {
+-- 
+2.51.0
+
diff --git a/queue-5.4/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch b/queue-5.4/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
new file mode 100644 (file)
index 0000000..463d3f0
--- /dev/null
@@ -0,0 +1,149 @@
+From 123ac1bf171a1d313268157a97fdb0304dc7c8d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:49 +0200
+Subject: Bluetooth: 6lowpan: Don't hold spin lock over sleeping functions
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 98454bc812f3611551e4b1f81732da4aa7b9597e ]
+
+disconnect_all_peers() calls sleeping function (l2cap_chan_close) under
+spinlock.  Holding the lock doesn't actually do any good -- we work on a
+local copy of the list, and the lock doesn't protect against peer->chan
+having already been freed.
+
+Fix by taking refcounts of peer->chan instead.  Clean up the code and
+old comments a bit.
+
+Take devices_lock instead of RCU, because the kfree_rcu();
+l2cap_chan_put(); construct in chan_close_cb() does not guarantee
+peer->chan is necessarily valid in RCU.
+
+Also take l2cap_chan_lock() which is required for l2cap_chan_close().
+
+Log: (bluez 6lowpan-tester Client Connect - Disable)
+------
+BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
+...
+<TASK>
+...
+l2cap_send_disconn_req (net/bluetooth/l2cap_core.c:938 net/bluetooth/l2cap_core.c:1495)
+...
+? __pfx_l2cap_chan_close (net/bluetooth/l2cap_core.c:809)
+do_enable_set (net/bluetooth/6lowpan.c:1048 net/bluetooth/6lowpan.c:1068)
+------
+
+Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 68 ++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 2df218b454cc0..c7cdb5c1273a1 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -52,6 +52,11 @@ static bool enable_6lowpan;
+ static struct l2cap_chan *listen_chan;
+ static DEFINE_MUTEX(set_lock);
++enum {
++      LOWPAN_PEER_CLOSING,
++      LOWPAN_PEER_MAXBITS
++};
++
+ struct lowpan_peer {
+       struct list_head list;
+       struct rcu_head rcu;
+@@ -60,6 +65,8 @@ struct lowpan_peer {
+       /* peer addresses in various formats */
+       unsigned char lladdr[ETH_ALEN];
+       struct in6_addr peer_addr;
++
++      DECLARE_BITMAP(flags, LOWPAN_PEER_MAXBITS);
+ };
+ struct lowpan_btle_dev {
+@@ -1043,41 +1050,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ static void disconnect_all_peers(void)
+ {
+       struct lowpan_btle_dev *entry;
+-      struct lowpan_peer *peer, *tmp_peer, *new_peer;
+-      struct list_head peers;
+-
+-      INIT_LIST_HEAD(&peers);
++      struct lowpan_peer *peer;
++      int nchans;
+-      /* We make a separate list of peers as the close_cb() will
+-       * modify the device peers list so it is better not to mess
+-       * with the same list at the same time.
++      /* l2cap_chan_close() cannot be called from RCU, and lock ordering
++       * chan->lock > devices_lock prevents taking write side lock, so copy
++       * then close.
+        */
+       rcu_read_lock();
++      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list)
++              list_for_each_entry_rcu(peer, &entry->peers, list)
++                      clear_bit(LOWPAN_PEER_CLOSING, peer->flags);
++      rcu_read_unlock();
+-      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
+-              list_for_each_entry_rcu(peer, &entry->peers, list) {
+-                      new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
+-                      if (!new_peer)
+-                              break;
++      do {
++              struct l2cap_chan *chans[32];
++              int i;
+-                      new_peer->chan = peer->chan;
+-                      INIT_LIST_HEAD(&new_peer->list);
++              nchans = 0;
+-                      list_add(&new_peer->list, &peers);
+-              }
+-      }
++              spin_lock(&devices_lock);
+-      rcu_read_unlock();
++              list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
++                      list_for_each_entry_rcu(peer, &entry->peers, list) {
++                              if (test_and_set_bit(LOWPAN_PEER_CLOSING,
++                                                   peer->flags))
++                                      continue;
+-      spin_lock(&devices_lock);
+-      list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
+-              l2cap_chan_close(peer->chan, ENOENT);
++                              l2cap_chan_hold(peer->chan);
++                              chans[nchans++] = peer->chan;
+-              list_del_rcu(&peer->list);
+-              kfree_rcu(peer, rcu);
+-      }
+-      spin_unlock(&devices_lock);
++                              if (nchans >= ARRAY_SIZE(chans))
++                                      goto done;
++                      }
++              }
++
++done:
++              spin_unlock(&devices_lock);
++
++              for (i = 0; i < nchans; ++i) {
++                      l2cap_chan_lock(chans[i]);
++                      l2cap_chan_close(chans[i], ENOENT);
++                      l2cap_chan_unlock(chans[i]);
++                      l2cap_chan_put(chans[i]);
++              }
++      } while (nchans);
+ }
+ struct set_enable {
+-- 
+2.51.0
+
diff --git a/queue-5.4/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch b/queue-5.4/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
new file mode 100644 (file)
index 0000000..1d4b5e9
--- /dev/null
@@ -0,0 +1,103 @@
+From a9681ec2c4ef1bc2a2df2f639f566e0f13344983 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:47 +0200
+Subject: Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type
+ confusion
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit b454505bf57a2e4f5d49951d4deb03730a9348d9 ]
+
+Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types,
+e.g. debugfs "connect" command takes the former, and "disconnect" and
+"connect" to already connected device take the latter.  This is due to
+using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le
+which take different dst_type values.
+
+Fix address type passed to hci_conn_hash_lookup_le().
+
+Retain the debugfs API difference between "connect" and "disconnect"
+commands since it's been like this since 2015 and nobody apparently
+complained.
+
+Fixes: f5ad4ffceba0 ("Bluetooth: 6lowpan: Use hci_conn_hash_lookup_le() when possible")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index dd7fdfd155c6f..2df218b454cc0 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -986,10 +986,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void)
+ }
+ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+-                        struct l2cap_conn **conn)
++                        struct l2cap_conn **conn, bool disconnect)
+ {
+       struct hci_conn *hcon;
+       struct hci_dev *hdev;
++      int le_addr_type;
+       int n;
+       n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
+@@ -1000,13 +1001,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+       if (n < 7)
+               return -EINVAL;
++      if (disconnect) {
++              /* The "disconnect" debugfs command has used different address
++               * type constants than "connect" since 2015. Let's retain that
++               * for now even though it's obviously buggy...
++               */
++              *addr_type += 1;
++      }
++
++      switch (*addr_type) {
++      case BDADDR_LE_PUBLIC:
++              le_addr_type = ADDR_LE_DEV_PUBLIC;
++              break;
++      case BDADDR_LE_RANDOM:
++              le_addr_type = ADDR_LE_DEV_RANDOM;
++              break;
++      default:
++              return -EINVAL;
++      }
++
+       /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
+       hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
+       if (!hdev)
+               return -ENOENT;
+       hci_dev_lock(hdev);
+-      hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
++      hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+@@ -1133,7 +1153,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       buf[buf_size] = '\0';
+       if (memcmp(buf, "connect ", 8) == 0) {
+-              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false);
+               if (ret == -EINVAL)
+                       return ret;
+@@ -1170,7 +1190,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       }
+       if (memcmp(buf, "disconnect ", 11) == 0) {
+-              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true);
+               if (ret < 0)
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-5.4/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch b/queue-5.4/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
new file mode 100644 (file)
index 0000000..90c47a8
--- /dev/null
@@ -0,0 +1,54 @@
+From 14eb67292df9e45369c9a929f91d30b59f5f074e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:46 +0200
+Subject: Bluetooth: 6lowpan: reset link-local header on ipv6 recv path
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3b78f50918276ab28fb22eac9aa49401ac436a3b ]
+
+Bluetooth 6lowpan.c netdev has header_ops, so it must set link-local
+header for RX skb, otherwise things crash, eg. with AF_PACKET SOCK_RAW
+
+Add missing skb_reset_mac_header() for uncompressed ipv6 RX path.
+
+For the compressed one, it is done in lowpan_header_decompress().
+
+Log: (BlueZ 6lowpan-tester Client Recv Raw - Success)
+------
+kernel BUG at net/core/skbuff.c:212!
+Call Trace:
+<IRQ>
+...
+packet_rcv (net/packet/af_packet.c:2152)
+...
+<TASK>
+__local_bh_enable_ip (kernel/softirq.c:407)
+netif_rx (net/core/dev.c:5648)
+chan_recv_cb (net/bluetooth/6lowpan.c:294 net/bluetooth/6lowpan.c:359)
+------
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 12052b7664414..dd7fdfd155c6f 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -317,6 +317,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
+               local_skb->pkt_type = PACKET_HOST;
+               local_skb->dev = dev;
++              skb_reset_mac_header(local_skb);
+               skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
+               if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) {
+-- 
+2.51.0
+
diff --git a/queue-5.4/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch b/queue-5.4/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
new file mode 100644 (file)
index 0000000..c2e3fc1
--- /dev/null
@@ -0,0 +1,65 @@
+From 6dbece2e8daa8d56113eb071a32f00a7e43db5e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:28:41 -0500
+Subject: Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
+
+From: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+
+[ Upstream commit 23d22f2f71768034d6ef86168213843fc49bf550 ]
+
+There is a KASAN: slab-use-after-free read in btusb_disconnect().
+Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will
+free the btusb data associated with the interface. The same data is
+then used later in the function, hence the UAF.
+
+Fix by moving the accesses to btusb data to before the data is free'd.
+
+Reported-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2fc81b50a4f8263a159b
+Tested-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Fixes: fd913ef7ce619 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 9f71f9135f9e3..3d79637a56cc4 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4004,6 +4004,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+       hci_unregister_dev(hdev);
++      if (data->oob_wake_irq)
++              device_init_wakeup(&data->udev->dev, false);
++      if (data->reset_gpio)
++              gpiod_put(data->reset_gpio);
++
+       if (intf == data->intf) {
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
+@@ -4014,17 +4019,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+                       usb_driver_release_interface(&btusb_driver, data->diag);
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       } else if (intf == data->diag) {
+-              usb_driver_release_interface(&btusb_driver, data->intf);
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
++              usb_driver_release_interface(&btusb_driver, data->intf);
+       }
+-      if (data->oob_wake_irq)
+-              device_init_wakeup(&data->udev->dev, false);
+-
+-      if (data->reset_gpio)
+-              gpiod_put(data->reset_gpio);
+-
+       hci_free_dev(hdev);
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.4/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch b/queue-5.4/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
new file mode 100644 (file)
index 0000000..f1412b5
--- /dev/null
@@ -0,0 +1,37 @@
+From 0bc9c8154c3f8735a24cad27c85dc58a3cb54b97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:48 +0200
+Subject: Bluetooth: L2CAP: export l2cap_chan_hold for modules
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit e060088db0bdf7932e0e3c2d24b7371c4c5b867c ]
+
+l2cap_chan_put() is exported, so export also l2cap_chan_hold() for
+modules.
+
+l2cap_chan_hold() has use case in net/bluetooth/6lowpan.c
+
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 1272ad73e4011..4c82770173aad 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -517,6 +517,7 @@ void l2cap_chan_hold(struct l2cap_chan *c)
+       kref_get(&c->kref);
+ }
++EXPORT_SYMBOL_GPL(l2cap_chan_hold);
+ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
+ {
+-- 
+2.51.0
+
diff --git a/queue-5.4/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch b/queue-5.4/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
new file mode 100644 (file)
index 0000000..54572fb
--- /dev/null
@@ -0,0 +1,39 @@
+From 9d16070048bc32aa640da6e4d7628899ed267674 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:14:21 +0800
+Subject: net: fec: correct rx_bytes statistic for the case SHIFT16 is set
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit ad17e7e92a7c52ce70bb764813fcf99464f96903 ]
+
+Two additional bytes in front of each frame received into the RX FIFO if
+SHIFT16 is set, so we need to subtract the extra two bytes from pkt_len
+to correct the statistic of rx_bytes.
+
+Fixes: 3ac72b7b63d5 ("net: fec: align IP header in hardware")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20251106021421.2096585-1-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 7b2ab0cc562cc..cd2fd2926f2f5 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1530,6 +1530,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               ndev->stats.rx_packets++;
+               pkt_len = fec16_to_cpu(bdp->cbd_datlen);
+               ndev->stats.rx_bytes += pkt_len;
++              if (fep->quirks & FEC_QUIRK_HAS_RACC)
++                      ndev->stats.rx_bytes -= 2;
+               index = fec_enet_get_bd_index(bdp, &rxq->bd);
+               skb = rxq->rx_skbuff[index];
+-- 
+2.51.0
+
diff --git a/queue-5.4/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch b/queue-5.4/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
new file mode 100644 (file)
index 0000000..d284c76
--- /dev/null
@@ -0,0 +1,45 @@
+From d8e028d20c7b5b60d9573d849e6f787497d1b79b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 07:49:22 +0100
+Subject: net: mdio: fix resource leak in mdiobus_register_device()
+
+From: Buday Csaba <buday.csaba@prolan.hu>
+
+[ Upstream commit e6ca8f533ed41129fcf052297718f417f021cc7d ]
+
+Fix a possible leak in mdiobus_register_device() when both a
+reset-gpio and a reset-controller are present.
+Clean up the already claimed reset-gpio, when the registration of
+the reset-controller fails, so when an error code is returned, the
+device retains its state before the registration attempt.
+
+Link: https://lore.kernel.org/all/20251106144603.39053c81@kernel.org/
+Fixes: 71dd6c0dff51 ("net: phy: add support for reset-controller")
+Signed-off-by: Buday Csaba <buday.csaba@prolan.hu>
+Link: https://patch.msgid.link/4b419377f8dd7d2f63f919d0f74a336c734f8fff.1762584481.git.buday.csaba@prolan.hu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mdio_bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index 931b9a6c5dc50..bdce184759eff 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -89,8 +89,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
+                       return err;
+               err = mdiobus_register_reset(mdiodev);
+-              if (err)
++              if (err) {
++                      gpiod_put(mdiodev->reset_gpio);
++                      mdiodev->reset_gpio = NULL;
+                       return err;
++              }
+               /* Assert the reset signal */
+               mdio_device_reset(mdiodev, 1);
+-- 
+2.51.0
+
diff --git a/queue-5.4/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch b/queue-5.4/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
new file mode 100644 (file)
index 0000000..ee30b0a
--- /dev/null
@@ -0,0 +1,58 @@
+From 2c8033e91ab6c8bcd359dc96a7154feb48d01b06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:51 +0200
+Subject: net/mlx5e: Fix maxrate wraparound in threshold between units
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit a7bf4d5063c7837096aab2853224eb23628514d9 ]
+
+The previous calculation used roundup() which caused an overflow for
+rates between 25.5Gbps and 26Gbps.
+For example, a rate of 25.6Gbps would result in using 100Mbps units with
+value of 256, which would overflow the 8 bits field.
+
+Simplify the upper_limit_mbps calculation by removing the
+unnecessary roundup, and adjust the comparison to use <= to correctly
+handle the boundary condition.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index f1952e14c8042..3379f99a44dd6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -579,18 +579,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       struct mlx5_core_dev *mdev = priv->mdev;
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+-      __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
++      __u64 upper_limit_mbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
++      upper_limit_mbps = 255 * MLX5E_100MB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+                       max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
+                       continue;
+               }
+-              if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
++              if (maxrate->tc_maxrate[i] <= upper_limit_mbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+-- 
+2.51.0
+
diff --git a/queue-5.4/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch b/queue-5.4/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
new file mode 100644 (file)
index 0000000..6a72646
--- /dev/null
@@ -0,0 +1,62 @@
+From 50c49830eced9030389c76f65361c8c82fa611c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:52 +0200
+Subject: net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 43b27d1bd88a4bce34ec2437d103acfae9655f9e ]
+
+Add validation to reject rates exceeding 255 Gbps that would overflow
+the 8 bits max bandwidth field.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 3379f99a44dd6..4acab31f53ac0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -580,11 +580,13 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+       __u64 upper_limit_mbps;
++      __u64 upper_limit_gbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+       upper_limit_mbps = 255 * MLX5E_100MB;
++      upper_limit_gbps = 255 * MLX5E_1GB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+@@ -596,10 +598,16 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else {
++              } else if (max_bw_value[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
++              } else {
++                      netdev_err(netdev,
++                                 "tc_%d maxrate %llu Kbps exceeds limit %llu\n",
++                                 i, maxrate->tc_maxrate[i],
++                                 upper_limit_gbps);
++                      return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.4/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch b/queue-5.4/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
new file mode 100644 (file)
index 0000000..d31db59
--- /dev/null
@@ -0,0 +1,70 @@
+From 71eeb246134ac7efcfd665f7bb04cd949ff34fdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:36 +0530
+Subject: net: sched: act_ife: initialize struct tc_ife to fix KMSAN
+ kernel-infoleak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit ce50039be49eea9b4cd8873ca6eccded1b4a130a ]
+
+Fix a KMSAN kernel-infoleak detected  by the syzbot .
+
+[net?] KMSAN: kernel-infoleak in __skb_datagram_iter
+
+In tcf_ife_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+This change silences the KMSAN report and prevents potential information
+leaks from the kernel memory.
+
+This fix has been tested and validated by syzbot. This patch closes the
+bug reported at the following syzkaller link and ensures no infoleak.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: ef6980b6becb ("introduce IFE action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-3-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ife.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index 488d10476e850..8f82842ad8cb5 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -642,13 +642,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_ife_info *ife = to_ife(a);
+       struct tcf_ife_params *p;
+-      struct tc_ife opt = {
+-              .index = ife->tcf_index,
+-              .refcnt = refcount_read(&ife->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
+-      };
++      struct tc_ife opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index = ife->tcf_index,
++      opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref,
++      opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
++
+       spin_lock_bh(&ife->tcf_lock);
+       opt.action = ife->tcf_action;
+       p = rcu_dereference_protected(ife->params,
+-- 
+2.51.0
+
diff --git a/queue-5.4/net_sched-limit-try_bulk_dequeue_skb-batches.patch b/queue-5.4/net_sched-limit-try_bulk_dequeue_skb-batches.patch
new file mode 100644 (file)
index 0000000..6374a3e
--- /dev/null
@@ -0,0 +1,143 @@
+From e3e36dbb4d98e19b99af39119c92c4bb6ae3d215 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:12:15 +0000
+Subject: net_sched: limit try_bulk_dequeue_skb() batches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0345552a653ce5542affeb69ac5aa52177a5199b ]
+
+After commit 100dfa74cad9 ("inet: dev_queue_xmit() llist adoption")
+I started seeing many qdisc requeues on IDPF under high TX workload.
+
+$ tc -s qd sh dev eth1 handle 1: ; sleep 1; tc -s qd sh dev eth1 handle 1:
+qdisc mq 1: root
+ Sent 43534617319319 bytes 268186451819 pkt (dropped 0, overlimits 0 requeues 3532840114)
+ backlog 1056Kb 6675p requeues 3532840114
+qdisc mq 1: root
+ Sent 43554665866695 bytes 268309964788 pkt (dropped 0, overlimits 0 requeues 3537737653)
+ backlog 781164b 4822p requeues 3537737653
+
+This is caused by try_bulk_dequeue_skb() being only limited by BQL budget.
+
+perf record -C120-239 -e qdisc:qdisc_dequeue sleep 1 ; perf script
+...
+ netperf 75332 [146]  2711.138269: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1292 skbaddr=0xff378005a1e9f200
+ netperf 75332 [146]  2711.138953: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1213 skbaddr=0xff378004d607a500
+ netperf 75330 [144]  2711.139631: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1233 skbaddr=0xff3780046be20100
+ netperf 75333 [147]  2711.140356: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1093 skbaddr=0xff37800514845b00
+ netperf 75337 [151]  2711.141037: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1353 skbaddr=0xff37800460753300
+ netperf 75337 [151]  2711.141877: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1367 skbaddr=0xff378004e72c7b00
+ netperf 75330 [144]  2711.142643: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1202 skbaddr=0xff3780045bd60000
+...
+
+This is bad because :
+
+1) Large batches hold one victim cpu for a very long time.
+
+2) Driver often hit their own TX ring limit (all slots are used).
+
+3) We call dev_requeue_skb()
+
+4) Requeues are using a FIFO (q->gso_skb), breaking qdisc ability to
+   implement FQ or priority scheduling.
+
+5) dequeue_skb() gets packets from q->gso_skb one skb at a time
+   with no xmit_more support. This is causing many spinlock games
+   between the qdisc and the device driver.
+
+Requeues were supposed to be very rare, lets keep them this way.
+
+Limit batch sizes to /proc/sys/net/core/dev_weight (default 64) as
+__qdisc_run() was designed to use.
+
+Fixes: 5772e9a3463b ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/20251109161215.2574081-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_generic.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 19fe5078a8d13..d52001d958cbc 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -172,9 +172,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
+ static void try_bulk_dequeue_skb(struct Qdisc *q,
+                                struct sk_buff *skb,
+                                const struct netdev_queue *txq,
+-                               int *packets)
++                               int *packets, int budget)
+ {
+       int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
++      int cnt = 0;
+       while (bytelimit > 0) {
+               struct sk_buff *nskb = q->dequeue(q);
+@@ -185,8 +186,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
+               bytelimit -= nskb->len; /* covers GSO len */
+               skb->next = nskb;
+               skb = nskb;
+-              (*packets)++; /* GSO counts as one pkt */
++              if (++cnt >= budget)
++                      break;
+       }
++      (*packets) += cnt;
+       skb_mark_not_on_list(skb);
+ }
+@@ -220,7 +223,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
+  * A requeued skb (via q->gso_skb) can also be a SKB list.
+  */
+ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+-                                 int *packets)
++                                 int *packets, int budget)
+ {
+       const struct netdev_queue *txq = q->dev_queue;
+       struct sk_buff *skb = NULL;
+@@ -287,7 +290,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+       if (skb) {
+ bulk:
+               if (qdisc_may_bulk(q))
+-                      try_bulk_dequeue_skb(q, skb, txq, packets);
++                      try_bulk_dequeue_skb(q, skb, txq, packets, budget);
+               else
+                       try_bulk_dequeue_skb_slow(q, skb, packets);
+       }
+@@ -379,7 +382,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+  *                            >0 - queue is not empty.
+  *
+  */
+-static inline bool qdisc_restart(struct Qdisc *q, int *packets)
++static inline bool qdisc_restart(struct Qdisc *q, int *packets, int budget)
+ {
+       spinlock_t *root_lock = NULL;
+       struct netdev_queue *txq;
+@@ -388,7 +391,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
+       bool validate;
+       /* Dequeue packet */
+-      skb = dequeue_skb(q, &validate, packets);
++      skb = dequeue_skb(q, &validate, packets, budget);
+       if (unlikely(!skb))
+               return false;
+@@ -406,7 +409,7 @@ void __qdisc_run(struct Qdisc *q)
+       int quota = READ_ONCE(dev_tx_weight);
+       int packets;
+-      while (qdisc_restart(q, &packets)) {
++      while (qdisc_restart(q, &packets, quota)) {
+               quota -= packets;
+               if (quota <= 0) {
+                       __netif_schedule(q);
+-- 
+2.51.0
+
diff --git a/queue-5.4/net_sched-remove-need_resched-from-qdisc_run.patch b/queue-5.4/net_sched-remove-need_resched-from-qdisc_run.patch
new file mode 100644 (file)
index 0000000..7dcafe6
--- /dev/null
@@ -0,0 +1,89 @@
+From 44244e775326539ee463420056f3a5e6c0b84e3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2019 14:02:36 -0700
+Subject: net_sched: remove need_resched() from qdisc_run()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b60fa1c5d01a10e358c509b904d4bead6114d593 ]
+
+The introduction of this schedule point was done in commit
+2ba2506ca7ca ("[NET]: Add preemption point in qdisc_run")
+at a time the loop was not bounded.
+
+Then later in commit d5b8aa1d246f ("net_sched: fix dequeuer fairness")
+we added a limit on the number of packets.
+
+Now is the time to remove the schedule point, since the default
+limit of 64 packets matches the number of packets a typical NAPI
+poll can process in a row.
+
+This solves a latency problem for most TCP receivers under moderate load :
+
+1) host receives a packet.
+   NET_RX_SOFTIRQ is raised by NIC hard IRQ handler
+
+2) __do_softirq() does its first loop, handling NET_RX_SOFTIRQ
+   and calling the driver napi->loop() function
+
+3) TCP stores the skb in socket receive queue:
+
+4) TCP calls sk->sk_data_ready() and wakeups a user thread
+   waiting for EPOLLIN (as a result, need_resched() might now be true)
+
+5) TCP cooks an ACK and sends it.
+
+6) qdisc_run() processes one packet from qdisc, and sees need_resched(),
+   this raises NET_TX_SOFTIRQ (even if there are no more packets in
+   the qdisc)
+
+Then we go back to the __do_softirq() in 2), and we see that new
+softirqs were raised. Since need_resched() is true, we end up waking
+ksoftirqd in this path :
+
+    if (pending) {
+            if (time_before(jiffies, end) && !need_resched() &&
+                --max_restart)
+                    goto restart;
+
+            wakeup_softirqd();
+    }
+
+So we have many wakeups of ksoftirqd kernel threads,
+and more calls to qdisc_run() with associated lock overhead.
+
+Note that another way to solve the issue would be to change TCP
+to first send the ACK packet, then signal the EPOLLIN,
+but this changes P99 latencies, as sending the ACK packet
+can add a long delay.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 0345552a653c ("net_sched: limit try_bulk_dequeue_skb() batches")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_generic.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 4250f3cf30e72..19fe5078a8d13 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -407,13 +407,8 @@ void __qdisc_run(struct Qdisc *q)
+       int packets;
+       while (qdisc_restart(q, &packets)) {
+-              /*
+-               * Ordered by possible occurrence: Postpone processing if
+-               * 1. we've exceeded packet quota
+-               * 2. another process needs the CPU;
+-               */
+               quota -= packets;
+-              if (quota <= 0 || need_resched()) {
++              if (quota <= 0) {
+                       __netif_schedule(q);
+                       break;
+               }
+-- 
+2.51.0
+
diff --git a/queue-5.4/sctp-get-netns-from-asoc-and-ep-base.patch b/queue-5.4/sctp-get-netns-from-asoc-and-ep-base.patch
new file mode 100644 (file)
index 0000000..c8a112d
--- /dev/null
@@ -0,0 +1,517 @@
+From f24b2806f5a2d262a34ab0dec482b5398a46b7d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Dec 2019 13:45:18 +0800
+Subject: sctp: get netns from asoc and ep base
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 4e7696d90b51a1a73ce0e8174f3aff58b914619c ]
+
+Commit 312434617cb1 ("sctp: cache netns in sctp_ep_common") set netns
+in asoc and ep base since they're created, and it will never change.
+It's a better way to get netns from asoc and ep base, comparing to
+calling sock_net().
+
+This patch is to replace them.
+
+v1->v2:
+  - no change.
+
+Suggested-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 1534ff77757e ("sctp: prevent possible shift-out-of-bounds in sctp_transport_update_rto")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/associola.c         | 10 +++++-----
+ net/sctp/chunk.c             |  2 +-
+ net/sctp/endpointola.c       |  6 +++---
+ net/sctp/input.c             |  5 ++---
+ net/sctp/output.c            |  2 +-
+ net/sctp/outqueue.c          |  6 +++---
+ net/sctp/sm_make_chunk.c     |  7 +++----
+ net/sctp/sm_sideeffect.c     | 16 ++++++----------
+ net/sctp/sm_statefuns.c      |  2 +-
+ net/sctp/socket.c            | 12 +++++-------
+ net/sctp/stream.c            |  3 +--
+ net/sctp/stream_interleave.c | 23 ++++++++++-------------
+ net/sctp/transport.c         |  2 +-
+ net/sctp/ulpqueue.c          | 15 +++++++--------
+ 14 files changed, 49 insertions(+), 62 deletions(-)
+
+diff --git a/net/sctp/associola.c b/net/sctp/associola.c
+index bc9a62744feca..253ab788cffca 100644
+--- a/net/sctp/associola.c
++++ b/net/sctp/associola.c
+@@ -579,7 +579,6 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
+                                          const gfp_t gfp,
+                                          const int peer_state)
+ {
+-      struct net *net = sock_net(asoc->base.sk);
+       struct sctp_transport *peer;
+       struct sctp_sock *sp;
+       unsigned short port;
+@@ -609,7 +608,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
+               return peer;
+       }
+-      peer = sctp_transport_new(net, addr, gfp);
++      peer = sctp_transport_new(asoc->base.net, addr, gfp);
+       if (!peer)
+               return NULL;
+@@ -978,7 +977,7 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
+       struct sctp_association *asoc =
+               container_of(work, struct sctp_association,
+                            base.inqueue.immediate);
+-      struct net *net = sock_net(asoc->base.sk);
++      struct net *net = asoc->base.net;
+       union sctp_subtype subtype;
+       struct sctp_endpoint *ep;
+       struct sctp_chunk *chunk;
+@@ -1445,7 +1444,8 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
+ /* Should we send a SACK to update our peer? */
+ static inline bool sctp_peer_needs_update(struct sctp_association *asoc)
+ {
+-      struct net *net = sock_net(asoc->base.sk);
++      struct net *net = asoc->base.net;
++
+       switch (asoc->state) {
+       case SCTP_STATE_ESTABLISHED:
+       case SCTP_STATE_SHUTDOWN_PENDING:
+@@ -1582,7 +1582,7 @@ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
+       if (asoc->peer.ipv6_address)
+               flags |= SCTP_ADDR6_PEERSUPP;
+-      return sctp_bind_addr_copy(sock_net(asoc->base.sk),
++      return sctp_bind_addr_copy(asoc->base.net,
+                                  &asoc->base.bind_addr,
+                                  &asoc->ep->base.bind_addr,
+                                  scope, gfp, flags);
+diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
+index cc0405c79dfc0..064675bc7b54c 100644
+--- a/net/sctp/chunk.c
++++ b/net/sctp/chunk.c
+@@ -227,7 +227,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
+       if (msg_len >= first_len) {
+               msg->can_delay = 0;
+               if (msg_len > first_len)
+-                      SCTP_INC_STATS(sock_net(asoc->base.sk),
++                      SCTP_INC_STATS(asoc->base.net,
+                                      SCTP_MIB_FRAGUSRMSGS);
+       } else {
+               /* Which may be the only one... */
+diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
+index 665a22d5c725b..208b121d5a783 100644
+--- a/net/sctp/endpointola.c
++++ b/net/sctp/endpointola.c
+@@ -251,7 +251,7 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep,
+       struct sctp_endpoint *retval = NULL;
+       if ((htons(ep->base.bind_addr.port) == laddr->v4.sin_port) &&
+-          net_eq(sock_net(ep->base.sk), net)) {
++          net_eq(ep->base.net, net)) {
+               if (sctp_bind_addr_match(&ep->base.bind_addr, laddr,
+                                        sctp_sk(ep->base.sk)))
+                       retval = ep;
+@@ -299,8 +299,8 @@ bool sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
+                                const union sctp_addr *paddr)
+ {
+       struct sctp_sockaddr_entry *addr;
++      struct net *net = ep->base.net;
+       struct sctp_bind_addr *bp;
+-      struct net *net = sock_net(ep->base.sk);
+       bp = &ep->base.bind_addr;
+       /* This function is called with the socket lock held,
+@@ -391,7 +391,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
+               if (asoc && sctp_chunk_is_data(chunk))
+                       asoc->peer.last_data_from = chunk->transport;
+               else {
+-                      SCTP_INC_STATS(sock_net(ep->base.sk), SCTP_MIB_INCTRLCHUNKS);
++                      SCTP_INC_STATS(ep->base.net, SCTP_MIB_INCTRLCHUNKS);
+                       if (asoc)
+                               asoc->stats.ictrlchunks++;
+               }
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 9013257cf3df3..28e0e110804ad 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -935,7 +935,7 @@ int sctp_hash_transport(struct sctp_transport *t)
+       if (t->asoc->temp)
+               return 0;
+-      arg.net   = sock_net(t->asoc->base.sk);
++      arg.net   = t->asoc->base.net;
+       arg.paddr = &t->ipaddr;
+       arg.lport = htons(t->asoc->base.bind_addr.port);
+@@ -1002,12 +1002,11 @@ struct sctp_transport *sctp_epaddr_lookup_transport(
+                               const struct sctp_endpoint *ep,
+                               const union sctp_addr *paddr)
+ {
+-      struct net *net = sock_net(ep->base.sk);
+       struct rhlist_head *tmp, *list;
+       struct sctp_transport *t;
+       struct sctp_hash_cmp_arg arg = {
+               .paddr = paddr,
+-              .net   = net,
++              .net   = ep->base.net,
+               .lport = htons(ep->base.bind_addr.port),
+       };
+diff --git a/net/sctp/output.c b/net/sctp/output.c
+index dbda7e7927fd9..1441eaf460bb3 100644
+--- a/net/sctp/output.c
++++ b/net/sctp/output.c
+@@ -282,7 +282,7 @@ static enum sctp_xmit sctp_packet_bundle_sack(struct sctp_packet *pkt,
+                                       sctp_chunk_free(sack);
+                                       goto out;
+                               }
+-                              SCTP_INC_STATS(sock_net(asoc->base.sk),
++                              SCTP_INC_STATS(asoc->base.net,
+                                              SCTP_MIB_OUTCTRLCHUNKS);
+                               asoc->stats.octrlchunks++;
+                               asoc->peer.sack_needed = 0;
+diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
+index adceb226ffab3..6b0b3bad4daa6 100644
+--- a/net/sctp/outqueue.c
++++ b/net/sctp/outqueue.c
+@@ -280,7 +280,7 @@ void sctp_outq_free(struct sctp_outq *q)
+ /* Put a new chunk in an sctp_outq.  */
+ void sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk, gfp_t gfp)
+ {
+-      struct net *net = sock_net(q->asoc->base.sk);
++      struct net *net = q->asoc->base.net;
+       pr_debug("%s: outq:%p, chunk:%p[%s]\n", __func__, q, chunk,
+                chunk && chunk->chunk_hdr ?
+@@ -534,7 +534,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
+ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
+                    enum sctp_retransmit_reason reason)
+ {
+-      struct net *net = sock_net(q->asoc->base.sk);
++      struct net *net = q->asoc->base.net;
+       switch (reason) {
+       case SCTP_RTXR_T3_RTX:
+@@ -1890,6 +1890,6 @@ void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
+       if (ftsn_chunk) {
+               list_add_tail(&ftsn_chunk->list, &q->control_chunk_list);
+-              SCTP_INC_STATS(sock_net(asoc->base.sk), SCTP_MIB_OUTCTRLCHUNKS);
++              SCTP_INC_STATS(asoc->base.net, SCTP_MIB_OUTCTRLCHUNKS);
+       }
+ }
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
+index 0c112134d9e32..d3cc5a59b0fec 100644
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -2319,7 +2319,6 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
+                     const union sctp_addr *peer_addr,
+                     struct sctp_init_chunk *peer_init, gfp_t gfp)
+ {
+-      struct net *net = sock_net(asoc->base.sk);
+       struct sctp_transport *transport;
+       struct list_head *pos, *temp;
+       union sctp_params param;
+@@ -2377,8 +2376,8 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
+        * also give us an option to silently ignore the packet, which
+        * is what we'll do here.
+        */
+-      if (!net->sctp.addip_noauth &&
+-           (asoc->peer.asconf_capable && !asoc->peer.auth_capable)) {
++      if (!asoc->base.net->sctp.addip_noauth &&
++          (asoc->peer.asconf_capable && !asoc->peer.auth_capable)) {
+               asoc->peer.addip_disabled_mask |= (SCTP_PARAM_ADD_IP |
+                                                 SCTP_PARAM_DEL_IP |
+                                                 SCTP_PARAM_SET_PRIMARY);
+@@ -2505,9 +2504,9 @@ static int sctp_process_param(struct sctp_association *asoc,
+                             const union sctp_addr *peer_addr,
+                             gfp_t gfp)
+ {
+-      struct net *net = sock_net(asoc->base.sk);
+       struct sctp_endpoint *ep = asoc->ep;
+       union sctp_addr_param *addr_param;
++      struct net *net = asoc->base.net;
+       struct sctp_transport *t;
+       enum sctp_scope scope;
+       union sctp_addr addr;
+diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
+index c964e7ca6f7e5..3ecd246feb76a 100644
+--- a/net/sctp/sm_sideeffect.c
++++ b/net/sctp/sm_sideeffect.c
+@@ -520,8 +520,6 @@ static void sctp_do_8_2_transport_strike(struct sctp_cmd_seq *commands,
+                                        struct sctp_transport *transport,
+                                        int is_hb)
+ {
+-      struct net *net = sock_net(asoc->base.sk);
+-
+       /* The check for association's overall error counter exceeding the
+        * threshold is done in the state function.
+        */
+@@ -548,10 +546,10 @@ static void sctp_do_8_2_transport_strike(struct sctp_cmd_seq *commands,
+        * is SCTP_ACTIVE, then mark this transport as Partially Failed,
+        * see SCTP Quick Failover Draft, section 5.1
+        */
+-      if (net->sctp.pf_enable &&
+-         (transport->state == SCTP_ACTIVE) &&
+-         (transport->error_count < transport->pathmaxrxt) &&
+-         (transport->error_count > transport->pf_retrans)) {
++      if (asoc->base.net->sctp.pf_enable &&
++          transport->state == SCTP_ACTIVE &&
++          transport->error_count < transport->pathmaxrxt &&
++          transport->error_count > transport->pf_retrans) {
+               sctp_assoc_control_transport(asoc, transport,
+                                            SCTP_TRANSPORT_PF,
+@@ -797,10 +795,8 @@ static int sctp_cmd_process_sack(struct sctp_cmd_seq *cmds,
+       int err = 0;
+       if (sctp_outq_sack(&asoc->outqueue, chunk)) {
+-              struct net *net = sock_net(asoc->base.sk);
+-
+               /* There are no more TSNs awaiting SACK.  */
+-              err = sctp_do_sm(net, SCTP_EVENT_T_OTHER,
++              err = sctp_do_sm(asoc->base.net, SCTP_EVENT_T_OTHER,
+                                SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN),
+                                asoc->state, asoc->ep, asoc, NULL,
+                                GFP_ATOMIC);
+@@ -833,7 +829,7 @@ static void sctp_cmd_assoc_update(struct sctp_cmd_seq *cmds,
+                                 struct sctp_association *asoc,
+                                 struct sctp_association *new)
+ {
+-      struct net *net = sock_net(asoc->base.sk);
++      struct net *net = asoc->base.net;
+       struct sctp_chunk *abort;
+       if (!sctp_assoc_update(asoc, new))
+diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
+index 876c18f70df89..7808dd812a72a 100644
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -1342,7 +1342,7 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
+                                      struct sctp_chunk *init,
+                                      struct sctp_cmd_seq *commands)
+ {
+-      struct net *net = sock_net(new_asoc->base.sk);
++      struct net *net = new_asoc->base.net;
+       struct sctp_transport *new_addr;
+       int ret = 1;
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 1ac05147dc304..722f8a940c2df 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -466,8 +466,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
+ static int sctp_send_asconf(struct sctp_association *asoc,
+                           struct sctp_chunk *chunk)
+ {
+-      struct net      *net = sock_net(asoc->base.sk);
+-      int             retval = 0;
++      int retval = 0;
+       /* If there is an outstanding ASCONF chunk, queue it for later
+        * transmission.
+@@ -479,7 +478,7 @@ static int sctp_send_asconf(struct sctp_association *asoc,
+       /* Hold the chunk until an ASCONF_ACK is received. */
+       sctp_chunk_hold(chunk);
+-      retval = sctp_primitive_ASCONF(net, asoc, chunk);
++      retval = sctp_primitive_ASCONF(asoc->base.net, asoc, chunk);
+       if (retval)
+               sctp_chunk_free(chunk);
+       else
+@@ -2462,9 +2461,8 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
+       int error;
+       if (params->spp_flags & SPP_HB_DEMAND && trans) {
+-              struct net *net = sock_net(trans->asoc->base.sk);
+-
+-              error = sctp_primitive_REQUESTHEARTBEAT(net, trans->asoc, trans);
++              error = sctp_primitive_REQUESTHEARTBEAT(trans->asoc->base.net,
++                                                      trans->asoc, trans);
+               if (error)
+                       return error;
+       }
+@@ -5334,7 +5332,7 @@ struct sctp_transport *sctp_transport_get_next(struct net *net,
+               if (!sctp_transport_hold(t))
+                       continue;
+-              if (net_eq(sock_net(t->asoc->base.sk), net) &&
++              if (net_eq(t->asoc->base.net, net) &&
+                   t->asoc->peer.primary_path == t)
+                       break;
+diff --git a/net/sctp/stream.c b/net/sctp/stream.c
+index 08cd06078fab1..0527728aee986 100644
+--- a/net/sctp/stream.c
++++ b/net/sctp/stream.c
+@@ -229,10 +229,9 @@ void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new)
+ static int sctp_send_reconf(struct sctp_association *asoc,
+                           struct sctp_chunk *chunk)
+ {
+-      struct net *net = sock_net(asoc->base.sk);
+       int retval = 0;
+-      retval = sctp_primitive_RECONF(net, asoc, chunk);
++      retval = sctp_primitive_RECONF(asoc->base.net, asoc, chunk);
+       if (retval)
+               sctp_chunk_free(chunk);
+diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
+index c982f99099dec..e3aad75cb11d9 100644
+--- a/net/sctp/stream_interleave.c
++++ b/net/sctp/stream_interleave.c
+@@ -241,9 +241,8 @@ static struct sctp_ulpevent *sctp_intl_retrieve_partial(
+       if (!first_frag)
+               return NULL;
+-      retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
+-                                           &ulpq->reasm, first_frag,
+-                                           last_frag);
++      retval = sctp_make_reassembled_event(ulpq->asoc->base.net, &ulpq->reasm,
++                                           first_frag, last_frag);
+       if (retval) {
+               sin->fsn = next_fsn;
+               if (is_last) {
+@@ -326,7 +325,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_reassembled(
+       pd_point = sctp_sk(asoc->base.sk)->pd_point;
+       if (pd_point && pd_point <= pd_len) {
+-              retval = sctp_make_reassembled_event(sock_net(asoc->base.sk),
++              retval = sctp_make_reassembled_event(asoc->base.net,
+                                                    &ulpq->reasm,
+                                                    pd_first, pd_last);
+               if (retval) {
+@@ -337,8 +336,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_reassembled(
+       goto out;
+ found:
+-      retval = sctp_make_reassembled_event(sock_net(asoc->base.sk),
+-                                           &ulpq->reasm,
++      retval = sctp_make_reassembled_event(asoc->base.net, &ulpq->reasm,
+                                            first_frag, pos);
+       if (retval)
+               retval->msg_flags |= MSG_EOR;
+@@ -630,7 +628,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_partial_uo(
+       if (!first_frag)
+               return NULL;
+-      retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
++      retval = sctp_make_reassembled_event(ulpq->asoc->base.net,
+                                            &ulpq->reasm_uo, first_frag,
+                                            last_frag);
+       if (retval) {
+@@ -716,7 +714,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_reassembled_uo(
+       pd_point = sctp_sk(asoc->base.sk)->pd_point;
+       if (pd_point && pd_point <= pd_len) {
+-              retval = sctp_make_reassembled_event(sock_net(asoc->base.sk),
++              retval = sctp_make_reassembled_event(asoc->base.net,
+                                                    &ulpq->reasm_uo,
+                                                    pd_first, pd_last);
+               if (retval) {
+@@ -727,8 +725,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_reassembled_uo(
+       goto out;
+ found:
+-      retval = sctp_make_reassembled_event(sock_net(asoc->base.sk),
+-                                           &ulpq->reasm_uo,
++      retval = sctp_make_reassembled_event(asoc->base.net, &ulpq->reasm_uo,
+                                            first_frag, pos);
+       if (retval)
+               retval->msg_flags |= MSG_EOR;
+@@ -814,7 +811,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_first_uo(struct sctp_ulpq *ulpq)
+               return NULL;
+ out:
+-      retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
++      retval = sctp_make_reassembled_event(ulpq->asoc->base.net,
+                                            &ulpq->reasm_uo, first_frag,
+                                            last_frag);
+       if (retval) {
+@@ -921,7 +918,7 @@ static struct sctp_ulpevent *sctp_intl_retrieve_first(struct sctp_ulpq *ulpq)
+               return NULL;
+ out:
+-      retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
++      retval = sctp_make_reassembled_event(ulpq->asoc->base.net,
+                                            &ulpq->reasm, first_frag,
+                                            last_frag);
+       if (retval) {
+@@ -1159,7 +1156,7 @@ static void sctp_generate_iftsn(struct sctp_outq *q, __u32 ctsn)
+       if (ftsn_chunk) {
+               list_add_tail(&ftsn_chunk->list, &q->control_chunk_list);
+-              SCTP_INC_STATS(sock_net(asoc->base.sk), SCTP_MIB_OUTCTRLCHUNKS);
++              SCTP_INC_STATS(asoc->base.net, SCTP_MIB_OUTCTRLCHUNKS);
+       }
+ }
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 80251c8d2225f..9c721d70df9c6 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -336,7 +336,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+               pr_debug("%s: rto_pending not set on transport %p!\n", __func__, tp);
+       if (tp->rttvar || tp->srtt) {
+-              struct net *net = sock_net(tp->asoc->base.sk);
++              struct net *net = tp->asoc->base.net;
+               /* 6.3.1 C3) When a new RTT measurement R' is made, set
+                * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+                * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
+index b6536b7f14c0d..1c6c640607c5c 100644
+--- a/net/sctp/ulpqueue.c
++++ b/net/sctp/ulpqueue.c
+@@ -486,10 +486,9 @@ static struct sctp_ulpevent *sctp_ulpq_retrieve_reassembled(struct sctp_ulpq *ul
+               cevent = sctp_skb2event(pd_first);
+               pd_point = sctp_sk(asoc->base.sk)->pd_point;
+               if (pd_point && pd_point <= pd_len) {
+-                      retval = sctp_make_reassembled_event(sock_net(asoc->base.sk),
++                      retval = sctp_make_reassembled_event(asoc->base.net,
+                                                            &ulpq->reasm,
+-                                                           pd_first,
+-                                                           pd_last);
++                                                           pd_first, pd_last);
+                       if (retval)
+                               sctp_ulpq_set_pd(ulpq);
+               }
+@@ -497,7 +496,7 @@ static struct sctp_ulpevent *sctp_ulpq_retrieve_reassembled(struct sctp_ulpq *ul
+ done:
+       return retval;
+ found:
+-      retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
++      retval = sctp_make_reassembled_event(ulpq->asoc->base.net,
+                                            &ulpq->reasm, first_frag, pos);
+       if (retval)
+               retval->msg_flags |= MSG_EOR;
+@@ -563,8 +562,8 @@ static struct sctp_ulpevent *sctp_ulpq_retrieve_partial(struct sctp_ulpq *ulpq)
+        * further.
+        */
+ done:
+-      retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
+-                                      &ulpq->reasm, first_frag, last_frag);
++      retval = sctp_make_reassembled_event(ulpq->asoc->base.net, &ulpq->reasm,
++                                           first_frag, last_frag);
+       if (retval && is_last)
+               retval->msg_flags |= MSG_EOR;
+@@ -664,8 +663,8 @@ static struct sctp_ulpevent *sctp_ulpq_retrieve_first(struct sctp_ulpq *ulpq)
+        * further.
+        */
+ done:
+-      retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
+-                                      &ulpq->reasm, first_frag, last_frag);
++      retval = sctp_make_reassembled_event(ulpq->asoc->base.net, &ulpq->reasm,
++                                           first_frag, last_frag);
+       return retval;
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.4/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch b/queue-5.4/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
new file mode 100644 (file)
index 0000000..a745a84
--- /dev/null
@@ -0,0 +1,86 @@
+From 2a606e1787723adf2fb72c67aeea3b09f3db6434 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 11:10:54 +0000
+Subject: sctp: prevent possible shift-out-of-bounds in
+ sctp_transport_update_rto
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 1534ff77757e44bcc4b98d0196bc5c0052fce5fa ]
+
+syzbot reported a possible shift-out-of-bounds [1]
+
+Blamed commit added rto_alpha_max and rto_beta_max set to 1000.
+
+It is unclear if some sctp users are setting very large rto_alpha
+and/or rto_beta.
+
+In order to prevent user regression, perform the test at run time.
+
+Also add READ_ONCE() annotations as sysctl values can change under us.
+
+[1]
+
+UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41
+shift exponent 64 is too large for 32-bit type 'unsigned int'
+CPU: 0 UID: 0 PID: 16704 Comm: syz.2.2320 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:94 [inline]
+  dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120
+  ubsan_epilogue lib/ubsan.c:233 [inline]
+  __ubsan_handle_shift_out_of_bounds+0x27f/0x420 lib/ubsan.c:494
+  sctp_transport_update_rto.cold+0x1c/0x34b net/sctp/transport.c:509
+  sctp_check_transmitted+0x11c4/0x1c30 net/sctp/outqueue.c:1502
+  sctp_outq_sack+0x4ef/0x1b20 net/sctp/outqueue.c:1338
+  sctp_cmd_process_sack net/sctp/sm_sideeffect.c:840 [inline]
+  sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1372 [inline]
+
+Fixes: b58537a1f562 ("net: sctp: fix permissions for rto_alpha and rto_beta knobs")
+Reported-by: syzbot+f8c46c8b2b7f6e076e99@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c81ae.050a0220.3d0d33.014e.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20251106111054.3288127-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/transport.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 9c721d70df9c6..9921041079781 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -337,6 +337,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+       if (tp->rttvar || tp->srtt) {
+               struct net *net = tp->asoc->base.net;
++              unsigned int rto_beta, rto_alpha;
+               /* 6.3.1 C3) When a new RTT measurement R' is made, set
+                * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+                * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+@@ -348,10 +349,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+                * For example, assuming the default value of RTO.Alpha of
+                * 1/8, rto_alpha would be expressed as 3.
+                */
+-              tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
+-                      + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
+-              tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
+-                      + (rtt >> net->sctp.rto_alpha);
++              rto_beta = READ_ONCE(net->sctp.rto_beta);
++              if (rto_beta < 32)
++                      tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta)
++                              + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> rto_beta);
++              rto_alpha = READ_ONCE(net->sctp.rto_alpha);
++              if (rto_alpha < 32)
++                      tp->srtt = tp->srtt - (tp->srtt >> rto_alpha)
++                              + (rtt >> rto_alpha);
+       } else {
+               /* 6.3.1 C2) When the first RTT measurement R is made, set
+                * SRTT <- R, RTTVAR <- R/2.
+-- 
+2.51.0
+
index 7fca1c3187cc891c5ec837f74d2830d0f6d48ae6..8f9ac8aa374c01b7be00015428374379ea84bb58 100644 (file)
@@ -126,3 +126,20 @@ compiler_types-move-unused-static-inline-functions-w.patch
 nfs4-fix-state-renewals-missing-after-boot.patch
 hid-quirks-avoid-cooler-master-mm712-dongle-wakeup-b.patch
 asoc-max98090-91-fixed-max98091-alsa-widget-powering.patch
+net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
+bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
+bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
+bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
+bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
+sctp-get-netns-from-asoc-and-ep-base.patch
+sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
+tipc-simplify-the-finalize-work-queue.patch
+tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
+net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
+wifi-mac80211-skip-rate-verification-for-not-capture.patch
+net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
+net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
+net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
+net_sched-remove-need_resched-from-qdisc_run.patch
+net_sched-limit-try_bulk_dequeue_skb-batches.patch
+bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
diff --git a/queue-5.4/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch b/queue-5.4/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
new file mode 100644 (file)
index 0000000..b90be33
--- /dev/null
@@ -0,0 +1,150 @@
+From eb932dbd9cd940e1f035dbaffed183fafe409fdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 06:40:25 +0000
+Subject: tipc: Fix use-after-free in tipc_mon_reinit_self().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 0725e6afb55128be21a2ca36e9674f573ccec173 ]
+
+syzbot reported use-after-free of tipc_net(net)->monitors[]
+in tipc_mon_reinit_self(). [0]
+
+The array is protected by RTNL, but tipc_mon_reinit_self()
+iterates over it without RTNL.
+
+tipc_mon_reinit_self() is called from tipc_net_finalize(),
+which is always under RTNL except for tipc_net_finalize_work().
+
+Let's hold RTNL in tipc_net_finalize_work().
+
+[0]:
+BUG: KASAN: slab-use-after-free in __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+Read of size 1 at addr ffff88805eae1030 by task kworker/0:7/5989
+
+CPU: 0 UID: 0 PID: 5989 Comm: kworker/0:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
+Workqueue: events tipc_net_finalize_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xca/0x240 mm/kasan/report.c:482
+ kasan_report+0x118/0x150 mm/kasan/report.c:595
+ __kasan_check_byte+0x2a/0x40 mm/kasan/common.c:568
+ kasan_check_byte include/linux/kasan.h:399 [inline]
+ lock_acquire+0x8d/0x360 kernel/locking/lockdep.c:5842
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+ rtlock_slowlock kernel/locking/rtmutex.c:1894 [inline]
+ rwbase_rtmutex_lock_state kernel/locking/spinlock_rt.c:160 [inline]
+ rwbase_write_lock+0xd3/0x7e0 kernel/locking/rwbase_rt.c:244
+ rt_write_lock+0x76/0x110 kernel/locking/spinlock_rt.c:243
+ write_lock_bh include/linux/rwlock_rt.h:99 [inline]
+ tipc_mon_reinit_self+0x79/0x430 net/tipc/monitor.c:718
+ tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
+ process_one_work kernel/workqueue.c:3236 [inline]
+ process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3319
+ worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
+ kthread+0x70e/0x8a0 kernel/kthread.c:463
+ ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+Allocated by task 6089:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __kmalloc_cache_noprof+0x1a8/0x320 mm/slub.c:4407
+ kmalloc_noprof include/linux/slab.h:905 [inline]
+ kzalloc_noprof include/linux/slab.h:1039 [inline]
+ tipc_mon_create+0xc3/0x4d0 net/tipc/monitor.c:657
+ tipc_enable_bearer net/tipc/bearer.c:357 [inline]
+ __tipc_nl_bearer_enable+0xe16/0x13f0 net/tipc/bearer.c:1047
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:371 [inline]
+ tipc_nl_compat_doit+0x3bc/0x5f0 net/tipc/netlink_compat.c:393
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:-1 [inline]
+ tipc_nl_compat_recv+0x83c/0xbe0 net/tipc/netlink_compat.c:1321
+ genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
+ netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
+ netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:729
+ ____sys_sendmsg+0x508/0x820 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 6088:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
+ poison_slab_object mm/kasan/common.c:243 [inline]
+ __kasan_slab_free+0x5b/0x80 mm/kasan/common.c:275
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2422 [inline]
+ slab_free mm/slub.c:4695 [inline]
+ kfree+0x195/0x550 mm/slub.c:4894
+ tipc_l2_device_event+0x380/0x650 net/tipc/bearer.c:-1
+ notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
+ call_netdevice_notifiers_extack net/core/dev.c:2267 [inline]
+ call_netdevice_notifiers net/core/dev.c:2281 [inline]
+ unregister_netdevice_many_notify+0x14d7/0x1fe0 net/core/dev.c:12166
+ unregister_netdevice_many net/core/dev.c:12229 [inline]
+ unregister_netdevice_queue+0x33c/0x380 net/core/dev.c:12073
+ unregister_netdevice include/linux/netdevice.h:3385 [inline]
+ __tun_detach+0xe4d/0x1620 drivers/net/tun.c:621
+ tun_detach drivers/net/tun.c:637 [inline]
+ tun_chr_close+0x10d/0x1c0 drivers/net/tun.c:3433
+ __fput+0x458/0xa80 fs/file_table.c:468
+ task_work_run+0x1d4/0x260 kernel/task_work.c:227
+ resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
+ exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:43
+ exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
+ syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline]
+ syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline]
+ do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 46cb01eeeb86 ("tipc: update mon's self addr when node addr generated")
+Reported-by: syzbot+d7dad7fd4b3921104957@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c323a.050a0220.baf87.007f.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251107064038.2361188-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/net.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/tipc/net.c b/net/tipc/net.c
+index 3807ead54d3d5..81c0b123875ae 100644
+--- a/net/tipc/net.c
++++ b/net/tipc/net.c
+@@ -141,7 +141,9 @@ void tipc_net_finalize_work(struct work_struct *work)
+ {
+       struct tipc_net *tn = container_of(work, struct tipc_net, work);
++      rtnl_lock();
+       tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
++      rtnl_unlock();
+ }
+ void tipc_net_stop(struct net *net)
+-- 
+2.51.0
+
diff --git a/queue-5.4/tipc-simplify-the-finalize-work-queue.patch b/queue-5.4/tipc-simplify-the-finalize-work-queue.patch
new file mode 100644 (file)
index 0000000..b6cb463
--- /dev/null
@@ -0,0 +1,164 @@
+From fa200a99d84c1cf6f84dfd187553e3d7f5df8807 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 10:09:08 +0800
+Subject: tipc: simplify the finalize work queue
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit be07f056396d6bb40963c45a02951c566ddeef8e ]
+
+This patch is to use "struct work_struct" for the finalize work queue
+instead of "struct tipc_net_work", as it can get the "net" and "addr"
+from tipc_net's other members and there is no need to add extra net
+and addr in tipc_net by defining "struct tipc_net_work".
+
+Note that it's safe to get net from tn->bcl as bcl is always released
+after the finalize work queue is done.
+
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 0725e6afb551 ("tipc: Fix use-after-free in tipc_mon_reinit_self().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/core.c     |  4 ++--
+ net/tipc/core.h     |  8 +-------
+ net/tipc/discover.c |  4 ++--
+ net/tipc/link.c     |  5 +++++
+ net/tipc/link.h     |  1 +
+ net/tipc/net.c      | 15 +++------------
+ 6 files changed, 14 insertions(+), 23 deletions(-)
+
+diff --git a/net/tipc/core.c b/net/tipc/core.c
+index 58ee5ee707816..cce4cde3f5f18 100644
+--- a/net/tipc/core.c
++++ b/net/tipc/core.c
+@@ -59,7 +59,7 @@ static int __net_init tipc_init_net(struct net *net)
+       tn->trial_addr = 0;
+       tn->addr_trial_end = 0;
+       tn->capabilities = TIPC_NODE_CAPABILITIES;
+-      INIT_WORK(&tn->final_work.work, tipc_net_finalize_work);
++      INIT_WORK(&tn->work, tipc_net_finalize_work);
+       memset(tn->node_id, 0, sizeof(tn->node_id));
+       memset(tn->node_id_string, 0, sizeof(tn->node_id_string));
+       tn->mon_threshold = TIPC_DEF_MON_THRESHOLD;
+@@ -101,7 +101,7 @@ static void __net_exit tipc_exit_net(struct net *net)
+       tipc_detach_loopback(net);
+       /* Make sure the tipc_net_finalize_work() finished */
+-      cancel_work_sync(&tn->final_work.work);
++      cancel_work_sync(&tn->work);
+       tipc_net_stop(net);
+       tipc_bcast_stop(net);
+diff --git a/net/tipc/core.h b/net/tipc/core.h
+index 59f97ef12e60d..32c5945c89338 100644
+--- a/net/tipc/core.h
++++ b/net/tipc/core.h
+@@ -87,12 +87,6 @@ extern unsigned int tipc_net_id __read_mostly;
+ extern int sysctl_tipc_rmem[3] __read_mostly;
+ extern int sysctl_tipc_named_timeout __read_mostly;
+-struct tipc_net_work {
+-      struct work_struct work;
+-      struct net *net;
+-      u32 addr;
+-};
+-
+ struct tipc_net {
+       u8  node_id[NODE_ID_LEN];
+       u32 node_addr;
+@@ -143,7 +137,7 @@ struct tipc_net {
+       struct packet_type loopback_pt;
+       /* Work item for net finalize */
+-      struct tipc_net_work final_work;
++      struct work_struct work;
+       /* The numbers of work queues in schedule */
+       atomic_t wq_count;
+ };
+diff --git a/net/tipc/discover.c b/net/tipc/discover.c
+index 9c64567f8a741..a6aa9ecc4a0bb 100644
+--- a/net/tipc/discover.c
++++ b/net/tipc/discover.c
+@@ -167,7 +167,7 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
+       /* Apply trial address if we just left trial period */
+       if (!trial && !self) {
+-              tipc_sched_net_finalize(net, tn->trial_addr);
++              schedule_work(&tn->work);
+               msg_set_prevnode(buf_msg(d->skb), tn->trial_addr);
+               msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
+       }
+@@ -310,7 +310,7 @@ static void tipc_disc_timeout(struct timer_list *t)
+       if (!time_before(jiffies, tn->addr_trial_end) && !tipc_own_addr(net)) {
+               mod_timer(&d->timer, jiffies + TIPC_DISC_INIT);
+               spin_unlock_bh(&d->lock);
+-              tipc_sched_net_finalize(net, tn->trial_addr);
++              schedule_work(&tn->work);
+               return;
+       }
+diff --git a/net/tipc/link.c b/net/tipc/link.c
+index 2052649fb537e..bf7e6fd855485 100644
+--- a/net/tipc/link.c
++++ b/net/tipc/link.c
+@@ -332,6 +332,11 @@ char tipc_link_plane(struct tipc_link *l)
+       return l->net_plane;
+ }
++struct net *tipc_link_net(struct tipc_link *l)
++{
++      return l->net;
++}
++
+ void tipc_link_update_caps(struct tipc_link *l, u16 capabilities)
+ {
+       l->peer_caps = capabilities;
+diff --git a/net/tipc/link.h b/net/tipc/link.h
+index adcad65e761ce..5ac43acce958a 100644
+--- a/net/tipc/link.h
++++ b/net/tipc/link.h
+@@ -151,4 +151,5 @@ int tipc_link_bc_sync_rcv(struct tipc_link *l,   struct tipc_msg *hdr,
+ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb,
+                         struct sk_buff_head *xmitq);
+ bool tipc_link_too_silent(struct tipc_link *l);
++struct net *tipc_link_net(struct tipc_link *l);
+ #endif
+diff --git a/net/tipc/net.c b/net/tipc/net.c
+index 2498ce8b83c1a..3807ead54d3d5 100644
+--- a/net/tipc/net.c
++++ b/net/tipc/net.c
+@@ -41,6 +41,7 @@
+ #include "socket.h"
+ #include "node.h"
+ #include "bcast.h"
++#include "link.h"
+ #include "netlink.h"
+ #include "monitor.h"
+@@ -138,19 +139,9 @@ static void tipc_net_finalize(struct net *net, u32 addr)
+ void tipc_net_finalize_work(struct work_struct *work)
+ {
+-      struct tipc_net_work *fwork;
++      struct tipc_net *tn = container_of(work, struct tipc_net, work);
+-      fwork = container_of(work, struct tipc_net_work, work);
+-      tipc_net_finalize(fwork->net, fwork->addr);
+-}
+-
+-void tipc_sched_net_finalize(struct net *net, u32 addr)
+-{
+-      struct tipc_net *tn = tipc_net(net);
+-
+-      tn->final_work.net = net;
+-      tn->final_work.addr = addr;
+-      schedule_work(&tn->final_work.work);
++      tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
+ }
+ void tipc_net_stop(struct net *net)
+-- 
+2.51.0
+
diff --git a/queue-5.4/wifi-mac80211-skip-rate-verification-for-not-capture.patch b/queue-5.4/wifi-mac80211-skip-rate-verification-for-not-capture.patch
new file mode 100644 (file)
index 0000000..c15c517
--- /dev/null
@@ -0,0 +1,48 @@
+From 800e8b73c1e6c7f429b54828067b77e7e624fcf8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 14:26:18 +0200
+Subject: wifi: mac80211: skip rate verification for not captured PSDUs
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 7fe0d21f5633af8c3fab9f0ef0706c6156623484 ]
+
+If for example the sniffer did not follow any AIDs in an MU frame, then
+some of the information may not be filled in or is even expected to be
+invalid. As an example, in that case it is expected that Nss is zero.
+
+Fixes: 2ff5e52e7836 ("radiotap: add 0-length PSDU "not captured" type")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251110142554.83a2858ee15b.I9f78ce7984872f474722f9278691ae16378f0a3e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 4c805530edfb6..e8e72271fbb8f 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -4669,10 +4669,14 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+       if (WARN_ON(!local->started))
+               goto drop;
+-      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) {
++      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) &&
++                 !(status->flag & RX_FLAG_NO_PSDU &&
++                   status->zero_length_psdu_type ==
++                   IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) {
+               /*
+-               * Validate the rate, unless a PLCP error means that
+-               * we probably can't have a valid rate here anyway.
++               * Validate the rate, unless there was a PLCP error which may
++               * have an invalid rate or the PSDU was not capture and may be
++               * missing rate information.
+                */
+               switch (status->encoding) {
+-- 
+2.51.0
+
diff --git a/queue-6.1/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch b/queue-6.1/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch
new file mode 100644 (file)
index 0000000..282476b
--- /dev/null
@@ -0,0 +1,49 @@
+From b37830869162339e719afc3e29f8f098e4b331a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:42 +0530
+Subject: ACPI: CPPC: Check _CPC validity for only the online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 6dd3b8a709a130a4d55c866af9804c81b8486d28 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function acpi_cpc_valid() checks for the validity of the
+_CPC object for all the present CPUs. This breaks when the kernel is
+booted with "nosmt=force".
+
+Hence check the validity of the _CPC objects of only the online CPUs.
+
+Fixes: 2aeca6bd0277 ("ACPI: CPPC: Check present CPUs for determining _CPC is valid")
+Reported-by: Christopher Harris <chris.harris79@gmail.com>
+Closes: https://lore.kernel.org/lkml/CAM+eXpdDT7KjLV0AxEwOLkSJ2QtrsvGvjA2cCHvt1d0k2_C4Cw@mail.gmail.com/
+Suggested-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Tested-by: Chrisopher Harris <chris.harris79@gmail.com>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-3-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 504fe14c566e3..6d89299af3bbe 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -440,7 +440,7 @@ bool acpi_cpc_valid(void)
+       if (acpi_disabled)
+               return false;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+               if (!cpc_ptr)
+                       return false;
+-- 
+2.51.0
+
diff --git a/queue-6.1/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch b/queue-6.1/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch
new file mode 100644 (file)
index 0000000..a2c0995
--- /dev/null
@@ -0,0 +1,45 @@
+From 6e34396a3b84db1d9e0c3fb003552a3c9e13cc7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:44 +0530
+Subject: ACPI: CPPC: Limit perf ctrs in PCC check only to online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 0fce75870666b46b700cfbd3216380b422f975da ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPU via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function cppc_perf_ctrs_in_pcc() checks if the CPPC
+perf-ctrs are in a PCC region for all the present CPUs, which breaks
+when the kernel is booted with "nosmt=force".
+
+Hence, limit the check only to the online CPUs.
+
+Fixes: ae2df912d1a5 ("ACPI: CPPC: Disable FIE if registers in PCC regions")
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-5-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 3aa4c489ca5bc..27729a1f34cb0 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -1336,7 +1336,7 @@ bool cppc_perf_ctrs_in_pcc(void)
+ {
+       int cpu;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               struct cpc_register_resource *ref_perf_reg;
+               struct cpc_desc *cpc_desc;
+-- 
+2.51.0
+
diff --git a/queue-6.1/acpi-cppc-perform-fast-check-switch-only-for-online-.patch b/queue-6.1/acpi-cppc-perform-fast-check-switch-only-for-online-.patch
new file mode 100644 (file)
index 0000000..c2169ba
--- /dev/null
@@ -0,0 +1,45 @@
+From 728c3e233ac332a97b4facc3f3ae149c2f819178 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:43 +0530
+Subject: ACPI: CPPC: Perform fast check switch only for online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 8821c8e80a65bc4eb73daf63b34aac6b8ad69461 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function cppc_allow_fast_switch() checks for the validity
+of the _CPC object for all the present CPUs. This breaks when the
+kernel is booted with "nosmt=force".
+
+Check fast_switch capability only on online CPUs
+
+Fixes: 15eece6c5b05 ("ACPI: CPPC: Fix NULL pointer dereference when nosmp is used")
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-4-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 6d89299af3bbe..3aa4c489ca5bc 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -456,7 +456,7 @@ bool cppc_allow_fast_switch(void)
+       struct cpc_desc *cpc_ptr;
+       int cpu;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+               desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF];
+               if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
+-- 
+2.51.0
+
diff --git a/queue-6.1/af_unix-initialise-scc_index-in-unix_add_edge.patch b/queue-6.1/af_unix-initialise-scc_index-in-unix_add_edge.patch
new file mode 100644 (file)
index 0000000..cacf39e
--- /dev/null
@@ -0,0 +1,139 @@
+From 8d9bbdfc02ac8d6c73a08b9d80f93bb02c09135a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 02:52:22 +0000
+Subject: af_unix: Initialise scc_index in unix_add_edge().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 60e6489f8e3b086bd1130ad4450a2c112e863791 ]
+
+Quang Le reported that the AF_UNIX GC could garbage-collect a
+receive queue of an alive in-flight socket, with a nice repro.
+
+The repro consists of three stages.
+
+  1)
+    1-a. Create a single cyclic reference with many sockets
+    1-b. close() all sockets
+    1-c. Trigger GC
+
+  2)
+    2-a. Pass sk-A to an embryo sk-B
+    2-b. Pass sk-X to sk-X
+    2-c. Trigger GC
+
+  3)
+    3-a. accept() the embryo sk-B
+    3-b. Pass sk-B to sk-C
+    3-c. close() the in-flight sk-A
+    3-d. Trigger GC
+
+As of 2-c, sk-A and sk-X are linked to unix_unvisited_vertices,
+and unix_walk_scc() groups them into two different SCCs:
+
+  unix_sk(sk-A)->vertex->scc_index = 2 (UNIX_VERTEX_INDEX_START)
+  unix_sk(sk-X)->vertex->scc_index = 3
+
+Once GC completes, unix_graph_grouped is set to true.
+Also, unix_graph_maybe_cyclic is set to true due to sk-X's
+cyclic self-reference, which makes close() trigger GC.
+
+At 3-b, unix_add_edge() allocates unix_sk(sk-B)->vertex and
+links it to unix_unvisited_vertices.
+
+unix_update_graph() is called at 3-a. and 3-b., but neither
+unix_graph_grouped nor unix_graph_maybe_cyclic is changed
+because both sk-B's listener and sk-C are not in-flight.
+
+3-c decrements sk-A's file refcnt to 1.
+
+Since unix_graph_grouped is true at 3-d, unix_walk_scc_fast()
+is finally called and iterates 3 sockets sk-A, sk-B, and sk-X:
+
+  sk-A -> sk-B (-> sk-C)
+  sk-X -> sk-X
+
+This is totally fine.  All of them are not yet close()d and
+should be grouped into different SCCs.
+
+However, unix_vertex_dead() misjudges that sk-A and sk-B are
+in the same SCC and sk-A is dead.
+
+  unix_sk(sk-A)->scc_index == unix_sk(sk-B)->scc_index <-- Wrong!
+  &&
+  sk-A's file refcnt == unix_sk(sk-A)->vertex->out_degree
+                                       ^-- 1 in-flight count for sk-B
+  -> sk-A is dead !?
+
+The problem is that unix_add_edge() does not initialise scc_index.
+
+Stage 1) is used for heap spraying, making a newly allocated
+vertex have vertex->scc_index == 2 (UNIX_VERTEX_INDEX_START)
+set by unix_walk_scc() at 1-c.
+
+Let's track the max SCC index from the previous unix_walk_scc()
+call and assign the max + 1 to a new vertex's scc_index.
+
+This way, we can continue to avoid Tarjan's algorithm while
+preventing misjudgments.
+
+Fixes: ad081928a8b0 ("af_unix: Avoid Tarjan's algorithm if unnecessary.")
+Reported-by: Quang Le <quanglex97@gmail.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20251109025233.3659187-1-kuniyu@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/garbage.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 0068e758be4dd..66fd606c43f45 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -136,6 +136,7 @@ enum unix_vertex_index {
+ };
+ static unsigned long unix_vertex_unvisited_index = UNIX_VERTEX_INDEX_MARK1;
++static unsigned long unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START;
+ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
+ {
+@@ -144,6 +145,7 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
+       if (!vertex) {
+               vertex = list_first_entry(&fpl->vertices, typeof(*vertex), entry);
+               vertex->index = unix_vertex_unvisited_index;
++              vertex->scc_index = ++unix_vertex_max_scc_index;
+               vertex->out_degree = 0;
+               INIT_LIST_HEAD(&vertex->edges);
+               INIT_LIST_HEAD(&vertex->scc_entry);
+@@ -480,10 +482,15 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde
+                               scc_dead = unix_vertex_dead(v);
+               }
+-              if (scc_dead)
++              if (scc_dead) {
+                       unix_collect_skb(&scc, hitlist);
+-              else if (!unix_graph_maybe_cyclic)
+-                      unix_graph_maybe_cyclic = unix_scc_cyclic(&scc);
++              } else {
++                      if (unix_vertex_max_scc_index < vertex->scc_index)
++                              unix_vertex_max_scc_index = vertex->scc_index;
++
++                      if (!unix_graph_maybe_cyclic)
++                              unix_graph_maybe_cyclic = unix_scc_cyclic(&scc);
++              }
+               list_del(&scc);
+       }
+@@ -498,6 +505,7 @@ static void unix_walk_scc(struct sk_buff_head *hitlist)
+       unsigned long last_index = UNIX_VERTEX_INDEX_START;
+       unix_graph_maybe_cyclic = false;
++      unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START;
+       /* Visit every vertex exactly once.
+        * __unix_walk_scc() moves visited vertices to unix_visited_vertices.
+-- 
+2.51.0
+
diff --git a/queue-6.1/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch b/queue-6.1/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
new file mode 100644 (file)
index 0000000..1bb354c
--- /dev/null
@@ -0,0 +1,149 @@
+From f833b8e78661757e60bec78776cac5be633f4ee0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:49 +0200
+Subject: Bluetooth: 6lowpan: Don't hold spin lock over sleeping functions
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 98454bc812f3611551e4b1f81732da4aa7b9597e ]
+
+disconnect_all_peers() calls sleeping function (l2cap_chan_close) under
+spinlock.  Holding the lock doesn't actually do any good -- we work on a
+local copy of the list, and the lock doesn't protect against peer->chan
+having already been freed.
+
+Fix by taking refcounts of peer->chan instead.  Clean up the code and
+old comments a bit.
+
+Take devices_lock instead of RCU, because the kfree_rcu();
+l2cap_chan_put(); construct in chan_close_cb() does not guarantee
+peer->chan is necessarily valid in RCU.
+
+Also take l2cap_chan_lock() which is required for l2cap_chan_close().
+
+Log: (bluez 6lowpan-tester Client Connect - Disable)
+------
+BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
+...
+<TASK>
+...
+l2cap_send_disconn_req (net/bluetooth/l2cap_core.c:938 net/bluetooth/l2cap_core.c:1495)
+...
+? __pfx_l2cap_chan_close (net/bluetooth/l2cap_core.c:809)
+do_enable_set (net/bluetooth/6lowpan.c:1048 net/bluetooth/6lowpan.c:1068)
+------
+
+Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 68 ++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 57553abde4180..347361ff0cc87 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -52,6 +52,11 @@ static bool enable_6lowpan;
+ static struct l2cap_chan *listen_chan;
+ static DEFINE_MUTEX(set_lock);
++enum {
++      LOWPAN_PEER_CLOSING,
++      LOWPAN_PEER_MAXBITS
++};
++
+ struct lowpan_peer {
+       struct list_head list;
+       struct rcu_head rcu;
+@@ -60,6 +65,8 @@ struct lowpan_peer {
+       /* peer addresses in various formats */
+       unsigned char lladdr[ETH_ALEN];
+       struct in6_addr peer_addr;
++
++      DECLARE_BITMAP(flags, LOWPAN_PEER_MAXBITS);
+ };
+ struct lowpan_btle_dev {
+@@ -1013,41 +1020,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ static void disconnect_all_peers(void)
+ {
+       struct lowpan_btle_dev *entry;
+-      struct lowpan_peer *peer, *tmp_peer, *new_peer;
+-      struct list_head peers;
+-
+-      INIT_LIST_HEAD(&peers);
++      struct lowpan_peer *peer;
++      int nchans;
+-      /* We make a separate list of peers as the close_cb() will
+-       * modify the device peers list so it is better not to mess
+-       * with the same list at the same time.
++      /* l2cap_chan_close() cannot be called from RCU, and lock ordering
++       * chan->lock > devices_lock prevents taking write side lock, so copy
++       * then close.
+        */
+       rcu_read_lock();
++      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list)
++              list_for_each_entry_rcu(peer, &entry->peers, list)
++                      clear_bit(LOWPAN_PEER_CLOSING, peer->flags);
++      rcu_read_unlock();
+-      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
+-              list_for_each_entry_rcu(peer, &entry->peers, list) {
+-                      new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
+-                      if (!new_peer)
+-                              break;
++      do {
++              struct l2cap_chan *chans[32];
++              int i;
+-                      new_peer->chan = peer->chan;
+-                      INIT_LIST_HEAD(&new_peer->list);
++              nchans = 0;
+-                      list_add(&new_peer->list, &peers);
+-              }
+-      }
++              spin_lock(&devices_lock);
+-      rcu_read_unlock();
++              list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
++                      list_for_each_entry_rcu(peer, &entry->peers, list) {
++                              if (test_and_set_bit(LOWPAN_PEER_CLOSING,
++                                                   peer->flags))
++                                      continue;
+-      spin_lock(&devices_lock);
+-      list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
+-              l2cap_chan_close(peer->chan, ENOENT);
++                              l2cap_chan_hold(peer->chan);
++                              chans[nchans++] = peer->chan;
+-              list_del_rcu(&peer->list);
+-              kfree_rcu(peer, rcu);
+-      }
+-      spin_unlock(&devices_lock);
++                              if (nchans >= ARRAY_SIZE(chans))
++                                      goto done;
++                      }
++              }
++
++done:
++              spin_unlock(&devices_lock);
++
++              for (i = 0; i < nchans; ++i) {
++                      l2cap_chan_lock(chans[i]);
++                      l2cap_chan_close(chans[i], ENOENT);
++                      l2cap_chan_unlock(chans[i]);
++                      l2cap_chan_put(chans[i]);
++              }
++      } while (nchans);
+ }
+ struct set_enable {
+-- 
+2.51.0
+
diff --git a/queue-6.1/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch b/queue-6.1/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
new file mode 100644 (file)
index 0000000..7946302
--- /dev/null
@@ -0,0 +1,103 @@
+From b6a617bb1ccac14562c18f0b28356adee0c7995c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:47 +0200
+Subject: Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type
+ confusion
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit b454505bf57a2e4f5d49951d4deb03730a9348d9 ]
+
+Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types,
+e.g. debugfs "connect" command takes the former, and "disconnect" and
+"connect" to already connected device take the latter.  This is due to
+using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le
+which take different dst_type values.
+
+Fix address type passed to hci_conn_hash_lookup_le().
+
+Retain the debugfs API difference between "connect" and "disconnect"
+commands since it's been like this since 2015 and nobody apparently
+complained.
+
+Fixes: f5ad4ffceba0 ("Bluetooth: 6lowpan: Use hci_conn_hash_lookup_le() when possible")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 003c8ae104f29..57553abde4180 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -956,10 +956,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void)
+ }
+ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+-                        struct l2cap_conn **conn)
++                        struct l2cap_conn **conn, bool disconnect)
+ {
+       struct hci_conn *hcon;
+       struct hci_dev *hdev;
++      int le_addr_type;
+       int n;
+       n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
+@@ -970,13 +971,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+       if (n < 7)
+               return -EINVAL;
++      if (disconnect) {
++              /* The "disconnect" debugfs command has used different address
++               * type constants than "connect" since 2015. Let's retain that
++               * for now even though it's obviously buggy...
++               */
++              *addr_type += 1;
++      }
++
++      switch (*addr_type) {
++      case BDADDR_LE_PUBLIC:
++              le_addr_type = ADDR_LE_DEV_PUBLIC;
++              break;
++      case BDADDR_LE_RANDOM:
++              le_addr_type = ADDR_LE_DEV_RANDOM;
++              break;
++      default:
++              return -EINVAL;
++      }
++
+       /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
+       hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
+       if (!hdev)
+               return -ENOENT;
+       hci_dev_lock(hdev);
+-      hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
++      hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+@@ -1103,7 +1123,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       buf[buf_size] = '\0';
+       if (memcmp(buf, "connect ", 8) == 0) {
+-              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false);
+               if (ret == -EINVAL)
+                       return ret;
+@@ -1140,7 +1160,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       }
+       if (memcmp(buf, "disconnect ", 11) == 0) {
+-              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true);
+               if (ret < 0)
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.1/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch b/queue-6.1/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
new file mode 100644 (file)
index 0000000..1736168
--- /dev/null
@@ -0,0 +1,54 @@
+From 57b482ac6b391c05a154d191e621a0115cfd30aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:46 +0200
+Subject: Bluetooth: 6lowpan: reset link-local header on ipv6 recv path
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3b78f50918276ab28fb22eac9aa49401ac436a3b ]
+
+Bluetooth 6lowpan.c netdev has header_ops, so it must set link-local
+header for RX skb, otherwise things crash, eg. with AF_PACKET SOCK_RAW
+
+Add missing skb_reset_mac_header() for uncompressed ipv6 RX path.
+
+For the compressed one, it is done in lowpan_header_decompress().
+
+Log: (BlueZ 6lowpan-tester Client Recv Raw - Success)
+------
+kernel BUG at net/core/skbuff.c:212!
+Call Trace:
+<IRQ>
+...
+packet_rcv (net/packet/af_packet.c:2152)
+...
+<TASK>
+__local_bh_enable_ip (kernel/softirq.c:407)
+netif_rx (net/core/dev.c:5648)
+chan_recv_cb (net/bluetooth/6lowpan.c:294 net/bluetooth/6lowpan.c:359)
+------
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index db119071a0ea0..003c8ae104f29 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -288,6 +288,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
+               local_skb->pkt_type = PACKET_HOST;
+               local_skb->dev = dev;
++              skb_reset_mac_header(local_skb);
+               skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
+               if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) {
+-- 
+2.51.0
+
diff --git a/queue-6.1/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch b/queue-6.1/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
new file mode 100644 (file)
index 0000000..4c8b807
--- /dev/null
@@ -0,0 +1,65 @@
+From a3e0b8c4cc233e9faae9c2a0641705b68b08b3ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:28:41 -0500
+Subject: Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
+
+From: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+
+[ Upstream commit 23d22f2f71768034d6ef86168213843fc49bf550 ]
+
+There is a KASAN: slab-use-after-free read in btusb_disconnect().
+Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will
+free the btusb data associated with the interface. The same data is
+then used later in the function, hence the UAF.
+
+Fix by moving the accesses to btusb data to before the data is free'd.
+
+Reported-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2fc81b50a4f8263a159b
+Tested-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Fixes: fd913ef7ce619 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 29130160066a5..70cdcef684138 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4204,6 +4204,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+       hci_unregister_dev(hdev);
++      if (data->oob_wake_irq)
++              device_init_wakeup(&data->udev->dev, false);
++      if (data->reset_gpio)
++              gpiod_put(data->reset_gpio);
++
+       if (intf == data->intf) {
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
+@@ -4214,17 +4219,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+                       usb_driver_release_interface(&btusb_driver, data->diag);
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       } else if (intf == data->diag) {
+-              usb_driver_release_interface(&btusb_driver, data->intf);
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
++              usb_driver_release_interface(&btusb_driver, data->intf);
+       }
+-      if (data->oob_wake_irq)
+-              device_init_wakeup(&data->udev->dev, false);
+-
+-      if (data->reset_gpio)
+-              gpiod_put(data->reset_gpio);
+-
+       hci_free_dev(hdev);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.1/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch b/queue-6.1/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
new file mode 100644 (file)
index 0000000..b4f2706
--- /dev/null
@@ -0,0 +1,37 @@
+From 80c1d177b47316d89ea31b76394fa4401a3e43f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:48 +0200
+Subject: Bluetooth: L2CAP: export l2cap_chan_hold for modules
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit e060088db0bdf7932e0e3c2d24b7371c4c5b867c ]
+
+l2cap_chan_put() is exported, so export also l2cap_chan_hold() for
+modules.
+
+l2cap_chan_hold() has use case in net/bluetooth/6lowpan.c
+
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 8bb6d2690e2b9..ea82a468b314a 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -521,6 +521,7 @@ void l2cap_chan_hold(struct l2cap_chan *c)
+       kref_get(&c->kref);
+ }
++EXPORT_SYMBOL_GPL(l2cap_chan_hold);
+ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
+ {
+-- 
+2.51.0
+
diff --git a/queue-6.1/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch b/queue-6.1/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch
new file mode 100644 (file)
index 0000000..89d9f54
--- /dev/null
@@ -0,0 +1,56 @@
+From cb4f8ffc3eee952cab3c4f000317485fb6ea5ead Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Nov 2025 20:16:12 +0200
+Subject: Bluetooth: MGMT: cancel mesh send timer when hdev removed
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 55fb52ffdd62850d667ebed842815e072d3c9961 ]
+
+mesh_send_done timer is not canceled when hdev is removed, which causes
+crash if the timer triggers after hdev is gone.
+
+Cancel the timer when MGMT removes the hdev, like other MGMT timers.
+
+Should fix the BUG: sporadically seen by BlueZ test bot
+(in "Mesh - Send cancel - 1" test).
+
+Log:
+------
+BUG: KASAN: slab-use-after-free in run_timer_softirq+0x76b/0x7d0
+...
+Freed by task 36:
+ kasan_save_stack+0x24/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3a/0x60
+ __kasan_slab_free+0x43/0x70
+ kfree+0x103/0x500
+ device_release+0x9a/0x210
+ kobject_put+0x100/0x1e0
+ vhci_release+0x18b/0x240
+------
+
+Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh")
+Link: https://lore.kernel.org/linux-bluetooth/67364c09.0c0a0220.113cba.39ff@mx.google.com/
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 9bd4d5bc84db1..b89c3fc364b83 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9501,6 +9501,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
+       cancel_delayed_work_sync(&hdev->discov_off);
+       cancel_delayed_work_sync(&hdev->service_cache);
+       cancel_delayed_work_sync(&hdev->rpa_expired);
++      cancel_delayed_work_sync(&hdev->mesh_send_done);
+ }
+ void mgmt_power_on(struct hci_dev *hdev, int err)
+-- 
+2.51.0
+
diff --git a/queue-6.1/hsr-fix-supervision-frame-sending-on-hsrv0.patch b/queue-6.1/hsr-fix-supervision-frame-sending-on-hsrv0.patch
new file mode 100644 (file)
index 0000000..1ea1266
--- /dev/null
@@ -0,0 +1,50 @@
+From 5a34eaeca220b8e7ee2a3c715f0c99ecc4e13b8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:29:32 +0100
+Subject: hsr: Fix supervision frame sending on HSRv0
+
+From: Felix Maurer <fmaurer@redhat.com>
+
+[ Upstream commit 96a3a03abf3d8cc38cd9cb0d280235fbcf7c3f7f ]
+
+On HSRv0, no supervision frames were sent. The supervison frames were
+generated successfully, but failed the check for a sufficiently long mac
+header, i.e., at least sizeof(struct hsr_ethhdr), in hsr_fill_frame_info()
+because the mac header only contained the ethernet header.
+
+Fix this by including the HSR header in the mac header when generating HSR
+supervision frames. Note that the mac header now also includes the TLV
+fields. This matches how we set the headers on rx and also the size of
+struct hsrv0_ethhdr_sp.
+
+Reported-by: Hangbin Liu <liuhangbin@gmail.com>
+Closes: https://lore.kernel.org/netdev/aMONxDXkzBZZRfE5@fedora/
+Fixes: 9cfb5e7f0ded ("net: hsr: fix hsr_init_sk() vs network/transport headers.")
+Signed-off-by: Felix Maurer <fmaurer@redhat.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://patch.msgid.link/4354114fea9a642fe71f49aeeb6c6159d1d61840.1762876095.git.fmaurer@redhat.com
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 0b23d52b8d87a..81eaae4c19da1 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -313,6 +313,9 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       }
+       hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag));
++      skb_set_network_header(skb, ETH_HLEN + HSR_HLEN);
++      skb_reset_mac_len(skb);
++
+       set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf));
+       set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch b/queue-6.1/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
new file mode 100644 (file)
index 0000000..e106e05
--- /dev/null
@@ -0,0 +1,39 @@
+From f2259a4c9c4bf1d7703036dd2a88a1b7772b3c29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:14:21 +0800
+Subject: net: fec: correct rx_bytes statistic for the case SHIFT16 is set
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit ad17e7e92a7c52ce70bb764813fcf99464f96903 ]
+
+Two additional bytes in front of each frame received into the RX FIFO if
+SHIFT16 is set, so we need to subtract the extra two bytes from pkt_len
+to correct the statistic of rx_bytes.
+
+Fixes: 3ac72b7b63d5 ("net: fec: align IP header in hardware")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20251106021421.2096585-1-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index ca271d7a388b4..c8f897afb30a6 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1681,6 +1681,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               ndev->stats.rx_packets++;
+               pkt_len = fec16_to_cpu(bdp->cbd_datlen);
+               ndev->stats.rx_bytes += pkt_len;
++              if (fep->quirks & FEC_QUIRK_HAS_RACC)
++                      ndev->stats.rx_bytes -= 2;
+               index = fec_enet_get_bd_index(bdp, &rxq->bd);
+               page = rxq->rx_skb_info[index].page;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch b/queue-6.1/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
new file mode 100644 (file)
index 0000000..a7c928f
--- /dev/null
@@ -0,0 +1,45 @@
+From 372570c2edecc20a316a1107677840010f1ff178 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 07:49:22 +0100
+Subject: net: mdio: fix resource leak in mdiobus_register_device()
+
+From: Buday Csaba <buday.csaba@prolan.hu>
+
+[ Upstream commit e6ca8f533ed41129fcf052297718f417f021cc7d ]
+
+Fix a possible leak in mdiobus_register_device() when both a
+reset-gpio and a reset-controller are present.
+Clean up the already claimed reset-gpio, when the registration of
+the reset-controller fails, so when an error code is returned, the
+device retains its state before the registration attempt.
+
+Link: https://lore.kernel.org/all/20251106144603.39053c81@kernel.org/
+Fixes: 71dd6c0dff51 ("net: phy: add support for reset-controller")
+Signed-off-by: Buday Csaba <buday.csaba@prolan.hu>
+Link: https://patch.msgid.link/4b419377f8dd7d2f63f919d0f74a336c734f8fff.1762584481.git.buday.csaba@prolan.hu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mdio_bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index 7a2dce8d12433..726799b1e7faf 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -80,8 +80,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
+                       return err;
+               err = mdiobus_register_reset(mdiodev);
+-              if (err)
++              if (err) {
++                      gpiod_put(mdiodev->reset_gpio);
++                      mdiodev->reset_gpio = NULL;
+                       return err;
++              }
+               /* Assert the reset signal */
+               mdio_device_reset(mdiodev, 1);
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5-expose-shared-buffer-registers-bits-and-str.patch b/queue-6.1/net-mlx5-expose-shared-buffer-registers-bits-and-str.patch
new file mode 100644 (file)
index 0000000..dcb3c0f
--- /dev/null
@@ -0,0 +1,111 @@
+From 54ad4fc7e71950f760342ad99c028e73aa388ab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 18:00:17 +0200
+Subject: net/mlx5: Expose shared buffer registers bits and structs
+
+From: Maher Sanalla <msanalla@nvidia.com>
+
+[ Upstream commit 8d231dbc3b10155727bcfa9e543d397ad357f14f ]
+
+Add the shared receive buffer management and configuration registers:
+1. SBPR - Shared Buffer Pools Register
+2. SBCM - Shared Buffer Class Management Register
+
+Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mlx5/driver.h   |  2 ++
+ include/linux/mlx5/mlx5_ifc.h | 61 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+)
+
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index b05f69a8306c9..9af7180eac9e3 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -100,6 +100,8 @@ enum {
+ };
+ enum {
++      MLX5_REG_SBPR            = 0xb001,
++      MLX5_REG_SBCM            = 0xb002,
+       MLX5_REG_QPTS            = 0x4002,
+       MLX5_REG_QETCR           = 0x4005,
+       MLX5_REG_QTCT            = 0x400a,
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index 271c5a87751fe..4df7b3d358607 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -10930,6 +10930,67 @@ struct mlx5_ifc_pbmc_reg_bits {
+       u8         reserved_at_2e0[0x80];
+ };
++struct mlx5_ifc_sbpr_reg_bits {
++      u8         desc[0x1];
++      u8         snap[0x1];
++      u8         reserved_at_2[0x4];
++      u8         dir[0x2];
++      u8         reserved_at_8[0x14];
++      u8         pool[0x4];
++
++      u8         infi_size[0x1];
++      u8         reserved_at_21[0x7];
++      u8         size[0x18];
++
++      u8         reserved_at_40[0x1c];
++      u8         mode[0x4];
++
++      u8         reserved_at_60[0x8];
++      u8         buff_occupancy[0x18];
++
++      u8         clr[0x1];
++      u8         reserved_at_81[0x7];
++      u8         max_buff_occupancy[0x18];
++
++      u8         reserved_at_a0[0x8];
++      u8         ext_buff_occupancy[0x18];
++};
++
++struct mlx5_ifc_sbcm_reg_bits {
++      u8         desc[0x1];
++      u8         snap[0x1];
++      u8         reserved_at_2[0x6];
++      u8         local_port[0x8];
++      u8         pnat[0x2];
++      u8         pg_buff[0x6];
++      u8         reserved_at_18[0x6];
++      u8         dir[0x2];
++
++      u8         reserved_at_20[0x1f];
++      u8         exc[0x1];
++
++      u8         reserved_at_40[0x40];
++
++      u8         reserved_at_80[0x8];
++      u8         buff_occupancy[0x18];
++
++      u8         clr[0x1];
++      u8         reserved_at_a1[0x7];
++      u8         max_buff_occupancy[0x18];
++
++      u8         reserved_at_c0[0x8];
++      u8         min_buff[0x18];
++
++      u8         infi_max[0x1];
++      u8         reserved_at_e1[0x7];
++      u8         max_buff[0x18];
++
++      u8         reserved_at_100[0x20];
++
++      u8         reserved_at_120[0x1c];
++      u8         pool[0x4];
++};
++
+ struct mlx5_ifc_qtct_reg_bits {
+       u8         reserved_at_0[0x8];
+       u8         port_number[0x8];
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5e-add-api-to-query-modify-sbpr-and-sbcm-regi.patch b/queue-6.1/net-mlx5e-add-api-to-query-modify-sbpr-and-sbcm-regi.patch
new file mode 100644 (file)
index 0000000..9f21970
--- /dev/null
@@ -0,0 +1,126 @@
+From 24139235afbb4735298eb34296763a73d9d0e1c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 18:23:40 +0200
+Subject: net/mlx5e: Add API to query/modify SBPR and SBCM registers
+
+From: Maher Sanalla <msanalla@nvidia.com>
+
+[ Upstream commit 11f0996d5c6023f4889882c8d088ec76a050d704 ]
+
+To allow users to configure shared receive buffer parameters through
+dcbnl callbacks, expose an API to query and modify SBPR and SBCM registers,
+which will be used in the upcoming patch.
+
+Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en/port.c | 72 +++++++++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en/port.h |  6 ++
+ 2 files changed, 78 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
+index 89510cac46c22..505ba41195b93 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
+@@ -287,6 +287,78 @@ int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in)
+       return err;
+ }
++int mlx5e_port_query_sbpr(struct mlx5_core_dev *mdev, u32 desc, u8 dir,
++                        u8 pool_idx, void *out, int size_out)
++{
++      u32 in[MLX5_ST_SZ_DW(sbpr_reg)] = {};
++
++      MLX5_SET(sbpr_reg, in, desc, desc);
++      MLX5_SET(sbpr_reg, in, dir, dir);
++      MLX5_SET(sbpr_reg, in, pool, pool_idx);
++
++      return mlx5_core_access_reg(mdev, in, sizeof(in), out, size_out, MLX5_REG_SBPR, 0, 0);
++}
++
++int mlx5e_port_set_sbpr(struct mlx5_core_dev *mdev, u32 desc, u8 dir,
++                      u8 pool_idx, u32 infi_size, u32 size)
++{
++      u32 out[MLX5_ST_SZ_DW(sbpr_reg)] = {};
++      u32 in[MLX5_ST_SZ_DW(sbpr_reg)] = {};
++
++      MLX5_SET(sbpr_reg, in, desc, desc);
++      MLX5_SET(sbpr_reg, in, dir, dir);
++      MLX5_SET(sbpr_reg, in, pool, pool_idx);
++      MLX5_SET(sbpr_reg, in, infi_size, infi_size);
++      MLX5_SET(sbpr_reg, in, size, size);
++      MLX5_SET(sbpr_reg, in, mode, 1);
++
++      return mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), MLX5_REG_SBPR, 0, 1);
++}
++
++static int mlx5e_port_query_sbcm(struct mlx5_core_dev *mdev, u32 desc,
++                               u8 pg_buff_idx, u8 dir, void *out,
++                               int size_out)
++{
++      u32 in[MLX5_ST_SZ_DW(sbcm_reg)] = {};
++
++      MLX5_SET(sbcm_reg, in, desc, desc);
++      MLX5_SET(sbcm_reg, in, local_port, 1);
++      MLX5_SET(sbcm_reg, in, pg_buff, pg_buff_idx);
++      MLX5_SET(sbcm_reg, in, dir, dir);
++
++      return mlx5_core_access_reg(mdev, in, sizeof(in), out, size_out, MLX5_REG_SBCM, 0, 0);
++}
++
++int mlx5e_port_set_sbcm(struct mlx5_core_dev *mdev, u32 desc, u8 pg_buff_idx,
++                      u8 dir, u8 infi_size, u32 max_buff, u8 pool_idx)
++{
++      u32 out[MLX5_ST_SZ_DW(sbcm_reg)] = {};
++      u32 in[MLX5_ST_SZ_DW(sbcm_reg)] = {};
++      u32 min_buff;
++      int err;
++      u8 exc;
++
++      err = mlx5e_port_query_sbcm(mdev, desc, pg_buff_idx, dir, out,
++                                  sizeof(out));
++      if (err)
++              return err;
++
++      exc = MLX5_GET(sbcm_reg, out, exc);
++      min_buff = MLX5_GET(sbcm_reg, out, min_buff);
++
++      MLX5_SET(sbcm_reg, in, desc, desc);
++      MLX5_SET(sbcm_reg, in, local_port, 1);
++      MLX5_SET(sbcm_reg, in, pg_buff, pg_buff_idx);
++      MLX5_SET(sbcm_reg, in, dir, dir);
++      MLX5_SET(sbcm_reg, in, exc, exc);
++      MLX5_SET(sbcm_reg, in, min_buff, min_buff);
++      MLX5_SET(sbcm_reg, in, infi_max, infi_size);
++      MLX5_SET(sbcm_reg, in, max_buff, max_buff);
++      MLX5_SET(sbcm_reg, in, pool, pool_idx);
++
++      return mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), MLX5_REG_SBCM, 0, 1);
++}
++
+ /* buffer[i]: buffer that priority i mapped to */
+ int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
+ {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h
+index 7a7defe607926..3f474e370828d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h
+@@ -57,6 +57,12 @@ u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed,
+ bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev);
+ int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out);
+ int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in);
++int mlx5e_port_query_sbpr(struct mlx5_core_dev *mdev, u32 desc, u8 dir,
++                        u8 pool_idx, void *out, int size_out);
++int mlx5e_port_set_sbpr(struct mlx5_core_dev *mdev, u32 desc, u8 dir,
++                      u8 pool_idx, u32 infi_size, u32 size);
++int mlx5e_port_set_sbcm(struct mlx5_core_dev *mdev, u32 desc, u8 pg_buff_idx,
++                      u8 dir, u8 infi_size, u32 max_buff, u8 pool_idx);
+ int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
+ int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5e-consider-internal-buffers-size-in-port-buf.patch b/queue-6.1/net-mlx5e-consider-internal-buffers-size-in-port-buf.patch
new file mode 100644 (file)
index 0000000..9fe172b
--- /dev/null
@@ -0,0 +1,209 @@
+From c292ae93098bfd55c817b8fceeebcc029464d45f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 May 2023 17:31:40 +0300
+Subject: net/mlx5e: Consider internal buffers size in port buffer calculations
+
+From: Maher Sanalla <msanalla@nvidia.com>
+
+[ Upstream commit 81fe2be062915e2a2fdc494c3cd90e946e946c25 ]
+
+Currently, when a user triggers a change in port buffer headroom
+(buffers 0-7), the driver checks that the requested headroom does
+not exceed the total port buffer size. However, this check does not
+take into account the internal buffers (buffers 8-9), which are also
+part of the total port buffer. This can result in treating invalid port
+buffer change requests as valid, causing unintended changes to the shared
+buffer.
+
+To address this, include the internal buffers size in the calculation of
+available port buffer space which ensures that port buffer requests do not
+exceed the correct limit.
+
+Furthermore, remove internal buffers (8-9) size from the total_size
+calculation as these buffers are reserved for internal use and are not
+exposed to the user.
+
+While at it, add verbosity to the debug prints in
+mlx5e_port_query_buffer() function to ease future debugging.
+
+Fixes: ecdf2dadee8e ("net/mlx5e: Receive buffer support for DCBX")
+Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.c       | 42 ++++++++++++-------
+ .../mellanox/mlx5/core/en/port_buffer.h       |  8 ++--
+ .../ethernet/mellanox/mlx5/core/en_dcbnl.c    |  7 ++--
+ 3 files changed, 36 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index e846417a8ca94..b02cba086b366 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -51,7 +51,7 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+       if (err)
+               goto out;
+-      for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
++      for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
+               buffer = MLX5_ADDR_OF(pbmc_reg, out, buffer[i]);
+               port_buffer->buffer[i].lossy =
+                       MLX5_GET(bufferx_reg, buffer, lossy);
+@@ -73,14 +73,24 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                         port_buffer->buffer[i].lossy);
+       }
+-      port_buffer->headroom_size = total_used;
++      port_buffer->internal_buffers_size = 0;
++      for (i = MLX5E_MAX_NETWORK_BUFFER; i < MLX5E_TOTAL_BUFFERS; i++) {
++              buffer = MLX5_ADDR_OF(pbmc_reg, out, buffer[i]);
++              port_buffer->internal_buffers_size +=
++                      MLX5_GET(bufferx_reg, buffer, size) * port_buff_cell_sz;
++      }
++
+       port_buffer->port_buffer_size =
+               MLX5_GET(pbmc_reg, out, port_buffer_size) * port_buff_cell_sz;
+-      port_buffer->spare_buffer_size =
+-              port_buffer->port_buffer_size - total_used;
+-
+-      mlx5e_dbg(HW, priv, "total buffer size=%d, spare buffer size=%d\n",
+-                port_buffer->port_buffer_size,
++      port_buffer->headroom_size = total_used;
++      port_buffer->spare_buffer_size = port_buffer->port_buffer_size -
++                                       port_buffer->internal_buffers_size -
++                                       port_buffer->headroom_size;
++
++      mlx5e_dbg(HW, priv,
++                "total buffer size=%u, headroom buffer size=%u, internal buffers size=%u, spare buffer size=%u\n",
++                port_buffer->port_buffer_size, port_buffer->headroom_size,
++                port_buffer->internal_buffers_size,
+                 port_buffer->spare_buffer_size);
+ out:
+       kfree(out);
+@@ -206,11 +216,11 @@ static int port_update_pool_cfg(struct mlx5_core_dev *mdev,
+       if (!MLX5_CAP_GEN(mdev, sbcam_reg))
+               return 0;
+-      for (i = 0; i < MLX5E_MAX_BUFFER; i++)
++      for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++)
+               lossless_buff_count += ((port_buffer->buffer[i].size) &&
+                                      (!(port_buffer->buffer[i].lossy)));
+-      for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
++      for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
+               p = select_sbcm_params(&port_buffer->buffer[i], lossless_buff_count);
+               err = mlx5e_port_set_sbcm(mdev, 0, i,
+                                         MLX5_INGRESS_DIR,
+@@ -293,7 +303,7 @@ static int port_set_buffer(struct mlx5e_priv *priv,
+       if (err)
+               goto out;
+-      for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
++      for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
+               void *buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]);
+               u64 size = port_buffer->buffer[i].size;
+               u64 xoff = port_buffer->buffer[i].xoff;
+@@ -351,7 +361,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
+ {
+       int i;
+-      for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
++      for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
+               if (port_buffer->buffer[i].lossy) {
+                       port_buffer->buffer[i].xoff = 0;
+                       port_buffer->buffer[i].xon  = 0;
+@@ -408,7 +418,7 @@ static int update_buffer_lossy(struct mlx5_core_dev *mdev,
+       int err;
+       int i;
+-      for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
++      for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
+               prio_count = 0;
+               lossy_count = 0;
+@@ -515,7 +525,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+       if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) {
+               update_prio2buffer = true;
+-              for (i = 0; i < MLX5E_MAX_BUFFER; i++)
++              for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++)
+                       mlx5e_dbg(HW, priv, "%s: requested to map prio[%d] to buffer %d\n",
+                                 __func__, i, prio2buffer[i]);
+@@ -530,7 +540,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+       }
+       if (change & MLX5E_PORT_BUFFER_SIZE) {
+-              for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
++              for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
+                       mlx5e_dbg(HW, priv, "%s: buffer[%d]=%d\n", __func__, i, buffer_size[i]);
+                       if (!port_buffer.buffer[i].lossy && !buffer_size[i]) {
+                               mlx5e_dbg(HW, priv, "%s: lossless buffer[%d] size cannot be zero\n",
+@@ -544,7 +554,9 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+               mlx5e_dbg(HW, priv, "%s: total buffer requested=%d\n", __func__, total_used);
+-              if (total_used > port_buffer.port_buffer_size)
++              if (total_used > port_buffer.headroom_size &&
++                  (total_used - port_buffer.headroom_size) >
++                          port_buffer.spare_buffer_size)
+                       return -EINVAL;
+               update_buffer = true;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index a6ef118de758f..f4a19ffbb641c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -35,7 +35,8 @@
+ #include "en.h"
+ #include "port.h"
+-#define MLX5E_MAX_BUFFER 8
++#define MLX5E_MAX_NETWORK_BUFFER 8
++#define MLX5E_TOTAL_BUFFERS 10
+ #define MLX5E_DEFAULT_CABLE_LEN 7 /* 7 meters */
+ #define MLX5_BUFFER_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, pcam_reg) && \
+@@ -60,8 +61,9 @@ struct mlx5e_bufferx_reg {
+ struct mlx5e_port_buffer {
+       u32                       port_buffer_size;
+       u32                       spare_buffer_size;
+-      u32                       headroom_size;
+-      struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_BUFFER];
++      u32                       headroom_size;          /* Buffers 0-7 */
++      u32                       internal_buffers_size;  /* Buffers 8-9 */
++      struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_NETWORK_BUFFER];
+ };
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 2d20e2ff29677..55ceb6740291d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -935,9 +935,10 @@ static int mlx5e_dcbnl_getbuffer(struct net_device *dev,
+       if (err)
+               return err;
+-      for (i = 0; i < MLX5E_MAX_BUFFER; i++)
++      for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++)
+               dcb_buffer->buffer_size[i] = port_buffer.buffer[i].size;
+-      dcb_buffer->total_size = port_buffer.port_buffer_size;
++      dcb_buffer->total_size = port_buffer.port_buffer_size -
++                               port_buffer.internal_buffers_size;
+       return 0;
+ }
+@@ -979,7 +980,7 @@ static int mlx5e_dcbnl_setbuffer(struct net_device *dev,
+       if (err)
+               return err;
+-      for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
++      for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
+               if (port_buffer.buffer[i].size != dcb_buffer->buffer_size[i]) {
+                       changed |= MLX5E_PORT_BUFFER_SIZE;
+                       buffer_size = dcb_buffer->buffer_size;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch b/queue-6.1/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
new file mode 100644 (file)
index 0000000..3bd11d8
--- /dev/null
@@ -0,0 +1,58 @@
+From 43c6e05267a40a2d7bcfad00bc9769b49572a7e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:51 +0200
+Subject: net/mlx5e: Fix maxrate wraparound in threshold between units
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit a7bf4d5063c7837096aab2853224eb23628514d9 ]
+
+The previous calculation used roundup() which caused an overflow for
+rates between 25.5Gbps and 26Gbps.
+For example, a rate of 25.6Gbps would result in using 100Mbps units with
+value of 256, which would overflow the 8 bits field.
+
+Simplify the upper_limit_mbps calculation by removing the
+unnecessary roundup, and adjust the comparison to use <= to correctly
+handle the boundary condition.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 89de92d064836..cfbf39f0f8727 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -587,18 +587,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       struct mlx5_core_dev *mdev = priv->mdev;
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+-      __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
++      __u64 upper_limit_mbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
++      upper_limit_mbps = 255 * MLX5E_100MB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+                       max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
+                       continue;
+               }
+-              if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
++              if (maxrate->tc_maxrate[i] <= upper_limit_mbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5e-fix-potentially-misleading-debug-message.patch b/queue-6.1/net-mlx5e-fix-potentially-misleading-debug-message.patch
new file mode 100644 (file)
index 0000000..c453b14
--- /dev/null
@@ -0,0 +1,62 @@
+From fbb3fee62dfc56b8326a8b3a675a954443a2a579 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:53 +0200
+Subject: net/mlx5e: Fix potentially misleading debug message
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 9fcc2b6c10523f7e75db6387946c86fcf19dc97e ]
+
+Change the debug message to print the correct units instead of always
+assuming Gbps, as the value can be in either 100 Mbps or 1 Gbps units.
+
+Fixes: 5da8bc3effb6 ("net/mlx5e: DCBNL, Add debug messages log")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-6-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index ca096d8bcca60..29e633e6dd3f0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -590,6 +590,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       __u64 upper_limit_mbps;
+       __u64 upper_limit_gbps;
+       int i;
++      struct {
++              int scale;
++              const char *units_str;
++      } units[] = {
++              [MLX5_100_MBPS_UNIT] = {
++                      .scale = 100,
++                      .units_str = "Mbps",
++              },
++              [MLX5_GBPS_UNIT] = {
++                      .scale = 1,
++                      .units_str = "Gbps",
++              },
++      };
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+@@ -620,8 +633,9 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       }
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+-              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %d Gbps\n",
+-                         __func__, i, max_bw_value[i]);
++              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %u %s\n", __func__, i,
++                         max_bw_value[i] * units[max_bw_unit[i]].scale,
++                         units[max_bw_unit[i]].units_str);
+       }
+       return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch b/queue-6.1/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
new file mode 100644 (file)
index 0000000..80200be
--- /dev/null
@@ -0,0 +1,62 @@
+From 441f0a8a7dc86e36a288163858273422bd7ba3d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:52 +0200
+Subject: net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 43b27d1bd88a4bce34ec2437d103acfae9655f9e ]
+
+Add validation to reject rates exceeding 255 Gbps that would overflow
+the 8 bits max bandwidth field.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index cfbf39f0f8727..2d20e2ff29677 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -588,11 +588,13 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+       __u64 upper_limit_mbps;
++      __u64 upper_limit_gbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+       upper_limit_mbps = 255 * MLX5E_100MB;
++      upper_limit_gbps = 255 * MLX5E_1GB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+@@ -604,10 +606,16 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else {
++              } else if (max_bw_value[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
++              } else {
++                      netdev_err(netdev,
++                                 "tc_%d maxrate %llu Kbps exceeds limit %llu\n",
++                                 i, maxrate->tc_maxrate[i],
++                                 upper_limit_gbps);
++                      return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5e-remove-mlx5e_dbg-and-msglvl-support.patch b/queue-6.1/net-mlx5e-remove-mlx5e_dbg-and-msglvl-support.patch
new file mode 100644 (file)
index 0000000..75b6ae3
--- /dev/null
@@ -0,0 +1,321 @@
+From ff2411a9baa9cbaf9d6105c6464e78292c91f7f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Apr 2023 14:29:26 +0300
+Subject: net/mlx5e: Remove mlx5e_dbg() and msglvl support
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 559f4c32ebff40a25199b5178d58c9283ac5eb9c ]
+
+The msglvl support was implemented using the mlx5e_dbg() macro which is
+rarely used in the driver, and is not very useful when you can just use
+dynamic debug instead.
+Remove mlx5e_dbg() and convert its usages to netdev_dbg().
+
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h  | 10 -----
+ .../mellanox/mlx5/core/en/port_buffer.c       | 44 ++++++++++---------
+ .../net/ethernet/mellanox/mlx5/core/en_arfs.c |  8 ++--
+ .../ethernet/mellanox/mlx5/core/en_dcbnl.c    | 26 +++++------
+ .../ethernet/mellanox/mlx5/core/en_ethtool.c  | 18 ++------
+ .../net/ethernet/mellanox/mlx5/core/en_main.c |  5 +--
+ 6 files changed, 45 insertions(+), 66 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index 0ee456480a488..906bf327cdef8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -165,15 +165,6 @@ struct page_pool;
+ #define MLX5E_MAX_KLM_PER_WQE(mdev) \
+       MLX5E_KLM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * mlx5e_get_max_sq_aligned_wqebbs(mdev))
+-#define MLX5E_MSG_LEVEL                       NETIF_MSG_LINK
+-
+-#define mlx5e_dbg(mlevel, priv, format, ...)                    \
+-do {                                                            \
+-      if (NETIF_MSG_##mlevel & (priv)->msglevel)              \
+-              netdev_warn(priv->netdev, format,               \
+-                          ##__VA_ARGS__);                     \
+-} while (0)
+-
+ #define mlx5e_state_dereference(priv, p) \
+       rcu_dereference_protected((p), lockdep_is_held(&(priv)->state_lock))
+@@ -901,7 +892,6 @@ struct mlx5e_priv {
+ #endif
+       /* priv data path fields - end */
+-      u32                        msglevel;
+       unsigned long              state;
+       struct mutex               state_lock; /* Protects Interface state */
+       struct mlx5e_rq            drop_rq;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index b02cba086b366..9be06df2d6e82 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -65,12 +65,13 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                       MLX5_GET(bufferx_reg, buffer, xoff_threshold) * port_buff_cell_sz;
+               total_used += port_buffer->buffer[i].size;
+-              mlx5e_dbg(HW, priv, "buffer %d: size=%d, xon=%d, xoff=%d, epsb=%d, lossy=%d\n", i,
+-                        port_buffer->buffer[i].size,
+-                        port_buffer->buffer[i].xon,
+-                        port_buffer->buffer[i].xoff,
+-                        port_buffer->buffer[i].epsb,
+-                        port_buffer->buffer[i].lossy);
++              netdev_dbg(priv->netdev, "buffer %d: size=%d, xon=%d, xoff=%d, epsb=%d, lossy=%d\n",
++                         i,
++                         port_buffer->buffer[i].size,
++                         port_buffer->buffer[i].xon,
++                         port_buffer->buffer[i].xoff,
++                         port_buffer->buffer[i].epsb,
++                         port_buffer->buffer[i].lossy);
+       }
+       port_buffer->internal_buffers_size = 0;
+@@ -87,11 +88,11 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                                        port_buffer->internal_buffers_size -
+                                        port_buffer->headroom_size;
+-      mlx5e_dbg(HW, priv,
+-                "total buffer size=%u, headroom buffer size=%u, internal buffers size=%u, spare buffer size=%u\n",
+-                port_buffer->port_buffer_size, port_buffer->headroom_size,
+-                port_buffer->internal_buffers_size,
+-                port_buffer->spare_buffer_size);
++      netdev_dbg(priv->netdev,
++                 "total buffer size=%u, headroom buffer size=%u, internal buffers size=%u, spare buffer size=%u\n",
++                 port_buffer->port_buffer_size, port_buffer->headroom_size,
++                 port_buffer->internal_buffers_size,
++                 port_buffer->spare_buffer_size);
+ out:
+       kfree(out);
+       return err;
+@@ -352,7 +353,7 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu)
+       xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100;
+-      mlx5e_dbg(HW, priv, "%s: xoff=%d\n", __func__, xoff);
++      netdev_dbg(priv->netdev, "%s: xoff=%d\n", __func__, xoff);
+       return xoff;
+ }
+@@ -484,6 +485,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u8 *prio2buffer)
+ {
+       u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
++      struct net_device *netdev = priv->netdev;
+       struct mlx5e_port_buffer port_buffer;
+       u32 xoff = calculate_xoff(priv, mtu);
+       bool update_prio2buffer = false;
+@@ -495,7 +497,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+       int err;
+       int i;
+-      mlx5e_dbg(HW, priv, "%s: change=%x\n", __func__, change);
++      netdev_dbg(netdev, "%s: change=%x\n", __func__, change);
+       max_mtu = max_t(unsigned int, priv->netdev->max_mtu, MINIMUM_MAX_MTU);
+       err = mlx5e_port_query_buffer(priv, &port_buffer);
+@@ -510,8 +512,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+       }
+       if (change & MLX5E_PORT_BUFFER_PFC) {
+-              mlx5e_dbg(HW, priv, "%s: requested PFC per priority bitmask: 0x%x\n",
+-                        __func__, pfc->pfc_en);
++              netdev_dbg(netdev, "%s: requested PFC per priority bitmask: 0x%x\n",
++                         __func__, pfc->pfc_en);
+               err = mlx5e_port_query_priority2buffer(priv->mdev, buffer);
+               if (err)
+                       return err;
+@@ -526,8 +528,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+       if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) {
+               update_prio2buffer = true;
+               for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++)
+-                      mlx5e_dbg(HW, priv, "%s: requested to map prio[%d] to buffer %d\n",
+-                                __func__, i, prio2buffer[i]);
++                      netdev_dbg(priv->netdev, "%s: requested to map prio[%d] to buffer %d\n",
++                                 __func__, i, prio2buffer[i]);
+               err = fill_pfc_en(priv->mdev, &curr_pfc_en);
+               if (err)
+@@ -541,10 +543,10 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+       if (change & MLX5E_PORT_BUFFER_SIZE) {
+               for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
+-                      mlx5e_dbg(HW, priv, "%s: buffer[%d]=%d\n", __func__, i, buffer_size[i]);
++                      netdev_dbg(priv->netdev, "%s: buffer[%d]=%d\n", __func__, i, buffer_size[i]);
+                       if (!port_buffer.buffer[i].lossy && !buffer_size[i]) {
+-                              mlx5e_dbg(HW, priv, "%s: lossless buffer[%d] size cannot be zero\n",
+-                                        __func__, i);
++                              netdev_dbg(priv->netdev, "%s: lossless buffer[%d] size cannot be zero\n",
++                                         __func__, i);
+                               return -EINVAL;
+                       }
+@@ -552,7 +554,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                       total_used += buffer_size[i];
+               }
+-              mlx5e_dbg(HW, priv, "%s: total buffer requested=%d\n", __func__, total_used);
++              netdev_dbg(priv->netdev, "%s: total buffer requested=%d\n", __func__, total_used);
+               if (total_used > port_buffer.headroom_size &&
+                   (total_used - port_buffer.headroom_size) >
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
+index ad51edf553185..16fade5b2d7ea 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
+@@ -595,10 +595,10 @@ static struct mlx5_flow_handle *arfs_add_rule(struct mlx5e_priv *priv,
+       if (IS_ERR(rule)) {
+               err = PTR_ERR(rule);
+               priv->channel_stats[arfs_rule->rxq]->rq.arfs_err++;
+-              mlx5e_dbg(HW, priv,
+-                        "%s: add rule(filter id=%d, rq idx=%d, ip proto=0x%x) failed,err=%d\n",
+-                        __func__, arfs_rule->filter_id, arfs_rule->rxq,
+-                        tuple->ip_proto, err);
++              netdev_dbg(priv->netdev,
++                         "%s: add rule(filter id=%d, rq idx=%d, ip proto=0x%x) failed,err=%d\n",
++                         __func__, arfs_rule->filter_id, arfs_rule->rxq,
++                         tuple->ip_proto, err);
+       }
+ out:
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 55ceb6740291d..ca096d8bcca60 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -275,10 +275,10 @@ static int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets
+       memcpy(priv->dcbx.tc_tsa, ets->tc_tsa, sizeof(ets->tc_tsa));
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+-              mlx5e_dbg(HW, priv, "%s: prio_%d <=> tc_%d\n",
+-                        __func__, i, ets->prio_tc[i]);
+-              mlx5e_dbg(HW, priv, "%s: tc_%d <=> tx_bw_%d%%, group_%d\n",
+-                        __func__, i, tc_tx_bw[i], tc_group[i]);
++              netdev_dbg(priv->netdev, "%s: prio_%d <=> tc_%d\n",
++                         __func__, i, ets->prio_tc[i]);
++              netdev_dbg(priv->netdev, "%s: tc_%d <=> tx_bw_%d%%, group_%d\n",
++                         __func__, i, tc_tx_bw[i], tc_group[i]);
+       }
+       return err;
+@@ -399,9 +399,9 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
+       }
+       if (!ret) {
+-              mlx5e_dbg(HW, priv,
+-                        "%s: PFC per priority bit mask: 0x%x\n",
+-                        __func__, pfc->pfc_en);
++              netdev_dbg(dev,
++                         "%s: PFC per priority bit mask: 0x%x\n",
++                         __func__, pfc->pfc_en);
+       }
+       return ret;
+ }
+@@ -620,8 +620,8 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       }
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+-              mlx5e_dbg(HW, priv, "%s: tc_%d <=> max_bw %d Gbps\n",
+-                        __func__, i, max_bw_value[i]);
++              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %d Gbps\n",
++                         __func__, i, max_bw_value[i]);
+       }
+       return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
+@@ -649,10 +649,10 @@ static u8 mlx5e_dcbnl_setall(struct net_device *netdev)
+               ets.tc_rx_bw[i] = cee_cfg->pg_bw_pct[i];
+               ets.tc_tsa[i]   = IEEE_8021QAZ_TSA_ETS;
+               ets.prio_tc[i]  = cee_cfg->prio_to_pg_map[i];
+-              mlx5e_dbg(HW, priv,
+-                        "%s: Priority group %d: tx_bw %d, rx_bw %d, prio_tc %d\n",
+-                        __func__, i, ets.tc_tx_bw[i], ets.tc_rx_bw[i],
+-                        ets.prio_tc[i]);
++              netdev_dbg(netdev,
++                         "%s: Priority group %d: tx_bw %d, rx_bw %d, prio_tc %d\n",
++                         __func__, i, ets.tc_tx_bw[i], ets.tc_rx_bw[i],
++                         ets.prio_tc[i]);
+       }
+       err = mlx5e_dbcnl_validate_ets(netdev, &ets, true);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+index 8cb127a6fabfe..35f33feee4dec 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+@@ -1703,16 +1703,6 @@ static int mlx5e_set_fecparam(struct net_device *netdev,
+       return 0;
+ }
+-static u32 mlx5e_get_msglevel(struct net_device *dev)
+-{
+-      return ((struct mlx5e_priv *)netdev_priv(dev))->msglevel;
+-}
+-
+-static void mlx5e_set_msglevel(struct net_device *dev, u32 val)
+-{
+-      ((struct mlx5e_priv *)netdev_priv(dev))->msglevel = val;
+-}
+-
+ static int mlx5e_set_phys_id(struct net_device *dev,
+                            enum ethtool_phys_id_state state)
+ {
+@@ -1966,9 +1956,9 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val
+       if (err)
+               return err;
+-      mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n",
+-                MLX5E_GET_PFLAG(&priv->channels.params,
+-                                MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF");
++      netdev_dbg(priv->netdev, "MLX5E: RxCqeCmprss was turned %s\n",
++                 MLX5E_GET_PFLAG(&priv->channels.params,
++                                 MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF");
+       return 0;
+ }
+@@ -2450,8 +2440,6 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
+       .get_priv_flags    = mlx5e_get_priv_flags,
+       .set_priv_flags    = mlx5e_set_priv_flags,
+       .self_test         = mlx5e_self_test,
+-      .get_msglevel      = mlx5e_get_msglevel,
+-      .set_msglevel      = mlx5e_set_msglevel,
+       .get_fec_stats     = mlx5e_get_fec_stats,
+       .get_fecparam      = mlx5e_get_fecparam,
+       .set_fecparam      = mlx5e_set_fecparam,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 887d446354006..0c1f89196f6c1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -2339,7 +2339,7 @@ static int mlx5e_channel_stats_alloc(struct mlx5e_priv *priv, int ix, int cpu)
+       /* Asymmetric dynamic memory allocation.
+        * Freed in mlx5e_priv_arrays_free, not on channel closure.
+        */
+-      mlx5e_dbg(DRV, priv, "Creating channel stats %d\n", ix);
++      netdev_dbg(priv->netdev, "Creating channel stats %d\n", ix);
+       priv->channel_stats[ix] = kvzalloc_node(sizeof(**priv->channel_stats),
+                                               GFP_KERNEL, cpu_to_node(cpu));
+       if (!priv->channel_stats[ix])
+@@ -2714,7 +2714,7 @@ int mlx5e_update_tx_netdev_queues(struct mlx5e_priv *priv)
+       if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_PORT_TS))
+               num_txqs += ntc;
+-      mlx5e_dbg(DRV, priv, "Setting num_txqs %d\n", num_txqs);
++      netdev_dbg(priv->netdev, "Setting num_txqs %d\n", num_txqs);
+       err = netif_set_real_num_tx_queues(priv->netdev, num_txqs);
+       if (err)
+               netdev_warn(priv->netdev, "netif_set_real_num_tx_queues failed, %d\n", err);
+@@ -5515,7 +5515,6 @@ int mlx5e_priv_init(struct mlx5e_priv *priv,
+       /* priv init */
+       priv->mdev        = mdev;
+       priv->netdev      = netdev;
+-      priv->msglevel    = MLX5E_MSG_LEVEL;
+       priv->max_nch     = nch;
+       priv->max_opened_tc = 1;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5e-update-shared-buffer-along-with-device-buf.patch b/queue-6.1/net-mlx5e-update-shared-buffer-along-with-device-buf.patch
new file mode 100644 (file)
index 0000000..a86fdd0
--- /dev/null
@@ -0,0 +1,366 @@
+From 57e618b3d95f270b0bcb979ad2050aae4c9a6d7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 19:03:07 +0200
+Subject: net/mlx5e: Update shared buffer along with device buffer changes
+
+From: Maher Sanalla <msanalla@nvidia.com>
+
+[ Upstream commit a440030d8946bfe3fd44b6da685e33ffe0ecd1ff ]
+
+Currently, the user can modify device's receive buffer size, modify the
+mapping between QoS priority groups to buffers and change the buffer
+state to become lossy/lossless via pfc command.
+
+However, the shared receive buffer pool alignments, as a result of
+such commands, is performed only when the shared buffer is in FW ownership.
+When a user changes the mapping of priority groups or buffer size,
+the shared buffer is moved to SW ownership.
+
+Therefore, for devices that support shared buffer, handle the shared buffer
+alignments in accordance to user's desired configurations.
+
+Meaning, the following will be performed:
+1. For every change of buffer's headroom, recalculate the size of shared
+   buffer to be equal to "total_buffer_size" - "new_headroom_size".
+   The new shared buffer size will be split in ratio of 3:1 between
+   lossy and lossless pools, respectively.
+
+2. For each port buffer change, count the number of lossless buffers.
+   If there is only one lossless buffer, then set its lossless pool
+   usage threshold to be infinite. Otherwise, if there is more than
+   one lossless buffer, set a usage threshold for each lossless buffer.
+
+While at it, add more verbosity to debug prints when handling user
+commands, to assist in future debug.
+
+Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.c       | 222 +++++++++++++++++-
+ .../mellanox/mlx5/core/en/port_buffer.h       |   1 +
+ 2 files changed, 219 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index 7899a7230299d..e846417a8ca94 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -73,6 +73,7 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                         port_buffer->buffer[i].lossy);
+       }
++      port_buffer->headroom_size = total_used;
+       port_buffer->port_buffer_size =
+               MLX5_GET(pbmc_reg, out, port_buffer_size) * port_buff_cell_sz;
+       port_buffer->spare_buffer_size =
+@@ -86,16 +87,204 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+       return err;
+ }
++struct mlx5e_buffer_pool {
++      u32 infi_size;
++      u32 size;
++      u32 buff_occupancy;
++};
++
++static int mlx5e_port_query_pool(struct mlx5_core_dev *mdev,
++                               struct mlx5e_buffer_pool *buffer_pool,
++                               u32 desc, u8 dir, u8 pool_idx)
++{
++      u32 out[MLX5_ST_SZ_DW(sbpr_reg)] = {};
++      int err;
++
++      err = mlx5e_port_query_sbpr(mdev, desc, dir, pool_idx, out,
++                                  sizeof(out));
++      if (err)
++              return err;
++
++      buffer_pool->size = MLX5_GET(sbpr_reg, out, size);
++      buffer_pool->infi_size = MLX5_GET(sbpr_reg, out, infi_size);
++      buffer_pool->buff_occupancy = MLX5_GET(sbpr_reg, out, buff_occupancy);
++
++      return err;
++}
++
++enum {
++      MLX5_INGRESS_DIR = 0,
++      MLX5_EGRESS_DIR = 1,
++};
++
++enum {
++      MLX5_LOSSY_POOL = 0,
++      MLX5_LOSSLESS_POOL = 1,
++};
++
++/* No limit on usage of shared buffer pool (max_buff=0) */
++#define MLX5_SB_POOL_NO_THRESHOLD  0
++/* Shared buffer pool usage threshold when calculated
++ * dynamically in alpha units. alpha=13 is equivalent to
++ * HW_alpha of  [(1/128) * 2 ^ (alpha-1)] = 32, where HW_alpha
++ * equates to the following portion of the shared buffer pool:
++ * [32 / (1 + n * 32)] While *n* is the number of buffers
++ * that are using the shared buffer pool.
++ */
++#define MLX5_SB_POOL_THRESHOLD 13
++
++/* Shared buffer class management parameters */
++struct mlx5_sbcm_params {
++      u8 pool_idx;
++      u8 max_buff;
++      u8 infi_size;
++};
++
++static const struct mlx5_sbcm_params sbcm_default = {
++      .pool_idx = MLX5_LOSSY_POOL,
++      .max_buff = MLX5_SB_POOL_NO_THRESHOLD,
++      .infi_size = 0,
++};
++
++static const struct mlx5_sbcm_params sbcm_lossy = {
++      .pool_idx = MLX5_LOSSY_POOL,
++      .max_buff = MLX5_SB_POOL_NO_THRESHOLD,
++      .infi_size = 1,
++};
++
++static const struct mlx5_sbcm_params sbcm_lossless = {
++      .pool_idx = MLX5_LOSSLESS_POOL,
++      .max_buff = MLX5_SB_POOL_THRESHOLD,
++      .infi_size = 0,
++};
++
++static const struct mlx5_sbcm_params sbcm_lossless_no_threshold = {
++      .pool_idx = MLX5_LOSSLESS_POOL,
++      .max_buff = MLX5_SB_POOL_NO_THRESHOLD,
++      .infi_size = 1,
++};
++
++/**
++ * select_sbcm_params() - selects the shared buffer pool configuration
++ *
++ * @buffer: <input> port buffer to retrieve params of
++ * @lossless_buff_count: <input> number of lossless buffers in total
++ *
++ * The selection is based on the following rules:
++ * 1. If buffer size is 0, no shared buffer pool is used.
++ * 2. If buffer is lossy, use lossy shared buffer pool.
++ * 3. If there are more than 1 lossless buffers, use lossless shared buffer pool
++ *    with threshold.
++ * 4. If there is only 1 lossless buffer, use lossless shared buffer pool
++ *    without threshold.
++ *
++ * @return const struct mlx5_sbcm_params* selected values
++ */
++static const struct mlx5_sbcm_params *
++select_sbcm_params(struct mlx5e_bufferx_reg *buffer, u8 lossless_buff_count)
++{
++      if (buffer->size == 0)
++              return &sbcm_default;
++
++      if (buffer->lossy)
++              return &sbcm_lossy;
++
++      if (lossless_buff_count > 1)
++              return &sbcm_lossless;
++
++      return &sbcm_lossless_no_threshold;
++}
++
++static int port_update_pool_cfg(struct mlx5_core_dev *mdev,
++                              struct mlx5e_port_buffer *port_buffer)
++{
++      const struct mlx5_sbcm_params *p;
++      u8 lossless_buff_count = 0;
++      int err;
++      int i;
++
++      if (!MLX5_CAP_GEN(mdev, sbcam_reg))
++              return 0;
++
++      for (i = 0; i < MLX5E_MAX_BUFFER; i++)
++              lossless_buff_count += ((port_buffer->buffer[i].size) &&
++                                     (!(port_buffer->buffer[i].lossy)));
++
++      for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
++              p = select_sbcm_params(&port_buffer->buffer[i], lossless_buff_count);
++              err = mlx5e_port_set_sbcm(mdev, 0, i,
++                                        MLX5_INGRESS_DIR,
++                                        p->infi_size,
++                                        p->max_buff,
++                                        p->pool_idx);
++              if (err)
++                      return err;
++      }
++
++      return 0;
++}
++
++static int port_update_shared_buffer(struct mlx5_core_dev *mdev,
++                                   u32 current_headroom_size,
++                                   u32 new_headroom_size)
++{
++      struct mlx5e_buffer_pool lossless_ipool;
++      struct mlx5e_buffer_pool lossy_epool;
++      u32 lossless_ipool_size;
++      u32 shared_buffer_size;
++      u32 total_buffer_size;
++      u32 lossy_epool_size;
++      int err;
++
++      if (!MLX5_CAP_GEN(mdev, sbcam_reg))
++              return 0;
++
++      err = mlx5e_port_query_pool(mdev, &lossy_epool, 0, MLX5_EGRESS_DIR,
++                                  MLX5_LOSSY_POOL);
++      if (err)
++              return err;
++
++      err = mlx5e_port_query_pool(mdev, &lossless_ipool, 0, MLX5_INGRESS_DIR,
++                                  MLX5_LOSSLESS_POOL);
++      if (err)
++              return err;
++
++      total_buffer_size = current_headroom_size + lossy_epool.size +
++                          lossless_ipool.size;
++      shared_buffer_size = total_buffer_size - new_headroom_size;
++
++      if (shared_buffer_size < 4) {
++              pr_err("Requested port buffer is too large, not enough space left for shared buffer\n");
++              return -EINVAL;
++      }
++
++      /* Total shared buffer size is split in a ratio of 3:1 between
++       * lossy and lossless pools respectively.
++       */
++      lossy_epool_size = (shared_buffer_size / 4) * 3;
++      lossless_ipool_size = shared_buffer_size / 4;
++
++      mlx5e_port_set_sbpr(mdev, 0, MLX5_EGRESS_DIR, MLX5_LOSSY_POOL, 0,
++                          lossy_epool_size);
++      mlx5e_port_set_sbpr(mdev, 0, MLX5_INGRESS_DIR, MLX5_LOSSLESS_POOL, 0,
++                          lossless_ipool_size);
++      return 0;
++}
++
+ static int port_set_buffer(struct mlx5e_priv *priv,
+                          struct mlx5e_port_buffer *port_buffer)
+ {
+       u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
+       struct mlx5_core_dev *mdev = priv->mdev;
+       int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
++      u32 new_headroom_size = 0;
++      u32 current_headroom_size;
+       void *in;
+       int err;
+       int i;
++      current_headroom_size = port_buffer->headroom_size;
++
+       in = kzalloc(sz, GFP_KERNEL);
+       if (!in)
+               return -ENOMEM;
+@@ -110,6 +299,7 @@ static int port_set_buffer(struct mlx5e_priv *priv,
+               u64 xoff = port_buffer->buffer[i].xoff;
+               u64 xon = port_buffer->buffer[i].xon;
++              new_headroom_size += size;
+               do_div(size, port_buff_cell_sz);
+               do_div(xoff, port_buff_cell_sz);
+               do_div(xon, port_buff_cell_sz);
+@@ -119,6 +309,17 @@ static int port_set_buffer(struct mlx5e_priv *priv,
+               MLX5_SET(bufferx_reg, buffer, xon_threshold, xon);
+       }
++      new_headroom_size /= port_buff_cell_sz;
++      current_headroom_size /= port_buff_cell_sz;
++      err = port_update_shared_buffer(priv->mdev, current_headroom_size,
++                                      new_headroom_size);
++      if (err)
++              return err;
++
++      err = port_update_pool_cfg(priv->mdev, port_buffer);
++      if (err)
++              return err;
++
+       err = mlx5e_port_set_pbmc(mdev, in);
+ out:
+       kfree(in);
+@@ -174,6 +375,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
+ /**
+  *    update_buffer_lossy     - Update buffer configuration based on pfc
++ *    @mdev: port function core device
+  *    @max_mtu: netdev's max_mtu
+  *    @pfc_en: <input> current pfc configuration
+  *    @buffer: <input> current prio to buffer mapping
+@@ -192,7 +394,8 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
+  *    @return: 0 if no error,
+  *    sets change to true if buffer configuration was modified.
+  */
+-static int update_buffer_lossy(unsigned int max_mtu,
++static int update_buffer_lossy(struct mlx5_core_dev *mdev,
++                             unsigned int max_mtu,
+                              u8 pfc_en, u8 *buffer, u32 xoff, u16 port_buff_cell_sz,
+                              struct mlx5e_port_buffer *port_buffer,
+                              bool *change)
+@@ -229,6 +432,10 @@ static int update_buffer_lossy(unsigned int max_mtu,
+       }
+       if (changed) {
++              err = port_update_pool_cfg(mdev, port_buffer);
++              if (err)
++                      return err;
++
+               err = update_xoff_threshold(port_buffer, xoff, max_mtu, port_buff_cell_sz);
+               if (err)
+                       return err;
+@@ -293,23 +500,30 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+       }
+       if (change & MLX5E_PORT_BUFFER_PFC) {
++              mlx5e_dbg(HW, priv, "%s: requested PFC per priority bitmask: 0x%x\n",
++                        __func__, pfc->pfc_en);
+               err = mlx5e_port_query_priority2buffer(priv->mdev, buffer);
+               if (err)
+                       return err;
+-              err = update_buffer_lossy(max_mtu, pfc->pfc_en, buffer, xoff, port_buff_cell_sz,
+-                                        &port_buffer, &update_buffer);
++              err = update_buffer_lossy(priv->mdev, max_mtu, pfc->pfc_en, buffer, xoff,
++                                        port_buff_cell_sz, &port_buffer,
++                                        &update_buffer);
+               if (err)
+                       return err;
+       }
+       if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) {
+               update_prio2buffer = true;
++              for (i = 0; i < MLX5E_MAX_BUFFER; i++)
++                      mlx5e_dbg(HW, priv, "%s: requested to map prio[%d] to buffer %d\n",
++                                __func__, i, prio2buffer[i]);
++
+               err = fill_pfc_en(priv->mdev, &curr_pfc_en);
+               if (err)
+                       return err;
+-              err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer, xoff,
++              err = update_buffer_lossy(priv->mdev, max_mtu, curr_pfc_en, prio2buffer, xoff,
+                                         port_buff_cell_sz, &port_buffer, &update_buffer);
+               if (err)
+                       return err;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index 80af7a5ac6046..a6ef118de758f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -60,6 +60,7 @@ struct mlx5e_bufferx_reg {
+ struct mlx5e_port_buffer {
+       u32                       port_buffer_size;
+       u32                       spare_buffer_size;
++      u32                       headroom_size;
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_BUFFER];
+ };
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch b/queue-6.1/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
new file mode 100644 (file)
index 0000000..4a7ca90
--- /dev/null
@@ -0,0 +1,59 @@
+From 3bcc8c4640f768d6629d160dc7419778af0b5080 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:35 +0530
+Subject: net: sched: act_connmark: initialize struct tc_ife to fix kernel leak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit 62b656e43eaeae445a39cd8021a4f47065af4389 ]
+
+In tcf_connmark_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: 22a5dc0e5e3e ("net: sched: Introduce connmark action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-2-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_connmark.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 79cfe51a09e74..4d75d2ae0d8ce 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -190,13 +190,15 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+       const struct tcf_connmark_parms *parms;
+-      struct tc_connmark opt = {
+-              .index   = ci->tcf_index,
+-              .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+-      };
++      struct tc_connmark opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index   = ci->tcf_index;
++      opt.refcnt  = refcount_read(&ci->tcf_refcnt) - ref;
++      opt.bindcnt = atomic_read(&ci->tcf_bindcnt) - bind;
++
+       rcu_read_lock();
+       parms = rcu_dereference(ci->parms);
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-sched-act_connmark-transition-to-percpu-stats-an.patch b/queue-6.1/net-sched-act_connmark-transition-to-percpu-stats-an.patch
new file mode 100644 (file)
index 0000000..ed98cc1
--- /dev/null
@@ -0,0 +1,277 @@
+From 7d3f72250e8a70a87d043f1f35a70e2cb5dcacca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 18:15:32 -0300
+Subject: net/sched: act_connmark: transition to percpu stats and rcu
+
+From: Pedro Tammela <pctammela@mojatatu.com>
+
+[ Upstream commit 288864effe33885988d53faf7830b35cb9a84c7a ]
+
+The tc action act_connmark was using shared stats and taking the per
+action lock in the datapath. Improve it by using percpu stats and rcu.
+
+perf before:
+- 13.55% tcf_connmark_act
+   - 81.18% _raw_spin_lock
+       80.46% native_queued_spin_lock_slowpath
+
+perf after:
+- 2.85% tcf_connmark_act
+
+tdc results:
+1..15
+ok 1 2002 - Add valid connmark action with defaults
+ok 2 56a5 - Add valid connmark action with control pass
+ok 3 7c66 - Add valid connmark action with control drop
+ok 4 a913 - Add valid connmark action with control pipe
+ok 5 bdd8 - Add valid connmark action with control reclassify
+ok 6 b8be - Add valid connmark action with control continue
+ok 7 d8a6 - Add valid connmark action with control jump
+ok 8 aae8 - Add valid connmark action with zone argument
+ok 9 2f0b - Add valid connmark action with invalid zone argument
+ok 10 9305 - Add connmark action with unsupported argument
+ok 11 71ca - Add valid connmark action and replace it
+ok 12 5f8f - Add valid connmark action with cookie
+ok 13 c506 - Replace connmark with invalid goto chain control
+ok 14 6571 - Delete connmark action with valid index
+ok 15 3426 - Delete connmark action with invalid index
+
+Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tc_act/tc_connmark.h |   9 ++-
+ net/sched/act_connmark.c         | 107 ++++++++++++++++++++-----------
+ 2 files changed, 75 insertions(+), 41 deletions(-)
+
+diff --git a/include/net/tc_act/tc_connmark.h b/include/net/tc_act/tc_connmark.h
+index 1f4cb477bb5d6..e8dd77a967480 100644
+--- a/include/net/tc_act/tc_connmark.h
++++ b/include/net/tc_act/tc_connmark.h
+@@ -4,10 +4,15 @@
+ #include <net/act_api.h>
+-struct tcf_connmark_info {
+-      struct tc_action common;
++struct tcf_connmark_parms {
+       struct net *net;
+       u16 zone;
++      struct rcu_head rcu;
++};
++
++struct tcf_connmark_info {
++      struct tc_action common;
++      struct tcf_connmark_parms __rcu *parms;
+ };
+ #define to_connmark(a) ((struct tcf_connmark_info *)a)
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index d41002e4613ff..418d60435b9d4 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -34,13 +34,15 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+       struct nf_conntrack_tuple tuple;
+       enum ip_conntrack_info ctinfo;
+       struct tcf_connmark_info *ca = to_connmark(a);
++      struct tcf_connmark_parms *parms;
+       struct nf_conntrack_zone zone;
+       struct nf_conn *c;
+       int proto;
+-      spin_lock(&ca->tcf_lock);
+       tcf_lastuse_update(&ca->tcf_tm);
+-      bstats_update(&ca->tcf_bstats, skb);
++      tcf_action_update_bstats(&ca->common, skb);
++
++      parms = rcu_dereference_bh(ca->parms);
+       switch (skb_protocol(skb, true)) {
+       case htons(ETH_P_IP):
+@@ -62,31 +64,29 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+       c = nf_ct_get(skb, &ctinfo);
+       if (c) {
+               skb->mark = READ_ONCE(c->mark);
+-              /* using overlimits stats to count how many packets marked */
+-              ca->tcf_qstats.overlimits++;
+-              goto out;
++              goto count;
+       }
+-      if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
+-                             proto, ca->net, &tuple))
++      if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, parms->net,
++                             &tuple))
+               goto out;
+-      zone.id = ca->zone;
++      zone.id = parms->zone;
+       zone.dir = NF_CT_DEFAULT_ZONE_DIR;
+-      thash = nf_conntrack_find_get(ca->net, &zone, &tuple);
++      thash = nf_conntrack_find_get(parms->net, &zone, &tuple);
+       if (!thash)
+               goto out;
+       c = nf_ct_tuplehash_to_ctrack(thash);
+-      /* using overlimits stats to count how many packets marked */
+-      ca->tcf_qstats.overlimits++;
+       skb->mark = READ_ONCE(c->mark);
+       nf_ct_put(c);
++count:
++      /* using overlimits stats to count how many packets marked */
++      tcf_action_inc_overlimit_qstats(&ca->common);
+ out:
+-      spin_unlock(&ca->tcf_lock);
+-      return ca->tcf_action;
++      return READ_ONCE(ca->tcf_action);
+ }
+ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
+@@ -99,6 +99,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+                            struct netlink_ext_ack *extack)
+ {
+       struct tc_action_net *tn = net_generic(net, act_connmark_ops.net_id);
++      struct tcf_connmark_parms *nparms, *oparms;
+       struct nlattr *tb[TCA_CONNMARK_MAX + 1];
+       bool bind = flags & TCA_ACT_FLAGS_BIND;
+       struct tcf_chain *goto_ch = NULL;
+@@ -118,52 +119,66 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+       if (!tb[TCA_CONNMARK_PARMS])
+               return -EINVAL;
++      nparms = kzalloc(sizeof(*nparms), GFP_KERNEL);
++      if (!nparms)
++              return -ENOMEM;
++
+       parm = nla_data(tb[TCA_CONNMARK_PARMS]);
+       index = parm->index;
+       ret = tcf_idr_check_alloc(tn, &index, a, bind);
+       if (!ret) {
+-              ret = tcf_idr_create(tn, index, est, a,
+-                                   &act_connmark_ops, bind, false, flags);
++              ret = tcf_idr_create_from_flags(tn, index, est, a,
++                                              &act_connmark_ops, bind, flags);
+               if (ret) {
+                       tcf_idr_cleanup(tn, index);
+-                      return ret;
++                      err = ret;
++                      goto out_free;
+               }
+               ci = to_connmark(*a);
+-              err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch,
+-                                             extack);
+-              if (err < 0)
+-                      goto release_idr;
+-              tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+-              ci->net = net;
+-              ci->zone = parm->zone;
++
++              nparms->net = net;
++              nparms->zone = parm->zone;
+               ret = ACT_P_CREATED;
+       } else if (ret > 0) {
+               ci = to_connmark(*a);
+-              if (bind)
+-                      return 0;
+-              if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
+-                      tcf_idr_release(*a, bind);
+-                      return -EEXIST;
++              if (bind) {
++                      err = 0;
++                      goto out_free;
+               }
+-              err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch,
+-                                             extack);
+-              if (err < 0)
++              if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
++                      err = -EEXIST;
+                       goto release_idr;
+-              /* replacing action and zone */
+-              spin_lock_bh(&ci->tcf_lock);
+-              goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+-              ci->zone = parm->zone;
+-              spin_unlock_bh(&ci->tcf_lock);
+-              if (goto_ch)
+-                      tcf_chain_put_by_act(goto_ch);
++              }
++
++              nparms->net = rtnl_dereference(ci->parms)->net;
++              nparms->zone = parm->zone;
++
+               ret = 0;
+       }
++      err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
++      if (err < 0)
++              goto release_idr;
++
++      spin_lock_bh(&ci->tcf_lock);
++      goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
++      oparms = rcu_replace_pointer(ci->parms, nparms, lockdep_is_held(&ci->tcf_lock));
++      spin_unlock_bh(&ci->tcf_lock);
++
++      if (goto_ch)
++              tcf_chain_put_by_act(goto_ch);
++
++      if (oparms)
++              kfree_rcu(oparms, rcu);
++
+       return ret;
++
+ release_idr:
+       tcf_idr_release(*a, bind);
++out_free:
++      kfree(nparms);
+       return err;
+ }
+@@ -177,11 +192,14 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+               .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+               .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+       };
++      struct tcf_connmark_parms *parms;
+       struct tcf_t t;
+       spin_lock_bh(&ci->tcf_lock);
++      parms = rcu_dereference_protected(ci->parms, lockdep_is_held(&ci->tcf_lock));
++
+       opt.action = ci->tcf_action;
+-      opt.zone = ci->zone;
++      opt.zone = parms->zone;
+       if (nla_put(skb, TCA_CONNMARK_PARMS, sizeof(opt), &opt))
+               goto nla_put_failure;
+@@ -199,6 +217,16 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       return -1;
+ }
++static void tcf_connmark_cleanup(struct tc_action *a)
++{
++      struct tcf_connmark_info *ci = to_connmark(a);
++      struct tcf_connmark_parms *parms;
++
++      parms = rcu_dereference_protected(ci->parms, 1);
++      if (parms)
++              kfree_rcu(parms, rcu);
++}
++
+ static struct tc_action_ops act_connmark_ops = {
+       .kind           =       "connmark",
+       .id             =       TCA_ID_CONNMARK,
+@@ -206,6 +234,7 @@ static struct tc_action_ops act_connmark_ops = {
+       .act            =       tcf_connmark_act,
+       .dump           =       tcf_connmark_dump,
+       .init           =       tcf_connmark_init,
++      .cleanup        =       tcf_connmark_cleanup,
+       .size           =       sizeof(struct tcf_connmark_info),
+ };
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch b/queue-6.1/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
new file mode 100644 (file)
index 0000000..f2ca228
--- /dev/null
@@ -0,0 +1,70 @@
+From c32a656102ee5f3a64199ae3d9d5d76a188ac40d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:36 +0530
+Subject: net: sched: act_ife: initialize struct tc_ife to fix KMSAN
+ kernel-infoleak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit ce50039be49eea9b4cd8873ca6eccded1b4a130a ]
+
+Fix a KMSAN kernel-infoleak detected  by the syzbot .
+
+[net?] KMSAN: kernel-infoleak in __skb_datagram_iter
+
+In tcf_ife_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+This change silences the KMSAN report and prevents potential information
+leaks from the kernel memory.
+
+This fix has been tested and validated by syzbot. This patch closes the
+bug reported at the following syzkaller link and ensures no infoleak.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: ef6980b6becb ("introduce IFE action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-3-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ife.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index 41d63b33461dc..a4505b926a1e4 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -643,13 +643,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_ife_info *ife = to_ife(a);
+       struct tcf_ife_params *p;
+-      struct tc_ife opt = {
+-              .index = ife->tcf_index,
+-              .refcnt = refcount_read(&ife->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
+-      };
++      struct tc_ife opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index = ife->tcf_index,
++      opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref,
++      opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
++
+       spin_lock_bh(&ife->tcf_lock);
+       opt.action = ife->tcf_action;
+       p = rcu_dereference_protected(ife->params,
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-smc-fix-mismatch-between-clc-header-and-proposal.patch b/queue-6.1/net-smc-fix-mismatch-between-clc-header-and-proposal.patch
new file mode 100644 (file)
index 0000000..27580e5
--- /dev/null
@@ -0,0 +1,55 @@
+From 881a97329ee69be344506da71f64235665454c45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 10:40:29 +0800
+Subject: net/smc: fix mismatch between CLC header and proposal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit ec33f2e5a2d0dbbfd71435209aee812fdc9369b8 ]
+
+The current CLC proposal message construction uses a mix of
+`ini->smc_type_v1/v2` and `pclc_base->hdr.typev1/v2` to decide whether
+to include optional extensions (IPv6 prefix extension for v1, and v2
+extension). This leads to a critical inconsistency: when
+`smc_clc_prfx_set()` fails - for example, in IPv6-only environments with
+only link-local addresses, or when the local IP address and the outgoing
+interface’s network address are not in the same subnet.
+
+As a result, the proposal message is assembled using the stale
+`ini->smc_type_v1` value—causing the IPv6 prefix extension to be
+included even though the header indicates v1 is not supported.
+The peer then receives a malformed CLC proposal where the header type
+does not match the payload, and immediately resets the connection.
+
+The fix ensures consistency between the CLC header flags and the actual
+payload by synchronizing `ini->smc_type_v1` with `pclc_base->hdr.typev1`
+when prefix setup fails.
+
+Fixes: 8c3dca341aea ("net/smc: build and send V2 CLC proposal")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20251107024029.88753-1-alibuda@linux.alibaba.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/smc_clc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
+index 6ed77f02ceac0..4a9a7ecf973ca 100644
+--- a/net/smc/smc_clc.c
++++ b/net/smc/smc_clc.c
+@@ -862,6 +862,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
+                               return SMC_CLC_DECL_CNFERR;
+                       }
+                       pclc_base->hdr.typev1 = SMC_TYPE_N;
++                      ini->smc_type_v1 = SMC_TYPE_N;
+               } else {
+                       pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
+                       plen += sizeof(*pclc_prfx) +
+-- 
+2.51.0
+
diff --git a/queue-6.1/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch b/queue-6.1/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch
new file mode 100644 (file)
index 0000000..bcca045
--- /dev/null
@@ -0,0 +1,100 @@
+From 806c79ba861400e43810e973978c4cc37c150db1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jul 2025 09:01:54 +0000
+Subject: net_sched: act_connmark: use RCU in tcf_connmark_dump()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0d752877705c0252ef2726e4c63c5573f048951c ]
+
+Also storing tcf_action into struct tcf_connmark_parms
+makes sure there is no discrepancy in tcf_connmark_act().
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250709090204.797558-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tc_act/tc_connmark.h |  1 +
+ net/sched/act_connmark.c         | 18 ++++++++++--------
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/tc_act/tc_connmark.h b/include/net/tc_act/tc_connmark.h
+index e8dd77a967480..a5ce83f3eea4b 100644
+--- a/include/net/tc_act/tc_connmark.h
++++ b/include/net/tc_act/tc_connmark.h
+@@ -7,6 +7,7 @@
+ struct tcf_connmark_parms {
+       struct net *net;
+       u16 zone;
++      int action;
+       struct rcu_head rcu;
+ };
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 418d60435b9d4..79cfe51a09e74 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -86,7 +86,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+       /* using overlimits stats to count how many packets marked */
+       tcf_action_inc_overlimit_qstats(&ca->common);
+ out:
+-      return READ_ONCE(ca->tcf_action);
++      return parms->action;
+ }
+ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
+@@ -162,6 +162,8 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+       if (err < 0)
+               goto release_idr;
++      nparms->action = parm->action;
++
+       spin_lock_bh(&ci->tcf_lock);
+       goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+       oparms = rcu_replace_pointer(ci->parms, nparms, lockdep_is_held(&ci->tcf_lock));
+@@ -185,20 +187,20 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+                                   int bind, int ref)
+ {
++      const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+-      struct tcf_connmark_info *ci = to_connmark(a);
++      const struct tcf_connmark_parms *parms;
+       struct tc_connmark opt = {
+               .index   = ci->tcf_index,
+               .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+               .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+       };
+-      struct tcf_connmark_parms *parms;
+       struct tcf_t t;
+-      spin_lock_bh(&ci->tcf_lock);
+-      parms = rcu_dereference_protected(ci->parms, lockdep_is_held(&ci->tcf_lock));
++      rcu_read_lock();
++      parms = rcu_dereference(ci->parms);
+-      opt.action = ci->tcf_action;
++      opt.action = parms->action;
+       opt.zone = parms->zone;
+       if (nla_put(skb, TCA_CONNMARK_PARMS, sizeof(opt), &opt))
+               goto nla_put_failure;
+@@ -207,12 +209,12 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       if (nla_put_64bit(skb, TCA_CONNMARK_TM, sizeof(t), &t,
+                         TCA_CONNMARK_PAD))
+               goto nla_put_failure;
+-      spin_unlock_bh(&ci->tcf_lock);
++      rcu_read_unlock();
+       return skb->len;
+ nla_put_failure:
+-      spin_unlock_bh(&ci->tcf_lock);
++      rcu_read_unlock();
+       nlmsg_trim(skb, b);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.1/net_sched-limit-try_bulk_dequeue_skb-batches.patch b/queue-6.1/net_sched-limit-try_bulk_dequeue_skb-batches.patch
new file mode 100644 (file)
index 0000000..c0bc490
--- /dev/null
@@ -0,0 +1,143 @@
+From 5ad2f483fcc4cc8ba54ab9179dc1a87b4d0eff9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:12:15 +0000
+Subject: net_sched: limit try_bulk_dequeue_skb() batches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0345552a653ce5542affeb69ac5aa52177a5199b ]
+
+After commit 100dfa74cad9 ("inet: dev_queue_xmit() llist adoption")
+I started seeing many qdisc requeues on IDPF under high TX workload.
+
+$ tc -s qd sh dev eth1 handle 1: ; sleep 1; tc -s qd sh dev eth1 handle 1:
+qdisc mq 1: root
+ Sent 43534617319319 bytes 268186451819 pkt (dropped 0, overlimits 0 requeues 3532840114)
+ backlog 1056Kb 6675p requeues 3532840114
+qdisc mq 1: root
+ Sent 43554665866695 bytes 268309964788 pkt (dropped 0, overlimits 0 requeues 3537737653)
+ backlog 781164b 4822p requeues 3537737653
+
+This is caused by try_bulk_dequeue_skb() being only limited by BQL budget.
+
+perf record -C120-239 -e qdisc:qdisc_dequeue sleep 1 ; perf script
+...
+ netperf 75332 [146]  2711.138269: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1292 skbaddr=0xff378005a1e9f200
+ netperf 75332 [146]  2711.138953: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1213 skbaddr=0xff378004d607a500
+ netperf 75330 [144]  2711.139631: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1233 skbaddr=0xff3780046be20100
+ netperf 75333 [147]  2711.140356: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1093 skbaddr=0xff37800514845b00
+ netperf 75337 [151]  2711.141037: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1353 skbaddr=0xff37800460753300
+ netperf 75337 [151]  2711.141877: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1367 skbaddr=0xff378004e72c7b00
+ netperf 75330 [144]  2711.142643: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1202 skbaddr=0xff3780045bd60000
+...
+
+This is bad because :
+
+1) Large batches hold one victim cpu for a very long time.
+
+2) Driver often hit their own TX ring limit (all slots are used).
+
+3) We call dev_requeue_skb()
+
+4) Requeues are using a FIFO (q->gso_skb), breaking qdisc ability to
+   implement FQ or priority scheduling.
+
+5) dequeue_skb() gets packets from q->gso_skb one skb at a time
+   with no xmit_more support. This is causing many spinlock games
+   between the qdisc and the device driver.
+
+Requeues were supposed to be very rare, lets keep them this way.
+
+Limit batch sizes to /proc/sys/net/core/dev_weight (default 64) as
+__qdisc_run() was designed to use.
+
+Fixes: 5772e9a3463b ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/20251109161215.2574081-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_generic.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index b51af871a621c..1b51b3038b4bd 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -178,9 +178,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
+ static void try_bulk_dequeue_skb(struct Qdisc *q,
+                                struct sk_buff *skb,
+                                const struct netdev_queue *txq,
+-                               int *packets)
++                               int *packets, int budget)
+ {
+       int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
++      int cnt = 0;
+       while (bytelimit > 0) {
+               struct sk_buff *nskb = q->dequeue(q);
+@@ -191,8 +192,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
+               bytelimit -= nskb->len; /* covers GSO len */
+               skb->next = nskb;
+               skb = nskb;
+-              (*packets)++; /* GSO counts as one pkt */
++              if (++cnt >= budget)
++                      break;
+       }
++      (*packets) += cnt;
+       skb_mark_not_on_list(skb);
+ }
+@@ -226,7 +229,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
+  * A requeued skb (via q->gso_skb) can also be a SKB list.
+  */
+ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+-                                 int *packets)
++                                 int *packets, int budget)
+ {
+       const struct netdev_queue *txq = q->dev_queue;
+       struct sk_buff *skb = NULL;
+@@ -293,7 +296,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+       if (skb) {
+ bulk:
+               if (qdisc_may_bulk(q))
+-                      try_bulk_dequeue_skb(q, skb, txq, packets);
++                      try_bulk_dequeue_skb(q, skb, txq, packets, budget);
+               else
+                       try_bulk_dequeue_skb_slow(q, skb, packets);
+       }
+@@ -385,7 +388,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+  *                            >0 - queue is not empty.
+  *
+  */
+-static inline bool qdisc_restart(struct Qdisc *q, int *packets)
++static inline bool qdisc_restart(struct Qdisc *q, int *packets, int budget)
+ {
+       spinlock_t *root_lock = NULL;
+       struct netdev_queue *txq;
+@@ -394,7 +397,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
+       bool validate;
+       /* Dequeue packet */
+-      skb = dequeue_skb(q, &validate, packets);
++      skb = dequeue_skb(q, &validate, packets, budget);
+       if (unlikely(!skb))
+               return false;
+@@ -412,7 +415,7 @@ void __qdisc_run(struct Qdisc *q)
+       int quota = READ_ONCE(dev_tx_weight);
+       int packets;
+-      while (qdisc_restart(q, &packets)) {
++      while (qdisc_restart(q, &packets, quota)) {
+               quota -= packets;
+               if (quota <= 0) {
+                       if (q->flags & TCQ_F_NOLOCK)
+-- 
+2.51.0
+
diff --git a/queue-6.1/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch b/queue-6.1/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
new file mode 100644 (file)
index 0000000..b265164
--- /dev/null
@@ -0,0 +1,86 @@
+From 615699f91654db03dea388c9b9a287314e0efe4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 11:10:54 +0000
+Subject: sctp: prevent possible shift-out-of-bounds in
+ sctp_transport_update_rto
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 1534ff77757e44bcc4b98d0196bc5c0052fce5fa ]
+
+syzbot reported a possible shift-out-of-bounds [1]
+
+Blamed commit added rto_alpha_max and rto_beta_max set to 1000.
+
+It is unclear if some sctp users are setting very large rto_alpha
+and/or rto_beta.
+
+In order to prevent user regression, perform the test at run time.
+
+Also add READ_ONCE() annotations as sysctl values can change under us.
+
+[1]
+
+UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41
+shift exponent 64 is too large for 32-bit type 'unsigned int'
+CPU: 0 UID: 0 PID: 16704 Comm: syz.2.2320 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:94 [inline]
+  dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120
+  ubsan_epilogue lib/ubsan.c:233 [inline]
+  __ubsan_handle_shift_out_of_bounds+0x27f/0x420 lib/ubsan.c:494
+  sctp_transport_update_rto.cold+0x1c/0x34b net/sctp/transport.c:509
+  sctp_check_transmitted+0x11c4/0x1c30 net/sctp/outqueue.c:1502
+  sctp_outq_sack+0x4ef/0x1b20 net/sctp/outqueue.c:1338
+  sctp_cmd_process_sack net/sctp/sm_sideeffect.c:840 [inline]
+  sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1372 [inline]
+
+Fixes: b58537a1f562 ("net: sctp: fix permissions for rto_alpha and rto_beta knobs")
+Reported-by: syzbot+f8c46c8b2b7f6e076e99@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c81ae.050a0220.3d0d33.014e.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20251106111054.3288127-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/transport.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 87ed33b9db1b3..52c872839f234 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -495,6 +495,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+       if (tp->rttvar || tp->srtt) {
+               struct net *net = tp->asoc->base.net;
++              unsigned int rto_beta, rto_alpha;
+               /* 6.3.1 C3) When a new RTT measurement R' is made, set
+                * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+                * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+@@ -506,10 +507,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+                * For example, assuming the default value of RTO.Alpha of
+                * 1/8, rto_alpha would be expressed as 3.
+                */
+-              tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
+-                      + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
+-              tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
+-                      + (rtt >> net->sctp.rto_alpha);
++              rto_beta = READ_ONCE(net->sctp.rto_beta);
++              if (rto_beta < 32)
++                      tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta)
++                              + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> rto_beta);
++              rto_alpha = READ_ONCE(net->sctp.rto_alpha);
++              if (rto_alpha < 32)
++                      tp->srtt = tp->srtt - (tp->srtt >> rto_alpha)
++                              + (rtt >> rto_alpha);
+       } else {
+               /* 6.3.1 C2) When the first RTT measurement R is made, set
+                * SRTT <- R, RTTVAR <- R/2.
+-- 
+2.51.0
+
diff --git a/queue-6.1/selftests-net-local_termination-wait-for-interfaces-.patch b/queue-6.1/selftests-net-local_termination-wait-for-interfaces-.patch
new file mode 100644 (file)
index 0000000..a81c7bf
--- /dev/null
@@ -0,0 +1,48 @@
+From a8287bda2b52e26d166d160fcf7bd501c41ae83f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 17:12:09 +0100
+Subject: selftests: net: local_termination: Wait for interfaces to come up
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+[ Upstream commit 57531b3416448d1ced36a2a974a4085ec43d57b0 ]
+
+It seems that most of the tests prepare the interfaces once before the test
+run (setup_prepare()), rely on setup_wait() to wait for link and only then
+run the test(s).
+
+local_termination brings the physical interfaces down and up during test
+run but never wait for them to come up. If the auto-negotiation takes
+some seconds, first test packets are being lost, which leads to
+false-negative test results.
+
+Use setup_wait() in run_test() to make sure auto-negotiation has been
+completed after all simple_if_init() calls on physical interfaces and test
+packets will not be lost because of the race against link establishment.
+
+Fixes: 90b9566aa5cd3f ("selftests: forwarding: add a test for local_termination.sh")
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Link: https://patch.msgid.link/20251106161213.459501-1-alexander.sverdlin@siemens.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/local_termination.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/selftests/net/forwarding/local_termination.sh b/tools/testing/selftests/net/forwarding/local_termination.sh
+index 9b5a63519b949..6cde61f10fd0e 100755
+--- a/tools/testing/selftests/net/forwarding/local_termination.sh
++++ b/tools/testing/selftests/net/forwarding/local_termination.sh
+@@ -108,6 +108,8 @@ run_test()
+       local smac=$(mac_get $h1)
+       local rcv_dmac=$(mac_get $rcv_if_name)
++      setup_wait
++
+       tcpdump_start $rcv_if_name
+       mc_route_prepare $h1
+-- 
+2.51.0
+
index a0ee287aff098ec831a1ab4859e507358a37067c..9de249505555de2d06dc8166807f580e5914e66b 100644 (file)
@@ -345,3 +345,36 @@ nfs-check-if-suid-sgid-was-cleared-after-a-write-as-.patch
 smb-server-fix-possible-memory-leak-in-smb2_read.patch
 smb-server-fix-possible-refcount-leak-in-smb2_sess_s.patch
 asoc-max98090-91-fixed-max98091-alsa-widget-powering.patch
+wifi-ath11k-add-tx-ack-signal-support-for-management.patch
+wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch
+selftests-net-local_termination-wait-for-interfaces-.patch
+net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
+bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch
+bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
+bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
+bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
+bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
+sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
+net-smc-fix-mismatch-between-clc-header-and-proposal.patch
+tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
+net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
+wifi-mac80211-skip-rate-verification-for-not-capture.patch
+af_unix-initialise-scc_index-in-unix_add_edge.patch
+net-sched-act_connmark-transition-to-percpu-stats-an.patch
+net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch
+net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
+net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
+net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
+net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
+net-mlx5-expose-shared-buffer-registers-bits-and-str.patch
+net-mlx5e-add-api-to-query-modify-sbpr-and-sbcm-regi.patch
+net-mlx5e-update-shared-buffer-along-with-device-buf.patch
+net-mlx5e-consider-internal-buffers-size-in-port-buf.patch
+net-mlx5e-remove-mlx5e_dbg-and-msglvl-support.patch
+net-mlx5e-fix-potentially-misleading-debug-message.patch
+net_sched-limit-try_bulk_dequeue_skb-batches.patch
+hsr-fix-supervision-frame-sending-on-hsrv0.patch
+acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch
+acpi-cppc-perform-fast-check-switch-only-for-online-.patch
+acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch
+bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
diff --git a/queue-6.1/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch b/queue-6.1/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
new file mode 100644 (file)
index 0000000..9fa6214
--- /dev/null
@@ -0,0 +1,150 @@
+From 9d1ab7806693502d7bdf1e0893b2421ac3fb087d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 06:40:25 +0000
+Subject: tipc: Fix use-after-free in tipc_mon_reinit_self().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 0725e6afb55128be21a2ca36e9674f573ccec173 ]
+
+syzbot reported use-after-free of tipc_net(net)->monitors[]
+in tipc_mon_reinit_self(). [0]
+
+The array is protected by RTNL, but tipc_mon_reinit_self()
+iterates over it without RTNL.
+
+tipc_mon_reinit_self() is called from tipc_net_finalize(),
+which is always under RTNL except for tipc_net_finalize_work().
+
+Let's hold RTNL in tipc_net_finalize_work().
+
+[0]:
+BUG: KASAN: slab-use-after-free in __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+Read of size 1 at addr ffff88805eae1030 by task kworker/0:7/5989
+
+CPU: 0 UID: 0 PID: 5989 Comm: kworker/0:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
+Workqueue: events tipc_net_finalize_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xca/0x240 mm/kasan/report.c:482
+ kasan_report+0x118/0x150 mm/kasan/report.c:595
+ __kasan_check_byte+0x2a/0x40 mm/kasan/common.c:568
+ kasan_check_byte include/linux/kasan.h:399 [inline]
+ lock_acquire+0x8d/0x360 kernel/locking/lockdep.c:5842
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+ rtlock_slowlock kernel/locking/rtmutex.c:1894 [inline]
+ rwbase_rtmutex_lock_state kernel/locking/spinlock_rt.c:160 [inline]
+ rwbase_write_lock+0xd3/0x7e0 kernel/locking/rwbase_rt.c:244
+ rt_write_lock+0x76/0x110 kernel/locking/spinlock_rt.c:243
+ write_lock_bh include/linux/rwlock_rt.h:99 [inline]
+ tipc_mon_reinit_self+0x79/0x430 net/tipc/monitor.c:718
+ tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
+ process_one_work kernel/workqueue.c:3236 [inline]
+ process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3319
+ worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
+ kthread+0x70e/0x8a0 kernel/kthread.c:463
+ ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+Allocated by task 6089:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __kmalloc_cache_noprof+0x1a8/0x320 mm/slub.c:4407
+ kmalloc_noprof include/linux/slab.h:905 [inline]
+ kzalloc_noprof include/linux/slab.h:1039 [inline]
+ tipc_mon_create+0xc3/0x4d0 net/tipc/monitor.c:657
+ tipc_enable_bearer net/tipc/bearer.c:357 [inline]
+ __tipc_nl_bearer_enable+0xe16/0x13f0 net/tipc/bearer.c:1047
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:371 [inline]
+ tipc_nl_compat_doit+0x3bc/0x5f0 net/tipc/netlink_compat.c:393
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:-1 [inline]
+ tipc_nl_compat_recv+0x83c/0xbe0 net/tipc/netlink_compat.c:1321
+ genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
+ netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
+ netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:729
+ ____sys_sendmsg+0x508/0x820 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 6088:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
+ poison_slab_object mm/kasan/common.c:243 [inline]
+ __kasan_slab_free+0x5b/0x80 mm/kasan/common.c:275
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2422 [inline]
+ slab_free mm/slub.c:4695 [inline]
+ kfree+0x195/0x550 mm/slub.c:4894
+ tipc_l2_device_event+0x380/0x650 net/tipc/bearer.c:-1
+ notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
+ call_netdevice_notifiers_extack net/core/dev.c:2267 [inline]
+ call_netdevice_notifiers net/core/dev.c:2281 [inline]
+ unregister_netdevice_many_notify+0x14d7/0x1fe0 net/core/dev.c:12166
+ unregister_netdevice_many net/core/dev.c:12229 [inline]
+ unregister_netdevice_queue+0x33c/0x380 net/core/dev.c:12073
+ unregister_netdevice include/linux/netdevice.h:3385 [inline]
+ __tun_detach+0xe4d/0x1620 drivers/net/tun.c:621
+ tun_detach drivers/net/tun.c:637 [inline]
+ tun_chr_close+0x10d/0x1c0 drivers/net/tun.c:3433
+ __fput+0x458/0xa80 fs/file_table.c:468
+ task_work_run+0x1d4/0x260 kernel/task_work.c:227
+ resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
+ exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:43
+ exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
+ syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline]
+ syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline]
+ do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 46cb01eeeb86 ("tipc: update mon's self addr when node addr generated")
+Reported-by: syzbot+d7dad7fd4b3921104957@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c323a.050a0220.baf87.007f.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251107064038.2361188-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/net.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/tipc/net.c b/net/tipc/net.c
+index 0e95572e56b41..7e65d0b0c4a8d 100644
+--- a/net/tipc/net.c
++++ b/net/tipc/net.c
+@@ -145,7 +145,9 @@ void tipc_net_finalize_work(struct work_struct *work)
+ {
+       struct tipc_net *tn = container_of(work, struct tipc_net, work);
++      rtnl_lock();
+       tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
++      rtnl_unlock();
+ }
+ void tipc_net_stop(struct net *net)
+-- 
+2.51.0
+
diff --git a/queue-6.1/wifi-ath11k-add-tx-ack-signal-support-for-management.patch b/queue-6.1/wifi-ath11k-add-tx-ack-signal-support-for-management.patch
new file mode 100644 (file)
index 0000000..4163b3f
--- /dev/null
@@ -0,0 +1,166 @@
+From abb915cca28fff68f221e845a58e4258d11ca749 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Dec 2022 11:08:44 +0530
+Subject: wifi: ath11k: Add tx ack signal support for management packets
+
+From: Abinaya Kalaiselvan <quic_akalaise@quicinc.com>
+
+[ Upstream commit 01c6c9fccbd51c1d9eab0f5794b0271b026178df ]
+
+Add support to notify tx ack signal values for management
+packets to userspace through nl80211 interface.
+
+Advertise NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT flag
+to enable this feature and it will be used for data
+packets as well.
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Abinaya Kalaiselvan <quic_akalaise@quicinc.com>
+Signed-off-by: Maharaja Kennadyrajan <quic_mkenna@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20221219053844.4084486-1-quic_mkenna@quicinc.com
+Stable-dep-of: 9065b9687523 ("wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/hw.c  |  1 +
+ drivers/net/wireless/ath/ath11k/mac.c |  5 +++++
+ drivers/net/wireless/ath/ath11k/wmi.c | 27 ++++++++++++++++-----------
+ drivers/net/wireless/ath/ath11k/wmi.h |  3 +++
+ 4 files changed, 25 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c
+index dbcc0c4035b62..332664643c7b4 100644
+--- a/drivers/net/wireless/ath/ath11k/hw.c
++++ b/drivers/net/wireless/ath/ath11k/hw.c
+@@ -201,6 +201,7 @@ static void ath11k_init_wmi_config_ipq8074(struct ath11k_base *ab,
+       config->twt_ap_pdev_count = ab->num_radios;
+       config->twt_ap_sta_count = 1000;
+       config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64;
++      config->flag1 |= WMI_RSRC_CFG_FLAG1_ACK_RSSI;
+ }
+ static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw,
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 8be42227dd943..4cab480f85a8d 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -9045,6 +9045,11 @@ static int __ath11k_mac_register(struct ath11k *ar)
+               goto err_free_if_combs;
+       }
++      if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI,
++                   ar->ab->wmi_ab.svc_map))
++              wiphy_ext_feature_set(ar->hw->wiphy,
++                                    NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
++
+       ar->hw->queues = ATH11K_HW_MAX_QUEUES;
+       ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN;
+       ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1;
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 38756ed48082c..1b58979bdfdc6 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -5221,8 +5221,8 @@ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
+       return 0;
+ }
+-static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id,
+-                                  u32 status)
++static int wmi_process_mgmt_tx_comp(struct ath11k *ar,
++                                  struct wmi_mgmt_tx_compl_event *tx_compl_param)
+ {
+       struct sk_buff *msdu;
+       struct ieee80211_tx_info *info;
+@@ -5230,24 +5230,29 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id,
+       int num_mgmt;
+       spin_lock_bh(&ar->txmgmt_idr_lock);
+-      msdu = idr_find(&ar->txmgmt_idr, desc_id);
++      msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id);
+       if (!msdu) {
+               ath11k_warn(ar->ab, "received mgmt tx compl for invalid msdu_id: %d\n",
+-                          desc_id);
++                          tx_compl_param->desc_id);
+               spin_unlock_bh(&ar->txmgmt_idr_lock);
+               return -ENOENT;
+       }
+-      idr_remove(&ar->txmgmt_idr, desc_id);
++      idr_remove(&ar->txmgmt_idr, tx_compl_param->desc_id);
+       spin_unlock_bh(&ar->txmgmt_idr_lock);
+       skb_cb = ATH11K_SKB_CB(msdu);
+       dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+       info = IEEE80211_SKB_CB(msdu);
+-      if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !status)
++      if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) &&
++          !tx_compl_param->status) {
+               info->flags |= IEEE80211_TX_STAT_ACK;
++              if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI,
++                           ar->ab->wmi_ab.svc_map))
++                      info->status.ack_signal = tx_compl_param->ack_rssi;
++      }
+       ieee80211_tx_status_irqsafe(ar->hw, msdu);
+@@ -5259,7 +5264,7 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id,
+       ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+                  "wmi mgmt tx comp pending %d desc id %d\n",
+-                 num_mgmt, desc_id);
++                 num_mgmt, tx_compl_param->desc_id);
+       if (!num_mgmt)
+               wake_up(&ar->txmgmt_empty_waitq);
+@@ -5292,6 +5297,7 @@ static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab,
+       param->pdev_id = ev->pdev_id;
+       param->desc_id = ev->desc_id;
+       param->status = ev->status;
++      param->ack_rssi = ev->ack_rssi;
+       kfree(tb);
+       return 0;
+@@ -7062,13 +7068,12 @@ static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *s
+               goto exit;
+       }
+-      wmi_process_mgmt_tx_comp(ar, tx_compl_param.desc_id,
+-                               tx_compl_param.status);
++      wmi_process_mgmt_tx_comp(ar, &tx_compl_param);
+       ath11k_dbg(ab, ATH11K_DBG_MGMT,
+-                 "mgmt tx compl ev pdev_id %d, desc_id %d, status %d",
++                 "mgmt tx compl ev pdev_id %d, desc_id %d, status %d ack_rssi %d",
+                  tx_compl_param.pdev_id, tx_compl_param.desc_id,
+-                 tx_compl_param.status);
++                 tx_compl_param.status, tx_compl_param.ack_rssi);
+ exit:
+       rcu_read_unlock();
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
+index 8f2c07d70a4a2..31d14e15ebc1d 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.h
++++ b/drivers/net/wireless/ath/ath11k/wmi.h
+@@ -2309,6 +2309,7 @@ struct wmi_init_cmd {
+ } __packed;
+ #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
++#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
+ struct wmi_resource_config {
+       u32 tlv_header;
+@@ -4541,6 +4542,8 @@ struct wmi_mgmt_tx_compl_event {
+       u32 desc_id;
+       u32 status;
+       u32 pdev_id;
++      u32 ppdu_id;
++      u32 ack_rssi;
+ } __packed;
+ struct wmi_scan_event {
+-- 
+2.51.0
+
diff --git a/queue-6.1/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch b/queue-6.1/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch
new file mode 100644 (file)
index 0000000..20720cc
--- /dev/null
@@ -0,0 +1,53 @@
+From d8d77101cb0aa9d721dc457e06328a0f4447fd6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Nov 2025 09:39:57 +0100
+Subject: wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp()
+
+From: Nicolas Escande <nico.escande@gmail.com>
+
+[ Upstream commit 9065b968752334f972e0d48e50c4463a172fc2a7 ]
+
+When reporting tx completion using ieee80211_tx_status_xxx() family of
+functions, the status part of the struct ieee80211_tx_info nested in the
+skb is used to report things like transmit rates & retry count to mac80211
+
+On the TX data path, this is correctly memset to 0 before calling
+ieee80211_tx_status_ext(), but on the tx mgmt path this was not done.
+
+This leads to mac80211 treating garbage values as valid transmit counters
+(like tx retries for example) and accounting them as real statistics that
+makes their way to userland via station dump.
+
+The same issue was resolved in ath12k by commit 9903c0986f78 ("wifi:
+ath12k: Add memset and update default rate value in wmi tx completion")
+
+Tested-on: QCN9074 PCI WLAN.HK.2.9.0.1-01977-QCAHKSWPL_SILICONZ-1
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
+Link: https://patch.msgid.link/20251104083957.717825-1-nico.escande@gmail.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 1b58979bdfdc6..ed12bbb11fe89 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -5246,6 +5246,9 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar,
+       dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+       info = IEEE80211_SKB_CB(msdu);
++      memset(&info->status, 0, sizeof(info->status));
++      info->status.rates[0].idx = -1;
++
+       if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) &&
+           !tx_compl_param->status) {
+               info->flags |= IEEE80211_TX_STAT_ACK;
+-- 
+2.51.0
+
diff --git a/queue-6.1/wifi-mac80211-skip-rate-verification-for-not-capture.patch b/queue-6.1/wifi-mac80211-skip-rate-verification-for-not-capture.patch
new file mode 100644 (file)
index 0000000..c27d2bc
--- /dev/null
@@ -0,0 +1,48 @@
+From 44a2123796cc1390a5b99377e438399a07f181c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 14:26:18 +0200
+Subject: wifi: mac80211: skip rate verification for not captured PSDUs
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 7fe0d21f5633af8c3fab9f0ef0706c6156623484 ]
+
+If for example the sniffer did not follow any AIDs in an MU frame, then
+some of the information may not be filled in or is even expected to be
+invalid. As an example, in that case it is expected that Nss is zero.
+
+Fixes: 2ff5e52e7836 ("radiotap: add 0-length PSDU "not captured" type")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251110142554.83a2858ee15b.I9f78ce7984872f474722f9278691ae16378f0a3e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 776f9fcf05abe..1cd75c200cfe6 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -5228,10 +5228,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+       if (WARN_ON(!local->started))
+               goto drop;
+-      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) {
++      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) &&
++                 !(status->flag & RX_FLAG_NO_PSDU &&
++                   status->zero_length_psdu_type ==
++                   IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) {
+               /*
+-               * Validate the rate, unless a PLCP error means that
+-               * we probably can't have a valid rate here anyway.
++               * Validate the rate, unless there was a PLCP error which may
++               * have an invalid rate or the PSDU was not capture and may be
++               * missing rate information.
+                */
+               switch (status->encoding) {
+-- 
+2.51.0
+
diff --git a/queue-6.12/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch b/queue-6.12/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch
new file mode 100644 (file)
index 0000000..36f08d0
--- /dev/null
@@ -0,0 +1,49 @@
+From 1d7b0081f30bc1d73359d2e9012027d5c8064888 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:42 +0530
+Subject: ACPI: CPPC: Check _CPC validity for only the online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 6dd3b8a709a130a4d55c866af9804c81b8486d28 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function acpi_cpc_valid() checks for the validity of the
+_CPC object for all the present CPUs. This breaks when the kernel is
+booted with "nosmt=force".
+
+Hence check the validity of the _CPC objects of only the online CPUs.
+
+Fixes: 2aeca6bd0277 ("ACPI: CPPC: Check present CPUs for determining _CPC is valid")
+Reported-by: Christopher Harris <chris.harris79@gmail.com>
+Closes: https://lore.kernel.org/lkml/CAM+eXpdDT7KjLV0AxEwOLkSJ2QtrsvGvjA2cCHvt1d0k2_C4Cw@mail.gmail.com/
+Suggested-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Tested-by: Chrisopher Harris <chris.harris79@gmail.com>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-3-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index dab941dc984a9..3ce5bb87d25b7 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -447,7 +447,7 @@ bool acpi_cpc_valid(void)
+       if (acpi_disabled)
+               return false;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+               if (!cpc_ptr)
+                       return false;
+-- 
+2.51.0
+
diff --git a/queue-6.12/acpi-cppc-detect-preferred-core-availability-on-onli.patch b/queue-6.12/acpi-cppc-detect-preferred-core-availability-on-onli.patch
new file mode 100644 (file)
index 0000000..9d74d77
--- /dev/null
@@ -0,0 +1,49 @@
+From 64d06bde4f8a0e98eba6e5df1afae66b9da2caa6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:41 +0530
+Subject: ACPI: CPPC: Detect preferred core availability on online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 4fe5934db4a7187d358f1af1b3ef9b6dd59bce58 ]
+
+Commit 279f838a61f9 ("x86/amd: Detect preferred cores in
+amd_get_boost_ratio_numerator()") introduced the ability to detect the
+preferred core on AMD platforms by checking if there at least two
+distinct highest_perf values.
+
+However, it uses for_each_present_cpu() to iterate through all the
+CPUs in the platform, which is problematic when the kernel is booted
+with "nosmt=force" commandline option.
+
+Hence limit the search to only the online CPUs.
+
+Fixes: 279f838a61f9 ("x86/amd: Detect preferred cores in amd_get_boost_ratio_numerator()")
+Reported-by: Christopher Harris <chris.harris79@gmail.com>
+Closes: https://lore.kernel.org/lkml/CAM+eXpdDT7KjLV0AxEwOLkSJ2QtrsvGvjA2cCHvt1d0k2_C4Cw@mail.gmail.com/
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Tested-by: Chrisopher Harris <chris.harris79@gmail.com>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-2-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/acpi/cppc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
+index aab9d0570841a..147f0d8d54d86 100644
+--- a/arch/x86/kernel/acpi/cppc.c
++++ b/arch/x86/kernel/acpi/cppc.c
+@@ -194,7 +194,7 @@ int amd_detect_prefcore(bool *detected)
+               break;
+       }
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               u32 tmp;
+               int ret;
+-- 
+2.51.0
+
diff --git a/queue-6.12/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch b/queue-6.12/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch
new file mode 100644 (file)
index 0000000..69b8f4a
--- /dev/null
@@ -0,0 +1,45 @@
+From 1b9990ca335dbecf8a507c50db454cbbf11021ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:44 +0530
+Subject: ACPI: CPPC: Limit perf ctrs in PCC check only to online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 0fce75870666b46b700cfbd3216380b422f975da ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPU via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function cppc_perf_ctrs_in_pcc() checks if the CPPC
+perf-ctrs are in a PCC region for all the present CPUs, which breaks
+when the kernel is booted with "nosmt=force".
+
+Hence, limit the check only to the online CPUs.
+
+Fixes: ae2df912d1a5 ("ACPI: CPPC: Disable FIE if registers in PCC regions")
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-5-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index c4a1fee4b4873..62b723f6c48df 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -1366,7 +1366,7 @@ bool cppc_perf_ctrs_in_pcc(void)
+ {
+       int cpu;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               struct cpc_register_resource *ref_perf_reg;
+               struct cpc_desc *cpc_desc;
+-- 
+2.51.0
+
diff --git a/queue-6.12/acpi-cppc-perform-fast-check-switch-only-for-online-.patch b/queue-6.12/acpi-cppc-perform-fast-check-switch-only-for-online-.patch
new file mode 100644 (file)
index 0000000..c20bba7
--- /dev/null
@@ -0,0 +1,45 @@
+From 62012c3d08c0680408d3b462b0bf3a6dc35fca2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:43 +0530
+Subject: ACPI: CPPC: Perform fast check switch only for online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 8821c8e80a65bc4eb73daf63b34aac6b8ad69461 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function cppc_allow_fast_switch() checks for the validity
+of the _CPC object for all the present CPUs. This breaks when the
+kernel is booted with "nosmt=force".
+
+Check fast_switch capability only on online CPUs
+
+Fixes: 15eece6c5b05 ("ACPI: CPPC: Fix NULL pointer dereference when nosmp is used")
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-4-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 3ce5bb87d25b7..c4a1fee4b4873 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -463,7 +463,7 @@ bool cppc_allow_fast_switch(void)
+       struct cpc_desc *cpc_ptr;
+       int cpu;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+               desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF];
+               if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
+-- 
+2.51.0
+
diff --git a/queue-6.12/af_unix-initialise-scc_index-in-unix_add_edge.patch b/queue-6.12/af_unix-initialise-scc_index-in-unix_add_edge.patch
new file mode 100644 (file)
index 0000000..94b6f35
--- /dev/null
@@ -0,0 +1,139 @@
+From c07d75bc5fe196efda55f6e2fa5c88967d3b563a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 02:52:22 +0000
+Subject: af_unix: Initialise scc_index in unix_add_edge().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 60e6489f8e3b086bd1130ad4450a2c112e863791 ]
+
+Quang Le reported that the AF_UNIX GC could garbage-collect a
+receive queue of an alive in-flight socket, with a nice repro.
+
+The repro consists of three stages.
+
+  1)
+    1-a. Create a single cyclic reference with many sockets
+    1-b. close() all sockets
+    1-c. Trigger GC
+
+  2)
+    2-a. Pass sk-A to an embryo sk-B
+    2-b. Pass sk-X to sk-X
+    2-c. Trigger GC
+
+  3)
+    3-a. accept() the embryo sk-B
+    3-b. Pass sk-B to sk-C
+    3-c. close() the in-flight sk-A
+    3-d. Trigger GC
+
+As of 2-c, sk-A and sk-X are linked to unix_unvisited_vertices,
+and unix_walk_scc() groups them into two different SCCs:
+
+  unix_sk(sk-A)->vertex->scc_index = 2 (UNIX_VERTEX_INDEX_START)
+  unix_sk(sk-X)->vertex->scc_index = 3
+
+Once GC completes, unix_graph_grouped is set to true.
+Also, unix_graph_maybe_cyclic is set to true due to sk-X's
+cyclic self-reference, which makes close() trigger GC.
+
+At 3-b, unix_add_edge() allocates unix_sk(sk-B)->vertex and
+links it to unix_unvisited_vertices.
+
+unix_update_graph() is called at 3-a. and 3-b., but neither
+unix_graph_grouped nor unix_graph_maybe_cyclic is changed
+because both sk-B's listener and sk-C are not in-flight.
+
+3-c decrements sk-A's file refcnt to 1.
+
+Since unix_graph_grouped is true at 3-d, unix_walk_scc_fast()
+is finally called and iterates 3 sockets sk-A, sk-B, and sk-X:
+
+  sk-A -> sk-B (-> sk-C)
+  sk-X -> sk-X
+
+This is totally fine.  All of them are not yet close()d and
+should be grouped into different SCCs.
+
+However, unix_vertex_dead() misjudges that sk-A and sk-B are
+in the same SCC and sk-A is dead.
+
+  unix_sk(sk-A)->scc_index == unix_sk(sk-B)->scc_index <-- Wrong!
+  &&
+  sk-A's file refcnt == unix_sk(sk-A)->vertex->out_degree
+                                       ^-- 1 in-flight count for sk-B
+  -> sk-A is dead !?
+
+The problem is that unix_add_edge() does not initialise scc_index.
+
+Stage 1) is used for heap spraying, making a newly allocated
+vertex have vertex->scc_index == 2 (UNIX_VERTEX_INDEX_START)
+set by unix_walk_scc() at 1-c.
+
+Let's track the max SCC index from the previous unix_walk_scc()
+call and assign the max + 1 to a new vertex's scc_index.
+
+This way, we can continue to avoid Tarjan's algorithm while
+preventing misjudgments.
+
+Fixes: ad081928a8b0 ("af_unix: Avoid Tarjan's algorithm if unnecessary.")
+Reported-by: Quang Le <quanglex97@gmail.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20251109025233.3659187-1-kuniyu@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/garbage.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 0068e758be4dd..66fd606c43f45 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -136,6 +136,7 @@ enum unix_vertex_index {
+ };
+ static unsigned long unix_vertex_unvisited_index = UNIX_VERTEX_INDEX_MARK1;
++static unsigned long unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START;
+ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
+ {
+@@ -144,6 +145,7 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
+       if (!vertex) {
+               vertex = list_first_entry(&fpl->vertices, typeof(*vertex), entry);
+               vertex->index = unix_vertex_unvisited_index;
++              vertex->scc_index = ++unix_vertex_max_scc_index;
+               vertex->out_degree = 0;
+               INIT_LIST_HEAD(&vertex->edges);
+               INIT_LIST_HEAD(&vertex->scc_entry);
+@@ -480,10 +482,15 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde
+                               scc_dead = unix_vertex_dead(v);
+               }
+-              if (scc_dead)
++              if (scc_dead) {
+                       unix_collect_skb(&scc, hitlist);
+-              else if (!unix_graph_maybe_cyclic)
+-                      unix_graph_maybe_cyclic = unix_scc_cyclic(&scc);
++              } else {
++                      if (unix_vertex_max_scc_index < vertex->scc_index)
++                              unix_vertex_max_scc_index = vertex->scc_index;
++
++                      if (!unix_graph_maybe_cyclic)
++                              unix_graph_maybe_cyclic = unix_scc_cyclic(&scc);
++              }
+               list_del(&scc);
+       }
+@@ -498,6 +505,7 @@ static void unix_walk_scc(struct sk_buff_head *hitlist)
+       unsigned long last_index = UNIX_VERTEX_INDEX_START;
+       unix_graph_maybe_cyclic = false;
++      unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START;
+       /* Visit every vertex exactly once.
+        * __unix_walk_scc() moves visited vertices to unix_visited_vertices.
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch b/queue-6.12/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
new file mode 100644 (file)
index 0000000..6229661
--- /dev/null
@@ -0,0 +1,149 @@
+From 6d180a8011781667b73c6554055c17a69190d2c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:49 +0200
+Subject: Bluetooth: 6lowpan: Don't hold spin lock over sleeping functions
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 98454bc812f3611551e4b1f81732da4aa7b9597e ]
+
+disconnect_all_peers() calls sleeping function (l2cap_chan_close) under
+spinlock.  Holding the lock doesn't actually do any good -- we work on a
+local copy of the list, and the lock doesn't protect against peer->chan
+having already been freed.
+
+Fix by taking refcounts of peer->chan instead.  Clean up the code and
+old comments a bit.
+
+Take devices_lock instead of RCU, because the kfree_rcu();
+l2cap_chan_put(); construct in chan_close_cb() does not guarantee
+peer->chan is necessarily valid in RCU.
+
+Also take l2cap_chan_lock() which is required for l2cap_chan_close().
+
+Log: (bluez 6lowpan-tester Client Connect - Disable)
+------
+BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
+...
+<TASK>
+...
+l2cap_send_disconn_req (net/bluetooth/l2cap_core.c:938 net/bluetooth/l2cap_core.c:1495)
+...
+? __pfx_l2cap_chan_close (net/bluetooth/l2cap_core.c:809)
+do_enable_set (net/bluetooth/6lowpan.c:1048 net/bluetooth/6lowpan.c:1068)
+------
+
+Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 68 ++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 73fe151a52a12..e5186a438290a 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -52,6 +52,11 @@ static bool enable_6lowpan;
+ static struct l2cap_chan *listen_chan;
+ static DEFINE_MUTEX(set_lock);
++enum {
++      LOWPAN_PEER_CLOSING,
++      LOWPAN_PEER_MAXBITS
++};
++
+ struct lowpan_peer {
+       struct list_head list;
+       struct rcu_head rcu;
+@@ -60,6 +65,8 @@ struct lowpan_peer {
+       /* peer addresses in various formats */
+       unsigned char lladdr[ETH_ALEN];
+       struct in6_addr peer_addr;
++
++      DECLARE_BITMAP(flags, LOWPAN_PEER_MAXBITS);
+ };
+ struct lowpan_btle_dev {
+@@ -1013,41 +1020,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ static void disconnect_all_peers(void)
+ {
+       struct lowpan_btle_dev *entry;
+-      struct lowpan_peer *peer, *tmp_peer, *new_peer;
+-      struct list_head peers;
+-
+-      INIT_LIST_HEAD(&peers);
++      struct lowpan_peer *peer;
++      int nchans;
+-      /* We make a separate list of peers as the close_cb() will
+-       * modify the device peers list so it is better not to mess
+-       * with the same list at the same time.
++      /* l2cap_chan_close() cannot be called from RCU, and lock ordering
++       * chan->lock > devices_lock prevents taking write side lock, so copy
++       * then close.
+        */
+       rcu_read_lock();
++      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list)
++              list_for_each_entry_rcu(peer, &entry->peers, list)
++                      clear_bit(LOWPAN_PEER_CLOSING, peer->flags);
++      rcu_read_unlock();
+-      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
+-              list_for_each_entry_rcu(peer, &entry->peers, list) {
+-                      new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
+-                      if (!new_peer)
+-                              break;
++      do {
++              struct l2cap_chan *chans[32];
++              int i;
+-                      new_peer->chan = peer->chan;
+-                      INIT_LIST_HEAD(&new_peer->list);
++              nchans = 0;
+-                      list_add(&new_peer->list, &peers);
+-              }
+-      }
++              spin_lock(&devices_lock);
+-      rcu_read_unlock();
++              list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
++                      list_for_each_entry_rcu(peer, &entry->peers, list) {
++                              if (test_and_set_bit(LOWPAN_PEER_CLOSING,
++                                                   peer->flags))
++                                      continue;
+-      spin_lock(&devices_lock);
+-      list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
+-              l2cap_chan_close(peer->chan, ENOENT);
++                              l2cap_chan_hold(peer->chan);
++                              chans[nchans++] = peer->chan;
+-              list_del_rcu(&peer->list);
+-              kfree_rcu(peer, rcu);
+-      }
+-      spin_unlock(&devices_lock);
++                              if (nchans >= ARRAY_SIZE(chans))
++                                      goto done;
++                      }
++              }
++
++done:
++              spin_unlock(&devices_lock);
++
++              for (i = 0; i < nchans; ++i) {
++                      l2cap_chan_lock(chans[i]);
++                      l2cap_chan_close(chans[i], ENOENT);
++                      l2cap_chan_unlock(chans[i]);
++                      l2cap_chan_put(chans[i]);
++              }
++      } while (nchans);
+ }
+ struct set_enable {
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch b/queue-6.12/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
new file mode 100644 (file)
index 0000000..0ee7fcd
--- /dev/null
@@ -0,0 +1,103 @@
+From a49f68bdc68fcce36f25f502bdf2e114d4ec1dc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:47 +0200
+Subject: Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type
+ confusion
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit b454505bf57a2e4f5d49951d4deb03730a9348d9 ]
+
+Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types,
+e.g. debugfs "connect" command takes the former, and "disconnect" and
+"connect" to already connected device take the latter.  This is due to
+using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le
+which take different dst_type values.
+
+Fix address type passed to hci_conn_hash_lookup_le().
+
+Retain the debugfs API difference between "connect" and "disconnect"
+commands since it's been like this since 2015 and nobody apparently
+complained.
+
+Fixes: f5ad4ffceba0 ("Bluetooth: 6lowpan: Use hci_conn_hash_lookup_le() when possible")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index e313b066733f8..73fe151a52a12 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -956,10 +956,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void)
+ }
+ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+-                        struct l2cap_conn **conn)
++                        struct l2cap_conn **conn, bool disconnect)
+ {
+       struct hci_conn *hcon;
+       struct hci_dev *hdev;
++      int le_addr_type;
+       int n;
+       n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
+@@ -970,13 +971,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+       if (n < 7)
+               return -EINVAL;
++      if (disconnect) {
++              /* The "disconnect" debugfs command has used different address
++               * type constants than "connect" since 2015. Let's retain that
++               * for now even though it's obviously buggy...
++               */
++              *addr_type += 1;
++      }
++
++      switch (*addr_type) {
++      case BDADDR_LE_PUBLIC:
++              le_addr_type = ADDR_LE_DEV_PUBLIC;
++              break;
++      case BDADDR_LE_RANDOM:
++              le_addr_type = ADDR_LE_DEV_RANDOM;
++              break;
++      default:
++              return -EINVAL;
++      }
++
+       /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
+       hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
+       if (!hdev)
+               return -ENOENT;
+       hci_dev_lock(hdev);
+-      hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
++      hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+@@ -1103,7 +1123,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       buf[buf_size] = '\0';
+       if (memcmp(buf, "connect ", 8) == 0) {
+-              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false);
+               if (ret == -EINVAL)
+                       return ret;
+@@ -1140,7 +1160,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       }
+       if (memcmp(buf, "disconnect ", 11) == 0) {
+-              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true);
+               if (ret < 0)
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch b/queue-6.12/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
new file mode 100644 (file)
index 0000000..ae1bd60
--- /dev/null
@@ -0,0 +1,54 @@
+From 270194a2234b20cf75e2942f919e86e196c44b14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:46 +0200
+Subject: Bluetooth: 6lowpan: reset link-local header on ipv6 recv path
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3b78f50918276ab28fb22eac9aa49401ac436a3b ]
+
+Bluetooth 6lowpan.c netdev has header_ops, so it must set link-local
+header for RX skb, otherwise things crash, eg. with AF_PACKET SOCK_RAW
+
+Add missing skb_reset_mac_header() for uncompressed ipv6 RX path.
+
+For the compressed one, it is done in lowpan_header_decompress().
+
+Log: (BlueZ 6lowpan-tester Client Recv Raw - Success)
+------
+kernel BUG at net/core/skbuff.c:212!
+Call Trace:
+<IRQ>
+...
+packet_rcv (net/packet/af_packet.c:2152)
+...
+<TASK>
+__local_bh_enable_ip (kernel/softirq.c:407)
+netif_rx (net/core/dev.c:5648)
+chan_recv_cb (net/bluetooth/6lowpan.c:294 net/bluetooth/6lowpan.c:359)
+------
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 3c29778171c58..e313b066733f8 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -288,6 +288,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
+               local_skb->pkt_type = PACKET_HOST;
+               local_skb->dev = dev;
++              skb_reset_mac_header(local_skb);
+               skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
+               if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) {
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch b/queue-6.12/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
new file mode 100644 (file)
index 0000000..9fbc0c5
--- /dev/null
@@ -0,0 +1,65 @@
+From 11af6c70bed6b48ff39396a08c43c18f2a648494 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:28:41 -0500
+Subject: Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
+
+From: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+
+[ Upstream commit 23d22f2f71768034d6ef86168213843fc49bf550 ]
+
+There is a KASAN: slab-use-after-free read in btusb_disconnect().
+Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will
+free the btusb data associated with the interface. The same data is
+then used later in the function, hence the UAF.
+
+Fix by moving the accesses to btusb data to before the data is free'd.
+
+Reported-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2fc81b50a4f8263a159b
+Tested-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Fixes: fd913ef7ce619 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index a734c5135a8be..aedb478614000 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4179,6 +4179,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+       hci_unregister_dev(hdev);
++      if (data->oob_wake_irq)
++              device_init_wakeup(&data->udev->dev, false);
++      if (data->reset_gpio)
++              gpiod_put(data->reset_gpio);
++
+       if (intf == data->intf) {
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
+@@ -4189,17 +4194,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+                       usb_driver_release_interface(&btusb_driver, data->diag);
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       } else if (intf == data->diag) {
+-              usb_driver_release_interface(&btusb_driver, data->intf);
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
++              usb_driver_release_interface(&btusb_driver, data->intf);
+       }
+-      if (data->oob_wake_irq)
+-              device_init_wakeup(&data->udev->dev, false);
+-
+-      if (data->reset_gpio)
+-              gpiod_put(data->reset_gpio);
+-
+       hci_free_dev(hdev);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch b/queue-6.12/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
new file mode 100644 (file)
index 0000000..04eaaa2
--- /dev/null
@@ -0,0 +1,37 @@
+From 59117a5eae2a6f457418b4a6b2d38b7aba3d000d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:48 +0200
+Subject: Bluetooth: L2CAP: export l2cap_chan_hold for modules
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit e060088db0bdf7932e0e3c2d24b7371c4c5b867c ]
+
+l2cap_chan_put() is exported, so export also l2cap_chan_hold() for
+modules.
+
+l2cap_chan_hold() has use case in net/bluetooth/6lowpan.c
+
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 7dafc3e0a15aa..41197f9fdf980 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -497,6 +497,7 @@ void l2cap_chan_hold(struct l2cap_chan *c)
+       kref_get(&c->kref);
+ }
++EXPORT_SYMBOL_GPL(l2cap_chan_hold);
+ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
+ {
+-- 
+2.51.0
+
diff --git a/queue-6.12/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch b/queue-6.12/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch
new file mode 100644 (file)
index 0000000..5d553b9
--- /dev/null
@@ -0,0 +1,56 @@
+From a7a477abfa1410aa927641b3de3715f25d854b8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Nov 2025 20:16:12 +0200
+Subject: Bluetooth: MGMT: cancel mesh send timer when hdev removed
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 55fb52ffdd62850d667ebed842815e072d3c9961 ]
+
+mesh_send_done timer is not canceled when hdev is removed, which causes
+crash if the timer triggers after hdev is gone.
+
+Cancel the timer when MGMT removes the hdev, like other MGMT timers.
+
+Should fix the BUG: sporadically seen by BlueZ test bot
+(in "Mesh - Send cancel - 1" test).
+
+Log:
+------
+BUG: KASAN: slab-use-after-free in run_timer_softirq+0x76b/0x7d0
+...
+Freed by task 36:
+ kasan_save_stack+0x24/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3a/0x60
+ __kasan_slab_free+0x43/0x70
+ kfree+0x103/0x500
+ device_release+0x9a/0x210
+ kobject_put+0x100/0x1e0
+ vhci_release+0x18b/0x240
+------
+
+Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh")
+Link: https://lore.kernel.org/linux-bluetooth/67364c09.0c0a0220.113cba.39ff@mx.google.com/
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 57295c3a8920f..c54cc701cdd48 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9492,6 +9492,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
+       cancel_delayed_work_sync(&hdev->discov_off);
+       cancel_delayed_work_sync(&hdev->service_cache);
+       cancel_delayed_work_sync(&hdev->rpa_expired);
++      cancel_delayed_work_sync(&hdev->mesh_send_done);
+ }
+ void mgmt_power_on(struct hci_dev *hdev, int err)
+-- 
+2.51.0
+
diff --git a/queue-6.12/erofs-avoid-infinite-loop-due-to-incomplete-zstd-com.patch b/queue-6.12/erofs-avoid-infinite-loop-due-to-incomplete-zstd-com.patch
new file mode 100644 (file)
index 0000000..3ef6f4c
--- /dev/null
@@ -0,0 +1,60 @@
+From 125fc46e444092130ac1e6afab4c568a333943f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Oct 2025 13:47:39 +0800
+Subject: erofs: avoid infinite loop due to incomplete zstd-compressed data
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit f2a12cc3b97f062186568a7b94ddb7aa2ef68140 ]
+
+Currently, the decompression logic incorrectly spins if compressed
+data is truncated in crafted (deliberately corrupted) images.
+
+Fixes: 7c35de4df105 ("erofs: Zstandard compression support")
+Reported-by: Robert Morris <rtm@csail.mit.edu>
+Closes: https://lore.kernel.org/r/50958.1761605413@localhost
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Reviewed-by: Chunhai Guo <guochunhai@vivo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/decompressor_zstd.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/erofs/decompressor_zstd.c b/fs/erofs/decompressor_zstd.c
+index 7e177304967e1..24f4731a7a6d4 100644
+--- a/fs/erofs/decompressor_zstd.c
++++ b/fs/erofs/decompressor_zstd.c
+@@ -178,7 +178,6 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
+       dctx.bounce = strm->bounce;
+       do {
+-              dctx.avail_out = out_buf.size - out_buf.pos;
+               dctx.inbuf_sz = in_buf.size;
+               dctx.inbuf_pos = in_buf.pos;
+               err = z_erofs_stream_switch_bufs(&dctx, &out_buf.dst,
+@@ -194,14 +193,18 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
+               in_buf.pos = dctx.inbuf_pos;
+               zerr = zstd_decompress_stream(stream, &out_buf, &in_buf);
+-              if (zstd_is_error(zerr) || (!zerr && rq->outputsize)) {
++              dctx.avail_out = out_buf.size - out_buf.pos;
++              if (zstd_is_error(zerr) ||
++                  ((rq->outputsize + dctx.avail_out) && (!zerr || (zerr > 0 &&
++                              !(rq->inputsize + in_buf.size - in_buf.pos))))) {
+                       erofs_err(sb, "failed to decompress in[%u] out[%u]: %s",
+                                 rq->inputsize, rq->outputsize,
+-                                zerr ? zstd_get_error_name(zerr) : "unexpected end of stream");
++                                zstd_is_error(zerr) ? zstd_get_error_name(zerr) :
++                                      "unexpected end of stream");
+                       err = -EFSCORRUPTED;
+                       break;
+               }
+-      } while (rq->outputsize || out_buf.pos < out_buf.size);
++      } while (rq->outputsize + dctx.avail_out);
+       if (dctx.kout)
+               kunmap_local(dctx.kout);
+-- 
+2.51.0
+
diff --git a/queue-6.12/hsr-fix-supervision-frame-sending-on-hsrv0.patch b/queue-6.12/hsr-fix-supervision-frame-sending-on-hsrv0.patch
new file mode 100644 (file)
index 0000000..16abe64
--- /dev/null
@@ -0,0 +1,50 @@
+From a69f071fdec75172c71e4b55b611e4664286d1c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:29:32 +0100
+Subject: hsr: Fix supervision frame sending on HSRv0
+
+From: Felix Maurer <fmaurer@redhat.com>
+
+[ Upstream commit 96a3a03abf3d8cc38cd9cb0d280235fbcf7c3f7f ]
+
+On HSRv0, no supervision frames were sent. The supervison frames were
+generated successfully, but failed the check for a sufficiently long mac
+header, i.e., at least sizeof(struct hsr_ethhdr), in hsr_fill_frame_info()
+because the mac header only contained the ethernet header.
+
+Fix this by including the HSR header in the mac header when generating HSR
+supervision frames. Note that the mac header now also includes the TLV
+fields. This matches how we set the headers on rx and also the size of
+struct hsrv0_ethhdr_sp.
+
+Reported-by: Hangbin Liu <liuhangbin@gmail.com>
+Closes: https://lore.kernel.org/netdev/aMONxDXkzBZZRfE5@fedora/
+Fixes: 9cfb5e7f0ded ("net: hsr: fix hsr_init_sk() vs network/transport headers.")
+Signed-off-by: Felix Maurer <fmaurer@redhat.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://patch.msgid.link/4354114fea9a642fe71f49aeeb6c6159d1d61840.1762876095.git.fmaurer@redhat.com
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index d2ae9fbed9e30..ae368cdcbd936 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -320,6 +320,9 @@ static void send_hsr_supervision_frame(struct hsr_port *port,
+       }
+       hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag));
++      skb_set_network_header(skb, ETH_HLEN + HSR_HLEN);
++      skb_reset_mac_len(skb);
++
+       set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf));
+       set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-respons.patch b/queue-6.12/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-respons.patch
new file mode 100644 (file)
index 0000000..3b27d01
--- /dev/null
@@ -0,0 +1,77 @@
+From 842f90f7e3f2a527ae5bf7419339fc219607f942 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 14:53:04 +0530
+Subject: net: ethernet: ti: am65-cpsw-qos: fix IET verify/response timeout
+
+From: Aksh Garg <a-garg7@ti.com>
+
+[ Upstream commit 49b3916465176a5abcb29a0e464825f553d55d58 ]
+
+The CPSW module uses the MAC_VERIFY_CNT bit field in the
+CPSW_PN_IET_VERIFY_REG_k register to set the verify/response timeout
+count. This register specifies the number of clock cycles to wait before
+resending a verify packet if the verification fails.
+
+The verify/response timeout count, as being set by the function
+am65_cpsw_iet_set_verify_timeout_count() is hardcoded for 125MHz
+clock frequency, which varies based on PHY mode and link speed.
+
+The respective clock frequencies are as follows:
+- RGMII mode:
+  * 1000 Mbps: 125 MHz
+  * 100 Mbps: 25 MHz
+  * 10 Mbps: 2.5 MHz
+- QSGMII/SGMII mode: 125 MHz (all speeds)
+
+Fix this by adding logic to calculate the correct timeout counts
+based on the actual PHY interface mode and link speed.
+
+Fixes: 49a2eb9068246 ("net: ethernet: ti: am65-cpsw-qos: Add Frame Preemption MAC Merge support")
+Signed-off-by: Aksh Garg <a-garg7@ti.com>
+Link: https://patch.msgid.link/20251106092305.1437347-2-a-garg7@ti.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-qos.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-qos.c b/drivers/net/ethernet/ti/am65-cpsw-qos.c
+index fa96db7c1a130..ad06942ce461a 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-qos.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-qos.c
+@@ -276,9 +276,31 @@ static int am65_cpsw_iet_set_verify_timeout_count(struct am65_cpsw_port *port)
+       /* The number of wireside clocks contained in the verify
+        * timeout counter. The default is 0x1312d0
+        * (10ms at 125Mhz in 1G mode).
++       * The frequency of the clock depends on the link speed
++       * and the PHY interface.
+        */
+-      val = 125 * HZ_PER_MHZ; /* assuming 125MHz wireside clock */
++      switch (port->slave.phy_if) {
++      case PHY_INTERFACE_MODE_RGMII:
++      case PHY_INTERFACE_MODE_RGMII_ID:
++      case PHY_INTERFACE_MODE_RGMII_RXID:
++      case PHY_INTERFACE_MODE_RGMII_TXID:
++              if (port->qos.link_speed == SPEED_1000)
++                      val = 125 * HZ_PER_MHZ; /* 125 MHz at 1000Mbps*/
++              else if (port->qos.link_speed == SPEED_100)
++                      val = 25 * HZ_PER_MHZ;  /* 25 MHz at 100Mbps*/
++              else
++                      val = (25 * HZ_PER_MHZ) / 10;   /* 2.5 MHz at 10Mbps*/
++              break;
++
++      case PHY_INTERFACE_MODE_QSGMII:
++      case PHY_INTERFACE_MODE_SGMII:
++              val = 125 * HZ_PER_MHZ; /* 125 MHz */
++              break;
++      default:
++              netdev_err(port->ndev, "selected mode does not supported IET\n");
++              return -EOPNOTSUPP;
++      }
+       val /= MILLIHZ_PER_HZ;          /* count per ms timeout */
+       val *= verify_time_ms;          /* count for timeout ms */
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-retry-m.patch b/queue-6.12/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-retry-m.patch
new file mode 100644 (file)
index 0000000..c445ae4
--- /dev/null
@@ -0,0 +1,87 @@
+From 70853305503f1e3d51db50b7e4769eb038f3d2e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 14:53:05 +0530
+Subject: net: ethernet: ti: am65-cpsw-qos: fix IET verify retry mechanism
+
+From: Aksh Garg <a-garg7@ti.com>
+
+[ Upstream commit d4b00d132d7cb70a74bc039c91c1d6120943c71b ]
+
+The am65_cpsw_iet_verify_wait() function attempts verification 20 times,
+toggling the AM65_CPSW_PN_IET_MAC_LINKFAIL bit in each iteration. When
+the LINKFAIL bit transitions from 1 to 0, the MAC merge layer initiates
+the verification process and waits for the timeout configured in
+MAC_VERIFY_CNT before automatically retransmitting. The MAC_VERIFY_CNT
+register is configured according to the user-defined verify/response
+timeout in am65_cpsw_iet_set_verify_timeout_count(). As per IEEE 802.3
+Clause 99, the hardware performs this automatic retry up to 3 times.
+
+Current implementation toggles LINKFAIL after the user-configured
+verify/response timeout in each iteration, forcing the hardware to
+restart verification instead of respecting the MAC_VERIFY_CNT timeout.
+This bypasses the hardware's automatic retry mechanism.
+
+Fix this by moving the LINKFAIL bit toggle outside the retry loop and
+reducing the retry count from 20 to 3. The software now only monitors
+the status register while the hardware autonomously handles the 3
+verification attempts at proper MAC_VERIFY_CNT intervals.
+
+Fixes: 49a2eb9068246 ("net: ethernet: ti: am65-cpsw-qos: Add Frame Preemption MAC Merge support")
+Signed-off-by: Aksh Garg <a-garg7@ti.com>
+Link: https://patch.msgid.link/20251106092305.1437347-3-a-garg7@ti.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-qos.c | 27 +++++++++++++------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-qos.c b/drivers/net/ethernet/ti/am65-cpsw-qos.c
+index ad06942ce461a..66e8b224827b6 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-qos.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-qos.c
+@@ -317,20 +317,21 @@ static int am65_cpsw_iet_verify_wait(struct am65_cpsw_port *port)
+       u32 ctrl, status;
+       int try;
+-      try = 20;
+-      do {
+-              /* Reset the verify state machine by writing 1
+-               * to LINKFAIL
+-               */
+-              ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
+-              ctrl |= AM65_CPSW_PN_IET_MAC_LINKFAIL;
+-              writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      try = 3;
+-              /* Clear MAC_LINKFAIL bit to start Verify. */
+-              ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
+-              ctrl &= ~AM65_CPSW_PN_IET_MAC_LINKFAIL;
+-              writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      /* Reset the verify state machine by writing 1
++       * to LINKFAIL
++       */
++      ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      ctrl |= AM65_CPSW_PN_IET_MAC_LINKFAIL;
++      writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      /* Clear MAC_LINKFAIL bit to start Verify. */
++      ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      ctrl &= ~AM65_CPSW_PN_IET_MAC_LINKFAIL;
++      writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++
++      do {
+               msleep(port->qos.iet.verify_time_ms);
+               status = readl(port->port_base + AM65_CPSW_PN_REG_IET_STATUS);
+@@ -352,7 +353,7 @@ static int am65_cpsw_iet_verify_wait(struct am65_cpsw_port *port)
+                       netdev_dbg(port->ndev, "MAC Merge verify error\n");
+                       return -ENODEV;
+               }
+-      } while (try-- > 0);
++      } while (--try > 0);
+       netdev_dbg(port->ndev, "MAC Merge verify timeout\n");
+       return -ETIMEDOUT;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch b/queue-6.12/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
new file mode 100644 (file)
index 0000000..9e95bed
--- /dev/null
@@ -0,0 +1,39 @@
+From a18da66c62811918aa45efd6cf2e9d3d10f28192 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:14:21 +0800
+Subject: net: fec: correct rx_bytes statistic for the case SHIFT16 is set
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit ad17e7e92a7c52ce70bb764813fcf99464f96903 ]
+
+Two additional bytes in front of each frame received into the RX FIFO if
+SHIFT16 is set, so we need to subtract the extra two bytes from pkt_len
+to correct the statistic of rx_bytes.
+
+Fixes: 3ac72b7b63d5 ("net: fec: align IP header in hardware")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20251106021421.2096585-1-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index d144494f97e91..d1800868c2e01 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1799,6 +1799,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               ndev->stats.rx_packets++;
+               pkt_len = fec16_to_cpu(bdp->cbd_datlen);
+               ndev->stats.rx_bytes += pkt_len;
++              if (fep->quirks & FEC_QUIRK_HAS_RACC)
++                      ndev->stats.rx_bytes -= 2;
+               index = fec_enet_get_bd_index(bdp, &rxq->bd);
+               page = rxq->rx_skb_info[index].page;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch b/queue-6.12/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch
new file mode 100644 (file)
index 0000000..ccca5df
--- /dev/null
@@ -0,0 +1,42 @@
+From f74065b398664b7e8e985f8d1997ec938f146b03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 14:45:11 +0000
+Subject: net/handshake: Fix memory leak in tls_handshake_accept()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit 3072f00bba764082fa41b3c3a2a7b013335353d2 ]
+
+In tls_handshake_accept(), a netlink message is allocated using
+genlmsg_new(). In the error handling path, genlmsg_cancel() is called
+to cancel the message construction, but the message itself is not freed.
+This leads to a memory leak.
+
+Fix this by calling nlmsg_free() in the error path after genlmsg_cancel()
+to release the allocated memory.
+
+Fixes: 2fd5532044a89 ("net/handshake: Add a kernel API for requesting a TLSv1.3 handshake")
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://patch.msgid.link/20251106144511.3859535-1-zilin@seu.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/tlshd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index d6f52839827ea..822507b87447c 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -253,6 +253,7 @@ static int tls_handshake_accept(struct handshake_req *req,
+ out_cancel:
+       genlmsg_cancel(msg, hdr);
++      nlmsg_free(msg);
+ out:
+       return ret;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch b/queue-6.12/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
new file mode 100644 (file)
index 0000000..e5f4d3e
--- /dev/null
@@ -0,0 +1,45 @@
+From 8588c17e710c20d563d7d3f8efc14d989b1a4b86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 07:49:22 +0100
+Subject: net: mdio: fix resource leak in mdiobus_register_device()
+
+From: Buday Csaba <buday.csaba@prolan.hu>
+
+[ Upstream commit e6ca8f533ed41129fcf052297718f417f021cc7d ]
+
+Fix a possible leak in mdiobus_register_device() when both a
+reset-gpio and a reset-controller are present.
+Clean up the already claimed reset-gpio, when the registration of
+the reset-controller fails, so when an error code is returned, the
+device retains its state before the registration attempt.
+
+Link: https://lore.kernel.org/all/20251106144603.39053c81@kernel.org/
+Fixes: 71dd6c0dff51 ("net: phy: add support for reset-controller")
+Signed-off-by: Buday Csaba <buday.csaba@prolan.hu>
+Link: https://patch.msgid.link/4b419377f8dd7d2f63f919d0f74a336c734f8fff.1762584481.git.buday.csaba@prolan.hu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mdio_bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index a508cd81cd4ed..d80b80ba20a1d 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -79,8 +79,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
+                       return err;
+               err = mdiobus_register_reset(mdiodev);
+-              if (err)
++              if (err) {
++                      gpiod_put(mdiodev->reset_gpio);
++                      mdiodev->reset_gpio = NULL;
+                       return err;
++              }
+               /* Assert the reset signal */
+               mdio_device_reset(mdiodev, 1);
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch b/queue-6.12/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
new file mode 100644 (file)
index 0000000..97ecc72
--- /dev/null
@@ -0,0 +1,58 @@
+From 3c5bf2929917d81580e03af824dd2725c8912110 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:51 +0200
+Subject: net/mlx5e: Fix maxrate wraparound in threshold between units
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit a7bf4d5063c7837096aab2853224eb23628514d9 ]
+
+The previous calculation used roundup() which caused an overflow for
+rates between 25.5Gbps and 26Gbps.
+For example, a rate of 25.6Gbps would result in using 100Mbps units with
+value of 256, which would overflow the 8 bits field.
+
+Simplify the upper_limit_mbps calculation by removing the
+unnecessary roundup, and adjust the comparison to use <= to correctly
+handle the boundary condition.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index b08328fe1aa30..99ee288ed43a4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -595,18 +595,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       struct mlx5_core_dev *mdev = priv->mdev;
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+-      __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
++      __u64 upper_limit_mbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
++      upper_limit_mbps = 255 * MLX5E_100MB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+                       max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
+                       continue;
+               }
+-              if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
++              if (maxrate->tc_maxrate[i] <= upper_limit_mbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5e-fix-potentially-misleading-debug-message.patch b/queue-6.12/net-mlx5e-fix-potentially-misleading-debug-message.patch
new file mode 100644 (file)
index 0000000..bbcfe62
--- /dev/null
@@ -0,0 +1,62 @@
+From 6beb5e8bfab17a20261a606352931c756c451f09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:53 +0200
+Subject: net/mlx5e: Fix potentially misleading debug message
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 9fcc2b6c10523f7e75db6387946c86fcf19dc97e ]
+
+Change the debug message to print the correct units instead of always
+assuming Gbps, as the value can be in either 100 Mbps or 1 Gbps units.
+
+Fixes: 5da8bc3effb6 ("net/mlx5e: DCBNL, Add debug messages log")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-6-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 154f8d9eec02a..2ca32fb1961e1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -598,6 +598,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       __u64 upper_limit_mbps;
+       __u64 upper_limit_gbps;
+       int i;
++      struct {
++              int scale;
++              const char *units_str;
++      } units[] = {
++              [MLX5_100_MBPS_UNIT] = {
++                      .scale = 100,
++                      .units_str = "Mbps",
++              },
++              [MLX5_GBPS_UNIT] = {
++                      .scale = 1,
++                      .units_str = "Gbps",
++              },
++      };
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+@@ -628,8 +641,9 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       }
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+-              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %d Gbps\n",
+-                         __func__, i, max_bw_value[i]);
++              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %u %s\n", __func__, i,
++                         max_bw_value[i] * units[max_bw_unit[i]].scale,
++                         units[max_bw_unit[i]].units_str);
+       }
+       return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch b/queue-6.12/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
new file mode 100644 (file)
index 0000000..fcfc968
--- /dev/null
@@ -0,0 +1,62 @@
+From d3229ae9dde02db1ee881e09699a7e7b086f12b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:52 +0200
+Subject: net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 43b27d1bd88a4bce34ec2437d103acfae9655f9e ]
+
+Add validation to reject rates exceeding 255 Gbps that would overflow
+the 8 bits max bandwidth field.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 99ee288ed43a4..154f8d9eec02a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -596,11 +596,13 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+       __u64 upper_limit_mbps;
++      __u64 upper_limit_gbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+       upper_limit_mbps = 255 * MLX5E_100MB;
++      upper_limit_gbps = 255 * MLX5E_1GB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+@@ -612,10 +614,16 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else {
++              } else if (max_bw_value[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
++              } else {
++                      netdev_err(netdev,
++                                 "tc_%d maxrate %llu Kbps exceeds limit %llu\n",
++                                 i, maxrate->tc_maxrate[i],
++                                 upper_limit_gbps);
++                      return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-phy-micrel-introduce-lanphy_modify_page_reg.patch b/queue-6.12/net-phy-micrel-introduce-lanphy_modify_page_reg.patch
new file mode 100644 (file)
index 0000000..809d9d5
--- /dev/null
@@ -0,0 +1,414 @@
+From 741f2ff018b456c95def08719431165660612835 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Aug 2025 09:51:19 +0200
+Subject: net: phy: micrel: Introduce lanphy_modify_page_reg
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit a0de636ed7a264a329c6a9c7d50727af02138536 ]
+
+As the name suggests this function modifies the register in an
+extended page. It has the same parameters as phy_modify_mmd.
+This function was introduce because there are many places in the
+code where the registers was read then the value was modified and
+written back. So replace all this code with this function to make
+it clear.
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://patch.msgid.link/20250818075121.1298170-3-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 96a9178a29a6 ("net: phy: micrel: lan8814 fix reset of the QSGMII interface")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 231 ++++++++++++++++++++-------------------
+ 1 file changed, 116 insertions(+), 115 deletions(-)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index f60cf630bdb3d..0ab3f813d29e4 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -2591,6 +2591,27 @@ static int lanphy_write_page_reg(struct phy_device *phydev, int page, u16 addr,
+       return val;
+ }
++static int lanphy_modify_page_reg(struct phy_device *phydev, int page, u16 addr,
++                                u16 mask, u16 set)
++{
++      int ret;
++
++      phy_lock_mdio_bus(phydev);
++      __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
++      __phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
++      __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
++                  (page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
++      ret = __phy_modify_changed(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA,
++                                 mask, set);
++      phy_unlock_mdio_bus(phydev);
++
++      if (ret < 0)
++              phydev_err(phydev, "__phy_modify_changed() failed: %pe\n",
++                         ERR_PTR(ret));
++
++      return ret;
++}
++
+ static int lan8814_config_ts_intr(struct phy_device *phydev, bool enable)
+ {
+       u16 val = 0;
+@@ -2680,7 +2701,6 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts,
+       struct lan8814_ptp_rx_ts *rx_ts, *tmp;
+       int txcfg = 0, rxcfg = 0;
+       int pkt_ts_enable;
+-      int tx_mod;
+       ptp_priv->hwts_tx_type = config->tx_type;
+       ptp_priv->rx_filter = config->rx_filter;
+@@ -2727,13 +2747,14 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts,
+       lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_TIMESTAMP_EN, pkt_ts_enable);
+       lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_TIMESTAMP_EN, pkt_ts_enable);
+-      tx_mod = lanphy_read_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD);
+       if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ONESTEP_SYNC) {
+-              lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
+-                                    tx_mod | PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
++              lanphy_modify_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
++                                     PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_,
++                                     PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
+       } else if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ON) {
+-              lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
+-                                    tx_mod & ~PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
++              lanphy_modify_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
++                                     PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_,
++                                     0);
+       }
+       if (config->rx_filter != HWTSTAMP_FILTER_NONE)
+@@ -3136,73 +3157,66 @@ static void lan8814_ptp_set_reload(struct phy_device *phydev, int event,
+ static void lan8814_ptp_enable_event(struct phy_device *phydev, int event,
+                                    int pulse_width)
+ {
+-      u16 val;
+-
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG);
+-      /* Set the pulse width of the event */
+-      val &= ~(LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_MASK(event));
+-      /* Make sure that the target clock will be incremented each time when
++      /* Set the pulse width of the event,
++       * Make sure that the target clock will be incremented each time when
+        * local time reaches or pass it
++       * Set the polarity high
+        */
+-      val |= LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width);
+-      val &= ~(LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event));
+-      /* Set the polarity high */
+-      val |= LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG, val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG,
++                             LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_MASK(event) |
++                             LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width) |
++                             LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event) |
++                             LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event),
++                             LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width) |
++                             LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event));
+ }
+ static void lan8814_ptp_disable_event(struct phy_device *phydev, int event)
+ {
+-      u16 val;
+-
+       /* Set target to too far in the future, effectively disabling it */
+       lan8814_ptp_set_target(phydev, event, 0xFFFFFFFF, 0);
+       /* And then reload once it recheas the target */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG);
+-      val |= LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG, val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG,
++                             LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event),
++                             LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event));
+ }
+ static void lan8814_ptp_perout_off(struct phy_device *phydev, int pin)
+ {
+-      u16 val;
+-
+       /* Disable gpio alternate function,
+        * 1: select as gpio,
+        * 0: select alt func
+        */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin));
+-      val |= LAN8814_GPIO_EN_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++                             LAN8814_GPIO_EN_BIT(pin),
++                             LAN8814_GPIO_EN_BIT(pin));
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin));
+-      val &= ~LAN8814_GPIO_DIR_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++                             LAN8814_GPIO_DIR_BIT(pin),
++                             0);
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin));
+-      val &= ~LAN8814_GPIO_BUF_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin),
++                             LAN8814_GPIO_BUF_BIT(pin),
++                             0);
+ }
+ static void lan8814_ptp_perout_on(struct phy_device *phydev, int pin)
+ {
+-      int val;
+-
+       /* Set as gpio output */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin));
+-      val |= LAN8814_GPIO_DIR_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++                             LAN8814_GPIO_DIR_BIT(pin),
++                             LAN8814_GPIO_DIR_BIT(pin));
+       /* Enable gpio 0:for alternate function, 1:gpio */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin));
+-      val &= ~LAN8814_GPIO_EN_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++                             LAN8814_GPIO_EN_BIT(pin),
++                             0);
+       /* Set buffer type to push pull */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin));
+-      val |= LAN8814_GPIO_BUF_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin),
++                             LAN8814_GPIO_BUF_BIT(pin),
++                             LAN8814_GPIO_BUF_BIT(pin));
+ }
+ static int lan8814_ptp_perout(struct ptp_clock_info *ptpci,
+@@ -3321,61 +3335,59 @@ static int lan8814_ptp_perout(struct ptp_clock_info *ptpci,
+ static void lan8814_ptp_extts_on(struct phy_device *phydev, int pin, u32 flags)
+ {
+-      u16 tmp;
+-
+       /* Set as gpio input */
+-      tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin));
+-      tmp &= ~LAN8814_GPIO_DIR_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), tmp);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++                             LAN8814_GPIO_DIR_BIT(pin),
++                             0);
+       /* Map the pin to ltc pin 0 of the capture map registers */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO);
+-      tmp |= pin;
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO,
++                             pin,
++                             pin);
+       /* Enable capture on the edges of the ltc pin */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_EN);
+       if (flags & PTP_RISING_EDGE)
+-              tmp |= PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0);
++              lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++                                     PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0),
++                                     PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0));
+       if (flags & PTP_FALLING_EDGE)
+-              tmp |= PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0);
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_EN, tmp);
++              lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++                                     PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0),
++                                     PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0));
+       /* Enable interrupt top interrupt */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_COMMON_INT_ENA);
+-      tmp |= PTP_COMMON_INT_ENA_GPIO_CAP_EN;
+-      lanphy_write_page_reg(phydev, 4, PTP_COMMON_INT_ENA, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_COMMON_INT_ENA,
++                             PTP_COMMON_INT_ENA_GPIO_CAP_EN,
++                             PTP_COMMON_INT_ENA_GPIO_CAP_EN);
+ }
+ static void lan8814_ptp_extts_off(struct phy_device *phydev, int pin)
+ {
+-      u16 tmp;
+-
+       /* Set as gpio out */
+-      tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin));
+-      tmp |= LAN8814_GPIO_DIR_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), tmp);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++                             LAN8814_GPIO_DIR_BIT(pin),
++                             LAN8814_GPIO_DIR_BIT(pin));
+       /* Enable alternate, 0:for alternate function, 1:gpio */
+-      tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin));
+-      tmp &= ~LAN8814_GPIO_EN_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), tmp);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++                             LAN8814_GPIO_EN_BIT(pin),
++                             0);
+       /* Clear the mapping of pin to registers 0 of the capture registers */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO);
+-      tmp &= ~GENMASK(3, 0);
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO,
++                             GENMASK(3, 0),
++                             0);
+       /* Disable capture on both of the edges */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_EN);
+-      tmp &= ~PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin);
+-      tmp &= ~PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin);
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_EN, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++                             PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin) |
++                             PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin),
++                             0);
+       /* Disable interrupt top interrupt */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_COMMON_INT_ENA);
+-      tmp &= ~PTP_COMMON_INT_ENA_GPIO_CAP_EN;
+-      lanphy_write_page_reg(phydev, 4, PTP_COMMON_INT_ENA, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_COMMON_INT_ENA,
++                             PTP_COMMON_INT_ENA_GPIO_CAP_EN,
++                             0);
+ }
+ static int lan8814_ptp_extts(struct ptp_clock_info *ptpci,
+@@ -3620,9 +3632,9 @@ static int lan8814_gpio_process_cap(struct lan8814_shared_priv *shared)
+       /* This is 0 because whatever was the input pin it was mapped it to
+        * ltc gpio pin 0
+        */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_SEL);
+-      tmp |= PTP_GPIO_SEL_GPIO_SEL(0);
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_SEL, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_SEL,
++                             PTP_GPIO_SEL_GPIO_SEL(0),
++                             PTP_GPIO_SEL_GPIO_SEL(0));
+       tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_STS);
+       if (!(tmp & PTP_GPIO_CAP_STS_PTP_GPIO_RE_STS(0)) &&
+@@ -3669,13 +3681,10 @@ static int lan8814_handle_gpio_interrupt(struct phy_device *phydev, u16 status)
+ static int lan8804_config_init(struct phy_device *phydev)
+ {
+-      int val;
+-
+       /* MDI-X setting for swap A,B transmit */
+-      val = lanphy_read_page_reg(phydev, 2, LAN8804_ALIGN_SWAP);
+-      val &= ~LAN8804_ALIGN_TX_A_B_SWAP_MASK;
+-      val |= LAN8804_ALIGN_TX_A_B_SWAP;
+-      lanphy_write_page_reg(phydev, 2, LAN8804_ALIGN_SWAP, val);
++      lanphy_modify_page_reg(phydev, 2, LAN8804_ALIGN_SWAP,
++                             LAN8804_ALIGN_TX_A_B_SWAP_MASK,
++                             LAN8804_ALIGN_TX_A_B_SWAP);
+       /* Make sure that the PHY will not stop generating the clock when the
+        * link partner goes down
+@@ -3817,7 +3826,6 @@ static void lan8814_ptp_init(struct phy_device *phydev)
+ {
+       struct kszphy_priv *priv = phydev->priv;
+       struct kszphy_ptp_priv *ptp_priv = &priv->ptp_priv;
+-      u32 temp;
+       if (!IS_ENABLED(CONFIG_PTP_1588_CLOCK) ||
+           !IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING))
+@@ -3825,13 +3833,13 @@ static void lan8814_ptp_init(struct phy_device *phydev)
+       lanphy_write_page_reg(phydev, 5, TSU_HARD_RESET, TSU_HARD_RESET_);
+-      temp = lanphy_read_page_reg(phydev, 5, PTP_TX_MOD);
+-      temp |= PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_;
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_MOD, temp);
++      lanphy_modify_page_reg(phydev, 5, PTP_TX_MOD,
++                             PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_,
++                             PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_);
+-      temp = lanphy_read_page_reg(phydev, 5, PTP_RX_MOD);
+-      temp |= PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_;
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_MOD, temp);
++      lanphy_modify_page_reg(phydev, 5, PTP_RX_MOD,
++                             PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_,
++                             PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_);
+       lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_CONFIG, 0);
+       lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_CONFIG, 0);
+@@ -3953,23 +3961,21 @@ static void lan8814_setup_led(struct phy_device *phydev, int val)
+ static int lan8814_config_init(struct phy_device *phydev)
+ {
+       struct kszphy_priv *lan8814 = phydev->priv;
+-      int val;
+       /* Reset the PHY */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET);
+-      val |= LAN8814_QSGMII_SOFT_RESET_BIT;
+-      lanphy_write_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET, val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET,
++                             LAN8814_QSGMII_SOFT_RESET_BIT,
++                             LAN8814_QSGMII_SOFT_RESET_BIT);
+       /* Disable ANEG with QSGMII PCS Host side */
+-      val = lanphy_read_page_reg(phydev, 5, LAN8814_QSGMII_PCS1G_ANEG_CONFIG);
+-      val &= ~LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA;
+-      lanphy_write_page_reg(phydev, 5, LAN8814_QSGMII_PCS1G_ANEG_CONFIG, val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_QSGMII_PCS1G_ANEG_CONFIG,
++                             LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA,
++                             0);
+       /* MDI-X setting for swap A,B transmit */
+-      val = lanphy_read_page_reg(phydev, 2, LAN8814_ALIGN_SWAP);
+-      val &= ~LAN8814_ALIGN_TX_A_B_SWAP_MASK;
+-      val |= LAN8814_ALIGN_TX_A_B_SWAP;
+-      lanphy_write_page_reg(phydev, 2, LAN8814_ALIGN_SWAP, val);
++      lanphy_modify_page_reg(phydev, 2, LAN8814_ALIGN_SWAP,
++                             LAN8814_ALIGN_TX_A_B_SWAP_MASK,
++                             LAN8814_ALIGN_TX_A_B_SWAP);
+       if (lan8814->led_mode >= 0)
+               lan8814_setup_led(phydev, lan8814->led_mode);
+@@ -4000,29 +4006,24 @@ static int lan8814_release_coma_mode(struct phy_device *phydev)
+ static void lan8814_clear_2psp_bit(struct phy_device *phydev)
+ {
+-      u16 val;
+-
+       /* It was noticed that when traffic is passing through the PHY and the
+        * cable is removed then the LED was still one even though there is no
+        * link
+        */
+-      val = lanphy_read_page_reg(phydev, 2, LAN8814_EEE_STATE);
+-      val &= ~LAN8814_EEE_STATE_MASK2P5P;
+-      lanphy_write_page_reg(phydev, 2, LAN8814_EEE_STATE, val);
++      lanphy_modify_page_reg(phydev, 2, LAN8814_EEE_STATE,
++                             LAN8814_EEE_STATE_MASK2P5P,
++                             0);
+ }
+ static void lan8814_update_meas_time(struct phy_device *phydev)
+ {
+-      u16 val;
+-
+       /* By setting the measure time to a value of 0xb this will allow cables
+        * longer than 100m to be used. This configuration can be used
+        * regardless of the mode of operation of the PHY
+        */
+-      val = lanphy_read_page_reg(phydev, 1, LAN8814_PD_CONTROLS);
+-      val &= ~LAN8814_PD_CONTROLS_PD_MEAS_TIME_MASK;
+-      val |= LAN8814_PD_CONTROLS_PD_MEAS_TIME_VAL;
+-      lanphy_write_page_reg(phydev, 1, LAN8814_PD_CONTROLS, val);
++      lanphy_modify_page_reg(phydev, 1, LAN8814_PD_CONTROLS,
++                             LAN8814_PD_CONTROLS_PD_MEAS_TIME_MASK,
++                             LAN8814_PD_CONTROLS_PD_MEAS_TIME_VAL);
+ }
+ static int lan8814_probe(struct phy_device *phydev)
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-phy-micrel-lan8814-fix-reset-of-the-qsgmii-inter.patch b/queue-6.12/net-phy-micrel-lan8814-fix-reset-of-the-qsgmii-inter.patch
new file mode 100644 (file)
index 0000000..7416d36
--- /dev/null
@@ -0,0 +1,59 @@
+From 11051c097e6a608f388139cbba90c302e20253a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:06:37 +0100
+Subject: net: phy: micrel: lan8814 fix reset of the QSGMII interface
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 96a9178a29a6b84bb632ebeb4e84cf61191c73d5 ]
+
+The lan8814 is a quad-phy and it is using QSGMII towards the MAC.
+The problem is that everytime when one of the ports is configured then
+the PCS is reseted for all the PHYs. Meaning that the other ports can
+loose traffic until the link is establish again.
+To fix this, do the reset one time for the entire PHY package.
+
+Fixes: ece19502834d ("net: phy: micrel: 1588 support for LAN8814 phy")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Divya Koppera <Divya.Koppera@microchip.com >
+Link: https://patch.msgid.link/20251106090637.2030625-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index e12040cf10eae..030e559a2cf15 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -4084,12 +4084,6 @@ static int lan8814_config_init(struct phy_device *phydev)
+ {
+       struct kszphy_priv *lan8814 = phydev->priv;
+-      /* Reset the PHY */
+-      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+-                             LAN8814_QSGMII_SOFT_RESET,
+-                             LAN8814_QSGMII_SOFT_RESET_BIT,
+-                             LAN8814_QSGMII_SOFT_RESET_BIT);
+-
+       /* Disable ANEG with QSGMII PCS Host side */
+       lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                              LAN8814_QSGMII_PCS1G_ANEG_CONFIG,
+@@ -4175,6 +4169,12 @@ static int lan8814_probe(struct phy_device *phydev)
+                             addr, sizeof(struct lan8814_shared_priv));
+       if (phy_package_init_once(phydev)) {
++              /* Reset the PHY */
++              lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                     LAN8814_QSGMII_SOFT_RESET,
++                                     LAN8814_QSGMII_SOFT_RESET_BIT,
++                                     LAN8814_QSGMII_SOFT_RESET_BIT);
++
+               err = lan8814_release_coma_mode(phydev);
+               if (err)
+                       return err;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-phy-micrel-replace-hardcoded-pages-with-defines.patch b/queue-6.12/net-phy-micrel-replace-hardcoded-pages-with-defines.patch
new file mode 100644 (file)
index 0000000..18b6067
--- /dev/null
@@ -0,0 +1,741 @@
+From a78cd2db7a05979d58923f15302de22d297189eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Aug 2025 09:51:20 +0200
+Subject: net: phy: micrel: Replace hardcoded pages with defines
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit d471793a9b67bbe3d7198ff695004190fd7b6bc7 ]
+
+The functions lan_*_page_reg gets as a second parameter the page
+where the register is. In all the functions the page was hardcoded.
+Replace the hardcoded values with defines to make it more clear
+what are those parameters.
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://patch.msgid.link/20250818075121.1298170-4-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 96a9178a29a6 ("net: phy: micrel: lan8814 fix reset of the QSGMII interface")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 342 ++++++++++++++++++++++++++-------------
+ 1 file changed, 233 insertions(+), 109 deletions(-)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index 0ab3f813d29e4..e12040cf10eae 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -2541,6 +2541,52 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev,
+       return ret;
+ }
++/**
++ * LAN8814_PAGE_AFE_PMA - Selects Extended Page 1.
++ *
++ * This page appears to control the Analog Front-End (AFE) and Physical
++ * Medium Attachment (PMA) layers. It is used to access registers like
++ * LAN8814_PD_CONTROLS and LAN8814_LINK_QUALITY.
++ */
++#define LAN8814_PAGE_AFE_PMA 1
++
++/**
++ * LAN8814_PAGE_PCS_DIGITAL - Selects Extended Page 2.
++ *
++ * This page seems dedicated to the Physical Coding Sublayer (PCS) and other
++ * digital logic. It is used for MDI-X alignment (LAN8814_ALIGN_SWAP) and EEE
++ * state (LAN8814_EEE_STATE) in the LAN8814, and is repurposed for statistics
++ * and self-test counters in the LAN8842.
++ */
++#define LAN8814_PAGE_PCS_DIGITAL 2
++
++/**
++ * LAN8814_PAGE_COMMON_REGS - Selects Extended Page 4.
++ *
++ * This page contains device-common registers that affect the entire chip.
++ * It includes controls for chip-level resets, strap status, GPIO,
++ * QSGMII, the shared 1588 PTP block, and the PVT monitor.
++ */
++#define LAN8814_PAGE_COMMON_REGS 4
++
++/**
++ * LAN8814_PAGE_PORT_REGS - Selects Extended Page 5.
++ *
++ * This page contains port-specific registers that must be accessed
++ * on a per-port basis. It includes controls for port LEDs, QSGMII PCS,
++ * rate adaptation FIFOs, and the per-port 1588 TSU block.
++ */
++#define LAN8814_PAGE_PORT_REGS 5
++
++/**
++ * LAN8814_PAGE_SYSTEM_CTRL - Selects Extended Page 31.
++ *
++ * This page appears to hold fundamental system or global controls. In the
++ * driver, it is used by the related LAN8804 to access the
++ * LAN8814_CLOCK_MANAGEMENT register.
++ */
++#define LAN8814_PAGE_SYSTEM_CTRL 31
++
+ #define LAN_EXT_PAGE_ACCESS_CONTROL                   0x16
+ #define LAN_EXT_PAGE_ACCESS_ADDRESS_DATA              0x17
+ #define LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC              0x4000
+@@ -2622,35 +2668,46 @@ static int lan8814_config_ts_intr(struct phy_device *phydev, bool enable)
+                     PTP_TSU_INT_EN_PTP_RX_TS_EN_ |
+                     PTP_TSU_INT_EN_PTP_RX_TS_OVRFL_EN_;
+-      return lanphy_write_page_reg(phydev, 5, PTP_TSU_INT_EN, val);
++      return lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                   PTP_TSU_INT_EN, val);
+ }
+ static void lan8814_ptp_rx_ts_get(struct phy_device *phydev,
+                                 u32 *seconds, u32 *nano_seconds, u16 *seq_id)
+ {
+-      *seconds = lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_SEC_HI);
++      *seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                      PTP_RX_INGRESS_SEC_HI);
+       *seconds = (*seconds << 16) |
+-                 lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_SEC_LO);
++                 lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                      PTP_RX_INGRESS_SEC_LO);
+-      *nano_seconds = lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_NS_HI);
++      *nano_seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                           PTP_RX_INGRESS_NS_HI);
+       *nano_seconds = ((*nano_seconds & 0x3fff) << 16) |
+-                      lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_NS_LO);
++                      lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                           PTP_RX_INGRESS_NS_LO);
+-      *seq_id = lanphy_read_page_reg(phydev, 5, PTP_RX_MSG_HEADER2);
++      *seq_id = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                     PTP_RX_MSG_HEADER2);
+ }
+ static void lan8814_ptp_tx_ts_get(struct phy_device *phydev,
+                                 u32 *seconds, u32 *nano_seconds, u16 *seq_id)
+ {
+-      *seconds = lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_SEC_HI);
++      *seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                      PTP_TX_EGRESS_SEC_HI);
+       *seconds = *seconds << 16 |
+-                 lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_SEC_LO);
++                 lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                      PTP_TX_EGRESS_SEC_LO);
+-      *nano_seconds = lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_NS_HI);
++      *nano_seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                           PTP_TX_EGRESS_NS_HI);
+       *nano_seconds = ((*nano_seconds & 0x3fff) << 16) |
+-                      lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_NS_LO);
++                      lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                           PTP_TX_EGRESS_NS_LO);
+-      *seq_id = lanphy_read_page_reg(phydev, 5, PTP_TX_MSG_HEADER2);
++      *seq_id = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                     PTP_TX_MSG_HEADER2);
+ }
+ static int lan8814_ts_info(struct mii_timestamper *mii_ts, struct kernel_ethtool_ts_info *info)
+@@ -2685,11 +2742,11 @@ static void lan8814_flush_fifo(struct phy_device *phydev, bool egress)
+       int i;
+       for (i = 0; i < FIFO_SIZE; ++i)
+-              lanphy_read_page_reg(phydev, 5,
++              lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
+                                    egress ? PTP_TX_MSG_HEADER2 : PTP_RX_MSG_HEADER2);
+       /* Read to clear overflow status bit */
+-      lanphy_read_page_reg(phydev, 5, PTP_TSU_INT_STS);
++      lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TSU_INT_STS);
+ }
+ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts,
+@@ -2739,20 +2796,26 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts,
+               rxcfg |= PTP_RX_PARSE_CONFIG_IPV4_EN_ | PTP_RX_PARSE_CONFIG_IPV6_EN_;
+               txcfg |= PTP_TX_PARSE_CONFIG_IPV4_EN_ | PTP_TX_PARSE_CONFIG_IPV6_EN_;
+       }
+-      lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_PARSE_CONFIG, rxcfg);
+-      lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_PARSE_CONFIG, txcfg);
++      lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_PARSE_CONFIG, rxcfg);
++      lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_PARSE_CONFIG, txcfg);
+       pkt_ts_enable = PTP_TIMESTAMP_EN_SYNC_ | PTP_TIMESTAMP_EN_DREQ_ |
+                       PTP_TIMESTAMP_EN_PDREQ_ | PTP_TIMESTAMP_EN_PDRES_;
+-      lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_TIMESTAMP_EN, pkt_ts_enable);
+-      lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_TIMESTAMP_EN, pkt_ts_enable);
++      lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_TIMESTAMP_EN, pkt_ts_enable);
++      lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_TIMESTAMP_EN, pkt_ts_enable);
+       if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ONESTEP_SYNC) {
+-              lanphy_modify_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
++              lanphy_modify_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                                     PTP_TX_MOD,
+                                      PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_,
+                                      PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
+       } else if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ON) {
+-              lanphy_modify_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
++              lanphy_modify_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                                     PTP_TX_MOD,
+                                      PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_,
+                                      0);
+       }
+@@ -2876,29 +2939,41 @@ static bool lan8814_rxtstamp(struct mii_timestamper *mii_ts, struct sk_buff *skb
+ static void lan8814_ptp_clock_set(struct phy_device *phydev,
+                                 time64_t sec, u32 nsec)
+ {
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_LO, lower_16_bits(sec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_MID, upper_16_bits(sec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_HI, upper_32_bits(sec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_NS_LO, lower_16_bits(nsec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_NS_HI, upper_16_bits(nsec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_SEC_LO, lower_16_bits(sec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_SEC_MID, upper_16_bits(sec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_SEC_HI, upper_32_bits(sec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_NS_LO, lower_16_bits(nsec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_NS_HI, upper_16_bits(nsec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_CLOCK_LOAD_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL,
++                            PTP_CMD_CTL_PTP_CLOCK_LOAD_);
+ }
+ static void lan8814_ptp_clock_get(struct phy_device *phydev,
+                                 time64_t *sec, u32 *nsec)
+ {
+-      lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_CLOCK_READ_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL,
++                            PTP_CMD_CTL_PTP_CLOCK_READ_);
+-      *sec = lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_HI);
++      *sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                  PTP_CLOCK_READ_SEC_HI);
+       *sec <<= 16;
+-      *sec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_MID);
++      *sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                   PTP_CLOCK_READ_SEC_MID);
+       *sec <<= 16;
+-      *sec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_LO);
++      *sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                   PTP_CLOCK_READ_SEC_LO);
+-      *nsec = lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_NS_HI);
++      *nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                   PTP_CLOCK_READ_NS_HI);
+       *nsec <<= 16;
+-      *nsec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_NS_LO);
++      *nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                    PTP_CLOCK_READ_NS_LO);
+ }
+ static int lan8814_ptpci_gettime64(struct ptp_clock_info *ptpci,
+@@ -2937,14 +3012,18 @@ static void lan8814_ptp_set_target(struct phy_device *phydev, int event,
+                                  s64 start_sec, u32 start_nsec)
+ {
+       /* Set the start time */
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_SEC_LO(event),
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LAN8814_PTP_CLOCK_TARGET_SEC_LO(event),
+                             lower_16_bits(start_sec));
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_SEC_HI(event),
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LAN8814_PTP_CLOCK_TARGET_SEC_HI(event),
+                             upper_16_bits(start_sec));
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_NS_LO(event),
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LAN8814_PTP_CLOCK_TARGET_NS_LO(event),
+                             lower_16_bits(start_nsec));
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_NS_HI(event),
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LAN8814_PTP_CLOCK_TARGET_NS_HI(event),
+                             upper_16_bits(start_nsec) & 0x3fff);
+ }
+@@ -3042,9 +3121,11 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev,
+                       adjustment_value_lo = adjustment_value & 0xffff;
+                       adjustment_value_hi = (adjustment_value >> 16) & 0x3fff;
+-                      lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO,
++                      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                            PTP_LTC_STEP_ADJ_LO,
+                                             adjustment_value_lo);
+-                      lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI,
++                      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                            PTP_LTC_STEP_ADJ_HI,
+                                             PTP_LTC_STEP_ADJ_DIR_ |
+                                             adjustment_value_hi);
+                       seconds -= ((s32)adjustment_value);
+@@ -3062,9 +3143,11 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev,
+                       adjustment_value_lo = adjustment_value & 0xffff;
+                       adjustment_value_hi = (adjustment_value >> 16) & 0x3fff;
+-                      lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO,
++                      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                            PTP_LTC_STEP_ADJ_LO,
+                                             adjustment_value_lo);
+-                      lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI,
++                      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                            PTP_LTC_STEP_ADJ_HI,
+                                             adjustment_value_hi);
+                       seconds += ((s32)adjustment_value);
+@@ -3072,8 +3155,8 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev,
+                       set_seconds += adjustment_value;
+                       lan8814_ptp_update_target(phydev, set_seconds);
+               }
+-              lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL,
+-                                    PTP_CMD_CTL_PTP_LTC_STEP_SEC_);
++              lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                    PTP_CMD_CTL, PTP_CMD_CTL_PTP_LTC_STEP_SEC_);
+       }
+       if (nano_seconds) {
+               u16 nano_seconds_lo;
+@@ -3082,12 +3165,14 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev,
+               nano_seconds_lo = nano_seconds & 0xffff;
+               nano_seconds_hi = (nano_seconds >> 16) & 0x3fff;
+-              lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO,
++              lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                    PTP_LTC_STEP_ADJ_LO,
+                                     nano_seconds_lo);
+-              lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI,
++              lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                    PTP_LTC_STEP_ADJ_HI,
+                                     PTP_LTC_STEP_ADJ_DIR_ |
+                                     nano_seconds_hi);
+-              lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL,
++              lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL,
+                                     PTP_CMD_CTL_PTP_LTC_STEP_NSEC_);
+       }
+ }
+@@ -3129,8 +3214,10 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm)
+               kszphy_rate_adj_hi |= PTP_CLOCK_RATE_ADJ_DIR_;
+       mutex_lock(&shared->shared_lock);
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_RATE_ADJ_HI, kszphy_rate_adj_hi);
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_RATE_ADJ_LO, kszphy_rate_adj_lo);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CLOCK_RATE_ADJ_HI,
++                            kszphy_rate_adj_hi);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CLOCK_RATE_ADJ_LO,
++                            kszphy_rate_adj_lo);
+       mutex_unlock(&shared->shared_lock);
+       return 0;
+@@ -3139,17 +3226,17 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm)
+ static void lan8814_ptp_set_reload(struct phy_device *phydev, int event,
+                                  s64 period_sec, u32 period_nsec)
+ {
+-      lanphy_write_page_reg(phydev, 4,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                             LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_LO(event),
+                             lower_16_bits(period_sec));
+-      lanphy_write_page_reg(phydev, 4,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                             LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_HI(event),
+                             upper_16_bits(period_sec));
+-      lanphy_write_page_reg(phydev, 4,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                             LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_LO(event),
+                             lower_16_bits(period_nsec));
+-      lanphy_write_page_reg(phydev, 4,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                             LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_HI(event),
+                             upper_16_bits(period_nsec) & 0x3fff);
+ }
+@@ -3162,7 +3249,7 @@ static void lan8814_ptp_enable_event(struct phy_device *phydev, int event,
+        * local time reaches or pass it
+        * Set the polarity high
+        */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_GENERAL_CONFIG,
+                              LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_MASK(event) |
+                              LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width) |
+                              LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event) |
+@@ -3177,7 +3264,7 @@ static void lan8814_ptp_disable_event(struct phy_device *phydev, int event)
+       lan8814_ptp_set_target(phydev, event, 0xFFFFFFFF, 0);
+       /* And then reload once it recheas the target */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_GENERAL_CONFIG,
+                              LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event),
+                              LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event));
+ }
+@@ -3188,15 +3275,18 @@ static void lan8814_ptp_perout_off(struct phy_device *phydev, int pin)
+        * 1: select as gpio,
+        * 0: select alt func
+        */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_EN_ADDR(pin),
+                              LAN8814_GPIO_EN_BIT(pin),
+                              LAN8814_GPIO_EN_BIT(pin));
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_DIR_ADDR(pin),
+                              LAN8814_GPIO_DIR_BIT(pin),
+                              0);
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_BUF_ADDR(pin),
+                              LAN8814_GPIO_BUF_BIT(pin),
+                              0);
+ }
+@@ -3204,17 +3294,20 @@ static void lan8814_ptp_perout_off(struct phy_device *phydev, int pin)
+ static void lan8814_ptp_perout_on(struct phy_device *phydev, int pin)
+ {
+       /* Set as gpio output */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_DIR_ADDR(pin),
+                              LAN8814_GPIO_DIR_BIT(pin),
+                              LAN8814_GPIO_DIR_BIT(pin));
+       /* Enable gpio 0:for alternate function, 1:gpio */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_EN_ADDR(pin),
+                              LAN8814_GPIO_EN_BIT(pin),
+                              0);
+       /* Set buffer type to push pull */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_BUF_ADDR(pin),
+                              LAN8814_GPIO_BUF_BIT(pin),
+                              LAN8814_GPIO_BUF_BIT(pin));
+ }
+@@ -3336,27 +3429,29 @@ static int lan8814_ptp_perout(struct ptp_clock_info *ptpci,
+ static void lan8814_ptp_extts_on(struct phy_device *phydev, int pin, u32 flags)
+ {
+       /* Set as gpio input */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_DIR_ADDR(pin),
+                              LAN8814_GPIO_DIR_BIT(pin),
+                              0);
+       /* Map the pin to ltc pin 0 of the capture map registers */
+-      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO,
+-                             pin,
+-                             pin);
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             PTP_GPIO_CAP_MAP_LO, pin, pin);
+       /* Enable capture on the edges of the ltc pin */
+       if (flags & PTP_RISING_EDGE)
+-              lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++              lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                     PTP_GPIO_CAP_EN,
+                                      PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0),
+                                      PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0));
+       if (flags & PTP_FALLING_EDGE)
+-              lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++              lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                     PTP_GPIO_CAP_EN,
+                                      PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0),
+                                      PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0));
+       /* Enable interrupt top interrupt */
+-      lanphy_modify_page_reg(phydev, 4, PTP_COMMON_INT_ENA,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_COMMON_INT_ENA,
+                              PTP_COMMON_INT_ENA_GPIO_CAP_EN,
+                              PTP_COMMON_INT_ENA_GPIO_CAP_EN);
+ }
+@@ -3364,28 +3459,31 @@ static void lan8814_ptp_extts_on(struct phy_device *phydev, int pin, u32 flags)
+ static void lan8814_ptp_extts_off(struct phy_device *phydev, int pin)
+ {
+       /* Set as gpio out */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_DIR_ADDR(pin),
+                              LAN8814_GPIO_DIR_BIT(pin),
+                              LAN8814_GPIO_DIR_BIT(pin));
+       /* Enable alternate, 0:for alternate function, 1:gpio */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_EN_ADDR(pin),
+                              LAN8814_GPIO_EN_BIT(pin),
+                              0);
+       /* Clear the mapping of pin to registers 0 of the capture registers */
+-      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             PTP_GPIO_CAP_MAP_LO,
+                              GENMASK(3, 0),
+                              0);
+       /* Disable capture on both of the edges */
+-      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_GPIO_CAP_EN,
+                              PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin) |
+                              PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin),
+                              0);
+       /* Disable interrupt top interrupt */
+-      lanphy_modify_page_reg(phydev, 4, PTP_COMMON_INT_ENA,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_COMMON_INT_ENA,
+                              PTP_COMMON_INT_ENA_GPIO_CAP_EN,
+                              0);
+ }
+@@ -3522,7 +3620,8 @@ static void lan8814_get_tx_ts(struct kszphy_ptp_priv *ptp_priv)
+               /* If other timestamps are available in the FIFO,
+                * process them.
+                */
+-              reg = lanphy_read_page_reg(phydev, 5, PTP_CAP_INFO);
++              reg = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                         PTP_CAP_INFO);
+       } while (PTP_CAP_INFO_TX_TS_CNT_GET_(reg) > 0);
+ }
+@@ -3595,7 +3694,8 @@ static void lan8814_get_rx_ts(struct kszphy_ptp_priv *ptp_priv)
+               /* If other timestamps are available in the FIFO,
+                * process them.
+                */
+-              reg = lanphy_read_page_reg(phydev, 5, PTP_CAP_INFO);
++              reg = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                         PTP_CAP_INFO);
+       } while (PTP_CAP_INFO_RX_TS_CNT_GET_(reg) > 0);
+ }
+@@ -3632,31 +3732,40 @@ static int lan8814_gpio_process_cap(struct lan8814_shared_priv *shared)
+       /* This is 0 because whatever was the input pin it was mapped it to
+        * ltc gpio pin 0
+        */
+-      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_SEL,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_GPIO_SEL,
+                              PTP_GPIO_SEL_GPIO_SEL(0),
+                              PTP_GPIO_SEL_GPIO_SEL(0));
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_STS);
++      tmp = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                 PTP_GPIO_CAP_STS);
+       if (!(tmp & PTP_GPIO_CAP_STS_PTP_GPIO_RE_STS(0)) &&
+           !(tmp & PTP_GPIO_CAP_STS_PTP_GPIO_FE_STS(0)))
+               return -1;
+       if (tmp & BIT(0)) {
+-              sec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_SEC_HI_CAP);
++              sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                         PTP_GPIO_RE_LTC_SEC_HI_CAP);
+               sec <<= 16;
+-              sec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_SEC_LO_CAP);
++              sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                          PTP_GPIO_RE_LTC_SEC_LO_CAP);
+-              nsec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_HI_CAP) & 0x3fff;
++              nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                          PTP_GPIO_RE_LTC_NS_HI_CAP) & 0x3fff;
+               nsec <<= 16;
+-              nsec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_LO_CAP);
++              nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                           PTP_GPIO_RE_LTC_NS_LO_CAP);
+       } else {
+-              sec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_SEC_HI_CAP);
++              sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                         PTP_GPIO_FE_LTC_SEC_HI_CAP);
+               sec <<= 16;
+-              sec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_SEC_LO_CAP);
++              sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                          PTP_GPIO_FE_LTC_SEC_LO_CAP);
+-              nsec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_NS_HI_CAP) & 0x3fff;
++              nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                          PTP_GPIO_FE_LTC_NS_HI_CAP) & 0x3fff;
+               nsec <<= 16;
+-              nsec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_LO_CAP);
++              nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                           PTP_GPIO_RE_LTC_NS_LO_CAP);
+       }
+       ptp_event.index = 0;
+@@ -3682,15 +3791,16 @@ static int lan8814_handle_gpio_interrupt(struct phy_device *phydev, u16 status)
+ static int lan8804_config_init(struct phy_device *phydev)
+ {
+       /* MDI-X setting for swap A,B transmit */
+-      lanphy_modify_page_reg(phydev, 2, LAN8804_ALIGN_SWAP,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8804_ALIGN_SWAP,
+                              LAN8804_ALIGN_TX_A_B_SWAP_MASK,
+                              LAN8804_ALIGN_TX_A_B_SWAP);
+       /* Make sure that the PHY will not stop generating the clock when the
+        * link partner goes down
+        */
+-      lanphy_write_page_reg(phydev, 31, LAN8814_CLOCK_MANAGEMENT, 0x27e);
+-      lanphy_read_page_reg(phydev, 1, LAN8814_LINK_QUALITY);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_SYSTEM_CTRL,
++                            LAN8814_CLOCK_MANAGEMENT, 0x27e);
++      lanphy_read_page_reg(phydev, LAN8814_PAGE_AFE_PMA, LAN8814_LINK_QUALITY);
+       return 0;
+ }
+@@ -3772,7 +3882,8 @@ static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev)
+       }
+       while (true) {
+-              irq_status = lanphy_read_page_reg(phydev, 5, PTP_TSU_INT_STS);
++              irq_status = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                                PTP_TSU_INT_STS);
+               if (!irq_status)
+                       break;
+@@ -3800,7 +3911,7 @@ static int lan8814_config_intr(struct phy_device *phydev)
+ {
+       int err;
+-      lanphy_write_page_reg(phydev, 4, LAN8814_INTR_CTRL_REG,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_INTR_CTRL_REG,
+                             LAN8814_INTR_CTRL_REG_POLARITY |
+                             LAN8814_INTR_CTRL_REG_INTR_ENABLE);
+@@ -3831,29 +3942,36 @@ static void lan8814_ptp_init(struct phy_device *phydev)
+           !IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING))
+               return;
+-      lanphy_write_page_reg(phydev, 5, TSU_HARD_RESET, TSU_HARD_RESET_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            TSU_HARD_RESET, TSU_HARD_RESET_);
+-      lanphy_modify_page_reg(phydev, 5, PTP_TX_MOD,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TX_MOD,
+                              PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_,
+                              PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_);
+-      lanphy_modify_page_reg(phydev, 5, PTP_RX_MOD,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_RX_MOD,
+                              PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_,
+                              PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_);
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_CONFIG, 0);
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_CONFIG, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_PARSE_CONFIG, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_PARSE_CONFIG, 0);
+       /* Removing default registers configs related to L2 and IP */
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_L2_ADDR_EN, 0);
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_L2_ADDR_EN, 0);
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_IP_ADDR_EN, 0);
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_IP_ADDR_EN, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_PARSE_L2_ADDR_EN, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_PARSE_L2_ADDR_EN, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_PARSE_IP_ADDR_EN, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_PARSE_IP_ADDR_EN, 0);
+       /* Disable checking for minorVersionPTP field */
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_VERSION,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_RX_VERSION,
+                             PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0));
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_VERSION,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TX_VERSION,
+                             PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0));
+       skb_queue_head_init(&ptp_priv->tx_queue);
+@@ -3934,12 +4052,14 @@ static int lan8814_ptp_probe_once(struct phy_device *phydev)
+       /* The EP.4 is shared between all the PHYs in the package and also it
+        * can be accessed by any of the PHYs
+        */
+-      lanphy_write_page_reg(phydev, 4, LTC_HARD_RESET, LTC_HARD_RESET_);
+-      lanphy_write_page_reg(phydev, 4, PTP_OPERATING_MODE,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LTC_HARD_RESET, LTC_HARD_RESET_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_OPERATING_MODE,
+                             PTP_OPERATING_MODE_STANDALONE_);
+       /* Enable ptp to run LTC clock for ptp and gpio 1PPS operation */
+-      lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_ENABLE_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL,
++                            PTP_CMD_CTL_PTP_ENABLE_);
+       return 0;
+ }
+@@ -3948,14 +4068,16 @@ static void lan8814_setup_led(struct phy_device *phydev, int val)
+ {
+       int temp;
+-      temp = lanphy_read_page_reg(phydev, 5, LAN8814_LED_CTRL_1);
++      temp = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                  LAN8814_LED_CTRL_1);
+       if (val)
+               temp |= LAN8814_LED_CTRL_1_KSZ9031_LED_MODE_;
+       else
+               temp &= ~LAN8814_LED_CTRL_1_KSZ9031_LED_MODE_;
+-      lanphy_write_page_reg(phydev, 5, LAN8814_LED_CTRL_1, temp);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            LAN8814_LED_CTRL_1, temp);
+ }
+ static int lan8814_config_init(struct phy_device *phydev)
+@@ -3963,17 +4085,19 @@ static int lan8814_config_init(struct phy_device *phydev)
+       struct kszphy_priv *lan8814 = phydev->priv;
+       /* Reset the PHY */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_QSGMII_SOFT_RESET,
+                              LAN8814_QSGMII_SOFT_RESET_BIT,
+                              LAN8814_QSGMII_SOFT_RESET_BIT);
+       /* Disable ANEG with QSGMII PCS Host side */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_QSGMII_PCS1G_ANEG_CONFIG,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_QSGMII_PCS1G_ANEG_CONFIG,
+                              LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA,
+                              0);
+       /* MDI-X setting for swap A,B transmit */
+-      lanphy_modify_page_reg(phydev, 2, LAN8814_ALIGN_SWAP,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8814_ALIGN_SWAP,
+                              LAN8814_ALIGN_TX_A_B_SWAP_MASK,
+                              LAN8814_ALIGN_TX_A_B_SWAP);
+@@ -4010,7 +4134,7 @@ static void lan8814_clear_2psp_bit(struct phy_device *phydev)
+        * cable is removed then the LED was still one even though there is no
+        * link
+        */
+-      lanphy_modify_page_reg(phydev, 2, LAN8814_EEE_STATE,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8814_EEE_STATE,
+                              LAN8814_EEE_STATE_MASK2P5P,
+                              0);
+ }
+@@ -4021,7 +4145,7 @@ static void lan8814_update_meas_time(struct phy_device *phydev)
+        * longer than 100m to be used. This configuration can be used
+        * regardless of the mode of operation of the PHY
+        */
+-      lanphy_modify_page_reg(phydev, 1, LAN8814_PD_CONTROLS,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_AFE_PMA, LAN8814_PD_CONTROLS,
+                              LAN8814_PD_CONTROLS_PD_MEAS_TIME_MASK,
+                              LAN8814_PD_CONTROLS_PD_MEAS_TIME_VAL);
+ }
+@@ -4046,7 +4170,7 @@ static int lan8814_probe(struct phy_device *phydev)
+       /* Strap-in value for PHY address, below register read gives starting
+        * phy address value
+        */
+-      addr = lanphy_read_page_reg(phydev, 4, 0) & 0x1F;
++      addr = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, 0) & 0x1F;
+       devm_phy_package_join(&phydev->mdio.dev, phydev,
+                             addr, sizeof(struct lan8814_shared_priv));
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch b/queue-6.12/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
new file mode 100644 (file)
index 0000000..7bd35c9
--- /dev/null
@@ -0,0 +1,59 @@
+From ecfbb5dbd7b8097f4c9bab1cbcc62cbe5d30640d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:35 +0530
+Subject: net: sched: act_connmark: initialize struct tc_ife to fix kernel leak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit 62b656e43eaeae445a39cd8021a4f47065af4389 ]
+
+In tcf_connmark_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: 22a5dc0e5e3e ("net: sched: Introduce connmark action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-2-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_connmark.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 3e89927d71164..26ba8c2d20abf 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -195,13 +195,15 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+       const struct tcf_connmark_parms *parms;
+-      struct tc_connmark opt = {
+-              .index   = ci->tcf_index,
+-              .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+-      };
++      struct tc_connmark opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index   = ci->tcf_index;
++      opt.refcnt  = refcount_read(&ci->tcf_refcnt) - ref;
++      opt.bindcnt = atomic_read(&ci->tcf_bindcnt) - bind;
++
+       rcu_read_lock();
+       parms = rcu_dereference(ci->parms);
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch b/queue-6.12/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
new file mode 100644 (file)
index 0000000..f6b3cdc
--- /dev/null
@@ -0,0 +1,70 @@
+From 0b020ccbdccbcd6c84656b735c17b3fe58a73817 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:36 +0530
+Subject: net: sched: act_ife: initialize struct tc_ife to fix KMSAN
+ kernel-infoleak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit ce50039be49eea9b4cd8873ca6eccded1b4a130a ]
+
+Fix a KMSAN kernel-infoleak detected  by the syzbot .
+
+[net?] KMSAN: kernel-infoleak in __skb_datagram_iter
+
+In tcf_ife_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+This change silences the KMSAN report and prevents potential information
+leaks from the kernel memory.
+
+This fix has been tested and validated by syzbot. This patch closes the
+bug reported at the following syzkaller link and ensures no infoleak.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: ef6980b6becb ("introduce IFE action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-3-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ife.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index 107c6d83dc5c4..7c6975632fc2e 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -644,13 +644,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_ife_info *ife = to_ife(a);
+       struct tcf_ife_params *p;
+-      struct tc_ife opt = {
+-              .index = ife->tcf_index,
+-              .refcnt = refcount_read(&ife->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
+-      };
++      struct tc_ife opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index = ife->tcf_index,
++      opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref,
++      opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
++
+       spin_lock_bh(&ife->tcf_lock);
+       opt.action = ife->tcf_action;
+       p = rcu_dereference_protected(ife->params,
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-smc-fix-mismatch-between-clc-header-and-proposal.patch b/queue-6.12/net-smc-fix-mismatch-between-clc-header-and-proposal.patch
new file mode 100644 (file)
index 0000000..60b2d24
--- /dev/null
@@ -0,0 +1,55 @@
+From d21a504269984e4c1e6f6a2bd5ed21cf3c20e9a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 10:40:29 +0800
+Subject: net/smc: fix mismatch between CLC header and proposal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit ec33f2e5a2d0dbbfd71435209aee812fdc9369b8 ]
+
+The current CLC proposal message construction uses a mix of
+`ini->smc_type_v1/v2` and `pclc_base->hdr.typev1/v2` to decide whether
+to include optional extensions (IPv6 prefix extension for v1, and v2
+extension). This leads to a critical inconsistency: when
+`smc_clc_prfx_set()` fails - for example, in IPv6-only environments with
+only link-local addresses, or when the local IP address and the outgoing
+interface’s network address are not in the same subnet.
+
+As a result, the proposal message is assembled using the stale
+`ini->smc_type_v1` value—causing the IPv6 prefix extension to be
+included even though the header indicates v1 is not supported.
+The peer then receives a malformed CLC proposal where the header type
+does not match the payload, and immediately resets the connection.
+
+The fix ensures consistency between the CLC header flags and the actual
+payload by synchronizing `ini->smc_type_v1` with `pclc_base->hdr.typev1`
+when prefix setup fails.
+
+Fixes: 8c3dca341aea ("net/smc: build and send V2 CLC proposal")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20251107024029.88753-1-alibuda@linux.alibaba.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/smc_clc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
+index 8a794333e9927..b3a8053d4ab4b 100644
+--- a/net/smc/smc_clc.c
++++ b/net/smc/smc_clc.c
+@@ -887,6 +887,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
+                               return SMC_CLC_DECL_CNFERR;
+                       }
+                       pclc_base->hdr.typev1 = SMC_TYPE_N;
++                      ini->smc_type_v1 = SMC_TYPE_N;
+               } else {
+                       pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
+                       plen += sizeof(*pclc_prfx) +
+-- 
+2.51.0
+
diff --git a/queue-6.12/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch b/queue-6.12/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch
new file mode 100644 (file)
index 0000000..90ed466
--- /dev/null
@@ -0,0 +1,100 @@
+From c4bc9a5527eda644bff316fdc837a91db6dd37c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jul 2025 09:01:54 +0000
+Subject: net_sched: act_connmark: use RCU in tcf_connmark_dump()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0d752877705c0252ef2726e4c63c5573f048951c ]
+
+Also storing tcf_action into struct tcf_connmark_parms
+makes sure there is no discrepancy in tcf_connmark_act().
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250709090204.797558-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tc_act/tc_connmark.h |  1 +
+ net/sched/act_connmark.c         | 18 ++++++++++--------
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/tc_act/tc_connmark.h b/include/net/tc_act/tc_connmark.h
+index e8dd77a967480..a5ce83f3eea4b 100644
+--- a/include/net/tc_act/tc_connmark.h
++++ b/include/net/tc_act/tc_connmark.h
+@@ -7,6 +7,7 @@
+ struct tcf_connmark_parms {
+       struct net *net;
+       u16 zone;
++      int action;
+       struct rcu_head rcu;
+ };
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 0fce631e7c911..3e89927d71164 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -88,7 +88,7 @@ TC_INDIRECT_SCOPE int tcf_connmark_act(struct sk_buff *skb,
+       /* using overlimits stats to count how many packets marked */
+       tcf_action_inc_overlimit_qstats(&ca->common);
+ out:
+-      return READ_ONCE(ca->tcf_action);
++      return parms->action;
+ }
+ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
+@@ -167,6 +167,8 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+       if (err < 0)
+               goto release_idr;
++      nparms->action = parm->action;
++
+       spin_lock_bh(&ci->tcf_lock);
+       goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+       oparms = rcu_replace_pointer(ci->parms, nparms, lockdep_is_held(&ci->tcf_lock));
+@@ -190,20 +192,20 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+                                   int bind, int ref)
+ {
++      const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+-      struct tcf_connmark_info *ci = to_connmark(a);
++      const struct tcf_connmark_parms *parms;
+       struct tc_connmark opt = {
+               .index   = ci->tcf_index,
+               .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+               .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+       };
+-      struct tcf_connmark_parms *parms;
+       struct tcf_t t;
+-      spin_lock_bh(&ci->tcf_lock);
+-      parms = rcu_dereference_protected(ci->parms, lockdep_is_held(&ci->tcf_lock));
++      rcu_read_lock();
++      parms = rcu_dereference(ci->parms);
+-      opt.action = ci->tcf_action;
++      opt.action = parms->action;
+       opt.zone = parms->zone;
+       if (nla_put(skb, TCA_CONNMARK_PARMS, sizeof(opt), &opt))
+               goto nla_put_failure;
+@@ -212,12 +214,12 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       if (nla_put_64bit(skb, TCA_CONNMARK_TM, sizeof(t), &t,
+                         TCA_CONNMARK_PAD))
+               goto nla_put_failure;
+-      spin_unlock_bh(&ci->tcf_lock);
++      rcu_read_unlock();
+       return skb->len;
+ nla_put_failure:
+-      spin_unlock_bh(&ci->tcf_lock);
++      rcu_read_unlock();
+       nlmsg_trim(skb, b);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net_sched-limit-try_bulk_dequeue_skb-batches.patch b/queue-6.12/net_sched-limit-try_bulk_dequeue_skb-batches.patch
new file mode 100644 (file)
index 0000000..9e9b304
--- /dev/null
@@ -0,0 +1,143 @@
+From 0813feb97ee108670df339c3f80b9c18f7ce46f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:12:15 +0000
+Subject: net_sched: limit try_bulk_dequeue_skb() batches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0345552a653ce5542affeb69ac5aa52177a5199b ]
+
+After commit 100dfa74cad9 ("inet: dev_queue_xmit() llist adoption")
+I started seeing many qdisc requeues on IDPF under high TX workload.
+
+$ tc -s qd sh dev eth1 handle 1: ; sleep 1; tc -s qd sh dev eth1 handle 1:
+qdisc mq 1: root
+ Sent 43534617319319 bytes 268186451819 pkt (dropped 0, overlimits 0 requeues 3532840114)
+ backlog 1056Kb 6675p requeues 3532840114
+qdisc mq 1: root
+ Sent 43554665866695 bytes 268309964788 pkt (dropped 0, overlimits 0 requeues 3537737653)
+ backlog 781164b 4822p requeues 3537737653
+
+This is caused by try_bulk_dequeue_skb() being only limited by BQL budget.
+
+perf record -C120-239 -e qdisc:qdisc_dequeue sleep 1 ; perf script
+...
+ netperf 75332 [146]  2711.138269: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1292 skbaddr=0xff378005a1e9f200
+ netperf 75332 [146]  2711.138953: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1213 skbaddr=0xff378004d607a500
+ netperf 75330 [144]  2711.139631: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1233 skbaddr=0xff3780046be20100
+ netperf 75333 [147]  2711.140356: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1093 skbaddr=0xff37800514845b00
+ netperf 75337 [151]  2711.141037: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1353 skbaddr=0xff37800460753300
+ netperf 75337 [151]  2711.141877: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1367 skbaddr=0xff378004e72c7b00
+ netperf 75330 [144]  2711.142643: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1202 skbaddr=0xff3780045bd60000
+...
+
+This is bad because :
+
+1) Large batches hold one victim cpu for a very long time.
+
+2) Driver often hit their own TX ring limit (all slots are used).
+
+3) We call dev_requeue_skb()
+
+4) Requeues are using a FIFO (q->gso_skb), breaking qdisc ability to
+   implement FQ or priority scheduling.
+
+5) dequeue_skb() gets packets from q->gso_skb one skb at a time
+   with no xmit_more support. This is causing many spinlock games
+   between the qdisc and the device driver.
+
+Requeues were supposed to be very rare, lets keep them this way.
+
+Limit batch sizes to /proc/sys/net/core/dev_weight (default 64) as
+__qdisc_run() was designed to use.
+
+Fixes: 5772e9a3463b ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/20251109161215.2574081-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_generic.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 8874ae6680952..d27383c54b70b 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -179,9 +179,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
+ static void try_bulk_dequeue_skb(struct Qdisc *q,
+                                struct sk_buff *skb,
+                                const struct netdev_queue *txq,
+-                               int *packets)
++                               int *packets, int budget)
+ {
+       int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
++      int cnt = 0;
+       while (bytelimit > 0) {
+               struct sk_buff *nskb = q->dequeue(q);
+@@ -192,8 +193,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
+               bytelimit -= nskb->len; /* covers GSO len */
+               skb->next = nskb;
+               skb = nskb;
+-              (*packets)++; /* GSO counts as one pkt */
++              if (++cnt >= budget)
++                      break;
+       }
++      (*packets) += cnt;
+       skb_mark_not_on_list(skb);
+ }
+@@ -227,7 +230,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
+  * A requeued skb (via q->gso_skb) can also be a SKB list.
+  */
+ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+-                                 int *packets)
++                                 int *packets, int budget)
+ {
+       const struct netdev_queue *txq = q->dev_queue;
+       struct sk_buff *skb = NULL;
+@@ -294,7 +297,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+       if (skb) {
+ bulk:
+               if (qdisc_may_bulk(q))
+-                      try_bulk_dequeue_skb(q, skb, txq, packets);
++                      try_bulk_dequeue_skb(q, skb, txq, packets, budget);
+               else
+                       try_bulk_dequeue_skb_slow(q, skb, packets);
+       }
+@@ -386,7 +389,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+  *                            >0 - queue is not empty.
+  *
+  */
+-static inline bool qdisc_restart(struct Qdisc *q, int *packets)
++static inline bool qdisc_restart(struct Qdisc *q, int *packets, int budget)
+ {
+       spinlock_t *root_lock = NULL;
+       struct netdev_queue *txq;
+@@ -395,7 +398,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
+       bool validate;
+       /* Dequeue packet */
+-      skb = dequeue_skb(q, &validate, packets);
++      skb = dequeue_skb(q, &validate, packets, budget);
+       if (unlikely(!skb))
+               return false;
+@@ -413,7 +416,7 @@ void __qdisc_run(struct Qdisc *q)
+       int quota = READ_ONCE(net_hotdata.dev_tx_weight);
+       int packets;
+-      while (qdisc_restart(q, &packets)) {
++      while (qdisc_restart(q, &packets, quota)) {
+               quota -= packets;
+               if (quota <= 0) {
+                       if (q->flags & TCQ_F_NOLOCK)
+-- 
+2.51.0
+
diff --git a/queue-6.12/nfsd-skip-close-replay-processing-if-xdr-encoding-fa.patch b/queue-6.12/nfsd-skip-close-replay-processing-if-xdr-encoding-fa.patch
new file mode 100644 (file)
index 0000000..43773ff
--- /dev/null
@@ -0,0 +1,43 @@
+From 6c137d9f6518fd7462e599a8c83d246849ca52bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Oct 2025 09:49:55 -0400
+Subject: NFSD: Skip close replay processing if XDR encoding fails
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit ff8141e49cf70d2d093a5228f5299ce188de6142 ]
+
+The replay logic added by commit 9411b1d4c7df ("nfsd4: cleanup
+handling of nfsv4.0 closed stateid's") cannot be done if encoding
+failed due to a short send buffer; there's no guarantee that the
+operation encoder has actually encoded the data that is being copied
+to the replay cache.
+
+Reported-by: rtm@csail.mit.edu
+Closes: https://lore.kernel.org/linux-nfs/c3628d57-94ae-48cf-8c9e-49087a28cec9@oracle.com/T/#t
+Fixes: 9411b1d4c7df ("nfsd4: cleanup handling of nfsv4.0 closed stateid's")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: NeilBrown <neil@brown.name>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4xdr.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index 66383eeeed15a..e6b000a4a31aa 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -5800,8 +5800,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
+                */
+               warn_on_nonidempotent_op(op);
+               xdr_truncate_encode(xdr, op_status_offset + XDR_UNIT);
+-      }
+-      if (so) {
++      } else if (so) {
+               int len = xdr->buf->len - (op_status_offset + XDR_UNIT);
+               so->so_replay.rp_status = op->status;
+-- 
+2.51.0
+
diff --git a/queue-6.12/rust-add-fno-isolate-erroneous-paths-dereference-to-.patch b/queue-6.12/rust-add-fno-isolate-erroneous-paths-dereference-to-.patch
new file mode 100644 (file)
index 0000000..27b5704
--- /dev/null
@@ -0,0 +1,41 @@
+From 0b8d183229f2be157cf7233098cafc6f6057ee64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:01:50 +0800
+Subject: rust: Add -fno-isolate-erroneous-paths-dereference to
+ bindgen_skip_c_flags
+
+From: Xi Ruoyao <xry111@xry111.site>
+
+[ Upstream commit fe4b3a34e9a9654d98d274218dac0270779db0ae ]
+
+It's used to work around an objtool issue since commit abb2a5572264
+("LoongArch: Add cflag -fno-isolate-erroneous-paths-dereference"), but
+it's then passed to bindgen and cause an error because Clang does not
+have this option.
+
+Fixes: abb2a5572264 ("LoongArch: Add cflag -fno-isolate-erroneous-paths-dereference")
+Acked-by: Miguel Ojeda <ojeda@kernel.org>
+Tested-by: Mingcong Bai <jeffbai@aosc.io>
+Signed-off-by: Xi Ruoyao <xry111@xry111.site>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rust/Makefile b/rust/Makefile
+index 07c13100000cd..c68c147205ed8 100644
+--- a/rust/Makefile
++++ b/rust/Makefile
+@@ -249,7 +249,7 @@ bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
+       -fno-inline-functions-called-once -fsanitize=bounds-strict \
+       -fstrict-flex-arrays=% -fmin-function-alignment=% \
+       -fzero-init-padding-bits=% -mno-fdpic \
+-      --param=% --param asan-%
++      --param=% --param asan-% -fno-isolate-erroneous-paths-dereference
+ # Derived from `scripts/Makefile.clang`.
+ BINDGEN_TARGET_x86    := x86_64-linux-gnu
+-- 
+2.51.0
+
diff --git a/queue-6.12/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch b/queue-6.12/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
new file mode 100644 (file)
index 0000000..9a81dbc
--- /dev/null
@@ -0,0 +1,86 @@
+From 13523c400b92a12c6eef373217c3c791991f2a7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 11:10:54 +0000
+Subject: sctp: prevent possible shift-out-of-bounds in
+ sctp_transport_update_rto
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 1534ff77757e44bcc4b98d0196bc5c0052fce5fa ]
+
+syzbot reported a possible shift-out-of-bounds [1]
+
+Blamed commit added rto_alpha_max and rto_beta_max set to 1000.
+
+It is unclear if some sctp users are setting very large rto_alpha
+and/or rto_beta.
+
+In order to prevent user regression, perform the test at run time.
+
+Also add READ_ONCE() annotations as sysctl values can change under us.
+
+[1]
+
+UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41
+shift exponent 64 is too large for 32-bit type 'unsigned int'
+CPU: 0 UID: 0 PID: 16704 Comm: syz.2.2320 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:94 [inline]
+  dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120
+  ubsan_epilogue lib/ubsan.c:233 [inline]
+  __ubsan_handle_shift_out_of_bounds+0x27f/0x420 lib/ubsan.c:494
+  sctp_transport_update_rto.cold+0x1c/0x34b net/sctp/transport.c:509
+  sctp_check_transmitted+0x11c4/0x1c30 net/sctp/outqueue.c:1502
+  sctp_outq_sack+0x4ef/0x1b20 net/sctp/outqueue.c:1338
+  sctp_cmd_process_sack net/sctp/sm_sideeffect.c:840 [inline]
+  sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1372 [inline]
+
+Fixes: b58537a1f562 ("net: sctp: fix permissions for rto_alpha and rto_beta knobs")
+Reported-by: syzbot+f8c46c8b2b7f6e076e99@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c81ae.050a0220.3d0d33.014e.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20251106111054.3288127-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/transport.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 31eca29b6cfbf..abb44c0ac1a0b 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -495,6 +495,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+       if (tp->rttvar || tp->srtt) {
+               struct net *net = tp->asoc->base.net;
++              unsigned int rto_beta, rto_alpha;
+               /* 6.3.1 C3) When a new RTT measurement R' is made, set
+                * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+                * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+@@ -506,10 +507,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+                * For example, assuming the default value of RTO.Alpha of
+                * 1/8, rto_alpha would be expressed as 3.
+                */
+-              tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
+-                      + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
+-              tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
+-                      + (rtt >> net->sctp.rto_alpha);
++              rto_beta = READ_ONCE(net->sctp.rto_beta);
++              if (rto_beta < 32)
++                      tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta)
++                              + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> rto_beta);
++              rto_alpha = READ_ONCE(net->sctp.rto_alpha);
++              if (rto_alpha < 32)
++                      tp->srtt = tp->srtt - (tp->srtt >> rto_alpha)
++                              + (rtt >> rto_alpha);
+       } else {
+               /* 6.3.1 C2) When the first RTT measurement R is made, set
+                * SRTT <- R, RTTVAR <- R/2.
+-- 
+2.51.0
+
diff --git a/queue-6.12/selftests-net-local_termination-wait-for-interfaces-.patch b/queue-6.12/selftests-net-local_termination-wait-for-interfaces-.patch
new file mode 100644 (file)
index 0000000..6419f8e
--- /dev/null
@@ -0,0 +1,48 @@
+From 226eb306c1f6d4317d5f7d7763de90e30da0225c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 17:12:09 +0100
+Subject: selftests: net: local_termination: Wait for interfaces to come up
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+[ Upstream commit 57531b3416448d1ced36a2a974a4085ec43d57b0 ]
+
+It seems that most of the tests prepare the interfaces once before the test
+run (setup_prepare()), rely on setup_wait() to wait for link and only then
+run the test(s).
+
+local_termination brings the physical interfaces down and up during test
+run but never wait for them to come up. If the auto-negotiation takes
+some seconds, first test packets are being lost, which leads to
+false-negative test results.
+
+Use setup_wait() in run_test() to make sure auto-negotiation has been
+completed after all simple_if_init() calls on physical interfaces and test
+packets will not be lost because of the race against link establishment.
+
+Fixes: 90b9566aa5cd3f ("selftests: forwarding: add a test for local_termination.sh")
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Link: https://patch.msgid.link/20251106161213.459501-1-alexander.sverdlin@siemens.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/local_termination.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/selftests/net/forwarding/local_termination.sh b/tools/testing/selftests/net/forwarding/local_termination.sh
+index ecd34f364125c..892895659c7e4 100755
+--- a/tools/testing/selftests/net/forwarding/local_termination.sh
++++ b/tools/testing/selftests/net/forwarding/local_termination.sh
+@@ -176,6 +176,8 @@ run_test()
+       local rcv_dmac=$(mac_get $rcv_if_name)
+       local should_receive
++      setup_wait
++
+       tcpdump_start $rcv_if_name
+       mc_route_prepare $send_if_name
+-- 
+2.51.0
+
index e885a5bf4e1ff7686f4d6d124652b0cb2b9cd443..bb4a5c4152ff8e4ca1cc9a8b26e5e1190e8c068d 100644 (file)
@@ -27,3 +27,40 @@ smb-server-fix-possible-memory-leak-in-smb2_read.patch
 smb-server-fix-possible-refcount-leak-in-smb2_sess_s.patch
 hid-logitech-hidpp-add-hidpp_quirk_reset_hi_res_scro.patch
 asoc-max98090-91-fixed-max98091-alsa-widget-powering.patch
+wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch
+erofs-avoid-infinite-loop-due-to-incomplete-zstd-com.patch
+selftests-net-local_termination-wait-for-interfaces-.patch
+net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
+net-phy-micrel-introduce-lanphy_modify_page_reg.patch
+net-phy-micrel-replace-hardcoded-pages-with-defines.patch
+net-phy-micrel-lan8814-fix-reset-of-the-qsgmii-inter.patch
+rust-add-fno-isolate-erroneous-paths-dereference-to-.patch
+nfsd-skip-close-replay-processing-if-xdr-encoding-fa.patch
+bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch
+bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
+bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
+bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
+bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
+sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
+net-smc-fix-mismatch-between-clc-header-and-proposal.patch
+net-handshake-fix-memory-leak-in-tls_handshake_accep.patch
+net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-respons.patch
+net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-retry-m.patch
+tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
+net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
+wifi-mac80211-skip-rate-verification-for-not-capture.patch
+af_unix-initialise-scc_index-in-unix_add_edge.patch
+net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch
+net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
+net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
+net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
+net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
+net-mlx5e-fix-potentially-misleading-debug-message.patch
+net_sched-limit-try_bulk_dequeue_skb-batches.patch
+virtio-net-fix-incorrect-flags-recording-in-big-mode.patch
+hsr-fix-supervision-frame-sending-on-hsrv0.patch
+acpi-cppc-detect-preferred-core-availability-on-onli.patch
+acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch
+acpi-cppc-perform-fast-check-switch-only-for-online-.patch
+acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch
+bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
diff --git a/queue-6.12/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch b/queue-6.12/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
new file mode 100644 (file)
index 0000000..bffcf6c
--- /dev/null
@@ -0,0 +1,150 @@
+From 72093695720e6b7501550d9b6ce9763249f83d16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 06:40:25 +0000
+Subject: tipc: Fix use-after-free in tipc_mon_reinit_self().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 0725e6afb55128be21a2ca36e9674f573ccec173 ]
+
+syzbot reported use-after-free of tipc_net(net)->monitors[]
+in tipc_mon_reinit_self(). [0]
+
+The array is protected by RTNL, but tipc_mon_reinit_self()
+iterates over it without RTNL.
+
+tipc_mon_reinit_self() is called from tipc_net_finalize(),
+which is always under RTNL except for tipc_net_finalize_work().
+
+Let's hold RTNL in tipc_net_finalize_work().
+
+[0]:
+BUG: KASAN: slab-use-after-free in __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+Read of size 1 at addr ffff88805eae1030 by task kworker/0:7/5989
+
+CPU: 0 UID: 0 PID: 5989 Comm: kworker/0:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
+Workqueue: events tipc_net_finalize_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xca/0x240 mm/kasan/report.c:482
+ kasan_report+0x118/0x150 mm/kasan/report.c:595
+ __kasan_check_byte+0x2a/0x40 mm/kasan/common.c:568
+ kasan_check_byte include/linux/kasan.h:399 [inline]
+ lock_acquire+0x8d/0x360 kernel/locking/lockdep.c:5842
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+ rtlock_slowlock kernel/locking/rtmutex.c:1894 [inline]
+ rwbase_rtmutex_lock_state kernel/locking/spinlock_rt.c:160 [inline]
+ rwbase_write_lock+0xd3/0x7e0 kernel/locking/rwbase_rt.c:244
+ rt_write_lock+0x76/0x110 kernel/locking/spinlock_rt.c:243
+ write_lock_bh include/linux/rwlock_rt.h:99 [inline]
+ tipc_mon_reinit_self+0x79/0x430 net/tipc/monitor.c:718
+ tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
+ process_one_work kernel/workqueue.c:3236 [inline]
+ process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3319
+ worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
+ kthread+0x70e/0x8a0 kernel/kthread.c:463
+ ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+Allocated by task 6089:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __kmalloc_cache_noprof+0x1a8/0x320 mm/slub.c:4407
+ kmalloc_noprof include/linux/slab.h:905 [inline]
+ kzalloc_noprof include/linux/slab.h:1039 [inline]
+ tipc_mon_create+0xc3/0x4d0 net/tipc/monitor.c:657
+ tipc_enable_bearer net/tipc/bearer.c:357 [inline]
+ __tipc_nl_bearer_enable+0xe16/0x13f0 net/tipc/bearer.c:1047
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:371 [inline]
+ tipc_nl_compat_doit+0x3bc/0x5f0 net/tipc/netlink_compat.c:393
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:-1 [inline]
+ tipc_nl_compat_recv+0x83c/0xbe0 net/tipc/netlink_compat.c:1321
+ genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
+ netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
+ netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:729
+ ____sys_sendmsg+0x508/0x820 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 6088:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
+ poison_slab_object mm/kasan/common.c:243 [inline]
+ __kasan_slab_free+0x5b/0x80 mm/kasan/common.c:275
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2422 [inline]
+ slab_free mm/slub.c:4695 [inline]
+ kfree+0x195/0x550 mm/slub.c:4894
+ tipc_l2_device_event+0x380/0x650 net/tipc/bearer.c:-1
+ notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
+ call_netdevice_notifiers_extack net/core/dev.c:2267 [inline]
+ call_netdevice_notifiers net/core/dev.c:2281 [inline]
+ unregister_netdevice_many_notify+0x14d7/0x1fe0 net/core/dev.c:12166
+ unregister_netdevice_many net/core/dev.c:12229 [inline]
+ unregister_netdevice_queue+0x33c/0x380 net/core/dev.c:12073
+ unregister_netdevice include/linux/netdevice.h:3385 [inline]
+ __tun_detach+0xe4d/0x1620 drivers/net/tun.c:621
+ tun_detach drivers/net/tun.c:637 [inline]
+ tun_chr_close+0x10d/0x1c0 drivers/net/tun.c:3433
+ __fput+0x458/0xa80 fs/file_table.c:468
+ task_work_run+0x1d4/0x260 kernel/task_work.c:227
+ resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
+ exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:43
+ exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
+ syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline]
+ syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline]
+ do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 46cb01eeeb86 ("tipc: update mon's self addr when node addr generated")
+Reported-by: syzbot+d7dad7fd4b3921104957@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c323a.050a0220.baf87.007f.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251107064038.2361188-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/net.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/tipc/net.c b/net/tipc/net.c
+index 0e95572e56b41..7e65d0b0c4a8d 100644
+--- a/net/tipc/net.c
++++ b/net/tipc/net.c
+@@ -145,7 +145,9 @@ void tipc_net_finalize_work(struct work_struct *work)
+ {
+       struct tipc_net *tn = container_of(work, struct tipc_net, work);
++      rtnl_lock();
+       tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
++      rtnl_unlock();
+ }
+ void tipc_net_stop(struct net *net)
+-- 
+2.51.0
+
diff --git a/queue-6.12/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch b/queue-6.12/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch
new file mode 100644 (file)
index 0000000..31a26ea
--- /dev/null
@@ -0,0 +1,72 @@
+From b4b3c41c2e7e0291e69c4b1b242b9c78a90080a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:08:28 +0800
+Subject: virtio-net: fix incorrect flags recording in big mode
+
+From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+
+[ Upstream commit 0eff2eaa5322b5b141ff5d5ded26fac4a52b5f7b ]
+
+The purpose of commit 703eec1b2422 ("virtio_net: fixing XDP for fully
+checksummed packets handling") is to record the flags in advance, as
+their value may be overwritten in the XDP case. However, the flags
+recorded under big mode are incorrect, because in big mode, the passed
+buf does not point to the rx buffer, but rather to the page of the
+submitted buffer. This commit fixes this issue.
+
+For the small mode, the commit c11a49d58ad2 ("virtio_net: Fix mismatched
+buf address when unmapping for small packets") fixed it.
+
+Tested-by: Alyssa Ross <hi@alyssa.is>
+Fixes: 703eec1b2422 ("virtio_net: fixing XDP for fully checksummed packets handling")
+Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Link: https://patch.msgid.link/20251111090828.23186-1-xuanzhuo@linux.alibaba.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/virtio_net.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 259e3a35dce93..97c49f33122c1 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -2455,22 +2455,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
+               return;
+       }
+-      /* 1. Save the flags early, as the XDP program might overwrite them.
++      /* About the flags below:
++       * 1. Save the flags early, as the XDP program might overwrite them.
+        * These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID
+        * stay valid after XDP processing.
+        * 2. XDP doesn't work with partially checksummed packets (refer to
+        * virtnet_xdp_set()), so packets marked as
+        * VIRTIO_NET_HDR_F_NEEDS_CSUM get dropped during XDP processing.
+        */
+-      flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+-      if (vi->mergeable_rx_bufs)
++      if (vi->mergeable_rx_bufs) {
++              flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+               skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
+                                       stats);
+-      else if (vi->big_packets)
++      } else if (vi->big_packets) {
++              void *p = page_address((struct page *)buf);
++
++              flags = ((struct virtio_net_common_hdr *)p)->hdr.flags;
+               skb = receive_big(dev, vi, rq, buf, len, stats);
+-      else
++      } else {
++              flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+               skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit, stats);
++      }
+       if (unlikely(!skb))
+               return;
+-- 
+2.51.0
+
diff --git a/queue-6.12/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch b/queue-6.12/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch
new file mode 100644 (file)
index 0000000..c8c9a0e
--- /dev/null
@@ -0,0 +1,53 @@
+From 9fe74e87cb63b31cff138dfff45de06be82316c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Nov 2025 09:39:57 +0100
+Subject: wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp()
+
+From: Nicolas Escande <nico.escande@gmail.com>
+
+[ Upstream commit 9065b968752334f972e0d48e50c4463a172fc2a7 ]
+
+When reporting tx completion using ieee80211_tx_status_xxx() family of
+functions, the status part of the struct ieee80211_tx_info nested in the
+skb is used to report things like transmit rates & retry count to mac80211
+
+On the TX data path, this is correctly memset to 0 before calling
+ieee80211_tx_status_ext(), but on the tx mgmt path this was not done.
+
+This leads to mac80211 treating garbage values as valid transmit counters
+(like tx retries for example) and accounting them as real statistics that
+makes their way to userland via station dump.
+
+The same issue was resolved in ath12k by commit 9903c0986f78 ("wifi:
+ath12k: Add memset and update default rate value in wmi tx completion")
+
+Tested-on: QCN9074 PCI WLAN.HK.2.9.0.1-01977-QCAHKSWPL_SILICONZ-1
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
+Link: https://patch.msgid.link/20251104083957.717825-1-nico.escande@gmail.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 98811726d33bf..bfca9d3639810 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -5961,6 +5961,9 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar,
+       dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+       info = IEEE80211_SKB_CB(msdu);
++      memset(&info->status, 0, sizeof(info->status));
++      info->status.rates[0].idx = -1;
++
+       if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) &&
+           !tx_compl_param->status) {
+               info->flags |= IEEE80211_TX_STAT_ACK;
+-- 
+2.51.0
+
diff --git a/queue-6.12/wifi-mac80211-skip-rate-verification-for-not-capture.patch b/queue-6.12/wifi-mac80211-skip-rate-verification-for-not-capture.patch
new file mode 100644 (file)
index 0000000..1332f4f
--- /dev/null
@@ -0,0 +1,48 @@
+From beb1369c90f054fcbbb77722ab2f4c602966d7c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 14:26:18 +0200
+Subject: wifi: mac80211: skip rate verification for not captured PSDUs
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 7fe0d21f5633af8c3fab9f0ef0706c6156623484 ]
+
+If for example the sniffer did not follow any AIDs in an MU frame, then
+some of the information may not be filled in or is even expected to be
+invalid. As an example, in that case it is expected that Nss is zero.
+
+Fixes: 2ff5e52e7836 ("radiotap: add 0-length PSDU "not captured" type")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251110142554.83a2858ee15b.I9f78ce7984872f474722f9278691ae16378f0a3e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 538c6eea645f2..ea6fe21c96c55 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -5402,10 +5402,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+       if (WARN_ON(!local->started))
+               goto drop;
+-      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) {
++      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) &&
++                 !(status->flag & RX_FLAG_NO_PSDU &&
++                   status->zero_length_psdu_type ==
++                   IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) {
+               /*
+-               * Validate the rate, unless a PLCP error means that
+-               * we probably can't have a valid rate here anyway.
++               * Validate the rate, unless there was a PLCP error which may
++               * have an invalid rate or the PSDU was not capture and may be
++               * missing rate information.
+                */
+               switch (status->encoding) {
+-- 
+2.51.0
+
diff --git a/queue-6.17/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch b/queue-6.17/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch
new file mode 100644 (file)
index 0000000..1e451a1
--- /dev/null
@@ -0,0 +1,49 @@
+From b410fb536ef1677c559f594b5c59b16325b5398a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:42 +0530
+Subject: ACPI: CPPC: Check _CPC validity for only the online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 6dd3b8a709a130a4d55c866af9804c81b8486d28 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function acpi_cpc_valid() checks for the validity of the
+_CPC object for all the present CPUs. This breaks when the kernel is
+booted with "nosmt=force".
+
+Hence check the validity of the _CPC objects of only the online CPUs.
+
+Fixes: 2aeca6bd0277 ("ACPI: CPPC: Check present CPUs for determining _CPC is valid")
+Reported-by: Christopher Harris <chris.harris79@gmail.com>
+Closes: https://lore.kernel.org/lkml/CAM+eXpdDT7KjLV0AxEwOLkSJ2QtrsvGvjA2cCHvt1d0k2_C4Cw@mail.gmail.com/
+Suggested-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Tested-by: Chrisopher Harris <chris.harris79@gmail.com>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-3-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 6b649031808f8..6694412a1e139 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -460,7 +460,7 @@ bool acpi_cpc_valid(void)
+       if (acpi_disabled)
+               return false;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+               if (!cpc_ptr)
+                       return false;
+-- 
+2.51.0
+
diff --git a/queue-6.17/acpi-cppc-detect-preferred-core-availability-on-onli.patch b/queue-6.17/acpi-cppc-detect-preferred-core-availability-on-onli.patch
new file mode 100644 (file)
index 0000000..a3a1531
--- /dev/null
@@ -0,0 +1,49 @@
+From 37db71e64b506a38ae3450fd756ed4ba151b6d64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:41 +0530
+Subject: ACPI: CPPC: Detect preferred core availability on online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 4fe5934db4a7187d358f1af1b3ef9b6dd59bce58 ]
+
+Commit 279f838a61f9 ("x86/amd: Detect preferred cores in
+amd_get_boost_ratio_numerator()") introduced the ability to detect the
+preferred core on AMD platforms by checking if there at least two
+distinct highest_perf values.
+
+However, it uses for_each_present_cpu() to iterate through all the
+CPUs in the platform, which is problematic when the kernel is booted
+with "nosmt=force" commandline option.
+
+Hence limit the search to only the online CPUs.
+
+Fixes: 279f838a61f9 ("x86/amd: Detect preferred cores in amd_get_boost_ratio_numerator()")
+Reported-by: Christopher Harris <chris.harris79@gmail.com>
+Closes: https://lore.kernel.org/lkml/CAM+eXpdDT7KjLV0AxEwOLkSJ2QtrsvGvjA2cCHvt1d0k2_C4Cw@mail.gmail.com/
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Tested-by: Chrisopher Harris <chris.harris79@gmail.com>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-2-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/acpi/cppc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
+index 7047124490f64..d7c8ef1e354d3 100644
+--- a/arch/x86/kernel/acpi/cppc.c
++++ b/arch/x86/kernel/acpi/cppc.c
+@@ -196,7 +196,7 @@ int amd_detect_prefcore(bool *detected)
+               break;
+       }
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               u32 tmp;
+               int ret;
+-- 
+2.51.0
+
diff --git a/queue-6.17/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch b/queue-6.17/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch
new file mode 100644 (file)
index 0000000..f4a7425
--- /dev/null
@@ -0,0 +1,45 @@
+From 9da33072c6bc661deaec130a255ca80c044072d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:44 +0530
+Subject: ACPI: CPPC: Limit perf ctrs in PCC check only to online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 0fce75870666b46b700cfbd3216380b422f975da ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPU via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function cppc_perf_ctrs_in_pcc() checks if the CPPC
+perf-ctrs are in a PCC region for all the present CPUs, which breaks
+when the kernel is booted with "nosmt=force".
+
+Hence, limit the check only to the online CPUs.
+
+Fixes: ae2df912d1a5 ("ACPI: CPPC: Disable FIE if registers in PCC regions")
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-5-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 51e925f289bf3..002c3dde283ff 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -1435,7 +1435,7 @@ bool cppc_perf_ctrs_in_pcc(void)
+ {
+       int cpu;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               struct cpc_register_resource *ref_perf_reg;
+               struct cpc_desc *cpc_desc;
+-- 
+2.51.0
+
diff --git a/queue-6.17/acpi-cppc-perform-fast-check-switch-only-for-online-.patch b/queue-6.17/acpi-cppc-perform-fast-check-switch-only-for-online-.patch
new file mode 100644 (file)
index 0000000..207a957
--- /dev/null
@@ -0,0 +1,45 @@
+From 5d3d305539664831a5bd2864eb56b2dde92c3ae5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:43 +0530
+Subject: ACPI: CPPC: Perform fast check switch only for online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 8821c8e80a65bc4eb73daf63b34aac6b8ad69461 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function cppc_allow_fast_switch() checks for the validity
+of the _CPC object for all the present CPUs. This breaks when the
+kernel is booted with "nosmt=force".
+
+Check fast_switch capability only on online CPUs
+
+Fixes: 15eece6c5b05 ("ACPI: CPPC: Fix NULL pointer dereference when nosmp is used")
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-4-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 6694412a1e139..51e925f289bf3 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -476,7 +476,7 @@ bool cppc_allow_fast_switch(void)
+       struct cpc_desc *cpc_ptr;
+       int cpu;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+               desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF];
+               if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
+-- 
+2.51.0
+
diff --git a/queue-6.17/af_unix-initialise-scc_index-in-unix_add_edge.patch b/queue-6.17/af_unix-initialise-scc_index-in-unix_add_edge.patch
new file mode 100644 (file)
index 0000000..e61d8f2
--- /dev/null
@@ -0,0 +1,139 @@
+From 70631e205e17748fd9120c924f9ff0b9e5abc1bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 02:52:22 +0000
+Subject: af_unix: Initialise scc_index in unix_add_edge().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 60e6489f8e3b086bd1130ad4450a2c112e863791 ]
+
+Quang Le reported that the AF_UNIX GC could garbage-collect a
+receive queue of an alive in-flight socket, with a nice repro.
+
+The repro consists of three stages.
+
+  1)
+    1-a. Create a single cyclic reference with many sockets
+    1-b. close() all sockets
+    1-c. Trigger GC
+
+  2)
+    2-a. Pass sk-A to an embryo sk-B
+    2-b. Pass sk-X to sk-X
+    2-c. Trigger GC
+
+  3)
+    3-a. accept() the embryo sk-B
+    3-b. Pass sk-B to sk-C
+    3-c. close() the in-flight sk-A
+    3-d. Trigger GC
+
+As of 2-c, sk-A and sk-X are linked to unix_unvisited_vertices,
+and unix_walk_scc() groups them into two different SCCs:
+
+  unix_sk(sk-A)->vertex->scc_index = 2 (UNIX_VERTEX_INDEX_START)
+  unix_sk(sk-X)->vertex->scc_index = 3
+
+Once GC completes, unix_graph_grouped is set to true.
+Also, unix_graph_maybe_cyclic is set to true due to sk-X's
+cyclic self-reference, which makes close() trigger GC.
+
+At 3-b, unix_add_edge() allocates unix_sk(sk-B)->vertex and
+links it to unix_unvisited_vertices.
+
+unix_update_graph() is called at 3-a. and 3-b., but neither
+unix_graph_grouped nor unix_graph_maybe_cyclic is changed
+because both sk-B's listener and sk-C are not in-flight.
+
+3-c decrements sk-A's file refcnt to 1.
+
+Since unix_graph_grouped is true at 3-d, unix_walk_scc_fast()
+is finally called and iterates 3 sockets sk-A, sk-B, and sk-X:
+
+  sk-A -> sk-B (-> sk-C)
+  sk-X -> sk-X
+
+This is totally fine.  All of them are not yet close()d and
+should be grouped into different SCCs.
+
+However, unix_vertex_dead() misjudges that sk-A and sk-B are
+in the same SCC and sk-A is dead.
+
+  unix_sk(sk-A)->scc_index == unix_sk(sk-B)->scc_index <-- Wrong!
+  &&
+  sk-A's file refcnt == unix_sk(sk-A)->vertex->out_degree
+                                       ^-- 1 in-flight count for sk-B
+  -> sk-A is dead !?
+
+The problem is that unix_add_edge() does not initialise scc_index.
+
+Stage 1) is used for heap spraying, making a newly allocated
+vertex have vertex->scc_index == 2 (UNIX_VERTEX_INDEX_START)
+set by unix_walk_scc() at 1-c.
+
+Let's track the max SCC index from the previous unix_walk_scc()
+call and assign the max + 1 to a new vertex's scc_index.
+
+This way, we can continue to avoid Tarjan's algorithm while
+preventing misjudgments.
+
+Fixes: ad081928a8b0 ("af_unix: Avoid Tarjan's algorithm if unnecessary.")
+Reported-by: Quang Le <quanglex97@gmail.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20251109025233.3659187-1-kuniyu@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/garbage.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 01e2b9452c75b..358fcaba9a732 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -145,6 +145,7 @@ enum unix_vertex_index {
+ };
+ static unsigned long unix_vertex_unvisited_index = UNIX_VERTEX_INDEX_MARK1;
++static unsigned long unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START;
+ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
+ {
+@@ -153,6 +154,7 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
+       if (!vertex) {
+               vertex = list_first_entry(&fpl->vertices, typeof(*vertex), entry);
+               vertex->index = unix_vertex_unvisited_index;
++              vertex->scc_index = ++unix_vertex_max_scc_index;
+               vertex->out_degree = 0;
+               INIT_LIST_HEAD(&vertex->edges);
+               INIT_LIST_HEAD(&vertex->scc_entry);
+@@ -489,10 +491,15 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde
+                               scc_dead = unix_vertex_dead(v);
+               }
+-              if (scc_dead)
++              if (scc_dead) {
+                       unix_collect_skb(&scc, hitlist);
+-              else if (!unix_graph_maybe_cyclic)
+-                      unix_graph_maybe_cyclic = unix_scc_cyclic(&scc);
++              } else {
++                      if (unix_vertex_max_scc_index < vertex->scc_index)
++                              unix_vertex_max_scc_index = vertex->scc_index;
++
++                      if (!unix_graph_maybe_cyclic)
++                              unix_graph_maybe_cyclic = unix_scc_cyclic(&scc);
++              }
+               list_del(&scc);
+       }
+@@ -507,6 +514,7 @@ static void unix_walk_scc(struct sk_buff_head *hitlist)
+       unsigned long last_index = UNIX_VERTEX_INDEX_START;
+       unix_graph_maybe_cyclic = false;
++      unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START;
+       /* Visit every vertex exactly once.
+        * __unix_walk_scc() moves visited vertices to unix_visited_vertices.
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch b/queue-6.17/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
new file mode 100644 (file)
index 0000000..8408f95
--- /dev/null
@@ -0,0 +1,149 @@
+From 32a55af5b354717c02f7d786bc2b66a2b7b223eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:49 +0200
+Subject: Bluetooth: 6lowpan: Don't hold spin lock over sleeping functions
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 98454bc812f3611551e4b1f81732da4aa7b9597e ]
+
+disconnect_all_peers() calls sleeping function (l2cap_chan_close) under
+spinlock.  Holding the lock doesn't actually do any good -- we work on a
+local copy of the list, and the lock doesn't protect against peer->chan
+having already been freed.
+
+Fix by taking refcounts of peer->chan instead.  Clean up the code and
+old comments a bit.
+
+Take devices_lock instead of RCU, because the kfree_rcu();
+l2cap_chan_put(); construct in chan_close_cb() does not guarantee
+peer->chan is necessarily valid in RCU.
+
+Also take l2cap_chan_lock() which is required for l2cap_chan_close().
+
+Log: (bluez 6lowpan-tester Client Connect - Disable)
+------
+BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
+...
+<TASK>
+...
+l2cap_send_disconn_req (net/bluetooth/l2cap_core.c:938 net/bluetooth/l2cap_core.c:1495)
+...
+? __pfx_l2cap_chan_close (net/bluetooth/l2cap_core.c:809)
+do_enable_set (net/bluetooth/6lowpan.c:1048 net/bluetooth/6lowpan.c:1068)
+------
+
+Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 68 ++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 0d8c2e2e9a6cf..588d7e94e6069 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -53,6 +53,11 @@ static bool enable_6lowpan;
+ static struct l2cap_chan *listen_chan;
+ static DEFINE_MUTEX(set_lock);
++enum {
++      LOWPAN_PEER_CLOSING,
++      LOWPAN_PEER_MAXBITS
++};
++
+ struct lowpan_peer {
+       struct list_head list;
+       struct rcu_head rcu;
+@@ -61,6 +66,8 @@ struct lowpan_peer {
+       /* peer addresses in various formats */
+       unsigned char lladdr[ETH_ALEN];
+       struct in6_addr peer_addr;
++
++      DECLARE_BITMAP(flags, LOWPAN_PEER_MAXBITS);
+ };
+ struct lowpan_btle_dev {
+@@ -1014,41 +1021,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ static void disconnect_all_peers(void)
+ {
+       struct lowpan_btle_dev *entry;
+-      struct lowpan_peer *peer, *tmp_peer, *new_peer;
+-      struct list_head peers;
+-
+-      INIT_LIST_HEAD(&peers);
++      struct lowpan_peer *peer;
++      int nchans;
+-      /* We make a separate list of peers as the close_cb() will
+-       * modify the device peers list so it is better not to mess
+-       * with the same list at the same time.
++      /* l2cap_chan_close() cannot be called from RCU, and lock ordering
++       * chan->lock > devices_lock prevents taking write side lock, so copy
++       * then close.
+        */
+       rcu_read_lock();
++      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list)
++              list_for_each_entry_rcu(peer, &entry->peers, list)
++                      clear_bit(LOWPAN_PEER_CLOSING, peer->flags);
++      rcu_read_unlock();
+-      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
+-              list_for_each_entry_rcu(peer, &entry->peers, list) {
+-                      new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
+-                      if (!new_peer)
+-                              break;
++      do {
++              struct l2cap_chan *chans[32];
++              int i;
+-                      new_peer->chan = peer->chan;
+-                      INIT_LIST_HEAD(&new_peer->list);
++              nchans = 0;
+-                      list_add(&new_peer->list, &peers);
+-              }
+-      }
++              spin_lock(&devices_lock);
+-      rcu_read_unlock();
++              list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
++                      list_for_each_entry_rcu(peer, &entry->peers, list) {
++                              if (test_and_set_bit(LOWPAN_PEER_CLOSING,
++                                                   peer->flags))
++                                      continue;
+-      spin_lock(&devices_lock);
+-      list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
+-              l2cap_chan_close(peer->chan, ENOENT);
++                              l2cap_chan_hold(peer->chan);
++                              chans[nchans++] = peer->chan;
+-              list_del_rcu(&peer->list);
+-              kfree_rcu(peer, rcu);
+-      }
+-      spin_unlock(&devices_lock);
++                              if (nchans >= ARRAY_SIZE(chans))
++                                      goto done;
++                      }
++              }
++
++done:
++              spin_unlock(&devices_lock);
++
++              for (i = 0; i < nchans; ++i) {
++                      l2cap_chan_lock(chans[i]);
++                      l2cap_chan_close(chans[i], ENOENT);
++                      l2cap_chan_unlock(chans[i]);
++                      l2cap_chan_put(chans[i]);
++              }
++      } while (nchans);
+ }
+ struct set_enable {
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch b/queue-6.17/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
new file mode 100644 (file)
index 0000000..a13a31d
--- /dev/null
@@ -0,0 +1,103 @@
+From 8f328addb48774e08700b63dda304ecb94036860 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:47 +0200
+Subject: Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type
+ confusion
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit b454505bf57a2e4f5d49951d4deb03730a9348d9 ]
+
+Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types,
+e.g. debugfs "connect" command takes the former, and "disconnect" and
+"connect" to already connected device take the latter.  This is due to
+using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le
+which take different dst_type values.
+
+Fix address type passed to hci_conn_hash_lookup_le().
+
+Retain the debugfs API difference between "connect" and "disconnect"
+commands since it's been like this since 2015 and nobody apparently
+complained.
+
+Fixes: f5ad4ffceba0 ("Bluetooth: 6lowpan: Use hci_conn_hash_lookup_le() when possible")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index f1d29fa4b4119..0d8c2e2e9a6cf 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -957,10 +957,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void)
+ }
+ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+-                        struct l2cap_conn **conn)
++                        struct l2cap_conn **conn, bool disconnect)
+ {
+       struct hci_conn *hcon;
+       struct hci_dev *hdev;
++      int le_addr_type;
+       int n;
+       n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
+@@ -971,13 +972,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+       if (n < 7)
+               return -EINVAL;
++      if (disconnect) {
++              /* The "disconnect" debugfs command has used different address
++               * type constants than "connect" since 2015. Let's retain that
++               * for now even though it's obviously buggy...
++               */
++              *addr_type += 1;
++      }
++
++      switch (*addr_type) {
++      case BDADDR_LE_PUBLIC:
++              le_addr_type = ADDR_LE_DEV_PUBLIC;
++              break;
++      case BDADDR_LE_RANDOM:
++              le_addr_type = ADDR_LE_DEV_RANDOM;
++              break;
++      default:
++              return -EINVAL;
++      }
++
+       /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
+       hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
+       if (!hdev)
+               return -ENOENT;
+       hci_dev_lock(hdev);
+-      hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
++      hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+@@ -1104,7 +1124,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       buf[buf_size] = '\0';
+       if (memcmp(buf, "connect ", 8) == 0) {
+-              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false);
+               if (ret == -EINVAL)
+                       return ret;
+@@ -1141,7 +1161,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       }
+       if (memcmp(buf, "disconnect ", 11) == 0) {
+-              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true);
+               if (ret < 0)
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch b/queue-6.17/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
new file mode 100644 (file)
index 0000000..c244888
--- /dev/null
@@ -0,0 +1,54 @@
+From 36b7edb73edd73828f6824a8419fde3e6eb56543 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:46 +0200
+Subject: Bluetooth: 6lowpan: reset link-local header on ipv6 recv path
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3b78f50918276ab28fb22eac9aa49401ac436a3b ]
+
+Bluetooth 6lowpan.c netdev has header_ops, so it must set link-local
+header for RX skb, otherwise things crash, eg. with AF_PACKET SOCK_RAW
+
+Add missing skb_reset_mac_header() for uncompressed ipv6 RX path.
+
+For the compressed one, it is done in lowpan_header_decompress().
+
+Log: (BlueZ 6lowpan-tester Client Recv Raw - Success)
+------
+kernel BUG at net/core/skbuff.c:212!
+Call Trace:
+<IRQ>
+...
+packet_rcv (net/packet/af_packet.c:2152)
+...
+<TASK>
+__local_bh_enable_ip (kernel/softirq.c:407)
+netif_rx (net/core/dev.c:5648)
+chan_recv_cb (net/bluetooth/6lowpan.c:294 net/bluetooth/6lowpan.c:359)
+------
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index f0c862091bff2..f1d29fa4b4119 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -289,6 +289,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
+               local_skb->pkt_type = PACKET_HOST;
+               local_skb->dev = dev;
++              skb_reset_mac_header(local_skb);
+               skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
+               if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) {
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch b/queue-6.17/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
new file mode 100644 (file)
index 0000000..8c44de9
--- /dev/null
@@ -0,0 +1,65 @@
+From 2328930334ad146d6ff2ad06da94a8d1628f4127 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:28:41 -0500
+Subject: Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
+
+From: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+
+[ Upstream commit 23d22f2f71768034d6ef86168213843fc49bf550 ]
+
+There is a KASAN: slab-use-after-free read in btusb_disconnect().
+Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will
+free the btusb data associated with the interface. The same data is
+then used later in the function, hence the UAF.
+
+Fix by moving the accesses to btusb data to before the data is free'd.
+
+Reported-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2fc81b50a4f8263a159b
+Tested-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Fixes: fd913ef7ce619 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 5e9ebf0c53125..a722446ec73dd 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4361,6 +4361,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+       hci_unregister_dev(hdev);
++      if (data->oob_wake_irq)
++              device_init_wakeup(&data->udev->dev, false);
++      if (data->reset_gpio)
++              gpiod_put(data->reset_gpio);
++
+       if (intf == data->intf) {
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
+@@ -4371,17 +4376,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+                       usb_driver_release_interface(&btusb_driver, data->diag);
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       } else if (intf == data->diag) {
+-              usb_driver_release_interface(&btusb_driver, data->intf);
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
++              usb_driver_release_interface(&btusb_driver, data->intf);
+       }
+-      if (data->oob_wake_irq)
+-              device_init_wakeup(&data->udev->dev, false);
+-
+-      if (data->reset_gpio)
+-              gpiod_put(data->reset_gpio);
+-
+       hci_free_dev(hdev);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-hci_conn-fix-not-cleaning-up-pa_link-conne.patch b/queue-6.17/bluetooth-hci_conn-fix-not-cleaning-up-pa_link-conne.patch
new file mode 100644 (file)
index 0000000..f3efb62
--- /dev/null
@@ -0,0 +1,149 @@
+From ac037a84362c9073e93ffeca412bbcfa524c94b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Nov 2025 17:02:04 -0500
+Subject: Bluetooth: hci_conn: Fix not cleaning up PA_LINK connections
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 41bf23338a501e745c398e0faee948dd05d0be98 ]
+
+Contrary to what was stated on d36349ea73d8 ("Bluetooth: hci_conn:
+Fix running bis_cleanup for hci_conn->type PA_LINK") the PA_LINK does
+in fact needs to run bis_cleanup in order to terminate the PA Sync,
+since that is bond to the listening socket which is the entity that
+controls the lifetime of PA Sync, so if it is closed/released the PA
+Sync shall be terminated, terminating the PA Sync shall not result in
+the BIG Sync being terminated since once the later is established it
+doesn't depend on the former anymore.
+
+If the use user wants to reconnect/rebind a number of BIS(s) it shall
+keep the socket open until it no longer needs the PA Sync, which means
+it retains full control of the lifetime of both PA and BIG Syncs.
+
+Fixes: d36349ea73d8 ("Bluetooth: hci_conn: Fix running bis_cleanup for hci_conn->type PA_LINK")
+Fixes: a7bcffc673de ("Bluetooth: Add PA_LINK to distinguish BIG sync and PA sync connections")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_conn.c  | 33 +++++++++++++++++++--------------
+ net/bluetooth/hci_event.c |  7 +------
+ net/bluetooth/hci_sync.c  |  2 +-
+ 3 files changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index c021c6cb3d9a5..5846b4bae77a3 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -769,21 +769,23 @@ static void find_bis(struct hci_conn *conn, void *data)
+       d->count++;
+ }
+-static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *conn)
++static int hci_le_big_terminate(struct hci_dev *hdev, struct hci_conn *conn)
+ {
+       struct iso_list_data *d;
+       int ret;
+-      bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, conn->sync_handle);
++      bt_dev_dbg(hdev, "hcon %p big 0x%2.2x sync_handle 0x%4.4x", conn,
++                 conn->iso_qos.bcast.big, conn->sync_handle);
+       d = kzalloc(sizeof(*d), GFP_KERNEL);
+       if (!d)
+               return -ENOMEM;
+-      d->big = big;
++      d->big = conn->iso_qos.bcast.big;
+       d->sync_handle = conn->sync_handle;
+-      if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) {
++      if (conn->type == PA_LINK &&
++          test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) {
+               hci_conn_hash_list_flag(hdev, find_bis, PA_LINK,
+                                       HCI_CONN_PA_SYNC, d);
+@@ -801,6 +803,9 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c
+                       d->big_sync_term = true;
+       }
++      if (!d->pa_sync_term && !d->big_sync_term)
++              return 0;
++
+       ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d,
+                                terminate_big_destroy);
+       if (ret)
+@@ -852,8 +857,7 @@ static void bis_cleanup(struct hci_conn *conn)
+               hci_le_terminate_big(hdev, conn);
+       } else {
+-              hci_le_big_terminate(hdev, conn->iso_qos.bcast.big,
+-                                   conn);
++              hci_le_big_terminate(hdev, conn);
+       }
+ }
+@@ -995,19 +999,20 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
+               conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
+               break;
+       case CIS_LINK:
+-      case BIS_LINK:
+-      case PA_LINK:
+               /* conn->src should reflect the local identity address */
+               hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
+-              /* set proper cleanup function */
+-              if (!bacmp(dst, BDADDR_ANY))
+-                      conn->cleanup = bis_cleanup;
+-              else if (conn->role == HCI_ROLE_MASTER)
++              if (conn->role == HCI_ROLE_MASTER)
+                       conn->cleanup = cis_cleanup;
+-              conn->mtu = hdev->iso_mtu ? hdev->iso_mtu :
+-                          hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
++              conn->mtu = hdev->iso_mtu;
++              break;
++      case PA_LINK:
++      case BIS_LINK:
++              /* conn->src should reflect the local identity address */
++              hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
++              conn->cleanup = bis_cleanup;
++              conn->mtu = hdev->iso_mtu;
+               break;
+       case SCO_LINK:
+               if (lmp_esco_capable(hdev))
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 7ee8bc7ac5a2a..0380d2f596c97 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -7011,14 +7011,9 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
+                               continue;
+               }
+-              if (ev->status != 0x42) {
++              if (ev->status != 0x42)
+                       /* Mark PA sync as established */
+                       set_bit(HCI_CONN_PA_SYNC, &bis->flags);
+-                      /* Reset cleanup callback of PA Sync so it doesn't
+-                       * terminate the sync when deleting the connection.
+-                       */
+-                      conn->cleanup = NULL;
+-              }
+               bis->sync_handle = conn->sync_handle;
+               bis->iso_qos.bcast.big = ev->handle;
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 73fc41b68b687..6e76798ec786b 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -6999,7 +6999,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
+       hci_dev_lock(hdev);
+-      if (!hci_conn_valid(hdev, conn))
++      if (hci_conn_valid(hdev, conn))
+               clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
+       if (!err)
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-hci_event-fix-not-handling-pa-sync-lost-ev.patch b/queue-6.17/bluetooth-hci_event-fix-not-handling-pa-sync-lost-ev.patch
new file mode 100644 (file)
index 0000000..3feaa14
--- /dev/null
@@ -0,0 +1,123 @@
+From 5333adefff9750184878aee17a2fb6d7981cd04b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 13:05:35 -0500
+Subject: Bluetooth: hci_event: Fix not handling PA Sync Lost event
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 485e0626e58768f3c53ba61ab9e09d6b60a455f4 ]
+
+This handles PA Sync Lost event which previously was assumed to be
+handled with BIG Sync Lost but their lifetime are not the same thus why
+there are 2 different events to inform when each sync is lost.
+
+Fixes: b2a5f2e1c127 ("Bluetooth: hci_event: Add support for handling LE BIG Sync Lost event")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h |  5 ++++
+ net/bluetooth/hci_event.c   | 49 ++++++++++++++++++++++++++-----------
+ 2 files changed, 40 insertions(+), 14 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index dca650cede3c4..63160cfcf2b22 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -2782,6 +2782,11 @@ struct hci_ev_le_per_adv_report {
+       __u8     data[];
+ } __packed;
++#define HCI_EV_LE_PA_SYNC_LOST                0x10
++struct hci_ev_le_pa_sync_lost {
++      __le16 handle;
++} __packed;
++
+ #define LE_PA_DATA_COMPLETE   0x00
+ #define LE_PA_DATA_MORE_TO_COME       0x01
+ #define LE_PA_DATA_TRUNCATED  0x02
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 0380d2f596c97..a9a5d12943fa0 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -5853,6 +5853,29 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data,
+                            le16_to_cpu(ev->supervision_timeout));
+ }
++static void hci_le_pa_sync_lost_evt(struct hci_dev *hdev, void *data,
++                                  struct sk_buff *skb)
++{
++      struct hci_ev_le_pa_sync_lost *ev = data;
++      u16 handle = le16_to_cpu(ev->handle);
++      struct hci_conn *conn;
++
++      bt_dev_dbg(hdev, "sync handle 0x%4.4x", handle);
++
++      hci_dev_lock(hdev);
++
++      /* Delete the pa sync connection */
++      conn = hci_conn_hash_lookup_pa_sync_handle(hdev, handle);
++      if (conn) {
++              clear_bit(HCI_CONN_BIG_SYNC, &conn->flags);
++              clear_bit(HCI_CONN_PA_SYNC, &conn->flags);
++              hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM);
++              hci_conn_del(conn);
++      }
++
++      hci_dev_unlock(hdev);
++}
++
+ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
+                                   struct sk_buff *skb)
+ {
+@@ -7056,29 +7079,24 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
+                                    struct sk_buff *skb)
+ {
+       struct hci_evt_le_big_sync_lost *ev = data;
+-      struct hci_conn *bis, *conn;
+-      bool mgmt_conn;
++      struct hci_conn *bis;
++      bool mgmt_conn = false;
+       bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle);
+       hci_dev_lock(hdev);
+-      /* Delete the pa sync connection */
+-      bis = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle);
+-      if (bis) {
+-              conn = hci_conn_hash_lookup_pa_sync_handle(hdev,
+-                                                         bis->sync_handle);
+-              if (conn)
+-                      hci_conn_del(conn);
+-      }
+-
+       /* Delete each bis connection */
+       while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle,
+                                                    BT_CONNECTED,
+                                                    HCI_ROLE_SLAVE))) {
+-              mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &bis->flags);
+-              mgmt_device_disconnected(hdev, &bis->dst, bis->type, bis->dst_type,
+-                                       ev->reason, mgmt_conn);
++              if (!mgmt_conn) {
++                      mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED,
++                                                     &bis->flags);
++                      mgmt_device_disconnected(hdev, &bis->dst, bis->type,
++                                               bis->dst_type, ev->reason,
++                                               mgmt_conn);
++              }
+               clear_bit(HCI_CONN_BIG_SYNC, &bis->flags);
+               hci_disconn_cfm(bis, ev->reason);
+@@ -7192,6 +7210,9 @@ static const struct hci_le_ev {
+                                hci_le_per_adv_report_evt,
+                                sizeof(struct hci_ev_le_per_adv_report),
+                                HCI_MAX_EVENT_SIZE),
++      /* [0x10 = HCI_EV_LE_PA_SYNC_LOST] */
++      HCI_LE_EV(HCI_EV_LE_PA_SYNC_LOST, hci_le_pa_sync_lost_evt,
++                sizeof(struct hci_ev_le_pa_sync_lost)),
+       /* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */
+       HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt,
+                 sizeof(struct hci_evt_le_ext_adv_set_term)),
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch b/queue-6.17/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
new file mode 100644 (file)
index 0000000..41f86a0
--- /dev/null
@@ -0,0 +1,37 @@
+From 2a29a39362eeacff2f6dd597924f3bb521b29403 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:48 +0200
+Subject: Bluetooth: L2CAP: export l2cap_chan_hold for modules
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit e060088db0bdf7932e0e3c2d24b7371c4c5b867c ]
+
+l2cap_chan_put() is exported, so export also l2cap_chan_hold() for
+modules.
+
+l2cap_chan_hold() has use case in net/bluetooth/6lowpan.c
+
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index d08320380ad67..35c57657bcf4e 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -497,6 +497,7 @@ void l2cap_chan_hold(struct l2cap_chan *c)
+       kref_get(&c->kref);
+ }
++EXPORT_SYMBOL_GPL(l2cap_chan_hold);
+ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
+ {
+-- 
+2.51.0
+
diff --git a/queue-6.17/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch b/queue-6.17/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch
new file mode 100644 (file)
index 0000000..1fd1e7a
--- /dev/null
@@ -0,0 +1,56 @@
+From 01497d25c7f3d53dadb79f3824637f568c1cbe7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Nov 2025 20:16:12 +0200
+Subject: Bluetooth: MGMT: cancel mesh send timer when hdev removed
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 55fb52ffdd62850d667ebed842815e072d3c9961 ]
+
+mesh_send_done timer is not canceled when hdev is removed, which causes
+crash if the timer triggers after hdev is gone.
+
+Cancel the timer when MGMT removes the hdev, like other MGMT timers.
+
+Should fix the BUG: sporadically seen by BlueZ test bot
+(in "Mesh - Send cancel - 1" test).
+
+Log:
+------
+BUG: KASAN: slab-use-after-free in run_timer_softirq+0x76b/0x7d0
+...
+Freed by task 36:
+ kasan_save_stack+0x24/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3a/0x60
+ __kasan_slab_free+0x43/0x70
+ kfree+0x103/0x500
+ device_release+0x9a/0x210
+ kobject_put+0x100/0x1e0
+ vhci_release+0x18b/0x240
+------
+
+Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh")
+Link: https://lore.kernel.org/linux-bluetooth/67364c09.0c0a0220.113cba.39ff@mx.google.com/
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 79762bfaea5ff..262bf984d2aaf 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9497,6 +9497,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
+       cancel_delayed_work_sync(&hdev->discov_off);
+       cancel_delayed_work_sync(&hdev->service_cache);
+       cancel_delayed_work_sync(&hdev->rpa_expired);
++      cancel_delayed_work_sync(&hdev->mesh_send_done);
+ }
+ void mgmt_power_on(struct hci_dev *hdev, int err)
+-- 
+2.51.0
+
diff --git a/queue-6.17/cpufreq-intel_pstate-check-ida-only-before-msr_ia32_.patch b/queue-6.17/cpufreq-intel_pstate-check-ida-only-before-msr_ia32_.patch
new file mode 100644 (file)
index 0000000..9ecdf05
--- /dev/null
@@ -0,0 +1,72 @@
+From 0e12f0fdd167723fb50a9207b43259e7312877c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 17:08:40 -0800
+Subject: cpufreq: intel_pstate: Check IDA only before MSR_IA32_PERF_CTL writes
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit 4b747cc628d8f500d56cf1338280eacc66362ff3 ]
+
+Commit ac4e04d9e378 ("cpufreq: intel_pstate: Unchecked MSR aceess in
+legacy mode") introduced a check for feature X86_FEATURE_IDA to verify
+turbo mode support. Although this is the correct way to check for turbo
+mode support, it causes issues on some platforms that disable turbo
+during OS boot, but enable it later [1]. Before adding this feature
+check, users were able to get turbo mode frequencies by writing 0 to
+/sys/devices/system/cpu/intel_pstate/no_turbo post-boot.
+
+To restore the old behavior on the affected systems while still
+addressing the unchecked MSR issue on some Skylake-X systems, check
+X86_FEATURE_IDA only immediately before updates of MSR_IA32_PERF_CTL
+that may involve setting the Turbo Engage Bit (bit 32).
+
+Fixes: ac4e04d9e378 ("cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode")
+Reported-by: Aaron Rainbolt <arainbolt@kfocus.org>
+Closes: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2122531 [1]
+Tested-by: Aaron Rainbolt <arainbolt@kfocus.org>
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+[ rjw: Subject adjustment, changelog edits ]
+Link: https://patch.msgid.link/20251111010840.141490-1-srinivas.pandruvada@linux.intel.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/intel_pstate.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index fc02a3542f656..99c80249fde88 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -603,9 +603,6 @@ static bool turbo_is_disabled(void)
+ {
+       u64 misc_en;
+-      if (!cpu_feature_enabled(X86_FEATURE_IDA))
+-              return true;
+-
+       rdmsrq(MSR_IA32_MISC_ENABLE, misc_en);
+       return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
+@@ -2141,7 +2138,8 @@ static u64 atom_get_val(struct cpudata *cpudata, int pstate)
+       u32 vid;
+       val = (u64)pstate << 8;
+-      if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled))
++      if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled) &&
++          cpu_feature_enabled(X86_FEATURE_IDA))
+               val |= (u64)1 << 32;
+       vid_fp = cpudata->vid.min + mul_fp(
+@@ -2306,7 +2304,8 @@ static u64 core_get_val(struct cpudata *cpudata, int pstate)
+       u64 val;
+       val = (u64)pstate << 8;
+-      if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled))
++      if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled) &&
++          cpu_feature_enabled(X86_FEATURE_IDA))
+               val |= (u64)1 << 32;
+       return val;
+-- 
+2.51.0
+
diff --git a/queue-6.17/erofs-avoid-infinite-loop-due-to-incomplete-zstd-com.patch b/queue-6.17/erofs-avoid-infinite-loop-due-to-incomplete-zstd-com.patch
new file mode 100644 (file)
index 0000000..69f73aa
--- /dev/null
@@ -0,0 +1,60 @@
+From bc73d9bfaa0aad4612cae530c0e3bde6f24f0955 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Oct 2025 13:47:39 +0800
+Subject: erofs: avoid infinite loop due to incomplete zstd-compressed data
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit f2a12cc3b97f062186568a7b94ddb7aa2ef68140 ]
+
+Currently, the decompression logic incorrectly spins if compressed
+data is truncated in crafted (deliberately corrupted) images.
+
+Fixes: 7c35de4df105 ("erofs: Zstandard compression support")
+Reported-by: Robert Morris <rtm@csail.mit.edu>
+Closes: https://lore.kernel.org/r/50958.1761605413@localhost
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Reviewed-by: Chunhai Guo <guochunhai@vivo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/decompressor_zstd.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/erofs/decompressor_zstd.c b/fs/erofs/decompressor_zstd.c
+index b4bfe14229f9f..e38d93bb21048 100644
+--- a/fs/erofs/decompressor_zstd.c
++++ b/fs/erofs/decompressor_zstd.c
+@@ -172,7 +172,6 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
+       dctx.bounce = strm->bounce;
+       do {
+-              dctx.avail_out = out_buf.size - out_buf.pos;
+               dctx.inbuf_sz = in_buf.size;
+               dctx.inbuf_pos = in_buf.pos;
+               err = z_erofs_stream_switch_bufs(&dctx, &out_buf.dst,
+@@ -188,14 +187,18 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
+               in_buf.pos = dctx.inbuf_pos;
+               zerr = zstd_decompress_stream(stream, &out_buf, &in_buf);
+-              if (zstd_is_error(zerr) || (!zerr && rq->outputsize)) {
++              dctx.avail_out = out_buf.size - out_buf.pos;
++              if (zstd_is_error(zerr) ||
++                  ((rq->outputsize + dctx.avail_out) && (!zerr || (zerr > 0 &&
++                              !(rq->inputsize + in_buf.size - in_buf.pos))))) {
+                       erofs_err(sb, "failed to decompress in[%u] out[%u]: %s",
+                                 rq->inputsize, rq->outputsize,
+-                                zerr ? zstd_get_error_name(zerr) : "unexpected end of stream");
++                                zstd_is_error(zerr) ? zstd_get_error_name(zerr) :
++                                      "unexpected end of stream");
+                       err = -EFSCORRUPTED;
+                       break;
+               }
+-      } while (rq->outputsize || out_buf.pos < out_buf.size);
++      } while (rq->outputsize + dctx.avail_out);
+       if (dctx.kout)
+               kunmap_local(dctx.kout);
+-- 
+2.51.0
+
diff --git a/queue-6.17/hsr-fix-supervision-frame-sending-on-hsrv0.patch b/queue-6.17/hsr-fix-supervision-frame-sending-on-hsrv0.patch
new file mode 100644 (file)
index 0000000..ff397a8
--- /dev/null
@@ -0,0 +1,50 @@
+From be848105ac9a247c121f87079ed4fc0e2fe7ed4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:29:32 +0100
+Subject: hsr: Fix supervision frame sending on HSRv0
+
+From: Felix Maurer <fmaurer@redhat.com>
+
+[ Upstream commit 96a3a03abf3d8cc38cd9cb0d280235fbcf7c3f7f ]
+
+On HSRv0, no supervision frames were sent. The supervison frames were
+generated successfully, but failed the check for a sufficiently long mac
+header, i.e., at least sizeof(struct hsr_ethhdr), in hsr_fill_frame_info()
+because the mac header only contained the ethernet header.
+
+Fix this by including the HSR header in the mac header when generating HSR
+supervision frames. Note that the mac header now also includes the TLV
+fields. This matches how we set the headers on rx and also the size of
+struct hsrv0_ethhdr_sp.
+
+Reported-by: Hangbin Liu <liuhangbin@gmail.com>
+Closes: https://lore.kernel.org/netdev/aMONxDXkzBZZRfE5@fedora/
+Fixes: 9cfb5e7f0ded ("net: hsr: fix hsr_init_sk() vs network/transport headers.")
+Signed-off-by: Felix Maurer <fmaurer@redhat.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://patch.msgid.link/4354114fea9a642fe71f49aeeb6c6159d1d61840.1762876095.git.fmaurer@redhat.com
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index fbbc3ccf9df64..1235abb2d79fa 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -320,6 +320,9 @@ static void send_hsr_supervision_frame(struct hsr_port *port,
+       }
+       hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag));
++      skb_set_network_header(skb, ETH_HLEN + HSR_HLEN);
++      skb_reset_mac_len(skb);
++
+       set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf));
+       set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+-- 
+2.51.0
+
diff --git a/queue-6.17/hsr-follow-standard-for-hsrv0-supervision-frames.patch b/queue-6.17/hsr-follow-standard-for-hsrv0-supervision-frames.patch
new file mode 100644 (file)
index 0000000..23350a3
--- /dev/null
@@ -0,0 +1,111 @@
+From 981a4012df7aa3988d4f7e8e6914c948d3b067d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:29:33 +0100
+Subject: hsr: Follow standard for HSRv0 supervision frames
+
+From: Felix Maurer <fmaurer@redhat.com>
+
+[ Upstream commit b2c26c82f7a94ec4da096f370e3612ee14424450 ]
+
+For HSRv0, the path_id has the following meaning:
+- 0000: PRP supervision frame
+- 0001-1001: HSR ring identifier
+- 1010-1011: Frames from PRP network (A/B, with RedBoxes)
+- 1111: HSR supervision frame
+
+Follow the IEC 62439-3:2010 standard more closely by setting the right
+path_id for HSRv0 supervision frames (actually, it is correctly set when
+the frame is constructed, but hsr_set_path_id() overwrites it) and set a
+fixed HSR ring identifier of 1. The ring identifier seems to be generally
+unused and we ignore it anyways on reception, but some fixed identifier is
+definitely better than using one identifier in one direction and a wrong
+identifier in the other.
+
+This was also the behavior before commit f266a683a480 ("net/hsr: Better
+frame dispatch") which introduced the alternating path_id. This was later
+moved to hsr_set_path_id() in commit 451d8123f897 ("net: prp: add packet
+handling support").
+
+The IEC 62439-3:2010 also contains 6 unused bytes after the MacAddressA in
+the HSRv0 supervision frames. Adjust a TODO comment accordingly.
+
+Fixes: f266a683a480 ("net/hsr: Better frame dispatch")
+Fixes: 451d8123f897 ("net: prp: add packet handling support")
+Signed-off-by: Felix Maurer <fmaurer@redhat.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://patch.msgid.link/ea0d5133cd593856b2fa673d6e2067bf1d4d1794.1762876095.git.fmaurer@redhat.com
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c  |  2 +-
+ net/hsr/hsr_forward.c | 22 +++++++++++++++-------
+ 2 files changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 1235abb2d79fa..492cbc78ab75a 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -337,7 +337,7 @@ static void send_hsr_supervision_frame(struct hsr_port *port,
+       }
+       hsr_stag->tlv.HSR_TLV_type = type;
+-      /* TODO: Why 12 in HSRv0? */
++      /* HSRv0 has 6 unused bytes after the MAC */
+       hsr_stag->tlv.HSR_TLV_length = hsr->prot_version ?
+                               sizeof(struct hsr_sup_payload) : 12;
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index c67c0d35921de..339f0d2202129 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -262,15 +262,23 @@ static struct sk_buff *prp_fill_rct(struct sk_buff *skb,
+       return skb;
+ }
+-static void hsr_set_path_id(struct hsr_ethhdr *hsr_ethhdr,
++static void hsr_set_path_id(struct hsr_frame_info *frame,
++                          struct hsr_ethhdr *hsr_ethhdr,
+                           struct hsr_port *port)
+ {
+       int path_id;
+-      if (port->type == HSR_PT_SLAVE_A)
+-              path_id = 0;
+-      else
+-              path_id = 1;
++      if (port->hsr->prot_version) {
++              if (port->type == HSR_PT_SLAVE_A)
++                      path_id = 0;
++              else
++                      path_id = 1;
++      } else {
++              if (frame->is_supervision)
++                      path_id = 0xf;
++              else
++                      path_id = 1;
++      }
+       set_hsr_tag_path(&hsr_ethhdr->hsr_tag, path_id);
+ }
+@@ -304,7 +312,7 @@ static struct sk_buff *hsr_fill_tag(struct sk_buff *skb,
+       else
+               hsr_ethhdr = (struct hsr_ethhdr *)pc;
+-      hsr_set_path_id(hsr_ethhdr, port);
++      hsr_set_path_id(frame, hsr_ethhdr, port);
+       set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size);
+       hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr);
+       hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;
+@@ -330,7 +338,7 @@ struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame,
+                       (struct hsr_ethhdr *)skb_mac_header(frame->skb_hsr);
+               /* set the lane id properly */
+-              hsr_set_path_id(hsr_ethhdr, port);
++              hsr_set_path_id(frame, hsr_ethhdr, port);
+               return skb_clone(frame->skb_hsr, GFP_ATOMIC);
+       } else if (port->dev->features & NETIF_F_HW_HSR_TAG_INS) {
+               return skb_clone(frame->skb_std, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.17/mlx5-fix-default-values-in-create-cq.patch b/queue-6.17/mlx5-fix-default-values-in-create-cq.patch
new file mode 100644 (file)
index 0000000..690a94a
--- /dev/null
@@ -0,0 +1,303 @@
+From 7b568ee912dcecbf3b3e7695da57beb3e6f311f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:49:03 +0200
+Subject: mlx5: Fix default values in create CQ
+
+From: Akiva Goldberger <agoldberger@nvidia.com>
+
+[ Upstream commit e5eba42f01340f73888dfe560be2806057c25913 ]
+
+Currently, CQs without a completion function are assigned the
+mlx5_add_cq_to_tasklet function by default. This is problematic since
+only user CQs created through the mlx5_ib driver are intended to use
+this function.
+
+Additionally, all CQs that will use doorbells instead of polling for
+completions must call mlx5_cq_arm. However, the default CQ creation flow
+leaves a valid value in the CQ's arm_db field, allowing FW to send
+interrupts to polling-only CQs in certain corner cases.
+
+These two factors would allow a polling-only kernel CQ to be triggered
+by an EQ interrupt and call a completion function intended only for user
+CQs, causing a null pointer exception.
+
+Some areas in the driver have prevented this issue with one-off fixes
+but did not address the root cause.
+
+This patch fixes the described issue by adding defaults to the create CQ
+flow. It adds a default dummy completion function to protect against
+null pointer exceptions, and it sets an invalid command sequence number
+by default in kernel CQs to prevent the FW from sending an interrupt to
+the CQ until it is armed. User CQs are responsible for their own
+initialization values.
+
+Callers of mlx5_core_create_cq are responsible for changing the
+completion function and arming the CQ per their needs.
+
+Fixes: cdd04f4d4d71 ("net/mlx5: Add support to create SQ and CQ for ASO")
+Signed-off-by: Akiva Goldberger <agoldberger@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Acked-by: Leon Romanovsky <leon@kernel.org>
+Link: https://patch.msgid.link/1762681743-1084694-1-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/cq.c               | 11 +++++---
+ drivers/net/ethernet/mellanox/mlx5/core/cq.c  | 23 +++++++++++++--
+ .../net/ethernet/mellanox/mlx5/core/en_main.c |  1 -
+ .../ethernet/mellanox/mlx5/core/fpga/conn.c   | 15 +++++-----
+ .../mellanox/mlx5/core/steering/hws/send.c    |  7 -----
+ .../mellanox/mlx5/core/steering/sws/dr_send.c | 28 +++++--------------
+ drivers/vdpa/mlx5/net/mlx5_vnet.c             |  6 ++--
+ include/linux/mlx5/cq.h                       |  1 +
+ 8 files changed, 44 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
+index a23b364e24ffe..651d76bca114d 100644
+--- a/drivers/infiniband/hw/mlx5/cq.c
++++ b/drivers/infiniband/hw/mlx5/cq.c
+@@ -1020,15 +1020,18 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+       if (cq->create_flags & IB_UVERBS_CQ_FLAGS_IGNORE_OVERRUN)
+               MLX5_SET(cqc, cqc, oi, 1);
++      if (udata) {
++              cq->mcq.comp = mlx5_add_cq_to_tasklet;
++              cq->mcq.tasklet_ctx.comp = mlx5_ib_cq_comp;
++      } else {
++              cq->mcq.comp  = mlx5_ib_cq_comp;
++      }
++
+       err = mlx5_core_create_cq(dev->mdev, &cq->mcq, cqb, inlen, out, sizeof(out));
+       if (err)
+               goto err_cqb;
+       mlx5_ib_dbg(dev, "cqn 0x%x\n", cq->mcq.cqn);
+-      if (udata)
+-              cq->mcq.tasklet_ctx.comp = mlx5_ib_cq_comp;
+-      else
+-              cq->mcq.comp  = mlx5_ib_cq_comp;
+       cq->mcq.event = mlx5_ib_cq_event;
+       INIT_LIST_HEAD(&cq->wc_list);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+index e9f319a9bdd6b..60f7ab1d72e78 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+@@ -66,8 +66,8 @@ void mlx5_cq_tasklet_cb(struct tasklet_struct *t)
+               tasklet_schedule(&ctx->task);
+ }
+-static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq,
+-                                 struct mlx5_eqe *eqe)
++void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq,
++                          struct mlx5_eqe *eqe)
+ {
+       unsigned long flags;
+       struct mlx5_eq_tasklet *tasklet_ctx = cq->tasklet_ctx.priv;
+@@ -95,7 +95,15 @@ static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq,
+       if (schedule_tasklet)
+               tasklet_schedule(&tasklet_ctx->task);
+ }
++EXPORT_SYMBOL(mlx5_add_cq_to_tasklet);
++static void mlx5_core_cq_dummy_cb(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe)
++{
++      mlx5_core_err(cq->eq->core.dev,
++                    "CQ default completion callback, CQ #%u\n", cq->cqn);
++}
++
++#define MLX5_CQ_INIT_CMD_SN cpu_to_be32(2 << 28)
+ /* Callers must verify outbox status in case of err */
+ int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+                  u32 *in, int inlen, u32 *out, int outlen)
+@@ -121,10 +129,19 @@ int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+       cq->arm_sn     = 0;
+       cq->eq         = eq;
+       cq->uid = MLX5_GET(create_cq_in, in, uid);
++
++      /* Kernel CQs must set the arm_db address prior to calling
++       * this function, allowing for the proper value to be
++       * initialized. User CQs are responsible for their own
++       * initialization since they do not use the arm_db field.
++       */
++      if (cq->arm_db)
++              *cq->arm_db = MLX5_CQ_INIT_CMD_SN;
++
+       refcount_set(&cq->refcount, 1);
+       init_completion(&cq->free);
+       if (!cq->comp)
+-              cq->comp = mlx5_add_cq_to_tasklet;
++              cq->comp = mlx5_core_cq_dummy_cb;
+       /* assuming CQ will be deleted before the EQ */
+       cq->tasklet_ctx.priv = &eq->tasklet_ctx;
+       INIT_LIST_HEAD(&cq->tasklet_ctx.list);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 110d654796de9..885ffb1e718a8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -2218,7 +2218,6 @@ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev,
+       mcq->set_ci_db  = cq->wq_ctrl.db.db;
+       mcq->arm_db     = cq->wq_ctrl.db.db + 1;
+       *mcq->set_ci_db = 0;
+-      *mcq->arm_db    = 0;
+       mcq->vector     = param->eq_ix;
+       mcq->comp       = mlx5e_completion_event;
+       mcq->event      = mlx5e_cq_error_event;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
+index cb1319974f83f..ccef64fb40b66 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
+@@ -421,6 +421,13 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size)
+       __be64 *pas;
+       u32 i;
++      conn->cq.mcq.cqe_sz     = 64;
++      conn->cq.mcq.set_ci_db  = conn->cq.wq_ctrl.db.db;
++      conn->cq.mcq.arm_db     = conn->cq.wq_ctrl.db.db + 1;
++      *conn->cq.mcq.set_ci_db = 0;
++      conn->cq.mcq.vector     = 0;
++      conn->cq.mcq.comp       = mlx5_fpga_conn_cq_complete;
++
+       cq_size = roundup_pow_of_two(cq_size);
+       MLX5_SET(cqc, temp_cqc, log_cq_size, ilog2(cq_size));
+@@ -468,15 +475,7 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size)
+       if (err)
+               goto err_cqwq;
+-      conn->cq.mcq.cqe_sz     = 64;
+-      conn->cq.mcq.set_ci_db  = conn->cq.wq_ctrl.db.db;
+-      conn->cq.mcq.arm_db     = conn->cq.wq_ctrl.db.db + 1;
+-      *conn->cq.mcq.set_ci_db = 0;
+-      *conn->cq.mcq.arm_db    = 0;
+-      conn->cq.mcq.vector     = 0;
+-      conn->cq.mcq.comp       = mlx5_fpga_conn_cq_complete;
+       tasklet_setup(&conn->cq.tasklet, mlx5_fpga_conn_cq_tasklet);
+-
+       mlx5_fpga_dbg(fdev, "Created CQ #0x%x\n", conn->cq.mcq.cqn);
+       goto out;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
+index 24ef7d66fa8aa..7510c46e58a57 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
+@@ -873,12 +873,6 @@ static int hws_send_ring_open_sq(struct mlx5hws_context *ctx,
+       return err;
+ }
+-static void hws_cq_complete(struct mlx5_core_cq *mcq,
+-                          struct mlx5_eqe *eqe)
+-{
+-      pr_err("CQ completion CQ: #%u\n", mcq->cqn);
+-}
+-
+ static int hws_send_ring_alloc_cq(struct mlx5_core_dev *mdev,
+                                 int numa_node,
+                                 struct mlx5hws_send_engine *queue,
+@@ -901,7 +895,6 @@ static int hws_send_ring_alloc_cq(struct mlx5_core_dev *mdev,
+       mcq->cqe_sz = 64;
+       mcq->set_ci_db = cq->wq_ctrl.db.db;
+       mcq->arm_db = cq->wq_ctrl.db.db + 1;
+-      mcq->comp = hws_cq_complete;
+       for (i = 0; i < mlx5_cqwq_get_size(&cq->wq); i++) {
+               cqe = mlx5_cqwq_get_wqe(&cq->wq, i);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c
+index 077a77fde670e..d034372fa0476 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c
+@@ -1049,12 +1049,6 @@ static int dr_prepare_qp_to_rts(struct mlx5dr_domain *dmn)
+       return 0;
+ }
+-static void dr_cq_complete(struct mlx5_core_cq *mcq,
+-                         struct mlx5_eqe *eqe)
+-{
+-      pr_err("CQ completion CQ: #%u\n", mcq->cqn);
+-}
+-
+ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev,
+                                     struct mlx5_uars_page *uar,
+                                     size_t ncqe)
+@@ -1089,6 +1083,13 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev,
+               cqe->op_own = MLX5_CQE_INVALID << 4 | MLX5_CQE_OWNER_MASK;
+       }
++      cq->mcq.cqe_sz = 64;
++      cq->mcq.set_ci_db = cq->wq_ctrl.db.db;
++      cq->mcq.arm_db = cq->wq_ctrl.db.db + 1;
++      *cq->mcq.set_ci_db = 0;
++      cq->mcq.vector = 0;
++      cq->mdev = mdev;
++
+       inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
+               sizeof(u64) * cq->wq_ctrl.buf.npages;
+       in = kvzalloc(inlen, GFP_KERNEL);
+@@ -1112,27 +1113,12 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev,
+       pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas);
+       mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, pas);
+-      cq->mcq.comp  = dr_cq_complete;
+-
+       err = mlx5_core_create_cq(mdev, &cq->mcq, in, inlen, out, sizeof(out));
+       kvfree(in);
+       if (err)
+               goto err_cqwq;
+-      cq->mcq.cqe_sz = 64;
+-      cq->mcq.set_ci_db = cq->wq_ctrl.db.db;
+-      cq->mcq.arm_db = cq->wq_ctrl.db.db + 1;
+-      *cq->mcq.set_ci_db = 0;
+-
+-      /* set no-zero value, in order to avoid the HW to run db-recovery on
+-       * CQ that used in polling mode.
+-       */
+-      *cq->mcq.arm_db = cpu_to_be32(2 << 28);
+-
+-      cq->mcq.vector = 0;
+-      cq->mdev = mdev;
+-
+       return cq;
+ err_cqwq:
+diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
+index 0ed2fc28e1cef..53cc9ef01e9f7 100644
+--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
+@@ -573,6 +573,8 @@ static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent)
+       vcq->mcq.set_ci_db = vcq->db.db;
+       vcq->mcq.arm_db = vcq->db.db + 1;
+       vcq->mcq.cqe_sz = 64;
++      vcq->mcq.comp = mlx5_vdpa_cq_comp;
++      vcq->cqe = num_ent;
+       err = cq_frag_buf_alloc(ndev, &vcq->buf, num_ent);
+       if (err)
+@@ -612,10 +614,6 @@ static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent)
+       if (err)
+               goto err_vec;
+-      vcq->mcq.comp = mlx5_vdpa_cq_comp;
+-      vcq->cqe = num_ent;
+-      vcq->mcq.set_ci_db = vcq->db.db;
+-      vcq->mcq.arm_db = vcq->db.db + 1;
+       mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index);
+       kfree(in);
+       return 0;
+diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
+index 7ef2c7c7d803d..9d47cdc727ad0 100644
+--- a/include/linux/mlx5/cq.h
++++ b/include/linux/mlx5/cq.h
+@@ -183,6 +183,7 @@ static inline void mlx5_cq_put(struct mlx5_core_cq *cq)
+               complete(&cq->free);
+ }
++void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe);
+ int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+                  u32 *in, int inlen, u32 *out, int outlen);
+ int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-o.patch b/queue-6.17/net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-o.patch
new file mode 100644 (file)
index 0000000..7b5a372
--- /dev/null
@@ -0,0 +1,68 @@
+From a03cf96e1576f3f9266131e56b3316ba00a472c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:46:35 +0100
+Subject: net: dsa: tag_brcm: do not mark link local traffic as offloaded
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit 762e7e174da91cf4babfe77e45bc6b67334b1503 ]
+
+Broadcom switches locally terminate link local traffic and do not
+forward it, so we should not mark it as offloaded.
+
+In some situations we still want/need to flood this traffic, e.g. if STP
+is disabled, or it is explicitly enabled via the group_fwd_mask. But if
+the skb is marked as offloaded, the kernel will assume this was already
+done in hardware, and the packets never reach other bridge ports.
+
+So ensure that link local traffic is never marked as offloaded, so that
+the kernel can forward/flood these packets in software if needed.
+
+Since the local termination in not configurable, check the destination
+MAC, and never mark packets as offloaded if it is a link local ether
+address.
+
+While modern switches set the tag reason code to BRCM_EG_RC_PROT_TERM
+for trapped link local traffic, they also set it for link local traffic
+that is flooded (01:80:c2:00:00:10 to 01:80:c2:00:00:2f), so we cannot
+use it and need to look at the destination address for them as well.
+
+Fixes: 964dbf186eaa ("net: dsa: tag_brcm: add support for legacy tags")
+Fixes: 0e62f543bed0 ("net: dsa: Fix duplicate frames flooded by learning")
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20251109134635.243951-1-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/tag_brcm.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
+index d9c77fa553b53..eadb358179ce3 100644
+--- a/net/dsa/tag_brcm.c
++++ b/net/dsa/tag_brcm.c
+@@ -176,7 +176,8 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb,
+       /* Remove Broadcom tag and update checksum */
+       skb_pull_rcsum(skb, BRCM_TAG_LEN);
+-      dsa_default_offload_fwd_mark(skb);
++      if (likely(!is_link_local_ether_addr(eth_hdr(skb)->h_dest)))
++              dsa_default_offload_fwd_mark(skb);
+       return skb;
+ }
+@@ -250,7 +251,8 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
+       /* Remove Broadcom tag and update checksum */
+       skb_pull_rcsum(skb, len);
+-      dsa_default_offload_fwd_mark(skb);
++      if (likely(!is_link_local_ether_addr(eth_hdr(skb)->h_dest)))
++              dsa_default_offload_fwd_mark(skb);
+       dsa_strip_etype_header(skb, len);
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-respons.patch b/queue-6.17/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-respons.patch
new file mode 100644 (file)
index 0000000..094d3d0
--- /dev/null
@@ -0,0 +1,77 @@
+From f5062809f3f6124a7cdff538ad938a2abb91e65d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 14:53:04 +0530
+Subject: net: ethernet: ti: am65-cpsw-qos: fix IET verify/response timeout
+
+From: Aksh Garg <a-garg7@ti.com>
+
+[ Upstream commit 49b3916465176a5abcb29a0e464825f553d55d58 ]
+
+The CPSW module uses the MAC_VERIFY_CNT bit field in the
+CPSW_PN_IET_VERIFY_REG_k register to set the verify/response timeout
+count. This register specifies the number of clock cycles to wait before
+resending a verify packet if the verification fails.
+
+The verify/response timeout count, as being set by the function
+am65_cpsw_iet_set_verify_timeout_count() is hardcoded for 125MHz
+clock frequency, which varies based on PHY mode and link speed.
+
+The respective clock frequencies are as follows:
+- RGMII mode:
+  * 1000 Mbps: 125 MHz
+  * 100 Mbps: 25 MHz
+  * 10 Mbps: 2.5 MHz
+- QSGMII/SGMII mode: 125 MHz (all speeds)
+
+Fix this by adding logic to calculate the correct timeout counts
+based on the actual PHY interface mode and link speed.
+
+Fixes: 49a2eb9068246 ("net: ethernet: ti: am65-cpsw-qos: Add Frame Preemption MAC Merge support")
+Signed-off-by: Aksh Garg <a-garg7@ti.com>
+Link: https://patch.msgid.link/20251106092305.1437347-2-a-garg7@ti.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-qos.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-qos.c b/drivers/net/ethernet/ti/am65-cpsw-qos.c
+index fa96db7c1a130..ad06942ce461a 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-qos.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-qos.c
+@@ -276,9 +276,31 @@ static int am65_cpsw_iet_set_verify_timeout_count(struct am65_cpsw_port *port)
+       /* The number of wireside clocks contained in the verify
+        * timeout counter. The default is 0x1312d0
+        * (10ms at 125Mhz in 1G mode).
++       * The frequency of the clock depends on the link speed
++       * and the PHY interface.
+        */
+-      val = 125 * HZ_PER_MHZ; /* assuming 125MHz wireside clock */
++      switch (port->slave.phy_if) {
++      case PHY_INTERFACE_MODE_RGMII:
++      case PHY_INTERFACE_MODE_RGMII_ID:
++      case PHY_INTERFACE_MODE_RGMII_RXID:
++      case PHY_INTERFACE_MODE_RGMII_TXID:
++              if (port->qos.link_speed == SPEED_1000)
++                      val = 125 * HZ_PER_MHZ; /* 125 MHz at 1000Mbps*/
++              else if (port->qos.link_speed == SPEED_100)
++                      val = 25 * HZ_PER_MHZ;  /* 25 MHz at 100Mbps*/
++              else
++                      val = (25 * HZ_PER_MHZ) / 10;   /* 2.5 MHz at 10Mbps*/
++              break;
++
++      case PHY_INTERFACE_MODE_QSGMII:
++      case PHY_INTERFACE_MODE_SGMII:
++              val = 125 * HZ_PER_MHZ; /* 125 MHz */
++              break;
++      default:
++              netdev_err(port->ndev, "selected mode does not supported IET\n");
++              return -EOPNOTSUPP;
++      }
+       val /= MILLIHZ_PER_HZ;          /* count per ms timeout */
+       val *= verify_time_ms;          /* count for timeout ms */
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-retry-m.patch b/queue-6.17/net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-retry-m.patch
new file mode 100644 (file)
index 0000000..b07fbd4
--- /dev/null
@@ -0,0 +1,87 @@
+From ad7551026fbedcd2df863bf092018e07e91a66f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 14:53:05 +0530
+Subject: net: ethernet: ti: am65-cpsw-qos: fix IET verify retry mechanism
+
+From: Aksh Garg <a-garg7@ti.com>
+
+[ Upstream commit d4b00d132d7cb70a74bc039c91c1d6120943c71b ]
+
+The am65_cpsw_iet_verify_wait() function attempts verification 20 times,
+toggling the AM65_CPSW_PN_IET_MAC_LINKFAIL bit in each iteration. When
+the LINKFAIL bit transitions from 1 to 0, the MAC merge layer initiates
+the verification process and waits for the timeout configured in
+MAC_VERIFY_CNT before automatically retransmitting. The MAC_VERIFY_CNT
+register is configured according to the user-defined verify/response
+timeout in am65_cpsw_iet_set_verify_timeout_count(). As per IEEE 802.3
+Clause 99, the hardware performs this automatic retry up to 3 times.
+
+Current implementation toggles LINKFAIL after the user-configured
+verify/response timeout in each iteration, forcing the hardware to
+restart verification instead of respecting the MAC_VERIFY_CNT timeout.
+This bypasses the hardware's automatic retry mechanism.
+
+Fix this by moving the LINKFAIL bit toggle outside the retry loop and
+reducing the retry count from 20 to 3. The software now only monitors
+the status register while the hardware autonomously handles the 3
+verification attempts at proper MAC_VERIFY_CNT intervals.
+
+Fixes: 49a2eb9068246 ("net: ethernet: ti: am65-cpsw-qos: Add Frame Preemption MAC Merge support")
+Signed-off-by: Aksh Garg <a-garg7@ti.com>
+Link: https://patch.msgid.link/20251106092305.1437347-3-a-garg7@ti.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-qos.c | 27 +++++++++++++------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-qos.c b/drivers/net/ethernet/ti/am65-cpsw-qos.c
+index ad06942ce461a..66e8b224827b6 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-qos.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-qos.c
+@@ -317,20 +317,21 @@ static int am65_cpsw_iet_verify_wait(struct am65_cpsw_port *port)
+       u32 ctrl, status;
+       int try;
+-      try = 20;
+-      do {
+-              /* Reset the verify state machine by writing 1
+-               * to LINKFAIL
+-               */
+-              ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
+-              ctrl |= AM65_CPSW_PN_IET_MAC_LINKFAIL;
+-              writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      try = 3;
+-              /* Clear MAC_LINKFAIL bit to start Verify. */
+-              ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
+-              ctrl &= ~AM65_CPSW_PN_IET_MAC_LINKFAIL;
+-              writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      /* Reset the verify state machine by writing 1
++       * to LINKFAIL
++       */
++      ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      ctrl |= AM65_CPSW_PN_IET_MAC_LINKFAIL;
++      writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      /* Clear MAC_LINKFAIL bit to start Verify. */
++      ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++      ctrl &= ~AM65_CPSW_PN_IET_MAC_LINKFAIL;
++      writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
++
++      do {
+               msleep(port->qos.iet.verify_time_ms);
+               status = readl(port->port_base + AM65_CPSW_PN_REG_IET_STATUS);
+@@ -352,7 +353,7 @@ static int am65_cpsw_iet_verify_wait(struct am65_cpsw_port *port)
+                       netdev_dbg(port->ndev, "MAC Merge verify error\n");
+                       return -ENODEV;
+               }
+-      } while (try-- > 0);
++      } while (--try > 0);
+       netdev_dbg(port->ndev, "MAC Merge verify timeout\n");
+       return -ETIMEDOUT;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch b/queue-6.17/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
new file mode 100644 (file)
index 0000000..c44447e
--- /dev/null
@@ -0,0 +1,39 @@
+From f783c9a26326a1f4cf357da4275b2412a2f67e3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:14:21 +0800
+Subject: net: fec: correct rx_bytes statistic for the case SHIFT16 is set
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit ad17e7e92a7c52ce70bb764813fcf99464f96903 ]
+
+Two additional bytes in front of each frame received into the RX FIFO if
+SHIFT16 is set, so we need to subtract the extra two bytes from pkt_len
+to correct the statistic of rx_bytes.
+
+Fixes: 3ac72b7b63d5 ("net: fec: align IP header in hardware")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20251106021421.2096585-1-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index adf1f2bbcbb16..c404ca590b73c 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1820,6 +1820,8 @@ fec_enet_rx_queue(struct net_device *ndev, u16 queue_id, int budget)
+               ndev->stats.rx_packets++;
+               pkt_len = fec16_to_cpu(bdp->cbd_datlen);
+               ndev->stats.rx_bytes += pkt_len;
++              if (fep->quirks & FEC_QUIRK_HAS_RACC)
++                      ndev->stats.rx_bytes -= 2;
+               index = fec_enet_get_bd_index(bdp, &rxq->bd);
+               page = rxq->rx_skb_info[index].page;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch b/queue-6.17/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch
new file mode 100644 (file)
index 0000000..f42e4d1
--- /dev/null
@@ -0,0 +1,42 @@
+From 6ecac7f08b743aa1d52b6e7114cd8038c31b0e30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 14:45:11 +0000
+Subject: net/handshake: Fix memory leak in tls_handshake_accept()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit 3072f00bba764082fa41b3c3a2a7b013335353d2 ]
+
+In tls_handshake_accept(), a netlink message is allocated using
+genlmsg_new(). In the error handling path, genlmsg_cancel() is called
+to cancel the message construction, but the message itself is not freed.
+This leads to a memory leak.
+
+Fix this by calling nlmsg_free() in the error path after genlmsg_cancel()
+to release the allocated memory.
+
+Fixes: 2fd5532044a89 ("net/handshake: Add a kernel API for requesting a TLSv1.3 handshake")
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://patch.msgid.link/20251106144511.3859535-1-zilin@seu.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/tlshd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index 081093dfd5533..8f9532a15f43f 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -259,6 +259,7 @@ static int tls_handshake_accept(struct handshake_req *req,
+ out_cancel:
+       genlmsg_cancel(msg, hdr);
++      nlmsg_free(msg);
+ out:
+       return ret;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch b/queue-6.17/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
new file mode 100644 (file)
index 0000000..c3c45a9
--- /dev/null
@@ -0,0 +1,45 @@
+From 0ec2298f91972a8b50399fa676efa3826365bd82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 07:49:22 +0100
+Subject: net: mdio: fix resource leak in mdiobus_register_device()
+
+From: Buday Csaba <buday.csaba@prolan.hu>
+
+[ Upstream commit e6ca8f533ed41129fcf052297718f417f021cc7d ]
+
+Fix a possible leak in mdiobus_register_device() when both a
+reset-gpio and a reset-controller are present.
+Clean up the already claimed reset-gpio, when the registration of
+the reset-controller fails, so when an error code is returned, the
+device retains its state before the registration attempt.
+
+Link: https://lore.kernel.org/all/20251106144603.39053c81@kernel.org/
+Fixes: 71dd6c0dff51 ("net: phy: add support for reset-controller")
+Signed-off-by: Buday Csaba <buday.csaba@prolan.hu>
+Link: https://patch.msgid.link/4b419377f8dd7d2f63f919d0f74a336c734f8fff.1762584481.git.buday.csaba@prolan.hu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mdio_bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index cad6ed3aa10b6..4354241137d50 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -73,8 +73,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
+                       return err;
+               err = mdiobus_register_reset(mdiodev);
+-              if (err)
++              if (err) {
++                      gpiod_put(mdiodev->reset_gpio);
++                      mdiodev->reset_gpio = NULL;
+                       return err;
++              }
+               /* Assert the reset signal */
+               mdio_device_reset(mdiodev, 1);
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mlx5-fix-typo-of-mlx5_eq_doorbel_offset.patch b/queue-6.17/net-mlx5-fix-typo-of-mlx5_eq_doorbel_offset.patch
new file mode 100644 (file)
index 0000000..388ef22
--- /dev/null
@@ -0,0 +1,49 @@
+From 6ac2d76198123549667d914304fcb743a2ebb22c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Sep 2025 17:11:35 +0300
+Subject: net/mlx5: Fix typo of MLX5_EQ_DOORBEL_OFFSET
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 917449e7c3cdc7a0dfe429de997e39098d9cdd20 ]
+
+Also convert it to a simple define.
+
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: e5eba42f0134 ("mlx5: Fix default values in create CQ")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/eq.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+index 1ab77159409d6..f3c714ebd9cb4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+@@ -32,9 +32,7 @@ enum {
+       MLX5_EQ_STATE_ALWAYS_ARMED      = 0xb,
+ };
+-enum {
+-      MLX5_EQ_DOORBEL_OFFSET  = 0x40,
+-};
++#define MLX5_EQ_DOORBELL_OFFSET 0x40
+ /* budget must be smaller than MLX5_NUM_SPARE_EQE to guarantee that we update
+  * the ci before we polled all the entries in the EQ. MLX5_NUM_SPARE_EQE is
+@@ -322,7 +320,7 @@ create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
+       eq->eqn = MLX5_GET(create_eq_out, out, eq_number);
+       eq->irqn = pci_irq_vector(dev->pdev, vecidx);
+       eq->dev = dev;
+-      eq->doorbell = priv->uar->map + MLX5_EQ_DOORBEL_OFFSET;
++      eq->doorbell = priv->uar->map + MLX5_EQ_DOORBELL_OFFSET;
+       err = mlx5_debug_eq_add(dev, eq);
+       if (err)
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mlx5-store-the-global-doorbell-in-mlx5_priv.patch b/queue-6.17/net-mlx5-store-the-global-doorbell-in-mlx5_priv.patch
new file mode 100644 (file)
index 0000000..1b1b499
--- /dev/null
@@ -0,0 +1,381 @@
+From e2ac326c10755ccf9ca4d8a6e890a653b19d1d16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Sep 2025 17:11:38 +0300
+Subject: net/mlx5: Store the global doorbell in mlx5_priv
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit aa4595d0ada65d5d44fa924a42a87c175d9d88e3 ]
+
+The global doorbell is used for more than just Ethernet resources, so
+move it out of mlx5e_hw_objs into a common place (mlx5_priv), to avoid
+non-Ethernet modules (e.g. HWS, ASO) depending on Ethernet structs.
+
+Use this opportunity to consolidate it with the 'uar' pointer already
+there, which was used as an RX doorbell. Underneath the 'uar' pointer is
+identical to 'bfreg->up', so store a single resource and use that
+instead.
+
+For CQ doorbells, care is taken to always use bfreg->up->index instead
+of bfreg->index, which may refer to a subsequent UAR page from the same
+ALLOC_UAR batch on some NICs.
+
+This paves the way for cleanly supporting multiple doorbells in the
+Ethernet driver.
+
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: e5eba42f0134 ("mlx5: Fix default values in create CQ")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/cq.c                       |  4 ++--
+ drivers/net/ethernet/mellanox/mlx5/core/cq.c          |  2 +-
+ drivers/net/ethernet/mellanox/mlx5/core/en/params.c   |  2 +-
+ drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c      |  2 +-
+ drivers/net/ethernet/mellanox/mlx5/core/en_common.c   | 11 +----------
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c     | 10 +++++-----
+ drivers/net/ethernet/mellanox/mlx5/core/eq.c          |  4 ++--
+ drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c     |  8 ++++----
+ drivers/net/ethernet/mellanox/mlx5/core/main.c        | 11 +++++------
+ .../ethernet/mellanox/mlx5/core/steering/hws/send.c   |  8 ++++----
+ drivers/net/ethernet/mellanox/mlx5/core/wc.c          |  4 ++--
+ include/linux/mlx5/driver.h                           |  3 +--
+ 12 files changed, 29 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
+index 9c8003a783343..a23b364e24ffe 100644
+--- a/drivers/infiniband/hw/mlx5/cq.c
++++ b/drivers/infiniband/hw/mlx5/cq.c
+@@ -648,7 +648,7 @@ int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
+ {
+       struct mlx5_core_dev *mdev = to_mdev(ibcq->device)->mdev;
+       struct mlx5_ib_cq *cq = to_mcq(ibcq);
+-      void __iomem *uar_page = mdev->priv.uar->map;
++      void __iomem *uar_page = mdev->priv.bfreg.up->map;
+       unsigned long irq_flags;
+       int ret = 0;
+@@ -923,7 +923,7 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
+                cq->buf.frag_buf.page_shift -
+                MLX5_ADAPTER_PAGE_SHIFT);
+-      *index = dev->mdev->priv.uar->index;
++      *index = dev->mdev->priv.bfreg.up->index;
+       return 0;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+index 1fd403713bafc..35039a95dcfd4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+@@ -145,7 +145,7 @@ int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+               mlx5_core_dbg(dev, "failed adding CP 0x%x to debug file system\n",
+                             cq->cqn);
+-      cq->uar = dev->priv.uar;
++      cq->uar = dev->priv.bfreg.up;
+       cq->irqn = eq->core.irqn;
+       return 0;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+index 06e1a04e693f3..c24cb2ab91cb1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+@@ -810,7 +810,7 @@ static void mlx5e_build_common_cq_param(struct mlx5_core_dev *mdev,
+ {
+       void *cqc = param->cqc;
+-      MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index);
++      MLX5_SET(cqc, cqc, uar_page, mdev->priv.bfreg.up->index);
+       if (MLX5_CAP_GEN(mdev, cqe_128_always) && cache_line_size() >= 128)
+               MLX5_SET(cqc, cqc, cqe_sz, CQE_STRIDE_128_PAD);
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+index 391b4e9c9dc49..7c1d9a9ea4645 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+@@ -334,7 +334,7 @@ static int mlx5e_ptp_alloc_txqsq(struct mlx5e_ptp *c, int txq_ix,
+       sq->mdev      = mdev;
+       sq->ch_ix     = MLX5E_PTP_CHANNEL_IX;
+       sq->txq_ix    = txq_ix;
+-      sq->uar_map   = mdev->mlx5e_res.hw_objs.bfreg.map;
++      sq->uar_map   = mdev->priv.bfreg.map;
+       sq->min_inline_mode = params->tx_min_inline_mode;
+       sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu);
+       sq->stats     = &c->priv->ptp_stats.sq[tc];
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
+index 6ed3a32b7e226..e9e36358c39d1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
+@@ -163,17 +163,11 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises)
+               goto err_dealloc_transport_domain;
+       }
+-      err = mlx5_alloc_bfreg(mdev, &res->bfreg, false, false);
+-      if (err) {
+-              mlx5_core_err(mdev, "alloc bfreg failed, %d\n", err);
+-              goto err_destroy_mkey;
+-      }
+-
+       if (create_tises) {
+               err = mlx5e_create_tises(mdev, res->tisn);
+               if (err) {
+                       mlx5_core_err(mdev, "alloc tises failed, %d\n", err);
+-                      goto err_destroy_bfreg;
++                      goto err_destroy_mkey;
+               }
+               res->tisn_valid = true;
+       }
+@@ -190,8 +184,6 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises)
+       return 0;
+-err_destroy_bfreg:
+-      mlx5_free_bfreg(mdev, &res->bfreg);
+ err_destroy_mkey:
+       mlx5_core_destroy_mkey(mdev, res->mkey);
+ err_dealloc_transport_domain:
+@@ -209,7 +201,6 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev)
+       mdev->mlx5e_res.dek_priv = NULL;
+       if (res->tisn_valid)
+               mlx5e_destroy_tises(mdev, res->tisn);
+-      mlx5_free_bfreg(mdev, &res->bfreg);
+       mlx5_core_destroy_mkey(mdev, res->mkey);
+       mlx5_core_dealloc_transport_domain(mdev, res->td.tdn);
+       mlx5_core_dealloc_pd(mdev, res->pdn);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 2c82c5100af3c..1a90fd1d44edb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -1551,7 +1551,7 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
+       sq->pdev      = c->pdev;
+       sq->mkey_be   = c->mkey_be;
+       sq->channel   = c;
+-      sq->uar_map   = mdev->mlx5e_res.hw_objs.bfreg.map;
++      sq->uar_map   = mdev->priv.bfreg.map;
+       sq->min_inline_mode = params->tx_min_inline_mode;
+       sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN;
+       sq->xsk_pool  = xsk_pool;
+@@ -1636,7 +1636,7 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c,
+       int err;
+       sq->channel   = c;
+-      sq->uar_map   = mdev->mlx5e_res.hw_objs.bfreg.map;
++      sq->uar_map   = mdev->priv.bfreg.map;
+       sq->reserved_room = param->stop_room;
+       param->wq.db_numa_node = cpu_to_node(c->cpu);
+@@ -1721,7 +1721,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
+       sq->priv      = c->priv;
+       sq->ch_ix     = c->ix;
+       sq->txq_ix    = txq_ix;
+-      sq->uar_map   = mdev->mlx5e_res.hw_objs.bfreg.map;
++      sq->uar_map   = mdev->priv.bfreg.map;
+       sq->min_inline_mode = params->tx_min_inline_mode;
+       sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu);
+       sq->max_sq_mpw_wqebbs = mlx5e_get_max_sq_aligned_wqebbs(mdev);
+@@ -1797,7 +1797,7 @@ static int mlx5e_create_sq(struct mlx5_core_dev *mdev,
+       MLX5_SET(sqc,  sqc, flush_in_error_en, 1);
+       MLX5_SET(wq,   wq, wq_type,       MLX5_WQ_TYPE_CYCLIC);
+-      MLX5_SET(wq,   wq, uar_page,      mdev->mlx5e_res.hw_objs.bfreg.index);
++      MLX5_SET(wq,   wq, uar_page,      mdev->priv.bfreg.index);
+       MLX5_SET(wq,   wq, log_wq_pg_sz,  csp->wq_ctrl->buf.page_shift -
+                                         MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET64(wq, wq, dbr_addr,      csp->wq_ctrl->db.dma);
+@@ -2292,7 +2292,7 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
+       MLX5_SET(cqc, cqc, cq_period_mode, mlx5e_cq_period_mode(param->cq_period_mode));
+       MLX5_SET(cqc,   cqc, c_eqn_or_apu_element, eqn);
+-      MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.uar->index);
++      MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.bfreg.up->index);
+       MLX5_SET(cqc,   cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
+                                           MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET64(cqc, cqc, dbr_addr,      cq->wq_ctrl.db.dma);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+index f3c714ebd9cb4..25499da177bc4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+@@ -307,7 +307,7 @@ create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
+       eqc = MLX5_ADDR_OF(create_eq_in, in, eq_context_entry);
+       MLX5_SET(eqc, eqc, log_eq_size, eq->fbc.log_sz);
+-      MLX5_SET(eqc, eqc, uar_page, priv->uar->index);
++      MLX5_SET(eqc, eqc, uar_page, priv->bfreg.up->index);
+       MLX5_SET(eqc, eqc, intr, vecidx);
+       MLX5_SET(eqc, eqc, log_page_size,
+                eq->frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
+@@ -320,7 +320,7 @@ create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
+       eq->eqn = MLX5_GET(create_eq_out, out, eq_number);
+       eq->irqn = pci_irq_vector(dev->pdev, vecidx);
+       eq->dev = dev;
+-      eq->doorbell = priv->uar->map + MLX5_EQ_DOORBELL_OFFSET;
++      eq->doorbell = priv->bfreg.up->map + MLX5_EQ_DOORBELL_OFFSET;
+       err = mlx5_debug_eq_add(dev, eq);
+       if (err)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
+index 58bd749b5e4de..129725159a935 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
+@@ -100,7 +100,7 @@ static int create_aso_cq(struct mlx5_aso_cq *cq, void *cqc_data)
+       MLX5_SET(cqc,   cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
+       MLX5_SET(cqc,   cqc, c_eqn_or_apu_element, eqn);
+-      MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.uar->index);
++      MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.bfreg.up->index);
+       MLX5_SET(cqc,   cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
+                                           MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET64(cqc, cqc, dbr_addr,      cq->wq_ctrl.db.dma);
+@@ -129,7 +129,7 @@ static int mlx5_aso_create_cq(struct mlx5_core_dev *mdev, int numa_node,
+               return -ENOMEM;
+       MLX5_SET(cqc, cqc_data, log_cq_size, 1);
+-      MLX5_SET(cqc, cqc_data, uar_page, mdev->priv.uar->index);
++      MLX5_SET(cqc, cqc_data, uar_page, mdev->priv.bfreg.up->index);
+       if (MLX5_CAP_GEN(mdev, cqe_128_always) && cache_line_size() >= 128)
+               MLX5_SET(cqc, cqc_data, cqe_sz, CQE_STRIDE_128_PAD);
+@@ -163,7 +163,7 @@ static int mlx5_aso_alloc_sq(struct mlx5_core_dev *mdev, int numa_node,
+       struct mlx5_wq_param param;
+       int err;
+-      sq->uar_map = mdev->mlx5e_res.hw_objs.bfreg.map;
++      sq->uar_map = mdev->priv.bfreg.map;
+       param.db_numa_node = numa_node;
+       param.buf_numa_node = numa_node;
+@@ -203,7 +203,7 @@ static int create_aso_sq(struct mlx5_core_dev *mdev, int pdn,
+       MLX5_SET(sqc, sqc, ts_format, ts_format);
+       MLX5_SET(wq,   wq, wq_type,       MLX5_WQ_TYPE_CYCLIC);
+-      MLX5_SET(wq,   wq, uar_page,      mdev->mlx5e_res.hw_objs.bfreg.index);
++      MLX5_SET(wq,   wq, uar_page,      mdev->priv.bfreg.index);
+       MLX5_SET(wq,   wq, log_wq_pg_sz,  sq->wq_ctrl.buf.page_shift -
+                                         MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET64(wq, wq, dbr_addr,      sq->wq_ctrl.db.dma);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 8517d4e5d5efc..3df7401f2256c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1340,10 +1340,9 @@ static int mlx5_load(struct mlx5_core_dev *dev)
+ {
+       int err;
+-      dev->priv.uar = mlx5_get_uars_page(dev);
+-      if (IS_ERR(dev->priv.uar)) {
+-              mlx5_core_err(dev, "Failed allocating uar, aborting\n");
+-              err = PTR_ERR(dev->priv.uar);
++      err = mlx5_alloc_bfreg(dev, &dev->priv.bfreg, false, false);
++      if (err) {
++              mlx5_core_err(dev, "Failed allocating bfreg, %d\n", err);
+               return err;
+       }
+@@ -1454,7 +1453,7 @@ static int mlx5_load(struct mlx5_core_dev *dev)
+ err_irq_table:
+       mlx5_pagealloc_stop(dev);
+       mlx5_events_stop(dev);
+-      mlx5_put_uars_page(dev, dev->priv.uar);
++      mlx5_free_bfreg(dev, &dev->priv.bfreg);
+       return err;
+ }
+@@ -1479,7 +1478,7 @@ static void mlx5_unload(struct mlx5_core_dev *dev)
+       mlx5_irq_table_destroy(dev);
+       mlx5_pagealloc_stop(dev);
+       mlx5_events_stop(dev);
+-      mlx5_put_uars_page(dev, dev->priv.uar);
++      mlx5_free_bfreg(dev, &dev->priv.bfreg);
+ }
+ int mlx5_init_one_devl_locked(struct mlx5_core_dev *dev)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
+index b0595c9b09e42..24ef7d66fa8aa 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
+@@ -690,7 +690,7 @@ static int hws_send_ring_alloc_sq(struct mlx5_core_dev *mdev,
+       size_t buf_sz;
+       int err;
+-      sq->uar_map = mdev->mlx5e_res.hw_objs.bfreg.map;
++      sq->uar_map = mdev->priv.bfreg.map;
+       sq->mdev = mdev;
+       param.db_numa_node = numa_node;
+@@ -764,7 +764,7 @@ static int hws_send_ring_create_sq(struct mlx5_core_dev *mdev, u32 pdn,
+       MLX5_SET(sqc, sqc, ts_format, ts_format);
+       MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
+-      MLX5_SET(wq, wq, uar_page, mdev->mlx5e_res.hw_objs.bfreg.index);
++      MLX5_SET(wq, wq, uar_page, mdev->priv.bfreg.index);
+       MLX5_SET(wq, wq, log_wq_pg_sz, sq->wq_ctrl.buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET64(wq, wq, dbr_addr, sq->wq_ctrl.db.dma);
+@@ -940,7 +940,7 @@ static int hws_send_ring_create_cq(struct mlx5_core_dev *mdev,
+                                 (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas));
+       MLX5_SET(cqc, cqc, c_eqn_or_apu_element, eqn);
+-      MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index);
++      MLX5_SET(cqc, cqc, uar_page, mdev->priv.bfreg.up->index);
+       MLX5_SET(cqc, cqc, log_page_size, cq->wq_ctrl.buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET64(cqc, cqc, dbr_addr, cq->wq_ctrl.db.dma);
+@@ -963,7 +963,7 @@ static int hws_send_ring_open_cq(struct mlx5_core_dev *mdev,
+       if (!cqc_data)
+               return -ENOMEM;
+-      MLX5_SET(cqc, cqc_data, uar_page, mdev->priv.uar->index);
++      MLX5_SET(cqc, cqc_data, uar_page, mdev->priv.bfreg.up->index);
+       MLX5_SET(cqc, cqc_data, log_cq_size, ilog2(queue->num_entries));
+       err = hws_send_ring_alloc_cq(mdev, numa_node, queue, cqc_data, cq);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wc.c b/drivers/net/ethernet/mellanox/mlx5/core/wc.c
+index 2f0316616fa40..0d3591ff22733 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/wc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/wc.c
+@@ -94,7 +94,7 @@ static int create_wc_cq(struct mlx5_wc_cq *cq, void *cqc_data)
+       MLX5_SET(cqc,   cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
+       MLX5_SET(cqc,   cqc, c_eqn_or_apu_element, eqn);
+-      MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.uar->index);
++      MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.bfreg.up->index);
+       MLX5_SET(cqc,   cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
+                                           MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET64(cqc, cqc, dbr_addr,      cq->wq_ctrl.db.dma);
+@@ -116,7 +116,7 @@ static int mlx5_wc_create_cq(struct mlx5_core_dev *mdev, struct mlx5_wc_cq *cq)
+               return -ENOMEM;
+       MLX5_SET(cqc, cqc, log_cq_size, TEST_WC_LOG_CQ_SZ);
+-      MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index);
++      MLX5_SET(cqc, cqc, uar_page, mdev->priv.bfreg.up->index);
+       if (MLX5_CAP_GEN(mdev, cqe_128_always) && cache_line_size() >= 128)
+               MLX5_SET(cqc, cqc, cqe_sz, CQE_STRIDE_128_PAD);
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 10fe492e1fedc..c185f082748ae 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -611,7 +611,7 @@ struct mlx5_priv {
+       struct mlx5_ft_pool             *ft_pool;
+       struct mlx5_bfreg_data          bfregs;
+-      struct mlx5_uars_page          *uar;
++      struct mlx5_sq_bfreg bfreg;
+ #ifdef CONFIG_MLX5_SF
+       struct mlx5_vhca_state_notifier *vhca_state_notifier;
+       struct mlx5_sf_dev_table *sf_dev_table;
+@@ -657,7 +657,6 @@ struct mlx5e_resources {
+               u32                        pdn;
+               struct mlx5_td             td;
+               u32                        mkey;
+-              struct mlx5_sq_bfreg       bfreg;
+ #define MLX5_MAX_NUM_TC 8
+               u32                        tisn[MLX5_MAX_PORTS][MLX5_MAX_NUM_TC];
+               bool                       tisn_valid;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch b/queue-6.17/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
new file mode 100644 (file)
index 0000000..4c26741
--- /dev/null
@@ -0,0 +1,58 @@
+From 71dd34345a1092d61ab76e70d902beb23368feb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:51 +0200
+Subject: net/mlx5e: Fix maxrate wraparound in threshold between units
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit a7bf4d5063c7837096aab2853224eb23628514d9 ]
+
+The previous calculation used roundup() which caused an overflow for
+rates between 25.5Gbps and 26Gbps.
+For example, a rate of 25.6Gbps would result in using 100Mbps units with
+value of 256, which would overflow the 8 bits field.
+
+Simplify the upper_limit_mbps calculation by removing the
+unnecessary roundup, and adjust the comparison to use <= to correctly
+handle the boundary condition.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index d166c0d5189e1..3456144710528 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -595,18 +595,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       struct mlx5_core_dev *mdev = priv->mdev;
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+-      __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
++      __u64 upper_limit_mbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
++      upper_limit_mbps = 255 * MLX5E_100MB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+                       max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
+                       continue;
+               }
+-              if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
++              if (maxrate->tc_maxrate[i] <= upper_limit_mbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mlx5e-fix-missing-error-assignment-in-mlx5e_xfrm.patch b/queue-6.17/net-mlx5e-fix-missing-error-assignment-in-mlx5e_xfrm.patch
new file mode 100644 (file)
index 0000000..a0c1728
--- /dev/null
@@ -0,0 +1,44 @@
+From ae8f261fdc9b3b48813c8781da042a5219b6b835 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:49 +0200
+Subject: net/mlx5e: Fix missing error assignment in mlx5e_xfrm_add_state()
+
+From: Carolina Jubran <cjubran@nvidia.com>
+
+[ Upstream commit 0bcd5b3b50cc1fcbf775479322cc37c15d35a489 ]
+
+Assign the return value of mlx5_eswitch_block_mode() to 'err' before
+checking it to avoid returning an uninitialized error code.
+
+Fixes: 22239eb258bc ("net/mlx5e: Prevent tunnel reformat when tunnel mode not allowed")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/202510271649.uwsIxD6O-lkp@intel.com/
+Closes: http://lore.kernel.org/linux-rdma/aPIEK4rLB586FdDt@stanley.mountain/
+Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
+Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 0a4fb8c922684..35d9530037a65 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -804,7 +804,8 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
+               goto err_xfrm;
+       }
+-      if (mlx5_eswitch_block_mode(priv->mdev))
++      err = mlx5_eswitch_block_mode(priv->mdev);
++      if (err)
+               goto unblock_ipsec;
+       if (x->props.mode == XFRM_MODE_TUNNEL &&
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mlx5e-fix-potentially-misleading-debug-message.patch b/queue-6.17/net-mlx5e-fix-potentially-misleading-debug-message.patch
new file mode 100644 (file)
index 0000000..829d9cf
--- /dev/null
@@ -0,0 +1,62 @@
+From 054dfd26f74f6b360ab83cf95c173ed219784f9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:53 +0200
+Subject: net/mlx5e: Fix potentially misleading debug message
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 9fcc2b6c10523f7e75db6387946c86fcf19dc97e ]
+
+Change the debug message to print the correct units instead of always
+assuming Gbps, as the value can be in either 100 Mbps or 1 Gbps units.
+
+Fixes: 5da8bc3effb6 ("net/mlx5e: DCBNL, Add debug messages log")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-6-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index d88a48210fdcb..9b93da4d52f64 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -598,6 +598,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       __u64 upper_limit_mbps;
+       __u64 upper_limit_gbps;
+       int i;
++      struct {
++              int scale;
++              const char *units_str;
++      } units[] = {
++              [MLX5_100_MBPS_UNIT] = {
++                      .scale = 100,
++                      .units_str = "Mbps",
++              },
++              [MLX5_GBPS_UNIT] = {
++                      .scale = 1,
++                      .units_str = "Gbps",
++              },
++      };
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+@@ -628,8 +641,9 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       }
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+-              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %d Gbps\n",
+-                         __func__, i, max_bw_value[i]);
++              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %u %s\n", __func__, i,
++                         max_bw_value[i] * units[max_bw_unit[i]].scale,
++                         units[max_bw_unit[i]].units_str);
+       }
+       return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch b/queue-6.17/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
new file mode 100644 (file)
index 0000000..29a1e46
--- /dev/null
@@ -0,0 +1,62 @@
+From 65ddef48acba089281868d75e058497234ee1311 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:52 +0200
+Subject: net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 43b27d1bd88a4bce34ec2437d103acfae9655f9e ]
+
+Add validation to reject rates exceeding 255 Gbps that would overflow
+the 8 bits max bandwidth field.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 3456144710528..d88a48210fdcb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -596,11 +596,13 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+       __u64 upper_limit_mbps;
++      __u64 upper_limit_gbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+       upper_limit_mbps = 255 * MLX5E_100MB;
++      upper_limit_gbps = 255 * MLX5E_1GB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+@@ -612,10 +614,16 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else {
++              } else if (max_bw_value[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
++              } else {
++                      netdev_err(netdev,
++                                 "tc_%d maxrate %llu Kbps exceeds limit %llu\n",
++                                 i, maxrate->tc_maxrate[i],
++                                 upper_limit_gbps);
++                      return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-mlx5e-prepare-for-using-different-cq-doorbells.patch b/queue-6.17/net-mlx5e-prepare-for-using-different-cq-doorbells.patch
new file mode 100644 (file)
index 0000000..2b0cebd
--- /dev/null
@@ -0,0 +1,173 @@
+From 3106aa072478c75163333b14088e5c27c15f0fec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Sep 2025 17:11:40 +0300
+Subject: net/mlx5e: Prepare for using different CQ doorbells
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit a315b723e87ba4e4573e1e5c759d512f38bdc0b3 ]
+
+Completion queues (CQs) in mlx5 use the same global doorbell, which may
+become contended when accessed concurrently from many cores.
+
+This patch prepares the CQ management code for supporting different
+doorbells per CQ. This will be used in downstream patches to allow
+separate doorbells to be used by channels CQs.
+
+The main change is moving the 'uar' pointer from struct mlx5_core_cq to
+struct mlx5e_cq, as the uar page to be used is better off stored
+directly there. Other users of mlx5_core_cq also store the UAR to be
+used separately and therefore the pointer being removed is dead weight
+for them. As evidence, in this patch there are two users which set the
+mcq.uar pointer but didn't use it, Software Steering and old Innova CQ
+creation code. Instead, they rang the doorbell directly from another
+pointer.
+
+The 'uar' pointer added to struct mlx5e_cq remains in a hot cacheline
+(as before), because it may get accessed for each packet.
+
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: e5eba42f0134 ("mlx5: Fix default values in create CQ")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/cq.c           |  1 -
+ drivers/net/ethernet/mellanox/mlx5/core/en.h           |  1 +
+ drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h      |  5 +----
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c      | 10 +++++++---
+ drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c    |  1 -
+ .../ethernet/mellanox/mlx5/core/steering/sws/dr_send.c |  1 -
+ include/linux/mlx5/cq.h                                |  1 -
+ 7 files changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+index 35039a95dcfd4..e9f319a9bdd6b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+@@ -145,7 +145,6 @@ int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+               mlx5_core_dbg(dev, "failed adding CP 0x%x to debug file system\n",
+                             cq->cqn);
+-      cq->uar = dev->priv.bfreg.up;
+       cq->irqn = eq->core.irqn;
+       return 0;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index ff4a68648e604..4fc102d18354f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -344,6 +344,7 @@ struct mlx5e_cq {
+       /* data path - accessed per napi poll */
+       u16                        event_ctr;
+       struct napi_struct        *napi;
++      struct mlx5_uars_page     *uar;
+       struct mlx5_core_cq        mcq;
+       struct mlx5e_ch_stats     *ch_stats;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+index 5dc04bbfc71bb..6760bb0336df9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+@@ -309,10 +309,7 @@ mlx5e_notify_hw(struct mlx5_wq_cyc *wq, u16 pc, void __iomem *uar_map,
+ static inline void mlx5e_cq_arm(struct mlx5e_cq *cq)
+ {
+-      struct mlx5_core_cq *mcq;
+-
+-      mcq = &cq->mcq;
+-      mlx5_cq_arm(mcq, MLX5_CQ_DB_REQ_NOT, mcq->uar->map, cq->wq.cc);
++      mlx5_cq_arm(&cq->mcq, MLX5_CQ_DB_REQ_NOT, cq->uar->map, cq->wq.cc);
+ }
+ static inline struct mlx5e_sq_dma *
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 1a90fd1d44edb..110d654796de9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -2201,6 +2201,7 @@ static void mlx5e_close_xdpredirect_sq(struct mlx5e_xdpsq *xdpsq)
+ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev,
+                                struct net_device *netdev,
+                                struct workqueue_struct *workqueue,
++                               struct mlx5_uars_page *uar,
+                                struct mlx5e_cq_param *param,
+                                struct mlx5e_cq *cq)
+ {
+@@ -2232,6 +2233,7 @@ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev,
+       cq->mdev = mdev;
+       cq->netdev = netdev;
+       cq->workqueue = workqueue;
++      cq->uar = uar;
+       return 0;
+ }
+@@ -2247,7 +2249,8 @@ static int mlx5e_alloc_cq(struct mlx5_core_dev *mdev,
+       param->wq.db_numa_node  = ccp->node;
+       param->eq_ix            = ccp->ix;
+-      err = mlx5e_alloc_cq_common(mdev, ccp->netdev, ccp->wq, param, cq);
++      err = mlx5e_alloc_cq_common(mdev, ccp->netdev, ccp->wq,
++                                  mdev->priv.bfreg.up, param, cq);
+       cq->napi     = ccp->napi;
+       cq->ch_stats = ccp->ch_stats;
+@@ -2292,7 +2295,7 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
+       MLX5_SET(cqc, cqc, cq_period_mode, mlx5e_cq_period_mode(param->cq_period_mode));
+       MLX5_SET(cqc,   cqc, c_eqn_or_apu_element, eqn);
+-      MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.bfreg.up->index);
++      MLX5_SET(cqc,   cqc, uar_page,      cq->uar->index);
+       MLX5_SET(cqc,   cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
+                                           MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET64(cqc, cqc, dbr_addr,      cq->wq_ctrl.db.dma);
+@@ -3584,7 +3587,8 @@ static int mlx5e_alloc_drop_cq(struct mlx5e_priv *priv,
+       param->wq.buf_numa_node = dev_to_node(mlx5_core_dma_dev(mdev));
+       param->wq.db_numa_node  = dev_to_node(mlx5_core_dma_dev(mdev));
+-      return mlx5e_alloc_cq_common(priv->mdev, priv->netdev, priv->wq, param, cq);
++      return mlx5e_alloc_cq_common(priv->mdev, priv->netdev, priv->wq,
++                                   mdev->priv.bfreg.up, param, cq);
+ }
+ int mlx5e_open_drop_rq(struct mlx5e_priv *priv,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
+index c4de6bf8d1b65..cb1319974f83f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
+@@ -475,7 +475,6 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size)
+       *conn->cq.mcq.arm_db    = 0;
+       conn->cq.mcq.vector     = 0;
+       conn->cq.mcq.comp       = mlx5_fpga_conn_cq_complete;
+-      conn->cq.mcq.uar        = fdev->conn_res.uar;
+       tasklet_setup(&conn->cq.tasklet, mlx5_fpga_conn_cq_tasklet);
+       mlx5_fpga_dbg(fdev, "Created CQ #0x%x\n", conn->cq.mcq.cqn);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c
+index 4fd4e8483382c..077a77fde670e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c
+@@ -1131,7 +1131,6 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev,
+       *cq->mcq.arm_db = cpu_to_be32(2 << 28);
+       cq->mcq.vector = 0;
+-      cq->mcq.uar = uar;
+       cq->mdev = mdev;
+       return cq;
+diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
+index 991526039ccbd..7ef2c7c7d803d 100644
+--- a/include/linux/mlx5/cq.h
++++ b/include/linux/mlx5/cq.h
+@@ -41,7 +41,6 @@ struct mlx5_core_cq {
+       int                     cqe_sz;
+       __be32                 *set_ci_db;
+       __be32                 *arm_db;
+-      struct mlx5_uars_page  *uar;
+       refcount_t              refcount;
+       struct completion       free;
+       unsigned                vector;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-phy-micrel-introduce-lanphy_modify_page_reg.patch b/queue-6.17/net-phy-micrel-introduce-lanphy_modify_page_reg.patch
new file mode 100644 (file)
index 0000000..0a6af3d
--- /dev/null
@@ -0,0 +1,414 @@
+From ff1c48b677374ea49d1ff97e1ad37cabf6c33f33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Aug 2025 09:51:19 +0200
+Subject: net: phy: micrel: Introduce lanphy_modify_page_reg
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit a0de636ed7a264a329c6a9c7d50727af02138536 ]
+
+As the name suggests this function modifies the register in an
+extended page. It has the same parameters as phy_modify_mmd.
+This function was introduce because there are many places in the
+code where the registers was read then the value was modified and
+written back. So replace all this code with this function to make
+it clear.
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://patch.msgid.link/20250818075121.1298170-3-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 96a9178a29a6 ("net: phy: micrel: lan8814 fix reset of the QSGMII interface")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 231 ++++++++++++++++++++-------------------
+ 1 file changed, 116 insertions(+), 115 deletions(-)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index 99f8374fd32a7..0efc5adbf789d 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -2840,6 +2840,27 @@ static int lanphy_write_page_reg(struct phy_device *phydev, int page, u16 addr,
+       return val;
+ }
++static int lanphy_modify_page_reg(struct phy_device *phydev, int page, u16 addr,
++                                u16 mask, u16 set)
++{
++      int ret;
++
++      phy_lock_mdio_bus(phydev);
++      __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
++      __phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
++      __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
++                  (page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
++      ret = __phy_modify_changed(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA,
++                                 mask, set);
++      phy_unlock_mdio_bus(phydev);
++
++      if (ret < 0)
++              phydev_err(phydev, "__phy_modify_changed() failed: %pe\n",
++                         ERR_PTR(ret));
++
++      return ret;
++}
++
+ static int lan8814_config_ts_intr(struct phy_device *phydev, bool enable)
+ {
+       u16 val = 0;
+@@ -2928,7 +2949,6 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts,
+       struct lan8814_ptp_rx_ts *rx_ts, *tmp;
+       int txcfg = 0, rxcfg = 0;
+       int pkt_ts_enable;
+-      int tx_mod;
+       ptp_priv->hwts_tx_type = config->tx_type;
+       ptp_priv->rx_filter = config->rx_filter;
+@@ -2975,13 +2995,14 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts,
+       lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_TIMESTAMP_EN, pkt_ts_enable);
+       lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_TIMESTAMP_EN, pkt_ts_enable);
+-      tx_mod = lanphy_read_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD);
+       if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ONESTEP_SYNC) {
+-              lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
+-                                    tx_mod | PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
++              lanphy_modify_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
++                                     PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_,
++                                     PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
+       } else if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ON) {
+-              lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
+-                                    tx_mod & ~PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
++              lanphy_modify_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
++                                     PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_,
++                                     0);
+       }
+       if (config->rx_filter != HWTSTAMP_FILTER_NONE)
+@@ -3384,73 +3405,66 @@ static void lan8814_ptp_set_reload(struct phy_device *phydev, int event,
+ static void lan8814_ptp_enable_event(struct phy_device *phydev, int event,
+                                    int pulse_width)
+ {
+-      u16 val;
+-
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG);
+-      /* Set the pulse width of the event */
+-      val &= ~(LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_MASK(event));
+-      /* Make sure that the target clock will be incremented each time when
++      /* Set the pulse width of the event,
++       * Make sure that the target clock will be incremented each time when
+        * local time reaches or pass it
++       * Set the polarity high
+        */
+-      val |= LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width);
+-      val &= ~(LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event));
+-      /* Set the polarity high */
+-      val |= LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG, val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG,
++                             LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_MASK(event) |
++                             LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width) |
++                             LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event) |
++                             LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event),
++                             LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width) |
++                             LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event));
+ }
+ static void lan8814_ptp_disable_event(struct phy_device *phydev, int event)
+ {
+-      u16 val;
+-
+       /* Set target to too far in the future, effectively disabling it */
+       lan8814_ptp_set_target(phydev, event, 0xFFFFFFFF, 0);
+       /* And then reload once it recheas the target */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG);
+-      val |= LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG, val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG,
++                             LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event),
++                             LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event));
+ }
+ static void lan8814_ptp_perout_off(struct phy_device *phydev, int pin)
+ {
+-      u16 val;
+-
+       /* Disable gpio alternate function,
+        * 1: select as gpio,
+        * 0: select alt func
+        */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin));
+-      val |= LAN8814_GPIO_EN_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++                             LAN8814_GPIO_EN_BIT(pin),
++                             LAN8814_GPIO_EN_BIT(pin));
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin));
+-      val &= ~LAN8814_GPIO_DIR_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++                             LAN8814_GPIO_DIR_BIT(pin),
++                             0);
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin));
+-      val &= ~LAN8814_GPIO_BUF_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin),
++                             LAN8814_GPIO_BUF_BIT(pin),
++                             0);
+ }
+ static void lan8814_ptp_perout_on(struct phy_device *phydev, int pin)
+ {
+-      int val;
+-
+       /* Set as gpio output */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin));
+-      val |= LAN8814_GPIO_DIR_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++                             LAN8814_GPIO_DIR_BIT(pin),
++                             LAN8814_GPIO_DIR_BIT(pin));
+       /* Enable gpio 0:for alternate function, 1:gpio */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin));
+-      val &= ~LAN8814_GPIO_EN_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++                             LAN8814_GPIO_EN_BIT(pin),
++                             0);
+       /* Set buffer type to push pull */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin));
+-      val |= LAN8814_GPIO_BUF_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin), val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin),
++                             LAN8814_GPIO_BUF_BIT(pin),
++                             LAN8814_GPIO_BUF_BIT(pin));
+ }
+ static int lan8814_ptp_perout(struct ptp_clock_info *ptpci,
+@@ -3565,61 +3579,59 @@ static int lan8814_ptp_perout(struct ptp_clock_info *ptpci,
+ static void lan8814_ptp_extts_on(struct phy_device *phydev, int pin, u32 flags)
+ {
+-      u16 tmp;
+-
+       /* Set as gpio input */
+-      tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin));
+-      tmp &= ~LAN8814_GPIO_DIR_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), tmp);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++                             LAN8814_GPIO_DIR_BIT(pin),
++                             0);
+       /* Map the pin to ltc pin 0 of the capture map registers */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO);
+-      tmp |= pin;
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO,
++                             pin,
++                             pin);
+       /* Enable capture on the edges of the ltc pin */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_EN);
+       if (flags & PTP_RISING_EDGE)
+-              tmp |= PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0);
++              lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++                                     PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0),
++                                     PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0));
+       if (flags & PTP_FALLING_EDGE)
+-              tmp |= PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0);
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_EN, tmp);
++              lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++                                     PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0),
++                                     PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0));
+       /* Enable interrupt top interrupt */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_COMMON_INT_ENA);
+-      tmp |= PTP_COMMON_INT_ENA_GPIO_CAP_EN;
+-      lanphy_write_page_reg(phydev, 4, PTP_COMMON_INT_ENA, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_COMMON_INT_ENA,
++                             PTP_COMMON_INT_ENA_GPIO_CAP_EN,
++                             PTP_COMMON_INT_ENA_GPIO_CAP_EN);
+ }
+ static void lan8814_ptp_extts_off(struct phy_device *phydev, int pin)
+ {
+-      u16 tmp;
+-
+       /* Set as gpio out */
+-      tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin));
+-      tmp |= LAN8814_GPIO_DIR_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), tmp);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++                             LAN8814_GPIO_DIR_BIT(pin),
++                             LAN8814_GPIO_DIR_BIT(pin));
+       /* Enable alternate, 0:for alternate function, 1:gpio */
+-      tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin));
+-      tmp &= ~LAN8814_GPIO_EN_BIT(pin);
+-      lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), tmp);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++                             LAN8814_GPIO_EN_BIT(pin),
++                             0);
+       /* Clear the mapping of pin to registers 0 of the capture registers */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO);
+-      tmp &= ~GENMASK(3, 0);
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO,
++                             GENMASK(3, 0),
++                             0);
+       /* Disable capture on both of the edges */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_EN);
+-      tmp &= ~PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin);
+-      tmp &= ~PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin);
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_EN, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++                             PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin) |
++                             PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin),
++                             0);
+       /* Disable interrupt top interrupt */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_COMMON_INT_ENA);
+-      tmp &= ~PTP_COMMON_INT_ENA_GPIO_CAP_EN;
+-      lanphy_write_page_reg(phydev, 4, PTP_COMMON_INT_ENA, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_COMMON_INT_ENA,
++                             PTP_COMMON_INT_ENA_GPIO_CAP_EN,
++                             0);
+ }
+ static int lan8814_ptp_extts(struct ptp_clock_info *ptpci,
+@@ -3859,9 +3871,9 @@ static int lan8814_gpio_process_cap(struct lan8814_shared_priv *shared)
+       /* This is 0 because whatever was the input pin it was mapped it to
+        * ltc gpio pin 0
+        */
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_SEL);
+-      tmp |= PTP_GPIO_SEL_GPIO_SEL(0);
+-      lanphy_write_page_reg(phydev, 4, PTP_GPIO_SEL, tmp);
++      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_SEL,
++                             PTP_GPIO_SEL_GPIO_SEL(0),
++                             PTP_GPIO_SEL_GPIO_SEL(0));
+       tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_STS);
+       if (!(tmp & PTP_GPIO_CAP_STS_PTP_GPIO_RE_STS(0)) &&
+@@ -3908,13 +3920,10 @@ static int lan8814_handle_gpio_interrupt(struct phy_device *phydev, u16 status)
+ static int lan8804_config_init(struct phy_device *phydev)
+ {
+-      int val;
+-
+       /* MDI-X setting for swap A,B transmit */
+-      val = lanphy_read_page_reg(phydev, 2, LAN8804_ALIGN_SWAP);
+-      val &= ~LAN8804_ALIGN_TX_A_B_SWAP_MASK;
+-      val |= LAN8804_ALIGN_TX_A_B_SWAP;
+-      lanphy_write_page_reg(phydev, 2, LAN8804_ALIGN_SWAP, val);
++      lanphy_modify_page_reg(phydev, 2, LAN8804_ALIGN_SWAP,
++                             LAN8804_ALIGN_TX_A_B_SWAP_MASK,
++                             LAN8804_ALIGN_TX_A_B_SWAP);
+       /* Make sure that the PHY will not stop generating the clock when the
+        * link partner goes down
+@@ -4056,7 +4065,6 @@ static void lan8814_ptp_init(struct phy_device *phydev)
+ {
+       struct kszphy_priv *priv = phydev->priv;
+       struct kszphy_ptp_priv *ptp_priv = &priv->ptp_priv;
+-      u32 temp;
+       if (!IS_ENABLED(CONFIG_PTP_1588_CLOCK) ||
+           !IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING))
+@@ -4064,13 +4072,13 @@ static void lan8814_ptp_init(struct phy_device *phydev)
+       lanphy_write_page_reg(phydev, 5, TSU_HARD_RESET, TSU_HARD_RESET_);
+-      temp = lanphy_read_page_reg(phydev, 5, PTP_TX_MOD);
+-      temp |= PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_;
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_MOD, temp);
++      lanphy_modify_page_reg(phydev, 5, PTP_TX_MOD,
++                             PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_,
++                             PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_);
+-      temp = lanphy_read_page_reg(phydev, 5, PTP_RX_MOD);
+-      temp |= PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_;
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_MOD, temp);
++      lanphy_modify_page_reg(phydev, 5, PTP_RX_MOD,
++                             PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_,
++                             PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_);
+       lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_CONFIG, 0);
+       lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_CONFIG, 0);
+@@ -4196,23 +4204,21 @@ static void lan8814_setup_led(struct phy_device *phydev, int val)
+ static int lan8814_config_init(struct phy_device *phydev)
+ {
+       struct kszphy_priv *lan8814 = phydev->priv;
+-      int val;
+       /* Reset the PHY */
+-      val = lanphy_read_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET);
+-      val |= LAN8814_QSGMII_SOFT_RESET_BIT;
+-      lanphy_write_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET, val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET,
++                             LAN8814_QSGMII_SOFT_RESET_BIT,
++                             LAN8814_QSGMII_SOFT_RESET_BIT);
+       /* Disable ANEG with QSGMII PCS Host side */
+-      val = lanphy_read_page_reg(phydev, 5, LAN8814_QSGMII_PCS1G_ANEG_CONFIG);
+-      val &= ~LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA;
+-      lanphy_write_page_reg(phydev, 5, LAN8814_QSGMII_PCS1G_ANEG_CONFIG, val);
++      lanphy_modify_page_reg(phydev, 4, LAN8814_QSGMII_PCS1G_ANEG_CONFIG,
++                             LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA,
++                             0);
+       /* MDI-X setting for swap A,B transmit */
+-      val = lanphy_read_page_reg(phydev, 2, LAN8814_ALIGN_SWAP);
+-      val &= ~LAN8814_ALIGN_TX_A_B_SWAP_MASK;
+-      val |= LAN8814_ALIGN_TX_A_B_SWAP;
+-      lanphy_write_page_reg(phydev, 2, LAN8814_ALIGN_SWAP, val);
++      lanphy_modify_page_reg(phydev, 2, LAN8814_ALIGN_SWAP,
++                             LAN8814_ALIGN_TX_A_B_SWAP_MASK,
++                             LAN8814_ALIGN_TX_A_B_SWAP);
+       if (lan8814->led_mode >= 0)
+               lan8814_setup_led(phydev, lan8814->led_mode);
+@@ -4243,29 +4249,24 @@ static int lan8814_release_coma_mode(struct phy_device *phydev)
+ static void lan8814_clear_2psp_bit(struct phy_device *phydev)
+ {
+-      u16 val;
+-
+       /* It was noticed that when traffic is passing through the PHY and the
+        * cable is removed then the LED was still one even though there is no
+        * link
+        */
+-      val = lanphy_read_page_reg(phydev, 2, LAN8814_EEE_STATE);
+-      val &= ~LAN8814_EEE_STATE_MASK2P5P;
+-      lanphy_write_page_reg(phydev, 2, LAN8814_EEE_STATE, val);
++      lanphy_modify_page_reg(phydev, 2, LAN8814_EEE_STATE,
++                             LAN8814_EEE_STATE_MASK2P5P,
++                             0);
+ }
+ static void lan8814_update_meas_time(struct phy_device *phydev)
+ {
+-      u16 val;
+-
+       /* By setting the measure time to a value of 0xb this will allow cables
+        * longer than 100m to be used. This configuration can be used
+        * regardless of the mode of operation of the PHY
+        */
+-      val = lanphy_read_page_reg(phydev, 1, LAN8814_PD_CONTROLS);
+-      val &= ~LAN8814_PD_CONTROLS_PD_MEAS_TIME_MASK;
+-      val |= LAN8814_PD_CONTROLS_PD_MEAS_TIME_VAL;
+-      lanphy_write_page_reg(phydev, 1, LAN8814_PD_CONTROLS, val);
++      lanphy_modify_page_reg(phydev, 1, LAN8814_PD_CONTROLS,
++                             LAN8814_PD_CONTROLS_PD_MEAS_TIME_MASK,
++                             LAN8814_PD_CONTROLS_PD_MEAS_TIME_VAL);
+ }
+ static int lan8814_probe(struct phy_device *phydev)
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-phy-micrel-lan8814-fix-reset-of-the-qsgmii-inter.patch b/queue-6.17/net-phy-micrel-lan8814-fix-reset-of-the-qsgmii-inter.patch
new file mode 100644 (file)
index 0000000..361c050
--- /dev/null
@@ -0,0 +1,59 @@
+From 536d742e7db7d446504340049fdcccd18b60dbf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:06:37 +0100
+Subject: net: phy: micrel: lan8814 fix reset of the QSGMII interface
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 96a9178a29a6b84bb632ebeb4e84cf61191c73d5 ]
+
+The lan8814 is a quad-phy and it is using QSGMII towards the MAC.
+The problem is that everytime when one of the ports is configured then
+the PCS is reseted for all the PHYs. Meaning that the other ports can
+loose traffic until the link is establish again.
+To fix this, do the reset one time for the entire PHY package.
+
+Fixes: ece19502834d ("net: phy: micrel: 1588 support for LAN8814 phy")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Divya Koppera <Divya.Koppera@microchip.com >
+Link: https://patch.msgid.link/20251106090637.2030625-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index 107e5c4c7da3b..39d2cd7cf4382 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -4327,12 +4327,6 @@ static int lan8814_config_init(struct phy_device *phydev)
+ {
+       struct kszphy_priv *lan8814 = phydev->priv;
+-      /* Reset the PHY */
+-      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+-                             LAN8814_QSGMII_SOFT_RESET,
+-                             LAN8814_QSGMII_SOFT_RESET_BIT,
+-                             LAN8814_QSGMII_SOFT_RESET_BIT);
+-
+       /* Disable ANEG with QSGMII PCS Host side */
+       lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                              LAN8814_QSGMII_PCS1G_ANEG_CONFIG,
+@@ -4418,6 +4412,12 @@ static int lan8814_probe(struct phy_device *phydev)
+                             addr, sizeof(struct lan8814_shared_priv));
+       if (phy_package_init_once(phydev)) {
++              /* Reset the PHY */
++              lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                     LAN8814_QSGMII_SOFT_RESET,
++                                     LAN8814_QSGMII_SOFT_RESET_BIT,
++                                     LAN8814_QSGMII_SOFT_RESET_BIT);
++
+               err = lan8814_release_coma_mode(phydev);
+               if (err)
+                       return err;
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-phy-micrel-replace-hardcoded-pages-with-defines.patch b/queue-6.17/net-phy-micrel-replace-hardcoded-pages-with-defines.patch
new file mode 100644 (file)
index 0000000..89dd46f
--- /dev/null
@@ -0,0 +1,741 @@
+From f862a8bc07a49e8c15e9eb360be0200d1d073c54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Aug 2025 09:51:20 +0200
+Subject: net: phy: micrel: Replace hardcoded pages with defines
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit d471793a9b67bbe3d7198ff695004190fd7b6bc7 ]
+
+The functions lan_*_page_reg gets as a second parameter the page
+where the register is. In all the functions the page was hardcoded.
+Replace the hardcoded values with defines to make it more clear
+what are those parameters.
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://patch.msgid.link/20250818075121.1298170-4-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 96a9178a29a6 ("net: phy: micrel: lan8814 fix reset of the QSGMII interface")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 342 ++++++++++++++++++++++++++-------------
+ 1 file changed, 233 insertions(+), 109 deletions(-)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index 0efc5adbf789d..107e5c4c7da3b 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -2790,6 +2790,52 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev,
+       return ret;
+ }
++/**
++ * LAN8814_PAGE_AFE_PMA - Selects Extended Page 1.
++ *
++ * This page appears to control the Analog Front-End (AFE) and Physical
++ * Medium Attachment (PMA) layers. It is used to access registers like
++ * LAN8814_PD_CONTROLS and LAN8814_LINK_QUALITY.
++ */
++#define LAN8814_PAGE_AFE_PMA 1
++
++/**
++ * LAN8814_PAGE_PCS_DIGITAL - Selects Extended Page 2.
++ *
++ * This page seems dedicated to the Physical Coding Sublayer (PCS) and other
++ * digital logic. It is used for MDI-X alignment (LAN8814_ALIGN_SWAP) and EEE
++ * state (LAN8814_EEE_STATE) in the LAN8814, and is repurposed for statistics
++ * and self-test counters in the LAN8842.
++ */
++#define LAN8814_PAGE_PCS_DIGITAL 2
++
++/**
++ * LAN8814_PAGE_COMMON_REGS - Selects Extended Page 4.
++ *
++ * This page contains device-common registers that affect the entire chip.
++ * It includes controls for chip-level resets, strap status, GPIO,
++ * QSGMII, the shared 1588 PTP block, and the PVT monitor.
++ */
++#define LAN8814_PAGE_COMMON_REGS 4
++
++/**
++ * LAN8814_PAGE_PORT_REGS - Selects Extended Page 5.
++ *
++ * This page contains port-specific registers that must be accessed
++ * on a per-port basis. It includes controls for port LEDs, QSGMII PCS,
++ * rate adaptation FIFOs, and the per-port 1588 TSU block.
++ */
++#define LAN8814_PAGE_PORT_REGS 5
++
++/**
++ * LAN8814_PAGE_SYSTEM_CTRL - Selects Extended Page 31.
++ *
++ * This page appears to hold fundamental system or global controls. In the
++ * driver, it is used by the related LAN8804 to access the
++ * LAN8814_CLOCK_MANAGEMENT register.
++ */
++#define LAN8814_PAGE_SYSTEM_CTRL 31
++
+ #define LAN_EXT_PAGE_ACCESS_CONTROL                   0x16
+ #define LAN_EXT_PAGE_ACCESS_ADDRESS_DATA              0x17
+ #define LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC              0x4000
+@@ -2871,35 +2917,46 @@ static int lan8814_config_ts_intr(struct phy_device *phydev, bool enable)
+                     PTP_TSU_INT_EN_PTP_RX_TS_EN_ |
+                     PTP_TSU_INT_EN_PTP_RX_TS_OVRFL_EN_;
+-      return lanphy_write_page_reg(phydev, 5, PTP_TSU_INT_EN, val);
++      return lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                   PTP_TSU_INT_EN, val);
+ }
+ static void lan8814_ptp_rx_ts_get(struct phy_device *phydev,
+                                 u32 *seconds, u32 *nano_seconds, u16 *seq_id)
+ {
+-      *seconds = lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_SEC_HI);
++      *seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                      PTP_RX_INGRESS_SEC_HI);
+       *seconds = (*seconds << 16) |
+-                 lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_SEC_LO);
++                 lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                      PTP_RX_INGRESS_SEC_LO);
+-      *nano_seconds = lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_NS_HI);
++      *nano_seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                           PTP_RX_INGRESS_NS_HI);
+       *nano_seconds = ((*nano_seconds & 0x3fff) << 16) |
+-                      lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_NS_LO);
++                      lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                           PTP_RX_INGRESS_NS_LO);
+-      *seq_id = lanphy_read_page_reg(phydev, 5, PTP_RX_MSG_HEADER2);
++      *seq_id = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                     PTP_RX_MSG_HEADER2);
+ }
+ static void lan8814_ptp_tx_ts_get(struct phy_device *phydev,
+                                 u32 *seconds, u32 *nano_seconds, u16 *seq_id)
+ {
+-      *seconds = lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_SEC_HI);
++      *seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                      PTP_TX_EGRESS_SEC_HI);
+       *seconds = *seconds << 16 |
+-                 lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_SEC_LO);
++                 lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                      PTP_TX_EGRESS_SEC_LO);
+-      *nano_seconds = lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_NS_HI);
++      *nano_seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                           PTP_TX_EGRESS_NS_HI);
+       *nano_seconds = ((*nano_seconds & 0x3fff) << 16) |
+-                      lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_NS_LO);
++                      lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                           PTP_TX_EGRESS_NS_LO);
+-      *seq_id = lanphy_read_page_reg(phydev, 5, PTP_TX_MSG_HEADER2);
++      *seq_id = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                     PTP_TX_MSG_HEADER2);
+ }
+ static int lan8814_ts_info(struct mii_timestamper *mii_ts, struct kernel_ethtool_ts_info *info)
+@@ -2933,11 +2990,11 @@ static void lan8814_flush_fifo(struct phy_device *phydev, bool egress)
+       int i;
+       for (i = 0; i < FIFO_SIZE; ++i)
+-              lanphy_read_page_reg(phydev, 5,
++              lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
+                                    egress ? PTP_TX_MSG_HEADER2 : PTP_RX_MSG_HEADER2);
+       /* Read to clear overflow status bit */
+-      lanphy_read_page_reg(phydev, 5, PTP_TSU_INT_STS);
++      lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TSU_INT_STS);
+ }
+ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts,
+@@ -2987,20 +3044,26 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts,
+               rxcfg |= PTP_RX_PARSE_CONFIG_IPV4_EN_ | PTP_RX_PARSE_CONFIG_IPV6_EN_;
+               txcfg |= PTP_TX_PARSE_CONFIG_IPV4_EN_ | PTP_TX_PARSE_CONFIG_IPV6_EN_;
+       }
+-      lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_PARSE_CONFIG, rxcfg);
+-      lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_PARSE_CONFIG, txcfg);
++      lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_PARSE_CONFIG, rxcfg);
++      lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_PARSE_CONFIG, txcfg);
+       pkt_ts_enable = PTP_TIMESTAMP_EN_SYNC_ | PTP_TIMESTAMP_EN_DREQ_ |
+                       PTP_TIMESTAMP_EN_PDREQ_ | PTP_TIMESTAMP_EN_PDRES_;
+-      lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_TIMESTAMP_EN, pkt_ts_enable);
+-      lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_TIMESTAMP_EN, pkt_ts_enable);
++      lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_TIMESTAMP_EN, pkt_ts_enable);
++      lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_TIMESTAMP_EN, pkt_ts_enable);
+       if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ONESTEP_SYNC) {
+-              lanphy_modify_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
++              lanphy_modify_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                                     PTP_TX_MOD,
+                                      PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_,
+                                      PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
+       } else if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ON) {
+-              lanphy_modify_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
++              lanphy_modify_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS,
++                                     PTP_TX_MOD,
+                                      PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_,
+                                      0);
+       }
+@@ -3124,29 +3187,41 @@ static bool lan8814_rxtstamp(struct mii_timestamper *mii_ts, struct sk_buff *skb
+ static void lan8814_ptp_clock_set(struct phy_device *phydev,
+                                 time64_t sec, u32 nsec)
+ {
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_LO, lower_16_bits(sec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_MID, upper_16_bits(sec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_HI, upper_32_bits(sec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_NS_LO, lower_16_bits(nsec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_NS_HI, upper_16_bits(nsec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_SEC_LO, lower_16_bits(sec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_SEC_MID, upper_16_bits(sec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_SEC_HI, upper_32_bits(sec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_NS_LO, lower_16_bits(nsec));
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            PTP_CLOCK_SET_NS_HI, upper_16_bits(nsec));
+-      lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_CLOCK_LOAD_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL,
++                            PTP_CMD_CTL_PTP_CLOCK_LOAD_);
+ }
+ static void lan8814_ptp_clock_get(struct phy_device *phydev,
+                                 time64_t *sec, u32 *nsec)
+ {
+-      lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_CLOCK_READ_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL,
++                            PTP_CMD_CTL_PTP_CLOCK_READ_);
+-      *sec = lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_HI);
++      *sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                  PTP_CLOCK_READ_SEC_HI);
+       *sec <<= 16;
+-      *sec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_MID);
++      *sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                   PTP_CLOCK_READ_SEC_MID);
+       *sec <<= 16;
+-      *sec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_LO);
++      *sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                   PTP_CLOCK_READ_SEC_LO);
+-      *nsec = lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_NS_HI);
++      *nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                   PTP_CLOCK_READ_NS_HI);
+       *nsec <<= 16;
+-      *nsec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_NS_LO);
++      *nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                    PTP_CLOCK_READ_NS_LO);
+ }
+ static int lan8814_ptpci_gettime64(struct ptp_clock_info *ptpci,
+@@ -3185,14 +3260,18 @@ static void lan8814_ptp_set_target(struct phy_device *phydev, int event,
+                                  s64 start_sec, u32 start_nsec)
+ {
+       /* Set the start time */
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_SEC_LO(event),
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LAN8814_PTP_CLOCK_TARGET_SEC_LO(event),
+                             lower_16_bits(start_sec));
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_SEC_HI(event),
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LAN8814_PTP_CLOCK_TARGET_SEC_HI(event),
+                             upper_16_bits(start_sec));
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_NS_LO(event),
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LAN8814_PTP_CLOCK_TARGET_NS_LO(event),
+                             lower_16_bits(start_nsec));
+-      lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_NS_HI(event),
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LAN8814_PTP_CLOCK_TARGET_NS_HI(event),
+                             upper_16_bits(start_nsec) & 0x3fff);
+ }
+@@ -3290,9 +3369,11 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev,
+                       adjustment_value_lo = adjustment_value & 0xffff;
+                       adjustment_value_hi = (adjustment_value >> 16) & 0x3fff;
+-                      lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO,
++                      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                            PTP_LTC_STEP_ADJ_LO,
+                                             adjustment_value_lo);
+-                      lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI,
++                      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                            PTP_LTC_STEP_ADJ_HI,
+                                             PTP_LTC_STEP_ADJ_DIR_ |
+                                             adjustment_value_hi);
+                       seconds -= ((s32)adjustment_value);
+@@ -3310,9 +3391,11 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev,
+                       adjustment_value_lo = adjustment_value & 0xffff;
+                       adjustment_value_hi = (adjustment_value >> 16) & 0x3fff;
+-                      lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO,
++                      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                            PTP_LTC_STEP_ADJ_LO,
+                                             adjustment_value_lo);
+-                      lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI,
++                      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                            PTP_LTC_STEP_ADJ_HI,
+                                             adjustment_value_hi);
+                       seconds += ((s32)adjustment_value);
+@@ -3320,8 +3403,8 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev,
+                       set_seconds += adjustment_value;
+                       lan8814_ptp_update_target(phydev, set_seconds);
+               }
+-              lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL,
+-                                    PTP_CMD_CTL_PTP_LTC_STEP_SEC_);
++              lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                    PTP_CMD_CTL, PTP_CMD_CTL_PTP_LTC_STEP_SEC_);
+       }
+       if (nano_seconds) {
+               u16 nano_seconds_lo;
+@@ -3330,12 +3413,14 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev,
+               nano_seconds_lo = nano_seconds & 0xffff;
+               nano_seconds_hi = (nano_seconds >> 16) & 0x3fff;
+-              lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO,
++              lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                    PTP_LTC_STEP_ADJ_LO,
+                                     nano_seconds_lo);
+-              lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI,
++              lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                    PTP_LTC_STEP_ADJ_HI,
+                                     PTP_LTC_STEP_ADJ_DIR_ |
+                                     nano_seconds_hi);
+-              lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL,
++              lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL,
+                                     PTP_CMD_CTL_PTP_LTC_STEP_NSEC_);
+       }
+ }
+@@ -3377,8 +3462,10 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm)
+               kszphy_rate_adj_hi |= PTP_CLOCK_RATE_ADJ_DIR_;
+       mutex_lock(&shared->shared_lock);
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_RATE_ADJ_HI, kszphy_rate_adj_hi);
+-      lanphy_write_page_reg(phydev, 4, PTP_CLOCK_RATE_ADJ_LO, kszphy_rate_adj_lo);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CLOCK_RATE_ADJ_HI,
++                            kszphy_rate_adj_hi);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CLOCK_RATE_ADJ_LO,
++                            kszphy_rate_adj_lo);
+       mutex_unlock(&shared->shared_lock);
+       return 0;
+@@ -3387,17 +3474,17 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm)
+ static void lan8814_ptp_set_reload(struct phy_device *phydev, int event,
+                                  s64 period_sec, u32 period_nsec)
+ {
+-      lanphy_write_page_reg(phydev, 4,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                             LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_LO(event),
+                             lower_16_bits(period_sec));
+-      lanphy_write_page_reg(phydev, 4,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                             LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_HI(event),
+                             upper_16_bits(period_sec));
+-      lanphy_write_page_reg(phydev, 4,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                             LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_LO(event),
+                             lower_16_bits(period_nsec));
+-      lanphy_write_page_reg(phydev, 4,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
+                             LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_HI(event),
+                             upper_16_bits(period_nsec) & 0x3fff);
+ }
+@@ -3410,7 +3497,7 @@ static void lan8814_ptp_enable_event(struct phy_device *phydev, int event,
+        * local time reaches or pass it
+        * Set the polarity high
+        */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_GENERAL_CONFIG,
+                              LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_MASK(event) |
+                              LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width) |
+                              LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event) |
+@@ -3425,7 +3512,7 @@ static void lan8814_ptp_disable_event(struct phy_device *phydev, int event)
+       lan8814_ptp_set_target(phydev, event, 0xFFFFFFFF, 0);
+       /* And then reload once it recheas the target */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_GENERAL_CONFIG,
+                              LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event),
+                              LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event));
+ }
+@@ -3436,15 +3523,18 @@ static void lan8814_ptp_perout_off(struct phy_device *phydev, int pin)
+        * 1: select as gpio,
+        * 0: select alt func
+        */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_EN_ADDR(pin),
+                              LAN8814_GPIO_EN_BIT(pin),
+                              LAN8814_GPIO_EN_BIT(pin));
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_DIR_ADDR(pin),
+                              LAN8814_GPIO_DIR_BIT(pin),
+                              0);
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_BUF_ADDR(pin),
+                              LAN8814_GPIO_BUF_BIT(pin),
+                              0);
+ }
+@@ -3452,17 +3542,20 @@ static void lan8814_ptp_perout_off(struct phy_device *phydev, int pin)
+ static void lan8814_ptp_perout_on(struct phy_device *phydev, int pin)
+ {
+       /* Set as gpio output */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_DIR_ADDR(pin),
+                              LAN8814_GPIO_DIR_BIT(pin),
+                              LAN8814_GPIO_DIR_BIT(pin));
+       /* Enable gpio 0:for alternate function, 1:gpio */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_EN_ADDR(pin),
+                              LAN8814_GPIO_EN_BIT(pin),
+                              0);
+       /* Set buffer type to push pull */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_BUF_ADDR(pin),
+                              LAN8814_GPIO_BUF_BIT(pin),
+                              LAN8814_GPIO_BUF_BIT(pin));
+ }
+@@ -3580,27 +3673,29 @@ static int lan8814_ptp_perout(struct ptp_clock_info *ptpci,
+ static void lan8814_ptp_extts_on(struct phy_device *phydev, int pin, u32 flags)
+ {
+       /* Set as gpio input */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_DIR_ADDR(pin),
+                              LAN8814_GPIO_DIR_BIT(pin),
+                              0);
+       /* Map the pin to ltc pin 0 of the capture map registers */
+-      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO,
+-                             pin,
+-                             pin);
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             PTP_GPIO_CAP_MAP_LO, pin, pin);
+       /* Enable capture on the edges of the ltc pin */
+       if (flags & PTP_RISING_EDGE)
+-              lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++              lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                     PTP_GPIO_CAP_EN,
+                                      PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0),
+                                      PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0));
+       if (flags & PTP_FALLING_EDGE)
+-              lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++              lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                     PTP_GPIO_CAP_EN,
+                                      PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0),
+                                      PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0));
+       /* Enable interrupt top interrupt */
+-      lanphy_modify_page_reg(phydev, 4, PTP_COMMON_INT_ENA,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_COMMON_INT_ENA,
+                              PTP_COMMON_INT_ENA_GPIO_CAP_EN,
+                              PTP_COMMON_INT_ENA_GPIO_CAP_EN);
+ }
+@@ -3608,28 +3703,31 @@ static void lan8814_ptp_extts_on(struct phy_device *phydev, int pin, u32 flags)
+ static void lan8814_ptp_extts_off(struct phy_device *phydev, int pin)
+ {
+       /* Set as gpio out */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_DIR_ADDR(pin),
+                              LAN8814_GPIO_DIR_BIT(pin),
+                              LAN8814_GPIO_DIR_BIT(pin));
+       /* Enable alternate, 0:for alternate function, 1:gpio */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin),
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_GPIO_EN_ADDR(pin),
+                              LAN8814_GPIO_EN_BIT(pin),
+                              0);
+       /* Clear the mapping of pin to registers 0 of the capture registers */
+-      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             PTP_GPIO_CAP_MAP_LO,
+                              GENMASK(3, 0),
+                              0);
+       /* Disable capture on both of the edges */
+-      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_CAP_EN,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_GPIO_CAP_EN,
+                              PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin) |
+                              PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin),
+                              0);
+       /* Disable interrupt top interrupt */
+-      lanphy_modify_page_reg(phydev, 4, PTP_COMMON_INT_ENA,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_COMMON_INT_ENA,
+                              PTP_COMMON_INT_ENA_GPIO_CAP_EN,
+                              0);
+ }
+@@ -3761,7 +3859,8 @@ static void lan8814_get_tx_ts(struct kszphy_ptp_priv *ptp_priv)
+               /* If other timestamps are available in the FIFO,
+                * process them.
+                */
+-              reg = lanphy_read_page_reg(phydev, 5, PTP_CAP_INFO);
++              reg = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                         PTP_CAP_INFO);
+       } while (PTP_CAP_INFO_TX_TS_CNT_GET_(reg) > 0);
+ }
+@@ -3834,7 +3933,8 @@ static void lan8814_get_rx_ts(struct kszphy_ptp_priv *ptp_priv)
+               /* If other timestamps are available in the FIFO,
+                * process them.
+                */
+-              reg = lanphy_read_page_reg(phydev, 5, PTP_CAP_INFO);
++              reg = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                         PTP_CAP_INFO);
+       } while (PTP_CAP_INFO_RX_TS_CNT_GET_(reg) > 0);
+ }
+@@ -3871,31 +3971,40 @@ static int lan8814_gpio_process_cap(struct lan8814_shared_priv *shared)
+       /* This is 0 because whatever was the input pin it was mapped it to
+        * ltc gpio pin 0
+        */
+-      lanphy_modify_page_reg(phydev, 4, PTP_GPIO_SEL,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_GPIO_SEL,
+                              PTP_GPIO_SEL_GPIO_SEL(0),
+                              PTP_GPIO_SEL_GPIO_SEL(0));
+-      tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_STS);
++      tmp = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                 PTP_GPIO_CAP_STS);
+       if (!(tmp & PTP_GPIO_CAP_STS_PTP_GPIO_RE_STS(0)) &&
+           !(tmp & PTP_GPIO_CAP_STS_PTP_GPIO_FE_STS(0)))
+               return -1;
+       if (tmp & BIT(0)) {
+-              sec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_SEC_HI_CAP);
++              sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                         PTP_GPIO_RE_LTC_SEC_HI_CAP);
+               sec <<= 16;
+-              sec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_SEC_LO_CAP);
++              sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                          PTP_GPIO_RE_LTC_SEC_LO_CAP);
+-              nsec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_HI_CAP) & 0x3fff;
++              nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                          PTP_GPIO_RE_LTC_NS_HI_CAP) & 0x3fff;
+               nsec <<= 16;
+-              nsec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_LO_CAP);
++              nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                           PTP_GPIO_RE_LTC_NS_LO_CAP);
+       } else {
+-              sec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_SEC_HI_CAP);
++              sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                         PTP_GPIO_FE_LTC_SEC_HI_CAP);
+               sec <<= 16;
+-              sec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_SEC_LO_CAP);
++              sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                          PTP_GPIO_FE_LTC_SEC_LO_CAP);
+-              nsec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_NS_HI_CAP) & 0x3fff;
++              nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                          PTP_GPIO_FE_LTC_NS_HI_CAP) & 0x3fff;
+               nsec <<= 16;
+-              nsec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_LO_CAP);
++              nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                                           PTP_GPIO_RE_LTC_NS_LO_CAP);
+       }
+       ptp_event.index = 0;
+@@ -3921,15 +4030,16 @@ static int lan8814_handle_gpio_interrupt(struct phy_device *phydev, u16 status)
+ static int lan8804_config_init(struct phy_device *phydev)
+ {
+       /* MDI-X setting for swap A,B transmit */
+-      lanphy_modify_page_reg(phydev, 2, LAN8804_ALIGN_SWAP,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8804_ALIGN_SWAP,
+                              LAN8804_ALIGN_TX_A_B_SWAP_MASK,
+                              LAN8804_ALIGN_TX_A_B_SWAP);
+       /* Make sure that the PHY will not stop generating the clock when the
+        * link partner goes down
+        */
+-      lanphy_write_page_reg(phydev, 31, LAN8814_CLOCK_MANAGEMENT, 0x27e);
+-      lanphy_read_page_reg(phydev, 1, LAN8814_LINK_QUALITY);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_SYSTEM_CTRL,
++                            LAN8814_CLOCK_MANAGEMENT, 0x27e);
++      lanphy_read_page_reg(phydev, LAN8814_PAGE_AFE_PMA, LAN8814_LINK_QUALITY);
+       return 0;
+ }
+@@ -4011,7 +4121,8 @@ static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev)
+       }
+       while (true) {
+-              irq_status = lanphy_read_page_reg(phydev, 5, PTP_TSU_INT_STS);
++              irq_status = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                                PTP_TSU_INT_STS);
+               if (!irq_status)
+                       break;
+@@ -4039,7 +4150,7 @@ static int lan8814_config_intr(struct phy_device *phydev)
+ {
+       int err;
+-      lanphy_write_page_reg(phydev, 4, LAN8814_INTR_CTRL_REG,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_INTR_CTRL_REG,
+                             LAN8814_INTR_CTRL_REG_POLARITY |
+                             LAN8814_INTR_CTRL_REG_INTR_ENABLE);
+@@ -4070,29 +4181,36 @@ static void lan8814_ptp_init(struct phy_device *phydev)
+           !IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING))
+               return;
+-      lanphy_write_page_reg(phydev, 5, TSU_HARD_RESET, TSU_HARD_RESET_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            TSU_HARD_RESET, TSU_HARD_RESET_);
+-      lanphy_modify_page_reg(phydev, 5, PTP_TX_MOD,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TX_MOD,
+                              PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_,
+                              PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_);
+-      lanphy_modify_page_reg(phydev, 5, PTP_RX_MOD,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_RX_MOD,
+                              PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_,
+                              PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_);
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_CONFIG, 0);
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_CONFIG, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_PARSE_CONFIG, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_PARSE_CONFIG, 0);
+       /* Removing default registers configs related to L2 and IP */
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_L2_ADDR_EN, 0);
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_L2_ADDR_EN, 0);
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_IP_ADDR_EN, 0);
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_IP_ADDR_EN, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_PARSE_L2_ADDR_EN, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_PARSE_L2_ADDR_EN, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_TX_PARSE_IP_ADDR_EN, 0);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            PTP_RX_PARSE_IP_ADDR_EN, 0);
+       /* Disable checking for minorVersionPTP field */
+-      lanphy_write_page_reg(phydev, 5, PTP_RX_VERSION,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_RX_VERSION,
+                             PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0));
+-      lanphy_write_page_reg(phydev, 5, PTP_TX_VERSION,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TX_VERSION,
+                             PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0));
+       skb_queue_head_init(&ptp_priv->tx_queue);
+@@ -4177,12 +4295,14 @@ static int lan8814_ptp_probe_once(struct phy_device *phydev)
+       /* The EP.4 is shared between all the PHYs in the package and also it
+        * can be accessed by any of the PHYs
+        */
+-      lanphy_write_page_reg(phydev, 4, LTC_HARD_RESET, LTC_HARD_RESET_);
+-      lanphy_write_page_reg(phydev, 4, PTP_OPERATING_MODE,
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                            LTC_HARD_RESET, LTC_HARD_RESET_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_OPERATING_MODE,
+                             PTP_OPERATING_MODE_STANDALONE_);
+       /* Enable ptp to run LTC clock for ptp and gpio 1PPS operation */
+-      lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_ENABLE_);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL,
++                            PTP_CMD_CTL_PTP_ENABLE_);
+       return 0;
+ }
+@@ -4191,14 +4311,16 @@ static void lan8814_setup_led(struct phy_device *phydev, int val)
+ {
+       int temp;
+-      temp = lanphy_read_page_reg(phydev, 5, LAN8814_LED_CTRL_1);
++      temp = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                                  LAN8814_LED_CTRL_1);
+       if (val)
+               temp |= LAN8814_LED_CTRL_1_KSZ9031_LED_MODE_;
+       else
+               temp &= ~LAN8814_LED_CTRL_1_KSZ9031_LED_MODE_;
+-      lanphy_write_page_reg(phydev, 5, LAN8814_LED_CTRL_1, temp);
++      lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS,
++                            LAN8814_LED_CTRL_1, temp);
+ }
+ static int lan8814_config_init(struct phy_device *phydev)
+@@ -4206,17 +4328,19 @@ static int lan8814_config_init(struct phy_device *phydev)
+       struct kszphy_priv *lan8814 = phydev->priv;
+       /* Reset the PHY */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_QSGMII_SOFT_RESET,
+                              LAN8814_QSGMII_SOFT_RESET_BIT,
+                              LAN8814_QSGMII_SOFT_RESET_BIT);
+       /* Disable ANEG with QSGMII PCS Host side */
+-      lanphy_modify_page_reg(phydev, 4, LAN8814_QSGMII_PCS1G_ANEG_CONFIG,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
++                             LAN8814_QSGMII_PCS1G_ANEG_CONFIG,
+                              LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA,
+                              0);
+       /* MDI-X setting for swap A,B transmit */
+-      lanphy_modify_page_reg(phydev, 2, LAN8814_ALIGN_SWAP,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8814_ALIGN_SWAP,
+                              LAN8814_ALIGN_TX_A_B_SWAP_MASK,
+                              LAN8814_ALIGN_TX_A_B_SWAP);
+@@ -4253,7 +4377,7 @@ static void lan8814_clear_2psp_bit(struct phy_device *phydev)
+        * cable is removed then the LED was still one even though there is no
+        * link
+        */
+-      lanphy_modify_page_reg(phydev, 2, LAN8814_EEE_STATE,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8814_EEE_STATE,
+                              LAN8814_EEE_STATE_MASK2P5P,
+                              0);
+ }
+@@ -4264,7 +4388,7 @@ static void lan8814_update_meas_time(struct phy_device *phydev)
+        * longer than 100m to be used. This configuration can be used
+        * regardless of the mode of operation of the PHY
+        */
+-      lanphy_modify_page_reg(phydev, 1, LAN8814_PD_CONTROLS,
++      lanphy_modify_page_reg(phydev, LAN8814_PAGE_AFE_PMA, LAN8814_PD_CONTROLS,
+                              LAN8814_PD_CONTROLS_PD_MEAS_TIME_MASK,
+                              LAN8814_PD_CONTROLS_PD_MEAS_TIME_VAL);
+ }
+@@ -4289,7 +4413,7 @@ static int lan8814_probe(struct phy_device *phydev)
+       /* Strap-in value for PHY address, below register read gives starting
+        * phy address value
+        */
+-      addr = lanphy_read_page_reg(phydev, 4, 0) & 0x1F;
++      addr = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, 0) & 0x1F;
+       devm_phy_package_join(&phydev->mdio.dev, phydev,
+                             addr, sizeof(struct lan8814_shared_priv));
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch b/queue-6.17/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
new file mode 100644 (file)
index 0000000..bba9e92
--- /dev/null
@@ -0,0 +1,59 @@
+From e13b7be2646cd24a2b011fd17fd7b6b5c73c54de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:35 +0530
+Subject: net: sched: act_connmark: initialize struct tc_ife to fix kernel leak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit 62b656e43eaeae445a39cd8021a4f47065af4389 ]
+
+In tcf_connmark_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: 22a5dc0e5e3e ("net: sched: Introduce connmark action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-2-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_connmark.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 3e89927d71164..26ba8c2d20abf 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -195,13 +195,15 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+       const struct tcf_connmark_parms *parms;
+-      struct tc_connmark opt = {
+-              .index   = ci->tcf_index,
+-              .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+-      };
++      struct tc_connmark opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index   = ci->tcf_index;
++      opt.refcnt  = refcount_read(&ci->tcf_refcnt) - ref;
++      opt.bindcnt = atomic_read(&ci->tcf_bindcnt) - bind;
++
+       rcu_read_lock();
+       parms = rcu_dereference(ci->parms);
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch b/queue-6.17/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
new file mode 100644 (file)
index 0000000..a3b2987
--- /dev/null
@@ -0,0 +1,70 @@
+From 7b38a77b36ef67c02aab445fa9772107d263b7d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:36 +0530
+Subject: net: sched: act_ife: initialize struct tc_ife to fix KMSAN
+ kernel-infoleak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit ce50039be49eea9b4cd8873ca6eccded1b4a130a ]
+
+Fix a KMSAN kernel-infoleak detected  by the syzbot .
+
+[net?] KMSAN: kernel-infoleak in __skb_datagram_iter
+
+In tcf_ife_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+This change silences the KMSAN report and prevents potential information
+leaks from the kernel memory.
+
+This fix has been tested and validated by syzbot. This patch closes the
+bug reported at the following syzkaller link and ensures no infoleak.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: ef6980b6becb ("introduce IFE action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-3-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ife.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index 107c6d83dc5c4..7c6975632fc2e 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -644,13 +644,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_ife_info *ife = to_ife(a);
+       struct tcf_ife_params *p;
+-      struct tc_ife opt = {
+-              .index = ife->tcf_index,
+-              .refcnt = refcount_read(&ife->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
+-      };
++      struct tc_ife opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index = ife->tcf_index,
++      opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref,
++      opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
++
+       spin_lock_bh(&ife->tcf_lock);
+       opt.action = ife->tcf_action;
+       p = rcu_dereference_protected(ife->params,
+-- 
+2.51.0
+
diff --git a/queue-6.17/net-smc-fix-mismatch-between-clc-header-and-proposal.patch b/queue-6.17/net-smc-fix-mismatch-between-clc-header-and-proposal.patch
new file mode 100644 (file)
index 0000000..f44630a
--- /dev/null
@@ -0,0 +1,55 @@
+From 53e1c1027042a62c658b41504a433e068e7791c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 10:40:29 +0800
+Subject: net/smc: fix mismatch between CLC header and proposal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit ec33f2e5a2d0dbbfd71435209aee812fdc9369b8 ]
+
+The current CLC proposal message construction uses a mix of
+`ini->smc_type_v1/v2` and `pclc_base->hdr.typev1/v2` to decide whether
+to include optional extensions (IPv6 prefix extension for v1, and v2
+extension). This leads to a critical inconsistency: when
+`smc_clc_prfx_set()` fails - for example, in IPv6-only environments with
+only link-local addresses, or when the local IP address and the outgoing
+interface’s network address are not in the same subnet.
+
+As a result, the proposal message is assembled using the stale
+`ini->smc_type_v1` value—causing the IPv6 prefix extension to be
+included even though the header indicates v1 is not supported.
+The peer then receives a malformed CLC proposal where the header type
+does not match the payload, and immediately resets the connection.
+
+The fix ensures consistency between the CLC header flags and the actual
+payload by synchronizing `ini->smc_type_v1` with `pclc_base->hdr.typev1`
+when prefix setup fails.
+
+Fixes: 8c3dca341aea ("net/smc: build and send V2 CLC proposal")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20251107024029.88753-1-alibuda@linux.alibaba.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/smc_clc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
+index 09745baa10170..27750a695ed8b 100644
+--- a/net/smc/smc_clc.c
++++ b/net/smc/smc_clc.c
+@@ -890,6 +890,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
+                               return SMC_CLC_DECL_CNFERR;
+                       }
+                       pclc_base->hdr.typev1 = SMC_TYPE_N;
++                      ini->smc_type_v1 = SMC_TYPE_N;
+               } else {
+                       pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
+                       plen += sizeof(*pclc_prfx) +
+-- 
+2.51.0
+
diff --git a/queue-6.17/net_sched-limit-try_bulk_dequeue_skb-batches.patch b/queue-6.17/net_sched-limit-try_bulk_dequeue_skb-batches.patch
new file mode 100644 (file)
index 0000000..21e5bb3
--- /dev/null
@@ -0,0 +1,143 @@
+From 2df456a23f3ec51853d77de1f9ca593929c9a774 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:12:15 +0000
+Subject: net_sched: limit try_bulk_dequeue_skb() batches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0345552a653ce5542affeb69ac5aa52177a5199b ]
+
+After commit 100dfa74cad9 ("inet: dev_queue_xmit() llist adoption")
+I started seeing many qdisc requeues on IDPF under high TX workload.
+
+$ tc -s qd sh dev eth1 handle 1: ; sleep 1; tc -s qd sh dev eth1 handle 1:
+qdisc mq 1: root
+ Sent 43534617319319 bytes 268186451819 pkt (dropped 0, overlimits 0 requeues 3532840114)
+ backlog 1056Kb 6675p requeues 3532840114
+qdisc mq 1: root
+ Sent 43554665866695 bytes 268309964788 pkt (dropped 0, overlimits 0 requeues 3537737653)
+ backlog 781164b 4822p requeues 3537737653
+
+This is caused by try_bulk_dequeue_skb() being only limited by BQL budget.
+
+perf record -C120-239 -e qdisc:qdisc_dequeue sleep 1 ; perf script
+...
+ netperf 75332 [146]  2711.138269: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1292 skbaddr=0xff378005a1e9f200
+ netperf 75332 [146]  2711.138953: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1213 skbaddr=0xff378004d607a500
+ netperf 75330 [144]  2711.139631: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1233 skbaddr=0xff3780046be20100
+ netperf 75333 [147]  2711.140356: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1093 skbaddr=0xff37800514845b00
+ netperf 75337 [151]  2711.141037: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1353 skbaddr=0xff37800460753300
+ netperf 75337 [151]  2711.141877: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1367 skbaddr=0xff378004e72c7b00
+ netperf 75330 [144]  2711.142643: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1202 skbaddr=0xff3780045bd60000
+...
+
+This is bad because :
+
+1) Large batches hold one victim cpu for a very long time.
+
+2) Driver often hit their own TX ring limit (all slots are used).
+
+3) We call dev_requeue_skb()
+
+4) Requeues are using a FIFO (q->gso_skb), breaking qdisc ability to
+   implement FQ or priority scheduling.
+
+5) dequeue_skb() gets packets from q->gso_skb one skb at a time
+   with no xmit_more support. This is causing many spinlock games
+   between the qdisc and the device driver.
+
+Requeues were supposed to be very rare, lets keep them this way.
+
+Limit batch sizes to /proc/sys/net/core/dev_weight (default 64) as
+__qdisc_run() was designed to use.
+
+Fixes: 5772e9a3463b ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/20251109161215.2574081-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_generic.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 1e008a228ebdf..7dee9748a56be 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -180,9 +180,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
+ static void try_bulk_dequeue_skb(struct Qdisc *q,
+                                struct sk_buff *skb,
+                                const struct netdev_queue *txq,
+-                               int *packets)
++                               int *packets, int budget)
+ {
+       int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
++      int cnt = 0;
+       while (bytelimit > 0) {
+               struct sk_buff *nskb = q->dequeue(q);
+@@ -193,8 +194,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
+               bytelimit -= nskb->len; /* covers GSO len */
+               skb->next = nskb;
+               skb = nskb;
+-              (*packets)++; /* GSO counts as one pkt */
++              if (++cnt >= budget)
++                      break;
+       }
++      (*packets) += cnt;
+       skb_mark_not_on_list(skb);
+ }
+@@ -228,7 +231,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
+  * A requeued skb (via q->gso_skb) can also be a SKB list.
+  */
+ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+-                                 int *packets)
++                                 int *packets, int budget)
+ {
+       const struct netdev_queue *txq = q->dev_queue;
+       struct sk_buff *skb = NULL;
+@@ -295,7 +298,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+       if (skb) {
+ bulk:
+               if (qdisc_may_bulk(q))
+-                      try_bulk_dequeue_skb(q, skb, txq, packets);
++                      try_bulk_dequeue_skb(q, skb, txq, packets, budget);
+               else
+                       try_bulk_dequeue_skb_slow(q, skb, packets);
+       }
+@@ -387,7 +390,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+  *                            >0 - queue is not empty.
+  *
+  */
+-static inline bool qdisc_restart(struct Qdisc *q, int *packets)
++static inline bool qdisc_restart(struct Qdisc *q, int *packets, int budget)
+ {
+       spinlock_t *root_lock = NULL;
+       struct netdev_queue *txq;
+@@ -396,7 +399,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
+       bool validate;
+       /* Dequeue packet */
+-      skb = dequeue_skb(q, &validate, packets);
++      skb = dequeue_skb(q, &validate, packets, budget);
+       if (unlikely(!skb))
+               return false;
+@@ -414,7 +417,7 @@ void __qdisc_run(struct Qdisc *q)
+       int quota = READ_ONCE(net_hotdata.dev_tx_weight);
+       int packets;
+-      while (qdisc_restart(q, &packets)) {
++      while (qdisc_restart(q, &packets, quota)) {
+               quota -= packets;
+               if (quota <= 0) {
+                       if (q->flags & TCQ_F_NOLOCK)
+-- 
+2.51.0
+
diff --git a/queue-6.17/netfilter-nft_ct-add-seqadj-extension-for-natted-con.patch b/queue-6.17/netfilter-nft_ct-add-seqadj-extension-for-natted-con.patch
new file mode 100644 (file)
index 0000000..ac6b6d8
--- /dev/null
@@ -0,0 +1,113 @@
+From 2fdce4a177dff1a44823fd39813f73c5b7798ce9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Oct 2025 18:22:16 +0200
+Subject: netfilter: nft_ct: add seqadj extension for natted connections
+
+From: Andrii Melnychenko <a.melnychenko@vyos.io>
+
+[ Upstream commit 90918e3b6404c2a37837b8f11692471b4c512de2 ]
+
+Sequence adjustment may be required for FTP traffic with PASV/EPSV modes.
+due to need to re-write packet payload (IP, port) on the ftp control
+connection. This can require changes to the TCP length and expected
+seq / ack_seq.
+
+The easiest way to reproduce this issue is with PASV mode.
+Example ruleset:
+table inet ftp_nat {
+        ct helper ftp_helper {
+                type "ftp" protocol tcp
+                l3proto inet
+        }
+
+        chain prerouting {
+                type filter hook prerouting priority 0; policy accept;
+                tcp dport 21 ct state new ct helper set "ftp_helper"
+        }
+}
+table ip nat {
+        chain prerouting {
+                type nat hook prerouting priority -100; policy accept;
+                tcp dport 21 dnat ip prefix to ip daddr map {
+                       192.168.100.1 : 192.168.13.2/32 }
+        }
+
+        chain postrouting {
+                type nat hook postrouting priority 100 ; policy accept;
+                tcp sport 21 snat ip prefix to ip saddr map {
+                       192.168.13.2 : 192.168.100.1/32 }
+        }
+}
+
+Note that the ftp helper gets assigned *after* the dnat setup.
+
+The inverse (nat after helper assign) is handled by an existing
+check in nf_nat_setup_info() and will not show the problem.
+
+Topoloy:
+
+ +-------------------+     +----------------------------------+
+ | FTP: 192.168.13.2 | <-> | NAT: 192.168.13.3, 192.168.100.1 |
+ +-------------------+     +----------------------------------+
+                                      |
+                         +-----------------------+
+                         | Client: 192.168.100.2 |
+                         +-----------------------+
+
+ftp nat changes do not work as expected in this case:
+Connected to 192.168.100.1.
+[..]
+ftp> epsv
+EPSV/EPRT on IPv4 off.
+ftp> ls
+227 Entering passive mode (192,168,100,1,209,129).
+421 Service not available, remote server has closed connection.
+
+Kernel logs:
+Missing nfct_seqadj_ext_add() setup call
+WARNING: CPU: 1 PID: 0 at net/netfilter/nf_conntrack_seqadj.c:41
+[..]
+ __nf_nat_mangle_tcp_packet+0x100/0x160 [nf_nat]
+ nf_nat_ftp+0x142/0x280 [nf_nat_ftp]
+ help+0x4d1/0x880 [nf_conntrack_ftp]
+ nf_confirm+0x122/0x2e0 [nf_conntrack]
+ nf_hook_slow+0x3c/0xb0
+ ..
+
+Fix this by adding the required extension when a conntrack helper is assigned
+to a connection that has a nat binding.
+
+Fixes: 1a64edf54f55 ("netfilter: nft_ct: add helper set support")
+Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_ct.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
+index d526e69a2a2b8..f358cdc5e6926 100644
+--- a/net/netfilter/nft_ct.c
++++ b/net/netfilter/nft_ct.c
+@@ -22,6 +22,7 @@
+ #include <net/netfilter/nf_conntrack_timeout.h>
+ #include <net/netfilter/nf_conntrack_l4proto.h>
+ #include <net/netfilter/nf_conntrack_expect.h>
++#include <net/netfilter/nf_conntrack_seqadj.h>
+ struct nft_ct_helper_obj  {
+       struct nf_conntrack_helper *helper4;
+@@ -1173,6 +1174,10 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
+       if (help) {
+               rcu_assign_pointer(help->helper, to_assign);
+               set_bit(IPS_HELPER_BIT, &ct->status);
++
++              if ((ct->status & IPS_NAT_MASK) && !nfct_seqadj(ct))
++                      if (!nfct_seqadj_ext_add(ct))
++                              regs->verdict.code = NF_DROP;
+       }
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.17/nfsd-skip-close-replay-processing-if-xdr-encoding-fa.patch b/queue-6.17/nfsd-skip-close-replay-processing-if-xdr-encoding-fa.patch
new file mode 100644 (file)
index 0000000..f42d526
--- /dev/null
@@ -0,0 +1,43 @@
+From 6ae90462da09069524543f23aa61e0db10b58102 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Oct 2025 09:49:55 -0400
+Subject: NFSD: Skip close replay processing if XDR encoding fails
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit ff8141e49cf70d2d093a5228f5299ce188de6142 ]
+
+The replay logic added by commit 9411b1d4c7df ("nfsd4: cleanup
+handling of nfsv4.0 closed stateid's") cannot be done if encoding
+failed due to a short send buffer; there's no guarantee that the
+operation encoder has actually encoded the data that is being copied
+to the replay cache.
+
+Reported-by: rtm@csail.mit.edu
+Closes: https://lore.kernel.org/linux-nfs/c3628d57-94ae-48cf-8c9e-49087a28cec9@oracle.com/T/#t
+Fixes: 9411b1d4c7df ("nfsd4: cleanup handling of nfsv4.0 closed stateid's")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: NeilBrown <neil@brown.name>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4xdr.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index 1f6c3db3bc6e5..37541ea408fc0 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -5928,8 +5928,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
+                */
+               warn_on_nonidempotent_op(op);
+               xdr_truncate_encode(xdr, op_status_offset + XDR_UNIT);
+-      }
+-      if (so) {
++      } else if (so) {
+               int len = xdr->buf->len - (op_status_offset + XDR_UNIT);
+               so->so_replay.rp_status = op->status;
+-- 
+2.51.0
+
diff --git a/queue-6.17/rust-add-fno-isolate-erroneous-paths-dereference-to-.patch b/queue-6.17/rust-add-fno-isolate-erroneous-paths-dereference-to-.patch
new file mode 100644 (file)
index 0000000..26cb64a
--- /dev/null
@@ -0,0 +1,41 @@
+From 0b00d93bb4967eb990e4b68ec2c373bca9a1028d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:01:50 +0800
+Subject: rust: Add -fno-isolate-erroneous-paths-dereference to
+ bindgen_skip_c_flags
+
+From: Xi Ruoyao <xry111@xry111.site>
+
+[ Upstream commit fe4b3a34e9a9654d98d274218dac0270779db0ae ]
+
+It's used to work around an objtool issue since commit abb2a5572264
+("LoongArch: Add cflag -fno-isolate-erroneous-paths-dereference"), but
+it's then passed to bindgen and cause an error because Clang does not
+have this option.
+
+Fixes: abb2a5572264 ("LoongArch: Add cflag -fno-isolate-erroneous-paths-dereference")
+Acked-by: Miguel Ojeda <ojeda@kernel.org>
+Tested-by: Mingcong Bai <jeffbai@aosc.io>
+Signed-off-by: Xi Ruoyao <xry111@xry111.site>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rust/Makefile b/rust/Makefile
+index 9ec1119c02d39..403ce8518381d 100644
+--- a/rust/Makefile
++++ b/rust/Makefile
+@@ -299,7 +299,7 @@ bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
+       -fno-inline-functions-called-once -fsanitize=bounds-strict \
+       -fstrict-flex-arrays=% -fmin-function-alignment=% \
+       -fzero-init-padding-bits=% -mno-fdpic \
+-      --param=% --param asan-%
++      --param=% --param asan-% -fno-isolate-erroneous-paths-dereference
+ # Derived from `scripts/Makefile.clang`.
+ BINDGEN_TARGET_x86    := x86_64-linux-gnu
+-- 
+2.51.0
+
diff --git a/queue-6.17/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch b/queue-6.17/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
new file mode 100644 (file)
index 0000000..84fb0f9
--- /dev/null
@@ -0,0 +1,86 @@
+From 5f5525c3374f2dfa741c9fd6a2817bc21a8dfe14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 11:10:54 +0000
+Subject: sctp: prevent possible shift-out-of-bounds in
+ sctp_transport_update_rto
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 1534ff77757e44bcc4b98d0196bc5c0052fce5fa ]
+
+syzbot reported a possible shift-out-of-bounds [1]
+
+Blamed commit added rto_alpha_max and rto_beta_max set to 1000.
+
+It is unclear if some sctp users are setting very large rto_alpha
+and/or rto_beta.
+
+In order to prevent user regression, perform the test at run time.
+
+Also add READ_ONCE() annotations as sysctl values can change under us.
+
+[1]
+
+UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41
+shift exponent 64 is too large for 32-bit type 'unsigned int'
+CPU: 0 UID: 0 PID: 16704 Comm: syz.2.2320 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:94 [inline]
+  dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120
+  ubsan_epilogue lib/ubsan.c:233 [inline]
+  __ubsan_handle_shift_out_of_bounds+0x27f/0x420 lib/ubsan.c:494
+  sctp_transport_update_rto.cold+0x1c/0x34b net/sctp/transport.c:509
+  sctp_check_transmitted+0x11c4/0x1c30 net/sctp/outqueue.c:1502
+  sctp_outq_sack+0x4ef/0x1b20 net/sctp/outqueue.c:1338
+  sctp_cmd_process_sack net/sctp/sm_sideeffect.c:840 [inline]
+  sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1372 [inline]
+
+Fixes: b58537a1f562 ("net: sctp: fix permissions for rto_alpha and rto_beta knobs")
+Reported-by: syzbot+f8c46c8b2b7f6e076e99@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c81ae.050a0220.3d0d33.014e.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20251106111054.3288127-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/transport.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 4d258a6e8033c..e0cf9a41e0e43 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -495,6 +495,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+       if (tp->rttvar || tp->srtt) {
+               struct net *net = tp->asoc->base.net;
++              unsigned int rto_beta, rto_alpha;
+               /* 6.3.1 C3) When a new RTT measurement R' is made, set
+                * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+                * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+@@ -506,10 +507,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+                * For example, assuming the default value of RTO.Alpha of
+                * 1/8, rto_alpha would be expressed as 3.
+                */
+-              tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
+-                      + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
+-              tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
+-                      + (rtt >> net->sctp.rto_alpha);
++              rto_beta = READ_ONCE(net->sctp.rto_beta);
++              if (rto_beta < 32)
++                      tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta)
++                              + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> rto_beta);
++              rto_alpha = READ_ONCE(net->sctp.rto_alpha);
++              if (rto_alpha < 32)
++                      tp->srtt = tp->srtt - (tp->srtt >> rto_alpha)
++                              + (rtt >> rto_alpha);
+       } else {
+               /* 6.3.1 C2) When the first RTT measurement R is made, set
+                * SRTT <- R, RTTVAR <- R/2.
+-- 
+2.51.0
+
diff --git a/queue-6.17/selftests-net-local_termination-wait-for-interfaces-.patch b/queue-6.17/selftests-net-local_termination-wait-for-interfaces-.patch
new file mode 100644 (file)
index 0000000..370566d
--- /dev/null
@@ -0,0 +1,48 @@
+From d0059d0e9a9a1104f73ab13d6013fe990663b2f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 17:12:09 +0100
+Subject: selftests: net: local_termination: Wait for interfaces to come up
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+[ Upstream commit 57531b3416448d1ced36a2a974a4085ec43d57b0 ]
+
+It seems that most of the tests prepare the interfaces once before the test
+run (setup_prepare()), rely on setup_wait() to wait for link and only then
+run the test(s).
+
+local_termination brings the physical interfaces down and up during test
+run but never wait for them to come up. If the auto-negotiation takes
+some seconds, first test packets are being lost, which leads to
+false-negative test results.
+
+Use setup_wait() in run_test() to make sure auto-negotiation has been
+completed after all simple_if_init() calls on physical interfaces and test
+packets will not be lost because of the race against link establishment.
+
+Fixes: 90b9566aa5cd3f ("selftests: forwarding: add a test for local_termination.sh")
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Link: https://patch.msgid.link/20251106161213.459501-1-alexander.sverdlin@siemens.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/local_termination.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/selftests/net/forwarding/local_termination.sh b/tools/testing/selftests/net/forwarding/local_termination.sh
+index ecd34f364125c..892895659c7e4 100755
+--- a/tools/testing/selftests/net/forwarding/local_termination.sh
++++ b/tools/testing/selftests/net/forwarding/local_termination.sh
+@@ -176,6 +176,8 @@ run_test()
+       local rcv_dmac=$(mac_get $rcv_if_name)
+       local should_receive
++      setup_wait
++
+       tcpdump_start $rcv_if_name
+       mc_route_prepare $send_if_name
+-- 
+2.51.0
+
index a50b5a0191625626eb5c067a20f71225000b71cc..c20ea3f45db98731963c3a057cb8b793f8cb3fb0 100644 (file)
@@ -43,3 +43,52 @@ hid-logitech-hidpp-add-hidpp_quirk_reset_hi_res_scro.patch
 asoc-max98090-91-fixed-max98091-alsa-widget-powering.patch
 alsa-hda-realtek-fix-mute-led-for-hp-omen-17-cb0xxx.patch
 ixgbe-handle-ixgbe_vf_features_negotiate-mbox-cmd.patch
+wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch
+erofs-avoid-infinite-loop-due-to-incomplete-zstd-com.patch
+selftests-net-local_termination-wait-for-interfaces-.patch
+net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
+net-phy-micrel-introduce-lanphy_modify_page_reg.patch
+net-phy-micrel-replace-hardcoded-pages-with-defines.patch
+net-phy-micrel-lan8814-fix-reset-of-the-qsgmii-inter.patch
+rust-add-fno-isolate-erroneous-paths-dereference-to-.patch
+nfsd-skip-close-replay-processing-if-xdr-encoding-fa.patch
+bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch
+bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
+bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
+bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
+bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
+bluetooth-hci_conn-fix-not-cleaning-up-pa_link-conne.patch
+sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
+net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-o.patch
+net-smc-fix-mismatch-between-clc-header-and-proposal.patch
+net-handshake-fix-memory-leak-in-tls_handshake_accep.patch
+net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-respons.patch
+net-ethernet-ti-am65-cpsw-qos-fix-iet-verify-retry-m.patch
+tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
+net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
+wifi-mac80211-skip-rate-verification-for-not-capture.patch
+af_unix-initialise-scc_index-in-unix_add_edge.patch
+bluetooth-hci_event-fix-not-handling-pa-sync-lost-ev.patch
+net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
+net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
+net-mlx5e-fix-missing-error-assignment-in-mlx5e_xfrm.patch
+net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
+net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
+net-mlx5e-fix-potentially-misleading-debug-message.patch
+net-mlx5-fix-typo-of-mlx5_eq_doorbel_offset.patch
+net-mlx5-store-the-global-doorbell-in-mlx5_priv.patch
+net-mlx5e-prepare-for-using-different-cq-doorbells.patch
+mlx5-fix-default-values-in-create-cq.patch
+net_sched-limit-try_bulk_dequeue_skb-batches.patch
+wifi-iwlwifi-mvm-fix-beacon-template-fixed-rate.patch
+wifi-iwlwifi-mld-always-take-beacon-ies-in-link-grad.patch
+virtio-net-fix-incorrect-flags-recording-in-big-mode.patch
+hsr-fix-supervision-frame-sending-on-hsrv0.patch
+hsr-follow-standard-for-hsrv0-supervision-frames.patch
+acpi-cppc-detect-preferred-core-availability-on-onli.patch
+acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch
+acpi-cppc-perform-fast-check-switch-only-for-online-.patch
+acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch
+cpufreq-intel_pstate-check-ida-only-before-msr_ia32_.patch
+bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
+netfilter-nft_ct-add-seqadj-extension-for-natted-con.patch
diff --git a/queue-6.17/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch b/queue-6.17/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
new file mode 100644 (file)
index 0000000..c27e129
--- /dev/null
@@ -0,0 +1,150 @@
+From e3ab22bbb46ed5ba04746f30ea15a76756e6776f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 06:40:25 +0000
+Subject: tipc: Fix use-after-free in tipc_mon_reinit_self().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 0725e6afb55128be21a2ca36e9674f573ccec173 ]
+
+syzbot reported use-after-free of tipc_net(net)->monitors[]
+in tipc_mon_reinit_self(). [0]
+
+The array is protected by RTNL, but tipc_mon_reinit_self()
+iterates over it without RTNL.
+
+tipc_mon_reinit_self() is called from tipc_net_finalize(),
+which is always under RTNL except for tipc_net_finalize_work().
+
+Let's hold RTNL in tipc_net_finalize_work().
+
+[0]:
+BUG: KASAN: slab-use-after-free in __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+Read of size 1 at addr ffff88805eae1030 by task kworker/0:7/5989
+
+CPU: 0 UID: 0 PID: 5989 Comm: kworker/0:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
+Workqueue: events tipc_net_finalize_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xca/0x240 mm/kasan/report.c:482
+ kasan_report+0x118/0x150 mm/kasan/report.c:595
+ __kasan_check_byte+0x2a/0x40 mm/kasan/common.c:568
+ kasan_check_byte include/linux/kasan.h:399 [inline]
+ lock_acquire+0x8d/0x360 kernel/locking/lockdep.c:5842
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+ rtlock_slowlock kernel/locking/rtmutex.c:1894 [inline]
+ rwbase_rtmutex_lock_state kernel/locking/spinlock_rt.c:160 [inline]
+ rwbase_write_lock+0xd3/0x7e0 kernel/locking/rwbase_rt.c:244
+ rt_write_lock+0x76/0x110 kernel/locking/spinlock_rt.c:243
+ write_lock_bh include/linux/rwlock_rt.h:99 [inline]
+ tipc_mon_reinit_self+0x79/0x430 net/tipc/monitor.c:718
+ tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
+ process_one_work kernel/workqueue.c:3236 [inline]
+ process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3319
+ worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
+ kthread+0x70e/0x8a0 kernel/kthread.c:463
+ ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+Allocated by task 6089:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __kmalloc_cache_noprof+0x1a8/0x320 mm/slub.c:4407
+ kmalloc_noprof include/linux/slab.h:905 [inline]
+ kzalloc_noprof include/linux/slab.h:1039 [inline]
+ tipc_mon_create+0xc3/0x4d0 net/tipc/monitor.c:657
+ tipc_enable_bearer net/tipc/bearer.c:357 [inline]
+ __tipc_nl_bearer_enable+0xe16/0x13f0 net/tipc/bearer.c:1047
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:371 [inline]
+ tipc_nl_compat_doit+0x3bc/0x5f0 net/tipc/netlink_compat.c:393
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:-1 [inline]
+ tipc_nl_compat_recv+0x83c/0xbe0 net/tipc/netlink_compat.c:1321
+ genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
+ netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
+ netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:729
+ ____sys_sendmsg+0x508/0x820 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 6088:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
+ poison_slab_object mm/kasan/common.c:243 [inline]
+ __kasan_slab_free+0x5b/0x80 mm/kasan/common.c:275
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2422 [inline]
+ slab_free mm/slub.c:4695 [inline]
+ kfree+0x195/0x550 mm/slub.c:4894
+ tipc_l2_device_event+0x380/0x650 net/tipc/bearer.c:-1
+ notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
+ call_netdevice_notifiers_extack net/core/dev.c:2267 [inline]
+ call_netdevice_notifiers net/core/dev.c:2281 [inline]
+ unregister_netdevice_many_notify+0x14d7/0x1fe0 net/core/dev.c:12166
+ unregister_netdevice_many net/core/dev.c:12229 [inline]
+ unregister_netdevice_queue+0x33c/0x380 net/core/dev.c:12073
+ unregister_netdevice include/linux/netdevice.h:3385 [inline]
+ __tun_detach+0xe4d/0x1620 drivers/net/tun.c:621
+ tun_detach drivers/net/tun.c:637 [inline]
+ tun_chr_close+0x10d/0x1c0 drivers/net/tun.c:3433
+ __fput+0x458/0xa80 fs/file_table.c:468
+ task_work_run+0x1d4/0x260 kernel/task_work.c:227
+ resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
+ exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:43
+ exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
+ syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline]
+ syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline]
+ do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 46cb01eeeb86 ("tipc: update mon's self addr when node addr generated")
+Reported-by: syzbot+d7dad7fd4b3921104957@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c323a.050a0220.baf87.007f.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251107064038.2361188-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/net.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/tipc/net.c b/net/tipc/net.c
+index 0e95572e56b41..7e65d0b0c4a8d 100644
+--- a/net/tipc/net.c
++++ b/net/tipc/net.c
+@@ -145,7 +145,9 @@ void tipc_net_finalize_work(struct work_struct *work)
+ {
+       struct tipc_net *tn = container_of(work, struct tipc_net, work);
++      rtnl_lock();
+       tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
++      rtnl_unlock();
+ }
+ void tipc_net_stop(struct net *net)
+-- 
+2.51.0
+
diff --git a/queue-6.17/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch b/queue-6.17/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch
new file mode 100644 (file)
index 0000000..f0c88d5
--- /dev/null
@@ -0,0 +1,72 @@
+From d5ee579a041d63cdf1caf281c860c588504eb23f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:08:28 +0800
+Subject: virtio-net: fix incorrect flags recording in big mode
+
+From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+
+[ Upstream commit 0eff2eaa5322b5b141ff5d5ded26fac4a52b5f7b ]
+
+The purpose of commit 703eec1b2422 ("virtio_net: fixing XDP for fully
+checksummed packets handling") is to record the flags in advance, as
+their value may be overwritten in the XDP case. However, the flags
+recorded under big mode are incorrect, because in big mode, the passed
+buf does not point to the rx buffer, but rather to the page of the
+submitted buffer. This commit fixes this issue.
+
+For the small mode, the commit c11a49d58ad2 ("virtio_net: Fix mismatched
+buf address when unmapping for small packets") fixed it.
+
+Tested-by: Alyssa Ross <hi@alyssa.is>
+Fixes: 703eec1b2422 ("virtio_net: fixing XDP for fully checksummed packets handling")
+Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Link: https://patch.msgid.link/20251111090828.23186-1-xuanzhuo@linux.alibaba.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/virtio_net.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 35bdbf1f45ee6..36b1bc0d56846 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -2632,22 +2632,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
+               return;
+       }
+-      /* 1. Save the flags early, as the XDP program might overwrite them.
++      /* About the flags below:
++       * 1. Save the flags early, as the XDP program might overwrite them.
+        * These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID
+        * stay valid after XDP processing.
+        * 2. XDP doesn't work with partially checksummed packets (refer to
+        * virtnet_xdp_set()), so packets marked as
+        * VIRTIO_NET_HDR_F_NEEDS_CSUM get dropped during XDP processing.
+        */
+-      flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+-      if (vi->mergeable_rx_bufs)
++      if (vi->mergeable_rx_bufs) {
++              flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+               skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
+                                       stats);
+-      else if (vi->big_packets)
++      } else if (vi->big_packets) {
++              void *p = page_address((struct page *)buf);
++
++              flags = ((struct virtio_net_common_hdr *)p)->hdr.flags;
+               skb = receive_big(dev, vi, rq, buf, len, stats);
+-      else
++      } else {
++              flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+               skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit, stats);
++      }
+       if (unlikely(!skb))
+               return;
+-- 
+2.51.0
+
diff --git a/queue-6.17/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch b/queue-6.17/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch
new file mode 100644 (file)
index 0000000..48790b6
--- /dev/null
@@ -0,0 +1,53 @@
+From 6550220f791a341056cc6a756e5f277b4bb46777 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Nov 2025 09:39:57 +0100
+Subject: wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp()
+
+From: Nicolas Escande <nico.escande@gmail.com>
+
+[ Upstream commit 9065b968752334f972e0d48e50c4463a172fc2a7 ]
+
+When reporting tx completion using ieee80211_tx_status_xxx() family of
+functions, the status part of the struct ieee80211_tx_info nested in the
+skb is used to report things like transmit rates & retry count to mac80211
+
+On the TX data path, this is correctly memset to 0 before calling
+ieee80211_tx_status_ext(), but on the tx mgmt path this was not done.
+
+This leads to mac80211 treating garbage values as valid transmit counters
+(like tx retries for example) and accounting them as real statistics that
+makes their way to userland via station dump.
+
+The same issue was resolved in ath12k by commit 9903c0986f78 ("wifi:
+ath12k: Add memset and update default rate value in wmi tx completion")
+
+Tested-on: QCN9074 PCI WLAN.HK.2.9.0.1-01977-QCAHKSWPL_SILICONZ-1
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
+Link: https://patch.msgid.link/20251104083957.717825-1-nico.escande@gmail.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 0491e3fd6b5e1..e3b444333deed 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -5961,6 +5961,9 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar,
+       dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+       info = IEEE80211_SKB_CB(msdu);
++      memset(&info->status, 0, sizeof(info->status));
++      info->status.rates[0].idx = -1;
++
+       if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) &&
+           !tx_compl_param->status) {
+               info->flags |= IEEE80211_TX_STAT_ACK;
+-- 
+2.51.0
+
diff --git a/queue-6.17/wifi-iwlwifi-mld-always-take-beacon-ies-in-link-grad.patch b/queue-6.17/wifi-iwlwifi-mld-always-take-beacon-ies-in-link-grad.patch
new file mode 100644 (file)
index 0000000..1d35f11
--- /dev/null
@@ -0,0 +1,71 @@
+From 2fc407a45f4ccbfa7644cd4532b14bd3030da409 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 14:57:00 +0200
+Subject: wifi: iwlwifi: mld: always take beacon ies in link grading
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit 1a222625b468effd13d1ebb662c36a41c28a835a ]
+
+One of the factors of a link's grade is the channel load, which is
+calculated from the AP's bss load element.
+The current code takes this element from the beacon for an active link,
+and from bss->ies for an inactive link.
+
+bss->ies is set to either the beacon's ies or to the probe response
+ones, with preference to the probe response (meaning that if there was
+even one probe response, the ies of it will be stored in bss->ies and
+won't be overiden by the beacon ies).
+
+The probe response can be very old, i.e. from the connection time,
+where a beacon is updated before each link selection (which is
+triggered only after a passive scan).
+
+In such case, the bss load element in the probe response will not
+include the channel load caused by the STA, where the beacon will.
+
+This will cause the inactive link to always have a lower channel
+load, and therefore an higher grade than the active link's one.
+
+This causes repeated link switches, causing the throughput to drop.
+
+Fix this by always taking the ies from the beacon, as those are for
+sure new.
+
+Fixes: d1e879ec600f ("wifi: iwlwifi: add iwlmld sub-driver")
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251110145652.b493dbb1853a.I058ba7309c84159f640cc9682d1bda56dd56a536@changeid
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mld/link.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.c b/drivers/net/wireless/intel/iwlwifi/mld/link.c
+index 131190977d4b0..5b10e1e443178 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mld/link.c
++++ b/drivers/net/wireless/intel/iwlwifi/mld/link.c
+@@ -701,18 +701,13 @@ static int
+ iwl_mld_get_chan_load_from_element(struct iwl_mld *mld,
+                                  struct ieee80211_bss_conf *link_conf)
+ {
+-      struct ieee80211_vif *vif = link_conf->vif;
+       const struct cfg80211_bss_ies *ies;
+       const struct element *bss_load_elem = NULL;
+       const struct ieee80211_bss_load_elem *bss_load;
+       guard(rcu)();
+-      if (ieee80211_vif_link_active(vif, link_conf->link_id))
+-              ies = rcu_dereference(link_conf->bss->beacon_ies);
+-      else
+-              ies = rcu_dereference(link_conf->bss->ies);
+-
++      ies = rcu_dereference(link_conf->bss->beacon_ies);
+       if (ies)
+               bss_load_elem = cfg80211_find_elem(WLAN_EID_QBSS_LOAD,
+                                                  ies->data, ies->len);
+-- 
+2.51.0
+
diff --git a/queue-6.17/wifi-iwlwifi-mvm-fix-beacon-template-fixed-rate.patch b/queue-6.17/wifi-iwlwifi-mvm-fix-beacon-template-fixed-rate.patch
new file mode 100644 (file)
index 0000000..a5c5ae9
--- /dev/null
@@ -0,0 +1,81 @@
+From b78dcff69c41699a5d20983995601033b6425084 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Oct 2025 11:20:44 +0200
+Subject: wifi: iwlwifi: mvm: fix beacon template/fixed rate
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 3592c0083fb29cca13cd9978b8844d58b4eff548 ]
+
+During the development of the rate changes, I evidently made
+some changes that shouldn't have been there; beacon templates
+with rate_n_flags are only in old versions, so no changes to
+them should have been necessary, and evidently broke on some
+devices. This also would have broken fixed (injection) rates,
+it would seem. Restore the old handling of this.
+
+Fixes: dabc88cb3b78 ("wifi: iwlwifi: handle v3 rates")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220558
+Reviewed-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Link: https://patch.msgid.link/20251008112044.3bb8ea849d8d.I90f4d2b2c1f62eaedaf304a61d2ab9e50c491c2d@changeid
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 13 +++----------
+ drivers/net/wireless/intel/iwlwifi/mvm/utils.c    | 12 +++++++++---
+ 2 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+index 8805ab344895a..0065c2ead56b1 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+@@ -938,19 +938,12 @@ u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct iwl_mvm *mvm,
+ u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx)
+ {
++      u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx);
+       bool is_new_rate = iwl_fw_lookup_cmd_ver(fw, BEACON_TEMPLATE_CMD, 0) > 10;
+-      u16 flags, cck_flag;
+-
+-      if (is_new_rate) {
+-              flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx);
+-              cck_flag = IWL_MAC_BEACON_CCK;
+-      } else {
+-              cck_flag = IWL_MAC_BEACON_CCK_V1;
+-              flags = iwl_fw_rate_idx_to_plcp(rate_idx);
+-      }
+       if (rate_idx <= IWL_LAST_CCK_RATE)
+-              flags |= cck_flag;
++              flags |= is_new_rate ? IWL_MAC_BEACON_CCK
++                        : IWL_MAC_BEACON_CCK_V1;
+       return flags;
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+index 62da0132f3838..a62f5288dfd06 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+@@ -169,9 +169,15 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
+ u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx)
+ {
+-      return (rate_idx >= IWL_FIRST_OFDM_RATE ?
+-              rate_idx - IWL_FIRST_OFDM_RATE :
+-              rate_idx);
++      if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8)
++              /* In the new rate legacy rates are indexed:
++               * 0 - 3 for CCK and 0 - 7 for OFDM.
++               */
++              return (rate_idx >= IWL_FIRST_OFDM_RATE ?
++                      rate_idx - IWL_FIRST_OFDM_RATE :
++                      rate_idx);
++
++      return iwl_fw_rate_idx_to_plcp(rate_idx);
+ }
+ u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac)
+-- 
+2.51.0
+
diff --git a/queue-6.17/wifi-mac80211-skip-rate-verification-for-not-capture.patch b/queue-6.17/wifi-mac80211-skip-rate-verification-for-not-capture.patch
new file mode 100644 (file)
index 0000000..14aa1e1
--- /dev/null
@@ -0,0 +1,48 @@
+From 4f638436e2df59343159ab515838879d9940c972 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 14:26:18 +0200
+Subject: wifi: mac80211: skip rate verification for not captured PSDUs
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 7fe0d21f5633af8c3fab9f0ef0706c6156623484 ]
+
+If for example the sniffer did not follow any AIDs in an MU frame, then
+some of the information may not be filled in or is even expected to be
+invalid. As an example, in that case it is expected that Nss is zero.
+
+Fixes: 2ff5e52e7836 ("radiotap: add 0-length PSDU "not captured" type")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251110142554.83a2858ee15b.I9f78ce7984872f474722f9278691ae16378f0a3e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 59baca24aa6b9..dcf4b24cc39cf 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -5352,10 +5352,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+       if (WARN_ON(!local->started))
+               goto drop;
+-      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) {
++      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) &&
++                 !(status->flag & RX_FLAG_NO_PSDU &&
++                   status->zero_length_psdu_type ==
++                   IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) {
+               /*
+-               * Validate the rate, unless a PLCP error means that
+-               * we probably can't have a valid rate here anyway.
++               * Validate the rate, unless there was a PLCP error which may
++               * have an invalid rate or the PSDU was not capture and may be
++               * missing rate information.
+                */
+               switch (status->encoding) {
+-- 
+2.51.0
+
diff --git a/queue-6.6/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch b/queue-6.6/acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch
new file mode 100644 (file)
index 0000000..dce26b5
--- /dev/null
@@ -0,0 +1,49 @@
+From c385bc7c8d8a21b3aa9fbd14be2efcabe216b62c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:42 +0530
+Subject: ACPI: CPPC: Check _CPC validity for only the online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 6dd3b8a709a130a4d55c866af9804c81b8486d28 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function acpi_cpc_valid() checks for the validity of the
+_CPC object for all the present CPUs. This breaks when the kernel is
+booted with "nosmt=force".
+
+Hence check the validity of the _CPC objects of only the online CPUs.
+
+Fixes: 2aeca6bd0277 ("ACPI: CPPC: Check present CPUs for determining _CPC is valid")
+Reported-by: Christopher Harris <chris.harris79@gmail.com>
+Closes: https://lore.kernel.org/lkml/CAM+eXpdDT7KjLV0AxEwOLkSJ2QtrsvGvjA2cCHvt1d0k2_C4Cw@mail.gmail.com/
+Suggested-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Tested-by: Chrisopher Harris <chris.harris79@gmail.com>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-3-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 10d531427ba77..39f248be9611f 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -445,7 +445,7 @@ bool acpi_cpc_valid(void)
+       if (acpi_disabled)
+               return false;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+               if (!cpc_ptr)
+                       return false;
+-- 
+2.51.0
+
diff --git a/queue-6.6/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch b/queue-6.6/acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch
new file mode 100644 (file)
index 0000000..b2c0ac2
--- /dev/null
@@ -0,0 +1,45 @@
+From bc12c0ed9f731afd8572d30afddf4deb477d1d7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:44 +0530
+Subject: ACPI: CPPC: Limit perf ctrs in PCC check only to online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 0fce75870666b46b700cfbd3216380b422f975da ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPU via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function cppc_perf_ctrs_in_pcc() checks if the CPPC
+perf-ctrs are in a PCC region for all the present CPUs, which breaks
+when the kernel is booted with "nosmt=force".
+
+Hence, limit the check only to the online CPUs.
+
+Fixes: ae2df912d1a5 ("ACPI: CPPC: Disable FIE if registers in PCC regions")
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-5-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 6e579be36a1eb..888c7838579a8 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -1368,7 +1368,7 @@ bool cppc_perf_ctrs_in_pcc(void)
+ {
+       int cpu;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               struct cpc_register_resource *ref_perf_reg;
+               struct cpc_desc *cpc_desc;
+-- 
+2.51.0
+
diff --git a/queue-6.6/acpi-cppc-perform-fast-check-switch-only-for-online-.patch b/queue-6.6/acpi-cppc-perform-fast-check-switch-only-for-online-.patch
new file mode 100644 (file)
index 0000000..0d82fa7
--- /dev/null
@@ -0,0 +1,45 @@
+From 2cdf07510768aaf87bd57de54860de5701ab207e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 13:11:43 +0530
+Subject: ACPI: CPPC: Perform fast check switch only for online CPUs
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit 8821c8e80a65bc4eb73daf63b34aac6b8ad69461 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However the function cppc_allow_fast_switch() checks for the validity
+of the _CPC object for all the present CPUs. This breaks when the
+kernel is booted with "nosmt=force".
+
+Check fast_switch capability only on online CPUs
+
+Fixes: 15eece6c5b05 ("ACPI: CPPC: Fix NULL pointer dereference when nosmp is used")
+Reviewed-by: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://patch.msgid.link/20251107074145.2340-4-gautham.shenoy@amd.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 39f248be9611f..6e579be36a1eb 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -461,7 +461,7 @@ bool cppc_allow_fast_switch(void)
+       struct cpc_desc *cpc_ptr;
+       int cpu;
+-      for_each_present_cpu(cpu) {
++      for_each_online_cpu(cpu) {
+               cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+               desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF];
+               if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
+-- 
+2.51.0
+
diff --git a/queue-6.6/af_unix-initialise-scc_index-in-unix_add_edge.patch b/queue-6.6/af_unix-initialise-scc_index-in-unix_add_edge.patch
new file mode 100644 (file)
index 0000000..679f156
--- /dev/null
@@ -0,0 +1,139 @@
+From d2ea2f960a58f5a9cfcd92e25ee20ba26c74372e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 02:52:22 +0000
+Subject: af_unix: Initialise scc_index in unix_add_edge().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 60e6489f8e3b086bd1130ad4450a2c112e863791 ]
+
+Quang Le reported that the AF_UNIX GC could garbage-collect a
+receive queue of an alive in-flight socket, with a nice repro.
+
+The repro consists of three stages.
+
+  1)
+    1-a. Create a single cyclic reference with many sockets
+    1-b. close() all sockets
+    1-c. Trigger GC
+
+  2)
+    2-a. Pass sk-A to an embryo sk-B
+    2-b. Pass sk-X to sk-X
+    2-c. Trigger GC
+
+  3)
+    3-a. accept() the embryo sk-B
+    3-b. Pass sk-B to sk-C
+    3-c. close() the in-flight sk-A
+    3-d. Trigger GC
+
+As of 2-c, sk-A and sk-X are linked to unix_unvisited_vertices,
+and unix_walk_scc() groups them into two different SCCs:
+
+  unix_sk(sk-A)->vertex->scc_index = 2 (UNIX_VERTEX_INDEX_START)
+  unix_sk(sk-X)->vertex->scc_index = 3
+
+Once GC completes, unix_graph_grouped is set to true.
+Also, unix_graph_maybe_cyclic is set to true due to sk-X's
+cyclic self-reference, which makes close() trigger GC.
+
+At 3-b, unix_add_edge() allocates unix_sk(sk-B)->vertex and
+links it to unix_unvisited_vertices.
+
+unix_update_graph() is called at 3-a. and 3-b., but neither
+unix_graph_grouped nor unix_graph_maybe_cyclic is changed
+because both sk-B's listener and sk-C are not in-flight.
+
+3-c decrements sk-A's file refcnt to 1.
+
+Since unix_graph_grouped is true at 3-d, unix_walk_scc_fast()
+is finally called and iterates 3 sockets sk-A, sk-B, and sk-X:
+
+  sk-A -> sk-B (-> sk-C)
+  sk-X -> sk-X
+
+This is totally fine.  All of them are not yet close()d and
+should be grouped into different SCCs.
+
+However, unix_vertex_dead() misjudges that sk-A and sk-B are
+in the same SCC and sk-A is dead.
+
+  unix_sk(sk-A)->scc_index == unix_sk(sk-B)->scc_index <-- Wrong!
+  &&
+  sk-A's file refcnt == unix_sk(sk-A)->vertex->out_degree
+                                       ^-- 1 in-flight count for sk-B
+  -> sk-A is dead !?
+
+The problem is that unix_add_edge() does not initialise scc_index.
+
+Stage 1) is used for heap spraying, making a newly allocated
+vertex have vertex->scc_index == 2 (UNIX_VERTEX_INDEX_START)
+set by unix_walk_scc() at 1-c.
+
+Let's track the max SCC index from the previous unix_walk_scc()
+call and assign the max + 1 to a new vertex's scc_index.
+
+This way, we can continue to avoid Tarjan's algorithm while
+preventing misjudgments.
+
+Fixes: ad081928a8b0 ("af_unix: Avoid Tarjan's algorithm if unnecessary.")
+Reported-by: Quang Le <quanglex97@gmail.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20251109025233.3659187-1-kuniyu@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/garbage.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 0068e758be4dd..66fd606c43f45 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -136,6 +136,7 @@ enum unix_vertex_index {
+ };
+ static unsigned long unix_vertex_unvisited_index = UNIX_VERTEX_INDEX_MARK1;
++static unsigned long unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START;
+ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
+ {
+@@ -144,6 +145,7 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
+       if (!vertex) {
+               vertex = list_first_entry(&fpl->vertices, typeof(*vertex), entry);
+               vertex->index = unix_vertex_unvisited_index;
++              vertex->scc_index = ++unix_vertex_max_scc_index;
+               vertex->out_degree = 0;
+               INIT_LIST_HEAD(&vertex->edges);
+               INIT_LIST_HEAD(&vertex->scc_entry);
+@@ -480,10 +482,15 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde
+                               scc_dead = unix_vertex_dead(v);
+               }
+-              if (scc_dead)
++              if (scc_dead) {
+                       unix_collect_skb(&scc, hitlist);
+-              else if (!unix_graph_maybe_cyclic)
+-                      unix_graph_maybe_cyclic = unix_scc_cyclic(&scc);
++              } else {
++                      if (unix_vertex_max_scc_index < vertex->scc_index)
++                              unix_vertex_max_scc_index = vertex->scc_index;
++
++                      if (!unix_graph_maybe_cyclic)
++                              unix_graph_maybe_cyclic = unix_scc_cyclic(&scc);
++              }
+               list_del(&scc);
+       }
+@@ -498,6 +505,7 @@ static void unix_walk_scc(struct sk_buff_head *hitlist)
+       unsigned long last_index = UNIX_VERTEX_INDEX_START;
+       unix_graph_maybe_cyclic = false;
++      unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START;
+       /* Visit every vertex exactly once.
+        * __unix_walk_scc() moves visited vertices to unix_visited_vertices.
+-- 
+2.51.0
+
diff --git a/queue-6.6/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch b/queue-6.6/bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
new file mode 100644 (file)
index 0000000..de63d46
--- /dev/null
@@ -0,0 +1,149 @@
+From 60b30019aa99bafdc4926aa4fd9104ee905a4307 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:49 +0200
+Subject: Bluetooth: 6lowpan: Don't hold spin lock over sleeping functions
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 98454bc812f3611551e4b1f81732da4aa7b9597e ]
+
+disconnect_all_peers() calls sleeping function (l2cap_chan_close) under
+spinlock.  Holding the lock doesn't actually do any good -- we work on a
+local copy of the list, and the lock doesn't protect against peer->chan
+having already been freed.
+
+Fix by taking refcounts of peer->chan instead.  Clean up the code and
+old comments a bit.
+
+Take devices_lock instead of RCU, because the kfree_rcu();
+l2cap_chan_put(); construct in chan_close_cb() does not guarantee
+peer->chan is necessarily valid in RCU.
+
+Also take l2cap_chan_lock() which is required for l2cap_chan_close().
+
+Log: (bluez 6lowpan-tester Client Connect - Disable)
+------
+BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
+...
+<TASK>
+...
+l2cap_send_disconn_req (net/bluetooth/l2cap_core.c:938 net/bluetooth/l2cap_core.c:1495)
+...
+? __pfx_l2cap_chan_close (net/bluetooth/l2cap_core.c:809)
+do_enable_set (net/bluetooth/6lowpan.c:1048 net/bluetooth/6lowpan.c:1068)
+------
+
+Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 68 ++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 820376eee8bc3..e65d4754c94f4 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -52,6 +52,11 @@ static bool enable_6lowpan;
+ static struct l2cap_chan *listen_chan;
+ static DEFINE_MUTEX(set_lock);
++enum {
++      LOWPAN_PEER_CLOSING,
++      LOWPAN_PEER_MAXBITS
++};
++
+ struct lowpan_peer {
+       struct list_head list;
+       struct rcu_head rcu;
+@@ -60,6 +65,8 @@ struct lowpan_peer {
+       /* peer addresses in various formats */
+       unsigned char lladdr[ETH_ALEN];
+       struct in6_addr peer_addr;
++
++      DECLARE_BITMAP(flags, LOWPAN_PEER_MAXBITS);
+ };
+ struct lowpan_btle_dev {
+@@ -1013,41 +1020,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ static void disconnect_all_peers(void)
+ {
+       struct lowpan_btle_dev *entry;
+-      struct lowpan_peer *peer, *tmp_peer, *new_peer;
+-      struct list_head peers;
+-
+-      INIT_LIST_HEAD(&peers);
++      struct lowpan_peer *peer;
++      int nchans;
+-      /* We make a separate list of peers as the close_cb() will
+-       * modify the device peers list so it is better not to mess
+-       * with the same list at the same time.
++      /* l2cap_chan_close() cannot be called from RCU, and lock ordering
++       * chan->lock > devices_lock prevents taking write side lock, so copy
++       * then close.
+        */
+       rcu_read_lock();
++      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list)
++              list_for_each_entry_rcu(peer, &entry->peers, list)
++                      clear_bit(LOWPAN_PEER_CLOSING, peer->flags);
++      rcu_read_unlock();
+-      list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
+-              list_for_each_entry_rcu(peer, &entry->peers, list) {
+-                      new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
+-                      if (!new_peer)
+-                              break;
++      do {
++              struct l2cap_chan *chans[32];
++              int i;
+-                      new_peer->chan = peer->chan;
+-                      INIT_LIST_HEAD(&new_peer->list);
++              nchans = 0;
+-                      list_add(&new_peer->list, &peers);
+-              }
+-      }
++              spin_lock(&devices_lock);
+-      rcu_read_unlock();
++              list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
++                      list_for_each_entry_rcu(peer, &entry->peers, list) {
++                              if (test_and_set_bit(LOWPAN_PEER_CLOSING,
++                                                   peer->flags))
++                                      continue;
+-      spin_lock(&devices_lock);
+-      list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
+-              l2cap_chan_close(peer->chan, ENOENT);
++                              l2cap_chan_hold(peer->chan);
++                              chans[nchans++] = peer->chan;
+-              list_del_rcu(&peer->list);
+-              kfree_rcu(peer, rcu);
+-      }
+-      spin_unlock(&devices_lock);
++                              if (nchans >= ARRAY_SIZE(chans))
++                                      goto done;
++                      }
++              }
++
++done:
++              spin_unlock(&devices_lock);
++
++              for (i = 0; i < nchans; ++i) {
++                      l2cap_chan_lock(chans[i]);
++                      l2cap_chan_close(chans[i], ENOENT);
++                      l2cap_chan_unlock(chans[i]);
++                      l2cap_chan_put(chans[i]);
++              }
++      } while (nchans);
+ }
+ struct set_enable {
+-- 
+2.51.0
+
diff --git a/queue-6.6/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch b/queue-6.6/bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
new file mode 100644 (file)
index 0000000..ee493bc
--- /dev/null
@@ -0,0 +1,103 @@
+From aeda6762922ffdbdffc825d713f2bff71ad522b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:47 +0200
+Subject: Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type
+ confusion
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit b454505bf57a2e4f5d49951d4deb03730a9348d9 ]
+
+Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types,
+e.g. debugfs "connect" command takes the former, and "disconnect" and
+"connect" to already connected device take the latter.  This is due to
+using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le
+which take different dst_type values.
+
+Fix address type passed to hci_conn_hash_lookup_le().
+
+Retain the debugfs API difference between "connect" and "disconnect"
+commands since it's been like this since 2015 and nobody apparently
+complained.
+
+Fixes: f5ad4ffceba0 ("Bluetooth: 6lowpan: Use hci_conn_hash_lookup_le() when possible")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 50ed3a6b0b0c4..820376eee8bc3 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -956,10 +956,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void)
+ }
+ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+-                        struct l2cap_conn **conn)
++                        struct l2cap_conn **conn, bool disconnect)
+ {
+       struct hci_conn *hcon;
+       struct hci_dev *hdev;
++      int le_addr_type;
+       int n;
+       n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
+@@ -970,13 +971,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+       if (n < 7)
+               return -EINVAL;
++      if (disconnect) {
++              /* The "disconnect" debugfs command has used different address
++               * type constants than "connect" since 2015. Let's retain that
++               * for now even though it's obviously buggy...
++               */
++              *addr_type += 1;
++      }
++
++      switch (*addr_type) {
++      case BDADDR_LE_PUBLIC:
++              le_addr_type = ADDR_LE_DEV_PUBLIC;
++              break;
++      case BDADDR_LE_RANDOM:
++              le_addr_type = ADDR_LE_DEV_RANDOM;
++              break;
++      default:
++              return -EINVAL;
++      }
++
+       /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
+       hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
+       if (!hdev)
+               return -ENOENT;
+       hci_dev_lock(hdev);
+-      hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
++      hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+@@ -1103,7 +1123,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       buf[buf_size] = '\0';
+       if (memcmp(buf, "connect ", 8) == 0) {
+-              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false);
+               if (ret == -EINVAL)
+                       return ret;
+@@ -1140,7 +1160,7 @@ static ssize_t lowpan_control_write(struct file *fp,
+       }
+       if (memcmp(buf, "disconnect ", 11) == 0) {
+-              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
++              ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true);
+               if (ret < 0)
+                       return ret;
+-- 
+2.51.0
+
diff --git a/queue-6.6/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch b/queue-6.6/bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
new file mode 100644 (file)
index 0000000..732f9a0
--- /dev/null
@@ -0,0 +1,54 @@
+From 66ab66f6cdfbdf58630153712486a832153f53a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:46 +0200
+Subject: Bluetooth: 6lowpan: reset link-local header on ipv6 recv path
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3b78f50918276ab28fb22eac9aa49401ac436a3b ]
+
+Bluetooth 6lowpan.c netdev has header_ops, so it must set link-local
+header for RX skb, otherwise things crash, eg. with AF_PACKET SOCK_RAW
+
+Add missing skb_reset_mac_header() for uncompressed ipv6 RX path.
+
+For the compressed one, it is done in lowpan_header_decompress().
+
+Log: (BlueZ 6lowpan-tester Client Recv Raw - Success)
+------
+kernel BUG at net/core/skbuff.c:212!
+Call Trace:
+<IRQ>
+...
+packet_rcv (net/packet/af_packet.c:2152)
+...
+<TASK>
+__local_bh_enable_ip (kernel/softirq.c:407)
+netif_rx (net/core/dev.c:5648)
+chan_recv_cb (net/bluetooth/6lowpan.c:294 net/bluetooth/6lowpan.c:359)
+------
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 13b752c169bed..50ed3a6b0b0c4 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -288,6 +288,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
+               local_skb->pkt_type = PACKET_HOST;
+               local_skb->dev = dev;
++              skb_reset_mac_header(local_skb);
+               skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
+               if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) {
+-- 
+2.51.0
+
diff --git a/queue-6.6/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch b/queue-6.6/bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
new file mode 100644 (file)
index 0000000..344a354
--- /dev/null
@@ -0,0 +1,65 @@
+From 76bd76c7fe0bc189b5d005d889ea46a823d845f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Nov 2025 14:28:41 -0500
+Subject: Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
+
+From: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+
+[ Upstream commit 23d22f2f71768034d6ef86168213843fc49bf550 ]
+
+There is a KASAN: slab-use-after-free read in btusb_disconnect().
+Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will
+free the btusb data associated with the interface. The same data is
+then used later in the function, hence the UAF.
+
+Fix by moving the accesses to btusb data to before the data is free'd.
+
+Reported-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2fc81b50a4f8263a159b
+Tested-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
+Fixes: fd913ef7ce619 ("Bluetooth: btusb: Add out-of-band wakeup support")
+Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 23a9a221056a4..74d264b64b534 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4713,6 +4713,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+       hci_unregister_dev(hdev);
++      if (data->oob_wake_irq)
++              device_init_wakeup(&data->udev->dev, false);
++      if (data->reset_gpio)
++              gpiod_put(data->reset_gpio);
++
+       if (intf == data->intf) {
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
+@@ -4723,17 +4728,11 @@ static void btusb_disconnect(struct usb_interface *intf)
+                       usb_driver_release_interface(&btusb_driver, data->diag);
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       } else if (intf == data->diag) {
+-              usb_driver_release_interface(&btusb_driver, data->intf);
+               if (data->isoc)
+                       usb_driver_release_interface(&btusb_driver, data->isoc);
++              usb_driver_release_interface(&btusb_driver, data->intf);
+       }
+-      if (data->oob_wake_irq)
+-              device_init_wakeup(&data->udev->dev, false);
+-
+-      if (data->reset_gpio)
+-              gpiod_put(data->reset_gpio);
+-
+       hci_free_dev(hdev);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.6/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch b/queue-6.6/bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
new file mode 100644 (file)
index 0000000..dbe01dd
--- /dev/null
@@ -0,0 +1,37 @@
+From 67b57fc4c2847e83e94de3ab508feb5470301f3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Nov 2025 20:29:48 +0200
+Subject: Bluetooth: L2CAP: export l2cap_chan_hold for modules
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit e060088db0bdf7932e0e3c2d24b7371c4c5b867c ]
+
+l2cap_chan_put() is exported, so export also l2cap_chan_hold() for
+modules.
+
+l2cap_chan_hold() has use case in net/bluetooth/6lowpan.c
+
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index dabc07700197c..ad46112cb596b 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -497,6 +497,7 @@ void l2cap_chan_hold(struct l2cap_chan *c)
+       kref_get(&c->kref);
+ }
++EXPORT_SYMBOL_GPL(l2cap_chan_hold);
+ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
+ {
+-- 
+2.51.0
+
diff --git a/queue-6.6/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch b/queue-6.6/bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch
new file mode 100644 (file)
index 0000000..bd6def5
--- /dev/null
@@ -0,0 +1,56 @@
+From d5b472fc11f45bd11bc559cb82f9c93a4d4d77de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Nov 2025 20:16:12 +0200
+Subject: Bluetooth: MGMT: cancel mesh send timer when hdev removed
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 55fb52ffdd62850d667ebed842815e072d3c9961 ]
+
+mesh_send_done timer is not canceled when hdev is removed, which causes
+crash if the timer triggers after hdev is gone.
+
+Cancel the timer when MGMT removes the hdev, like other MGMT timers.
+
+Should fix the BUG: sporadically seen by BlueZ test bot
+(in "Mesh - Send cancel - 1" test).
+
+Log:
+------
+BUG: KASAN: slab-use-after-free in run_timer_softirq+0x76b/0x7d0
+...
+Freed by task 36:
+ kasan_save_stack+0x24/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3a/0x60
+ __kasan_slab_free+0x43/0x70
+ kfree+0x103/0x500
+ device_release+0x9a/0x210
+ kobject_put+0x100/0x1e0
+ vhci_release+0x18b/0x240
+------
+
+Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh")
+Link: https://lore.kernel.org/linux-bluetooth/67364c09.0c0a0220.113cba.39ff@mx.google.com/
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 600518293b864..7de0a0d752629 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9440,6 +9440,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
+       cancel_delayed_work_sync(&hdev->discov_off);
+       cancel_delayed_work_sync(&hdev->service_cache);
+       cancel_delayed_work_sync(&hdev->rpa_expired);
++      cancel_delayed_work_sync(&hdev->mesh_send_done);
+ }
+ void mgmt_power_on(struct hci_dev *hdev, int err)
+-- 
+2.51.0
+
diff --git a/queue-6.6/cifs-stop-writeback-extension-when-change-of-size-is.patch b/queue-6.6/cifs-stop-writeback-extension-when-change-of-size-is.patch
new file mode 100644 (file)
index 0000000..0308ee8
--- /dev/null
@@ -0,0 +1,99 @@
+From 2a2b12769d424fa67a160a6ad598424521e67f4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Nov 2025 14:30:55 +0530
+Subject: cifs: stop writeback extension when change of size is detected
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+cifs_extend_writeback can pick up a folio on an extending write which
+has been dirtied, but we have aclamp on the writeback to an i_size
+local variable, which can cause short writes, yet mark the page as clean.
+This can cause a data corruption.
+
+As an example, consider this scenario:
+1. First write to the file happens offset 0 len 5k.
+2. Writeback starts for the range (0-5k).
+3. Writeback locks page 1 in cifs_writepages_begin. But does not lock
+page 2 yet.
+4. Page 2 is now written to by the next write, which extends the file
+by another 5k. Page 2 and 3 are now marked dirty.
+5. Now we reach cifs_extend_writeback, where we extend to include the
+next folio (even if it should be partially written). We will mark page
+2 for writeback.
+6. But after exiting cifs_extend_writeback, we will clamp the
+writeback to i_size, which was 5k when it started. So we write only 1k
+bytes in page 2.
+7. We still will now mark page 2 as flushed and mark it clean. So
+remaining contents of page 2 will not be written to the server (hence
+the hole in that gap, unless that range gets overwritten).
+
+With this patch, we will make sure not extend the writeback anymore
+when a change in the file size is detected.
+
+This fix also changes the error handling of cifs_extend_writeback when
+a folio get fails. We will now stop the extension when a folio get fails.
+
+Cc: stable@kernel.org # v6.3~v6.9
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Acked-by: David Howells <dhowells@redhat.com>
+Reported-by: Mark A Whiting <whitingm@opentext.com>
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/file.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index 1058066913dd6..1f0a53738426e 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -2747,8 +2747,10 @@ static void cifs_extend_writeback(struct address_space *mapping,
+                                 loff_t start,
+                                 int max_pages,
+                                 loff_t max_len,
+-                                size_t *_len)
++                                size_t *_len,
++                                unsigned long long i_size)
+ {
++      struct inode *inode = mapping->host;
+       struct folio_batch batch;
+       struct folio *folio;
+       unsigned int nr_pages;
+@@ -2779,7 +2781,7 @@ static void cifs_extend_writeback(struct address_space *mapping,
+                       if (!folio_try_get(folio)) {
+                               xas_reset(xas);
+-                              continue;
++                              break;
+                       }
+                       nr_pages = folio_nr_pages(folio);
+                       if (nr_pages > max_pages) {
+@@ -2799,6 +2801,15 @@ static void cifs_extend_writeback(struct address_space *mapping,
+                               xas_reset(xas);
+                               break;
+                       }
++
++                      /* if file size is changing, stop extending */
++                      if (i_size_read(inode) != i_size) {
++                              folio_unlock(folio);
++                              folio_put(folio);
++                              xas_reset(xas);
++                              break;
++                      }
++
+                       if (!folio_test_dirty(folio) ||
+                           folio_test_writeback(folio)) {
+                               folio_unlock(folio);
+@@ -2934,7 +2945,8 @@ static ssize_t cifs_write_back_from_locked_folio(struct address_space *mapping,
+                       if (max_pages > 0)
+                               cifs_extend_writeback(mapping, xas, &count, start,
+-                                                    max_pages, max_len, &len);
++                                                    max_pages, max_len, &len,
++                                                    i_size);
+               }
+       }
+       len = min_t(unsigned long long, len, i_size - start);
+-- 
+2.51.0
+
diff --git a/queue-6.6/hsr-fix-supervision-frame-sending-on-hsrv0.patch b/queue-6.6/hsr-fix-supervision-frame-sending-on-hsrv0.patch
new file mode 100644 (file)
index 0000000..3991136
--- /dev/null
@@ -0,0 +1,50 @@
+From 415b90a67dcd50b38fd70278c8269b6fae5a8af0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:29:32 +0100
+Subject: hsr: Fix supervision frame sending on HSRv0
+
+From: Felix Maurer <fmaurer@redhat.com>
+
+[ Upstream commit 96a3a03abf3d8cc38cd9cb0d280235fbcf7c3f7f ]
+
+On HSRv0, no supervision frames were sent. The supervison frames were
+generated successfully, but failed the check for a sufficiently long mac
+header, i.e., at least sizeof(struct hsr_ethhdr), in hsr_fill_frame_info()
+because the mac header only contained the ethernet header.
+
+Fix this by including the HSR header in the mac header when generating HSR
+supervision frames. Note that the mac header now also includes the TLV
+fields. This matches how we set the headers on rx and also the size of
+struct hsrv0_ethhdr_sp.
+
+Reported-by: Hangbin Liu <liuhangbin@gmail.com>
+Closes: https://lore.kernel.org/netdev/aMONxDXkzBZZRfE5@fedora/
+Fixes: 9cfb5e7f0ded ("net: hsr: fix hsr_init_sk() vs network/transport headers.")
+Signed-off-by: Felix Maurer <fmaurer@redhat.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://patch.msgid.link/4354114fea9a642fe71f49aeeb6c6159d1d61840.1762876095.git.fmaurer@redhat.com
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 5514b5bedc929..70e958caa956d 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -313,6 +313,9 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+       }
+       hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag));
++      skb_set_network_header(skb, ETH_HLEN + HSR_HLEN);
++      skb_reset_mac_len(skb);
++
+       set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf));
+       set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch b/queue-6.6/net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
new file mode 100644 (file)
index 0000000..d4161f5
--- /dev/null
@@ -0,0 +1,39 @@
+From bb54828b79a9a3d235d352b424db16953bb22fa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 10:14:21 +0800
+Subject: net: fec: correct rx_bytes statistic for the case SHIFT16 is set
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit ad17e7e92a7c52ce70bb764813fcf99464f96903 ]
+
+Two additional bytes in front of each frame received into the RX FIFO if
+SHIFT16 is set, so we need to subtract the extra two bytes from pkt_len
+to correct the statistic of rx_bytes.
+
+Fixes: 3ac72b7b63d5 ("net: fec: align IP header in hardware")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20251106021421.2096585-1-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 64cd72c194783..ee0306ab97714 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1776,6 +1776,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               ndev->stats.rx_packets++;
+               pkt_len = fec16_to_cpu(bdp->cbd_datlen);
+               ndev->stats.rx_bytes += pkt_len;
++              if (fep->quirks & FEC_QUIRK_HAS_RACC)
++                      ndev->stats.rx_bytes -= 2;
+               index = fec_enet_get_bd_index(bdp, &rxq->bd);
+               page = rxq->rx_skb_info[index].page;
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch b/queue-6.6/net-handshake-fix-memory-leak-in-tls_handshake_accep.patch
new file mode 100644 (file)
index 0000000..bc31008
--- /dev/null
@@ -0,0 +1,42 @@
+From cbc01ecc0d75ccb4017be497f586e95771572334 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 14:45:11 +0000
+Subject: net/handshake: Fix memory leak in tls_handshake_accept()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit 3072f00bba764082fa41b3c3a2a7b013335353d2 ]
+
+In tls_handshake_accept(), a netlink message is allocated using
+genlmsg_new(). In the error handling path, genlmsg_cancel() is called
+to cancel the message construction, but the message itself is not freed.
+This leads to a memory leak.
+
+Fix this by calling nlmsg_free() in the error path after genlmsg_cancel()
+to release the allocated memory.
+
+Fixes: 2fd5532044a89 ("net/handshake: Add a kernel API for requesting a TLSv1.3 handshake")
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://patch.msgid.link/20251106144511.3859535-1-zilin@seu.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/tlshd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index bbfb4095ddd6b..06916a80cc130 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -254,6 +254,7 @@ static int tls_handshake_accept(struct handshake_req *req,
+ out_cancel:
+       genlmsg_cancel(msg, hdr);
++      nlmsg_free(msg);
+ out:
+       return ret;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch b/queue-6.6/net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
new file mode 100644 (file)
index 0000000..9965d29
--- /dev/null
@@ -0,0 +1,45 @@
+From 212a54f8a59a23b9fa0579d979e0b669b2d3dff8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Nov 2025 07:49:22 +0100
+Subject: net: mdio: fix resource leak in mdiobus_register_device()
+
+From: Buday Csaba <buday.csaba@prolan.hu>
+
+[ Upstream commit e6ca8f533ed41129fcf052297718f417f021cc7d ]
+
+Fix a possible leak in mdiobus_register_device() when both a
+reset-gpio and a reset-controller are present.
+Clean up the already claimed reset-gpio, when the registration of
+the reset-controller fails, so when an error code is returned, the
+device retains its state before the registration attempt.
+
+Link: https://lore.kernel.org/all/20251106144603.39053c81@kernel.org/
+Fixes: 71dd6c0dff51 ("net: phy: add support for reset-controller")
+Signed-off-by: Buday Csaba <buday.csaba@prolan.hu>
+Link: https://patch.msgid.link/4b419377f8dd7d2f63f919d0f74a336c734f8fff.1762584481.git.buday.csaba@prolan.hu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mdio_bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index f1fac89721ed9..7da30a6752bee 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -81,8 +81,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev)
+                       return err;
+               err = mdiobus_register_reset(mdiodev);
+-              if (err)
++              if (err) {
++                      gpiod_put(mdiodev->reset_gpio);
++                      mdiodev->reset_gpio = NULL;
+                       return err;
++              }
+               /* Assert the reset signal */
+               mdio_device_reset(mdiodev, 1);
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch b/queue-6.6/net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
new file mode 100644 (file)
index 0000000..824f03b
--- /dev/null
@@ -0,0 +1,58 @@
+From dfc242f9bbb0c1cdb8df5d2f376e1b12958bc0fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:51 +0200
+Subject: net/mlx5e: Fix maxrate wraparound in threshold between units
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit a7bf4d5063c7837096aab2853224eb23628514d9 ]
+
+The previous calculation used roundup() which caused an overflow for
+rates between 25.5Gbps and 26Gbps.
+For example, a rate of 25.6Gbps would result in using 100Mbps units with
+value of 256, which would overflow the 8 bits field.
+
+Simplify the upper_limit_mbps calculation by removing the
+unnecessary roundup, and adjust the comparison to use <= to correctly
+handle the boundary condition.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 8705cffc747ff..5e388cd518be9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -587,18 +587,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       struct mlx5_core_dev *mdev = priv->mdev;
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+-      __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
++      __u64 upper_limit_mbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
++      upper_limit_mbps = 255 * MLX5E_100MB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+                       max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
+                       continue;
+               }
+-              if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
++              if (maxrate->tc_maxrate[i] <= upper_limit_mbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5e-fix-potentially-misleading-debug-message.patch b/queue-6.6/net-mlx5e-fix-potentially-misleading-debug-message.patch
new file mode 100644 (file)
index 0000000..94e0c58
--- /dev/null
@@ -0,0 +1,62 @@
+From 114109c0f7fc8f840471d99219c410113e96f550 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:53 +0200
+Subject: net/mlx5e: Fix potentially misleading debug message
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 9fcc2b6c10523f7e75db6387946c86fcf19dc97e ]
+
+Change the debug message to print the correct units instead of always
+assuming Gbps, as the value can be in either 100 Mbps or 1 Gbps units.
+
+Fixes: 5da8bc3effb6 ("net/mlx5e: DCBNL, Add debug messages log")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-6-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index ca096d8bcca60..29e633e6dd3f0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -590,6 +590,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       __u64 upper_limit_mbps;
+       __u64 upper_limit_gbps;
+       int i;
++      struct {
++              int scale;
++              const char *units_str;
++      } units[] = {
++              [MLX5_100_MBPS_UNIT] = {
++                      .scale = 100,
++                      .units_str = "Mbps",
++              },
++              [MLX5_GBPS_UNIT] = {
++                      .scale = 1,
++                      .units_str = "Gbps",
++              },
++      };
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+@@ -620,8 +633,9 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       }
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+-              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %d Gbps\n",
+-                         __func__, i, max_bw_value[i]);
++              netdev_dbg(netdev, "%s: tc_%d <=> max_bw %u %s\n", __func__, i,
++                         max_bw_value[i] * units[max_bw_unit[i]].scale,
++                         units[max_bw_unit[i]].units_str);
+       }
+       return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch b/queue-6.6/net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
new file mode 100644 (file)
index 0000000..0413bcd
--- /dev/null
@@ -0,0 +1,62 @@
+From 20ff333f1148e64a40fe5d90e31c17b77a0f2276 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 11:37:52 +0200
+Subject: net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 43b27d1bd88a4bce34ec2437d103acfae9655f9e ]
+
+Add validation to reject rates exceeding 255 Gbps that would overflow
+the 8 bits max bandwidth field.
+
+Fixes: d8880795dabf ("net/mlx5e: Implement DCBNL IEEE max rate")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Nimrod Oren <noren@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1762681073-1084058-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+index 5e388cd518be9..ca096d8bcca60 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -588,11 +588,13 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+       u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
+       u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
+       __u64 upper_limit_mbps;
++      __u64 upper_limit_gbps;
+       int i;
+       memset(max_bw_value, 0, sizeof(max_bw_value));
+       memset(max_bw_unit, 0, sizeof(max_bw_unit));
+       upper_limit_mbps = 255 * MLX5E_100MB;
++      upper_limit_gbps = 255 * MLX5E_1GB;
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               if (!maxrate->tc_maxrate[i]) {
+@@ -604,10 +606,16 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
+                                                 MLX5E_100MB);
+                       max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
+                       max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
+-              } else {
++              } else if (max_bw_value[i] <= upper_limit_gbps) {
+                       max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
+                                                 MLX5E_1GB);
+                       max_bw_unit[i]  = MLX5_GBPS_UNIT;
++              } else {
++                      netdev_err(netdev,
++                                 "tc_%d maxrate %llu Kbps exceeds limit %llu\n",
++                                 i, maxrate->tc_maxrate[i],
++                                 upper_limit_gbps);
++                      return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch b/queue-6.6/net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
new file mode 100644 (file)
index 0000000..452deca
--- /dev/null
@@ -0,0 +1,59 @@
+From 383e81d69ad2a8f78f159e86ae3095306193d426 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:35 +0530
+Subject: net: sched: act_connmark: initialize struct tc_ife to fix kernel leak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit 62b656e43eaeae445a39cd8021a4f47065af4389 ]
+
+In tcf_connmark_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: 22a5dc0e5e3e ("net: sched: Introduce connmark action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-2-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_connmark.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 31719a113ed31..d90a2fa5966b7 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -195,13 +195,15 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+       const struct tcf_connmark_parms *parms;
+-      struct tc_connmark opt = {
+-              .index   = ci->tcf_index,
+-              .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+-      };
++      struct tc_connmark opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index   = ci->tcf_index;
++      opt.refcnt  = refcount_read(&ci->tcf_refcnt) - ref;
++      opt.bindcnt = atomic_read(&ci->tcf_bindcnt) - bind;
++
+       rcu_read_lock();
+       parms = rcu_dereference(ci->parms);
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch b/queue-6.6/net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
new file mode 100644 (file)
index 0000000..4e5968a
--- /dev/null
@@ -0,0 +1,70 @@
+From 2647a90f7dab248e33ea28ebbb5fa1652855f9e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:43:36 +0530
+Subject: net: sched: act_ife: initialize struct tc_ife to fix KMSAN
+ kernel-infoleak
+
+From: Ranganath V N <vnranganath.20@gmail.com>
+
+[ Upstream commit ce50039be49eea9b4cd8873ca6eccded1b4a130a ]
+
+Fix a KMSAN kernel-infoleak detected  by the syzbot .
+
+[net?] KMSAN: kernel-infoleak in __skb_datagram_iter
+
+In tcf_ife_dump(), the variable 'opt' was partially initialized using a
+designatied initializer. While the padding bytes are reamined
+uninitialized. nla_put() copies the entire structure into a
+netlink message, these uninitialized bytes leaked to userspace.
+
+Initialize the structure with memset before assigning its fields
+to ensure all members and padding are cleared prior to beign copied.
+
+This change silences the KMSAN report and prevents potential information
+leaks from the kernel memory.
+
+This fix has been tested and validated by syzbot. This patch closes the
+bug reported at the following syzkaller link and ensures no infoleak.
+
+Reported-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c85cae3350b7d486aee
+Tested-by: syzbot+0c85cae3350b7d486aee@syzkaller.appspotmail.com
+Fixes: ef6980b6becb ("introduce IFE action")
+Signed-off-by: Ranganath V N <vnranganath.20@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251109091336.9277-3-vnranganath.20@gmail.com
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ife.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index bc7611b0744c4..431921204f660 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -644,13 +644,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
+       unsigned char *b = skb_tail_pointer(skb);
+       struct tcf_ife_info *ife = to_ife(a);
+       struct tcf_ife_params *p;
+-      struct tc_ife opt = {
+-              .index = ife->tcf_index,
+-              .refcnt = refcount_read(&ife->tcf_refcnt) - ref,
+-              .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
+-      };
++      struct tc_ife opt;
+       struct tcf_t t;
++      memset(&opt, 0, sizeof(opt));
++
++      opt.index = ife->tcf_index,
++      opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref,
++      opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
++
+       spin_lock_bh(&ife->tcf_lock);
+       opt.action = ife->tcf_action;
+       p = rcu_dereference_protected(ife->params,
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-smc-fix-mismatch-between-clc-header-and-proposal.patch b/queue-6.6/net-smc-fix-mismatch-between-clc-header-and-proposal.patch
new file mode 100644 (file)
index 0000000..737035f
--- /dev/null
@@ -0,0 +1,55 @@
+From d25dbc79bf0592e41546d87cc49126d733bf4d3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 10:40:29 +0800
+Subject: net/smc: fix mismatch between CLC header and proposal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit ec33f2e5a2d0dbbfd71435209aee812fdc9369b8 ]
+
+The current CLC proposal message construction uses a mix of
+`ini->smc_type_v1/v2` and `pclc_base->hdr.typev1/v2` to decide whether
+to include optional extensions (IPv6 prefix extension for v1, and v2
+extension). This leads to a critical inconsistency: when
+`smc_clc_prfx_set()` fails - for example, in IPv6-only environments with
+only link-local addresses, or when the local IP address and the outgoing
+interface’s network address are not in the same subnet.
+
+As a result, the proposal message is assembled using the stale
+`ini->smc_type_v1` value—causing the IPv6 prefix extension to be
+included even though the header indicates v1 is not supported.
+The peer then receives a malformed CLC proposal where the header type
+does not match the payload, and immediately resets the connection.
+
+The fix ensures consistency between the CLC header flags and the actual
+payload by synchronizing `ini->smc_type_v1` with `pclc_base->hdr.typev1`
+when prefix setup fails.
+
+Fixes: 8c3dca341aea ("net/smc: build and send V2 CLC proposal")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20251107024029.88753-1-alibuda@linux.alibaba.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/smc_clc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
+index 4f485b9b31b28..2f748226f1433 100644
+--- a/net/smc/smc_clc.c
++++ b/net/smc/smc_clc.c
+@@ -883,6 +883,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
+                               return SMC_CLC_DECL_CNFERR;
+                       }
+                       pclc_base->hdr.typev1 = SMC_TYPE_N;
++                      ini->smc_type_v1 = SMC_TYPE_N;
+               } else {
+                       pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
+                       plen += sizeof(*pclc_prfx) +
+-- 
+2.51.0
+
diff --git a/queue-6.6/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch b/queue-6.6/net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch
new file mode 100644 (file)
index 0000000..ba5f3f8
--- /dev/null
@@ -0,0 +1,100 @@
+From c7eedb2c0b8379f1b8ae26fbfdbc0a5af895260a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jul 2025 09:01:54 +0000
+Subject: net_sched: act_connmark: use RCU in tcf_connmark_dump()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0d752877705c0252ef2726e4c63c5573f048951c ]
+
+Also storing tcf_action into struct tcf_connmark_parms
+makes sure there is no discrepancy in tcf_connmark_act().
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250709090204.797558-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tc_act/tc_connmark.h |  1 +
+ net/sched/act_connmark.c         | 18 ++++++++++--------
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/tc_act/tc_connmark.h b/include/net/tc_act/tc_connmark.h
+index e8dd77a967480..a5ce83f3eea4b 100644
+--- a/include/net/tc_act/tc_connmark.h
++++ b/include/net/tc_act/tc_connmark.h
+@@ -7,6 +7,7 @@
+ struct tcf_connmark_parms {
+       struct net *net;
+       u16 zone;
++      int action;
+       struct rcu_head rcu;
+ };
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 0d7aee8933c5f..31719a113ed31 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -88,7 +88,7 @@ TC_INDIRECT_SCOPE int tcf_connmark_act(struct sk_buff *skb,
+       /* using overlimits stats to count how many packets marked */
+       tcf_action_inc_overlimit_qstats(&ca->common);
+ out:
+-      return READ_ONCE(ca->tcf_action);
++      return parms->action;
+ }
+ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
+@@ -167,6 +167,8 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+       if (err < 0)
+               goto release_idr;
++      nparms->action = parm->action;
++
+       spin_lock_bh(&ci->tcf_lock);
+       goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+       oparms = rcu_replace_pointer(ci->parms, nparms, lockdep_is_held(&ci->tcf_lock));
+@@ -190,20 +192,20 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+                                   int bind, int ref)
+ {
++      const struct tcf_connmark_info *ci = to_connmark(a);
+       unsigned char *b = skb_tail_pointer(skb);
+-      struct tcf_connmark_info *ci = to_connmark(a);
++      const struct tcf_connmark_parms *parms;
+       struct tc_connmark opt = {
+               .index   = ci->tcf_index,
+               .refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
+               .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+       };
+-      struct tcf_connmark_parms *parms;
+       struct tcf_t t;
+-      spin_lock_bh(&ci->tcf_lock);
+-      parms = rcu_dereference_protected(ci->parms, lockdep_is_held(&ci->tcf_lock));
++      rcu_read_lock();
++      parms = rcu_dereference(ci->parms);
+-      opt.action = ci->tcf_action;
++      opt.action = parms->action;
+       opt.zone = parms->zone;
+       if (nla_put(skb, TCA_CONNMARK_PARMS, sizeof(opt), &opt))
+               goto nla_put_failure;
+@@ -212,12 +214,12 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+       if (nla_put_64bit(skb, TCA_CONNMARK_TM, sizeof(t), &t,
+                         TCA_CONNMARK_PAD))
+               goto nla_put_failure;
+-      spin_unlock_bh(&ci->tcf_lock);
++      rcu_read_unlock();
+       return skb->len;
+ nla_put_failure:
+-      spin_unlock_bh(&ci->tcf_lock);
++      rcu_read_unlock();
+       nlmsg_trim(skb, b);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net_sched-limit-try_bulk_dequeue_skb-batches.patch b/queue-6.6/net_sched-limit-try_bulk_dequeue_skb-batches.patch
new file mode 100644 (file)
index 0000000..7430792
--- /dev/null
@@ -0,0 +1,143 @@
+From 30357356860a72801a08c556a39098610083439d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 16:12:15 +0000
+Subject: net_sched: limit try_bulk_dequeue_skb() batches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0345552a653ce5542affeb69ac5aa52177a5199b ]
+
+After commit 100dfa74cad9 ("inet: dev_queue_xmit() llist adoption")
+I started seeing many qdisc requeues on IDPF under high TX workload.
+
+$ tc -s qd sh dev eth1 handle 1: ; sleep 1; tc -s qd sh dev eth1 handle 1:
+qdisc mq 1: root
+ Sent 43534617319319 bytes 268186451819 pkt (dropped 0, overlimits 0 requeues 3532840114)
+ backlog 1056Kb 6675p requeues 3532840114
+qdisc mq 1: root
+ Sent 43554665866695 bytes 268309964788 pkt (dropped 0, overlimits 0 requeues 3537737653)
+ backlog 781164b 4822p requeues 3537737653
+
+This is caused by try_bulk_dequeue_skb() being only limited by BQL budget.
+
+perf record -C120-239 -e qdisc:qdisc_dequeue sleep 1 ; perf script
+...
+ netperf 75332 [146]  2711.138269: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1292 skbaddr=0xff378005a1e9f200
+ netperf 75332 [146]  2711.138953: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1213 skbaddr=0xff378004d607a500
+ netperf 75330 [144]  2711.139631: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1233 skbaddr=0xff3780046be20100
+ netperf 75333 [147]  2711.140356: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1093 skbaddr=0xff37800514845b00
+ netperf 75337 [151]  2711.141037: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1353 skbaddr=0xff37800460753300
+ netperf 75337 [151]  2711.141877: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1367 skbaddr=0xff378004e72c7b00
+ netperf 75330 [144]  2711.142643: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1202 skbaddr=0xff3780045bd60000
+...
+
+This is bad because :
+
+1) Large batches hold one victim cpu for a very long time.
+
+2) Driver often hit their own TX ring limit (all slots are used).
+
+3) We call dev_requeue_skb()
+
+4) Requeues are using a FIFO (q->gso_skb), breaking qdisc ability to
+   implement FQ or priority scheduling.
+
+5) dequeue_skb() gets packets from q->gso_skb one skb at a time
+   with no xmit_more support. This is causing many spinlock games
+   between the qdisc and the device driver.
+
+Requeues were supposed to be very rare, lets keep them this way.
+
+Limit batch sizes to /proc/sys/net/core/dev_weight (default 64) as
+__qdisc_run() was designed to use.
+
+Fixes: 5772e9a3463b ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Link: https://patch.msgid.link/20251109161215.2574081-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_generic.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index b51af871a621c..1b51b3038b4bd 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -178,9 +178,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
+ static void try_bulk_dequeue_skb(struct Qdisc *q,
+                                struct sk_buff *skb,
+                                const struct netdev_queue *txq,
+-                               int *packets)
++                               int *packets, int budget)
+ {
+       int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
++      int cnt = 0;
+       while (bytelimit > 0) {
+               struct sk_buff *nskb = q->dequeue(q);
+@@ -191,8 +192,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
+               bytelimit -= nskb->len; /* covers GSO len */
+               skb->next = nskb;
+               skb = nskb;
+-              (*packets)++; /* GSO counts as one pkt */
++              if (++cnt >= budget)
++                      break;
+       }
++      (*packets) += cnt;
+       skb_mark_not_on_list(skb);
+ }
+@@ -226,7 +229,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
+  * A requeued skb (via q->gso_skb) can also be a SKB list.
+  */
+ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+-                                 int *packets)
++                                 int *packets, int budget)
+ {
+       const struct netdev_queue *txq = q->dev_queue;
+       struct sk_buff *skb = NULL;
+@@ -293,7 +296,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
+       if (skb) {
+ bulk:
+               if (qdisc_may_bulk(q))
+-                      try_bulk_dequeue_skb(q, skb, txq, packets);
++                      try_bulk_dequeue_skb(q, skb, txq, packets, budget);
+               else
+                       try_bulk_dequeue_skb_slow(q, skb, packets);
+       }
+@@ -385,7 +388,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+  *                            >0 - queue is not empty.
+  *
+  */
+-static inline bool qdisc_restart(struct Qdisc *q, int *packets)
++static inline bool qdisc_restart(struct Qdisc *q, int *packets, int budget)
+ {
+       spinlock_t *root_lock = NULL;
+       struct netdev_queue *txq;
+@@ -394,7 +397,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
+       bool validate;
+       /* Dequeue packet */
+-      skb = dequeue_skb(q, &validate, packets);
++      skb = dequeue_skb(q, &validate, packets, budget);
+       if (unlikely(!skb))
+               return false;
+@@ -412,7 +415,7 @@ void __qdisc_run(struct Qdisc *q)
+       int quota = READ_ONCE(dev_tx_weight);
+       int packets;
+-      while (qdisc_restart(q, &packets)) {
++      while (qdisc_restart(q, &packets, quota)) {
+               quota -= packets;
+               if (quota <= 0) {
+                       if (q->flags & TCQ_F_NOLOCK)
+-- 
+2.51.0
+
diff --git a/queue-6.6/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch b/queue-6.6/sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
new file mode 100644 (file)
index 0000000..95f04a3
--- /dev/null
@@ -0,0 +1,86 @@
+From 5a52dba8bcb12fcabeb2662da0a952a7e6ceaf02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 11:10:54 +0000
+Subject: sctp: prevent possible shift-out-of-bounds in
+ sctp_transport_update_rto
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 1534ff77757e44bcc4b98d0196bc5c0052fce5fa ]
+
+syzbot reported a possible shift-out-of-bounds [1]
+
+Blamed commit added rto_alpha_max and rto_beta_max set to 1000.
+
+It is unclear if some sctp users are setting very large rto_alpha
+and/or rto_beta.
+
+In order to prevent user regression, perform the test at run time.
+
+Also add READ_ONCE() annotations as sysctl values can change under us.
+
+[1]
+
+UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41
+shift exponent 64 is too large for 32-bit type 'unsigned int'
+CPU: 0 UID: 0 PID: 16704 Comm: syz.2.2320 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:94 [inline]
+  dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120
+  ubsan_epilogue lib/ubsan.c:233 [inline]
+  __ubsan_handle_shift_out_of_bounds+0x27f/0x420 lib/ubsan.c:494
+  sctp_transport_update_rto.cold+0x1c/0x34b net/sctp/transport.c:509
+  sctp_check_transmitted+0x11c4/0x1c30 net/sctp/outqueue.c:1502
+  sctp_outq_sack+0x4ef/0x1b20 net/sctp/outqueue.c:1338
+  sctp_cmd_process_sack net/sctp/sm_sideeffect.c:840 [inline]
+  sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1372 [inline]
+
+Fixes: b58537a1f562 ("net: sctp: fix permissions for rto_alpha and rto_beta knobs")
+Reported-by: syzbot+f8c46c8b2b7f6e076e99@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c81ae.050a0220.3d0d33.014e.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20251106111054.3288127-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/transport.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 31eca29b6cfbf..abb44c0ac1a0b 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -495,6 +495,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+       if (tp->rttvar || tp->srtt) {
+               struct net *net = tp->asoc->base.net;
++              unsigned int rto_beta, rto_alpha;
+               /* 6.3.1 C3) When a new RTT measurement R' is made, set
+                * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+                * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+@@ -506,10 +507,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+                * For example, assuming the default value of RTO.Alpha of
+                * 1/8, rto_alpha would be expressed as 3.
+                */
+-              tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
+-                      + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
+-              tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
+-                      + (rtt >> net->sctp.rto_alpha);
++              rto_beta = READ_ONCE(net->sctp.rto_beta);
++              if (rto_beta < 32)
++                      tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta)
++                              + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> rto_beta);
++              rto_alpha = READ_ONCE(net->sctp.rto_alpha);
++              if (rto_alpha < 32)
++                      tp->srtt = tp->srtt - (tp->srtt >> rto_alpha)
++                              + (rtt >> rto_alpha);
+       } else {
+               /* 6.3.1 C2) When the first RTT measurement R is made, set
+                * SRTT <- R, RTTVAR <- R/2.
+-- 
+2.51.0
+
diff --git a/queue-6.6/selftests-net-local_termination-wait-for-interfaces-.patch b/queue-6.6/selftests-net-local_termination-wait-for-interfaces-.patch
new file mode 100644 (file)
index 0000000..1bf1e2f
--- /dev/null
@@ -0,0 +1,48 @@
+From 9b04f3512a91858667fefa89dbb20cf8056343f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Nov 2025 17:12:09 +0100
+Subject: selftests: net: local_termination: Wait for interfaces to come up
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+[ Upstream commit 57531b3416448d1ced36a2a974a4085ec43d57b0 ]
+
+It seems that most of the tests prepare the interfaces once before the test
+run (setup_prepare()), rely on setup_wait() to wait for link and only then
+run the test(s).
+
+local_termination brings the physical interfaces down and up during test
+run but never wait for them to come up. If the auto-negotiation takes
+some seconds, first test packets are being lost, which leads to
+false-negative test results.
+
+Use setup_wait() in run_test() to make sure auto-negotiation has been
+completed after all simple_if_init() calls on physical interfaces and test
+packets will not be lost because of the race against link establishment.
+
+Fixes: 90b9566aa5cd3f ("selftests: forwarding: add a test for local_termination.sh")
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Link: https://patch.msgid.link/20251106161213.459501-1-alexander.sverdlin@siemens.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/local_termination.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/selftests/net/forwarding/local_termination.sh b/tools/testing/selftests/net/forwarding/local_termination.sh
+index 9b5a63519b949..6cde61f10fd0e 100755
+--- a/tools/testing/selftests/net/forwarding/local_termination.sh
++++ b/tools/testing/selftests/net/forwarding/local_termination.sh
+@@ -108,6 +108,8 @@ run_test()
+       local smac=$(mac_get $h1)
+       local rcv_dmac=$(mac_get $rcv_if_name)
++      setup_wait
++
+       tcpdump_start $rcv_if_name
+       mc_route_prepare $h1
+-- 
+2.51.0
+
index 3fbc1596ead51fa2c5eca4df01145ca49ccf3be2..085f4fd3bbd14712b686a6cf9315e1189b31b4d3 100644 (file)
@@ -391,3 +391,32 @@ hid-quirks-add-always_poll-quirk-for-vrs-r295-steeri.patch
 smb-server-fix-possible-memory-leak-in-smb2_read.patch
 smb-server-fix-possible-refcount-leak-in-smb2_sess_s.patch
 asoc-max98090-91-fixed-max98091-alsa-widget-powering.patch
+wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch
+selftests-net-local_termination-wait-for-interfaces-.patch
+net-fec-correct-rx_bytes-statistic-for-the-case-shif.patch
+bluetooth-mgmt-cancel-mesh-send-timer-when-hdev-remo.patch
+bluetooth-btusb-reorder-cleanup-in-btusb_disconnect-.patch
+bluetooth-6lowpan-reset-link-local-header-on-ipv6-re.patch
+bluetooth-6lowpan-fix-bdaddr_le-vs-addr_le_dev-addre.patch
+bluetooth-6lowpan-don-t-hold-spin-lock-over-sleeping.patch
+sctp-prevent-possible-shift-out-of-bounds-in-sctp_tr.patch
+net-smc-fix-mismatch-between-clc-header-and-proposal.patch
+net-handshake-fix-memory-leak-in-tls_handshake_accep.patch
+tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
+net-mdio-fix-resource-leak-in-mdiobus_register_devic.patch
+wifi-mac80211-skip-rate-verification-for-not-capture.patch
+af_unix-initialise-scc_index-in-unix_add_edge.patch
+net_sched-act_connmark-use-rcu-in-tcf_connmark_dump.patch
+net-sched-act_connmark-initialize-struct-tc_ife-to-f.patch
+net-sched-act_ife-initialize-struct-tc_ife-to-fix-km.patch
+net-mlx5e-fix-maxrate-wraparound-in-threshold-betwee.patch
+net-mlx5e-fix-wraparound-in-rate-limiting-for-values.patch
+net-mlx5e-fix-potentially-misleading-debug-message.patch
+net_sched-limit-try_bulk_dequeue_skb-batches.patch
+virtio-net-fix-incorrect-flags-recording-in-big-mode.patch
+hsr-fix-supervision-frame-sending-on-hsrv0.patch
+acpi-cppc-check-_cpc-validity-for-only-the-online-cp.patch
+acpi-cppc-perform-fast-check-switch-only-for-online-.patch
+acpi-cppc-limit-perf-ctrs-in-pcc-check-only-to-onlin.patch
+bluetooth-l2cap-export-l2cap_chan_hold-for-modules.patch
+cifs-stop-writeback-extension-when-change-of-size-is.patch
diff --git a/queue-6.6/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch b/queue-6.6/tipc-fix-use-after-free-in-tipc_mon_reinit_self.patch
new file mode 100644 (file)
index 0000000..4584f1c
--- /dev/null
@@ -0,0 +1,150 @@
+From 28f3b7033d2bfb89095e826858c572233382610e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Nov 2025 06:40:25 +0000
+Subject: tipc: Fix use-after-free in tipc_mon_reinit_self().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 0725e6afb55128be21a2ca36e9674f573ccec173 ]
+
+syzbot reported use-after-free of tipc_net(net)->monitors[]
+in tipc_mon_reinit_self(). [0]
+
+The array is protected by RTNL, but tipc_mon_reinit_self()
+iterates over it without RTNL.
+
+tipc_mon_reinit_self() is called from tipc_net_finalize(),
+which is always under RTNL except for tipc_net_finalize_work().
+
+Let's hold RTNL in tipc_net_finalize_work().
+
+[0]:
+BUG: KASAN: slab-use-after-free in __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+Read of size 1 at addr ffff88805eae1030 by task kworker/0:7/5989
+
+CPU: 0 UID: 0 PID: 5989 Comm: kworker/0:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
+Workqueue: events tipc_net_finalize_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xca/0x240 mm/kasan/report.c:482
+ kasan_report+0x118/0x150 mm/kasan/report.c:595
+ __kasan_check_byte+0x2a/0x40 mm/kasan/common.c:568
+ kasan_check_byte include/linux/kasan.h:399 [inline]
+ lock_acquire+0x8d/0x360 kernel/locking/lockdep.c:5842
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
+ rtlock_slowlock kernel/locking/rtmutex.c:1894 [inline]
+ rwbase_rtmutex_lock_state kernel/locking/spinlock_rt.c:160 [inline]
+ rwbase_write_lock+0xd3/0x7e0 kernel/locking/rwbase_rt.c:244
+ rt_write_lock+0x76/0x110 kernel/locking/spinlock_rt.c:243
+ write_lock_bh include/linux/rwlock_rt.h:99 [inline]
+ tipc_mon_reinit_self+0x79/0x430 net/tipc/monitor.c:718
+ tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
+ process_one_work kernel/workqueue.c:3236 [inline]
+ process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3319
+ worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
+ kthread+0x70e/0x8a0 kernel/kthread.c:463
+ ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+Allocated by task 6089:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __kmalloc_cache_noprof+0x1a8/0x320 mm/slub.c:4407
+ kmalloc_noprof include/linux/slab.h:905 [inline]
+ kzalloc_noprof include/linux/slab.h:1039 [inline]
+ tipc_mon_create+0xc3/0x4d0 net/tipc/monitor.c:657
+ tipc_enable_bearer net/tipc/bearer.c:357 [inline]
+ __tipc_nl_bearer_enable+0xe16/0x13f0 net/tipc/bearer.c:1047
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:371 [inline]
+ tipc_nl_compat_doit+0x3bc/0x5f0 net/tipc/netlink_compat.c:393
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:-1 [inline]
+ tipc_nl_compat_recv+0x83c/0xbe0 net/tipc/netlink_compat.c:1321
+ genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
+ netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
+ netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x21c/0x270 net/socket.c:729
+ ____sys_sendmsg+0x508/0x820 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 6088:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
+ kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
+ poison_slab_object mm/kasan/common.c:243 [inline]
+ __kasan_slab_free+0x5b/0x80 mm/kasan/common.c:275
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2422 [inline]
+ slab_free mm/slub.c:4695 [inline]
+ kfree+0x195/0x550 mm/slub.c:4894
+ tipc_l2_device_event+0x380/0x650 net/tipc/bearer.c:-1
+ notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
+ call_netdevice_notifiers_extack net/core/dev.c:2267 [inline]
+ call_netdevice_notifiers net/core/dev.c:2281 [inline]
+ unregister_netdevice_many_notify+0x14d7/0x1fe0 net/core/dev.c:12166
+ unregister_netdevice_many net/core/dev.c:12229 [inline]
+ unregister_netdevice_queue+0x33c/0x380 net/core/dev.c:12073
+ unregister_netdevice include/linux/netdevice.h:3385 [inline]
+ __tun_detach+0xe4d/0x1620 drivers/net/tun.c:621
+ tun_detach drivers/net/tun.c:637 [inline]
+ tun_chr_close+0x10d/0x1c0 drivers/net/tun.c:3433
+ __fput+0x458/0xa80 fs/file_table.c:468
+ task_work_run+0x1d4/0x260 kernel/task_work.c:227
+ resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
+ exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:43
+ exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
+ syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline]
+ syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline]
+ do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 46cb01eeeb86 ("tipc: update mon's self addr when node addr generated")
+Reported-by: syzbot+d7dad7fd4b3921104957@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/690c323a.050a0220.baf87.007f.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251107064038.2361188-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/net.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/tipc/net.c b/net/tipc/net.c
+index 0e95572e56b41..7e65d0b0c4a8d 100644
+--- a/net/tipc/net.c
++++ b/net/tipc/net.c
+@@ -145,7 +145,9 @@ void tipc_net_finalize_work(struct work_struct *work)
+ {
+       struct tipc_net *tn = container_of(work, struct tipc_net, work);
++      rtnl_lock();
+       tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
++      rtnl_unlock();
+ }
+ void tipc_net_stop(struct net *net)
+-- 
+2.51.0
+
diff --git a/queue-6.6/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch b/queue-6.6/virtio-net-fix-incorrect-flags-recording-in-big-mode.patch
new file mode 100644 (file)
index 0000000..e38b0c8
--- /dev/null
@@ -0,0 +1,72 @@
+From 517d347ea2ed5a044f154f04fa7ee59be2bbae78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Nov 2025 17:08:28 +0800
+Subject: virtio-net: fix incorrect flags recording in big mode
+
+From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+
+[ Upstream commit 0eff2eaa5322b5b141ff5d5ded26fac4a52b5f7b ]
+
+The purpose of commit 703eec1b2422 ("virtio_net: fixing XDP for fully
+checksummed packets handling") is to record the flags in advance, as
+their value may be overwritten in the XDP case. However, the flags
+recorded under big mode are incorrect, because in big mode, the passed
+buf does not point to the rx buffer, but rather to the page of the
+submitted buffer. This commit fixes this issue.
+
+For the small mode, the commit c11a49d58ad2 ("virtio_net: Fix mismatched
+buf address when unmapping for small packets") fixed it.
+
+Tested-by: Alyssa Ross <hi@alyssa.is>
+Fixes: 703eec1b2422 ("virtio_net: fixing XDP for fully checksummed packets handling")
+Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Link: https://patch.msgid.link/20251111090828.23186-1-xuanzhuo@linux.alibaba.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/virtio_net.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index fd5663075bd77..caae11ba2f8be 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -1821,22 +1821,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
+               return;
+       }
+-      /* 1. Save the flags early, as the XDP program might overwrite them.
++      /* About the flags below:
++       * 1. Save the flags early, as the XDP program might overwrite them.
+        * These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID
+        * stay valid after XDP processing.
+        * 2. XDP doesn't work with partially checksummed packets (refer to
+        * virtnet_xdp_set()), so packets marked as
+        * VIRTIO_NET_HDR_F_NEEDS_CSUM get dropped during XDP processing.
+        */
+-      flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+-      if (vi->mergeable_rx_bufs)
++      if (vi->mergeable_rx_bufs) {
++              flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+               skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
+                                       stats);
+-      else if (vi->big_packets)
++      } else if (vi->big_packets) {
++              void *p = page_address((struct page *)buf);
++
++              flags = ((struct virtio_net_common_hdr *)p)->hdr.flags;
+               skb = receive_big(dev, vi, rq, buf, len, stats);
+-      else
++      } else {
++              flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+               skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit, stats);
++      }
+       if (unlikely(!skb))
+               return;
+-- 
+2.51.0
+
diff --git a/queue-6.6/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch b/queue-6.6/wifi-ath11k-zero-init-info-status-in-wmi_process_mgm.patch
new file mode 100644 (file)
index 0000000..a18f6d1
--- /dev/null
@@ -0,0 +1,53 @@
+From d1c7bc9cb4b5b649e597e98602fb99d0fe9a109b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Nov 2025 09:39:57 +0100
+Subject: wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp()
+
+From: Nicolas Escande <nico.escande@gmail.com>
+
+[ Upstream commit 9065b968752334f972e0d48e50c4463a172fc2a7 ]
+
+When reporting tx completion using ieee80211_tx_status_xxx() family of
+functions, the status part of the struct ieee80211_tx_info nested in the
+skb is used to report things like transmit rates & retry count to mac80211
+
+On the TX data path, this is correctly memset to 0 before calling
+ieee80211_tx_status_ext(), but on the tx mgmt path this was not done.
+
+This leads to mac80211 treating garbage values as valid transmit counters
+(like tx retries for example) and accounting them as real statistics that
+makes their way to userland via station dump.
+
+The same issue was resolved in ath12k by commit 9903c0986f78 ("wifi:
+ath12k: Add memset and update default rate value in wmi tx completion")
+
+Tested-on: QCN9074 PCI WLAN.HK.2.9.0.1-01977-QCAHKSWPL_SILICONZ-1
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
+Link: https://patch.msgid.link/20251104083957.717825-1-nico.escande@gmail.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 31dbabc9eaf33..16687223bdcba 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -5841,6 +5841,9 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar,
+       dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+       info = IEEE80211_SKB_CB(msdu);
++      memset(&info->status, 0, sizeof(info->status));
++      info->status.rates[0].idx = -1;
++
+       if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) &&
+           !tx_compl_param->status) {
+               info->flags |= IEEE80211_TX_STAT_ACK;
+-- 
+2.51.0
+
diff --git a/queue-6.6/wifi-mac80211-skip-rate-verification-for-not-capture.patch b/queue-6.6/wifi-mac80211-skip-rate-verification-for-not-capture.patch
new file mode 100644 (file)
index 0000000..0e20f30
--- /dev/null
@@ -0,0 +1,48 @@
+From 39e572516a0bb0e41fd4b0b3cc4da92d6045e3ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Nov 2025 14:26:18 +0200
+Subject: wifi: mac80211: skip rate verification for not captured PSDUs
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 7fe0d21f5633af8c3fab9f0ef0706c6156623484 ]
+
+If for example the sniffer did not follow any AIDs in an MU frame, then
+some of the information may not be filled in or is even expected to be
+invalid. As an example, in that case it is expected that Nss is zero.
+
+Fixes: 2ff5e52e7836 ("radiotap: add 0-length PSDU "not captured" type")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20251110142554.83a2858ee15b.I9f78ce7984872f474722f9278691ae16378f0a3e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 164c6e8049826..e6a0a65d4d43a 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -5341,10 +5341,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+       if (WARN_ON(!local->started))
+               goto drop;
+-      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) {
++      if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) &&
++                 !(status->flag & RX_FLAG_NO_PSDU &&
++                   status->zero_length_psdu_type ==
++                   IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) {
+               /*
+-               * Validate the rate, unless a PLCP error means that
+-               * we probably can't have a valid rate here anyway.
++               * Validate the rate, unless there was a PLCP error which may
++               * have an invalid rate or the PSDU was not capture and may be
++               * missing rate information.
+                */
+               switch (status->encoding) {
+-- 
+2.51.0
+