]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees
authorSasha Levin <sashal@kernel.org>
Sat, 30 Aug 2025 16:55:51 +0000 (12:55 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 30 Aug 2025 16:55:51 +0000 (12:55 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
227 files changed:
queue-5.10/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch [new file with mode: 0644]
queue-5.10/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch [new file with mode: 0644]
queue-5.10/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch [new file with mode: 0644]
queue-5.10/net-dlink-fix-multicast-stats-being-counted-incorrec.patch [new file with mode: 0644]
queue-5.10/net-ipv4-fix-regression-in-local-broadcast-routes.patch [new file with mode: 0644]
queue-5.10/net-mlx5e-set-local-xoff-after-fw-update.patch [new file with mode: 0644]
queue-5.10/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch [new file with mode: 0644]
queue-5.10/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch [new file with mode: 0644]
queue-5.10/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch [new file with mode: 0644]
queue-5.10/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch [new file with mode: 0644]
queue-5.10/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch [new file with mode: 0644]
queue-5.10/series
queue-5.15/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch [new file with mode: 0644]
queue-5.15/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch [new file with mode: 0644]
queue-5.15/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch [new file with mode: 0644]
queue-5.15/net-dlink-fix-multicast-stats-being-counted-incorrec.patch [new file with mode: 0644]
queue-5.15/net-ipv4-fix-regression-in-local-broadcast-routes.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-set-local-xoff-after-fw-update.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch [new file with mode: 0644]
queue-5.15/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch [new file with mode: 0644]
queue-5.15/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch [new file with mode: 0644]
queue-5.15/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch [new file with mode: 0644]
queue-5.15/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch [new file with mode: 0644]
queue-5.15/series
queue-5.4/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch [new file with mode: 0644]
queue-5.4/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch [new file with mode: 0644]
queue-5.4/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch [new file with mode: 0644]
queue-5.4/net-atm-remove-the-atmdev_ops-get-set-sockopt-method.patch [new file with mode: 0644]
queue-5.4/net-dlink-fix-multicast-stats-being-counted-incorrec.patch [new file with mode: 0644]
queue-5.4/net-ipv4-fix-regression-in-local-broadcast-routes.patch [new file with mode: 0644]
queue-5.4/net-mlx5e-set-local-xoff-after-fw-update.patch [new file with mode: 0644]
queue-5.4/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch [new file with mode: 0644]
queue-5.4/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch [new file with mode: 0644]
queue-5.4/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch [new file with mode: 0644]
queue-5.4/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch [new file with mode: 0644]
queue-5.4/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch [new file with mode: 0644]
queue-5.4/series
queue-6.1/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch [new file with mode: 0644]
queue-6.1/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch [new file with mode: 0644]
queue-6.1/bluetooth-hci_event-mark-connection-as-closed-during.patch [new file with mode: 0644]
queue-6.1/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch [new file with mode: 0644]
queue-6.1/bluetooth-hci_sync-fix-set_local_name-race-condition.patch [new file with mode: 0644]
queue-6.1/drm-msm-defer-fd_install-in-submit-ioctl.patch [new file with mode: 0644]
queue-6.1/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch [new file with mode: 0644]
queue-6.1/hid-input-rename-hidinput_set_battery_charge_status.patch [new file with mode: 0644]
queue-6.1/hid-input-report-battery-status-changes-immediately.patch [new file with mode: 0644]
queue-6.1/net-dlink-fix-multicast-stats-being-counted-incorrec.patch [new file with mode: 0644]
queue-6.1/net-ipv4-fix-regression-in-local-broadcast-routes.patch [new file with mode: 0644]
queue-6.1/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-set-local-xoff-after-fw-update.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch [new file with mode: 0644]
queue-6.1/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch [new file with mode: 0644]
queue-6.1/net-rose-convert-use-field-to-refcount_t.patch [new file with mode: 0644]
queue-6.1/net-rose-include-node-references-in-rose_neigh-refco.patch [new file with mode: 0644]
queue-6.1/net-rose-split-remove-and-free-operations-in-rose_re.patch [new file with mode: 0644]
queue-6.1/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch [new file with mode: 0644]
queue-6.1/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch [new file with mode: 0644]
queue-6.1/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch [new file with mode: 0644]
queue-6.1/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch [new file with mode: 0644]
queue-6.1/series
queue-6.12/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_event-mark-connection-as-closed-during.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_sync-fix-set_local_name-race-condition.patch [new file with mode: 0644]
queue-6.12/bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch [new file with mode: 0644]
queue-6.12/bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch [new file with mode: 0644]
queue-6.12/bnxt_en-fix-stats-context-reservation-logic.patch [new file with mode: 0644]
queue-6.12/drm-mediatek-add-error-handling-for-old-state-crtc-i.patch [new file with mode: 0644]
queue-6.12/drm-msm-defer-fd_install-in-submit-ioctl.patch [new file with mode: 0644]
queue-6.12/drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch [new file with mode: 0644]
queue-6.12/drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch [new file with mode: 0644]
queue-6.12/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch [new file with mode: 0644]
queue-6.12/drm-nouveau-remove-unused-memory-target-test.patch [new file with mode: 0644]
queue-6.12/drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch [new file with mode: 0644]
queue-6.12/drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch [new file with mode: 0644]
queue-6.12/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch [new file with mode: 0644]
queue-6.12/efi-stmm-fix-incorrect-buffer-allocation-method.patch [new file with mode: 0644]
queue-6.12/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch [new file with mode: 0644]
queue-6.12/fbnic-move-phylink-resume-out-of-service_task-and-in.patch [new file with mode: 0644]
queue-6.12/hid-input-rename-hidinput_set_battery_charge_status.patch [new file with mode: 0644]
queue-6.12/hid-input-report-battery-status-changes-immediately.patch [new file with mode: 0644]
queue-6.12/hv_netvsc-link-queues-to-napis.patch [new file with mode: 0644]
queue-6.12/ice-don-t-leave-device-non-functional-if-tx-schedule.patch [new file with mode: 0644]
queue-6.12/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch [new file with mode: 0644]
queue-6.12/ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch [new file with mode: 0644]
queue-6.12/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch [new file with mode: 0644]
queue-6.12/net-dlink-fix-multicast-stats-being-counted-incorrec.patch [new file with mode: 0644]
queue-6.12/net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch [new file with mode: 0644]
queue-6.12/net-ipv4-fix-regression-in-local-broadcast-routes.patch [new file with mode: 0644]
queue-6.12/net-macb-disable-clocks-once.patch [new file with mode: 0644]
queue-6.12/net-macb-fix-unregister_netdev-call-order-in-macb_re.patch [new file with mode: 0644]
queue-6.12/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch [new file with mode: 0644]
queue-6.12/net-mlx5-nack-sync-reset-when-sfs-are-present.patch [new file with mode: 0644]
queue-6.12/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-set-local-xoff-after-fw-update.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch [new file with mode: 0644]
queue-6.12/net-rose-convert-use-field-to-refcount_t.patch [new file with mode: 0644]
queue-6.12/net-rose-include-node-references-in-rose_neigh-refco.patch [new file with mode: 0644]
queue-6.12/net-rose-split-remove-and-free-operations-in-rose_re.patch [new file with mode: 0644]
queue-6.12/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch [new file with mode: 0644]
queue-6.12/net-stmmac-xgmac-correct-supported-speed-modes.patch [new file with mode: 0644]
queue-6.12/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch [new file with mode: 0644]
queue-6.12/of-reserved_mem-restructure-call-site-for-dma_contig.patch [new file with mode: 0644]
queue-6.12/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch [new file with mode: 0644]
queue-6.12/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch [new file with mode: 0644]
queue-6.12/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch [new file with mode: 0644]
queue-6.12/series
queue-6.16/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch [new file with mode: 0644]
queue-6.16/block-validate-qos-before-calling-__rq_qos_done_bio.patch [new file with mode: 0644]
queue-6.16/bluetooth-hci_conn-make-unacked-packet-handling-more.patch [new file with mode: 0644]
queue-6.16/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch [new file with mode: 0644]
queue-6.16/bluetooth-hci_event-disconnect-device-when-big-sync-.patch [new file with mode: 0644]
queue-6.16/bluetooth-hci_event-mark-connection-as-closed-during.patch [new file with mode: 0644]
queue-6.16/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch [new file with mode: 0644]
queue-6.16/bluetooth-hci_sync-fix-set_local_name-race-condition.patch [new file with mode: 0644]
queue-6.16/bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch [new file with mode: 0644]
queue-6.16/bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch [new file with mode: 0644]
queue-6.16/bnxt_en-fix-stats-context-reservation-logic.patch [new file with mode: 0644]
queue-6.16/drm-mediatek-add-error-handling-for-old-state-crtc-i.patch [new file with mode: 0644]
queue-6.16/drm-mediatek-mtk_hdmi-fix-inverted-parameters-in-som.patch [new file with mode: 0644]
queue-6.16/drm-msm-defer-fd_install-in-submit-ioctl.patch [new file with mode: 0644]
queue-6.16/drm-msm-dpu-add-a-null-ptr-check-for-dpu_encoder_nee.patch [new file with mode: 0644]
queue-6.16/drm-msm-dpu-correct-dpu_plane_virtual_atomic_check.patch [new file with mode: 0644]
queue-6.16/drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch [new file with mode: 0644]
queue-6.16/drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch [new file with mode: 0644]
queue-6.16/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch [new file with mode: 0644]
queue-6.16/drm-nouveau-remove-unused-memory-target-test.patch [new file with mode: 0644]
queue-6.16/drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch [new file with mode: 0644]
queue-6.16/drm-xe-vm-don-t-pin-the-vm_resv-during-validation.patch [new file with mode: 0644]
queue-6.16/drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch [new file with mode: 0644]
queue-6.16/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch [new file with mode: 0644]
queue-6.16/efi-stmm-fix-incorrect-buffer-allocation-method.patch [new file with mode: 0644]
queue-6.16/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch [new file with mode: 0644]
queue-6.16/fbnic-move-phylink-resume-out-of-service_task-and-in.patch [new file with mode: 0644]
queue-6.16/hid-input-rename-hidinput_set_battery_charge_status.patch [new file with mode: 0644]
queue-6.16/hid-input-report-battery-status-changes-immediately.patch [new file with mode: 0644]
queue-6.16/hid-intel-thc-hid-intel-quicki2c-enhance-driver-re-i.patch [new file with mode: 0644]
queue-6.16/hid-intel-thc-hid-intel-quicki2c-fix-acpi-dsd-icrs-i.patch [new file with mode: 0644]
queue-6.16/hid-intel-thc-hid-intel-thc-fix-incorrect-pointer-ar.patch [new file with mode: 0644]
queue-6.16/ice-don-t-leave-device-non-functional-if-tx-schedule.patch [new file with mode: 0644]
queue-6.16/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch [new file with mode: 0644]
queue-6.16/ice-fix-null-pointer-dereference-in-ice_unplug_aux_d.patch [new file with mode: 0644]
queue-6.16/ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch [new file with mode: 0644]
queue-6.16/idpf-add-support-for-tx-refillqs-in-flow-scheduling-.patch [new file with mode: 0644]
queue-6.16/idpf-replace-flow-scheduling-buffer-ring-with-buffer.patch [new file with mode: 0644]
queue-6.16/idpf-simplify-and-fix-splitq-tx-packet-rollback-erro.patch [new file with mode: 0644]
queue-6.16/idpf-stop-tx-if-there-are-insufficient-buffer-resour.patch [new file with mode: 0644]
queue-6.16/io_uring-kbuf-always-use-read_once-to-read-ring-prov.patch [new file with mode: 0644]
queue-6.16/io_uring-kbuf-fix-signedness-in-this_len-calculation.patch [new file with mode: 0644]
queue-6.16/ixgbe-fix-ixgbe_orom_civd_info-struct-layout.patch [new file with mode: 0644]
queue-6.16/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch [new file with mode: 0644]
queue-6.16/misdn-hfcpci-fix-warning-when-deleting-uninitialized.patch [new file with mode: 0644]
queue-6.16/net-dlink-fix-multicast-stats-being-counted-incorrec.patch [new file with mode: 0644]
queue-6.16/net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch [new file with mode: 0644]
queue-6.16/net-ipv4-fix-regression-in-local-broadcast-routes.patch [new file with mode: 0644]
queue-6.16/net-macb-disable-clocks-once.patch [new file with mode: 0644]
queue-6.16/net-macb-fix-offset-error-in-gem_update_stats.patch [new file with mode: 0644]
queue-6.16/net-macb-fix-unregister_netdev-call-order-in-macb_re.patch [new file with mode: 0644]
queue-6.16/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch [new file with mode: 0644]
queue-6.16/net-mlx5-hws-fix-memory-leak-in-hws_action_get_share.patch [new file with mode: 0644]
queue-6.16/net-mlx5-hws-fix-memory-leak-in-hws_pool_buddy_init-.patch [new file with mode: 0644]
queue-6.16/net-mlx5-hws-fix-pattern-destruction-in-mlx5hws_pat_.patch [new file with mode: 0644]
queue-6.16/net-mlx5-hws-fix-uninitialized-variables-in-mlx5hws_.patch [new file with mode: 0644]
queue-6.16/net-mlx5-nack-sync-reset-when-sfs-are-present.patch [new file with mode: 0644]
queue-6.16/net-mlx5-prevent-flow-steering-mode-changes-in-switc.patch [new file with mode: 0644]
queue-6.16/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch [new file with mode: 0644]
queue-6.16/net-mlx5e-set-local-xoff-after-fw-update.patch [new file with mode: 0644]
queue-6.16/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch [new file with mode: 0644]
queue-6.16/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch [new file with mode: 0644]
queue-6.16/net-rose-convert-use-field-to-refcount_t.patch [new file with mode: 0644]
queue-6.16/net-rose-include-node-references-in-rose_neigh-refco.patch [new file with mode: 0644]
queue-6.16/net-rose-split-remove-and-free-operations-in-rose_re.patch [new file with mode: 0644]
queue-6.16/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch [new file with mode: 0644]
queue-6.16/net-stmmac-xgmac-correct-supported-speed-modes.patch [new file with mode: 0644]
queue-6.16/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch [new file with mode: 0644]
queue-6.16/octeontx2-af-fix-nix-x2p-calibration-failures.patch [new file with mode: 0644]
queue-6.16/octeontx2-set-appropriate-pf-vf-masks-and-shifts-bas.patch [new file with mode: 0644]
queue-6.16/octeontx2-vf-fix-max-packet-length-errors.patch [new file with mode: 0644]
queue-6.16/of-reserved_mem-restructure-call-site-for-dma_contig.patch [new file with mode: 0644]
queue-6.16/page_pool-fix-incorrect-mp_ops-error-handling.patch [new file with mode: 0644]
queue-6.16/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch [new file with mode: 0644]
queue-6.16/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch [new file with mode: 0644]
queue-6.16/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch [new file with mode: 0644]
queue-6.16/series
queue-6.6/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch [new file with mode: 0644]
queue-6.6/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch [new file with mode: 0644]
queue-6.6/bluetooth-hci_event-mark-connection-as-closed-during.patch [new file with mode: 0644]
queue-6.6/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch [new file with mode: 0644]
queue-6.6/bluetooth-hci_sync-fix-set_local_name-race-condition.patch [new file with mode: 0644]
queue-6.6/drm-msm-defer-fd_install-in-submit-ioctl.patch [new file with mode: 0644]
queue-6.6/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch [new file with mode: 0644]
queue-6.6/drm-nouveau-remove-unused-memory-target-test.patch [new file with mode: 0644]
queue-6.6/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch [new file with mode: 0644]
queue-6.6/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch [new file with mode: 0644]
queue-6.6/hid-input-rename-hidinput_set_battery_charge_status.patch [new file with mode: 0644]
queue-6.6/hid-input-report-battery-status-changes-immediately.patch [new file with mode: 0644]
queue-6.6/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch [new file with mode: 0644]
queue-6.6/ice-gather-page_count-s-of-each-frag-right-before-xd.patch [new file with mode: 0644]
queue-6.6/ice-introduce-ice_xdp_buff.patch [new file with mode: 0644]
queue-6.6/ice-stop-storing-xdp-verdict-within-ice_rx_buf.patch [new file with mode: 0644]
queue-6.6/net-dlink-fix-multicast-stats-being-counted-incorrec.patch [new file with mode: 0644]
queue-6.6/net-ipv4-fix-regression-in-local-broadcast-routes.patch [new file with mode: 0644]
queue-6.6/net-mlx5-add-device-cap-for-supporting-hot-reset-in-.patch [new file with mode: 0644]
queue-6.6/net-mlx5-add-support-for-sync-reset-using-hot-reset.patch [new file with mode: 0644]
queue-6.6/net-mlx5-call-mlx5_sf_id_erase-once-in-mlx5_sf_deall.patch [new file with mode: 0644]
queue-6.6/net-mlx5-convert-sf-port_indices-xarray-to-function_.patch [new file with mode: 0644]
queue-6.6/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch [new file with mode: 0644]
queue-6.6/net-mlx5-nack-sync-reset-when-sfs-are-present.patch [new file with mode: 0644]
queue-6.6/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch [new file with mode: 0644]
queue-6.6/net-mlx5-use-devlink-port-pointer-to-get-the-pointer.patch [new file with mode: 0644]
queue-6.6/net-mlx5e-set-local-xoff-after-fw-update.patch [new file with mode: 0644]
queue-6.6/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch [new file with mode: 0644]
queue-6.6/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch [new file with mode: 0644]
queue-6.6/net-rose-convert-use-field-to-refcount_t.patch [new file with mode: 0644]
queue-6.6/net-rose-include-node-references-in-rose_neigh-refco.patch [new file with mode: 0644]
queue-6.6/net-rose-split-remove-and-free-operations-in-rose_re.patch [new file with mode: 0644]
queue-6.6/net-stmmac-rename-phylink_get_caps-callback-to-updat.patch [new file with mode: 0644]
queue-6.6/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch [new file with mode: 0644]
queue-6.6/net-stmmac-xgmac-correct-supported-speed-modes.patch [new file with mode: 0644]
queue-6.6/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch [new file with mode: 0644]
queue-6.6/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch [new file with mode: 0644]
queue-6.6/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch [new file with mode: 0644]
queue-6.6/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-5.10/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch b/queue-5.10/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
new file mode 100644 (file)
index 0000000..f848820
--- /dev/null
@@ -0,0 +1,192 @@
+From feb6a428abd6148be60e7e5789455671b7111e0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+  struct atmtcp_control {
+       struct atmtcp_hdr hdr;  /* must be first */
+  ...
+       atm_kptr_t vcc;         /* both directions */
+  ...
+  } __ATM_API_ALIGN;
+
+  typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+  1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+  2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS:  00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 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+0x19b/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
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c   | 17 ++++++++++++++---
+ include/linux/atmdev.h |  1 +
+ net/atm/common.c       | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index ff558908897f3..9c83fb29b2f1b 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+         return NULL;
+ }
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++      struct atmtcp_hdr *hdr;
++
++      if (skb->len < sizeof(struct atmtcp_hdr))
++              return -EINVAL;
++
++      hdr = (struct atmtcp_hdr *)skb->data;
++      if (hdr->length == ATMTCP_HDR_MAGIC)
++              return -EINVAL;
++
++      return 0;
++}
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+       struct sk_buff *new_skb;
+       int result = 0;
+-      if (skb->len < sizeof(struct atmtcp_hdr))
+-              goto done;
+-
+       dev = vcc->dev_data;
+       hdr = (struct atmtcp_hdr *) skb->data;
+       if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+       .close          = atmtcp_c_close,
++      .pre_send       = atmtcp_c_pre_send,
+       .send           = atmtcp_c_send
+ };
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index bc24d19ec2b37..8cbb992f6293c 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
++      int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+       void (*phy_put)(struct atm_dev *dev,unsigned char value,
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 930eb302cd10f..38ed7b985f655 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+       skb->dev = NULL; /* for paths shared with net_device interfaces */
+       if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+-              atm_return_tx(vcc, skb);
+-              kfree_skb(skb);
+               error = -EFAULT;
+-              goto out;
++              goto free_skb;
+       }
+       if (eff != size)
+               memset(skb->data + size, 0, eff-size);
++
++      if (vcc->dev->ops->pre_send) {
++              error = vcc->dev->ops->pre_send(vcc, skb);
++              if (error)
++                      goto free_skb;
++      }
++
+       error = vcc->dev->ops->send(vcc, skb);
+       error = error ? error : size;
+ out:
+       release_sock(sk);
+       return error;
++free_skb:
++      atm_return_tx(vcc, skb);
++      kfree_skb(skb);
++      goto out;
+ }
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+-- 
+2.50.1
+
diff --git a/queue-5.10/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch b/queue-5.10/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
new file mode 100644 (file)
index 0000000..2312ebc
--- /dev/null
@@ -0,0 +1,47 @@
+From c32f5b807b15b29b9216e66837ae79ead6b3d1ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 7f26c1aab9a06..c6dbb4aebfbc1 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3811,7 +3811,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+               if (!conn)
+                       continue;
+-              conn->sent -= count;
++              /* Check if there is really enough packets outstanding before
++               * attempting to decrease the sent counter otherwise it could
++               * underflow..
++               */
++              if (conn->sent >= count) {
++                      conn->sent -= count;
++              } else {
++                      bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++                                  conn, conn->sent, count);
++                      conn->sent = 0;
++              }
+               switch (conn->type) {
+               case ACL_LINK:
+-- 
+2.50.1
+
diff --git a/queue-5.10/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch b/queue-5.10/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
new file mode 100644 (file)
index 0000000..4a2c47b
--- /dev/null
@@ -0,0 +1,77 @@
+From 46f2e902822a9af3b36ff11a7d7ec6f19e059c7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+  BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+  Call trace:
+   kasan_check_range+0xe8/0x190
+   __asan_loadN+0x1c/0x28
+   memcmp+0x98/0xd0
+   efivarfs_d_compare+0x68/0xd8
+   __d_lookup_rcu_op_compare+0x178/0x218
+   __d_lookup_rcu+0x1f8/0x228
+   d_alloc_parallel+0x150/0x648
+   lookup_open.isra.0+0x5f0/0x8d0
+   open_last_lookups+0x264/0x828
+   path_openat+0x130/0x3f8
+   do_filp_open+0x114/0x248
+   do_sys_openat2+0x340/0x3c0
+   __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+  T1                   T2
+  lookup_open
+   ->lookup
+    simple_lookup
+     d_add
+     // invalid dentry is added to hash list
+
+                       lookup_open
+                        d_alloc_parallel
+                         __d_lookup_rcu
+                          __d_lookup_rcu_op_compare
+                           hlist_bl_for_each_entry_rcu
+                           // invalid dentry can be retrieved
+                            ->d_compare
+                             efivarfs_d_compare
+                             // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 99d002438008b..124db520b2bd6 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -47,6 +47,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+       int guid = len - EFI_VARIABLE_GUID_LEN;
++      /* Parallel lookups may produce a temporary invalid filename */
++      if (guid <= 0)
++              return 1;
++
+       if (name->len != len)
+               return 1;
+-- 
+2.50.1
+
diff --git a/queue-5.10/net-dlink-fix-multicast-stats-being-counted-incorrec.patch b/queue-5.10/net-dlink-fix-multicast-stats-being-counted-incorrec.patch
new file mode 100644 (file)
index 0000000..12a6aa1
--- /dev/null
@@ -0,0 +1,46 @@
+From 3fe83a12405c50dbc0093f021716355383bb1239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index b7f992103da3c..af1e96e0209fc 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1095,7 +1095,7 @@ get_stats (struct net_device *dev)
+       dev->stats.rx_bytes += dr32(OctetRcvOk);
+       dev->stats.tx_bytes += dr32(OctetXmtOk);
+-      dev->stats.multicast = dr32(McstFramesRcvdOk);
++      dev->stats.multicast += dr32(McstFramesRcvdOk);
+       dev->stats.collisions += dr32(SingleColFrames)
+                            +  dr32(MultiColFrames);
+-- 
+2.50.1
+
diff --git a/queue-5.10/net-ipv4-fix-regression-in-local-broadcast-routes.patch b/queue-5.10/net-ipv4-fix-regression-in-local-broadcast-routes.patch
new file mode 100644 (file)
index 0000000..5cd7e2a
--- /dev/null
@@ -0,0 +1,57 @@
+From 8c68cde06a0e806946122a7dc33ae099c05b6902 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 7c4479adbf325..fbaed08600f0f 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2452,12 +2452,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+                   !netif_is_l3_master(dev_out))
+                       return ERR_PTR(-EINVAL);
+-      if (ipv4_is_lbcast(fl4->daddr))
++      if (ipv4_is_lbcast(fl4->daddr)) {
+               type = RTN_BROADCAST;
+-      else if (ipv4_is_multicast(fl4->daddr))
++
++              /* reset fi to prevent gateway resolution */
++              fi = NULL;
++      } else if (ipv4_is_multicast(fl4->daddr)) {
+               type = RTN_MULTICAST;
+-      else if (ipv4_is_zeronet(fl4->daddr))
++      } else if (ipv4_is_zeronet(fl4->daddr)) {
+               return ERR_PTR(-EINVAL);
++      }
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+-- 
+2.50.1
+
diff --git a/queue-5.10/net-mlx5e-set-local-xoff-after-fw-update.patch b/queue-5.10/net-mlx5e-set-local-xoff-after-fw-update.patch
new file mode 100644 (file)
index 0000000..0f527c4
--- /dev/null
@@ -0,0 +1,50 @@
+From d0049c813edf1f7090ac77f2be2f1367ac0478bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+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 c9d5d8d93994d..7899a7230299d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -346,7 +346,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+               if (err)
+                       return err;
+       }
+-      priv->dcbx.xoff = xoff;
+       /* Apply the settings */
+       if (update_buffer) {
+@@ -355,6 +354,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                       return err;
+       }
++      priv->dcbx.xoff = xoff;
++
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+-- 
+2.50.1
+
diff --git a/queue-5.10/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch b/queue-5.10/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
new file mode 100644 (file)
index 0000000..089f4a6
--- /dev/null
@@ -0,0 +1,100 @@
+From 68c45b5d4899aecf1373f6c532344d8b8818d056 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h         | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c   | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+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..a23e3d810f3e4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -63,11 +63,23 @@ struct mlx5e_port_buffer {
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_BUFFER];
+ };
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++                              u32 change, unsigned int mtu,
++                              void *pfc,
++                              u32 *buffer_size,
++                              u8 *prio2buffer)
++{
++      return 0;
++}
++#endif
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index c3ff1fc577a7c..cef60bc2589cc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -42,6 +42,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2874,9 +2875,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+       struct mlx5e_params *params = &priv->channels.params;
+       struct net_device *netdev = priv->netdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
+-      u16 mtu;
++      u16 mtu, prev_mtu;
+       int err;
++      mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+       err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+       if (err)
+               return err;
+@@ -2886,6 +2889,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+               netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+                           __func__, mtu, params->sw_mtu);
++      if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++              err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++                                                    NULL, NULL, NULL);
++              if (err) {
++                      netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++                                  __func__, mtu, err, prev_mtu);
++
++                      mlx5e_set_mtu(mdev, params, prev_mtu);
++                      return err;
++              }
++      }
++
+       params->sw_mtu = mtu;
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-5.10/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch b/queue-5.10/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
new file mode 100644 (file)
index 0000000..e5f7614
--- /dev/null
@@ -0,0 +1,46 @@
+From e771bc39e892fe3eb9efb178f4613876b5e946d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index cef60bc2589cc..cc93c503984a1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -141,6 +141,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+       if (port_state == VPORT_STATE_UP) {
+               netdev_info(priv->netdev, "Link up\n");
+               netif_carrier_on(priv->netdev);
++              mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++                                              NULL, NULL, NULL);
+       } else {
+               netdev_info(priv->netdev, "Link down\n");
+               netif_carrier_off(priv->netdev);
+-- 
+2.50.1
+
diff --git a/queue-5.10/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch b/queue-5.10/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
new file mode 100644 (file)
index 0000000..baac294
--- /dev/null
@@ -0,0 +1,49 @@
+From 44900a377bd65e613869bfc5da8caff4955d6a4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index a5583d706b9f2..e30bbe1933ec8 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -199,10 +199,6 @@ static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+       }
+       writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+-      /* Enable MTL RX overflow */
+-      value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+-      writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+-- 
+2.50.1
+
diff --git a/queue-5.10/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch b/queue-5.10/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
new file mode 100644 (file)
index 0000000..fb6510c
--- /dev/null
@@ -0,0 +1,68 @@
+From 365ebd7126b79065e7b9416343e990f854237b68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index d89cf802d9aa7..8067641561a4f 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+       }
+-      switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++      switch (inst_no_rt & ~KVM_MASK_RB) {
+       case KVM_INST_MTSRIN:
+               if (features & KVM_MAGIC_FEAT_SR) {
+                       u32 inst_rb = _inst & KVM_MASK_RB;
+                       kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+               }
+               break;
+-#endif
+       }
++#endif
+-      switch (_inst) {
+ #ifdef CONFIG_BOOKE
++      switch (_inst) {
+       case KVM_INST_WRTEEI_0:
+               kvm_patch_ins_wrteei_0(inst);
+               break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+       case KVM_INST_WRTEEI_1:
+               kvm_patch_ins_wrtee(inst, 0, 1);
+               break;
+-#endif
+       }
++#endif
+ }
+ extern u32 kvm_template_start[];
+-- 
+2.50.1
+
diff --git a/queue-5.10/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch b/queue-5.10/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
new file mode 100644 (file)
index 0000000..841decd
--- /dev/null
@@ -0,0 +1,72 @@
+From 76e8d36a4f53030ffd449407fbcc0fe23253bfa8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+  sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+  sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+  sctp_get_port net/sctp/socket.c:8523 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+  x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+  do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+  sctp_get_port net/sctp/socket.c:8515 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index d594b949ae82f..a9cfe4d62df83 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -499,7 +499,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+       addr->v6.sin6_family = AF_INET6;
+       addr->v6.sin6_port = 0;
++      addr->v6.sin6_flowinfo = 0;
+       addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++      addr->v6.sin6_scope_id = 0;
+ }
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+-- 
+2.50.1
+
index 45e7ce1e767e98941c9376f07197e3603b3076b7..afd0baa5dfcc663bee256ea04dbde27d6a93842c 100644 (file)
@@ -5,3 +5,14 @@ x86-cpu-hygon-add-missing-resctrl_cpu_detect-in-bsp_init-helper.patch
 nfs-fold-nfs_page_group_lock_subrequests-into-nfs_lock_and_join_requests.patch
 nfs-fix-a-race-when-updating-an-existing-write.patch
 vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
diff --git a/queue-5.15/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch b/queue-5.15/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
new file mode 100644 (file)
index 0000000..341e2b0
--- /dev/null
@@ -0,0 +1,192 @@
+From 18026b07fcd6b2a9975264ddab50cd935daea54a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+  struct atmtcp_control {
+       struct atmtcp_hdr hdr;  /* must be first */
+  ...
+       atm_kptr_t vcc;         /* both directions */
+  ...
+  } __ATM_API_ALIGN;
+
+  typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+  1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+  2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS:  00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 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+0x19b/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
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c   | 17 ++++++++++++++---
+ include/linux/atmdev.h |  1 +
+ net/atm/common.c       | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index ff558908897f3..9c83fb29b2f1b 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+         return NULL;
+ }
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++      struct atmtcp_hdr *hdr;
++
++      if (skb->len < sizeof(struct atmtcp_hdr))
++              return -EINVAL;
++
++      hdr = (struct atmtcp_hdr *)skb->data;
++      if (hdr->length == ATMTCP_HDR_MAGIC)
++              return -EINVAL;
++
++      return 0;
++}
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+       struct sk_buff *new_skb;
+       int result = 0;
+-      if (skb->len < sizeof(struct atmtcp_hdr))
+-              goto done;
+-
+       dev = vcc->dev_data;
+       hdr = (struct atmtcp_hdr *) skb->data;
+       if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+       .close          = atmtcp_c_close,
++      .pre_send       = atmtcp_c_pre_send,
+       .send           = atmtcp_c_send
+ };
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
++      int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 930eb302cd10f..38ed7b985f655 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+       skb->dev = NULL; /* for paths shared with net_device interfaces */
+       if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+-              atm_return_tx(vcc, skb);
+-              kfree_skb(skb);
+               error = -EFAULT;
+-              goto out;
++              goto free_skb;
+       }
+       if (eff != size)
+               memset(skb->data + size, 0, eff-size);
++
++      if (vcc->dev->ops->pre_send) {
++              error = vcc->dev->ops->pre_send(vcc, skb);
++              if (error)
++                      goto free_skb;
++      }
++
+       error = vcc->dev->ops->send(vcc, skb);
+       error = error ? error : size;
+ out:
+       release_sock(sk);
+       return error;
++free_skb:
++      atm_return_tx(vcc, skb);
++      kfree_skb(skb);
++      goto out;
+ }
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+-- 
+2.50.1
+
diff --git a/queue-5.15/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch b/queue-5.15/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
new file mode 100644 (file)
index 0000000..d478e4b
--- /dev/null
@@ -0,0 +1,47 @@
+From c886599c79dfcda729ed09a3aa8a25175ac577f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 84b07b27b3cf4..cfdaaecf78600 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3919,7 +3919,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+               if (!conn)
+                       continue;
+-              conn->sent -= count;
++              /* Check if there is really enough packets outstanding before
++               * attempting to decrease the sent counter otherwise it could
++               * underflow..
++               */
++              if (conn->sent >= count) {
++                      conn->sent -= count;
++              } else {
++                      bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++                                  conn, conn->sent, count);
++                      conn->sent = 0;
++              }
+               switch (conn->type) {
+               case ACL_LINK:
+-- 
+2.50.1
+
diff --git a/queue-5.15/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch b/queue-5.15/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
new file mode 100644 (file)
index 0000000..560a082
--- /dev/null
@@ -0,0 +1,77 @@
+From 04e740b4dfd074a755299a16dc8394497e284442 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+  BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+  Call trace:
+   kasan_check_range+0xe8/0x190
+   __asan_loadN+0x1c/0x28
+   memcmp+0x98/0xd0
+   efivarfs_d_compare+0x68/0xd8
+   __d_lookup_rcu_op_compare+0x178/0x218
+   __d_lookup_rcu+0x1f8/0x228
+   d_alloc_parallel+0x150/0x648
+   lookup_open.isra.0+0x5f0/0x8d0
+   open_last_lookups+0x264/0x828
+   path_openat+0x130/0x3f8
+   do_filp_open+0x114/0x248
+   do_sys_openat2+0x340/0x3c0
+   __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+  T1                   T2
+  lookup_open
+   ->lookup
+    simple_lookup
+     d_add
+     // invalid dentry is added to hash list
+
+                       lookup_open
+                        d_alloc_parallel
+                         __d_lookup_rcu
+                          __d_lookup_rcu_op_compare
+                           hlist_bl_for_each_entry_rcu
+                           // invalid dentry can be retrieved
+                            ->d_compare
+                             efivarfs_d_compare
+                             // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 99d002438008b..124db520b2bd6 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -47,6 +47,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+       int guid = len - EFI_VARIABLE_GUID_LEN;
++      /* Parallel lookups may produce a temporary invalid filename */
++      if (guid <= 0)
++              return 1;
++
+       if (name->len != len)
+               return 1;
+-- 
+2.50.1
+
diff --git a/queue-5.15/net-dlink-fix-multicast-stats-being-counted-incorrec.patch b/queue-5.15/net-dlink-fix-multicast-stats-being-counted-incorrec.patch
new file mode 100644 (file)
index 0000000..7892b5d
--- /dev/null
@@ -0,0 +1,46 @@
+From 631de0a7006b7a2bf147157adf4e531c3087fca6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index 09a275eb44487..81395852b4d43 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1095,7 +1095,7 @@ get_stats (struct net_device *dev)
+       dev->stats.rx_bytes += dr32(OctetRcvOk);
+       dev->stats.tx_bytes += dr32(OctetXmtOk);
+-      dev->stats.multicast = dr32(McstFramesRcvdOk);
++      dev->stats.multicast += dr32(McstFramesRcvdOk);
+       dev->stats.collisions += dr32(SingleColFrames)
+                            +  dr32(MultiColFrames);
+-- 
+2.50.1
+
diff --git a/queue-5.15/net-ipv4-fix-regression-in-local-broadcast-routes.patch b/queue-5.15/net-ipv4-fix-regression-in-local-broadcast-routes.patch
new file mode 100644 (file)
index 0000000..c342dea
--- /dev/null
@@ -0,0 +1,57 @@
+From 6666f564e6dc3bc10eb0247005b47faff923759a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index df4cbf9ba288f..b24de1c67d0c2 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2552,12 +2552,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+                   !netif_is_l3_master(dev_out))
+                       return ERR_PTR(-EINVAL);
+-      if (ipv4_is_lbcast(fl4->daddr))
++      if (ipv4_is_lbcast(fl4->daddr)) {
+               type = RTN_BROADCAST;
+-      else if (ipv4_is_multicast(fl4->daddr))
++
++              /* reset fi to prevent gateway resolution */
++              fi = NULL;
++      } else if (ipv4_is_multicast(fl4->daddr)) {
+               type = RTN_MULTICAST;
+-      else if (ipv4_is_zeronet(fl4->daddr))
++      } else if (ipv4_is_zeronet(fl4->daddr)) {
+               return ERR_PTR(-EINVAL);
++      }
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+-- 
+2.50.1
+
diff --git a/queue-5.15/net-mlx5e-set-local-xoff-after-fw-update.patch b/queue-5.15/net-mlx5e-set-local-xoff-after-fw-update.patch
new file mode 100644 (file)
index 0000000..2689939
--- /dev/null
@@ -0,0 +1,50 @@
+From ef84cd46f5974a389e2183063b47367c3de2d8b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+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 c9d5d8d93994d..7899a7230299d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -346,7 +346,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+               if (err)
+                       return err;
+       }
+-      priv->dcbx.xoff = xoff;
+       /* Apply the settings */
+       if (update_buffer) {
+@@ -355,6 +354,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                       return err;
+       }
++      priv->dcbx.xoff = xoff;
++
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+-- 
+2.50.1
+
diff --git a/queue-5.15/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch b/queue-5.15/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
new file mode 100644 (file)
index 0000000..d7e0d0b
--- /dev/null
@@ -0,0 +1,100 @@
+From 7d673e811f13804fda8f0874d49487abf56a521e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h         | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c   | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+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..a23e3d810f3e4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -63,11 +63,23 @@ struct mlx5e_port_buffer {
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_BUFFER];
+ };
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++                              u32 change, unsigned int mtu,
++                              void *pfc,
++                              u32 *buffer_size,
++                              u8 *prio2buffer)
++{
++      return 0;
++}
++#endif
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 321441e6ad328..bb7e3c80ad74e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -42,6 +42,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2242,9 +2243,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+       struct mlx5e_params *params = &priv->channels.params;
+       struct net_device *netdev = priv->netdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
+-      u16 mtu;
++      u16 mtu, prev_mtu;
+       int err;
++      mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+       err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+       if (err)
+               return err;
+@@ -2254,6 +2257,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+               netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+                           __func__, mtu, params->sw_mtu);
++      if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++              err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++                                                    NULL, NULL, NULL);
++              if (err) {
++                      netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++                                  __func__, mtu, err, prev_mtu);
++
++                      mlx5e_set_mtu(mdev, params, prev_mtu);
++                      return err;
++              }
++      }
++
+       params->sw_mtu = mtu;
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-5.15/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch b/queue-5.15/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
new file mode 100644 (file)
index 0000000..16072d7
--- /dev/null
@@ -0,0 +1,46 @@
+From 41ed1b2b238aa0c45ab2d6ca606542ec374a75cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index bb7e3c80ad74e..cfbc569edfb5f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -104,6 +104,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+       if (up) {
+               netdev_info(priv->netdev, "Link up\n");
+               netif_carrier_on(priv->netdev);
++              mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++                                              NULL, NULL, NULL);
+       } else {
+               netdev_info(priv->netdev, "Link down\n");
+               netif_carrier_off(priv->netdev);
+-- 
+2.50.1
+
diff --git a/queue-5.15/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch b/queue-5.15/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
new file mode 100644 (file)
index 0000000..2c42711
--- /dev/null
@@ -0,0 +1,49 @@
+From 17dcb63450422550503507a8ba929ee9fd226c1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5e98355f422b3..3e4318d5dcdf5 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -199,10 +199,6 @@ static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+       }
+       writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+-      /* Enable MTL RX overflow */
+-      value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+-      writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+-- 
+2.50.1
+
diff --git a/queue-5.15/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch b/queue-5.15/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
new file mode 100644 (file)
index 0000000..dc7764c
--- /dev/null
@@ -0,0 +1,135 @@
+From 1ef13ace52d87b240f4952102c94c0173a41e31c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h      |  4 ++++
+ drivers/net/phy/mscc/mscc_main.c |  4 +---
+ drivers/net/phy/mscc/mscc_ptp.c  | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 878298304430c..fcfbff691b3c6 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -474,6 +474,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -488,6 +489,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+       return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+       return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index 03aa85ec60dfc..982e73adf2bcf 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2326,9 +2326,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *priv = phydev->priv;
+-
+-      skb_queue_purge(&priv->rx_skbs_list);
++      vsc8584_ptp_deinit(phydev);
+ }
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index f77bfbee5f20b..e30e6ba9da2f4 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1294,7 +1294,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *vsc8531 = phydev->priv;
+       static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+       static const u8  ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+       u32 val;
+@@ -1511,17 +1510,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+       vsc85xx_ts_eth_cmp1_sig(phydev);
+-      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+-      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+-      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+-      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
+-      phydev->mii_ts = &vsc8531->mii_ts;
+-
+-      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+-      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+-                                                   &phydev->mdio.dev);
+-      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++      return 0;
+ }
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1548,6 +1537,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+       return 0;
+ }
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++      struct vsc8531_private *vsc8531 = phydev->priv;
++
++      if (vsc8531->ptp->ptp_clock) {
++              ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++              skb_queue_purge(&vsc8531->rx_skbs_list);
++      }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+       struct vsc8531_private *priv = phydev->priv;
+@@ -1605,7 +1604,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+       vsc8531->ptp->phydev = phydev;
+-      return 0;
++      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
++      phydev->mii_ts = &vsc8531->mii_ts;
++
++      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++                                                   &phydev->mdio.dev);
++      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+-- 
+2.50.1
+
diff --git a/queue-5.15/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch b/queue-5.15/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
new file mode 100644 (file)
index 0000000..33862fe
--- /dev/null
@@ -0,0 +1,68 @@
+From bbb8d2abdf55950847e3450f7463eea454664e61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 6568823cf3063..5d9d38834507d 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+       }
+-      switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++      switch (inst_no_rt & ~KVM_MASK_RB) {
+       case KVM_INST_MTSRIN:
+               if (features & KVM_MAGIC_FEAT_SR) {
+                       u32 inst_rb = _inst & KVM_MASK_RB;
+                       kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+               }
+               break;
+-#endif
+       }
++#endif
+-      switch (_inst) {
+ #ifdef CONFIG_BOOKE
++      switch (_inst) {
+       case KVM_INST_WRTEEI_0:
+               kvm_patch_ins_wrteei_0(inst);
+               break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+       case KVM_INST_WRTEEI_1:
+               kvm_patch_ins_wrtee(inst, 0, 1);
+               break;
+-#endif
+       }
++#endif
+ }
+ extern u32 kvm_template_start[];
+-- 
+2.50.1
+
diff --git a/queue-5.15/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch b/queue-5.15/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
new file mode 100644 (file)
index 0000000..1b14413
--- /dev/null
@@ -0,0 +1,72 @@
+From 7168fc6bd436b474e4170fc54d6a3d426c42399c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+  sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+  sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+  sctp_get_port net/sctp/socket.c:8523 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+  x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+  do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+  sctp_get_port net/sctp/socket.c:8515 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 470dbdc27d584..107255d92037f 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -547,7 +547,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+       addr->v6.sin6_family = AF_INET6;
+       addr->v6.sin6_port = 0;
++      addr->v6.sin6_flowinfo = 0;
+       addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++      addr->v6.sin6_scope_id = 0;
+ }
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+-- 
+2.50.1
+
index 54a5b4d148b3de9144c148def11147975bc3ecf3..2f9a025e7c72cc75bfc8038e891c138833bd96fd 100644 (file)
@@ -5,3 +5,15 @@ asoc-codecs-tx-macro-correct-tx_macro_component_drv-.patch
 nfs-fold-nfs_page_group_lock_subrequests-into-nfs_lock_and_join_requests.patch
 nfs-fix-a-race-when-updating-an-existing-write.patch
 vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
diff --git a/queue-5.4/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch b/queue-5.4/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
new file mode 100644 (file)
index 0000000..9a52c95
--- /dev/null
@@ -0,0 +1,192 @@
+From 51d4666edc74dbd1eee81b83126369380eaa2160 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+  struct atmtcp_control {
+       struct atmtcp_hdr hdr;  /* must be first */
+  ...
+       atm_kptr_t vcc;         /* both directions */
+  ...
+  } __ATM_API_ALIGN;
+
+  typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+  1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+  2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS:  00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 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+0x19b/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
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c   | 17 ++++++++++++++---
+ include/linux/atmdev.h |  1 +
+ net/atm/common.c       | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index afc1af542c3b5..c6915c5effbd7 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+         return NULL;
+ }
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++      struct atmtcp_hdr *hdr;
++
++      if (skb->len < sizeof(struct atmtcp_hdr))
++              return -EINVAL;
++
++      hdr = (struct atmtcp_hdr *)skb->data;
++      if (hdr->length == ATMTCP_HDR_MAGIC)
++              return -EINVAL;
++
++      return 0;
++}
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+       struct sk_buff *new_skb;
+       int result = 0;
+-      if (skb->len < sizeof(struct atmtcp_hdr))
+-              goto done;
+-
+       dev = vcc->dev_data;
+       hdr = (struct atmtcp_hdr *) skb->data;
+       if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static struct atmdev_ops atmtcp_v_dev_ops = {
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+       .close          = atmtcp_c_close,
++      .pre_send       = atmtcp_c_pre_send,
+       .send           = atmtcp_c_send
+ };
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index bc24d19ec2b37..8cbb992f6293c 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
++      int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+       void (*phy_put)(struct atm_dev *dev,unsigned char value,
+diff --git a/net/atm/common.c b/net/atm/common.c
+index a51994aba34c4..59b61886629e6 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+       skb->dev = NULL; /* for paths shared with net_device interfaces */
+       if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+-              atm_return_tx(vcc, skb);
+-              kfree_skb(skb);
+               error = -EFAULT;
+-              goto out;
++              goto free_skb;
+       }
+       if (eff != size)
+               memset(skb->data + size, 0, eff-size);
++
++      if (vcc->dev->ops->pre_send) {
++              error = vcc->dev->ops->pre_send(vcc, skb);
++              if (error)
++                      goto free_skb;
++      }
++
+       error = vcc->dev->ops->send(vcc, skb);
+       error = error ? error : size;
+ out:
+       release_sock(sk);
+       return error;
++free_skb:
++      atm_return_tx(vcc, skb);
++      kfree_skb(skb);
++      goto out;
+ }
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+-- 
+2.50.1
+
diff --git a/queue-5.4/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch b/queue-5.4/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
new file mode 100644 (file)
index 0000000..da24c3a
--- /dev/null
@@ -0,0 +1,47 @@
+From 7a268e98cab1fe76fe4d1519de97acdff4fb12e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 33b025a52b83a..4e8911501255d 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3681,7 +3681,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+               if (!conn)
+                       continue;
+-              conn->sent -= count;
++              /* Check if there is really enough packets outstanding before
++               * attempting to decrease the sent counter otherwise it could
++               * underflow..
++               */
++              if (conn->sent >= count) {
++                      conn->sent -= count;
++              } else {
++                      bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++                                  conn, conn->sent, count);
++                      conn->sent = 0;
++              }
+               switch (conn->type) {
+               case ACL_LINK:
+-- 
+2.50.1
+
diff --git a/queue-5.4/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch b/queue-5.4/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
new file mode 100644 (file)
index 0000000..e127926
--- /dev/null
@@ -0,0 +1,77 @@
+From dd55ca1d46c176720dfa0e02a0e3f1961613e275 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+  BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+  Call trace:
+   kasan_check_range+0xe8/0x190
+   __asan_loadN+0x1c/0x28
+   memcmp+0x98/0xd0
+   efivarfs_d_compare+0x68/0xd8
+   __d_lookup_rcu_op_compare+0x178/0x218
+   __d_lookup_rcu+0x1f8/0x228
+   d_alloc_parallel+0x150/0x648
+   lookup_open.isra.0+0x5f0/0x8d0
+   open_last_lookups+0x264/0x828
+   path_openat+0x130/0x3f8
+   do_filp_open+0x114/0x248
+   do_sys_openat2+0x340/0x3c0
+   __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+  T1                   T2
+  lookup_open
+   ->lookup
+    simple_lookup
+     d_add
+     // invalid dentry is added to hash list
+
+                       lookup_open
+                        d_alloc_parallel
+                         __d_lookup_rcu
+                          __d_lookup_rcu_op_compare
+                           hlist_bl_for_each_entry_rcu
+                           // invalid dentry can be retrieved
+                            ->d_compare
+                             efivarfs_d_compare
+                             // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index d12a21b2dd9d0..0f3d3d96599b8 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -46,6 +46,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+       int guid = len - EFI_VARIABLE_GUID_LEN;
++      /* Parallel lookups may produce a temporary invalid filename */
++      if (guid <= 0)
++              return 1;
++
+       if (name->len != len)
+               return 1;
+-- 
+2.50.1
+
diff --git a/queue-5.4/net-atm-remove-the-atmdev_ops-get-set-sockopt-method.patch b/queue-5.4/net-atm-remove-the-atmdev_ops-get-set-sockopt-method.patch
new file mode 100644 (file)
index 0000000..a91dca2
--- /dev/null
@@ -0,0 +1,331 @@
+From 7461361c85f5aeecb6c604601f57b40cb416c6ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2020 08:23:10 +0200
+Subject: net/atm: remove the atmdev_ops {get, set}sockopt methods
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit a06d30ae7af492497ffbca6abf1621d508b8fcaa ]
+
+All implementations of these two methods are dummies that always
+return -EINVAL.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: ec79003c5f9d ("atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/eni.c        | 17 -----------------
+ drivers/atm/firestream.c |  2 --
+ drivers/atm/fore200e.c   | 27 ---------------------------
+ drivers/atm/horizon.c    | 40 ----------------------------------------
+ drivers/atm/iphase.c     | 16 ----------------
+ drivers/atm/lanai.c      |  2 --
+ drivers/atm/solos-pci.c  |  2 --
+ drivers/atm/zatm.c       | 16 ----------------
+ include/linux/atmdev.h   |  9 ---------
+ net/atm/common.c         | 14 ++------------
+ 10 files changed, 2 insertions(+), 143 deletions(-)
+
+diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
+index 4816db0553ef8..0f082bd626543 100644
+--- a/drivers/atm/eni.c
++++ b/drivers/atm/eni.c
+@@ -2035,21 +2035,6 @@ static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
+       return dev->phy->ioctl(dev,cmd,arg);
+ }
+-
+-static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
+-    void __user *optval,int optlen)
+-{
+-      return -EINVAL;
+-}
+-
+-
+-static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
+-    void __user *optval,unsigned int optlen)
+-{
+-      return -EINVAL;
+-}
+-
+-
+ static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+       enum enq_res res;
+@@ -2223,8 +2208,6 @@ static const struct atmdev_ops ops = {
+       .open           = eni_open,
+       .close          = eni_close,
+       .ioctl          = eni_ioctl,
+-      .getsockopt     = eni_getsockopt,
+-      .setsockopt     = eni_setsockopt,
+       .send           = eni_send,
+       .phy_put        = eni_phy_put,
+       .phy_get        = eni_phy_get,
+diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
+index 8995c39330fac..c7c3aeecd1c61 100644
+--- a/drivers/atm/firestream.c
++++ b/drivers/atm/firestream.c
+@@ -1278,8 +1278,6 @@ static const struct atmdev_ops ops = {
+       .send =         fs_send,
+       .owner =        THIS_MODULE,
+       /* ioctl:          fs_ioctl, */
+-      /* getsockopt:     fs_getsockopt, */
+-      /* setsockopt:     fs_setsockopt, */
+       /* change_qos:     fs_change_qos, */
+       /* For now implement these internally here... */  
+diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
+index 8fbd36eb89410..a36f555cc0403 100644
+--- a/drivers/atm/fore200e.c
++++ b/drivers/atm/fore200e.c
+@@ -1710,31 +1710,6 @@ fore200e_getstats(struct fore200e* fore200e)
+     return 0;
+ }
+-
+-static int
+-fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
+-{
+-    /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
+-
+-    DPRINTK(2, "getsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
+-          vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
+-
+-    return -EINVAL;
+-}
+-
+-
+-static int
+-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
+-{
+-    /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
+-    
+-    DPRINTK(2, "setsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
+-          vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
+-    
+-    return -EINVAL;
+-}
+-
+-
+ #if 0 /* currently unused */
+ static int
+ fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
+@@ -3026,8 +3001,6 @@ static const struct atmdev_ops fore200e_ops = {
+       .open       = fore200e_open,
+       .close      = fore200e_close,
+       .ioctl      = fore200e_ioctl,
+-      .getsockopt = fore200e_getsockopt,
+-      .setsockopt = fore200e_setsockopt,
+       .send       = fore200e_send,
+       .change_qos = fore200e_change_qos,
+       .proc_read  = fore200e_proc_read,
+diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
+index e5da51f907a25..4f2951cbe69c0 100644
+--- a/drivers/atm/horizon.c
++++ b/drivers/atm/horizon.c
+@@ -2527,46 +2527,6 @@ static void hrz_close (struct atm_vcc * atm_vcc) {
+   clear_bit(ATM_VF_ADDR,&atm_vcc->flags);
+ }
+-#if 0
+-static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
+-                         void *optval, int optlen) {
+-  hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
+-  PRINTD (DBG_FLOW|DBG_VCC, "hrz_getsockopt");
+-  switch (level) {
+-    case SOL_SOCKET:
+-      switch (optname) {
+-//    case SO_BCTXOPT:
+-//      break;
+-//    case SO_BCRXOPT:
+-//      break;
+-      default:
+-        return -ENOPROTOOPT;
+-      };
+-      break;
+-  }
+-  return -EINVAL;
+-}
+-
+-static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
+-                         void *optval, unsigned int optlen) {
+-  hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
+-  PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
+-  switch (level) {
+-    case SOL_SOCKET:
+-      switch (optname) {
+-//    case SO_BCTXOPT:
+-//      break;
+-//    case SO_BCRXOPT:
+-//      break;
+-      default:
+-        return -ENOPROTOOPT;
+-      };
+-      break;
+-  }
+-  return -EINVAL;
+-}
+-#endif
+-
+ #if 0
+ static int hrz_ioctl (struct atm_dev * atm_dev, unsigned int cmd, void *arg) {
+   hrz_dev * dev = HRZ_DEV(atm_dev);
+diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
+index bfc889367d5e3..cc90f550ab75a 100644
+--- a/drivers/atm/iphase.c
++++ b/drivers/atm/iphase.c
+@@ -2882,20 +2882,6 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
+    return 0;  
+ }  
+   
+-static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,   
+-      void __user *optval, int optlen)  
+-{  
+-      IF_EVENT(printk(">ia_getsockopt\n");)  
+-      return -EINVAL;  
+-}  
+-  
+-static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,   
+-      void __user *optval, unsigned int optlen)  
+-{  
+-      IF_EVENT(printk(">ia_setsockopt\n");)  
+-      return -EINVAL;  
+-}  
+-  
+ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
+         IADEV *iadev;
+         struct dle *wr_ptr;
+@@ -3166,8 +3152,6 @@ static const struct atmdev_ops ops = {
+       .open           = ia_open,  
+       .close          = ia_close,  
+       .ioctl          = ia_ioctl,  
+-      .getsockopt     = ia_getsockopt,  
+-      .setsockopt     = ia_setsockopt,  
+       .send           = ia_send,  
+       .phy_put        = ia_phy_put,  
+       .phy_get        = ia_phy_get,  
+diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
+index c6b38112bcf4f..2ed832e1dafa2 100644
+--- a/drivers/atm/lanai.c
++++ b/drivers/atm/lanai.c
+@@ -2540,8 +2540,6 @@ static const struct atmdev_ops ops = {
+       .dev_close      = lanai_dev_close,
+       .open           = lanai_open,
+       .close          = lanai_close,
+-      .getsockopt     = NULL,
+-      .setsockopt     = NULL,
+       .send           = lanai_send,
+       .phy_put        = NULL,
+       .phy_get        = NULL,
+diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
+index 9f2148daf8ad1..669466d010efa 100644
+--- a/drivers/atm/solos-pci.c
++++ b/drivers/atm/solos-pci.c
+@@ -1179,8 +1179,6 @@ static const struct atmdev_ops fpga_ops = {
+       .open =         popen,
+       .close =        pclose,
+       .ioctl =        NULL,
+-      .getsockopt =   NULL,
+-      .setsockopt =   NULL,
+       .send =         psend,
+       .send_oam =     NULL,
+       .phy_put =      NULL,
+diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
+index 165eebe06e39e..ee059c77e3bbc 100644
+--- a/drivers/atm/zatm.c
++++ b/drivers/atm/zatm.c
+@@ -1515,20 +1515,6 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
+       }
+ }
+-
+-static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
+-    void __user *optval,int optlen)
+-{
+-      return -EINVAL;
+-}
+-
+-
+-static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
+-    void __user *optval,unsigned int optlen)
+-{
+-      return -EINVAL;
+-}
+-
+ static int zatm_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+       int error;
+@@ -1582,8 +1568,6 @@ static const struct atmdev_ops ops = {
+       .open           = zatm_open,
+       .close          = zatm_close,
+       .ioctl          = zatm_ioctl,
+-      .getsockopt     = zatm_getsockopt,
+-      .setsockopt     = zatm_setsockopt,
+       .send           = zatm_send,
+       .phy_put        = zatm_phy_put,
+       .phy_get        = zatm_phy_get,
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 19c0f91c38bdd..bc24d19ec2b37 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -176,11 +176,6 @@ struct atm_dev {
+ #define ATM_OF_IMMED  1               /* Attempt immediate delivery */
+ #define ATM_OF_INRATE 2               /* Attempt in-rate delivery */
+-
+-/*
+- * ioctl, getsockopt, and setsockopt are optional and can be set to NULL.
+- */
+-
+ struct atmdev_ops { /* only send is required */
+       void (*dev_close)(struct atm_dev *dev);
+       int (*open)(struct atm_vcc *vcc);
+@@ -190,10 +185,6 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
+-      int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
+-          void __user *optval,int optlen);
+-      int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
+-          void __user *optval,unsigned int optlen);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+       void (*phy_put)(struct atm_dev *dev,unsigned char value,
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 1e07a5fc53d05..a51994aba34c4 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -783,13 +783,8 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
+                       vcc->atm_options &= ~ATM_ATMOPT_CLP;
+               return 0;
+       default:
+-              if (level == SOL_SOCKET)
+-                      return -EINVAL;
+-              break;
+-      }
+-      if (!vcc->dev || !vcc->dev->ops->setsockopt)
+               return -EINVAL;
+-      return vcc->dev->ops->setsockopt(vcc, level, optname, optval, optlen);
++      }
+ }
+ int vcc_getsockopt(struct socket *sock, int level, int optname,
+@@ -827,13 +822,8 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
+               return copy_to_user(optval, &pvc, sizeof(pvc)) ? -EFAULT : 0;
+       }
+       default:
+-              if (level == SOL_SOCKET)
+-                      return -EINVAL;
+-              break;
+-      }
+-      if (!vcc->dev || !vcc->dev->ops->getsockopt)
+               return -EINVAL;
+-      return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len);
++      }
+ }
+ int register_atmdevice_notifier(struct notifier_block *nb)
+-- 
+2.50.1
+
diff --git a/queue-5.4/net-dlink-fix-multicast-stats-being-counted-incorrec.patch b/queue-5.4/net-dlink-fix-multicast-stats-being-counted-incorrec.patch
new file mode 100644 (file)
index 0000000..0a0aef7
--- /dev/null
@@ -0,0 +1,46 @@
+From 06520857bf70423ebff4cdebeb35674058ac1fb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index 8d57fb5072054..b4a8d4f12087a 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1102,7 +1102,7 @@ get_stats (struct net_device *dev)
+       dev->stats.rx_bytes += dr32(OctetRcvOk);
+       dev->stats.tx_bytes += dr32(OctetXmtOk);
+-      dev->stats.multicast = dr32(McstFramesRcvdOk);
++      dev->stats.multicast += dr32(McstFramesRcvdOk);
+       dev->stats.collisions += dr32(SingleColFrames)
+                            +  dr32(MultiColFrames);
+-- 
+2.50.1
+
diff --git a/queue-5.4/net-ipv4-fix-regression-in-local-broadcast-routes.patch b/queue-5.4/net-ipv4-fix-regression-in-local-broadcast-routes.patch
new file mode 100644 (file)
index 0000000..c41bc24
--- /dev/null
@@ -0,0 +1,57 @@
+From a49d39fa6c97f5a783636b87167f3e41b4de394d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 80612f73ff531..eb83ce4b845ab 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2365,12 +2365,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+                   !netif_is_l3_master(dev_out))
+                       return ERR_PTR(-EINVAL);
+-      if (ipv4_is_lbcast(fl4->daddr))
++      if (ipv4_is_lbcast(fl4->daddr)) {
+               type = RTN_BROADCAST;
+-      else if (ipv4_is_multicast(fl4->daddr))
++
++              /* reset fi to prevent gateway resolution */
++              fi = NULL;
++      } else if (ipv4_is_multicast(fl4->daddr)) {
+               type = RTN_MULTICAST;
+-      else if (ipv4_is_zeronet(fl4->daddr))
++      } else if (ipv4_is_zeronet(fl4->daddr)) {
+               return ERR_PTR(-EINVAL);
++      }
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+-- 
+2.50.1
+
diff --git a/queue-5.4/net-mlx5e-set-local-xoff-after-fw-update.patch b/queue-5.4/net-mlx5e-set-local-xoff-after-fw-update.patch
new file mode 100644 (file)
index 0000000..2c505cf
--- /dev/null
@@ -0,0 +1,50 @@
+From e63cb1028414bc22af506551acb649eb673c6905 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+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 99c7cdd0404a5..44d3d6826f696 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -341,7 +341,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+               if (err)
+                       return err;
+       }
+-      priv->dcbx.xoff = xoff;
+       /* Apply the settings */
+       if (update_buffer) {
+@@ -350,6 +349,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                       return err;
+       }
++      priv->dcbx.xoff = xoff;
++
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+-- 
+2.50.1
+
diff --git a/queue-5.4/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch b/queue-5.4/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
new file mode 100644 (file)
index 0000000..bc4ecd7
--- /dev/null
@@ -0,0 +1,100 @@
+From 65cfd30f453ae6071cfe271ed37a23cd7977e32c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h         | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c   | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+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 34f55b81a0deb..7b852b87a609f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -64,11 +64,23 @@ struct mlx5e_port_buffer {
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_BUFFER];
+ };
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++                              u32 change, unsigned int mtu,
++                              void *pfc,
++                              u32 *buffer_size,
++                              u8 *prio2buffer)
++{
++      return 0;
++}
++#endif
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index b3ba996004f1d..41bd16cc9d0f6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -42,6 +42,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2894,9 +2895,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+       struct mlx5e_params *params = &priv->channels.params;
+       struct net_device *netdev = priv->netdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
+-      u16 mtu;
++      u16 mtu, prev_mtu;
+       int err;
++      mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+       err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+       if (err)
+               return err;
+@@ -2906,6 +2909,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+               netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+                           __func__, mtu, params->sw_mtu);
++      if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++              err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++                                                    NULL, NULL, NULL);
++              if (err) {
++                      netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++                                  __func__, mtu, err, prev_mtu);
++
++                      mlx5e_set_mtu(mdev, params, prev_mtu);
++                      return err;
++              }
++      }
++
+       params->sw_mtu = mtu;
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-5.4/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch b/queue-5.4/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
new file mode 100644 (file)
index 0000000..349de8c
--- /dev/null
@@ -0,0 +1,46 @@
+From 7844bc7fe4896ad0ff5821e80fedee7bcd0283ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 41bd16cc9d0f6..b8d0b68befcb9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -141,6 +141,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+       if (port_state == VPORT_STATE_UP) {
+               netdev_info(priv->netdev, "Link up\n");
+               netif_carrier_on(priv->netdev);
++              mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++                                              NULL, NULL, NULL);
+       } else {
+               netdev_info(priv->netdev, "Link down\n");
+               netif_carrier_off(priv->netdev);
+-- 
+2.50.1
+
diff --git a/queue-5.4/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch b/queue-5.4/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
new file mode 100644 (file)
index 0000000..117b388
--- /dev/null
@@ -0,0 +1,49 @@
+From f73fa5730fb89860c7baa5bbce8a80473ce135af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 07ef0ac725b3e..93d1b78c9d4ec 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -206,10 +206,6 @@ static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+       }
+       writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+-      /* Enable MTL RX overflow */
+-      value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+-      writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+-- 
+2.50.1
+
diff --git a/queue-5.4/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch b/queue-5.4/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
new file mode 100644 (file)
index 0000000..2f5b84b
--- /dev/null
@@ -0,0 +1,68 @@
+From b86acca59e57fb40f6a55f13d567274c0365991d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index d89cf802d9aa7..8067641561a4f 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+       }
+-      switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++      switch (inst_no_rt & ~KVM_MASK_RB) {
+       case KVM_INST_MTSRIN:
+               if (features & KVM_MAGIC_FEAT_SR) {
+                       u32 inst_rb = _inst & KVM_MASK_RB;
+                       kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+               }
+               break;
+-#endif
+       }
++#endif
+-      switch (_inst) {
+ #ifdef CONFIG_BOOKE
++      switch (_inst) {
+       case KVM_INST_WRTEEI_0:
+               kvm_patch_ins_wrteei_0(inst);
+               break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+       case KVM_INST_WRTEEI_1:
+               kvm_patch_ins_wrtee(inst, 0, 1);
+               break;
+-#endif
+       }
++#endif
+ }
+ extern u32 kvm_template_start[];
+-- 
+2.50.1
+
diff --git a/queue-5.4/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch b/queue-5.4/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
new file mode 100644 (file)
index 0000000..3946cb5
--- /dev/null
@@ -0,0 +1,72 @@
+From b5a913dcc708835316413c9194bbfde05fb0432b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+  sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+  sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+  sctp_get_port net/sctp/socket.c:8523 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+  x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+  do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+  sctp_get_port net/sctp/socket.c:8515 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index fae6157e837aa..33981ea102814 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -499,7 +499,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+       addr->v6.sin6_family = AF_INET6;
+       addr->v6.sin6_port = 0;
++      addr->v6.sin6_flowinfo = 0;
+       addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++      addr->v6.sin6_scope_id = 0;
+ }
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+-- 
+2.50.1
+
index 7a5f66f3bce31d40f99bc61fc55810b24661823f..425cf07ca8bd737a1ffa1c1a5b7f1e700672ecd6 100644 (file)
@@ -2,3 +2,15 @@ pinctrl-stmfx-add-missing-has_iomem-dependency.patch
 ftrace-fix-potential-warning-in-trace_printk_seq-dur.patch
 scsi-core-sysfs-correct-sysfs-attributes-access-righ.patch
 vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+net-atm-remove-the-atmdev_ops-get-set-sockopt-method.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
diff --git a/queue-6.1/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch b/queue-6.1/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
new file mode 100644 (file)
index 0000000..8aaad5f
--- /dev/null
@@ -0,0 +1,192 @@
+From 515045984d0b06fbcb39d0089cf5190e6279f06c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+  struct atmtcp_control {
+       struct atmtcp_hdr hdr;  /* must be first */
+  ...
+       atm_kptr_t vcc;         /* both directions */
+  ...
+  } __ATM_API_ALIGN;
+
+  typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+  1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+  2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS:  00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 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+0x19b/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
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c   | 17 ++++++++++++++---
+ include/linux/atmdev.h |  1 +
+ net/atm/common.c       | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index ff558908897f3..9c83fb29b2f1b 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+         return NULL;
+ }
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++      struct atmtcp_hdr *hdr;
++
++      if (skb->len < sizeof(struct atmtcp_hdr))
++              return -EINVAL;
++
++      hdr = (struct atmtcp_hdr *)skb->data;
++      if (hdr->length == ATMTCP_HDR_MAGIC)
++              return -EINVAL;
++
++      return 0;
++}
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+       struct sk_buff *new_skb;
+       int result = 0;
+-      if (skb->len < sizeof(struct atmtcp_hdr))
+-              goto done;
+-
+       dev = vcc->dev_data;
+       hdr = (struct atmtcp_hdr *) skb->data;
+       if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+       .close          = atmtcp_c_close,
++      .pre_send       = atmtcp_c_pre_send,
+       .send           = atmtcp_c_send
+ };
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
++      int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 9cc82acbc7358..48bb3f66a3f2a 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+       skb->dev = NULL; /* for paths shared with net_device interfaces */
+       if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+-              atm_return_tx(vcc, skb);
+-              kfree_skb(skb);
+               error = -EFAULT;
+-              goto out;
++              goto free_skb;
+       }
+       if (eff != size)
+               memset(skb->data + size, 0, eff-size);
++
++      if (vcc->dev->ops->pre_send) {
++              error = vcc->dev->ops->pre_send(vcc, skb);
++              if (error)
++                      goto free_skb;
++      }
++
+       error = vcc->dev->ops->send(vcc, skb);
+       error = error ? error : size;
+ out:
+       release_sock(sk);
+       return error;
++free_skb:
++      atm_return_tx(vcc, skb);
++      kfree_skb(skb);
++      goto out;
+ }
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+-- 
+2.50.1
+
diff --git a/queue-6.1/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch b/queue-6.1/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
new file mode 100644 (file)
index 0000000..ea9cc21
--- /dev/null
@@ -0,0 +1,47 @@
+From 49aad117a9b12de69a4f32f21f5202e99a1e52d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index ff013e1d82a85..3d81afcccff8b 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4409,7 +4409,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+               if (!conn)
+                       continue;
+-              conn->sent -= count;
++              /* Check if there is really enough packets outstanding before
++               * attempting to decrease the sent counter otherwise it could
++               * underflow..
++               */
++              if (conn->sent >= count) {
++                      conn->sent -= count;
++              } else {
++                      bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++                                  conn, conn->sent, count);
++                      conn->sent = 0;
++              }
+               switch (conn->type) {
+               case ACL_LINK:
+-- 
+2.50.1
+
diff --git a/queue-6.1/bluetooth-hci_event-mark-connection-as-closed-during.patch b/queue-6.1/bluetooth-hci_event-mark-connection-as-closed-during.patch
new file mode 100644 (file)
index 0000000..6cd7ca3
--- /dev/null
@@ -0,0 +1,80 @@
+From ed821df74519a971266af7d76764f0e17a57c358 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:27 +0200
+Subject: Bluetooth: hci_event: Mark connection as closed during suspend
+ disconnect
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit b7fafbc499b5ee164018eb0eefe9027f5a6aaad2 ]
+
+When suspending, the disconnect command for an active Bluetooth
+connection could be issued, but the corresponding
+`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
+completes the suspend process. This can lead to an inconsistent state.
+
+On resume, the controller may auto-accept reconnections from the same
+device (due to suspend event filters), but these new connections are
+rejected by the kernel which still has connection objects from before
+suspend. Resulting in errors like:
+```
+kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
+kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
+connection
+```
+
+This is a btmon snippet that shows the issue:
+```
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+        Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+        Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+      Disconnect (0x01|0x0006) ncmd 2
+        Status: Success (0x00)
+[...]
+// Host suspends with the event filter set for the device
+// On resume, the device tries to reconnect with a new handle
+
+> HCI Event: Connect Complete (0x03) plen 11
+        Status: Success (0x00)
+        Handle: 2
+        Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+
+// Kernel ignores this event because there is an existing connection
+with
+// handle 1
+```
+
+By explicitly setting the connection state to BT_CLOSED we can ensure a
+consistent state, even if we don't receive the disconnect complete event
+in time.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 3ff428df58a46..ff013e1d82a85 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2782,6 +2782,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+               goto done;
+       }
++      /* During suspend, mark connection as closed immediately
++       * since we might not receive HCI_EV_DISCONN_COMPLETE
++       */
++      if (hdev->suspended)
++              conn->state = BT_CLOSED;
++
+       mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+       if (conn->type == ACL_LINK) {
+-- 
+2.50.1
+
diff --git a/queue-6.1/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch b/queue-6.1/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
new file mode 100644 (file)
index 0000000..80ba865
--- /dev/null
@@ -0,0 +1,84 @@
+From 4a12ac6ea3860e8e49c16b8a10b4b550398d5ed4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:26 +0200
+Subject: Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit 2f050a5392b7a0928bf836d9891df4851463512c ]
+
+When the host sends an HCI_OP_DISCONNECT command, the controller may
+respond with the status HCI_ERROR_UNKNOWN_CONN_ID (0x02). E.g. this can
+happen on resume from suspend, if the link was terminated by the remote
+device before the event mask was correctly set.
+
+This is a btmon snippet that shows the issue:
+```
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+      L2CAP: Disconnection Request (0x06) ident 5 len 4
+        Destination CID: 65
+        Source CID: 72
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+      L2CAP: Disconnection Response (0x07) ident 5 len 4
+        Destination CID: 65
+        Source CID: 72
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+      L2CAP: Disconnection Request (0x06) ident 6 len 4
+        Destination CID: 64
+        Source CID: 71
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+      L2CAP: Disconnection Response (0x07) ident 6 len 4
+        Destination CID: 64
+        Source CID: 71
+< HCI Command: Set Event Mask (0x03|0x0001) plen 8
+        Mask: 0x3dbff807fffbffff
+          Inquiry Complete
+          Inquiry Result
+          Connection Complete
+          Connection Request
+          Disconnection Complete
+          Authentication Complete
+[...]
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+        Handle: 3 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+        Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+      Disconnect (0x01|0x0006) ncmd 1
+        Status: Unknown Connection Identifier (0x02)
+```
+
+Currently, the hci_cs_disconnect function treats any non-zero status
+as a command failure. This can be misleading because the connection is
+indeed being terminated and the controller is confirming that is has no
+knowledge of that connection handle. Meaning that the initial request of
+disconnecting a device should be treated as done.
+
+With this change we allow the function to proceed, following the success
+path, which correctly calls `mgmt_device_disconnected` and ensures a
+consistent state.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 866462c97dbaf..3ff428df58a46 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2767,7 +2767,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+       if (!conn)
+               goto unlock;
+-      if (status) {
++      if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+               mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+                                      conn->dst_type, status);
+-- 
+2.50.1
+
diff --git a/queue-6.1/bluetooth-hci_sync-fix-set_local_name-race-condition.patch b/queue-6.1/bluetooth-hci_sync-fix-set_local_name-race-condition.patch
new file mode 100644 (file)
index 0000000..09834ca
--- /dev/null
@@ -0,0 +1,90 @@
+From c8647fe81cac13a8586803254ba95ec303a1cda8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 12:20:55 +0300
+Subject: Bluetooth: hci_sync: fix set_local_name race condition
+
+From: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+
+[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]
+
+Function set_name_sync() uses hdev->dev_name field to send
+HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
+is called after mgmt cmd was queued, so it is possible that function
+set_name_sync() will read old name value.
+
+This change adds name as a parameter for function hci_update_name_sync()
+to avoid race condition.
+
+Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
+Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+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>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_sync.c         | 6 +++---
+ net/bluetooth/mgmt.c             | 5 ++++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 3a7658d660224..a8b106d884d41 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -65,7 +65,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index acff47da799aa..965b0f2b43a72 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3424,13 +3424,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+       return hci_write_scan_enable_sync(hdev, scan);
+ }
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+       struct hci_cp_write_local_name cp;
+       memset(&cp, 0, sizeof(cp));
+-      memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++      memcpy(cp.name, name, sizeof(cp.name));
+       return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+                                           sizeof(cp), &cp,
+@@ -3482,7 +3482,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+                       hci_write_fast_connectable_sync(hdev, false);
+               hci_update_scan_sync(hdev);
+               hci_update_class_sync(hdev);
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, hdev->dev_name);
+               hci_update_eir_sync(hdev);
+       }
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 919e1bae2b269..27876512c63a4 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3897,8 +3897,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++      struct mgmt_pending_cmd *cmd = data;
++      struct mgmt_cp_set_local_name *cp = cmd->param;
++
+       if (lmp_bredr_capable(hdev)) {
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, cp->name);
+               hci_update_eir_sync(hdev);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.1/drm-msm-defer-fd_install-in-submit-ioctl.patch b/queue-6.1/drm-msm-defer-fd_install-in-submit-ioctl.patch
new file mode 100644 (file)
index 0000000..a9c0f5b
--- /dev/null
@@ -0,0 +1,59 @@
+From ffd8dad18451b6f59f866ed6630bbf2d3aa890b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jul 2025 13:28:22 -0700
+Subject: drm/msm: Defer fd_install in SUBMIT ioctl
+
+From: Rob Clark <robin.clark@oss.qualcomm.com>
+
+[ Upstream commit f22853435bbd1e9836d0dce7fd99c040b94c2bf1 ]
+
+Avoid fd_install() until there are no more potential error paths, to
+avoid put_unused_fd() after the fd is made visible to userspace.
+
+Fixes: 68dc6c2d5eec ("drm/msm: Fix submit error-path leaks")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665363/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index 572dd662e8095..6a02f790624a9 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -929,12 +929,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+       if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+               sync_file = sync_file_create(submit->user_fence);
+-              if (!sync_file) {
++              if (!sync_file)
+                       ret = -ENOMEM;
+-              } else {
+-                      fd_install(out_fence_fd, sync_file->file);
+-                      args->fence_fd = out_fence_fd;
+-              }
+       }
+       submit_attach_object_fences(submit);
+@@ -959,10 +955,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ out_unlock:
+       mutex_unlock(&queue->lock);
+ out_post_unlock:
+-      if (ret && (out_fence_fd >= 0)) {
+-              put_unused_fd(out_fence_fd);
++      if (ret) {
++              if (out_fence_fd >= 0)
++                      put_unused_fd(out_fence_fd);
+               if (sync_file)
+                       fput(sync_file->file);
++      } else if (sync_file) {
++              fd_install(out_fence_fd, sync_file->file);
++              args->fence_fd = out_fence_fd;
+       }
+       if (!IS_ERR_OR_NULL(submit)) {
+-- 
+2.50.1
+
diff --git a/queue-6.1/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch b/queue-6.1/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
new file mode 100644 (file)
index 0000000..94f7ec3
--- /dev/null
@@ -0,0 +1,77 @@
+From e5b4d67100cfc25f7953ca3f115d0e40a8147495 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+  BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+  Call trace:
+   kasan_check_range+0xe8/0x190
+   __asan_loadN+0x1c/0x28
+   memcmp+0x98/0xd0
+   efivarfs_d_compare+0x68/0xd8
+   __d_lookup_rcu_op_compare+0x178/0x218
+   __d_lookup_rcu+0x1f8/0x228
+   d_alloc_parallel+0x150/0x648
+   lookup_open.isra.0+0x5f0/0x8d0
+   open_last_lookups+0x264/0x828
+   path_openat+0x130/0x3f8
+   do_filp_open+0x114/0x248
+   do_sys_openat2+0x340/0x3c0
+   __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+  T1                   T2
+  lookup_open
+   ->lookup
+    simple_lookup
+     d_add
+     // invalid dentry is added to hash list
+
+                       lookup_open
+                        d_alloc_parallel
+                         __d_lookup_rcu
+                          __d_lookup_rcu_op_compare
+                           hlist_bl_for_each_entry_rcu
+                           // invalid dentry can be retrieved
+                            ->d_compare
+                             efivarfs_d_compare
+                             // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index b8c4641ed152b..9025430cf2ad3 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -47,6 +47,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+       int guid = len - EFI_VARIABLE_GUID_LEN;
++      /* Parallel lookups may produce a temporary invalid filename */
++      if (guid <= 0)
++              return 1;
++
+       if (name->len != len)
+               return 1;
+-- 
+2.50.1
+
diff --git a/queue-6.1/hid-input-rename-hidinput_set_battery_charge_status.patch b/queue-6.1/hid-input-rename-hidinput_set_battery_charge_status.patch
new file mode 100644 (file)
index 0000000..6b3ce46
--- /dev/null
@@ -0,0 +1,147 @@
+From 0d4293271a70cf23360bfe1b72e5341e9848a65d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:39 +0200
+Subject: HID: input: rename hidinput_set_battery_charge_status()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit a82231b2a8712d0218fc286a9b0da328d419a3f4 ]
+
+In preparation for a patch fixing a bug affecting
+hidinput_set_battery_charge_status(), rename the function to
+hidinput_update_battery_charge_status() and move it up so it can be used
+by hidinput_update_battery().
+
+Refactor, no functional changes.
+
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Stable-dep-of: e94536e1d181 ("HID: input: report battery status changes immediately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input-test.c | 10 +++++-----
+ drivers/hid/hid-input.c      | 38 ++++++++++++++++++------------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7..6f5c71660d823 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+ #include <kunit/test.h>
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+       struct hid_device *dev;
+       bool handled;
+@@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
+       dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+-      handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+       KUNIT_EXPECT_FALSE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
+ }
+ static struct kunit_case hid_input_tests[] = {
+-      KUNIT_CASE(hid_test_input_set_battery_charge_status),
++      KUNIT_CASE(hid_test_input_update_battery_charge_status),
+       KUNIT_CASE(hid_test_input_get_battery_property),
+       { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index b0091819fd58a..51be30b7c1851 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -609,6 +609,20 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+       dev->battery = NULL;
+ }
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
++{
++      switch (usage) {
++      case HID_BAT_CHARGING:
++              dev->battery_charge_status = value ?
++                                           POWER_SUPPLY_STATUS_CHARGING :
++                                           POWER_SUPPLY_STATUS_DISCHARGING;
++              return true;
++      }
++
++      return false;
++}
++
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+       int capacity;
+@@ -631,20 +645,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
+               power_supply_changed(dev->battery);
+       }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
+-{
+-      switch (usage) {
+-      case HID_BAT_CHARGING:
+-              dev->battery_charge_status = value ?
+-                                           POWER_SUPPLY_STATUS_CHARGING :
+-                                           POWER_SUPPLY_STATUS_DISCHARGING;
+-              return true;
+-      }
+-
+-      return false;
+-}
+ #else  /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+                                 struct hid_field *field, bool is_percentage)
+@@ -656,14 +656,14 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
+ {
++      return false;
+ }
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+-      return false;
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1509,7 +1509,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+               return;
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++              bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+               if (!handled)
+                       hidinput_update_battery(hid, value);
+-- 
+2.50.1
+
diff --git a/queue-6.1/hid-input-report-battery-status-changes-immediately.patch b/queue-6.1/hid-input-report-battery-status-changes-immediately.patch
new file mode 100644 (file)
index 0000000..9e2bd5d
--- /dev/null
@@ -0,0 +1,97 @@
+From dfa8b47f74e76e1341248105b248a16cbac24cd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:40 +0200
+Subject: HID: input: report battery status changes immediately
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit e94536e1d1818b0989aa19b443b7089f50133c35 ]
+
+Previously, the battery status (charging/discharging) was not reported
+immediately to user-space. 
+
+For most input devices, this wasn't problematic because changing their
+battery status requires connecting them to a different bus.
+For example, a gamepad would report a discharging status while
+connected via Bluetooth and a charging status while connected via USB.
+
+However, certain devices are not connected or disconnected when their
+battery status changes. For example, a phone battery changes its status
+without connecting or disconnecting it.
+In these cases, the battery status was not reported immediately to user
+space.
+
+Report battery status changes immediately to user space to support
+these kinds of devices.
+
+Fixes: a608dc1c0639 ("HID: input: map battery system charging")
+Reported-by: 卢国宏 <luguohong@xiaomi.com>
+Closes: https://lore.kernel.org/linux-input/aI49Im0sGb6fpgc8@fedora/T/
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 51be30b7c1851..cd9d031858438 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -623,13 +623,19 @@ static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+       return false;
+ }
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++                                  int value)
+ {
+       int capacity;
+       if (!dev->battery)
+               return;
++      if (hidinput_update_battery_charge_status(dev, usage, value)) {
++              power_supply_changed(dev->battery);
++              return;
++      }
++
+       if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+               return;
+@@ -656,13 +662,8 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+-static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+-                                                unsigned int usage, int value)
+-{
+-      return false;
+-}
+-
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++                                  int value)
+ {
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1509,11 +1510,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+               return;
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+-
+-              if (!handled)
+-                      hidinput_update_battery(hid, value);
+-
++              hidinput_update_battery(hid, usage->hid, value);
+               return;
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-dlink-fix-multicast-stats-being-counted-incorrec.patch b/queue-6.1/net-dlink-fix-multicast-stats-being-counted-incorrec.patch
new file mode 100644 (file)
index 0000000..25238a6
--- /dev/null
@@ -0,0 +1,46 @@
+From ff0fa8ea093748ab38ebcb7f54a9e9bd08e1cf5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index dfc23cc173097..2acb63b547c35 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1094,7 +1094,7 @@ get_stats (struct net_device *dev)
+       dev->stats.rx_bytes += dr32(OctetRcvOk);
+       dev->stats.tx_bytes += dr32(OctetXmtOk);
+-      dev->stats.multicast = dr32(McstFramesRcvdOk);
++      dev->stats.multicast += dr32(McstFramesRcvdOk);
+       dev->stats.collisions += dr32(SingleColFrames)
+                            +  dr32(MultiColFrames);
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-ipv4-fix-regression-in-local-broadcast-routes.patch b/queue-6.1/net-ipv4-fix-regression-in-local-broadcast-routes.patch
new file mode 100644 (file)
index 0000000..d78d8d6
--- /dev/null
@@ -0,0 +1,57 @@
+From 3acb75e4c01db107debd7ea6867cdc8347d95c87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index c57a1cee98e2c..395bc567b15d3 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2549,12 +2549,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+                   !netif_is_l3_master(dev_out))
+                       return ERR_PTR(-EINVAL);
+-      if (ipv4_is_lbcast(fl4->daddr))
++      if (ipv4_is_lbcast(fl4->daddr)) {
+               type = RTN_BROADCAST;
+-      else if (ipv4_is_multicast(fl4->daddr))
++
++              /* reset fi to prevent gateway resolution */
++              fi = NULL;
++      } else if (ipv4_is_multicast(fl4->daddr)) {
+               type = RTN_MULTICAST;
+-      else if (ipv4_is_zeronet(fl4->daddr))
++      } else if (ipv4_is_zeronet(fl4->daddr)) {
+               return ERR_PTR(-EINVAL);
++      }
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch b/queue-6.1/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
new file mode 100644 (file)
index 0000000..9c5f903
--- /dev/null
@@ -0,0 +1,51 @@
+From 831c343133b7497cd786713a7620c835e70ba618 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:28 +0300
+Subject: net/mlx5: Reload auxiliary drivers on fw_activate
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 34cc6a54914f478c93e176450fae6313404f9f74 ]
+
+The devlink reload fw_activate command performs firmware activation
+followed by driver reload, while devlink reload driver_reinit triggers
+only driver reload. However, the driver reload logic differs between the
+two modes, as on driver_reinit mode mlx5 also reloads auxiliary drivers,
+while in fw_activate mode the auxiliary drivers are suspended where
+applicable.
+
+Additionally, following the cited commit, if the device has multiple PFs,
+the behavior during fw_activate may vary between PFs: one PF may suspend
+auxiliary drivers, while another reloads them.
+
+Align devlink dev reload fw_activate behavior with devlink dev reload
+driver_reinit, to reload all auxiliary drivers.
+
+Fixes: 72ed5d5624af ("net/mlx5: Suspend auxiliary devices only in case of PCI device suspend")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 3749eb83d9e53..64dcfac9ce724 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -108,7 +108,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+       if (err)
+               return err;
+-      mlx5_unload_one_devl_locked(dev, true);
++      mlx5_unload_one_devl_locked(dev, false);
+       err = mlx5_health_wait_pci_up(dev);
+       if (err)
+               NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-mlx5e-set-local-xoff-after-fw-update.patch b/queue-6.1/net-mlx5e-set-local-xoff-after-fw-update.patch
new file mode 100644 (file)
index 0000000..9196c58
--- /dev/null
@@ -0,0 +1,50 @@
+From 2f9f2ec5cef9ae7ab2205ed3024788126759b0d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+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 c9d5d8d93994d..7899a7230299d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -346,7 +346,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+               if (err)
+                       return err;
+       }
+-      priv->dcbx.xoff = xoff;
+       /* Apply the settings */
+       if (update_buffer) {
+@@ -355,6 +354,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                       return err;
+       }
++      priv->dcbx.xoff = xoff;
++
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch b/queue-6.1/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
new file mode 100644 (file)
index 0000000..b2ec6f2
--- /dev/null
@@ -0,0 +1,100 @@
+From 08f0d6bce3462cf84ed26cceed7135a084912a20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h         | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c   | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+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..a23e3d810f3e4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -63,11 +63,23 @@ struct mlx5e_port_buffer {
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_BUFFER];
+ };
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++                              u32 change, unsigned int mtu,
++                              void *pfc,
++                              u32 *buffer_size,
++                              u8 *prio2buffer)
++{
++      return 0;
++}
++#endif
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 887d446354006..7612070b66160 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -42,6 +42,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2640,9 +2641,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+       struct mlx5e_params *params = &priv->channels.params;
+       struct net_device *netdev = priv->netdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
+-      u16 mtu;
++      u16 mtu, prev_mtu;
+       int err;
++      mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+       err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+       if (err)
+               return err;
+@@ -2652,6 +2655,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+               netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+                           __func__, mtu, params->sw_mtu);
++      if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++              err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++                                                    NULL, NULL, NULL);
++              if (err) {
++                      netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++                                  __func__, mtu, err, prev_mtu);
++
++                      mlx5e_set_mtu(mdev, params, prev_mtu);
++                      return err;
++              }
++      }
++
+       params->sw_mtu = mtu;
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch b/queue-6.1/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
new file mode 100644 (file)
index 0000000..100c216
--- /dev/null
@@ -0,0 +1,46 @@
+From b798855a1158684e6262f6096495bc5e99464e14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 7612070b66160..ae3a7b96f7978 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -107,6 +107,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+       if (up) {
+               netdev_info(priv->netdev, "Link up\n");
+               netif_carrier_on(priv->netdev);
++              mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++                                              NULL, NULL, NULL);
+       } else {
+               netdev_info(priv->netdev, "Link down\n");
+               netif_carrier_off(priv->netdev);
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-rose-convert-use-field-to-refcount_t.patch b/queue-6.1/net-rose-convert-use-field-to-refcount_t.patch
new file mode 100644 (file)
index 0000000..2a59db1
--- /dev/null
@@ -0,0 +1,370 @@
+From 9666ef8acc9799c4e776bfe40ead3ee83f50da46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:56 +0900
+Subject: net: rose: convert 'use' field to refcount_t
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit d860d1faa6b2ce3becfdb8b0c2b048ad31800061 ]
+
+The 'use' field in struct rose_neigh is used as a reference counter but
+lacks atomicity. This can lead to race conditions where a rose_neigh
+structure is freed while still being referenced by other code paths.
+
+For example, when rose_neigh->use becomes zero during an ioctl operation
+via rose_rt_ioctl(), the structure may be removed while its timer is
+still active, potentially causing use-after-free issues.
+
+This patch changes the type of 'use' from unsigned short to refcount_t and
+updates all code paths to use rose_neigh_hold() and rose_neigh_put() which
+operate reference counts atomically.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-3-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h    | 18 +++++++++++++-----
+ net/rose/af_rose.c    | 13 +++++++------
+ net/rose/rose_in.c    | 12 ++++++------
+ net/rose/rose_route.c | 33 ++++++++++++++++++---------------
+ net/rose/rose_timer.c |  2 +-
+ 5 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 174b4f605d849..2b5491bbf39ab 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H 
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+       ax25_cb                 *ax25;
+       struct net_device               *dev;
+       unsigned short          count;
+-      unsigned short          use;
++      refcount_t              use;
+       unsigned int            number;
+       char                    restarted;
+       char                    dce_mode;
+@@ -151,12 +152,19 @@ struct rose_sock {
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++      refcount_inc(&rose_neigh->use);
++}
++
+ static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
+ {
+-      if (rose_neigh->ax25)
+-              ax25_cb_put(rose_neigh->ax25);
+-      kfree(rose_neigh->digipeat);
+-      kfree(rose_neigh);
++      if (refcount_dec_and_test(&rose_neigh->use)) {
++              if (rose_neigh->ax25)
++                      ax25_cb_put(rose_neigh->ax25);
++              kfree(rose_neigh->digipeat);
++              kfree(rose_neigh);
++      }
+ }
+ /* af_rose.c */
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index b21c2ce401928..5a0bf022a84be 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+               if (rose->neighbour == neigh) {
+                       rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour = NULL;
+               }
+       }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+               if (rose->device == dev) {
+                       rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+                       if (rose->neighbour)
+-                              rose->neighbour->use--;
++                              rose_neigh_put(rose->neighbour);
+                       netdev_put(rose->device, &rose->dev_tracker);
+                       rose->device = NULL;
+               }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+               break;
+       case ROSE_STATE_2:
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               release_sock(sk);
+               rose_disconnect(sk, 0, -1, -1);
+               lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       rose->lci = rose_new_lci(rose->neighbour);
+       if (!rose->lci) {
+               err = -ENETUNREACH;
++              rose_neigh_put(rose->neighbour);
+               goto out_release;
+       }
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+               dev = rose_dev_first();
+               if (!dev) {
+                       err = -ENETUNREACH;
++                      rose_neigh_put(rose->neighbour);
+                       goto out_release;
+               }
+               user = ax25_findbyuid(current_euid());
+               if (!user) {
+                       err = -EINVAL;
++                      rose_neigh_put(rose->neighbour);
+                       dev_put(dev);
+                       goto out_release;
+               }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       rose->state = ROSE_STATE_1;
+-      rose->neighbour->use++;
+-
+       rose_write_internal(sk, ROSE_CALL_REQUEST);
+       rose_start_heartbeat(sk);
+       rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
+                            GFP_ATOMIC);
+       make_rose->facilities    = facilities;
+-      make_rose->neighbour->use++;
++      rose_neigh_hold(make_rose->neighbour);
+       if (rose_sk(sk)->defer) {
+               make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b4..7caae93937ee9 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       case ROSE_CLEAR_CONFIRMATION:
+               rose_disconnect(sk, 0, -1, -1);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety
+       if (frametype == ROSE_CLEAR_REQUEST) {
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose_sk(sk)->neighbour->use--;
++              rose_neigh_put(rose_sk(sk)->neighbour);
+       }
+       return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index b406b1e0fb1e7..42460da0854d5 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+               rose_neigh->ax25      = NULL;
+               rose_neigh->dev       = dev;
+               rose_neigh->count     = 0;
+-              rose_neigh->use       = 0;
+               rose_neigh->dce_mode  = 0;
+               rose_neigh->loopback  = 0;
+               rose_neigh->number    = rose_neigh_no++;
+               rose_neigh->restarted = 0;
++              refcount_set(&rose_neigh->use, 1);
+               skb_queue_head_init(&rose_neigh->queue);
+@@ -255,10 +255,10 @@ static void rose_remove_route(struct rose_route *rose_route)
+       struct rose_route *s;
+       if (rose_route->neigh1 != NULL)
+-              rose_route->neigh1->use--;
++              rose_neigh_put(rose_route->neigh1);
+       if (rose_route->neigh2 != NULL)
+-              rose_route->neigh2->use--;
++              rose_neigh_put(rose_route->neigh2);
+       if ((s = rose_route_list) == rose_route) {
+               rose_route_list = rose_route->next;
+@@ -323,7 +323,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0) {
++                      if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
+                               rose_neigh_put(rose_neigh);
+                       }
+@@ -375,11 +375,11 @@ void rose_add_loopback_neigh(void)
+       sn->ax25      = NULL;
+       sn->dev       = NULL;
+       sn->count     = 0;
+-      sn->use       = 0;
+       sn->dce_mode  = 1;
+       sn->loopback  = 1;
+       sn->number    = rose_neigh_no++;
+       sn->restarted = 1;
++      refcount_set(&sn->use, 1);
+       skb_queue_head_init(&sn->queue);
+@@ -561,8 +561,7 @@ static int rose_clear_routes(void)
+               s          = rose_neigh;
+               rose_neigh = rose_neigh->next;
+-              if (s->use == 0 && !s->loopback) {
+-                      s->count = 0;
++              if (!s->loopback) {
+                       rose_remove_neigh(s);
+                       rose_neigh_put(s);
+               }
+@@ -680,6 +679,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+                       for (i = 0; i < node->count; i++) {
+                               if (node->neighbour[i]->restarted) {
+                                       res = node->neighbour[i];
++                                      rose_neigh_hold(node->neighbour[i]);
+                                       goto out;
+                               }
+                       }
+@@ -691,6 +691,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+                               for (i = 0; i < node->count; i++) {
+                                       if (!rose_ftimer_running(node->neighbour[i])) {
+                                               res = node->neighbour[i];
++                                              rose_neigh_hold(node->neighbour[i]);
+                                               goto out;
+                                       }
+                                       failed = 1;
+@@ -780,13 +781,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
+               }
+               if (rose_route->neigh1 == rose_neigh) {
+-                      rose_route->neigh1->use--;
++                      rose_neigh_put(rose_route->neigh1);
+                       rose_route->neigh1 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+               }
+               if (rose_route->neigh2 == rose_neigh) {
+-                      rose_route->neigh2->use--;
++                      rose_neigh_put(rose_route->neigh2);
+                       rose_route->neigh2 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+               }
+@@ -915,7 +916,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+                       rose_clear_queues(sk);
+                       rose->cause      = ROSE_NETWORK_CONGESTION;
+                       rose->diagnostic = 0;
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour  = NULL;
+                       rose->lci        = 0;
+                       rose->state      = ROSE_STATE_0;
+@@ -1040,12 +1041,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+               rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
+-              goto out;
++              goto put_neigh;
+       }
+       if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+               rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+-              goto out;
++              goto put_neigh;
+       }
+       rose_route->lci1      = lci;
+@@ -1058,8 +1059,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_route->lci2      = new_lci;
+       rose_route->neigh2    = new_neigh;
+-      rose_route->neigh1->use++;
+-      rose_route->neigh2->use++;
++      rose_neigh_hold(rose_route->neigh1);
++      rose_neigh_hold(rose_route->neigh2);
+       rose_route->next = rose_route_list;
+       rose_route_list  = rose_route;
+@@ -1071,6 +1072,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_transmit_link(skb, rose_route->neigh2);
+       res = 1;
++put_neigh:
++      rose_neigh_put(new_neigh);
+ out:
+       spin_unlock_bh(&rose_route_list_lock);
+       spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1186,7 +1189,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         rose_neigh->use,
++                         refcount_read(&rose_neigh->use) - 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 1525773e94aa1..c52d7d20c5199 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+               break;
+       case ROSE_STATE_2:      /* T3 */
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               rose_disconnect(sk, ETIMEDOUT, -1, -1);
+               break;
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-rose-include-node-references-in-rose_neigh-refco.patch b/queue-6.1/net-rose-include-node-references-in-rose_neigh-refco.patch
new file mode 100644 (file)
index 0000000..f84a51f
--- /dev/null
@@ -0,0 +1,142 @@
+From 9d5f8b18b47e19d73d093926dfd2aedc48c01c5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:57 +0900
+Subject: net: rose: include node references in rose_neigh refcount
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit da9c9c877597170b929a6121a68dcd3dd9a80f45 ]
+
+Current implementation maintains two separate reference counting
+mechanisms: the 'count' field in struct rose_neigh tracks references from
+rose_node structures, while the 'use' field (now refcount_t) tracks
+references from rose_sock.
+
+This patch merges these two reference counting systems using 'use' field
+for proper reference management. Specifically, this patch adds incrementing
+and decrementing of rose_neigh->use when rose_neigh->count is incremented
+or decremented.
+
+This patch also modifies rose_rt_free(), rose_rt_device_down() and
+rose_clear_route() to properly release references to rose_neigh objects
+before freeing a rose_node through rose_remove_node().
+
+These changes ensure rose_neigh structures are properly freed only when
+all references, including those from rose_node structures, are released.
+As a result, this resolves a slab-use-after-free issue reported by Syzbot.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+942297eecf7d2d61d1f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=942297eecf7d2d61d1f1
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-4-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/rose_route.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 42460da0854d5..6acbb795c506d 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+                       }
+               }
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+               goto out;
+       }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+               rose_node->neighbour[rose_node->count] = rose_neigh;
+               rose_node->count++;
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+       }
+ out:
+@@ -322,6 +324,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+       for (i = 0; i < rose_node->count; i++) {
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
++                      rose_neigh_put(rose_neigh);
+                       if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
+@@ -430,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+       rose_node_list  = rose_node;
+       rose_loopback_neigh->count++;
++      rose_neigh_hold(rose_loopback_neigh);
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -461,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+       rose_remove_node(rose_node);
+       rose_loopback_neigh->count--;
++      rose_neigh_put(rose_loopback_neigh);
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -500,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+                               memmove(&t->neighbour[i], &t->neighbour[i + 1],
+                                       sizeof(t->neighbour[0]) *
+                                               (t->count - i));
++                              rose_neigh_put(s);
+                       }
+                       if (t->count <= 0)
+@@ -543,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+       struct rose_neigh *s, *rose_neigh;
+       struct rose_node  *t, *rose_node;
++      int i;
+       spin_lock_bh(&rose_node_list_lock);
+       spin_lock_bh(&rose_neigh_list_lock);
+@@ -553,8 +560,12 @@ static int rose_clear_routes(void)
+       while (rose_node != NULL) {
+               t         = rose_node;
+               rose_node = rose_node->next;
+-              if (!t->loopback)
++
++              if (!t->loopback) {
++                      for (i = 0; i < rose_node->count; i++)
++                              rose_neigh_put(t->neighbour[i]);
+                       rose_remove_node(t);
++              }
+       }
+       while (rose_neigh != NULL) {
+@@ -1189,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         refcount_read(&rose_neigh->use) - 1,
++                         refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1294,6 +1305,7 @@ void __exit rose_rt_free(void)
+       struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+       struct rose_node  *t, *rose_node  = rose_node_list;
+       struct rose_route *u, *rose_route = rose_route_list;
++      int i;
+       while (rose_neigh != NULL) {
+               s          = rose_neigh;
+@@ -1307,6 +1319,8 @@ void __exit rose_rt_free(void)
+               t         = rose_node;
+               rose_node = rose_node->next;
++              for (i = 0; i < t->count; i++)
++                      rose_neigh_put(t->neighbour[i]);
+               rose_remove_node(t);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-rose-split-remove-and-free-operations-in-rose_re.patch b/queue-6.1/net-rose-split-remove-and-free-operations-in-rose_re.patch
new file mode 100644 (file)
index 0000000..07dfe5c
--- /dev/null
@@ -0,0 +1,115 @@
+From 3c8bbd7d9ec2674b5e4dd6ed3fb22c2486bb1b4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:55 +0900
+Subject: net: rose: split remove and free operations in rose_remove_neigh()
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit dcb34659028f856c423a29ef9b4e2571d203444d ]
+
+The current rose_remove_neigh() performs two distinct operations:
+1. Removes rose_neigh from rose_neigh_list
+2. Frees the rose_neigh structure
+
+Split these operations into separate functions to improve maintainability
+and prepare for upcoming refcount_t conversion. The timer cleanup remains
+in rose_remove_neigh() because free operations can be called from timer
+itself.
+
+This patch introduce rose_neigh_put() to handle the freeing of rose_neigh
+structures and modify rose_remove_neigh() to handle removal only.
+
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-2-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h    |  8 ++++++++
+ net/rose/rose_route.c | 15 ++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa3..174b4f605d849 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -151,6 +151,14 @@ struct rose_sock {
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++      if (rose_neigh->ax25)
++              ax25_cb_put(rose_neigh->ax25);
++      kfree(rose_neigh->digipeat);
++      kfree(rose_neigh);
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int  sysctl_rose_restart_request_timeout;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index a7054546f52df..b406b1e0fb1e7 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,20 +234,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+       if ((s = rose_neigh_list) == rose_neigh) {
+               rose_neigh_list = rose_neigh->next;
+-              if (rose_neigh->ax25)
+-                      ax25_cb_put(rose_neigh->ax25);
+-              kfree(rose_neigh->digipeat);
+-              kfree(rose_neigh);
+               return;
+       }
+       while (s != NULL && s->next != NULL) {
+               if (s->next == rose_neigh) {
+                       s->next = rose_neigh->next;
+-                      if (rose_neigh->ax25)
+-                              ax25_cb_put(rose_neigh->ax25);
+-                      kfree(rose_neigh->digipeat);
+-                      kfree(rose_neigh);
+                       return;
+               }
+@@ -331,8 +323,10 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0)
++                      if (rose_neigh->count == 0 && rose_neigh->use == 0) {
+                               rose_remove_neigh(rose_neigh);
++                              rose_neigh_put(rose_neigh);
++                      }
+                       rose_node->count--;
+@@ -513,6 +507,7 @@ void rose_rt_device_down(struct net_device *dev)
+               }
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       spin_unlock_bh(&rose_neigh_list_lock);
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -569,6 +564,7 @@ static int rose_clear_routes(void)
+               if (s->use == 0 && !s->loopback) {
+                       s->count = 0;
+                       rose_remove_neigh(s);
++                      rose_neigh_put(s);
+               }
+       }
+@@ -1301,6 +1297,7 @@ void __exit rose_rt_free(void)
+               rose_neigh = rose_neigh->next;
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       while (rose_node != NULL) {
+-- 
+2.50.1
+
diff --git a/queue-6.1/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch b/queue-6.1/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
new file mode 100644 (file)
index 0000000..c83d96d
--- /dev/null
@@ -0,0 +1,49 @@
+From e4d3b2f3c42ea950f76ef8f986c6084ee0b23228 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5e98355f422b3..3e4318d5dcdf5 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -199,10 +199,6 @@ static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+       }
+       writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+-      /* Enable MTL RX overflow */
+-      value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+-      writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+-- 
+2.50.1
+
diff --git a/queue-6.1/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch b/queue-6.1/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
new file mode 100644 (file)
index 0000000..2fbee29
--- /dev/null
@@ -0,0 +1,135 @@
+From 9da465f24262fd3c9e37cca7ad2144a4c8ef0eaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h      |  4 ++++
+ drivers/net/phy/mscc/mscc_main.c |  4 +---
+ drivers/net/phy/mscc/mscc_ptp.c  | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 878298304430c..fcfbff691b3c6 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -474,6 +474,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -488,6 +489,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+       return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+       return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index 36734bb217e42..2fabb6a7d2415 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2326,9 +2326,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *priv = phydev->priv;
+-
+-      skb_queue_purge(&priv->rx_skbs_list);
++      vsc8584_ptp_deinit(phydev);
+ }
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index add1a9ee721af..1f6237705b44b 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1297,7 +1297,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *vsc8531 = phydev->priv;
+       static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+       static const u8  ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+       u32 val;
+@@ -1514,17 +1513,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+       vsc85xx_ts_eth_cmp1_sig(phydev);
+-      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+-      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+-      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+-      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
+-      phydev->mii_ts = &vsc8531->mii_ts;
+-
+-      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+-      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+-                                                   &phydev->mdio.dev);
+-      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++      return 0;
+ }
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1551,6 +1540,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+       return 0;
+ }
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++      struct vsc8531_private *vsc8531 = phydev->priv;
++
++      if (vsc8531->ptp->ptp_clock) {
++              ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++              skb_queue_purge(&vsc8531->rx_skbs_list);
++      }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+       struct vsc8531_private *priv = phydev->priv;
+@@ -1608,7 +1607,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+       vsc8531->ptp->phydev = phydev;
+-      return 0;
++      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
++      phydev->mii_ts = &vsc8531->mii_ts;
++
++      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++                                                   &phydev->mdio.dev);
++      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+-- 
+2.50.1
+
diff --git a/queue-6.1/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch b/queue-6.1/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
new file mode 100644 (file)
index 0000000..7201bcb
--- /dev/null
@@ -0,0 +1,68 @@
+From fea42020e1cc8cf9cd2d6c512325306a8903b262 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf..7209d00a9c257 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+       }
+-      switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++      switch (inst_no_rt & ~KVM_MASK_RB) {
+       case KVM_INST_MTSRIN:
+               if (features & KVM_MAGIC_FEAT_SR) {
+                       u32 inst_rb = _inst & KVM_MASK_RB;
+                       kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+               }
+               break;
+-#endif
+       }
++#endif
+-      switch (_inst) {
+ #ifdef CONFIG_BOOKE
++      switch (_inst) {
+       case KVM_INST_WRTEEI_0:
+               kvm_patch_ins_wrteei_0(inst);
+               break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+       case KVM_INST_WRTEEI_1:
+               kvm_patch_ins_wrtee(inst, 0, 1);
+               break;
+-#endif
+       }
++#endif
+ }
+ extern u32 kvm_template_start[];
+-- 
+2.50.1
+
diff --git a/queue-6.1/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch b/queue-6.1/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
new file mode 100644 (file)
index 0000000..a0828d6
--- /dev/null
@@ -0,0 +1,72 @@
+From 192861fb3fee49d6282d4a56c7068160ef4216f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+  sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+  sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+  sctp_get_port net/sctp/socket.c:8523 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+  x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+  do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+  sctp_get_port net/sctp/socket.c:8515 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index d081858c2d073..a1cb8ac0408af 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -547,7 +547,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+       addr->v6.sin6_family = AF_INET6;
+       addr->v6.sin6_port = 0;
++      addr->v6.sin6_flowinfo = 0;
+       addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++      addr->v6.sin6_scope_id = 0;
+ }
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+-- 
+2.50.1
+
index 522cbe2ac5bd130c9dd4669b46a94e340e7f023f..39e2b81d221c3377c141bf4266d5adaa972aece9 100644 (file)
@@ -10,3 +10,25 @@ acpi-ec-add-device-to-acpi_ec_no_wakeup-qurik-list.patch
 nfs-fold-nfs_page_group_lock_subrequests-into-nfs_lock_and_join_requests.patch
 nfs-fix-a-race-when-updating-an-existing-write.patch
 vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+drm-msm-defer-fd_install-in-submit-ioctl.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+hid-input-rename-hidinput_set_battery_charge_status.patch
+hid-input-report-battery-status-changes-immediately.patch
+bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
+bluetooth-hci_event-mark-connection-as-closed-during.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+bluetooth-hci_sync-fix-set_local_name-race-condition.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+net-rose-split-remove-and-free-operations-in-rose_re.patch
+net-rose-convert-use-field-to-refcount_t.patch
+net-rose-include-node-references-in-rose_neigh-refco.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
diff --git a/queue-6.12/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch b/queue-6.12/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
new file mode 100644 (file)
index 0000000..c63eae2
--- /dev/null
@@ -0,0 +1,192 @@
+From 687aceb7b0d9af513b48098f317fcb30bf1e67bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+  struct atmtcp_control {
+       struct atmtcp_hdr hdr;  /* must be first */
+  ...
+       atm_kptr_t vcc;         /* both directions */
+  ...
+  } __ATM_API_ALIGN;
+
+  typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+  1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+  2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS:  00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 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+0x19b/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
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c   | 17 ++++++++++++++---
+ include/linux/atmdev.h |  1 +
+ net/atm/common.c       | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index eeae160c898d3..fa3c76a2b49d1 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+         return NULL;
+ }
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++      struct atmtcp_hdr *hdr;
++
++      if (skb->len < sizeof(struct atmtcp_hdr))
++              return -EINVAL;
++
++      hdr = (struct atmtcp_hdr *)skb->data;
++      if (hdr->length == ATMTCP_HDR_MAGIC)
++              return -EINVAL;
++
++      return 0;
++}
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+       struct sk_buff *new_skb;
+       int result = 0;
+-      if (skb->len < sizeof(struct atmtcp_hdr))
+-              goto done;
+-
+       dev = vcc->dev_data;
+       hdr = (struct atmtcp_hdr *) skb->data;
+       if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+       .close          = atmtcp_c_close,
++      .pre_send       = atmtcp_c_pre_send,
+       .send           = atmtcp_c_send
+ };
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
++      int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index d7f7976ea13ac..881c7f259dbd4 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+       skb->dev = NULL; /* for paths shared with net_device interfaces */
+       if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+-              atm_return_tx(vcc, skb);
+-              kfree_skb(skb);
+               error = -EFAULT;
+-              goto out;
++              goto free_skb;
+       }
+       if (eff != size)
+               memset(skb->data + size, 0, eff-size);
++
++      if (vcc->dev->ops->pre_send) {
++              error = vcc->dev->ops->pre_send(vcc, skb);
++              if (error)
++                      goto free_skb;
++      }
++
+       error = vcc->dev->ops->send(vcc, skb);
+       error = error ? error : size;
+ out:
+       release_sock(sk);
+       return error;
++free_skb:
++      atm_return_tx(vcc, skb);
++      kfree_skb(skb);
++      goto out;
+ }
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+-- 
+2.50.1
+
diff --git a/queue-6.12/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch b/queue-6.12/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
new file mode 100644 (file)
index 0000000..2ebb56f
--- /dev/null
@@ -0,0 +1,47 @@
+From 8742d460d4ff9605984e6f4221b08411b078b60f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index b8213bfa0a674..262ff30261d67 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4395,7 +4395,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+               if (!conn)
+                       continue;
+-              conn->sent -= count;
++              /* Check if there is really enough packets outstanding before
++               * attempting to decrease the sent counter otherwise it could
++               * underflow..
++               */
++              if (conn->sent >= count) {
++                      conn->sent -= count;
++              } else {
++                      bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++                                  conn, conn->sent, count);
++                      conn->sent = 0;
++              }
+               switch (conn->type) {
+               case ACL_LINK:
+-- 
+2.50.1
+
diff --git a/queue-6.12/bluetooth-hci_event-mark-connection-as-closed-during.patch b/queue-6.12/bluetooth-hci_event-mark-connection-as-closed-during.patch
new file mode 100644 (file)
index 0000000..5a0b9f0
--- /dev/null
@@ -0,0 +1,80 @@
+From a38f9aa0ee062b0243b10165b8a71996ed90c694 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:27 +0200
+Subject: Bluetooth: hci_event: Mark connection as closed during suspend
+ disconnect
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit b7fafbc499b5ee164018eb0eefe9027f5a6aaad2 ]
+
+When suspending, the disconnect command for an active Bluetooth
+connection could be issued, but the corresponding
+`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
+completes the suspend process. This can lead to an inconsistent state.
+
+On resume, the controller may auto-accept reconnections from the same
+device (due to suspend event filters), but these new connections are
+rejected by the kernel which still has connection objects from before
+suspend. Resulting in errors like:
+```
+kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
+kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
+connection
+```
+
+This is a btmon snippet that shows the issue:
+```
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+        Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+        Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+      Disconnect (0x01|0x0006) ncmd 2
+        Status: Success (0x00)
+[...]
+// Host suspends with the event filter set for the device
+// On resume, the device tries to reconnect with a new handle
+
+> HCI Event: Connect Complete (0x03) plen 11
+        Status: Success (0x00)
+        Handle: 2
+        Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+
+// Kernel ignores this event because there is an existing connection
+with
+// handle 1
+```
+
+By explicitly setting the connection state to BT_CLOSED we can ensure a
+consistent state, even if we don't receive the disconnect complete event
+in time.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 428aba38a3654..b8213bfa0a674 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2709,6 +2709,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+               goto done;
+       }
++      /* During suspend, mark connection as closed immediately
++       * since we might not receive HCI_EV_DISCONN_COMPLETE
++       */
++      if (hdev->suspended)
++              conn->state = BT_CLOSED;
++
+       mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+       if (conn->type == ACL_LINK) {
+-- 
+2.50.1
+
diff --git a/queue-6.12/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch b/queue-6.12/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
new file mode 100644 (file)
index 0000000..74f8c4a
--- /dev/null
@@ -0,0 +1,84 @@
+From eacf8dc08de40aae74d47b0f4990737307871633 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:26 +0200
+Subject: Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit 2f050a5392b7a0928bf836d9891df4851463512c ]
+
+When the host sends an HCI_OP_DISCONNECT command, the controller may
+respond with the status HCI_ERROR_UNKNOWN_CONN_ID (0x02). E.g. this can
+happen on resume from suspend, if the link was terminated by the remote
+device before the event mask was correctly set.
+
+This is a btmon snippet that shows the issue:
+```
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+      L2CAP: Disconnection Request (0x06) ident 5 len 4
+        Destination CID: 65
+        Source CID: 72
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+      L2CAP: Disconnection Response (0x07) ident 5 len 4
+        Destination CID: 65
+        Source CID: 72
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+      L2CAP: Disconnection Request (0x06) ident 6 len 4
+        Destination CID: 64
+        Source CID: 71
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+      L2CAP: Disconnection Response (0x07) ident 6 len 4
+        Destination CID: 64
+        Source CID: 71
+< HCI Command: Set Event Mask (0x03|0x0001) plen 8
+        Mask: 0x3dbff807fffbffff
+          Inquiry Complete
+          Inquiry Result
+          Connection Complete
+          Connection Request
+          Disconnection Complete
+          Authentication Complete
+[...]
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+        Handle: 3 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+        Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+      Disconnect (0x01|0x0006) ncmd 1
+        Status: Unknown Connection Identifier (0x02)
+```
+
+Currently, the hci_cs_disconnect function treats any non-zero status
+as a command failure. This can be misleading because the connection is
+indeed being terminated and the controller is confirming that is has no
+knowledge of that connection handle. Meaning that the initial request of
+disconnecting a device should be treated as done.
+
+With this change we allow the function to proceed, following the success
+path, which correctly calls `mgmt_device_disconnected` and ensures a
+consistent state.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 768bd5fd808f2..428aba38a3654 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2694,7 +2694,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+       if (!conn)
+               goto unlock;
+-      if (status) {
++      if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+               mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+                                      conn->dst_type, status);
+-- 
+2.50.1
+
diff --git a/queue-6.12/bluetooth-hci_sync-fix-set_local_name-race-condition.patch b/queue-6.12/bluetooth-hci_sync-fix-set_local_name-race-condition.patch
new file mode 100644 (file)
index 0000000..e180c08
--- /dev/null
@@ -0,0 +1,90 @@
+From 1efa42f26b69b7a61f88a8c52cb27c12632a334a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 12:20:55 +0300
+Subject: Bluetooth: hci_sync: fix set_local_name race condition
+
+From: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+
+[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]
+
+Function set_name_sync() uses hdev->dev_name field to send
+HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
+is called after mgmt cmd was queued, so it is possible that function
+set_name_sync() will read old name value.
+
+This change adds name as a parameter for function hci_update_name_sync()
+to avoid race condition.
+
+Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
+Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+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>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_sync.c         | 6 +++---
+ net/bluetooth/mgmt.c             | 5 ++++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index dbabc17b30cdf..17e5112f7840e 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -93,7 +93,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index af86df9de941d..bc2aa514b8c5d 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3491,13 +3491,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+       return hci_write_scan_enable_sync(hdev, scan);
+ }
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+       struct hci_cp_write_local_name cp;
+       memset(&cp, 0, sizeof(cp));
+-      memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++      memcpy(cp.name, name, sizeof(cp.name));
+       return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+                                           sizeof(cp), &cp,
+@@ -3550,7 +3550,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+                       hci_write_fast_connectable_sync(hdev, false);
+               hci_update_scan_sync(hdev);
+               hci_update_class_sync(hdev);
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, hdev->dev_name);
+               hci_update_eir_sync(hdev);
+       }
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index ade93532db34b..8b75647076bae 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3826,8 +3826,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++      struct mgmt_pending_cmd *cmd = data;
++      struct mgmt_cp_set_local_name *cp = cmd->param;
++
+       if (lmp_bredr_capable(hdev)) {
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, cp->name);
+               hci_update_eir_sync(hdev);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.12/bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch b/queue-6.12/bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch
new file mode 100644 (file)
index 0000000..a1807e5
--- /dev/null
@@ -0,0 +1,64 @@
+From 8a59728704077d2ebdbcded760bcf3b467776186 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:26 -0700
+Subject: bnxt_en: Adjust TX rings if reservation is less than requested
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 1ee581c24dfdcbc6de25aac95a48c1f08e9a542c ]
+
+Before we accept an ethtool request to increase a resource (such as
+rings), we call the FW to check that the requested resource is likely
+available first before we commit.  But it is still possible that
+the actual reservation or allocation can fail.  The existing code
+is missing the logic to adjust the TX rings in case the reserved
+TX rings are less than requested.  Add a warning message (a similar
+message for RX rings already exists) and add the logic to adjust
+the TX rings.  Without this fix, the number of TX rings reported
+to the stack can exceed the actual TX rings and ethtool -l will
+report more than the actual TX rings.
+
+Fixes: 674f50a5b026 ("bnxt_en: Implement new method to reserve rings.")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-3-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index dc123822771b6..b8c6087a5c31e 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -7788,6 +7788,11 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+               hwr.rx = rx_rings << 1;
+       tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx);
+       hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings;
++      if (hwr.tx != bp->tx_nr_rings) {
++              netdev_warn(bp->dev,
++                          "Able to reserve only %d out of %d requested TX rings\n",
++                          hwr.tx, bp->tx_nr_rings);
++      }
+       bp->tx_nr_rings = hwr.tx;
+       /* If we cannot reserve all the RX rings, reset the RSS map only
+@@ -12269,6 +12274,13 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+       if (rc)
+               return rc;
++      /* Make adjustments if reserved TX rings are less than requested */
++      bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
++      if (bp->tx_nr_rings_xdp) {
++              bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
++              bp->tx_nr_rings += bp->tx_nr_rings_xdp;
++      }
+       rc = bnxt_alloc_mem(bp, irq_re_init);
+       if (rc) {
+               netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
+-- 
+2.50.1
+
diff --git a/queue-6.12/bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch b/queue-6.12/bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch
new file mode 100644 (file)
index 0000000..4a46304
--- /dev/null
@@ -0,0 +1,106 @@
+From a7e3730820faf6b43ca08e0dc86d3b5f3d26e2ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:25 -0700
+Subject: bnxt_en: Fix memory corruption when FW resources change during ifdown
+
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+
+[ Upstream commit 2747328ba2714f1a7454208dbbc1dc0631990b4a ]
+
+bnxt_set_dflt_rings() assumes that it is always called before any TC has
+been created.  So it doesn't take bp->num_tc into account and assumes
+that it is always 0 or 1.
+
+In the FW resource or capability change scenario, the FW will return
+flags in bnxt_hwrm_if_change() that will cause the driver to
+reinitialize and call bnxt_cancel_reservations().  This will lead to
+bnxt_init_dflt_ring_mode() calling bnxt_set_dflt_rings() and bp->num_tc
+may be greater than 1.  This will cause bp->tx_ring[] to be sized too
+small and cause memory corruption in bnxt_alloc_cp_rings().
+
+Fix it by properly scaling the TX rings by bp->num_tc in the code
+paths mentioned above.  Add 2 helper functions to determine
+bp->tx_nr_rings and bp->tx_nr_rings_per_tc.
+
+Fixes: ec5d31e3c15d ("bnxt_en: Handle firmware reset status during IF_UP.")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-2-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index f4bafc71a7399..dc123822771b6 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -12241,6 +12241,17 @@ static int bnxt_set_xps_mapping(struct bnxt *bp)
+       return rc;
+ }
++static int bnxt_tx_nr_rings(struct bnxt *bp)
++{
++      return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc :
++                          bp->tx_nr_rings_per_tc;
++}
++
++static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
++{
++      return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
++}
++
+ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+ {
+       int rc = 0;
+@@ -15676,7 +15687,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
+       bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings);
+       bp->rx_nr_rings = bp->cp_nr_rings;
+       bp->tx_nr_rings_per_tc = bp->cp_nr_rings;
+-      bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++      bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+ }
+ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+@@ -15708,7 +15719,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+               bnxt_trim_dflt_sh_rings(bp);
+       else
+               bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
+-      bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++      bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+       avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
+       if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
+@@ -15721,7 +15732,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+       rc = __bnxt_reserve_rings(bp);
+       if (rc && rc != -ENODEV)
+               netdev_warn(bp->dev, "Unable to reserve tx rings\n");
+-      bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+       if (sh)
+               bnxt_trim_dflt_sh_rings(bp);
+@@ -15730,7 +15741,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+               rc = __bnxt_reserve_rings(bp);
+               if (rc && rc != -ENODEV)
+                       netdev_warn(bp->dev, "2nd rings reservation failed.\n");
+-              bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++              bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+       }
+       if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
+               bp->rx_nr_rings++;
+@@ -15764,7 +15775,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
+       if (rc)
+               goto init_dflt_ring_err;
+-      bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+       bnxt_set_dflt_rfs(bp);
+-- 
+2.50.1
+
diff --git a/queue-6.12/bnxt_en-fix-stats-context-reservation-logic.patch b/queue-6.12/bnxt_en-fix-stats-context-reservation-logic.patch
new file mode 100644 (file)
index 0000000..8906e01
--- /dev/null
@@ -0,0 +1,44 @@
+From 2ffd938d0b3fe90bd0cdbda7e7e124825add1978 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:27 -0700
+Subject: bnxt_en: Fix stats context reservation logic
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit b4fc8faacfea2538184a1dbd616ae9447a361f3d ]
+
+The HW resource reservation logic allows the L2 driver to use the
+RoCE resources if the RoCE driver is not registered.  When calculating
+the stats contexts available for L2, we should not blindly subtract
+the stats contexts reserved for RoCE unless the RoCE driver is
+registered.  This bug may cause the L2 rings to be less than the
+number requested when we are close to running out of stats contexts.
+
+Fixes: 2e4592dc9bee ("bnxt_en: Change MSIX/NQs allocation policy")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-4-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index b8c6087a5c31e..08886c3a28c61 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -7780,7 +7780,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+       }
+       rx_rings = min_t(int, rx_rings, hwr.grp);
+       hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings);
+-      if (hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
++      if (bnxt_ulp_registered(bp->edev) &&
++          hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
+               hwr.stat -= bnxt_get_ulp_stat_ctxs(bp);
+       hwr.cp = min_t(int, hwr.cp, hwr.stat);
+       rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh);
+-- 
+2.50.1
+
diff --git a/queue-6.12/drm-mediatek-add-error-handling-for-old-state-crtc-i.patch b/queue-6.12/drm-mediatek-add-error-handling-for-old-state-crtc-i.patch
new file mode 100644 (file)
index 0000000..40ca4f9
--- /dev/null
@@ -0,0 +1,66 @@
+From 23bb2edbf20032947f7a47761276665fe714ce36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jul 2025 10:48:50 +0800
+Subject: drm/mediatek: Add error handling for old state CRTC in atomic_disable
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 0c6b24d70da21201ed009a2aca740d2dfddc7ab5 ]
+
+Introduce error handling to address an issue where, after a hotplug
+event, the cursor continues to update. This situation can lead to a
+kernel panic due to accessing the NULL `old_state->crtc`.
+
+E,g.
+Unable to handle kernel NULL pointer dereference at virtual address
+Call trace:
+ mtk_crtc_plane_disable+0x24/0x140
+ mtk_plane_atomic_update+0x8c/0xa8
+ drm_atomic_helper_commit_planes+0x114/0x2c8
+ drm_atomic_helper_commit_tail_rpm+0x4c/0x158
+ commit_tail+0xa0/0x168
+ drm_atomic_helper_commit+0x110/0x120
+ drm_atomic_commit+0x8c/0xe0
+ drm_atomic_helper_update_plane+0xd4/0x128
+ __setplane_atomic+0xcc/0x110
+ drm_mode_cursor_common+0x250/0x440
+ drm_mode_cursor_ioctl+0x44/0x70
+ drm_ioctl+0x264/0x5d8
+ __arm64_sys_ioctl+0xd8/0x510
+ invoke_syscall+0x6c/0xe0
+ do_el0_svc+0x68/0xe8
+ el0_svc+0x34/0x60
+ el0t_64_sync_handler+0x1c/0xf8
+ el0t_64_sync+0x180/0x188
+
+Adding NULL pointer checks to ensure stability by preventing operations
+on an invalid CRTC state.
+
+Fixes: d208261e9f7c ("drm/mediatek: Add wait_event_timeout when disabling plane")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20250728025036.24953-1-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_plane.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
+index 74c2704efb664..6e20f7037b5bb 100644
+--- a/drivers/gpu/drm/mediatek/mtk_plane.c
++++ b/drivers/gpu/drm/mediatek/mtk_plane.c
+@@ -292,7 +292,8 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
+       wmb(); /* Make sure the above parameter is set before update */
+       mtk_plane_state->pending.dirty = true;
+-      mtk_crtc_plane_disable(old_state->crtc, plane);
++      if (old_state && old_state->crtc)
++              mtk_crtc_plane_disable(old_state->crtc, plane);
+ }
+ static void mtk_plane_atomic_update(struct drm_plane *plane,
+-- 
+2.50.1
+
diff --git a/queue-6.12/drm-msm-defer-fd_install-in-submit-ioctl.patch b/queue-6.12/drm-msm-defer-fd_install-in-submit-ioctl.patch
new file mode 100644 (file)
index 0000000..ce9c052
--- /dev/null
@@ -0,0 +1,59 @@
+From 93316df3cf5624b86066b09d9e48489023825a58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jul 2025 13:28:22 -0700
+Subject: drm/msm: Defer fd_install in SUBMIT ioctl
+
+From: Rob Clark <robin.clark@oss.qualcomm.com>
+
+[ Upstream commit f22853435bbd1e9836d0dce7fd99c040b94c2bf1 ]
+
+Avoid fd_install() until there are no more potential error paths, to
+avoid put_unused_fd() after the fd is made visible to userspace.
+
+Fixes: 68dc6c2d5eec ("drm/msm: Fix submit error-path leaks")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665363/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index 4b3a8ee8e278f..3eee6517541e3 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -879,12 +879,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+       if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+               sync_file = sync_file_create(submit->user_fence);
+-              if (!sync_file) {
++              if (!sync_file)
+                       ret = -ENOMEM;
+-              } else {
+-                      fd_install(out_fence_fd, sync_file->file);
+-                      args->fence_fd = out_fence_fd;
+-              }
+       }
+       if (ret)
+@@ -912,10 +908,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ out_unlock:
+       mutex_unlock(&queue->lock);
+ out_post_unlock:
+-      if (ret && (out_fence_fd >= 0)) {
+-              put_unused_fd(out_fence_fd);
++      if (ret) {
++              if (out_fence_fd >= 0)
++                      put_unused_fd(out_fence_fd);
+               if (sync_file)
+                       fput(sync_file->file);
++      } else if (sync_file) {
++              fd_install(out_fence_fd, sync_file->file);
++              args->fence_fd = out_fence_fd;
+       }
+       if (!IS_ERR_OR_NULL(submit)) {
+-- 
+2.50.1
+
diff --git a/queue-6.12/drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch b/queue-6.12/drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch
new file mode 100644 (file)
index 0000000..14a063f
--- /dev/null
@@ -0,0 +1,118 @@
+From a57a0e8e68d8d2fbf0fab60ef8f37dca9d5aecd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 18:50:37 +0300
+Subject: drm/msm/kms: move snapshot init earlier in KMS init
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 553666f839b86545300773954df7426a45c169c4 ]
+
+Various parts of the display driver can be triggering the display
+snapshot (including the IOMMU fault handlers). Move the call to
+msm_disp_snapshot_init() before KMS initialization, otherwise it is
+possible to ocassionally trigger the kernel fault during init:
+
+  __lock_acquire+0x44/0x2798 (P)
+  lock_acquire+0x114/0x25c
+  _raw_spin_lock_irqsave+0x6c/0x90
+  kthread_queue_work+0x2c/0xac
+  msm_disp_snapshot_state+0x2c/0x4c
+  msm_kms_fault_handler+0x2c/0x74
+  msm_disp_fault_handler+0x30/0x48
+  report_iommu_fault+0x54/0x128
+  arm_smmu_context_fault+0x74/0x184
+  __handle_irq_event_percpu+0xa4/0x24c
+  handle_irq_event_percpu+0x20/0x5c
+  handle_irq_event+0x48/0x84
+  handle_fasteoi_irq+0xcc/0x170
+  generic_handle_domain_irq+0x48/0x70
+  gic_handle_irq+0x54/0x11c
+  call_on_irq_stack+0x3c/0x50
+  do_interrupt_handler+0x54/0x78
+  el1_interrupt+0x3c/0x5c
+  el1h_64_irq_handler+0x20/0x30
+  el1h_64_irq+0x6c/0x70
+  _raw_spin_unlock_irqrestore+0x44/0x68 (P)
+  klist_next+0xc4/0x124
+  bus_for_each_drv+0x9c/0xe8
+  __device_attach+0xfc/0x190
+  device_initial_probe+0x1c/0x2c
+  bus_probe_device+0x44/0xa0
+  device_add+0x204/0x3e4
+  platform_device_add+0x170/0x244
+  platform_device_register_full+0x130/0x138
+  drm_connector_hdmi_audio_init+0xc0/0x108
+  drm_bridge_connector_init+0x318/0x394
+  msm_dsi_manager_connector_init+0xac/0xdc
+  msm_dsi_modeset_init+0x78/0xc0
+  _dpu_kms_drm_obj_init+0x198/0x75c
+  dpu_kms_hw_init+0x2f8/0x494
+  msm_drm_kms_init+0xb0/0x230
+  msm_drm_init+0x218/0x250
+  msm_drm_bind+0x3c/0x4c
+  try_to_bring_up_aggregate_device+0x208/0x2a4
+  __component_add+0xa8/0x188
+  component_add+0x1c/0x2c
+  dsi_dev_attach+0x24/0x34
+  dsi_host_attach+0x68/0xa0
+  devm_mipi_dsi_attach+0x40/0xcc
+  lt9611_attach_dsi+0x94/0x118
+  lt9611_probe+0x368/0x3c8
+  i2c_device_probe+0x2d0/0x3d8
+  really_probe+0x130/0x354
+  __driver_probe_device+0xac/0x110
+  driver_probe_device+0x44/0x110
+  __device_attach_driver+0xb0/0x138
+  bus_for_each_drv+0x90/0xe8
+  __device_attach+0xfc/0x190
+  device_initial_probe+0x1c/0x2c
+  bus_probe_device+0x44/0xa0
+  deferred_probe_work_func+0xac/0x110
+  process_one_work+0x20c/0x51c
+  process_scheduled_works+0x58/0x88
+  worker_thread+0x1ec/0x304
+  kthread+0x194/0x1d4
+  ret_from_fork+0x10/0x20
+
+Reported-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Fixes: 98659487b845 ("drm/msm: add support to take dpu snapshot")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/664149/
+Link: https://lore.kernel.org/r/20250715-msm-move-snapshot-init-v1-1-f39c396192ab@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_kms.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c
+index 6749f0fbca96d..52464a1346f81 100644
+--- a/drivers/gpu/drm/msm/msm_kms.c
++++ b/drivers/gpu/drm/msm/msm_kms.c
+@@ -241,6 +241,12 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+       if (ret)
+               return ret;
++      ret = msm_disp_snapshot_init(ddev);
++      if (ret) {
++              DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
++              return ret;
++      }
++
+       ret = priv->kms_init(ddev);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "failed to load kms\n");
+@@ -293,10 +299,6 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+               goto err_msm_uninit;
+       }
+-      ret = msm_disp_snapshot_init(ddev);
+-      if (ret)
+-              DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
+-
+       drm_mode_config_reset(ddev);
+       return 0;
+-- 
+2.50.1
+
diff --git a/queue-6.12/drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch b/queue-6.12/drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch
new file mode 100644 (file)
index 0000000..78c080a
--- /dev/null
@@ -0,0 +1,89 @@
+From 3644bfe38ef67e87834d43291a213eec2e79cc48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jul 2025 18:09:38 +0530
+Subject: drm/msm: update the high bitfield of certain DSI registers
+
+From: Ayushi Makhija <quic_amakhija@quicinc.com>
+
+[ Upstream commit 494045c561e68945b1183ff416b8db8e37a122d6 ]
+
+Currently, the high bitfield of certain DSI registers
+do not align with the configuration of the SWI registers
+description. This can lead to wrong programming these DSI
+registers, for example for 4k resloution where H_TOTAL is
+taking 13 bits but software is programming only 12 bits
+because of the incorrect bitmask for H_TOTAL bitfeild,
+this is causing DSI FIFO errors. To resolve this issue,
+increase the high bitfield of the DSI registers from 12 bits
+to 16 bits in dsi.xml to match the SWI register configuration.
+
+Signed-off-by: Ayushi Makhija <quic_amakhija@quicinc.com>
+Fixes: 4f52f5e63b62 ("drm/msm: import XML display registers database")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/666229/
+Link: https://lore.kernel.org/r/20250730123938.1038640-1-quic_amakhija@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/registers/display/dsi.xml | 28 +++++++++----------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/registers/display/dsi.xml b/drivers/gpu/drm/msm/registers/display/dsi.xml
+index 501ffc585a9f6..c7a7b633d747b 100644
+--- a/drivers/gpu/drm/msm/registers/display/dsi.xml
++++ b/drivers/gpu/drm/msm/registers/display/dsi.xml
+@@ -159,28 +159,28 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+               <bitfield name="RGB_SWAP" low="12" high="14" type="dsi_rgb_swap"/>
+       </reg32>
+       <reg32 offset="0x00020" name="ACTIVE_H">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00024" name="ACTIVE_V">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00028" name="TOTAL">
+-              <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+-              <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++              <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++              <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x0002c" name="ACTIVE_HSYNC">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00030" name="ACTIVE_VSYNC_HPOS">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00034" name="ACTIVE_VSYNC_VPOS">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00038" name="CMD_DMA_CTRL">
+@@ -209,8 +209,8 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+               <bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00058" name="CMD_MDP_STREAM0_TOTAL">
+-              <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+-              <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++              <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++              <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x0005c" name="CMD_MDP_STREAM1_CTRL">
+               <bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+-- 
+2.50.1
+
diff --git a/queue-6.12/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch b/queue-6.12/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
new file mode 100644 (file)
index 0000000..6e9f050
--- /dev/null
@@ -0,0 +1,39 @@
+From 9f1639b83ddb706015a8fa3e576957489ed4a49f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:03 -0500
+Subject: drm/nouveau: remove unused increment in gm200_flcn_pio_imem_wr
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit f529b8915543fb9ceb732cec5571f7fe12bc9530 ]
+
+The 'tag' parameter is passed by value and is not actually used after
+being incremented, so remove the increment.  It's the function that calls
+gm200_flcn_pio_imem_wr that is supposed to (and does) increment 'tag'.
+
+Fixes: 0e44c2170876 ("drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)")
+Reviewed-by: Philipp Stanner <phasta@kernel.org>
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-2-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index b7da3ab44c277..6a004c6e67425 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -103,7 +103,7 @@ gm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 i
+ static void
+ gm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
+ {
+-      nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag++);
++      nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag);
+       while (len >= 4) {
+               nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
+               img += 4;
+-- 
+2.50.1
+
diff --git a/queue-6.12/drm-nouveau-remove-unused-memory-target-test.patch b/queue-6.12/drm-nouveau-remove-unused-memory-target-test.patch
new file mode 100644 (file)
index 0000000..0b56ba7
--- /dev/null
@@ -0,0 +1,57 @@
+From 768c07fc37905da64c3caa744c8051260da4965b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:04 -0500
+Subject: drm/nouveau: remove unused memory target test
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit 64c722b5e7f6b909b0e448e580f64628a0d76208 ]
+
+The memory target check is a hold-over from a refactor.  It's harmless
+but distracting, so just remove it.
+
+Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs")
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-3-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index 6a004c6e67425..7c43397c19e61 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -249,9 +249,11 @@ int
+ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ {
+       struct nvkm_falcon *falcon = fw->falcon;
+-      int target, ret;
++      int ret;
+       if (fw->inst) {
++              int target;
++
+               nvkm_falcon_mask(falcon, 0x048, 0x00000001, 0x00000001);
+               switch (nvkm_memory_target(fw->inst)) {
+@@ -285,15 +287,6 @@ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+       }
+       if (fw->boot) {
+-              switch (nvkm_memory_target(&fw->fw.mem.memory)) {
+-              case NVKM_MEM_TARGET_VRAM: target = 4; break;
+-              case NVKM_MEM_TARGET_HOST: target = 5; break;
+-              case NVKM_MEM_TARGET_NCOH: target = 6; break;
+-              default:
+-                      WARN_ON(1);
+-                      return -EINVAL;
+-              }
+-
+               ret = nvkm_falcon_pio_wr(falcon, fw->boot, 0, 0,
+                                        IMEM, falcon->code.limit - fw->boot_size, fw->boot_size,
+                                        fw->boot_addr >> 8, false);
+-- 
+2.50.1
+
diff --git a/queue-6.12/drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch b/queue-6.12/drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch
new file mode 100644 (file)
index 0000000..37f05d0
--- /dev/null
@@ -0,0 +1,48 @@
+From 60f50f33cd54966008a221b09a9f682a0127dcff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:28:41 -0700
+Subject: drm/xe: Don't trigger rebind on initial dma-buf validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ Upstream commit 16ca06aa2c2218cb21907c0c45a746958c944def ]
+
+On the first validate of an imported dma-buf (initial bind), the device
+has no GPU mappings, so a rebind is unnecessary. Rebinding here is
+harmful in multi-GPU setups and for VMs using preempt-fence mode, as it
+would evict in-flight GPU work.
+
+v2:
+ - Drop dma_buf_validated, check for XE_PL_SYSTEM (Thomas)
+
+Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Link: https://lore.kernel.org/r/20250825152841.3837378-1-matthew.brost@intel.com
+(cherry picked from commit ffdf968762e4fb3cdae54e811ec3525e67440a60)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 5f745d9ed6cc2..445bbe0299b08 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -671,7 +671,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+       }
+       if (ttm_bo->type == ttm_bo_type_sg) {
+-              ret = xe_bo_move_notify(bo, ctx);
++              if (new_mem->mem_type == XE_PL_SYSTEM)
++                      ret = xe_bo_move_notify(bo, ctx);
+               if (!ret)
+                       ret = xe_bo_move_dmabuf(ttm_bo, new_mem);
+               return ret;
+-- 
+2.50.1
+
diff --git a/queue-6.12/drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch b/queue-6.12/drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch
new file mode 100644 (file)
index 0000000..05f60b1
--- /dev/null
@@ -0,0 +1,56 @@
+From b324dc7789028df9286c46bfd4fc6fda30707fe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 10:39:04 +0200
+Subject: drm/xe/xe_sync: avoid race during ufence signaling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
+
+[ Upstream commit 04e1f683cd28dc9407b238543871a6e09a570dc0 ]
+
+Marking ufence as signalled after copy_to_user() is too late.
+Worker thread which signals ufence by memory write might be raced
+with another userspace vm-bind call. In map/unmap scenario unmap
+may still see ufence is not signalled causing -EBUSY. Change the
+order of marking / write to user-fence fixes this issue.
+
+Fixes: 977e5b82e090 ("drm/xe: Expose user fence from xe_sync_entry")
+Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/5536
+Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250820083903.2109891-2-zbigniew.kempczynski@intel.com
+(cherry picked from commit 8ae04fe9ffc93d6bc3bc63ac08375427d69cee06)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_sync.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c
+index b0684e6d2047b..dd7bd766ae184 100644
+--- a/drivers/gpu/drm/xe/xe_sync.c
++++ b/drivers/gpu/drm/xe/xe_sync.c
+@@ -77,6 +77,7 @@ static void user_fence_worker(struct work_struct *w)
+ {
+       struct xe_user_fence *ufence = container_of(w, struct xe_user_fence, worker);
++      WRITE_ONCE(ufence->signalled, 1);
+       if (mmget_not_zero(ufence->mm)) {
+               kthread_use_mm(ufence->mm);
+               if (copy_to_user(ufence->addr, &ufence->value, sizeof(ufence->value)))
+@@ -89,7 +90,6 @@ static void user_fence_worker(struct work_struct *w)
+        * Wake up waiters only after updating the ufence state, allowing the UMD
+        * to safely reuse the same ufence without encountering -EBUSY errors.
+        */
+-      WRITE_ONCE(ufence->signalled, 1);
+       wake_up_all(&ufence->xe->ufence_wq);
+       user_fence_put(ufence);
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.12/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch b/queue-6.12/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
new file mode 100644 (file)
index 0000000..10fbf71
--- /dev/null
@@ -0,0 +1,39 @@
+From 3c58e54ef9ec24d58a23ea32aa2373306d37a0e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Aug 2025 11:36:54 +0300
+Subject: dt-bindings: display/msm: qcom,mdp5: drop lut clock
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 7ab3b7579a6d2660a3425b9ea93b9a140b07f49c ]
+
+None of MDP5 platforms have a LUT clock on the display-controller, it
+was added by the mistake. Drop it, fixing DT warnings on MSM8976 /
+MSM8956 platforms. Technically it's an ABI break, but no other platforms
+are affected.
+
+Fixes: 385c8ac763b3 ("dt-bindings: display/msm: convert MDP5 schema to YAML format")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Patchwork: https://patchwork.freedesktop.org/patch/667822/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+index e153f8d26e7aa..2735c78b0b67a 100644
+--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
++++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+@@ -60,7 +60,6 @@ properties:
+           - const: bus
+           - const: core
+           - const: vsync
+-          - const: lut
+           - const: tbu
+           - const: tbu_rt
+         # MSM8996 has additional iommu clock
+-- 
+2.50.1
+
diff --git a/queue-6.12/efi-stmm-fix-incorrect-buffer-allocation-method.patch b/queue-6.12/efi-stmm-fix-incorrect-buffer-allocation-method.patch
new file mode 100644 (file)
index 0000000..0db5188
--- /dev/null
@@ -0,0 +1,111 @@
+From 1329715063cc21aa07b52f39911d96b406c76254 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 18:07:10 +0200
+Subject: efi: stmm: Fix incorrect buffer allocation method
+
+From: Jan Kiszka <jan.kiszka@siemens.com>
+
+[ Upstream commit c5e81e672699e0c5557b2b755cc8f7a69aa92bff ]
+
+The communication buffer allocated by setup_mm_hdr() is later on passed
+to tee_shm_register_kernel_buf(). The latter expects those buffers to be
+contiguous pages, but setup_mm_hdr() just uses kmalloc(). That can cause
+various corruptions or BUGs, specifically since commit 9aec2fb0fd5e
+("slab: allocate frozen pages"), though it was broken before as well.
+
+Fix this by using alloc_pages_exact() instead of kmalloc().
+
+Fixes: c44b6be62e8d ("efi: Add tee-based EFI variable driver")
+Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
+Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
+Acked-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/stmm/tee_stmm_efi.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/firmware/efi/stmm/tee_stmm_efi.c b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+index f741ca279052b..e15d11ed165ee 100644
+--- a/drivers/firmware/efi/stmm/tee_stmm_efi.c
++++ b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+@@ -143,6 +143,10 @@ static efi_status_t mm_communicate(u8 *comm_buf, size_t payload_size)
+       return var_hdr->ret_status;
+ }
++#define COMM_BUF_SIZE(__payload_size) (MM_COMMUNICATE_HEADER_SIZE + \
++                                       MM_VARIABLE_COMMUNICATE_SIZE + \
++                                       (__payload_size))
++
+ /**
+  * setup_mm_hdr() -   Allocate a buffer for StandAloneMM and initialize the
+  *                    header data.
+@@ -173,9 +177,8 @@ static void *setup_mm_hdr(u8 **dptr, size_t payload_size, size_t func,
+               return NULL;
+       }
+-      comm_buf = kzalloc(MM_COMMUNICATE_HEADER_SIZE +
+-                                 MM_VARIABLE_COMMUNICATE_SIZE + payload_size,
+-                         GFP_KERNEL);
++      comm_buf = alloc_pages_exact(COMM_BUF_SIZE(payload_size),
++                                   GFP_KERNEL | __GFP_ZERO);
+       if (!comm_buf) {
+               *ret = EFI_OUT_OF_RESOURCES;
+               return NULL;
+@@ -239,7 +242,7 @@ static efi_status_t get_max_payload(size_t *size)
+        */
+       *size -= 2;
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -282,7 +285,7 @@ static efi_status_t get_property_int(u16 *name, size_t name_size,
+       memcpy(var_property, &smm_property->property, sizeof(*var_property));
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -347,7 +350,7 @@ static efi_status_t tee_get_variable(u16 *name, efi_guid_t *vendor,
+       memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
+              var_acc->data_size);
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -404,7 +407,7 @@ static efi_status_t tee_get_next_variable(unsigned long *name_size,
+       memcpy(name, var_getnext->name, var_getnext->name_size);
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -467,7 +470,7 @@ static efi_status_t tee_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+       ret = mm_communicate(comm_buf, payload_size);
+       dev_dbg(pvt_data.dev, "Set Variable %s %d %lx\n", __FILE__, __LINE__, ret);
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -507,7 +510,7 @@ static efi_status_t tee_query_variable_info(u32 attributes,
+       *max_variable_size = mm_query_info->max_variable_size;
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.12/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch b/queue-6.12/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
new file mode 100644 (file)
index 0000000..6a819f9
--- /dev/null
@@ -0,0 +1,77 @@
+From 3ac5c874579749a79dd928cbafa4115d9757d66a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+  BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+  Call trace:
+   kasan_check_range+0xe8/0x190
+   __asan_loadN+0x1c/0x28
+   memcmp+0x98/0xd0
+   efivarfs_d_compare+0x68/0xd8
+   __d_lookup_rcu_op_compare+0x178/0x218
+   __d_lookup_rcu+0x1f8/0x228
+   d_alloc_parallel+0x150/0x648
+   lookup_open.isra.0+0x5f0/0x8d0
+   open_last_lookups+0x264/0x828
+   path_openat+0x130/0x3f8
+   do_filp_open+0x114/0x248
+   do_sys_openat2+0x340/0x3c0
+   __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+  T1                   T2
+  lookup_open
+   ->lookup
+    simple_lookup
+     d_add
+     // invalid dentry is added to hash list
+
+                       lookup_open
+                        d_alloc_parallel
+                         __d_lookup_rcu
+                          __d_lookup_rcu_op_compare
+                           hlist_bl_for_each_entry_rcu
+                           // invalid dentry can be retrieved
+                            ->d_compare
+                             efivarfs_d_compare
+                             // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 11ebddc57bc73..1831e015b2f26 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -127,6 +127,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+       int guid = len - EFI_VARIABLE_GUID_LEN;
++      /* Parallel lookups may produce a temporary invalid filename */
++      if (guid <= 0)
++              return 1;
++
+       if (name->len != len)
+               return 1;
+-- 
+2.50.1
+
diff --git a/queue-6.12/fbnic-move-phylink-resume-out-of-service_task-and-in.patch b/queue-6.12/fbnic-move-phylink-resume-out-of-service_task-and-in.patch
new file mode 100644 (file)
index 0000000..ddd9785
--- /dev/null
@@ -0,0 +1,120 @@
+From 0ab0a25913e4111285f05def02dcd646101a15c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 15:56:13 -0700
+Subject: fbnic: Move phylink resume out of service_task and into open/close
+
+From: Alexander Duyck <alexanderduyck@fb.com>
+
+[ Upstream commit 6ede14a2c6365e7e5d855643c7c8390b5268c467 ]
+
+The fbnic driver was presenting with the following locking assert coming
+out of a PM resume:
+[   42.208116][  T164] RTNL: assertion failed at drivers/net/phy/phylink.c (2611)
+[   42.208492][  T164] WARNING: CPU: 1 PID: 164 at drivers/net/phy/phylink.c:2611 phylink_resume+0x190/0x1e0
+[   42.208872][  T164] Modules linked in:
+[   42.209140][  T164] CPU: 1 UID: 0 PID: 164 Comm: bash Not tainted 6.17.0-rc2-virtme #134 PREEMPT(full)
+[   42.209496][  T164] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-5.fc42 04/01/2014
+[   42.209861][  T164] RIP: 0010:phylink_resume+0x190/0x1e0
+[   42.210057][  T164] Code: 83 e5 01 0f 85 b0 fe ff ff c6 05 1c cd 3e 02 01 90 ba 33 0a 00 00 48 c7 c6 20 3a 1d a5 48 c7 c7 e0 3e 1d a5 e8 21 b8 90 fe 90 <0f> 0b 90 90 e9 86 fe ff ff e8 42 ea 1f ff e9 e2 fe ff ff 48 89 ef
+[   42.210708][  T164] RSP: 0018:ffffc90000affbd8 EFLAGS: 00010296
+[   42.210983][  T164] RAX: 0000000000000000 RBX: ffff8880078d8400 RCX: 0000000000000000
+[   42.211235][  T164] RDX: 0000000000000000 RSI: 1ffffffff4f10938 RDI: 0000000000000001
+[   42.211466][  T164] RBP: 0000000000000000 R08: ffffffffa2ae79ea R09: fffffbfff4b3eb84
+[   42.211707][  T164] R10: 0000000000000003 R11: 0000000000000000 R12: ffff888007ad8000
+[   42.211997][  T164] R13: 0000000000000002 R14: ffff888006a18800 R15: ffffffffa34c59e0
+[   42.212234][  T164] FS:  00007f0dc8e39740(0000) GS:ffff88808f51f000(0000) knlGS:0000000000000000
+[   42.212505][  T164] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   42.212704][  T164] CR2: 00007f0dc8e9fe10 CR3: 000000000b56d003 CR4: 0000000000772ef0
+[   42.213227][  T164] PKRU: 55555554
+[   42.213366][  T164] Call Trace:
+[   42.213483][  T164]  <TASK>
+[   42.213565][  T164]  __fbnic_pm_attach.isra.0+0x8e/0xa0
+[   42.213725][  T164]  pci_reset_function+0x116/0x1d0
+[   42.213895][  T164]  reset_store+0xa0/0x100
+[   42.214025][  T164]  ? pci_dev_reset_attr_is_visible+0x50/0x50
+[   42.214221][  T164]  ? sysfs_file_kobj+0xc1/0x1e0
+[   42.214374][  T164]  ? sysfs_kf_write+0x65/0x160
+[   42.214526][  T164]  kernfs_fop_write_iter+0x2f8/0x4c0
+[   42.214677][  T164]  ? kernfs_vma_page_mkwrite+0x1f0/0x1f0
+[   42.214836][  T164]  new_sync_write+0x308/0x6f0
+[   42.214987][  T164]  ? __lock_acquire+0x34c/0x740
+[   42.215135][  T164]  ? new_sync_read+0x6f0/0x6f0
+[   42.215288][  T164]  ? lock_acquire.part.0+0xbc/0x260
+[   42.215440][  T164]  ? ksys_write+0xff/0x200
+[   42.215590][  T164]  ? perf_trace_sched_switch+0x6d0/0x6d0
+[   42.215742][  T164]  vfs_write+0x65e/0xbb0
+[   42.215876][  T164]  ksys_write+0xff/0x200
+[   42.215994][  T164]  ? __ia32_sys_read+0xc0/0xc0
+[   42.216141][  T164]  ? do_user_addr_fault+0x269/0x9f0
+[   42.216292][  T164]  ? rcu_is_watching+0x15/0xd0
+[   42.216442][  T164]  do_syscall_64+0xbb/0x360
+[   42.216591][  T164]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[   42.216784][  T164] RIP: 0033:0x7f0dc8ea9986
+
+A bit of digging showed that we were invoking the phylink_resume as a part
+of the fbnic_up path when we were enabling the service task while not
+holding the RTNL lock. We should be enabling this sooner as a part of the
+ndo_open path and then just letting the service task come online later.
+This will help to enforce the correct locking and brings the phylink
+interface online at the same time as the network interface, instead of at a
+later time.
+
+I tested this on QEMU to verify this was working by putting the system to
+sleep using "echo mem > /sys/power/state" to put the system to sleep in the
+guest and then using the command "system_wakeup" in the QEMU monitor.
+
+Fixes: 69684376eed5 ("eth: fbnic: Add link detection")
+Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Link: https://patch.msgid.link/175616257316.1963577.12238158800417771119.stgit@ahduyck-xeon-server.home.arpa
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 4 ++++
+ drivers/net/ethernet/meta/fbnic/fbnic_pci.c    | 2 --
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index 79e94632533c8..a8c95b1732f4d 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -53,6 +53,8 @@ int __fbnic_open(struct fbnic_net *fbn)
+       fbnic_bmc_rpc_init(fbd);
+       fbnic_rss_reinit(fbd, fbn);
++      phylink_resume(fbn->phylink);
++
+       return 0;
+ release_ownership:
+       fbnic_fw_xmit_ownership_msg(fbn->fbd, false);
+@@ -79,6 +81,8 @@ static int fbnic_stop(struct net_device *netdev)
+ {
+       struct fbnic_net *fbn = netdev_priv(netdev);
++      phylink_suspend(fbn->phylink, fbnic_bmc_present(fbn->fbd));
++
+       fbnic_down(fbn);
+       fbnic_pcs_irq_disable(fbn->fbd);
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+index 268489b15616f..72bdc6c76c0c5 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+@@ -116,14 +116,12 @@ static void fbnic_service_task_start(struct fbnic_net *fbn)
+       struct fbnic_dev *fbd = fbn->fbd;
+       schedule_delayed_work(&fbd->service_task, HZ);
+-      phylink_resume(fbn->phylink);
+ }
+ static void fbnic_service_task_stop(struct fbnic_net *fbn)
+ {
+       struct fbnic_dev *fbd = fbn->fbd;
+-      phylink_suspend(fbn->phylink, fbnic_bmc_present(fbd));
+       cancel_delayed_work(&fbd->service_task);
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.12/hid-input-rename-hidinput_set_battery_charge_status.patch b/queue-6.12/hid-input-rename-hidinput_set_battery_charge_status.patch
new file mode 100644 (file)
index 0000000..666950d
--- /dev/null
@@ -0,0 +1,147 @@
+From 6ed7183eeaccdf5f881b37501585d73357b3fe81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:39 +0200
+Subject: HID: input: rename hidinput_set_battery_charge_status()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit a82231b2a8712d0218fc286a9b0da328d419a3f4 ]
+
+In preparation for a patch fixing a bug affecting
+hidinput_set_battery_charge_status(), rename the function to
+hidinput_update_battery_charge_status() and move it up so it can be used
+by hidinput_update_battery().
+
+Refactor, no functional changes.
+
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Stable-dep-of: e94536e1d181 ("HID: input: report battery status changes immediately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input-test.c | 10 +++++-----
+ drivers/hid/hid-input.c      | 38 ++++++++++++++++++------------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7..6f5c71660d823 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+ #include <kunit/test.h>
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+       struct hid_device *dev;
+       bool handled;
+@@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
+       dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+-      handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+       KUNIT_EXPECT_FALSE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
+ }
+ static struct kunit_case hid_input_tests[] = {
+-      KUNIT_CASE(hid_test_input_set_battery_charge_status),
++      KUNIT_CASE(hid_test_input_update_battery_charge_status),
+       KUNIT_CASE(hid_test_input_get_battery_property),
+       { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 9d80635a91ebd..b372b74f3e24b 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -595,6 +595,20 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+       dev->battery = NULL;
+ }
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
++{
++      switch (usage) {
++      case HID_BAT_CHARGING:
++              dev->battery_charge_status = value ?
++                                           POWER_SUPPLY_STATUS_CHARGING :
++                                           POWER_SUPPLY_STATUS_DISCHARGING;
++              return true;
++      }
++
++      return false;
++}
++
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+       int capacity;
+@@ -617,20 +631,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
+               power_supply_changed(dev->battery);
+       }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
+-{
+-      switch (usage) {
+-      case HID_BAT_CHARGING:
+-              dev->battery_charge_status = value ?
+-                                           POWER_SUPPLY_STATUS_CHARGING :
+-                                           POWER_SUPPLY_STATUS_DISCHARGING;
+-              return true;
+-      }
+-
+-      return false;
+-}
+ #else  /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+                                 struct hid_field *field, bool is_percentage)
+@@ -642,14 +642,14 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
+ {
++      return false;
+ }
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+-      return false;
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,7 +1515,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+               return;
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++              bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+               if (!handled)
+                       hidinput_update_battery(hid, value);
+-- 
+2.50.1
+
diff --git a/queue-6.12/hid-input-report-battery-status-changes-immediately.patch b/queue-6.12/hid-input-report-battery-status-changes-immediately.patch
new file mode 100644 (file)
index 0000000..12ef707
--- /dev/null
@@ -0,0 +1,97 @@
+From 83093093b438e989a01804dd51939eca14ee3f84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:40 +0200
+Subject: HID: input: report battery status changes immediately
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit e94536e1d1818b0989aa19b443b7089f50133c35 ]
+
+Previously, the battery status (charging/discharging) was not reported
+immediately to user-space. 
+
+For most input devices, this wasn't problematic because changing their
+battery status requires connecting them to a different bus.
+For example, a gamepad would report a discharging status while
+connected via Bluetooth and a charging status while connected via USB.
+
+However, certain devices are not connected or disconnected when their
+battery status changes. For example, a phone battery changes its status
+without connecting or disconnecting it.
+In these cases, the battery status was not reported immediately to user
+space.
+
+Report battery status changes immediately to user space to support
+these kinds of devices.
+
+Fixes: a608dc1c0639 ("HID: input: map battery system charging")
+Reported-by: 卢国宏 <luguohong@xiaomi.com>
+Closes: https://lore.kernel.org/linux-input/aI49Im0sGb6fpgc8@fedora/T/
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index b372b74f3e24b..f5c217ac4bfaa 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -609,13 +609,19 @@ static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+       return false;
+ }
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++                                  int value)
+ {
+       int capacity;
+       if (!dev->battery)
+               return;
++      if (hidinput_update_battery_charge_status(dev, usage, value)) {
++              power_supply_changed(dev->battery);
++              return;
++      }
++
+       if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+               return;
+@@ -642,13 +648,8 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+-static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+-                                                unsigned int usage, int value)
+-{
+-      return false;
+-}
+-
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++                                  int value)
+ {
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+               return;
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+-
+-              if (!handled)
+-                      hidinput_update_battery(hid, value);
+-
++              hidinput_update_battery(hid, usage->hid, value);
+               return;
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.12/hv_netvsc-link-queues-to-napis.patch b/queue-6.12/hv_netvsc-link-queues-to-napis.patch
new file mode 100644 (file)
index 0000000..e56fe96
--- /dev/null
@@ -0,0 +1,110 @@
+From 47b18549e5d8bd0cf953155c44834f4bfc3e496d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 17:27:09 +0000
+Subject: hv_netvsc: Link queues to NAPIs
+
+From: Joe Damato <jdamato@fastly.com>
+
+[ Upstream commit 8b641b5e4c782464c8818a71b443eeef8984bf34 ]
+
+Use netif_queue_set_napi to link queues to NAPI instances so that they
+can be queried with netlink.
+
+Shradha Gupta tested the patch and reported that the results are
+as expected:
+
+$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml \
+                           --dump queue-get --json='{"ifindex": 2}'
+
+ [{'id': 0, 'ifindex': 2, 'napi-id': 8193, 'type': 'rx'},
+  {'id': 1, 'ifindex': 2, 'napi-id': 8194, 'type': 'rx'},
+  {'id': 2, 'ifindex': 2, 'napi-id': 8195, 'type': 'rx'},
+  {'id': 3, 'ifindex': 2, 'napi-id': 8196, 'type': 'rx'},
+  {'id': 4, 'ifindex': 2, 'napi-id': 8197, 'type': 'rx'},
+  {'id': 5, 'ifindex': 2, 'napi-id': 8198, 'type': 'rx'},
+  {'id': 6, 'ifindex': 2, 'napi-id': 8199, 'type': 'rx'},
+  {'id': 7, 'ifindex': 2, 'napi-id': 8200, 'type': 'rx'},
+  {'id': 0, 'ifindex': 2, 'napi-id': 8193, 'type': 'tx'},
+  {'id': 1, 'ifindex': 2, 'napi-id': 8194, 'type': 'tx'},
+  {'id': 2, 'ifindex': 2, 'napi-id': 8195, 'type': 'tx'},
+  {'id': 3, 'ifindex': 2, 'napi-id': 8196, 'type': 'tx'},
+  {'id': 4, 'ifindex': 2, 'napi-id': 8197, 'type': 'tx'},
+  {'id': 5, 'ifindex': 2, 'napi-id': 8198, 'type': 'tx'},
+  {'id': 6, 'ifindex': 2, 'napi-id': 8199, 'type': 'tx'},
+  {'id': 7, 'ifindex': 2, 'napi-id': 8200, 'type': 'tx'}]
+
+Signed-off-by: Joe Damato <jdamato@fastly.com>
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Tested-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 9448ccd85336 ("net: hv_netvsc: fix loss of early receive events from host during channel open.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/netvsc.c       | 13 ++++++++++++-
+ drivers/net/hyperv/rndis_filter.c |  9 +++++++--
+ 2 files changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 807465dd4c8e3..87ac2a5f18091 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -712,8 +712,13 @@ void netvsc_device_remove(struct hv_device *device)
+       for (i = 0; i < net_device->num_chn; i++) {
+               /* See also vmbus_reset_channel_cb(). */
+               /* only disable enabled NAPI channel */
+-              if (i < ndev->real_num_rx_queues)
++              if (i < ndev->real_num_rx_queues) {
++                      netif_queue_set_napi(ndev, i, NETDEV_QUEUE_TYPE_TX,
++                                           NULL);
++                      netif_queue_set_napi(ndev, i, NETDEV_QUEUE_TYPE_RX,
++                                           NULL);
+                       napi_disable(&net_device->chan_table[i].napi);
++              }
+               netif_napi_del(&net_device->chan_table[i].napi);
+       }
+@@ -1826,6 +1831,10 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+       netdev_dbg(ndev, "hv_netvsc channel opened successfully\n");
+       napi_enable(&net_device->chan_table[0].napi);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
++                           &net_device->chan_table[0].napi);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
++                           &net_device->chan_table[0].napi);
+       /* Connect with the NetVsp */
+       ret = netvsc_connect_vsp(device, net_device, device_info);
+@@ -1844,6 +1853,8 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+ close:
+       RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
+       napi_disable(&net_device->chan_table[0].napi);
+       /* Now, we can close the channel safely */
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+index e457f809fe311..9b8769a8b77a1 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1255,10 +1255,15 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+       ret = vmbus_open(new_sc, netvsc_ring_bytes,
+                        netvsc_ring_bytes, NULL, 0,
+                        netvsc_channel_cb, nvchan);
+-      if (ret == 0)
++      if (ret == 0) {
+               napi_enable(&nvchan->napi);
+-      else
++              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++                                   &nvchan->napi);
++              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++                                   &nvchan->napi);
++      } else {
+               netdev_notice(ndev, "sub channel open failed: %d\n", ret);
++      }
+       if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn)
+               wake_up(&nvscdev->subchan_open);
+-- 
+2.50.1
+
diff --git a/queue-6.12/ice-don-t-leave-device-non-functional-if-tx-schedule.patch b/queue-6.12/ice-don-t-leave-device-non-functional-if-tx-schedule.patch
new file mode 100644 (file)
index 0000000..8256177
--- /dev/null
@@ -0,0 +1,238 @@
+From 13b10e4ac93c7b81a58b661ff2004d05ab52d197 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 09:57:09 -0700
+Subject: ice: don't leave device non-functional if Tx scheduler config fails
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 86aae43f21cf784c1d7f6a9af93e5116b0f232ab ]
+
+The ice_cfg_tx_topo function attempts to apply Tx scheduler topology
+configuration based on NVM parameters, selecting either a 5 or 9 layer
+topology.
+
+As part of this flow, the driver acquires the "Global Configuration Lock",
+which is a hardware resource associated with programming the DDP package
+to the device. This "lock" is implemented by firmware as a way to
+guarantee that only one PF can program the DDP for a device. Unlike a
+traditional lock, once a PF has acquired this lock, no other PF will be
+able to acquire it again (including that PF) until a CORER of the device.
+Future requests to acquire the lock report that global configuration has
+already completed.
+
+The following flow is used to program the Tx topology:
+
+ * Read the DDP package for scheduler configuration data
+ * Acquire the global configuration lock
+ * Program Tx scheduler topology according to DDP package data
+ * Trigger a CORER which clears the global configuration lock
+
+This is followed by the flow for programming the DDP package:
+
+ * Acquire the global configuration lock (again)
+ * Download the DDP package to the device
+ * Release the global configuration lock.
+
+However, if configuration of the Tx topology fails, (i.e.
+ice_get_set_tx_topo returns an error code), the driver exits
+ice_cfg_tx_topo() immediately, and fails to trigger CORER.
+
+While the global configuration lock is held, the firmware rejects most
+AdminQ commands, as it is waiting for the DDP package download (or Tx
+scheduler topology programming) to occur.
+
+The current driver flows assume that the global configuration lock has been
+reset by CORER after programming the Tx topology. Thus, the same PF
+attempts to acquire the global lock again, and fails. This results in the
+driver reporting "an unknown error occurred when loading the DDP package".
+It then attempts to enter safe mode, but ultimately fails to finish
+ice_probe() since nearly all AdminQ command report error codes, and the
+driver stops loading the device at some point during its initialization.
+
+The only currently known way that ice_get_set_tx_topo() can fail is with
+certain older DDP packages which contain invalid topology configuration, on
+firmware versions which strictly validate this data. The most recent
+releases of the DDP have resolved the invalid data. However, it is still
+poor practice to essentially brick the device, and prevent access to the
+device even through safe mode or recovery mode. It is also plausible that
+this command could fail for some other reason in the future.
+
+We cannot simply release the global lock after a failed call to
+ice_get_set_tx_topo(). Releasing the lock indicates to firmware that global
+configuration (downloading of the DDP) has completed. Future attempts by
+this or other PFs to load the DDP will fail with a report that the DDP
+package has already been downloaded. Then, PFs will enter safe mode as they
+realize that the package on the device does not meet the minimum version
+requirement to load. The reported error messages are confusing, as they
+indicate the version of the default "safe mode" package in the NVM, rather
+than the version of the file loaded from /lib/firmware.
+
+Instead, we need to trigger CORER to clear global configuration. This is
+the lowest level of hardware reset which clears the global configuration
+lock and related state. It also clears any already downloaded DDP.
+Crucially, it does *not* clear the Tx scheduler topology configuration.
+
+Refactor ice_cfg_tx_topo() to always trigger a CORER after acquiring the
+global lock, regardless of success or failure of the topology
+configuration.
+
+We need to re-initialize the HW structure when we trigger the CORER. Thus,
+it makes sense for this to be the responsibility of ice_cfg_tx_topo()
+rather than its caller, ice_init_tx_topology(). This avoids needless
+re-initialization in cases where we don't attempt to update the Tx
+scheduler topology, such as if it has already been programmed.
+
+There is one catch: failure to re-initialize the HW struct should stop
+ice_probe(). If this function fails, we won't have a valid HW structure and
+cannot ensure the device is functioning properly. To handle this, ensure
+ice_cfg_tx_topo() returns a limited set of error codes. Set aside one
+specifically, -ENODEV, to indicate that the ice_init_tx_topology() should
+fail and stop probe.
+
+Other error codes indicate failure to apply the Tx scheduler topology. This
+is treated as a non-fatal error, with an informational message informing
+the system administrator that the updated Tx topology did not apply. This
+allows the device to load and function with the default Tx scheduler
+topology, rather than failing to load entirely.
+
+Note that this use of CORER will not result in loops with future PFs
+attempting to also load the invalid Tx topology configuration. The first PF
+will acquire the global configuration lock as part of programming the DDP.
+Each PF after this will attempt to acquire the global lock as part of
+programming the Tx topology, and will fail with the indication from
+firmware that global configuration is already complete. Tx scheduler
+topology configuration is only performed during driver init (probe or
+devlink reload) and not during cleanup for a CORER that happens after probe
+completes.
+
+Fixes: 91427e6d9030 ("ice: Support 5 layer topology")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ddp.c  | 44 ++++++++++++++++-------
+ drivers/net/ethernet/intel/ice/ice_main.c | 16 ++++++---
+ 2 files changed, 43 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c
+index e4c8cd12a41d1..04bec5d8e7084 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ddp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c
+@@ -2352,7 +2352,13 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
+  * The function will apply the new Tx topology from the package buffer
+  * if available.
+  *
+- * Return: zero when update was successful, negative values otherwise.
++ * Return:
++ * * 0 - Successfully applied topology configuration.
++ * * -EBUSY - Failed to acquire global configuration lock.
++ * * -EEXIST - Topology configuration has already been applied.
++ * * -EIO - Unable to apply topology configuration.
++ * * -ENODEV - Failed to re-initialize device after applying configuration.
++ * * Other negative error codes indicate unexpected failures.
+  */
+ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+ {
+@@ -2385,7 +2391,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
+-              return status;
++              return -EIO;
+       }
+       /* Is default topology already applied ? */
+@@ -2472,31 +2478,45 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+                                ICE_GLOBAL_CFG_LOCK_TIMEOUT);
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n");
+-              return status;
++              return -EBUSY;
+       }
+       /* Check if reset was triggered already. */
+       reg = rd32(hw, GLGEN_RSTAT);
+       if (reg & GLGEN_RSTAT_DEVSTATE_M) {
+-              /* Reset is in progress, re-init the HW again */
+               ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer topology might be applied already\n");
+               ice_check_reset(hw);
+-              return 0;
++              /* Reset is in progress, re-init the HW again */
++              goto reinit_hw;
+       }
+       /* Set new topology */
+       status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);
+       if (status) {
+-              ice_debug(hw, ICE_DBG_INIT, "Failed setting Tx topology\n");
+-              return status;
++              ice_debug(hw, ICE_DBG_INIT, "Failed to set Tx topology, status %pe\n",
++                        ERR_PTR(status));
++              /* only report -EIO here as the caller checks the error value
++               * and reports an informational error message informing that
++               * the driver failed to program Tx topology.
++               */
++              status = -EIO;
+       }
+-      /* New topology is updated, delay 1 second before issuing the CORER */
++      /* Even if Tx topology config failed, we need to CORE reset here to
++       * clear the global configuration lock. Delay 1 second to allow
++       * hardware to settle then issue a CORER
++       */
+       msleep(1000);
+       ice_reset(hw, ICE_RESET_CORER);
+-      /* CORER will clear the global lock, so no explicit call
+-       * required for release.
+-       */
++      ice_check_reset(hw);
++
++reinit_hw:
++      /* Since we triggered a CORER, re-initialize hardware */
++      ice_deinit_hw(hw);
++      if (ice_init_hw(hw)) {
++              ice_debug(hw, ICE_DBG_INIT, "Failed to re-init hardware after setting Tx topology\n");
++              return -ENODEV;
++      }
+-      return 0;
++      return status;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index d1abd21cfc647..74d4f2fde3e0f 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -4559,17 +4559,23 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
+                       dev_info(dev, "Tx scheduling layers switching feature disabled\n");
+               else
+                       dev_info(dev, "Tx scheduling layers switching feature enabled\n");
+-              /* if there was a change in topology ice_cfg_tx_topo triggered
+-               * a CORER and we need to re-init hw
++              return 0;
++      } else if (err == -ENODEV) {
++              /* If we failed to re-initialize the device, we can no longer
++               * continue loading.
+                */
+-              ice_deinit_hw(hw);
+-              err = ice_init_hw(hw);
+-
++              dev_warn(dev, "Failed to initialize hardware after applying Tx scheduling configuration.\n");
+               return err;
+       } else if (err == -EIO) {
+               dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n");
++              return 0;
++      } else if (err == -EEXIST) {
++              return 0;
+       }
++      /* Do not treat this as a fatal error. */
++      dev_info(dev, "Failed to apply Tx scheduling configuration, err %pe\n",
++               ERR_PTR(err));
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.12/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch b/queue-6.12/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
new file mode 100644 (file)
index 0000000..4ed3ebb
--- /dev/null
@@ -0,0 +1,46 @@
+From 84791f14f20b44015822f6ca5791d1c0bd24585b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Aug 2025 17:53:10 +0200
+Subject: ice: fix incorrect counter for buffer allocation failures
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit b1a0c977c6f1130f7dd125ee3db8c2435d7e3d41 ]
+
+Currently, the driver increments `alloc_page_failed` when buffer allocation fails
+in `ice_clean_rx_irq()`. However, this counter is intended for page allocation
+failures, not buffer allocation issues.
+
+This patch corrects the counter by incrementing `alloc_buf_failed` instead,
+ensuring accurate statistics reporting for buffer allocation failures.
+
+Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
+Reported-by: Jacob Keller <jacob.e.keller@intel.com>
+Suggested-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Priya Singh <priyax.singh@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index f522dd42093a9..cde69f5686656 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -1295,7 +1295,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+                       skb = ice_construct_skb(rx_ring, xdp);
+               /* exit if we failed to retrieve a buffer */
+               if (!skb) {
+-                      rx_ring->ring_stats->rx_stats.alloc_page_failed++;
++                      rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
+                       xdp_verdict = ICE_XDP_CONSUMED;
+               }
+               ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+-- 
+2.50.1
+
diff --git a/queue-6.12/ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch b/queue-6.12/ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch
new file mode 100644 (file)
index 0000000..910e02c
--- /dev/null
@@ -0,0 +1,202 @@
+From ec18b0f742f2f8c03c0d6c975059403927507bb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Aug 2025 15:27:12 -0700
+Subject: ice: use fixed adapter index for E825C embedded devices
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 5c5e5b52bf05c7fe88768318c041052c5fac36b8 ]
+
+The ice_adapter structure is used by the ice driver to connect multiple
+physical functions of a device in software. It was introduced by
+commit 0e2bddf9e5f9 ("ice: add ice_adapter for shared data across PFs on
+the same NIC") and is primarily used for PTP support, as well as for
+handling certain cross-PF synchronization.
+
+The original design of ice_adapter used PCI address information to
+determine which devices should be connected. This was extended to support
+E825C devices by commit fdb7f54700b1 ("ice: Initial support for E825C
+hardware in ice_adapter"), which used the device ID for E825C devices
+instead of the PCI address.
+
+Later, commit 0093cb194a75 ("ice: use DSN instead of PCI BDF for
+ice_adapter index") replaced the use of Bus/Device/Function addressing with
+use of the device serial number.
+
+E825C devices may appear in "Dual NAC" configuration which has multiple
+physical devices tied to the same clock source and which need to use the
+same ice_adapter. Unfortunately, each "NAC" has its own NVM which has its
+own unique Device Serial Number. Thus, use of the DSN for connecting
+ice_adapter does not work properly. It "worked" in the pre-production
+systems because the DSN was not initialized on the test NVMs and all the
+NACs had the same zero'd serial number.
+
+Since we cannot rely on the DSN, lets fall back to the logic in the
+original E825C support which used the device ID. This is safe for E825C
+only because of the embedded nature of the device. It isn't a discreet
+adapter that can be plugged into an arbitrary system. All E825C devices on
+a given system are connected to the same clock source and need to be
+configured through the same PTP clock.
+
+To make this separation clear, reserve bit 63 of the 64-bit index values as
+a "fixed index" indicator. Always clear this bit when using the device
+serial number as an index.
+
+For E825C, use a fixed value defined as the 0x579C E825C backplane device
+ID bitwise ORed with the fixed index indicator. This is slightly different
+than the original logic of just using the device ID directly. Doing so
+prevents a potential issue with systems where only one of the NACs is
+connected with an external PHY over SGMII. In that case, one NAC would
+have the E825C_SGMII device ID, but the other would not.
+
+Separate the determination of the full 64-bit index from the 32-bit
+reduction logic. Provide both ice_adapter_index() and a wrapping
+ice_adapter_xa_index() which handles reducing the index to a long on 32-bit
+systems. As before, cache the full index value in the adapter structure to
+warn about collisions.
+
+This fixes issues with E825C not initializing PTP on both NACs, due to
+failure to connect the appropriate devices to the same ice_adapter.
+
+Fixes: 0093cb194a75 ("ice: use DSN instead of PCI BDF for ice_adapter index")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_adapter.c | 49 +++++++++++++++-----
+ drivers/net/ethernet/intel/ice/ice_adapter.h |  4 +-
+ 2 files changed, 40 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c b/drivers/net/ethernet/intel/ice/ice_adapter.c
+index 66e070095d1bb..10285995c9edd 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.c
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.c
+@@ -13,16 +13,45 @@
+ static DEFINE_XARRAY(ice_adapters);
+ static DEFINE_MUTEX(ice_adapters_mutex);
+-static unsigned long ice_adapter_index(u64 dsn)
++#define ICE_ADAPTER_FIXED_INDEX       BIT_ULL(63)
++
++#define ICE_ADAPTER_INDEX_E825C       \
++      (ICE_DEV_ID_E825C_BACKPLANE | ICE_ADAPTER_FIXED_INDEX)
++
++static u64 ice_adapter_index(struct pci_dev *pdev)
+ {
++      switch (pdev->device) {
++      case ICE_DEV_ID_E825C_BACKPLANE:
++      case ICE_DEV_ID_E825C_QSFP:
++      case ICE_DEV_ID_E825C_SFP:
++      case ICE_DEV_ID_E825C_SGMII:
++              /* E825C devices have multiple NACs which are connected to the
++               * same clock source, and which must share the same
++               * ice_adapter structure. We can't use the serial number since
++               * each NAC has its own NVM generated with its own unique
++               * Device Serial Number. Instead, rely on the embedded nature
++               * of the E825C devices, and use a fixed index. This relies on
++               * the fact that all E825C physical functions in a given
++               * system are part of the same overall device.
++               */
++              return ICE_ADAPTER_INDEX_E825C;
++      default:
++              return pci_get_dsn(pdev) & ~ICE_ADAPTER_FIXED_INDEX;
++      }
++}
++
++static unsigned long ice_adapter_xa_index(struct pci_dev *pdev)
++{
++      u64 index = ice_adapter_index(pdev);
++
+ #if BITS_PER_LONG == 64
+-      return dsn;
++      return index;
+ #else
+-      return (u32)dsn ^ (u32)(dsn >> 32);
++      return (u32)index ^ (u32)(index >> 32);
+ #endif
+ }
+-static struct ice_adapter *ice_adapter_new(u64 dsn)
++static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev)
+ {
+       struct ice_adapter *adapter;
+@@ -30,7 +59,7 @@ static struct ice_adapter *ice_adapter_new(u64 dsn)
+       if (!adapter)
+               return NULL;
+-      adapter->device_serial_number = dsn;
++      adapter->index = ice_adapter_index(pdev);
+       spin_lock_init(&adapter->ptp_gltsyn_time_lock);
+       refcount_set(&adapter->refcount, 1);
+@@ -63,24 +92,23 @@ static void ice_adapter_free(struct ice_adapter *adapter)
+  */
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+ {
+-      u64 dsn = pci_get_dsn(pdev);
+       struct ice_adapter *adapter;
+       unsigned long index;
+       int err;
+-      index = ice_adapter_index(dsn);
++      index = ice_adapter_xa_index(pdev);
+       scoped_guard(mutex, &ice_adapters_mutex) {
+               err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
+               if (err == -EBUSY) {
+                       adapter = xa_load(&ice_adapters, index);
+                       refcount_inc(&adapter->refcount);
+-                      WARN_ON_ONCE(adapter->device_serial_number != dsn);
++                      WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
+                       return adapter;
+               }
+               if (err)
+                       return ERR_PTR(err);
+-              adapter = ice_adapter_new(dsn);
++              adapter = ice_adapter_new(pdev);
+               if (!adapter)
+                       return ERR_PTR(-ENOMEM);
+               xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
+@@ -99,11 +127,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+  */
+ void ice_adapter_put(struct pci_dev *pdev)
+ {
+-      u64 dsn = pci_get_dsn(pdev);
+       struct ice_adapter *adapter;
+       unsigned long index;
+-      index = ice_adapter_index(dsn);
++      index = ice_adapter_xa_index(pdev);
+       scoped_guard(mutex, &ice_adapters_mutex) {
+               adapter = xa_load(&ice_adapters, index);
+               if (WARN_ON(!adapter))
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h b/drivers/net/ethernet/intel/ice/ice_adapter.h
+index ac15c0d2bc1a4..409467847c753 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.h
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h
+@@ -32,7 +32,7 @@ struct ice_port_list {
+  * @refcount: Reference count. struct ice_pf objects hold the references.
+  * @ctrl_pf: Control PF of the adapter
+  * @ports: Ports list
+- * @device_serial_number: DSN cached for collision detection on 32bit systems
++ * @index: 64-bit index cached for collision detection on 32bit systems
+  */
+ struct ice_adapter {
+       refcount_t refcount;
+@@ -41,7 +41,7 @@ struct ice_adapter {
+       struct ice_pf *ctrl_pf;
+       struct ice_port_list ports;
+-      u64 device_serial_number;
++      u64 index;
+ };
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev);
+-- 
+2.50.1
+
diff --git a/queue-6.12/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch b/queue-6.12/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch
new file mode 100644 (file)
index 0000000..0c6fc50
--- /dev/null
@@ -0,0 +1,112 @@
+From a8e2d0e7edd1d9a33531482f397fb8c24195a72c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 13:44:35 +0000
+Subject: l2tp: do not use sock_hold() in pppol2tp_session_get_sock()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9b8c88f875c04d4cb9111bd5dd9291c7e9691bf5 ]
+
+pppol2tp_session_get_sock() is using RCU, it must be ready
+for sk_refcnt being zero.
+
+Commit ee40fb2e1eb5 ("l2tp: protect sock pointer of
+struct pppol2tp_session with RCU") was correct because it
+had a call_rcu(..., pppol2tp_put_sk) which was later removed in blamed commit.
+
+pppol2tp_recv() can use pppol2tp_session_get_sock() as well.
+
+Fixes: c5cbaef992d6 ("l2tp: refactor ppp socket/session relationship")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Chapman <jchapman@katalix.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Link: https://patch.msgid.link/20250826134435.1683435-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_ppp.c | 25 ++++++++-----------------
+ 1 file changed, 8 insertions(+), 17 deletions(-)
+
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index 53baf2dd5d5da..16c514f628eac 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -129,22 +129,12 @@ static const struct ppp_channel_ops pppol2tp_chan_ops = {
+ static const struct proto_ops pppol2tp_ops;
+-/* Retrieves the pppol2tp socket associated to a session.
+- * A reference is held on the returned socket, so this function must be paired
+- * with sock_put().
+- */
++/* Retrieves the pppol2tp socket associated to a session. */
+ static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session)
+ {
+       struct pppol2tp_session *ps = l2tp_session_priv(session);
+-      struct sock *sk;
+-
+-      rcu_read_lock();
+-      sk = rcu_dereference(ps->sk);
+-      if (sk)
+-              sock_hold(sk);
+-      rcu_read_unlock();
+-      return sk;
++      return rcu_dereference(ps->sk);
+ }
+ /* Helpers to obtain tunnel/session contexts from sockets.
+@@ -206,14 +196,13 @@ static int pppol2tp_recvmsg(struct socket *sock, struct msghdr *msg,
+ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
+ {
+-      struct pppol2tp_session *ps = l2tp_session_priv(session);
+-      struct sock *sk = NULL;
++      struct sock *sk;
+       /* If the socket is bound, send it in to PPP's input queue. Otherwise
+        * queue it on the session socket.
+        */
+       rcu_read_lock();
+-      sk = rcu_dereference(ps->sk);
++      sk = pppol2tp_session_get_sock(session);
+       if (!sk)
+               goto no_sock;
+@@ -510,13 +499,14 @@ static void pppol2tp_show(struct seq_file *m, void *arg)
+       struct l2tp_session *session = arg;
+       struct sock *sk;
++      rcu_read_lock();
+       sk = pppol2tp_session_get_sock(session);
+       if (sk) {
+               struct pppox_sock *po = pppox_sk(sk);
+               seq_printf(m, "   interface %s\n", ppp_dev_name(&po->chan));
+-              sock_put(sk);
+       }
++      rcu_read_unlock();
+ }
+ static void pppol2tp_session_init(struct l2tp_session *session)
+@@ -1529,6 +1519,7 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+               port = ntohs(inet->inet_sport);
+       }
++      rcu_read_lock();
+       sk = pppol2tp_session_get_sock(session);
+       if (sk) {
+               state = sk->sk_state;
+@@ -1564,8 +1555,8 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+               struct pppox_sock *po = pppox_sk(sk);
+               seq_printf(m, "   interface %s\n", ppp_dev_name(&po->chan));
+-              sock_put(sk);
+       }
++      rcu_read_unlock();
+ }
+ static int pppol2tp_seq_show(struct seq_file *m, void *v)
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-dlink-fix-multicast-stats-being-counted-incorrec.patch b/queue-6.12/net-dlink-fix-multicast-stats-being-counted-incorrec.patch
new file mode 100644 (file)
index 0000000..0dbf078
--- /dev/null
@@ -0,0 +1,46 @@
+From c9f00cf87102c00aa4da68a43d324fb233ae7947 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index 787218d60c6b1..2c1b551e14423 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1091,7 +1091,7 @@ get_stats (struct net_device *dev)
+       dev->stats.rx_bytes += dr32(OctetRcvOk);
+       dev->stats.tx_bytes += dr32(OctetXmtOk);
+-      dev->stats.multicast = dr32(McstFramesRcvdOk);
++      dev->stats.multicast += dr32(McstFramesRcvdOk);
+       dev->stats.collisions += dr32(SingleColFrames)
+                            +  dr32(MultiColFrames);
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch b/queue-6.12/net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch
new file mode 100644 (file)
index 0000000..2d46b77
--- /dev/null
@@ -0,0 +1,122 @@
+From 3a60e772658803e5a200c03d353f7b78750ac313 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 04:56:27 -0700
+Subject: net: hv_netvsc: fix loss of early receive events from host during
+ channel open.
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 9448ccd853368582efa9db05db344f8bb9dffe0f ]
+
+The hv_netvsc driver currently enables NAPI after opening the primary and
+subchannels. This ordering creates a race: if the Hyper-V host places data
+in the host -> guest ring buffer and signals the channel before
+napi_enable() has been called, the channel callback will run but
+napi_schedule_prep() will return false. As a result, the NAPI poller never
+gets scheduled, the data in the ring buffer is not consumed, and the
+receive queue may remain permanently stuck until another interrupt happens
+to arrive.
+
+Fix this by enabling NAPI and registering it with the RX/TX queues before
+vmbus channel is opened. This guarantees that any early host signal after
+open will correctly trigger NAPI scheduling and the ring buffer will be
+drained.
+
+Fixes: 76bb5db5c749d ("netvsc: fix use after free on module removal")
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20250825115627.GA32189@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/netvsc.c       | 17 ++++++++---------
+ drivers/net/hyperv/rndis_filter.c | 23 ++++++++++++++++-------
+ 2 files changed, 24 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 87ac2a5f18091..5f14799b68c53 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1811,6 +1811,11 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+       /* Enable NAPI handler before init callbacks */
+       netif_napi_add(ndev, &net_device->chan_table[0].napi, netvsc_poll);
++      napi_enable(&net_device->chan_table[0].napi);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
++                           &net_device->chan_table[0].napi);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
++                           &net_device->chan_table[0].napi);
+       /* Open the channel */
+       device->channel->next_request_id_callback = vmbus_next_request_id;
+@@ -1830,12 +1835,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+       /* Channel is opened */
+       netdev_dbg(ndev, "hv_netvsc channel opened successfully\n");
+-      napi_enable(&net_device->chan_table[0].napi);
+-      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
+-                           &net_device->chan_table[0].napi);
+-      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
+-                           &net_device->chan_table[0].napi);
+-
+       /* Connect with the NetVsp */
+       ret = netvsc_connect_vsp(device, net_device, device_info);
+       if (ret != 0) {
+@@ -1853,14 +1852,14 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+ close:
+       RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
+-      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
+-      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
+-      napi_disable(&net_device->chan_table[0].napi);
+       /* Now, we can close the channel safely */
+       vmbus_close(device->channel);
+ cleanup:
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
++      napi_disable(&net_device->chan_table[0].napi);
+       netif_napi_del(&net_device->chan_table[0].napi);
+ cleanup2:
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+index 9b8769a8b77a1..9a92552ee35c2 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1252,17 +1252,26 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+       new_sc->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes);
+       new_sc->max_pkt_size = NETVSC_MAX_PKT_SIZE;
++      /* Enable napi before opening the vmbus channel to avoid races
++       * as the host placing data on the host->guest ring may be left
++       * out if napi was not enabled.
++       */
++      napi_enable(&nvchan->napi);
++      netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++                           &nvchan->napi);
++      netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++                           &nvchan->napi);
++
+       ret = vmbus_open(new_sc, netvsc_ring_bytes,
+                        netvsc_ring_bytes, NULL, 0,
+                        netvsc_channel_cb, nvchan);
+-      if (ret == 0) {
+-              napi_enable(&nvchan->napi);
+-              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
+-                                   &nvchan->napi);
+-              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
+-                                   &nvchan->napi);
+-      } else {
++      if (ret != 0) {
+               netdev_notice(ndev, "sub channel open failed: %d\n", ret);
++              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++                                   NULL);
++              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++                                   NULL);
++              napi_disable(&nvchan->napi);
+       }
+       if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn)
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-ipv4-fix-regression-in-local-broadcast-routes.patch b/queue-6.12/net-ipv4-fix-regression-in-local-broadcast-routes.patch
new file mode 100644 (file)
index 0000000..250dbd0
--- /dev/null
@@ -0,0 +1,57 @@
+From 2053842dfbc405f44eb671b366bcb3f68e00f445 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 9a5c9497b3931..261ddb6542a40 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2532,12 +2532,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+                   !netif_is_l3_master(dev_out))
+                       return ERR_PTR(-EINVAL);
+-      if (ipv4_is_lbcast(fl4->daddr))
++      if (ipv4_is_lbcast(fl4->daddr)) {
+               type = RTN_BROADCAST;
+-      else if (ipv4_is_multicast(fl4->daddr))
++
++              /* reset fi to prevent gateway resolution */
++              fi = NULL;
++      } else if (ipv4_is_multicast(fl4->daddr)) {
+               type = RTN_MULTICAST;
+-      else if (ipv4_is_zeronet(fl4->daddr))
++      } else if (ipv4_is_zeronet(fl4->daddr)) {
+               return ERR_PTR(-EINVAL);
++      }
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-macb-disable-clocks-once.patch b/queue-6.12/net-macb-disable-clocks-once.patch
new file mode 100644 (file)
index 0000000..56274c2
--- /dev/null
@@ -0,0 +1,49 @@
+From d50a0061fa6e2e36188ec60bb5f3c0201b9effe3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 10:30:22 -0400
+Subject: net: macb: Disable clocks once
+
+From: Neil Mandir <neil.mandir@seco.com>
+
+[ Upstream commit dac978e51cce0c1f00a14c4a82f81d387f79b2d4 ]
+
+When the driver is removed the clocks are disabled twice: once in
+macb_remove and a second time by runtime pm. Disable wakeup in remove so
+all the clocks are disabled and skip the second call to macb_clks_disable.
+Always suspend the device as we always set it active in probe.
+
+Fixes: d54f89af6cc4 ("net: macb: Add pm runtime support")
+Signed-off-by: Neil Mandir <neil.mandir@seco.com>
+Co-developed-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Link: https://patch.msgid.link/20250826143022.935521-1-sean.anderson@linux.dev
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index 2421a7bcd221e..6c2d69ef1a8db 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5230,14 +5230,11 @@ static void macb_remove(struct platform_device *pdev)
+               mdiobus_unregister(bp->mii_bus);
+               mdiobus_free(bp->mii_bus);
++              device_set_wakeup_enable(&bp->pdev->dev, 0);
+               cancel_work_sync(&bp->hresp_err_bh_work);
+               pm_runtime_disable(&pdev->dev);
+               pm_runtime_dont_use_autosuspend(&pdev->dev);
+-              if (!pm_runtime_suspended(&pdev->dev)) {
+-                      macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk,
+-                                        bp->rx_clk, bp->tsu_clk);
+-                      pm_runtime_set_suspended(&pdev->dev);
+-              }
++              pm_runtime_set_suspended(&pdev->dev);
+               phylink_destroy(bp->phylink);
+               free_netdev(dev);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-macb-fix-unregister_netdev-call-order-in-macb_re.patch b/queue-6.12/net-macb-fix-unregister_netdev-call-order-in-macb_re.patch
new file mode 100644 (file)
index 0000000..cd8d66c
--- /dev/null
@@ -0,0 +1,63 @@
+From 4682769487e10126710667542f30f606416557a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Aug 2025 07:25:27 +0800
+Subject: net: macb: fix unregister_netdev call order in macb_remove()
+
+From: luoguangfei <15388634752@163.com>
+
+[ Upstream commit 01b9128c5db1b470575d07b05b67ffa3cb02ebf1 ]
+
+When removing a macb device, the driver calls phy_exit() before
+unregister_netdev(). This leads to a WARN from kernfs:
+
+  ------------[ cut here ]------------
+  kernfs: can not remove 'attached_dev', no directory
+  WARNING: CPU: 1 PID: 27146 at fs/kernfs/dir.c:1683
+  Call trace:
+    kernfs_remove_by_name_ns+0xd8/0xf0
+    sysfs_remove_link+0x24/0x58
+    phy_detach+0x5c/0x168
+    phy_disconnect+0x4c/0x70
+    phylink_disconnect_phy+0x6c/0xc0 [phylink]
+    macb_close+0x6c/0x170 [macb]
+    ...
+    macb_remove+0x60/0x168 [macb]
+    platform_remove+0x5c/0x80
+    ...
+
+The warning happens because the PHY is being exited while the netdev
+is still registered. The correct order is to unregister the netdev
+before shutting down the PHY and cleaning up the MDIO bus.
+
+Fix this by moving unregister_netdev() ahead of phy_exit() in
+macb_remove().
+
+Fixes: 8b73fa3ae02b ("net: macb: Added ZynqMP-specific initialization")
+Signed-off-by: luoguangfei <15388634752@163.com>
+Link: https://patch.msgid.link/20250818232527.1316-1-15388634752@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index 3c2a7919b1289..2421a7bcd221e 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5225,11 +5225,11 @@ static void macb_remove(struct platform_device *pdev)
+       if (dev) {
+               bp = netdev_priv(dev);
++              unregister_netdev(dev);
+               phy_exit(bp->sgmii_phy);
+               mdiobus_unregister(bp->mii_bus);
+               mdiobus_free(bp->mii_bus);
+-              unregister_netdev(dev);
+               cancel_work_sync(&bp->hresp_err_bh_work);
+               pm_runtime_disable(&pdev->dev);
+               pm_runtime_dont_use_autosuspend(&pdev->dev);
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch b/queue-6.12/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
new file mode 100644 (file)
index 0000000..ee1fd81
--- /dev/null
@@ -0,0 +1,247 @@
+From 4ae30f329aee5fe1c57434e23ad9ae6cfc1fb216 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:29 +0300
+Subject: net/mlx5: Fix lockdep assertion on sync reset unload event
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 902a8bc23a24882200f57cadc270e15a2cfaf2bb ]
+
+Fix lockdep assertion triggered during sync reset unload event. When the
+sync reset flow is initiated using the devlink reload fw_activate
+option, the PF already holds the devlink lock while handling unload
+event. In this case, delegate sync reset unload event handling back to
+the devlink callback process to avoid double-locking and resolve the
+lockdep warning.
+
+Kernel log:
+WARNING: CPU: 9 PID: 1578 at devl_assert_locked+0x31/0x40
+[...]
+Call Trace:
+<TASK>
+ mlx5_unload_one_devl_locked+0x2c/0xc0 [mlx5_core]
+ mlx5_sync_reset_unload_event+0xaf/0x2f0 [mlx5_core]
+ process_one_work+0x222/0x640
+ worker_thread+0x199/0x350
+ kthread+0x10b/0x230
+ ? __pfx_worker_thread+0x10/0x10
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x8e/0x100
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+</TASK>
+
+Fixes: 7a9770f1bfea ("net/mlx5: Handle sync reset unload event")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-7-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c |   2 +-
+ .../ethernet/mellanox/mlx5/core/fw_reset.c    | 108 ++++++++++--------
+ .../ethernet/mellanox/mlx5/core/fw_reset.h    |   1 +
+ 3 files changed, 63 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 7211e65ad2dcc..511b3ba245420 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+       if (err)
+               return err;
+-      mlx5_unload_one_devl_locked(dev, false);
++      mlx5_sync_reset_unload_flow(dev, true);
+       err = mlx5_health_wait_pci_up(dev);
+       if (err)
+               NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 4f55e55ecb551..0829912157c97 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -12,7 +12,8 @@ enum {
+       MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+       MLX5_FW_RESET_FLAGS_PENDING_COMP,
+       MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+-      MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
++      MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
++      MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
+ };
+ struct mlx5_fw_reset {
+@@ -218,7 +219,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
+       return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false);
+ }
+-static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded)
++static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ {
+       struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
+       struct devlink *devlink = priv_to_devlink(dev);
+@@ -227,8 +228,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload
+       if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
+               complete(&fw_reset->done);
+       } else {
+-              if (!unloaded)
+-                      mlx5_unload_one(dev, false);
++              mlx5_sync_reset_unload_flow(dev, false);
+               if (mlx5_health_wait_pci_up(dev))
+                       mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+               else
+@@ -271,7 +271,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work)
+       mlx5_sync_reset_clear_reset_requested(dev, false);
+       mlx5_enter_error_state(dev, true);
+-      mlx5_fw_reset_complete_reload(dev, false);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ #define MLX5_RESET_POLL_INTERVAL      (HZ / 10)
+@@ -581,6 +581,59 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
+       return err;
+ }
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked)
++{
++      struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++      unsigned long timeout;
++      bool reset_action;
++      u8 rst_state;
++      int err;
++
++      if (locked)
++              mlx5_unload_one_devl_locked(dev, false);
++      else
++              mlx5_unload_one(dev, false);
++
++      if (!test_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags))
++              return;
++
++      mlx5_set_fw_rst_ack(dev);
++      mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
++
++      reset_action = false;
++      timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
++      do {
++              rst_state = mlx5_get_fw_rst_state(dev);
++              if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
++                  rst_state == MLX5_FW_RST_STATE_IDLE) {
++                      reset_action = true;
++                      break;
++              }
++              msleep(20);
++      } while (!time_after(jiffies, timeout));
++
++      if (!reset_action) {
++              mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
++                            rst_state);
++              fw_reset->ret = -ETIMEDOUT;
++              goto done;
++      }
++
++      mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n",
++                     rst_state);
++      if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
++              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
++              if (err) {
++                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n",
++                                     err);
++                      fw_reset->ret = err;
++              }
++      }
++
++done:
++      clear_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+@@ -608,16 +661,13 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+       mlx5_enter_error_state(dev, true);
+ done:
+       fw_reset->ret = err;
+-      mlx5_fw_reset_complete_reload(dev, false);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset;
+       struct mlx5_core_dev *dev;
+-      unsigned long timeout;
+-      bool reset_action;
+-      u8 rst_state;
+       int err;
+       fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work);
+@@ -626,6 +676,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, false))
+               return;
++      set_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n");
+       err = mlx5_cmd_fast_teardown_hca(dev);
+@@ -634,44 +685,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+       else
+               mlx5_enter_error_state(dev, true);
+-      if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
+-              mlx5_unload_one_devl_locked(dev, false);
+-      else
+-              mlx5_unload_one(dev, false);
+-
+-      mlx5_set_fw_rst_ack(dev);
+-      mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
+-
+-      reset_action = false;
+-      timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
+-      do {
+-              rst_state = mlx5_get_fw_rst_state(dev);
+-              if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
+-                  rst_state == MLX5_FW_RST_STATE_IDLE) {
+-                      reset_action = true;
+-                      break;
+-              }
+-              msleep(20);
+-      } while (!time_after(jiffies, timeout));
+-
+-      if (!reset_action) {
+-              mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
+-                            rst_state);
+-              fw_reset->ret = -ETIMEDOUT;
+-              goto done;
+-      }
+-
+-      mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
+-      if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+-              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+-              if (err) {
+-                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
+-                      fw_reset->ret = err;
+-              }
+-      }
+-
+-done:
+-      mlx5_fw_reset_complete_reload(dev, true);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index ea527d06a85f0..d5b28525c960d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -12,6 +12,7 @@ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+ int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev,
+                                    struct netlink_ext_ack *extack);
+ void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev);
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-mlx5-nack-sync-reset-when-sfs-are-present.patch b/queue-6.12/net-mlx5-nack-sync-reset-when-sfs-are-present.patch
new file mode 100644 (file)
index 0000000..ef5e00c
--- /dev/null
@@ -0,0 +1,100 @@
+From 0305d98a7569aa2db9f851517fd3bf6d6209cc08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:30 +0300
+Subject: net/mlx5: Nack sync reset when SFs are present
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 26e42ec7712d392d561964514b1f253b1a96f42d ]
+
+If PF (Physical Function) has SFs (Sub-Functions), since the SFs are not
+taking part in the synchronization flow, sync reset can lead to fatal
+error on the SFs, as the function will be closed unexpectedly from the
+SF point of view.
+
+Add a check to prevent sync reset when there are SFs on a PF device
+which is not ECPF, as ECPF is teardowned gracefully before reset.
+
+Fixes: 92501fa6e421 ("net/mlx5: Ack on sync_reset_request only if PF can do reset_now")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-8-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c   |  6 ++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 10 ++++++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h      |  6 ++++++
+ 3 files changed, 22 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 0829912157c97..516df7f1997eb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -6,6 +6,7 @@
+ #include "fw_reset.h"
+ #include "diag/fw_tracer.h"
+ #include "lib/tout.h"
++#include "sf/sf.h"
+ enum {
+       MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+@@ -423,6 +424,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev,
+               return false;
+       }
++      if (!mlx5_core_is_ecpf(dev) && !mlx5_sf_table_empty(dev)) {
++              mlx5_core_warn(dev, "SFs should be removed before reset\n");
++              return false;
++      }
++
+ #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)
+       if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) {
+               err = mlx5_check_hotplug_interrupt(dev);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index b96909fbeb12d..bdac3db1bd61d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -518,3 +518,13 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+       WARN_ON(!xa_empty(&table->function_ids));
+       kfree(table);
+ }
++
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++      struct mlx5_sf_table *table = dev->priv.sf_table;
++
++      if (!table)
++              return true;
++
++      return xa_empty(&table->function_ids);
++}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+index 860f9ddb7107b..89559a37997ad 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+@@ -17,6 +17,7 @@ void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev);
+ int mlx5_sf_table_init(struct mlx5_core_dev *dev);
+ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev);
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev);
+ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+                            const struct devlink_port_new_attrs *add_attr,
+@@ -61,6 +62,11 @@ static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ {
+ }
++static inline bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++      return true;
++}
++
+ #endif
+ #endif
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch b/queue-6.12/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
new file mode 100644 (file)
index 0000000..416832f
--- /dev/null
@@ -0,0 +1,51 @@
+From 80660628a803bd3aacc006ba6403cfc16e627fd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:28 +0300
+Subject: net/mlx5: Reload auxiliary drivers on fw_activate
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 34cc6a54914f478c93e176450fae6313404f9f74 ]
+
+The devlink reload fw_activate command performs firmware activation
+followed by driver reload, while devlink reload driver_reinit triggers
+only driver reload. However, the driver reload logic differs between the
+two modes, as on driver_reinit mode mlx5 also reloads auxiliary drivers,
+while in fw_activate mode the auxiliary drivers are suspended where
+applicable.
+
+Additionally, following the cited commit, if the device has multiple PFs,
+the behavior during fw_activate may vary between PFs: one PF may suspend
+auxiliary drivers, while another reloads them.
+
+Align devlink dev reload fw_activate behavior with devlink dev reload
+driver_reinit, to reload all auxiliary drivers.
+
+Fixes: 72ed5d5624af ("net/mlx5: Suspend auxiliary devices only in case of PCI device suspend")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index a2cf3e79693dd..7211e65ad2dcc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+       if (err)
+               return err;
+-      mlx5_unload_one_devl_locked(dev, true);
++      mlx5_unload_one_devl_locked(dev, false);
+       err = mlx5_health_wait_pci_up(dev);
+       if (err)
+               NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-mlx5e-set-local-xoff-after-fw-update.patch b/queue-6.12/net-mlx5e-set-local-xoff-after-fw-update.patch
new file mode 100644 (file)
index 0000000..1af4407
--- /dev/null
@@ -0,0 +1,50 @@
+From b11f28dc3d930781e666b59b5287b57ec75144c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+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 3efa8bf1d14ef..4720523813b97 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -575,7 +575,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+               if (err)
+                       return err;
+       }
+-      priv->dcbx.xoff = xoff;
+       /* Apply the settings */
+       if (update_buffer) {
+@@ -584,6 +583,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                       return err;
+       }
++      priv->dcbx.xoff = xoff;
++
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch b/queue-6.12/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
new file mode 100644 (file)
index 0000000..b509f9f
--- /dev/null
@@ -0,0 +1,100 @@
+From 66bef2beb2be1701962f54c355755376b35f1c32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h         | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c   | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+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 f4a19ffbb641c..66d276a1be836 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -66,11 +66,23 @@ struct mlx5e_port_buffer {
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_NETWORK_BUFFER];
+ };
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++                              u32 change, unsigned int mtu,
++                              void *pfc,
++                              u32 *buffer_size,
++                              u8 *prio2buffer)
++{
++      return 0;
++}
++#endif
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 4a2f58a9d7066..de2327ffb0f78 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -47,6 +47,7 @@
+ #include "en.h"
+ #include "en/dim.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2917,9 +2918,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+       struct mlx5e_params *params = &priv->channels.params;
+       struct net_device *netdev = priv->netdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
+-      u16 mtu;
++      u16 mtu, prev_mtu;
+       int err;
++      mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+       err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+       if (err)
+               return err;
+@@ -2929,6 +2932,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+               netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+                           __func__, mtu, params->sw_mtu);
++      if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++              err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++                                                    NULL, NULL, NULL);
++              if (err) {
++                      netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++                                  __func__, mtu, err, prev_mtu);
++
++                      mlx5e_set_mtu(mdev, params, prev_mtu);
++                      return err;
++              }
++      }
++
+       params->sw_mtu = mtu;
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch b/queue-6.12/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
new file mode 100644 (file)
index 0000000..5bfb35e
--- /dev/null
@@ -0,0 +1,46 @@
+From ad7d85c7665145322f6cc2c6d3169d00eb152099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index de2327ffb0f78..6176457b846bc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -135,6 +135,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+       if (up) {
+               netdev_info(priv->netdev, "Link up\n");
+               netif_carrier_on(priv->netdev);
++              mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++                                              NULL, NULL, NULL);
+       } else {
+               netdev_info(priv->netdev, "Link down\n");
+               netif_carrier_off(priv->netdev);
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-rose-convert-use-field-to-refcount_t.patch b/queue-6.12/net-rose-convert-use-field-to-refcount_t.patch
new file mode 100644 (file)
index 0000000..bfe4960
--- /dev/null
@@ -0,0 +1,370 @@
+From af3b1f96a4b1ec39e8ae59d453e7c3db06736ec4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:56 +0900
+Subject: net: rose: convert 'use' field to refcount_t
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit d860d1faa6b2ce3becfdb8b0c2b048ad31800061 ]
+
+The 'use' field in struct rose_neigh is used as a reference counter but
+lacks atomicity. This can lead to race conditions where a rose_neigh
+structure is freed while still being referenced by other code paths.
+
+For example, when rose_neigh->use becomes zero during an ioctl operation
+via rose_rt_ioctl(), the structure may be removed while its timer is
+still active, potentially causing use-after-free issues.
+
+This patch changes the type of 'use' from unsigned short to refcount_t and
+updates all code paths to use rose_neigh_hold() and rose_neigh_put() which
+operate reference counts atomically.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-3-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h    | 18 +++++++++++++-----
+ net/rose/af_rose.c    | 13 +++++++------
+ net/rose/rose_in.c    | 12 ++++++------
+ net/rose/rose_route.c | 33 ++++++++++++++++++---------------
+ net/rose/rose_timer.c |  2 +-
+ 5 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 174b4f605d849..2b5491bbf39ab 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H 
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+       ax25_cb                 *ax25;
+       struct net_device               *dev;
+       unsigned short          count;
+-      unsigned short          use;
++      refcount_t              use;
+       unsigned int            number;
+       char                    restarted;
+       char                    dce_mode;
+@@ -151,12 +152,19 @@ struct rose_sock {
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++      refcount_inc(&rose_neigh->use);
++}
++
+ static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
+ {
+-      if (rose_neigh->ax25)
+-              ax25_cb_put(rose_neigh->ax25);
+-      kfree(rose_neigh->digipeat);
+-      kfree(rose_neigh);
++      if (refcount_dec_and_test(&rose_neigh->use)) {
++              if (rose_neigh->ax25)
++                      ax25_cb_put(rose_neigh->ax25);
++              kfree(rose_neigh->digipeat);
++              kfree(rose_neigh);
++      }
+ }
+ /* af_rose.c */
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index a4a668b88a8f2..b8078b42f5de6 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+               if (rose->neighbour == neigh) {
+                       rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour = NULL;
+               }
+       }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+               if (rose->device == dev) {
+                       rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+                       if (rose->neighbour)
+-                              rose->neighbour->use--;
++                              rose_neigh_put(rose->neighbour);
+                       netdev_put(rose->device, &rose->dev_tracker);
+                       rose->device = NULL;
+               }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+               break;
+       case ROSE_STATE_2:
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               release_sock(sk);
+               rose_disconnect(sk, 0, -1, -1);
+               lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       rose->lci = rose_new_lci(rose->neighbour);
+       if (!rose->lci) {
+               err = -ENETUNREACH;
++              rose_neigh_put(rose->neighbour);
+               goto out_release;
+       }
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+               dev = rose_dev_first();
+               if (!dev) {
+                       err = -ENETUNREACH;
++                      rose_neigh_put(rose->neighbour);
+                       goto out_release;
+               }
+               user = ax25_findbyuid(current_euid());
+               if (!user) {
+                       err = -EINVAL;
++                      rose_neigh_put(rose->neighbour);
+                       dev_put(dev);
+                       goto out_release;
+               }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       rose->state = ROSE_STATE_1;
+-      rose->neighbour->use++;
+-
+       rose_write_internal(sk, ROSE_CALL_REQUEST);
+       rose_start_heartbeat(sk);
+       rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
+                            GFP_ATOMIC);
+       make_rose->facilities    = facilities;
+-      make_rose->neighbour->use++;
++      rose_neigh_hold(make_rose->neighbour);
+       if (rose_sk(sk)->defer) {
+               make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b4..7caae93937ee9 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       case ROSE_CLEAR_CONFIRMATION:
+               rose_disconnect(sk, 0, -1, -1);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety
+       if (frametype == ROSE_CLEAR_REQUEST) {
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose_sk(sk)->neighbour->use--;
++              rose_neigh_put(rose_sk(sk)->neighbour);
+       }
+       return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index b406b1e0fb1e7..42460da0854d5 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+               rose_neigh->ax25      = NULL;
+               rose_neigh->dev       = dev;
+               rose_neigh->count     = 0;
+-              rose_neigh->use       = 0;
+               rose_neigh->dce_mode  = 0;
+               rose_neigh->loopback  = 0;
+               rose_neigh->number    = rose_neigh_no++;
+               rose_neigh->restarted = 0;
++              refcount_set(&rose_neigh->use, 1);
+               skb_queue_head_init(&rose_neigh->queue);
+@@ -255,10 +255,10 @@ static void rose_remove_route(struct rose_route *rose_route)
+       struct rose_route *s;
+       if (rose_route->neigh1 != NULL)
+-              rose_route->neigh1->use--;
++              rose_neigh_put(rose_route->neigh1);
+       if (rose_route->neigh2 != NULL)
+-              rose_route->neigh2->use--;
++              rose_neigh_put(rose_route->neigh2);
+       if ((s = rose_route_list) == rose_route) {
+               rose_route_list = rose_route->next;
+@@ -323,7 +323,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0) {
++                      if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
+                               rose_neigh_put(rose_neigh);
+                       }
+@@ -375,11 +375,11 @@ void rose_add_loopback_neigh(void)
+       sn->ax25      = NULL;
+       sn->dev       = NULL;
+       sn->count     = 0;
+-      sn->use       = 0;
+       sn->dce_mode  = 1;
+       sn->loopback  = 1;
+       sn->number    = rose_neigh_no++;
+       sn->restarted = 1;
++      refcount_set(&sn->use, 1);
+       skb_queue_head_init(&sn->queue);
+@@ -561,8 +561,7 @@ static int rose_clear_routes(void)
+               s          = rose_neigh;
+               rose_neigh = rose_neigh->next;
+-              if (s->use == 0 && !s->loopback) {
+-                      s->count = 0;
++              if (!s->loopback) {
+                       rose_remove_neigh(s);
+                       rose_neigh_put(s);
+               }
+@@ -680,6 +679,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+                       for (i = 0; i < node->count; i++) {
+                               if (node->neighbour[i]->restarted) {
+                                       res = node->neighbour[i];
++                                      rose_neigh_hold(node->neighbour[i]);
+                                       goto out;
+                               }
+                       }
+@@ -691,6 +691,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+                               for (i = 0; i < node->count; i++) {
+                                       if (!rose_ftimer_running(node->neighbour[i])) {
+                                               res = node->neighbour[i];
++                                              rose_neigh_hold(node->neighbour[i]);
+                                               goto out;
+                                       }
+                                       failed = 1;
+@@ -780,13 +781,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
+               }
+               if (rose_route->neigh1 == rose_neigh) {
+-                      rose_route->neigh1->use--;
++                      rose_neigh_put(rose_route->neigh1);
+                       rose_route->neigh1 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+               }
+               if (rose_route->neigh2 == rose_neigh) {
+-                      rose_route->neigh2->use--;
++                      rose_neigh_put(rose_route->neigh2);
+                       rose_route->neigh2 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+               }
+@@ -915,7 +916,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+                       rose_clear_queues(sk);
+                       rose->cause      = ROSE_NETWORK_CONGESTION;
+                       rose->diagnostic = 0;
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour  = NULL;
+                       rose->lci        = 0;
+                       rose->state      = ROSE_STATE_0;
+@@ -1040,12 +1041,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+               rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
+-              goto out;
++              goto put_neigh;
+       }
+       if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+               rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+-              goto out;
++              goto put_neigh;
+       }
+       rose_route->lci1      = lci;
+@@ -1058,8 +1059,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_route->lci2      = new_lci;
+       rose_route->neigh2    = new_neigh;
+-      rose_route->neigh1->use++;
+-      rose_route->neigh2->use++;
++      rose_neigh_hold(rose_route->neigh1);
++      rose_neigh_hold(rose_route->neigh2);
+       rose_route->next = rose_route_list;
+       rose_route_list  = rose_route;
+@@ -1071,6 +1072,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_transmit_link(skb, rose_route->neigh2);
+       res = 1;
++put_neigh:
++      rose_neigh_put(new_neigh);
+ out:
+       spin_unlock_bh(&rose_route_list_lock);
+       spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1186,7 +1189,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         rose_neigh->use,
++                         refcount_read(&rose_neigh->use) - 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 1525773e94aa1..c52d7d20c5199 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+               break;
+       case ROSE_STATE_2:      /* T3 */
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               rose_disconnect(sk, ETIMEDOUT, -1, -1);
+               break;
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-rose-include-node-references-in-rose_neigh-refco.patch b/queue-6.12/net-rose-include-node-references-in-rose_neigh-refco.patch
new file mode 100644 (file)
index 0000000..7791916
--- /dev/null
@@ -0,0 +1,142 @@
+From 93c95d20d183797f279f77a77bcda21d14739ed3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:57 +0900
+Subject: net: rose: include node references in rose_neigh refcount
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit da9c9c877597170b929a6121a68dcd3dd9a80f45 ]
+
+Current implementation maintains two separate reference counting
+mechanisms: the 'count' field in struct rose_neigh tracks references from
+rose_node structures, while the 'use' field (now refcount_t) tracks
+references from rose_sock.
+
+This patch merges these two reference counting systems using 'use' field
+for proper reference management. Specifically, this patch adds incrementing
+and decrementing of rose_neigh->use when rose_neigh->count is incremented
+or decremented.
+
+This patch also modifies rose_rt_free(), rose_rt_device_down() and
+rose_clear_route() to properly release references to rose_neigh objects
+before freeing a rose_node through rose_remove_node().
+
+These changes ensure rose_neigh structures are properly freed only when
+all references, including those from rose_node structures, are released.
+As a result, this resolves a slab-use-after-free issue reported by Syzbot.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+942297eecf7d2d61d1f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=942297eecf7d2d61d1f1
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-4-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/rose_route.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 42460da0854d5..6acbb795c506d 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+                       }
+               }
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+               goto out;
+       }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+               rose_node->neighbour[rose_node->count] = rose_neigh;
+               rose_node->count++;
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+       }
+ out:
+@@ -322,6 +324,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+       for (i = 0; i < rose_node->count; i++) {
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
++                      rose_neigh_put(rose_neigh);
+                       if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
+@@ -430,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+       rose_node_list  = rose_node;
+       rose_loopback_neigh->count++;
++      rose_neigh_hold(rose_loopback_neigh);
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -461,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+       rose_remove_node(rose_node);
+       rose_loopback_neigh->count--;
++      rose_neigh_put(rose_loopback_neigh);
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -500,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+                               memmove(&t->neighbour[i], &t->neighbour[i + 1],
+                                       sizeof(t->neighbour[0]) *
+                                               (t->count - i));
++                              rose_neigh_put(s);
+                       }
+                       if (t->count <= 0)
+@@ -543,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+       struct rose_neigh *s, *rose_neigh;
+       struct rose_node  *t, *rose_node;
++      int i;
+       spin_lock_bh(&rose_node_list_lock);
+       spin_lock_bh(&rose_neigh_list_lock);
+@@ -553,8 +560,12 @@ static int rose_clear_routes(void)
+       while (rose_node != NULL) {
+               t         = rose_node;
+               rose_node = rose_node->next;
+-              if (!t->loopback)
++
++              if (!t->loopback) {
++                      for (i = 0; i < rose_node->count; i++)
++                              rose_neigh_put(t->neighbour[i]);
+                       rose_remove_node(t);
++              }
+       }
+       while (rose_neigh != NULL) {
+@@ -1189,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         refcount_read(&rose_neigh->use) - 1,
++                         refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1294,6 +1305,7 @@ void __exit rose_rt_free(void)
+       struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+       struct rose_node  *t, *rose_node  = rose_node_list;
+       struct rose_route *u, *rose_route = rose_route_list;
++      int i;
+       while (rose_neigh != NULL) {
+               s          = rose_neigh;
+@@ -1307,6 +1319,8 @@ void __exit rose_rt_free(void)
+               t         = rose_node;
+               rose_node = rose_node->next;
++              for (i = 0; i < t->count; i++)
++                      rose_neigh_put(t->neighbour[i]);
+               rose_remove_node(t);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-rose-split-remove-and-free-operations-in-rose_re.patch b/queue-6.12/net-rose-split-remove-and-free-operations-in-rose_re.patch
new file mode 100644 (file)
index 0000000..2c45d3f
--- /dev/null
@@ -0,0 +1,115 @@
+From a2748e21b13e2c0c770b77e13d842cb1edc831e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:55 +0900
+Subject: net: rose: split remove and free operations in rose_remove_neigh()
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit dcb34659028f856c423a29ef9b4e2571d203444d ]
+
+The current rose_remove_neigh() performs two distinct operations:
+1. Removes rose_neigh from rose_neigh_list
+2. Frees the rose_neigh structure
+
+Split these operations into separate functions to improve maintainability
+and prepare for upcoming refcount_t conversion. The timer cleanup remains
+in rose_remove_neigh() because free operations can be called from timer
+itself.
+
+This patch introduce rose_neigh_put() to handle the freeing of rose_neigh
+structures and modify rose_remove_neigh() to handle removal only.
+
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-2-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h    |  8 ++++++++
+ net/rose/rose_route.c | 15 ++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa3..174b4f605d849 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -151,6 +151,14 @@ struct rose_sock {
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++      if (rose_neigh->ax25)
++              ax25_cb_put(rose_neigh->ax25);
++      kfree(rose_neigh->digipeat);
++      kfree(rose_neigh);
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int  sysctl_rose_restart_request_timeout;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index a7054546f52df..b406b1e0fb1e7 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,20 +234,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+       if ((s = rose_neigh_list) == rose_neigh) {
+               rose_neigh_list = rose_neigh->next;
+-              if (rose_neigh->ax25)
+-                      ax25_cb_put(rose_neigh->ax25);
+-              kfree(rose_neigh->digipeat);
+-              kfree(rose_neigh);
+               return;
+       }
+       while (s != NULL && s->next != NULL) {
+               if (s->next == rose_neigh) {
+                       s->next = rose_neigh->next;
+-                      if (rose_neigh->ax25)
+-                              ax25_cb_put(rose_neigh->ax25);
+-                      kfree(rose_neigh->digipeat);
+-                      kfree(rose_neigh);
+                       return;
+               }
+@@ -331,8 +323,10 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0)
++                      if (rose_neigh->count == 0 && rose_neigh->use == 0) {
+                               rose_remove_neigh(rose_neigh);
++                              rose_neigh_put(rose_neigh);
++                      }
+                       rose_node->count--;
+@@ -513,6 +507,7 @@ void rose_rt_device_down(struct net_device *dev)
+               }
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       spin_unlock_bh(&rose_neigh_list_lock);
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -569,6 +564,7 @@ static int rose_clear_routes(void)
+               if (s->use == 0 && !s->loopback) {
+                       s->count = 0;
+                       rose_remove_neigh(s);
++                      rose_neigh_put(s);
+               }
+       }
+@@ -1301,6 +1297,7 @@ void __exit rose_rt_free(void)
+               rose_neigh = rose_neigh->next;
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       while (rose_node != NULL) {
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch b/queue-6.12/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
new file mode 100644 (file)
index 0000000..75e60e6
--- /dev/null
@@ -0,0 +1,68 @@
+From ae8d420d7e128b9a02396d38cd542c9b890c81dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:54 +0800
+Subject: net: stmmac: Set CIC bit only for TX queues with COE
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit b1eded580ab28119de0b0f21efe37ee2b4419144 ]
+
+Currently, in the AF_XDP transmit paths, the CIC bit of
+TX Desc3 is set for all packets. Setting this bit for
+packets transmitting through queues that don't support
+checksum offloading causes the TX DMA to get stuck after
+transmitting some packets. This patch ensures the CIC bit
+of TX Desc3 is set only if the TX queue supports checksum
+offloading.
+
+Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-3-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 058cd9e9fd71d..40d56ff66b6a8 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2488,6 +2488,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+       struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
+       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
+       struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
++      bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+       struct xsk_buff_pool *pool = tx_q->xsk_pool;
+       unsigned int entry = tx_q->cur_tx;
+       struct dma_desc *tx_desc = NULL;
+@@ -2573,7 +2574,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+               }
+               stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
+-                                     true, priv->mode, true, true,
++                                     csum, priv->mode, true, true,
+                                      xdp_desc.len);
+               stmmac_enable_dma_transmission(priv, priv->ioaddr, queue);
+@@ -4902,6 +4903,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ {
+       struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
+       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
++      bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+       unsigned int entry = tx_q->cur_tx;
+       struct dma_desc *tx_desc;
+       dma_addr_t dma_addr;
+@@ -4953,7 +4955,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+       stmmac_set_desc_addr(priv, tx_desc, dma_addr);
+       stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len,
+-                             true, priv->mode, true, true,
++                             csum, priv->mode, true, true,
+                              xdpf->len);
+       tx_q->tx_count_frames++;
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-stmmac-xgmac-correct-supported-speed-modes.patch b/queue-6.12/net-stmmac-xgmac-correct-supported-speed-modes.patch
new file mode 100644 (file)
index 0000000..8d71078
--- /dev/null
@@ -0,0 +1,96 @@
+From 1a4d2517f1d21daef0a273d2adbfac5da7ae5030 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:53 +0800
+Subject: net: stmmac: xgmac: Correct supported speed modes
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 42ef11b2bff5b6a2910c28d2ea47cc00e0fbcaec ]
+
+Correct supported speed modes as per the XGMAC databook.
+Commit 9cb54af214a7 ("net: stmmac: Fix IP-cores specific
+MAC capabilities") removes support for 10M, 100M and
+1000HD. 1000HD is not supported by XGMAC IP, but it does
+support 10M and 100M FD mode for XGMAC version >= 2_20,
+and it also supports 10M and 100M HD mode if the HDSEL bit
+is set in the MAC_HW_FEATURE0 reg. This commit enables support
+for 10M and 100M speed modes for XGMAC IP based on XGMAC
+version and MAC capabilities.
+
+Fixes: 9cb54af214a7 ("net: stmmac: Fix IP-cores specific MAC capabilities")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-2-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 13 +++++++++++--
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c  |  5 +++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+index f519d43738b08..445259f2ee935 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+@@ -47,6 +47,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
+       writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
+ }
++static void dwxgmac2_update_caps(struct stmmac_priv *priv)
++{
++      if (!priv->dma_cap.mbps_10_100)
++              priv->hw->link.caps &= ~(MAC_10 | MAC_100);
++      else if (!priv->dma_cap.half_duplex)
++              priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD);
++}
++
+ static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
+ {
+       u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
+@@ -1532,6 +1540,7 @@ static void dwxgmac3_fpe_configure(void __iomem *ioaddr,
+ const struct stmmac_ops dwxgmac210_ops = {
+       .core_init = dwxgmac2_core_init,
++      .update_caps = dwxgmac2_update_caps,
+       .set_mac = dwxgmac2_set_mac,
+       .rx_ipc = dwxgmac2_rx_ipc,
+       .rx_queue_enable = dwxgmac2_rx_queue_enable,
+@@ -1646,8 +1655,8 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
+               mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+       mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+-                       MAC_1000FD | MAC_2500FD | MAC_5000FD |
+-                       MAC_10000FD;
++                       MAC_10 | MAC_100 | MAC_1000FD |
++                       MAC_2500FD | MAC_5000FD | MAC_10000FD;
+       mac->link.duplex = 0;
+       mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
+       mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 7201a38842651..4d6bb995d8d84 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -382,8 +382,11 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
+ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+                                  struct dma_features *dma_cap)
+ {
++      struct stmmac_priv *priv;
+       u32 hw_cap;
++      priv = container_of(dma_cap, struct stmmac_priv, dma_cap);
++
+       /* MAC HW feature 0 */
+       hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
+       dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31;
+@@ -406,6 +409,8 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+       dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
+       dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3;
+       dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
++      if (dma_cap->mbps_1000 && priv->synopsys_id >= DWXGMAC_CORE_2_20)
++              dma_cap->mbps_10_100 = 1;
+       /* MAC HW feature 1 */
+       hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
+-- 
+2.50.1
+
diff --git a/queue-6.12/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch b/queue-6.12/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
new file mode 100644 (file)
index 0000000..ad52ecd
--- /dev/null
@@ -0,0 +1,49 @@
+From 21d8fd933800cb4019e17798b522eca54b67be1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5dcc95bc0ad28..7201a38842651 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -203,10 +203,6 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+       }
+       writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+-      /* Enable MTL RX overflow */
+-      value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+-      writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+-- 
+2.50.1
+
diff --git a/queue-6.12/of-reserved_mem-restructure-call-site-for-dma_contig.patch b/queue-6.12/of-reserved_mem-restructure-call-site-for-dma_contig.patch
new file mode 100644 (file)
index 0000000..a1db2b0
--- /dev/null
@@ -0,0 +1,101 @@
+From 2c88ee76ee491dd224dfb5c628dfd172dd4ea8a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Aug 2025 10:24:21 -0700
+Subject: of: reserved_mem: Restructure call site for
+ dma_contiguous_early_fixup()
+
+From: Oreoluwa Babatunde <oreoluwa.babatunde@oss.qualcomm.com>
+
+[ Upstream commit 2c223f7239f376a90d71903ec474ba887cf21d94 ]
+
+Restructure the call site for dma_contiguous_early_fixup() to
+where the reserved_mem nodes are being parsed from the DT so that
+dma_mmu_remap[] is populated before dma_contiguous_remap() is called.
+
+Fixes: 8a6e02d0c00e ("of: reserved_mem: Restructure how the reserved memory regions are processed")
+Signed-off-by: Oreoluwa Babatunde <oreoluwa.babatunde@oss.qualcomm.com>
+Tested-by: William Zhang <william.zhang@broadcom.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20250806172421.2748302-1-oreoluwa.babatunde@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/of_reserved_mem.c | 16 ++++++++++++----
+ include/linux/dma-map-ops.h  |  3 +++
+ kernel/dma/contiguous.c      |  2 --
+ 3 files changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
+index 45445a1600a96..7b5d6562fe4a0 100644
+--- a/drivers/of/of_reserved_mem.c
++++ b/drivers/of/of_reserved_mem.c
+@@ -24,6 +24,7 @@
+ #include <linux/memblock.h>
+ #include <linux/kmemleak.h>
+ #include <linux/cma.h>
++#include <linux/dma-map-ops.h>
+ #include "of_private.h"
+@@ -128,13 +129,17 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
+               base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+               size = dt_mem_next_cell(dt_root_size_cells, &prop);
+-              if (size &&
+-                  early_init_dt_reserve_memory(base, size, nomap) == 0)
++              if (size && early_init_dt_reserve_memory(base, size, nomap) == 0) {
++                      /* Architecture specific contiguous memory fixup. */
++                      if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++                          of_get_flat_dt_prop(node, "reusable", NULL))
++                              dma_contiguous_early_fixup(base, size);
+                       pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
+                               uname, &base, (unsigned long)(size / SZ_1M));
+-              else
++              } else {
+                       pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
+                              uname, &base, (unsigned long)(size / SZ_1M));
++              }
+               len -= t_len;
+       }
+@@ -417,7 +422,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
+                      uname, (unsigned long)(size / SZ_1M));
+               return -ENOMEM;
+       }
+-
++      /* Architecture specific contiguous memory fixup. */
++      if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++          of_get_flat_dt_prop(node, "reusable", NULL))
++              dma_contiguous_early_fixup(base, size);
+       /* Save region in the reserved_mem array */
+       fdt_reserved_mem_save_node(node, uname, base, size);
+       return 0;
+diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
+index b7773201414c2..b42408a24ad13 100644
+--- a/include/linux/dma-map-ops.h
++++ b/include/linux/dma-map-ops.h
+@@ -153,6 +153,9 @@ static inline void dma_free_contiguous(struct device *dev, struct page *page,
+ {
+       __free_pages(page, get_order(size));
+ }
++static inline void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
++{
++}
+ #endif /* CONFIG_DMA_CMA*/
+ #ifdef CONFIG_DMA_DECLARE_COHERENT
+diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
+index 8df0dfaaca18e..9e5d63efe7c57 100644
+--- a/kernel/dma/contiguous.c
++++ b/kernel/dma/contiguous.c
+@@ -480,8 +480,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
+               pr_err("Reserved memory: unable to setup CMA region\n");
+               return err;
+       }
+-      /* Architecture specific contiguous memory fixup. */
+-      dma_contiguous_early_fixup(rmem->base, rmem->size);
+       if (default_cma)
+               dma_contiguous_default_area = cma;
+-- 
+2.50.1
+
diff --git a/queue-6.12/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch b/queue-6.12/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
new file mode 100644 (file)
index 0000000..adf196c
--- /dev/null
@@ -0,0 +1,135 @@
+From 136619f1311981f6639f4ce9ef7d3c5800678d66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h      |  4 ++++
+ drivers/net/phy/mscc/mscc_main.c |  4 +---
+ drivers/net/phy/mscc/mscc_ptp.c  | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 58c6d47fbe046..2bfe314ef881c 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -481,6 +481,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -495,6 +496,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+       return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+       return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index 42cafa68c4009..19983b206405c 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2337,9 +2337,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *priv = phydev->priv;
+-
+-      skb_queue_purge(&priv->rx_skbs_list);
++      vsc8584_ptp_deinit(phydev);
+ }
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index 80992827a3bdd..920f35f8f84e7 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1295,7 +1295,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *vsc8531 = phydev->priv;
+       static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+       static const u8  ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+       u32 val;
+@@ -1512,17 +1511,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+       vsc85xx_ts_eth_cmp1_sig(phydev);
+-      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+-      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+-      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+-      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
+-      phydev->mii_ts = &vsc8531->mii_ts;
+-
+-      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+-      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+-                                                   &phydev->mdio.dev);
+-      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++      return 0;
+ }
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1549,6 +1538,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+       return 0;
+ }
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++      struct vsc8531_private *vsc8531 = phydev->priv;
++
++      if (vsc8531->ptp->ptp_clock) {
++              ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++              skb_queue_purge(&vsc8531->rx_skbs_list);
++      }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+       struct vsc8531_private *priv = phydev->priv;
+@@ -1609,7 +1608,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+       vsc8531->ptp->phydev = phydev;
+-      return 0;
++      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
++      phydev->mii_ts = &vsc8531->mii_ts;
++
++      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++                                                   &phydev->mdio.dev);
++      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+-- 
+2.50.1
+
diff --git a/queue-6.12/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch b/queue-6.12/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
new file mode 100644 (file)
index 0000000..b8ffdf6
--- /dev/null
@@ -0,0 +1,68 @@
+From b55c17db53adb9617ed394336f77e7e15147127c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf..7209d00a9c257 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+       }
+-      switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++      switch (inst_no_rt & ~KVM_MASK_RB) {
+       case KVM_INST_MTSRIN:
+               if (features & KVM_MAGIC_FEAT_SR) {
+                       u32 inst_rb = _inst & KVM_MASK_RB;
+                       kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+               }
+               break;
+-#endif
+       }
++#endif
+-      switch (_inst) {
+ #ifdef CONFIG_BOOKE
++      switch (_inst) {
+       case KVM_INST_WRTEEI_0:
+               kvm_patch_ins_wrteei_0(inst);
+               break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+       case KVM_INST_WRTEEI_1:
+               kvm_patch_ins_wrtee(inst, 0, 1);
+               break;
+-#endif
+       }
++#endif
+ }
+ extern u32 kvm_template_start[];
+-- 
+2.50.1
+
diff --git a/queue-6.12/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch b/queue-6.12/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
new file mode 100644 (file)
index 0000000..53ece61
--- /dev/null
@@ -0,0 +1,72 @@
+From a8034c1d5c73cced6548531d13f4c797523ded0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+  sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+  sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+  sctp_get_port net/sctp/socket.c:8523 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+  x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+  do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+  sctp_get_port net/sctp/socket.c:8515 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 38e2fbdcbeac4..9f835e674c599 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -546,7 +546,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+       addr->v6.sin6_family = AF_INET6;
+       addr->v6.sin6_port = 0;
++      addr->v6.sin6_flowinfo = 0;
+       addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++      addr->v6.sin6_scope_id = 0;
+ }
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+-- 
+2.50.1
+
index e260a49596b1229e86cfa624d1d552b3cab0ee98..7f624fbcaae3563b4f4c88c4d4ebe68a184af160 100644 (file)
@@ -16,3 +16,51 @@ asoc-codecs-tx-macro-correct-tx_macro_component_drv-.patch
 erofs-fix-atomic-context-detection-when-config_debug.patch
 acpi-ec-add-device-to-acpi_ec_no_wakeup-qurik-list.patch
 vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+drm-msm-defer-fd_install-in-submit-ioctl.patch
+of-reserved_mem-restructure-call-site-for-dma_contig.patch
+drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch
+drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch
+drm-mediatek-add-error-handling-for-old-state-crtc-i.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+hid-input-rename-hidinput_set_battery_charge_status.patch
+hid-input-report-battery-status-changes-immediately.patch
+net-macb-fix-unregister_netdev-call-order-in-macb_re.patch
+bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
+bluetooth-hci_event-mark-connection-as-closed-during.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+bluetooth-hci_sync-fix-set_local_name-race-condition.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
+drm-nouveau-remove-unused-memory-target-test.patch
+ice-don-t-leave-device-non-functional-if-tx-schedule.patch
+ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch
+ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
+dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+efi-stmm-fix-incorrect-buffer-allocation-method.patch
+drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch
+drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch
+bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch
+bnxt_en-fix-stats-context-reservation-logic.patch
+net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
+net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
+net-mlx5-nack-sync-reset-when-sfs-are-present.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+net-stmmac-xgmac-correct-supported-speed-modes.patch
+net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
+hv_netvsc-link-queues-to-napis.patch
+net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch
+net-rose-split-remove-and-free-operations-in-rose_re.patch
+net-rose-convert-use-field-to-refcount_t.patch
+net-rose-include-node-references-in-rose_neigh-refco.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch
+fbnic-move-phylink-resume-out-of-service_task-and-in.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
+net-macb-disable-clocks-once.patch
diff --git a/queue-6.16/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch b/queue-6.16/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
new file mode 100644 (file)
index 0000000..7011de7
--- /dev/null
@@ -0,0 +1,192 @@
+From f9253d2466a57b581daa54dbfd40320a109d165f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+  struct atmtcp_control {
+       struct atmtcp_hdr hdr;  /* must be first */
+  ...
+       atm_kptr_t vcc;         /* both directions */
+  ...
+  } __ATM_API_ALIGN;
+
+  typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+  1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+  2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS:  00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 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+0x19b/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
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c   | 17 ++++++++++++++---
+ include/linux/atmdev.h |  1 +
+ net/atm/common.c       | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index eeae160c898d3..fa3c76a2b49d1 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+         return NULL;
+ }
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++      struct atmtcp_hdr *hdr;
++
++      if (skb->len < sizeof(struct atmtcp_hdr))
++              return -EINVAL;
++
++      hdr = (struct atmtcp_hdr *)skb->data;
++      if (hdr->length == ATMTCP_HDR_MAGIC)
++              return -EINVAL;
++
++      return 0;
++}
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+       struct sk_buff *new_skb;
+       int result = 0;
+-      if (skb->len < sizeof(struct atmtcp_hdr))
+-              goto done;
+-
+       dev = vcc->dev_data;
+       hdr = (struct atmtcp_hdr *) skb->data;
+       if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+       .close          = atmtcp_c_close,
++      .pre_send       = atmtcp_c_pre_send,
+       .send           = atmtcp_c_send
+ };
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
++      int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index d7f7976ea13ac..881c7f259dbd4 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+       skb->dev = NULL; /* for paths shared with net_device interfaces */
+       if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+-              atm_return_tx(vcc, skb);
+-              kfree_skb(skb);
+               error = -EFAULT;
+-              goto out;
++              goto free_skb;
+       }
+       if (eff != size)
+               memset(skb->data + size, 0, eff-size);
++
++      if (vcc->dev->ops->pre_send) {
++              error = vcc->dev->ops->pre_send(vcc, skb);
++              if (error)
++                      goto free_skb;
++      }
++
+       error = vcc->dev->ops->send(vcc, skb);
+       error = error ? error : size;
+ out:
+       release_sock(sk);
+       return error;
++free_skb:
++      atm_return_tx(vcc, skb);
++      kfree_skb(skb);
++      goto out;
+ }
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+-- 
+2.50.1
+
diff --git a/queue-6.16/block-validate-qos-before-calling-__rq_qos_done_bio.patch b/queue-6.16/block-validate-qos-before-calling-__rq_qos_done_bio.patch
new file mode 100644 (file)
index 0000000..314f96d
--- /dev/null
@@ -0,0 +1,54 @@
+From 71ee7d6d8a5e362507936a311f858e1885a745db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 22:00:32 +0530
+Subject: block: validate QoS before calling __rq_qos_done_bio()
+
+From: Nilay Shroff <nilay@linux.ibm.com>
+
+[ Upstream commit e3ef9445cd9d90e43de0bd3cd55d437773dfd139 ]
+
+If a bio has BIO_QOS_xxx set, it doesn't guarantee that q->rq_qos is
+also present at-least for stacked block devices. For instance, in case
+of NVMe when multipath is enabled, the bottom device may have QoS
+enabled but top device doesn't. So always validate QoS is enabled and
+q->rq_qos is present before calling __rq_qos_done_bio().
+
+Fixes: 370ac285f23a ("block: avoid cpu_hotplug_lock depedency on freeze_lock")
+Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Closes: https://lore.kernel.org/all/3a07b752-06a4-4eee-b302-f4669feb859d@linux.ibm.com/
+Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
+Link: https://lore.kernel.org/r/20250826163128.1952394-1-nilay@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-rq-qos.h | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
+index 1fe22000a3790..b538f2c0febc2 100644
+--- a/block/blk-rq-qos.h
++++ b/block/blk-rq-qos.h
+@@ -149,12 +149,15 @@ static inline void rq_qos_done_bio(struct bio *bio)
+       q = bdev_get_queue(bio->bi_bdev);
+       /*
+-       * If a bio has BIO_QOS_xxx set, it implicitly implies that
+-       * q->rq_qos is present. So, we skip re-checking q->rq_qos
+-       * here as an extra optimization and directly call
+-       * __rq_qos_done_bio().
++       * A BIO may carry BIO_QOS_* flags even if the associated request_queue
++       * does not have rq_qos enabled. This can happen with stacked block
++       * devices — for example, NVMe multipath, where it's possible that the
++       * bottom device has QoS enabled but the top device does not. Therefore,
++       * always verify that q->rq_qos is present and QoS is enabled before
++       * calling __rq_qos_done_bio().
+        */
+-      __rq_qos_done_bio(q->rq_qos, bio);
++      if (test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags) && q->rq_qos)
++              __rq_qos_done_bio(q->rq_qos, bio);
+ }
+ static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio)
+-- 
+2.50.1
+
diff --git a/queue-6.16/bluetooth-hci_conn-make-unacked-packet-handling-more.patch b/queue-6.16/bluetooth-hci_conn-make-unacked-packet-handling-more.patch
new file mode 100644 (file)
index 0000000..89d513a
--- /dev/null
@@ -0,0 +1,106 @@
+From dd7c40fab01a5e41e822b0b35d0d9fcb075a7e10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 13:40:18 -0400
+Subject: Bluetooth: hci_conn: Make unacked packet handling more robust
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 5d7eba62e5eb68347de59b31b347b24f304cf21c ]
+
+This attempts to make unacked packet handling more robust by detecting
+if there are no connections left then restore all buffers of the
+respective pool.
+
+Fixes: 5638d9ea9c01 ("Bluetooth: hci_conn: Fix not restoring ISO buffer count on disconnect")
+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 | 58 ++++++++++++++++++++++++++++------------
+ 1 file changed, 41 insertions(+), 17 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 6a064a6b0e431..ad5574e9a93ee 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -149,8 +149,6 @@ static void hci_conn_cleanup(struct hci_conn *conn)
+       hci_chan_list_flush(conn);
+-      hci_conn_hash_del(hdev, conn);
+-
+       if (HCI_CONN_HANDLE_UNSET(conn->handle))
+               ida_free(&hdev->unset_handle_ida, conn->handle);
+@@ -1142,28 +1140,54 @@ void hci_conn_del(struct hci_conn *conn)
+       disable_delayed_work_sync(&conn->auto_accept_work);
+       disable_delayed_work_sync(&conn->idle_work);
+-      if (conn->type == ACL_LINK) {
+-              /* Unacked frames */
+-              hdev->acl_cnt += conn->sent;
+-      } else if (conn->type == LE_LINK) {
+-              cancel_delayed_work(&conn->le_conn_timeout);
++      /* Remove the connection from the list so unacked logic can detect when
++       * a certain pool is not being utilized.
++       */
++      hci_conn_hash_del(hdev, conn);
+-              if (hdev->le_pkts)
+-                      hdev->le_cnt += conn->sent;
++      /* Handle unacked frames:
++       *
++       * - In case there are no connection, or if restoring the buffers
++       *   considered in transist would overflow, restore all buffers to the
++       *   pool.
++       * - Otherwise restore just the buffers considered in transit for the
++       *   hci_conn
++       */
++      switch (conn->type) {
++      case ACL_LINK:
++              if (!hci_conn_num(hdev, ACL_LINK) ||
++                  hdev->acl_cnt + conn->sent > hdev->acl_pkts)
++                      hdev->acl_cnt = hdev->acl_pkts;
+               else
+                       hdev->acl_cnt += conn->sent;
+-      } else {
+-              /* Unacked ISO frames */
+-              if (conn->type == CIS_LINK ||
+-                  conn->type == BIS_LINK ||
+-                  conn->type == PA_LINK) {
+-                      if (hdev->iso_pkts)
+-                              hdev->iso_cnt += conn->sent;
+-                      else if (hdev->le_pkts)
++              break;
++      case LE_LINK:
++              cancel_delayed_work(&conn->le_conn_timeout);
++
++              if (hdev->le_pkts) {
++                      if (!hci_conn_num(hdev, LE_LINK) ||
++                          hdev->le_cnt + conn->sent > hdev->le_pkts)
++                              hdev->le_cnt = hdev->le_pkts;
++                      else
+                               hdev->le_cnt += conn->sent;
++              } else {
++                      if ((!hci_conn_num(hdev, LE_LINK) &&
++                           !hci_conn_num(hdev, ACL_LINK)) ||
++                          hdev->acl_cnt + conn->sent > hdev->acl_pkts)
++                              hdev->acl_cnt = hdev->acl_pkts;
+                       else
+                               hdev->acl_cnt += conn->sent;
+               }
++              break;
++      case CIS_LINK:
++      case BIS_LINK:
++      case PA_LINK:
++              if (!hci_iso_count(hdev) ||
++                  hdev->iso_cnt + conn->sent > hdev->iso_pkts)
++                      hdev->iso_cnt = hdev->iso_pkts;
++              else
++                      hdev->iso_cnt += conn->sent;
++              break;
+       }
+       skb_queue_purge(&conn->data_q);
+-- 
+2.50.1
+
diff --git a/queue-6.16/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch b/queue-6.16/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
new file mode 100644 (file)
index 0000000..d3be6fe
--- /dev/null
@@ -0,0 +1,47 @@
+From d392fd1d430b4afc49bb5cca6b24d1c56ea4f18e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index cadb53e21c0ef..02b2ef9a75746 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4404,7 +4404,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+               if (!conn)
+                       continue;
+-              conn->sent -= count;
++              /* Check if there is really enough packets outstanding before
++               * attempting to decrease the sent counter otherwise it could
++               * underflow..
++               */
++              if (conn->sent >= count) {
++                      conn->sent -= count;
++              } else {
++                      bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++                                  conn, conn->sent, count);
++                      conn->sent = 0;
++              }
+               for (i = 0; i < count; ++i)
+                       hci_conn_tx_dequeue(conn);
+-- 
+2.50.1
+
diff --git a/queue-6.16/bluetooth-hci_event-disconnect-device-when-big-sync-.patch b/queue-6.16/bluetooth-hci_event-disconnect-device-when-big-sync-.patch
new file mode 100644 (file)
index 0000000..6991021
--- /dev/null
@@ -0,0 +1,65 @@
+From 4c447d1ff9b38451ca7fb1ec5f1f08e3364c0bb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 10:16:17 +0800
+Subject: Bluetooth: hci_event: Disconnect device when BIG sync is lost
+
+From: Yang Li <yang.li@amlogic.com>
+
+[ Upstream commit 55b9551fcdf6a2fe7f3422918d5697b56794da72 ]
+
+When a BIG sync is lost, the device should be set to "disconnected".
+This ensures symmetry with the ISO path setup, where the device is
+marked as "connected" once the path is established. Without this
+change, the device state remains inconsistent and may lead to a
+memory leak.
+
+Fixes: b2a5f2e1c127 ("Bluetooth: hci_event: Add support for handling LE BIG Sync Lost event")
+Signed-off-by: Yang Li <yang.li@amlogic.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 5 +++++
+ net/bluetooth/mgmt.c      | 4 +++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 02b2ef9a75746..0ffdbe249f5d3 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -7019,6 +7019,7 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
+ {
+       struct hci_evt_le_big_sync_lost *ev = data;
+       struct hci_conn *bis, *conn;
++      bool mgmt_conn;
+       bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle);
+@@ -7037,6 +7038,10 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
+       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);
++
+               clear_bit(HCI_CONN_BIG_SYNC, &bis->flags);
+               hci_disconn_cfm(bis, ev->reason);
+               hci_conn_del(bis);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 3166f5fb876b1..90e37ff2c85db 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9705,7 +9705,9 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
+       if (!mgmt_connected)
+               return;
+-      if (link_type != ACL_LINK && link_type != LE_LINK)
++      if (link_type != ACL_LINK &&
++          link_type != LE_LINK  &&
++          link_type != BIS_LINK)
+               return;
+       bacpy(&ev.addr.bdaddr, bdaddr);
+-- 
+2.50.1
+
diff --git a/queue-6.16/bluetooth-hci_event-mark-connection-as-closed-during.patch b/queue-6.16/bluetooth-hci_event-mark-connection-as-closed-during.patch
new file mode 100644 (file)
index 0000000..2dd89a1
--- /dev/null
@@ -0,0 +1,80 @@
+From 674fe564ad11835bd72555e6e077103673811942 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:27 +0200
+Subject: Bluetooth: hci_event: Mark connection as closed during suspend
+ disconnect
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit b7fafbc499b5ee164018eb0eefe9027f5a6aaad2 ]
+
+When suspending, the disconnect command for an active Bluetooth
+connection could be issued, but the corresponding
+`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
+completes the suspend process. This can lead to an inconsistent state.
+
+On resume, the controller may auto-accept reconnections from the same
+device (due to suspend event filters), but these new connections are
+rejected by the kernel which still has connection objects from before
+suspend. Resulting in errors like:
+```
+kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
+kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
+connection
+```
+
+This is a btmon snippet that shows the issue:
+```
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+        Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+        Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+      Disconnect (0x01|0x0006) ncmd 2
+        Status: Success (0x00)
+[...]
+// Host suspends with the event filter set for the device
+// On resume, the device tries to reconnect with a new handle
+
+> HCI Event: Connect Complete (0x03) plen 11
+        Status: Success (0x00)
+        Handle: 2
+        Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+
+// Kernel ignores this event because there is an existing connection
+with
+// handle 1
+```
+
+By explicitly setting the connection state to BT_CLOSED we can ensure a
+consistent state, even if we don't receive the disconnect complete event
+in time.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 1902982538da7..cadb53e21c0ef 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2718,6 +2718,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+               goto done;
+       }
++      /* During suspend, mark connection as closed immediately
++       * since we might not receive HCI_EV_DISCONN_COMPLETE
++       */
++      if (hdev->suspended)
++              conn->state = BT_CLOSED;
++
+       mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+       if (conn->type == ACL_LINK) {
+-- 
+2.50.1
+
diff --git a/queue-6.16/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch b/queue-6.16/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
new file mode 100644 (file)
index 0000000..d05617d
--- /dev/null
@@ -0,0 +1,84 @@
+From 57880a80e476d8e932ceadfa7d8a452562019ee0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:26 +0200
+Subject: Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit 2f050a5392b7a0928bf836d9891df4851463512c ]
+
+When the host sends an HCI_OP_DISCONNECT command, the controller may
+respond with the status HCI_ERROR_UNKNOWN_CONN_ID (0x02). E.g. this can
+happen on resume from suspend, if the link was terminated by the remote
+device before the event mask was correctly set.
+
+This is a btmon snippet that shows the issue:
+```
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+      L2CAP: Disconnection Request (0x06) ident 5 len 4
+        Destination CID: 65
+        Source CID: 72
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+      L2CAP: Disconnection Response (0x07) ident 5 len 4
+        Destination CID: 65
+        Source CID: 72
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+      L2CAP: Disconnection Request (0x06) ident 6 len 4
+        Destination CID: 64
+        Source CID: 71
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+      L2CAP: Disconnection Response (0x07) ident 6 len 4
+        Destination CID: 64
+        Source CID: 71
+< HCI Command: Set Event Mask (0x03|0x0001) plen 8
+        Mask: 0x3dbff807fffbffff
+          Inquiry Complete
+          Inquiry Result
+          Connection Complete
+          Connection Request
+          Disconnection Complete
+          Authentication Complete
+[...]
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+        Handle: 3 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+        Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+      Disconnect (0x01|0x0006) ncmd 1
+        Status: Unknown Connection Identifier (0x02)
+```
+
+Currently, the hci_cs_disconnect function treats any non-zero status
+as a command failure. This can be misleading because the connection is
+indeed being terminated and the controller is confirming that is has no
+knowledge of that connection handle. Meaning that the initial request of
+disconnecting a device should be treated as done.
+
+With this change we allow the function to proceed, following the success
+path, which correctly calls `mgmt_device_disconnected` and ensures a
+consistent state.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 5ef54853bc5eb..1902982538da7 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2703,7 +2703,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+       if (!conn)
+               goto unlock;
+-      if (status) {
++      if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+               mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+                                      conn->dst_type, status);
+-- 
+2.50.1
+
diff --git a/queue-6.16/bluetooth-hci_sync-fix-set_local_name-race-condition.patch b/queue-6.16/bluetooth-hci_sync-fix-set_local_name-race-condition.patch
new file mode 100644 (file)
index 0000000..2d93da1
--- /dev/null
@@ -0,0 +1,90 @@
+From 7dbac4e2175ef7cdeab9b544e8fab30b66f50759 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 12:20:55 +0300
+Subject: Bluetooth: hci_sync: fix set_local_name race condition
+
+From: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+
+[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]
+
+Function set_name_sync() uses hdev->dev_name field to send
+HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
+is called after mgmt cmd was queued, so it is possible that function
+set_name_sync() will read old name value.
+
+This change adds name as a parameter for function hci_update_name_sync()
+to avoid race condition.
+
+Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
+Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+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>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_sync.c         | 6 +++---
+ net/bluetooth/mgmt.c             | 5 ++++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 5224f57f6af2c..e352a4e0ef8d7 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -93,7 +93,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 115dc1cd99ce4..749bba1512eb1 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3481,13 +3481,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+       return hci_write_scan_enable_sync(hdev, scan);
+ }
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+       struct hci_cp_write_local_name cp;
+       memset(&cp, 0, sizeof(cp));
+-      memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++      memcpy(cp.name, name, sizeof(cp.name));
+       return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+                                           sizeof(cp), &cp,
+@@ -3540,7 +3540,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+                       hci_write_fast_connectable_sync(hdev, false);
+               hci_update_scan_sync(hdev);
+               hci_update_class_sync(hdev);
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, hdev->dev_name);
+               hci_update_eir_sync(hdev);
+       }
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 90e37ff2c85db..50634ef5c8b70 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3892,8 +3892,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++      struct mgmt_pending_cmd *cmd = data;
++      struct mgmt_cp_set_local_name *cp = cmd->param;
++
+       if (lmp_bredr_capable(hdev)) {
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, cp->name);
+               hci_update_eir_sync(hdev);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.16/bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch b/queue-6.16/bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch
new file mode 100644 (file)
index 0000000..e4c1d68
--- /dev/null
@@ -0,0 +1,64 @@
+From bd11dca44cf30511d4c2417c82320e9ef5ed8492 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:26 -0700
+Subject: bnxt_en: Adjust TX rings if reservation is less than requested
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 1ee581c24dfdcbc6de25aac95a48c1f08e9a542c ]
+
+Before we accept an ethtool request to increase a resource (such as
+rings), we call the FW to check that the requested resource is likely
+available first before we commit.  But it is still possible that
+the actual reservation or allocation can fail.  The existing code
+is missing the logic to adjust the TX rings in case the reserved
+TX rings are less than requested.  Add a warning message (a similar
+message for RX rings already exists) and add the logic to adjust
+the TX rings.  Without this fix, the number of TX rings reported
+to the stack can exceed the actual TX rings and ethtool -l will
+report more than the actual TX rings.
+
+Fixes: 674f50a5b026 ("bnxt_en: Implement new method to reserve rings.")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-3-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index a4f4d90caf5e9..5360c42ad409c 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -8017,6 +8017,11 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+               hwr.rx = rx_rings << 1;
+       tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx);
+       hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings;
++      if (hwr.tx != bp->tx_nr_rings) {
++              netdev_warn(bp->dev,
++                          "Able to reserve only %d out of %d requested TX rings\n",
++                          hwr.tx, bp->tx_nr_rings);
++      }
+       bp->tx_nr_rings = hwr.tx;
+       /* If we cannot reserve all the RX rings, reset the RSS map only
+@@ -12872,6 +12877,13 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+       if (rc)
+               return rc;
++      /* Make adjustments if reserved TX rings are less than requested */
++      bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
++      if (bp->tx_nr_rings_xdp) {
++              bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
++              bp->tx_nr_rings += bp->tx_nr_rings_xdp;
++      }
+       rc = bnxt_alloc_mem(bp, irq_re_init);
+       if (rc) {
+               netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
+-- 
+2.50.1
+
diff --git a/queue-6.16/bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch b/queue-6.16/bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch
new file mode 100644 (file)
index 0000000..2ee699a
--- /dev/null
@@ -0,0 +1,106 @@
+From 1028d4f3c65673898e39224f25372b8ca0f1eb55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:25 -0700
+Subject: bnxt_en: Fix memory corruption when FW resources change during ifdown
+
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+
+[ Upstream commit 2747328ba2714f1a7454208dbbc1dc0631990b4a ]
+
+bnxt_set_dflt_rings() assumes that it is always called before any TC has
+been created.  So it doesn't take bp->num_tc into account and assumes
+that it is always 0 or 1.
+
+In the FW resource or capability change scenario, the FW will return
+flags in bnxt_hwrm_if_change() that will cause the driver to
+reinitialize and call bnxt_cancel_reservations().  This will lead to
+bnxt_init_dflt_ring_mode() calling bnxt_set_dflt_rings() and bp->num_tc
+may be greater than 1.  This will cause bp->tx_ring[] to be sized too
+small and cause memory corruption in bnxt_alloc_cp_rings().
+
+Fix it by properly scaling the TX rings by bp->num_tc in the code
+paths mentioned above.  Add 2 helper functions to determine
+bp->tx_nr_rings and bp->tx_nr_rings_per_tc.
+
+Fixes: ec5d31e3c15d ("bnxt_en: Handle firmware reset status during IF_UP.")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-2-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index ec8752c298e69..a4f4d90caf5e9 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -12844,6 +12844,17 @@ static int bnxt_set_xps_mapping(struct bnxt *bp)
+       return rc;
+ }
++static int bnxt_tx_nr_rings(struct bnxt *bp)
++{
++      return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc :
++                          bp->tx_nr_rings_per_tc;
++}
++
++static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
++{
++      return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
++}
++
+ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+ {
+       int rc = 0;
+@@ -16338,7 +16349,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
+       bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings);
+       bp->rx_nr_rings = bp->cp_nr_rings;
+       bp->tx_nr_rings_per_tc = bp->cp_nr_rings;
+-      bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++      bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+ }
+ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+@@ -16370,7 +16381,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+               bnxt_trim_dflt_sh_rings(bp);
+       else
+               bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
+-      bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++      bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+       avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
+       if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
+@@ -16383,7 +16394,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+       rc = __bnxt_reserve_rings(bp);
+       if (rc && rc != -ENODEV)
+               netdev_warn(bp->dev, "Unable to reserve tx rings\n");
+-      bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+       if (sh)
+               bnxt_trim_dflt_sh_rings(bp);
+@@ -16392,7 +16403,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+               rc = __bnxt_reserve_rings(bp);
+               if (rc && rc != -ENODEV)
+                       netdev_warn(bp->dev, "2nd rings reservation failed.\n");
+-              bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++              bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+       }
+       if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
+               bp->rx_nr_rings++;
+@@ -16426,7 +16437,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
+       if (rc)
+               goto init_dflt_ring_err;
+-      bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++      bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+       bnxt_set_dflt_rfs(bp);
+-- 
+2.50.1
+
diff --git a/queue-6.16/bnxt_en-fix-stats-context-reservation-logic.patch b/queue-6.16/bnxt_en-fix-stats-context-reservation-logic.patch
new file mode 100644 (file)
index 0000000..53e9b7d
--- /dev/null
@@ -0,0 +1,44 @@
+From daf38dbb8f1bfb0d57daa254b01b7f9912f79ac5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:27 -0700
+Subject: bnxt_en: Fix stats context reservation logic
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit b4fc8faacfea2538184a1dbd616ae9447a361f3d ]
+
+The HW resource reservation logic allows the L2 driver to use the
+RoCE resources if the RoCE driver is not registered.  When calculating
+the stats contexts available for L2, we should not blindly subtract
+the stats contexts reserved for RoCE unless the RoCE driver is
+registered.  This bug may cause the L2 rings to be less than the
+number requested when we are close to running out of stats contexts.
+
+Fixes: 2e4592dc9bee ("bnxt_en: Change MSIX/NQs allocation policy")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-4-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 5360c42ad409c..cb76ab78904fc 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -8009,7 +8009,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+       }
+       rx_rings = min_t(int, rx_rings, hwr.grp);
+       hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings);
+-      if (hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
++      if (bnxt_ulp_registered(bp->edev) &&
++          hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
+               hwr.stat -= bnxt_get_ulp_stat_ctxs(bp);
+       hwr.cp = min_t(int, hwr.cp, hwr.stat);
+       rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh);
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-mediatek-add-error-handling-for-old-state-crtc-i.patch b/queue-6.16/drm-mediatek-add-error-handling-for-old-state-crtc-i.patch
new file mode 100644 (file)
index 0000000..30356cc
--- /dev/null
@@ -0,0 +1,66 @@
+From 643e0d64586d376b5871131c616949c76383bf5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jul 2025 10:48:50 +0800
+Subject: drm/mediatek: Add error handling for old state CRTC in atomic_disable
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 0c6b24d70da21201ed009a2aca740d2dfddc7ab5 ]
+
+Introduce error handling to address an issue where, after a hotplug
+event, the cursor continues to update. This situation can lead to a
+kernel panic due to accessing the NULL `old_state->crtc`.
+
+E,g.
+Unable to handle kernel NULL pointer dereference at virtual address
+Call trace:
+ mtk_crtc_plane_disable+0x24/0x140
+ mtk_plane_atomic_update+0x8c/0xa8
+ drm_atomic_helper_commit_planes+0x114/0x2c8
+ drm_atomic_helper_commit_tail_rpm+0x4c/0x158
+ commit_tail+0xa0/0x168
+ drm_atomic_helper_commit+0x110/0x120
+ drm_atomic_commit+0x8c/0xe0
+ drm_atomic_helper_update_plane+0xd4/0x128
+ __setplane_atomic+0xcc/0x110
+ drm_mode_cursor_common+0x250/0x440
+ drm_mode_cursor_ioctl+0x44/0x70
+ drm_ioctl+0x264/0x5d8
+ __arm64_sys_ioctl+0xd8/0x510
+ invoke_syscall+0x6c/0xe0
+ do_el0_svc+0x68/0xe8
+ el0_svc+0x34/0x60
+ el0t_64_sync_handler+0x1c/0xf8
+ el0t_64_sync+0x180/0x188
+
+Adding NULL pointer checks to ensure stability by preventing operations
+on an invalid CRTC state.
+
+Fixes: d208261e9f7c ("drm/mediatek: Add wait_event_timeout when disabling plane")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20250728025036.24953-1-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_plane.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
+index cbc4f37da8ba8..02349bd440017 100644
+--- a/drivers/gpu/drm/mediatek/mtk_plane.c
++++ b/drivers/gpu/drm/mediatek/mtk_plane.c
+@@ -292,7 +292,8 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
+       wmb(); /* Make sure the above parameter is set before update */
+       mtk_plane_state->pending.dirty = true;
+-      mtk_crtc_plane_disable(old_state->crtc, plane);
++      if (old_state && old_state->crtc)
++              mtk_crtc_plane_disable(old_state->crtc, plane);
+ }
+ static void mtk_plane_atomic_update(struct drm_plane *plane,
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-mediatek-mtk_hdmi-fix-inverted-parameters-in-som.patch b/queue-6.16/drm-mediatek-mtk_hdmi-fix-inverted-parameters-in-som.patch
new file mode 100644 (file)
index 0000000..6bedadd
--- /dev/null
@@ -0,0 +1,54 @@
+From 721777d3e398883c79ada0e27257f6787719fc62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Aug 2025 16:17:52 +0200
+Subject: drm/mediatek: mtk_hdmi: Fix inverted parameters in some
+ regmap_update_bits calls
+
+From: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+
+[ Upstream commit c34414883f773412964404d77cd2fea04c6f7d60 ]
+
+In mtk_hdmi driver, a recent change replaced custom register access
+function calls by regmap ones, but two replacements by regmap_update_bits
+were done incorrectly, because original offset and mask parameters were
+inverted, so fix them.
+
+Fixes: d6e25b3590a0 ("drm/mediatek: hdmi: Use regmap instead of iomem for main registers")
+Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20250818-mt8173-fix-hdmi-issue-v1-1-55aff9b0295d@collabora.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_hdmi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+index 8803cd4a8bc9b..4404e1b527b52 100644
+--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+@@ -182,8 +182,8 @@ static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
+ static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
+ {
+-      regmap_update_bits(hdmi->regs, VIDEO_SOURCE_SEL,
+-                         VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH);
++      regmap_update_bits(hdmi->regs, VIDEO_CFG_4,
++                         VIDEO_SOURCE_SEL, black ? GEN_RGB : NORMAL_PATH);
+ }
+ static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable)
+@@ -310,8 +310,8 @@ static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer,
+ static void mtk_hdmi_hw_send_aud_packet(struct mtk_hdmi *hdmi, bool enable)
+ {
+-      regmap_update_bits(hdmi->regs, AUDIO_PACKET_OFF,
+-                         GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF);
++      regmap_update_bits(hdmi->regs, GRL_SHIFT_R2,
++                         AUDIO_PACKET_OFF, enable ? 0 : AUDIO_PACKET_OFF);
+ }
+ static void mtk_hdmi_hw_config_sys(struct mtk_hdmi *hdmi)
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-msm-defer-fd_install-in-submit-ioctl.patch b/queue-6.16/drm-msm-defer-fd_install-in-submit-ioctl.patch
new file mode 100644 (file)
index 0000000..1e2e60b
--- /dev/null
@@ -0,0 +1,59 @@
+From cedc6de13668f5088bfc92adb4ff52aa728211bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jul 2025 13:28:22 -0700
+Subject: drm/msm: Defer fd_install in SUBMIT ioctl
+
+From: Rob Clark <robin.clark@oss.qualcomm.com>
+
+[ Upstream commit f22853435bbd1e9836d0dce7fd99c040b94c2bf1 ]
+
+Avoid fd_install() until there are no more potential error paths, to
+avoid put_unused_fd() after the fd is made visible to userspace.
+
+Fixes: 68dc6c2d5eec ("drm/msm: Fix submit error-path leaks")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665363/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index d4f71bb54e84c..081d59979e31d 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -869,12 +869,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+       if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+               sync_file = sync_file_create(submit->user_fence);
+-              if (!sync_file) {
++              if (!sync_file)
+                       ret = -ENOMEM;
+-              } else {
+-                      fd_install(out_fence_fd, sync_file->file);
+-                      args->fence_fd = out_fence_fd;
+-              }
+       }
+       if (ret)
+@@ -902,10 +898,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ out_unlock:
+       mutex_unlock(&queue->lock);
+ out_post_unlock:
+-      if (ret && (out_fence_fd >= 0)) {
+-              put_unused_fd(out_fence_fd);
++      if (ret) {
++              if (out_fence_fd >= 0)
++                      put_unused_fd(out_fence_fd);
+               if (sync_file)
+                       fput(sync_file->file);
++      } else if (sync_file) {
++              fd_install(out_fence_fd, sync_file->file);
++              args->fence_fd = out_fence_fd;
+       }
+       if (!IS_ERR_OR_NULL(submit)) {
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-msm-dpu-add-a-null-ptr-check-for-dpu_encoder_nee.patch b/queue-6.16/drm-msm-dpu-add-a-null-ptr-check-for-dpu_encoder_nee.patch
new file mode 100644 (file)
index 0000000..b4ca14d
--- /dev/null
@@ -0,0 +1,42 @@
+From 1085747a2621ee739c2b1840e757e3d381da2601 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jul 2025 16:17:40 -0500
+Subject: drm/msm/dpu: Add a null ptr check for dpu_encoder_needs_modeset
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit abebfed208515726760d79cf4f9f1a76b9a10a84 ]
+
+The drm_atomic_get_new_connector_state() can return NULL if the
+connector is not part of the atomic state. Add a check to prevent
+a NULL pointer dereference.
+
+This follows the same pattern used in dpu_encoder_update_topology()
+within the same file, which checks for NULL before using conn_state.
+
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Fixes: 1ce69c265a53 ("drm/msm/dpu: move resource allocation to CRTC")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665188/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index c0ed110a7d30f..4bddb9504796b 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -729,6 +729,8 @@ bool dpu_encoder_needs_modeset(struct drm_encoder *drm_enc, struct drm_atomic_st
+               return false;
+       conn_state = drm_atomic_get_new_connector_state(state, connector);
++      if (!conn_state)
++              return false;
+       /**
+        * These checks are duplicated from dpu_encoder_update_topology() since
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-msm-dpu-correct-dpu_plane_virtual_atomic_check.patch b/queue-6.16/drm-msm-dpu-correct-dpu_plane_virtual_atomic_check.patch
new file mode 100644 (file)
index 0000000..089c1e4
--- /dev/null
@@ -0,0 +1,41 @@
+From b6dd18ad11593feb8e60fdc32a51ede696151b3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 20:28:18 +0300
+Subject: drm/msm/dpu: correct dpu_plane_virtual_atomic_check()
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 1a76b255eceb9c570c6228f6393e1d63d97a22ba ]
+
+Fix c&p error in dpu_plane_virtual_atomic_check(), compare CRTC width
+too, in addition to CRTC height.
+
+Fixes: 8c62a31607f6 ("drm/msm/dpu: allow using two SSPP blocks for a single plane")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202507150432.U0cALR6W-lkp@intel.com/
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/664170/
+Link: https://lore.kernel.org/r/20250715-msm-fix-virt-atomic-check-v1-1-9bab02c9f952@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+index 421138bc3cb77..28d42eade5ccb 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+@@ -1169,7 +1169,7 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
+       if (!old_plane_state || !old_plane_state->fb ||
+           old_plane_state->src_w != plane_state->src_w ||
+           old_plane_state->src_h != plane_state->src_h ||
+-          old_plane_state->src_w != plane_state->src_w ||
++          old_plane_state->crtc_w != plane_state->crtc_w ||
+           old_plane_state->crtc_h != plane_state->crtc_h ||
+           msm_framebuffer_format(old_plane_state->fb) !=
+           msm_framebuffer_format(plane_state->fb))
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch b/queue-6.16/drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch
new file mode 100644 (file)
index 0000000..d07348c
--- /dev/null
@@ -0,0 +1,118 @@
+From 2cdaed6725c591a52bd5dede850f6d78049c647e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 18:50:37 +0300
+Subject: drm/msm/kms: move snapshot init earlier in KMS init
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 553666f839b86545300773954df7426a45c169c4 ]
+
+Various parts of the display driver can be triggering the display
+snapshot (including the IOMMU fault handlers). Move the call to
+msm_disp_snapshot_init() before KMS initialization, otherwise it is
+possible to ocassionally trigger the kernel fault during init:
+
+  __lock_acquire+0x44/0x2798 (P)
+  lock_acquire+0x114/0x25c
+  _raw_spin_lock_irqsave+0x6c/0x90
+  kthread_queue_work+0x2c/0xac
+  msm_disp_snapshot_state+0x2c/0x4c
+  msm_kms_fault_handler+0x2c/0x74
+  msm_disp_fault_handler+0x30/0x48
+  report_iommu_fault+0x54/0x128
+  arm_smmu_context_fault+0x74/0x184
+  __handle_irq_event_percpu+0xa4/0x24c
+  handle_irq_event_percpu+0x20/0x5c
+  handle_irq_event+0x48/0x84
+  handle_fasteoi_irq+0xcc/0x170
+  generic_handle_domain_irq+0x48/0x70
+  gic_handle_irq+0x54/0x11c
+  call_on_irq_stack+0x3c/0x50
+  do_interrupt_handler+0x54/0x78
+  el1_interrupt+0x3c/0x5c
+  el1h_64_irq_handler+0x20/0x30
+  el1h_64_irq+0x6c/0x70
+  _raw_spin_unlock_irqrestore+0x44/0x68 (P)
+  klist_next+0xc4/0x124
+  bus_for_each_drv+0x9c/0xe8
+  __device_attach+0xfc/0x190
+  device_initial_probe+0x1c/0x2c
+  bus_probe_device+0x44/0xa0
+  device_add+0x204/0x3e4
+  platform_device_add+0x170/0x244
+  platform_device_register_full+0x130/0x138
+  drm_connector_hdmi_audio_init+0xc0/0x108
+  drm_bridge_connector_init+0x318/0x394
+  msm_dsi_manager_connector_init+0xac/0xdc
+  msm_dsi_modeset_init+0x78/0xc0
+  _dpu_kms_drm_obj_init+0x198/0x75c
+  dpu_kms_hw_init+0x2f8/0x494
+  msm_drm_kms_init+0xb0/0x230
+  msm_drm_init+0x218/0x250
+  msm_drm_bind+0x3c/0x4c
+  try_to_bring_up_aggregate_device+0x208/0x2a4
+  __component_add+0xa8/0x188
+  component_add+0x1c/0x2c
+  dsi_dev_attach+0x24/0x34
+  dsi_host_attach+0x68/0xa0
+  devm_mipi_dsi_attach+0x40/0xcc
+  lt9611_attach_dsi+0x94/0x118
+  lt9611_probe+0x368/0x3c8
+  i2c_device_probe+0x2d0/0x3d8
+  really_probe+0x130/0x354
+  __driver_probe_device+0xac/0x110
+  driver_probe_device+0x44/0x110
+  __device_attach_driver+0xb0/0x138
+  bus_for_each_drv+0x90/0xe8
+  __device_attach+0xfc/0x190
+  device_initial_probe+0x1c/0x2c
+  bus_probe_device+0x44/0xa0
+  deferred_probe_work_func+0xac/0x110
+  process_one_work+0x20c/0x51c
+  process_scheduled_works+0x58/0x88
+  worker_thread+0x1ec/0x304
+  kthread+0x194/0x1d4
+  ret_from_fork+0x10/0x20
+
+Reported-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Fixes: 98659487b845 ("drm/msm: add support to take dpu snapshot")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/664149/
+Link: https://lore.kernel.org/r/20250715-msm-move-snapshot-init-v1-1-f39c396192ab@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_kms.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c
+index 35d5397e73b4c..f2c00716f9d1a 100644
+--- a/drivers/gpu/drm/msm/msm_kms.c
++++ b/drivers/gpu/drm/msm/msm_kms.c
+@@ -258,6 +258,12 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+       if (ret)
+               return ret;
++      ret = msm_disp_snapshot_init(ddev);
++      if (ret) {
++              DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
++              return ret;
++      }
++
+       ret = priv->kms_init(ddev);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "failed to load kms\n");
+@@ -310,10 +316,6 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+               goto err_msm_uninit;
+       }
+-      ret = msm_disp_snapshot_init(ddev);
+-      if (ret)
+-              DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
+-
+       drm_mode_config_reset(ddev);
+       return 0;
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch b/queue-6.16/drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch
new file mode 100644 (file)
index 0000000..35d7888
--- /dev/null
@@ -0,0 +1,89 @@
+From 79e96c1c52a349e29f628a54916a9dd796141faa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jul 2025 18:09:38 +0530
+Subject: drm/msm: update the high bitfield of certain DSI registers
+
+From: Ayushi Makhija <quic_amakhija@quicinc.com>
+
+[ Upstream commit 494045c561e68945b1183ff416b8db8e37a122d6 ]
+
+Currently, the high bitfield of certain DSI registers
+do not align with the configuration of the SWI registers
+description. This can lead to wrong programming these DSI
+registers, for example for 4k resloution where H_TOTAL is
+taking 13 bits but software is programming only 12 bits
+because of the incorrect bitmask for H_TOTAL bitfeild,
+this is causing DSI FIFO errors. To resolve this issue,
+increase the high bitfield of the DSI registers from 12 bits
+to 16 bits in dsi.xml to match the SWI register configuration.
+
+Signed-off-by: Ayushi Makhija <quic_amakhija@quicinc.com>
+Fixes: 4f52f5e63b62 ("drm/msm: import XML display registers database")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/666229/
+Link: https://lore.kernel.org/r/20250730123938.1038640-1-quic_amakhija@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/registers/display/dsi.xml | 28 +++++++++----------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/registers/display/dsi.xml b/drivers/gpu/drm/msm/registers/display/dsi.xml
+index 501ffc585a9f6..c7a7b633d747b 100644
+--- a/drivers/gpu/drm/msm/registers/display/dsi.xml
++++ b/drivers/gpu/drm/msm/registers/display/dsi.xml
+@@ -159,28 +159,28 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+               <bitfield name="RGB_SWAP" low="12" high="14" type="dsi_rgb_swap"/>
+       </reg32>
+       <reg32 offset="0x00020" name="ACTIVE_H">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00024" name="ACTIVE_V">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00028" name="TOTAL">
+-              <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+-              <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++              <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++              <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x0002c" name="ACTIVE_HSYNC">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00030" name="ACTIVE_VSYNC_HPOS">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00034" name="ACTIVE_VSYNC_VPOS">
+-              <bitfield name="START" low="0" high="11" type="uint"/>
+-              <bitfield name="END" low="16" high="27" type="uint"/>
++              <bitfield name="START" low="0" high="15" type="uint"/>
++              <bitfield name="END" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00038" name="CMD_DMA_CTRL">
+@@ -209,8 +209,8 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+               <bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x00058" name="CMD_MDP_STREAM0_TOTAL">
+-              <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+-              <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++              <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++              <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+       </reg32>
+       <reg32 offset="0x0005c" name="CMD_MDP_STREAM1_CTRL">
+               <bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch b/queue-6.16/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
new file mode 100644 (file)
index 0000000..d7e9396
--- /dev/null
@@ -0,0 +1,39 @@
+From cf92907fed69bcb375b4941ffd3285966c2f3939 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:03 -0500
+Subject: drm/nouveau: remove unused increment in gm200_flcn_pio_imem_wr
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit f529b8915543fb9ceb732cec5571f7fe12bc9530 ]
+
+The 'tag' parameter is passed by value and is not actually used after
+being incremented, so remove the increment.  It's the function that calls
+gm200_flcn_pio_imem_wr that is supposed to (and does) increment 'tag'.
+
+Fixes: 0e44c2170876 ("drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)")
+Reviewed-by: Philipp Stanner <phasta@kernel.org>
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-2-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index b7da3ab44c277..6a004c6e67425 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -103,7 +103,7 @@ gm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 i
+ static void
+ gm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
+ {
+-      nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag++);
++      nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag);
+       while (len >= 4) {
+               nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
+               img += 4;
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-nouveau-remove-unused-memory-target-test.patch b/queue-6.16/drm-nouveau-remove-unused-memory-target-test.patch
new file mode 100644 (file)
index 0000000..e92c79a
--- /dev/null
@@ -0,0 +1,57 @@
+From 496f2e1354c28ecc1b2df9953eac47b7f76ee4be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:04 -0500
+Subject: drm/nouveau: remove unused memory target test
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit 64c722b5e7f6b909b0e448e580f64628a0d76208 ]
+
+The memory target check is a hold-over from a refactor.  It's harmless
+but distracting, so just remove it.
+
+Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs")
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-3-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index 6a004c6e67425..7c43397c19e61 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -249,9 +249,11 @@ int
+ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ {
+       struct nvkm_falcon *falcon = fw->falcon;
+-      int target, ret;
++      int ret;
+       if (fw->inst) {
++              int target;
++
+               nvkm_falcon_mask(falcon, 0x048, 0x00000001, 0x00000001);
+               switch (nvkm_memory_target(fw->inst)) {
+@@ -285,15 +287,6 @@ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+       }
+       if (fw->boot) {
+-              switch (nvkm_memory_target(&fw->fw.mem.memory)) {
+-              case NVKM_MEM_TARGET_VRAM: target = 4; break;
+-              case NVKM_MEM_TARGET_HOST: target = 5; break;
+-              case NVKM_MEM_TARGET_NCOH: target = 6; break;
+-              default:
+-                      WARN_ON(1);
+-                      return -EINVAL;
+-              }
+-
+               ret = nvkm_falcon_pio_wr(falcon, fw->boot, 0, 0,
+                                        IMEM, falcon->code.limit - fw->boot_size, fw->boot_size,
+                                        fw->boot_addr >> 8, false);
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch b/queue-6.16/drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch
new file mode 100644 (file)
index 0000000..b15ac48
--- /dev/null
@@ -0,0 +1,48 @@
+From 5064a5a5da12f395cda17abd5fa598f63eff5443 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:28:41 -0700
+Subject: drm/xe: Don't trigger rebind on initial dma-buf validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ Upstream commit 16ca06aa2c2218cb21907c0c45a746958c944def ]
+
+On the first validate of an imported dma-buf (initial bind), the device
+has no GPU mappings, so a rebind is unnecessary. Rebinding here is
+harmful in multi-GPU setups and for VMs using preempt-fence mode, as it
+would evict in-flight GPU work.
+
+v2:
+ - Drop dma_buf_validated, check for XE_PL_SYSTEM (Thomas)
+
+Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Link: https://lore.kernel.org/r/20250825152841.3837378-1-matthew.brost@intel.com
+(cherry picked from commit ffdf968762e4fb3cdae54e811ec3525e67440a60)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index e2c6493cb70d9..74635b444122d 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -796,7 +796,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+       }
+       if (ttm_bo->type == ttm_bo_type_sg) {
+-              ret = xe_bo_move_notify(bo, ctx);
++              if (new_mem->mem_type == XE_PL_SYSTEM)
++                      ret = xe_bo_move_notify(bo, ctx);
+               if (!ret)
+                       ret = xe_bo_move_dmabuf(ttm_bo, new_mem);
+               return ret;
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-xe-vm-don-t-pin-the-vm_resv-during-validation.patch b/queue-6.16/drm-xe-vm-don-t-pin-the-vm_resv-during-validation.patch
new file mode 100644 (file)
index 0000000..430b183
--- /dev/null
@@ -0,0 +1,103 @@
+From 1850e2b00bbfd8a3c2a0b2bd6705101201cfe4a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 16:30:43 +0200
+Subject: drm/xe/vm: Don't pin the vm_resv during validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+
+[ Upstream commit 7551865cd12af2dc47e5a174eebcfb0b94b5449b ]
+
+The pinning has the odd side-effect that unlocking *any* resv
+during validation triggers an "unlocking pinned lock" warning.
+
+Cc: Matthew Brost <matthew.brost@intel.com>
+Fixes: 5cc3325584c4 ("drm/xe: Rework eviction rejection of bound external bos")
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250821143045.106005-2-thomas.hellstrom@linux.intel.com
+(cherry picked from commit 0a51bf3e54dd8b77e6f1febbbb66def0660862d2)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c |  5 ++---
+ drivers/gpu/drm/xe/xe_vm.h | 15 ++-------------
+ 2 files changed, 4 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 7aa2c17825da9..e2c6493cb70d9 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -2435,7 +2435,6 @@ int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
+               .no_wait_gpu = false,
+               .gfp_retry_mayfail = true,
+       };
+-      struct pin_cookie cookie;
+       int ret;
+       if (vm) {
+@@ -2446,10 +2445,10 @@ int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
+               ctx.resv = xe_vm_resv(vm);
+       }
+-      cookie = xe_vm_set_validating(vm, allow_res_evict);
++      xe_vm_set_validating(vm, allow_res_evict);
+       trace_xe_bo_validate(bo);
+       ret = ttm_bo_validate(&bo->ttm, &bo->placement, &ctx);
+-      xe_vm_clear_validating(vm, allow_res_evict, cookie);
++      xe_vm_clear_validating(vm, allow_res_evict);
+       return ret;
+ }
+diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
+index 0158ec0ae3b23..e54ca835b5828 100644
+--- a/drivers/gpu/drm/xe/xe_vm.h
++++ b/drivers/gpu/drm/xe/xe_vm.h
+@@ -310,22 +310,14 @@ void xe_vm_snapshot_free(struct xe_vm_snapshot *snap);
+  * Register this task as currently making bos resident for the vm. Intended
+  * to avoid eviction by the same task of shared bos bound to the vm.
+  * Call with the vm's resv lock held.
+- *
+- * Return: A pin cookie that should be used for xe_vm_clear_validating().
+  */
+-static inline struct pin_cookie xe_vm_set_validating(struct xe_vm *vm,
+-                                                   bool allow_res_evict)
++static inline void xe_vm_set_validating(struct xe_vm *vm, bool allow_res_evict)
+ {
+-      struct pin_cookie cookie = {};
+-
+       if (vm && !allow_res_evict) {
+               xe_vm_assert_held(vm);
+-              cookie = lockdep_pin_lock(&xe_vm_resv(vm)->lock.base);
+               /* Pairs with READ_ONCE in xe_vm_is_validating() */
+               WRITE_ONCE(vm->validating, current);
+       }
+-
+-      return cookie;
+ }
+ /**
+@@ -333,17 +325,14 @@ static inline struct pin_cookie xe_vm_set_validating(struct xe_vm *vm,
+  * @vm: Pointer to the vm or NULL
+  * @allow_res_evict: Eviction from @vm was allowed. Must be set to the same
+  * value as for xe_vm_set_validation().
+- * @cookie: Cookie obtained from xe_vm_set_validating().
+  *
+  * Register this task as currently making bos resident for the vm. Intended
+  * to avoid eviction by the same task of shared bos bound to the vm.
+  * Call with the vm's resv lock held.
+  */
+-static inline void xe_vm_clear_validating(struct xe_vm *vm, bool allow_res_evict,
+-                                        struct pin_cookie cookie)
++static inline void xe_vm_clear_validating(struct xe_vm *vm, bool allow_res_evict)
+ {
+       if (vm && !allow_res_evict) {
+-              lockdep_unpin_lock(&xe_vm_resv(vm)->lock.base, cookie);
+               /* Pairs with READ_ONCE in xe_vm_is_validating() */
+               WRITE_ONCE(vm->validating, NULL);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.16/drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch b/queue-6.16/drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch
new file mode 100644 (file)
index 0000000..ea45457
--- /dev/null
@@ -0,0 +1,56 @@
+From eee342b865862b49cca0f8370369fee7586cee59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 10:39:04 +0200
+Subject: drm/xe/xe_sync: avoid race during ufence signaling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
+
+[ Upstream commit 04e1f683cd28dc9407b238543871a6e09a570dc0 ]
+
+Marking ufence as signalled after copy_to_user() is too late.
+Worker thread which signals ufence by memory write might be raced
+with another userspace vm-bind call. In map/unmap scenario unmap
+may still see ufence is not signalled causing -EBUSY. Change the
+order of marking / write to user-fence fixes this issue.
+
+Fixes: 977e5b82e090 ("drm/xe: Expose user fence from xe_sync_entry")
+Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/5536
+Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250820083903.2109891-2-zbigniew.kempczynski@intel.com
+(cherry picked from commit 8ae04fe9ffc93d6bc3bc63ac08375427d69cee06)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_sync.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c
+index f87276df18f28..82872a51f0983 100644
+--- a/drivers/gpu/drm/xe/xe_sync.c
++++ b/drivers/gpu/drm/xe/xe_sync.c
+@@ -77,6 +77,7 @@ static void user_fence_worker(struct work_struct *w)
+ {
+       struct xe_user_fence *ufence = container_of(w, struct xe_user_fence, worker);
++      WRITE_ONCE(ufence->signalled, 1);
+       if (mmget_not_zero(ufence->mm)) {
+               kthread_use_mm(ufence->mm);
+               if (copy_to_user(ufence->addr, &ufence->value, sizeof(ufence->value)))
+@@ -91,7 +92,6 @@ static void user_fence_worker(struct work_struct *w)
+        * Wake up waiters only after updating the ufence state, allowing the UMD
+        * to safely reuse the same ufence without encountering -EBUSY errors.
+        */
+-      WRITE_ONCE(ufence->signalled, 1);
+       wake_up_all(&ufence->xe->ufence_wq);
+       user_fence_put(ufence);
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.16/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch b/queue-6.16/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
new file mode 100644 (file)
index 0000000..75ce100
--- /dev/null
@@ -0,0 +1,39 @@
+From 7e1fb54cd5fd623cd674ad162637a4030e16bb1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Aug 2025 11:36:54 +0300
+Subject: dt-bindings: display/msm: qcom,mdp5: drop lut clock
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 7ab3b7579a6d2660a3425b9ea93b9a140b07f49c ]
+
+None of MDP5 platforms have a LUT clock on the display-controller, it
+was added by the mistake. Drop it, fixing DT warnings on MSM8976 /
+MSM8956 platforms. Technically it's an ABI break, but no other platforms
+are affected.
+
+Fixes: 385c8ac763b3 ("dt-bindings: display/msm: convert MDP5 schema to YAML format")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Patchwork: https://patchwork.freedesktop.org/patch/667822/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+index e153f8d26e7aa..2735c78b0b67a 100644
+--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
++++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+@@ -60,7 +60,6 @@ properties:
+           - const: bus
+           - const: core
+           - const: vsync
+-          - const: lut
+           - const: tbu
+           - const: tbu_rt
+         # MSM8996 has additional iommu clock
+-- 
+2.50.1
+
diff --git a/queue-6.16/efi-stmm-fix-incorrect-buffer-allocation-method.patch b/queue-6.16/efi-stmm-fix-incorrect-buffer-allocation-method.patch
new file mode 100644 (file)
index 0000000..11904e5
--- /dev/null
@@ -0,0 +1,111 @@
+From 261aecfdcd3d8a4cdf60881d3a717a72f006e1df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 18:07:10 +0200
+Subject: efi: stmm: Fix incorrect buffer allocation method
+
+From: Jan Kiszka <jan.kiszka@siemens.com>
+
+[ Upstream commit c5e81e672699e0c5557b2b755cc8f7a69aa92bff ]
+
+The communication buffer allocated by setup_mm_hdr() is later on passed
+to tee_shm_register_kernel_buf(). The latter expects those buffers to be
+contiguous pages, but setup_mm_hdr() just uses kmalloc(). That can cause
+various corruptions or BUGs, specifically since commit 9aec2fb0fd5e
+("slab: allocate frozen pages"), though it was broken before as well.
+
+Fix this by using alloc_pages_exact() instead of kmalloc().
+
+Fixes: c44b6be62e8d ("efi: Add tee-based EFI variable driver")
+Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
+Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
+Acked-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/stmm/tee_stmm_efi.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/firmware/efi/stmm/tee_stmm_efi.c b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+index f741ca279052b..e15d11ed165ee 100644
+--- a/drivers/firmware/efi/stmm/tee_stmm_efi.c
++++ b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+@@ -143,6 +143,10 @@ static efi_status_t mm_communicate(u8 *comm_buf, size_t payload_size)
+       return var_hdr->ret_status;
+ }
++#define COMM_BUF_SIZE(__payload_size) (MM_COMMUNICATE_HEADER_SIZE + \
++                                       MM_VARIABLE_COMMUNICATE_SIZE + \
++                                       (__payload_size))
++
+ /**
+  * setup_mm_hdr() -   Allocate a buffer for StandAloneMM and initialize the
+  *                    header data.
+@@ -173,9 +177,8 @@ static void *setup_mm_hdr(u8 **dptr, size_t payload_size, size_t func,
+               return NULL;
+       }
+-      comm_buf = kzalloc(MM_COMMUNICATE_HEADER_SIZE +
+-                                 MM_VARIABLE_COMMUNICATE_SIZE + payload_size,
+-                         GFP_KERNEL);
++      comm_buf = alloc_pages_exact(COMM_BUF_SIZE(payload_size),
++                                   GFP_KERNEL | __GFP_ZERO);
+       if (!comm_buf) {
+               *ret = EFI_OUT_OF_RESOURCES;
+               return NULL;
+@@ -239,7 +242,7 @@ static efi_status_t get_max_payload(size_t *size)
+        */
+       *size -= 2;
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -282,7 +285,7 @@ static efi_status_t get_property_int(u16 *name, size_t name_size,
+       memcpy(var_property, &smm_property->property, sizeof(*var_property));
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -347,7 +350,7 @@ static efi_status_t tee_get_variable(u16 *name, efi_guid_t *vendor,
+       memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
+              var_acc->data_size);
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -404,7 +407,7 @@ static efi_status_t tee_get_next_variable(unsigned long *name_size,
+       memcpy(name, var_getnext->name, var_getnext->name_size);
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -467,7 +470,7 @@ static efi_status_t tee_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+       ret = mm_communicate(comm_buf, payload_size);
+       dev_dbg(pvt_data.dev, "Set Variable %s %d %lx\n", __FILE__, __LINE__, ret);
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+@@ -507,7 +510,7 @@ static efi_status_t tee_query_variable_info(u32 attributes,
+       *max_variable_size = mm_query_info->max_variable_size;
+ out:
+-      kfree(comm_buf);
++      free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+       return ret;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.16/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch b/queue-6.16/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
new file mode 100644 (file)
index 0000000..4e4a47d
--- /dev/null
@@ -0,0 +1,77 @@
+From 3bec7c0470fdba2b688af477fa7d1757698b677b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+  BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+  Call trace:
+   kasan_check_range+0xe8/0x190
+   __asan_loadN+0x1c/0x28
+   memcmp+0x98/0xd0
+   efivarfs_d_compare+0x68/0xd8
+   __d_lookup_rcu_op_compare+0x178/0x218
+   __d_lookup_rcu+0x1f8/0x228
+   d_alloc_parallel+0x150/0x648
+   lookup_open.isra.0+0x5f0/0x8d0
+   open_last_lookups+0x264/0x828
+   path_openat+0x130/0x3f8
+   do_filp_open+0x114/0x248
+   do_sys_openat2+0x340/0x3c0
+   __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+  T1                   T2
+  lookup_open
+   ->lookup
+    simple_lookup
+     d_add
+     // invalid dentry is added to hash list
+
+                       lookup_open
+                        d_alloc_parallel
+                         __d_lookup_rcu
+                          __d_lookup_rcu_op_compare
+                           hlist_bl_for_each_entry_rcu
+                           // invalid dentry can be retrieved
+                            ->d_compare
+                             efivarfs_d_compare
+                             // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 284d6dbba2ece..5c0d45cccc10e 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -152,6 +152,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+       int guid = len - EFI_VARIABLE_GUID_LEN;
++      /* Parallel lookups may produce a temporary invalid filename */
++      if (guid <= 0)
++              return 1;
++
+       if (name->len != len)
+               return 1;
+-- 
+2.50.1
+
diff --git a/queue-6.16/fbnic-move-phylink-resume-out-of-service_task-and-in.patch b/queue-6.16/fbnic-move-phylink-resume-out-of-service_task-and-in.patch
new file mode 100644 (file)
index 0000000..455d267
--- /dev/null
@@ -0,0 +1,120 @@
+From 42537d367c4e534c42d1c8e149b80958ca1c994d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 15:56:13 -0700
+Subject: fbnic: Move phylink resume out of service_task and into open/close
+
+From: Alexander Duyck <alexanderduyck@fb.com>
+
+[ Upstream commit 6ede14a2c6365e7e5d855643c7c8390b5268c467 ]
+
+The fbnic driver was presenting with the following locking assert coming
+out of a PM resume:
+[   42.208116][  T164] RTNL: assertion failed at drivers/net/phy/phylink.c (2611)
+[   42.208492][  T164] WARNING: CPU: 1 PID: 164 at drivers/net/phy/phylink.c:2611 phylink_resume+0x190/0x1e0
+[   42.208872][  T164] Modules linked in:
+[   42.209140][  T164] CPU: 1 UID: 0 PID: 164 Comm: bash Not tainted 6.17.0-rc2-virtme #134 PREEMPT(full)
+[   42.209496][  T164] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-5.fc42 04/01/2014
+[   42.209861][  T164] RIP: 0010:phylink_resume+0x190/0x1e0
+[   42.210057][  T164] Code: 83 e5 01 0f 85 b0 fe ff ff c6 05 1c cd 3e 02 01 90 ba 33 0a 00 00 48 c7 c6 20 3a 1d a5 48 c7 c7 e0 3e 1d a5 e8 21 b8 90 fe 90 <0f> 0b 90 90 e9 86 fe ff ff e8 42 ea 1f ff e9 e2 fe ff ff 48 89 ef
+[   42.210708][  T164] RSP: 0018:ffffc90000affbd8 EFLAGS: 00010296
+[   42.210983][  T164] RAX: 0000000000000000 RBX: ffff8880078d8400 RCX: 0000000000000000
+[   42.211235][  T164] RDX: 0000000000000000 RSI: 1ffffffff4f10938 RDI: 0000000000000001
+[   42.211466][  T164] RBP: 0000000000000000 R08: ffffffffa2ae79ea R09: fffffbfff4b3eb84
+[   42.211707][  T164] R10: 0000000000000003 R11: 0000000000000000 R12: ffff888007ad8000
+[   42.211997][  T164] R13: 0000000000000002 R14: ffff888006a18800 R15: ffffffffa34c59e0
+[   42.212234][  T164] FS:  00007f0dc8e39740(0000) GS:ffff88808f51f000(0000) knlGS:0000000000000000
+[   42.212505][  T164] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   42.212704][  T164] CR2: 00007f0dc8e9fe10 CR3: 000000000b56d003 CR4: 0000000000772ef0
+[   42.213227][  T164] PKRU: 55555554
+[   42.213366][  T164] Call Trace:
+[   42.213483][  T164]  <TASK>
+[   42.213565][  T164]  __fbnic_pm_attach.isra.0+0x8e/0xa0
+[   42.213725][  T164]  pci_reset_function+0x116/0x1d0
+[   42.213895][  T164]  reset_store+0xa0/0x100
+[   42.214025][  T164]  ? pci_dev_reset_attr_is_visible+0x50/0x50
+[   42.214221][  T164]  ? sysfs_file_kobj+0xc1/0x1e0
+[   42.214374][  T164]  ? sysfs_kf_write+0x65/0x160
+[   42.214526][  T164]  kernfs_fop_write_iter+0x2f8/0x4c0
+[   42.214677][  T164]  ? kernfs_vma_page_mkwrite+0x1f0/0x1f0
+[   42.214836][  T164]  new_sync_write+0x308/0x6f0
+[   42.214987][  T164]  ? __lock_acquire+0x34c/0x740
+[   42.215135][  T164]  ? new_sync_read+0x6f0/0x6f0
+[   42.215288][  T164]  ? lock_acquire.part.0+0xbc/0x260
+[   42.215440][  T164]  ? ksys_write+0xff/0x200
+[   42.215590][  T164]  ? perf_trace_sched_switch+0x6d0/0x6d0
+[   42.215742][  T164]  vfs_write+0x65e/0xbb0
+[   42.215876][  T164]  ksys_write+0xff/0x200
+[   42.215994][  T164]  ? __ia32_sys_read+0xc0/0xc0
+[   42.216141][  T164]  ? do_user_addr_fault+0x269/0x9f0
+[   42.216292][  T164]  ? rcu_is_watching+0x15/0xd0
+[   42.216442][  T164]  do_syscall_64+0xbb/0x360
+[   42.216591][  T164]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[   42.216784][  T164] RIP: 0033:0x7f0dc8ea9986
+
+A bit of digging showed that we were invoking the phylink_resume as a part
+of the fbnic_up path when we were enabling the service task while not
+holding the RTNL lock. We should be enabling this sooner as a part of the
+ndo_open path and then just letting the service task come online later.
+This will help to enforce the correct locking and brings the phylink
+interface online at the same time as the network interface, instead of at a
+later time.
+
+I tested this on QEMU to verify this was working by putting the system to
+sleep using "echo mem > /sys/power/state" to put the system to sleep in the
+guest and then using the command "system_wakeup" in the QEMU monitor.
+
+Fixes: 69684376eed5 ("eth: fbnic: Add link detection")
+Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Link: https://patch.msgid.link/175616257316.1963577.12238158800417771119.stgit@ahduyck-xeon-server.home.arpa
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 4 ++++
+ drivers/net/ethernet/meta/fbnic/fbnic_pci.c    | 2 --
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index 553bd8b8bb056..d3d1003df8314 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -52,6 +52,8 @@ int __fbnic_open(struct fbnic_net *fbn)
+       fbnic_bmc_rpc_init(fbd);
+       fbnic_rss_reinit(fbd, fbn);
++      phylink_resume(fbn->phylink);
++
+       return 0;
+ time_stop:
+       fbnic_time_stop(fbn);
+@@ -84,6 +86,8 @@ static int fbnic_stop(struct net_device *netdev)
+ {
+       struct fbnic_net *fbn = netdev_priv(netdev);
++      phylink_suspend(fbn->phylink, fbnic_bmc_present(fbn->fbd));
++
+       fbnic_down(fbn);
+       fbnic_pcs_free_irq(fbn->fbd);
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+index 249d3ef862d5a..38045cce38012 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+@@ -118,14 +118,12 @@ static void fbnic_service_task_start(struct fbnic_net *fbn)
+       struct fbnic_dev *fbd = fbn->fbd;
+       schedule_delayed_work(&fbd->service_task, HZ);
+-      phylink_resume(fbn->phylink);
+ }
+ static void fbnic_service_task_stop(struct fbnic_net *fbn)
+ {
+       struct fbnic_dev *fbd = fbn->fbd;
+-      phylink_suspend(fbn->phylink, fbnic_bmc_present(fbd));
+       cancel_delayed_work(&fbd->service_task);
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.16/hid-input-rename-hidinput_set_battery_charge_status.patch b/queue-6.16/hid-input-rename-hidinput_set_battery_charge_status.patch
new file mode 100644 (file)
index 0000000..26a7b92
--- /dev/null
@@ -0,0 +1,147 @@
+From 7b4a69905042843249550d6467d8b7c6bd9b7161 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:39 +0200
+Subject: HID: input: rename hidinput_set_battery_charge_status()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit a82231b2a8712d0218fc286a9b0da328d419a3f4 ]
+
+In preparation for a patch fixing a bug affecting
+hidinput_set_battery_charge_status(), rename the function to
+hidinput_update_battery_charge_status() and move it up so it can be used
+by hidinput_update_battery().
+
+Refactor, no functional changes.
+
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Stable-dep-of: e94536e1d181 ("HID: input: report battery status changes immediately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input-test.c | 10 +++++-----
+ drivers/hid/hid-input.c      | 38 ++++++++++++++++++------------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7..6f5c71660d823 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+ #include <kunit/test.h>
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+       struct hid_device *dev;
+       bool handled;
+@@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
+       dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+-      handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+       KUNIT_EXPECT_FALSE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
+ }
+ static struct kunit_case hid_input_tests[] = {
+-      KUNIT_CASE(hid_test_input_set_battery_charge_status),
++      KUNIT_CASE(hid_test_input_update_battery_charge_status),
+       KUNIT_CASE(hid_test_input_get_battery_property),
+       { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index ff1784b5c2a47..262787e6eb204 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -595,6 +595,20 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+       dev->battery = NULL;
+ }
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
++{
++      switch (usage) {
++      case HID_BAT_CHARGING:
++              dev->battery_charge_status = value ?
++                                           POWER_SUPPLY_STATUS_CHARGING :
++                                           POWER_SUPPLY_STATUS_DISCHARGING;
++              return true;
++      }
++
++      return false;
++}
++
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+       int capacity;
+@@ -617,20 +631,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
+               power_supply_changed(dev->battery);
+       }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
+-{
+-      switch (usage) {
+-      case HID_BAT_CHARGING:
+-              dev->battery_charge_status = value ?
+-                                           POWER_SUPPLY_STATUS_CHARGING :
+-                                           POWER_SUPPLY_STATUS_DISCHARGING;
+-              return true;
+-      }
+-
+-      return false;
+-}
+ #else  /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+                                 struct hid_field *field, bool is_percentage)
+@@ -642,14 +642,14 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
+ {
++      return false;
+ }
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+-      return false;
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,7 +1515,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+               return;
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++              bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+               if (!handled)
+                       hidinput_update_battery(hid, value);
+-- 
+2.50.1
+
diff --git a/queue-6.16/hid-input-report-battery-status-changes-immediately.patch b/queue-6.16/hid-input-report-battery-status-changes-immediately.patch
new file mode 100644 (file)
index 0000000..e46cab7
--- /dev/null
@@ -0,0 +1,97 @@
+From 647a17f9f643be926d6ac02e2bbf7b9d91073209 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:40 +0200
+Subject: HID: input: report battery status changes immediately
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit e94536e1d1818b0989aa19b443b7089f50133c35 ]
+
+Previously, the battery status (charging/discharging) was not reported
+immediately to user-space. 
+
+For most input devices, this wasn't problematic because changing their
+battery status requires connecting them to a different bus.
+For example, a gamepad would report a discharging status while
+connected via Bluetooth and a charging status while connected via USB.
+
+However, certain devices are not connected or disconnected when their
+battery status changes. For example, a phone battery changes its status
+without connecting or disconnecting it.
+In these cases, the battery status was not reported immediately to user
+space.
+
+Report battery status changes immediately to user space to support
+these kinds of devices.
+
+Fixes: a608dc1c0639 ("HID: input: map battery system charging")
+Reported-by: 卢国宏 <luguohong@xiaomi.com>
+Closes: https://lore.kernel.org/linux-input/aI49Im0sGb6fpgc8@fedora/T/
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 262787e6eb204..f45f856a127fe 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -609,13 +609,19 @@ static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+       return false;
+ }
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++                                  int value)
+ {
+       int capacity;
+       if (!dev->battery)
+               return;
++      if (hidinput_update_battery_charge_status(dev, usage, value)) {
++              power_supply_changed(dev->battery);
++              return;
++      }
++
+       if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+               return;
+@@ -642,13 +648,8 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+-static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+-                                                unsigned int usage, int value)
+-{
+-      return false;
+-}
+-
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++                                  int value)
+ {
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+               return;
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+-
+-              if (!handled)
+-                      hidinput_update_battery(hid, value);
+-
++              hidinput_update_battery(hid, usage->hid, value);
+               return;
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.16/hid-intel-thc-hid-intel-quicki2c-enhance-driver-re-i.patch b/queue-6.16/hid-intel-thc-hid-intel-quicki2c-enhance-driver-re-i.patch
new file mode 100644 (file)
index 0000000..2b2bd40
--- /dev/null
@@ -0,0 +1,41 @@
+From f132ce581cb8a4d42085a9dba91d46ca9b0d7fc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Aug 2025 08:23:32 +0800
+Subject: HID: intel-thc-hid: Intel-quicki2c: Enhance driver re-install flow
+
+From: Even Xu <even.xu@intel.com>
+
+[ Upstream commit afa17a09c699410113199dc15256c6ea2b4133f7 ]
+
+After driver module is removed and during re-install stage, if there
+is continueous user touching on the screen, it is a risk impacting
+THC hardware initialization which causes driver installation failure.
+
+This patch enhances this flow by quiescing the external touch
+interrupt after driver is removed which keeps THC hardware
+ignore external interrupt during this remove and re-install stage.
+
+Signed-off-by: Even Xu <even.xu@intel.com>
+Tested-by: Rui Zhang <rui1.zhang@intel.com>
+Fixes: 66b59bfce6d9 ("HID: intel-thc-hid: intel-quicki2c: Complete THC QuickI2C driver")
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+index 8a8c4a46f9270..142e5c40192ea 100644
+--- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
++++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+@@ -406,6 +406,7 @@ static struct quicki2c_device *quicki2c_dev_init(struct pci_dev *pdev, void __io
+  */
+ static void quicki2c_dev_deinit(struct quicki2c_device *qcdev)
+ {
++      thc_interrupt_quiesce(qcdev->thc_hw, true);
+       thc_interrupt_enable(qcdev->thc_hw, false);
+       thc_ltr_unconfig(qcdev->thc_hw);
+-- 
+2.50.1
+
diff --git a/queue-6.16/hid-intel-thc-hid-intel-quicki2c-fix-acpi-dsd-icrs-i.patch b/queue-6.16/hid-intel-thc-hid-intel-quicki2c-fix-acpi-dsd-icrs-i.patch
new file mode 100644 (file)
index 0000000..af3e045
--- /dev/null
@@ -0,0 +1,87 @@
+From 13e9d367fbc2fc84a45b0457d3da5492ff70a1c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Aug 2025 14:57:25 +0800
+Subject: HID: intel-thc-hid: intel-quicki2c: Fix ACPI dsd ICRS/ISUB length
+
+From: Aaron Ma <aaron.ma@canonical.com>
+
+[ Upstream commit 1db9df89a213318a48d958385dc1b17b379dc32b ]
+
+The QuickI2C ACPI _DSD methods return ICRS and ISUB data with a
+trailing byte, making the actual length is one more byte than the
+structs defined.
+
+It caused stack-out-of-bounds and kernel crash:
+
+kernel: BUG: KASAN: stack-out-of-bounds in quicki2c_acpi_get_dsd_property.constprop.0+0x111/0x1b0 [intel_quicki2c]
+kernel: Write of size 12 at addr ffff888106d1f900 by task kworker/u33:2/75
+kernel:
+kernel: CPU: 3 UID: 0 PID: 75 Comm: kworker/u33:2 Not tainted 6.16.0+ #3 PREEMPT(voluntary)
+kernel: Workqueue: async async_run_entry_fn
+kernel: Call Trace:
+kernel:  <TASK>
+kernel:  dump_stack_lvl+0x76/0xa0
+kernel:  print_report+0xd1/0x660
+kernel:  ? __pfx__raw_spin_lock_irqsave+0x10/0x10
+kernel:  ? __kasan_slab_free+0x5d/0x80
+kernel:  ? kasan_addr_to_slab+0xd/0xb0
+kernel:  kasan_report+0xe1/0x120
+kernel:  ? quicki2c_acpi_get_dsd_property.constprop.0+0x111/0x1b0 [intel_quicki2c]
+kernel:  ? quicki2c_acpi_get_dsd_property.constprop.0+0x111/0x1b0 [intel_quicki2c]
+kernel:  kasan_check_range+0x11c/0x200
+kernel:  __asan_memcpy+0x3b/0x80
+kernel:  quicki2c_acpi_get_dsd_property.constprop.0+0x111/0x1b0 [intel_quicki2c]
+kernel:  ? __pfx_quicki2c_acpi_get_dsd_property.constprop.0+0x10/0x10 [intel_quicki2c]
+kernel:  quicki2c_get_acpi_resources+0x237/0x730 [intel_quicki2c]
+[...]
+kernel:  </TASK>
+kernel:
+kernel: The buggy address belongs to stack of task kworker/u33:2/75
+kernel:  and is located at offset 48 in frame:
+kernel:  quicki2c_get_acpi_resources+0x0/0x730 [intel_quicki2c]
+kernel:
+kernel: This frame has 3 objects:
+kernel:  [32, 36) 'hid_desc_addr'
+kernel:  [48, 59) 'i2c_param'
+kernel:  [80, 224) 'i2c_config'
+
+ACPI DSD methods return:
+
+\_SB.PC00.THC0.ICRS Buffer       000000003fdc947b 001 Len 0C = 0A 00 80 1A 06 00 00 00 00 00 00 00
+\_SB.PC00.THC0.ISUB Buffer       00000000f2fcbdc4 001 Len 91 = 00 00 00 00 00 00 00 00 00 00 00 00
+
+Adding reserved padding to quicki2c_subip_acpi_parameter/config.
+
+Fixes: 5282e45ccbfa9 ("HID: intel-thc-hid: intel-quicki2c: Add THC QuickI2C ACPI interfaces")
+Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
+Reviewed-by: Even Xu <even.xu@intel.com>
+Tested-by: Even Xu <even.xu@intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
+index 6ddb584bd6110..97085a6a7452d 100644
+--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
++++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
+@@ -71,6 +71,7 @@ struct quicki2c_subip_acpi_parameter {
+       u16 device_address;
+       u64 connection_speed;
+       u8 addressing_mode;
++      u8 reserved;
+ } __packed;
+ /**
+@@ -120,6 +121,7 @@ struct quicki2c_subip_acpi_config {
+       u64 HMTD;
+       u64 HMRD;
+       u64 HMSL;
++      u8 reserved;
+ };
+ struct device;
+-- 
+2.50.1
+
diff --git a/queue-6.16/hid-intel-thc-hid-intel-thc-fix-incorrect-pointer-ar.patch b/queue-6.16/hid-intel-thc-hid-intel-thc-fix-incorrect-pointer-ar.patch
new file mode 100644 (file)
index 0000000..845d9c0
--- /dev/null
@@ -0,0 +1,82 @@
+From 082e59fd3aeedb2ccd4475a4dbddb5aa8e9d27ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Aug 2025 14:57:26 +0800
+Subject: HID: intel-thc-hid: intel-thc: Fix incorrect pointer arithmetic in
+ I2C regs save
+
+From: Aaron Ma <aaron.ma@canonical.com>
+
+[ Upstream commit a7fc15ed629be89e51e09b743277c53e0a0168f5 ]
+
+Improper use of secondary pointer (&dev->i2c_subip_regs) caused
+kernel crash and out-of-bounds error:
+
+ BUG: KASAN: slab-out-of-bounds in _regmap_bulk_read+0x449/0x510
+ Write of size 4 at addr ffff888136005dc0 by task kworker/u33:5/5107
+
+ CPU: 3 UID: 0 PID: 5107 Comm: kworker/u33:5 Not tainted 6.16.0+ #3 PREEMPT(voluntary)
+ Workqueue: async async_run_entry_fn
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x76/0xa0
+  print_report+0xd1/0x660
+  ? __pfx__raw_spin_lock_irqsave+0x10/0x10
+  ? kasan_complete_mode_report_info+0x26/0x200
+  kasan_report+0xe1/0x120
+  ? _regmap_bulk_read+0x449/0x510
+  ? _regmap_bulk_read+0x449/0x510
+  __asan_report_store4_noabort+0x17/0x30
+  _regmap_bulk_read+0x449/0x510
+  ? __pfx__regmap_bulk_read+0x10/0x10
+  regmap_bulk_read+0x270/0x3d0
+  pio_complete+0x1ee/0x2c0 [intel_thc]
+  ? __pfx_pio_complete+0x10/0x10 [intel_thc]
+  ? __pfx_pio_wait+0x10/0x10 [intel_thc]
+  ? regmap_update_bits_base+0x13b/0x1f0
+  thc_i2c_subip_pio_read+0x117/0x270 [intel_thc]
+  thc_i2c_subip_regs_save+0xc2/0x140 [intel_thc]
+  ? __pfx_thc_i2c_subip_regs_save+0x10/0x10 [intel_thc]
+[...]
+ The buggy address belongs to the object at ffff888136005d00
+  which belongs to the cache kmalloc-rnd-12-192 of size 192
+ The buggy address is located 0 bytes to the right of
+  allocated 192-byte region [ffff888136005d00, ffff888136005dc0)
+
+Replaced with direct array indexing (&dev->i2c_subip_regs[i]) to ensure
+safe memory access.
+
+Fixes: 4228966def884 ("HID: intel-thc-hid: intel-thc: Add THC I2C config interfaces")
+Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
+Reviewed-by: Even Xu <even.xu@intel.com>
+Tested-by: Even Xu <even.xu@intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
+index c105df7f6c873..4698722e0d0a6 100644
+--- a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
++++ b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
+@@ -1539,7 +1539,7 @@ int thc_i2c_subip_regs_save(struct thc_device *dev)
+       for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
+               ret = thc_i2c_subip_pio_read(dev, i2c_subip_regs[i],
+-                                           &read_size, (u32 *)&dev->i2c_subip_regs + i);
++                                           &read_size, &dev->i2c_subip_regs[i]);
+               if (ret < 0)
+                       return ret;
+       }
+@@ -1562,7 +1562,7 @@ int thc_i2c_subip_regs_restore(struct thc_device *dev)
+       for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
+               ret = thc_i2c_subip_pio_write(dev, i2c_subip_regs[i],
+-                                            write_size, (u32 *)&dev->i2c_subip_regs + i);
++                                            write_size, &dev->i2c_subip_regs[i]);
+               if (ret < 0)
+                       return ret;
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.16/ice-don-t-leave-device-non-functional-if-tx-schedule.patch b/queue-6.16/ice-don-t-leave-device-non-functional-if-tx-schedule.patch
new file mode 100644 (file)
index 0000000..1bcaa42
--- /dev/null
@@ -0,0 +1,238 @@
+From 7b6fe95a26cf79fc5770078e2223c940b89adb88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 09:57:09 -0700
+Subject: ice: don't leave device non-functional if Tx scheduler config fails
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 86aae43f21cf784c1d7f6a9af93e5116b0f232ab ]
+
+The ice_cfg_tx_topo function attempts to apply Tx scheduler topology
+configuration based on NVM parameters, selecting either a 5 or 9 layer
+topology.
+
+As part of this flow, the driver acquires the "Global Configuration Lock",
+which is a hardware resource associated with programming the DDP package
+to the device. This "lock" is implemented by firmware as a way to
+guarantee that only one PF can program the DDP for a device. Unlike a
+traditional lock, once a PF has acquired this lock, no other PF will be
+able to acquire it again (including that PF) until a CORER of the device.
+Future requests to acquire the lock report that global configuration has
+already completed.
+
+The following flow is used to program the Tx topology:
+
+ * Read the DDP package for scheduler configuration data
+ * Acquire the global configuration lock
+ * Program Tx scheduler topology according to DDP package data
+ * Trigger a CORER which clears the global configuration lock
+
+This is followed by the flow for programming the DDP package:
+
+ * Acquire the global configuration lock (again)
+ * Download the DDP package to the device
+ * Release the global configuration lock.
+
+However, if configuration of the Tx topology fails, (i.e.
+ice_get_set_tx_topo returns an error code), the driver exits
+ice_cfg_tx_topo() immediately, and fails to trigger CORER.
+
+While the global configuration lock is held, the firmware rejects most
+AdminQ commands, as it is waiting for the DDP package download (or Tx
+scheduler topology programming) to occur.
+
+The current driver flows assume that the global configuration lock has been
+reset by CORER after programming the Tx topology. Thus, the same PF
+attempts to acquire the global lock again, and fails. This results in the
+driver reporting "an unknown error occurred when loading the DDP package".
+It then attempts to enter safe mode, but ultimately fails to finish
+ice_probe() since nearly all AdminQ command report error codes, and the
+driver stops loading the device at some point during its initialization.
+
+The only currently known way that ice_get_set_tx_topo() can fail is with
+certain older DDP packages which contain invalid topology configuration, on
+firmware versions which strictly validate this data. The most recent
+releases of the DDP have resolved the invalid data. However, it is still
+poor practice to essentially brick the device, and prevent access to the
+device even through safe mode or recovery mode. It is also plausible that
+this command could fail for some other reason in the future.
+
+We cannot simply release the global lock after a failed call to
+ice_get_set_tx_topo(). Releasing the lock indicates to firmware that global
+configuration (downloading of the DDP) has completed. Future attempts by
+this or other PFs to load the DDP will fail with a report that the DDP
+package has already been downloaded. Then, PFs will enter safe mode as they
+realize that the package on the device does not meet the minimum version
+requirement to load. The reported error messages are confusing, as they
+indicate the version of the default "safe mode" package in the NVM, rather
+than the version of the file loaded from /lib/firmware.
+
+Instead, we need to trigger CORER to clear global configuration. This is
+the lowest level of hardware reset which clears the global configuration
+lock and related state. It also clears any already downloaded DDP.
+Crucially, it does *not* clear the Tx scheduler topology configuration.
+
+Refactor ice_cfg_tx_topo() to always trigger a CORER after acquiring the
+global lock, regardless of success or failure of the topology
+configuration.
+
+We need to re-initialize the HW structure when we trigger the CORER. Thus,
+it makes sense for this to be the responsibility of ice_cfg_tx_topo()
+rather than its caller, ice_init_tx_topology(). This avoids needless
+re-initialization in cases where we don't attempt to update the Tx
+scheduler topology, such as if it has already been programmed.
+
+There is one catch: failure to re-initialize the HW struct should stop
+ice_probe(). If this function fails, we won't have a valid HW structure and
+cannot ensure the device is functioning properly. To handle this, ensure
+ice_cfg_tx_topo() returns a limited set of error codes. Set aside one
+specifically, -ENODEV, to indicate that the ice_init_tx_topology() should
+fail and stop probe.
+
+Other error codes indicate failure to apply the Tx scheduler topology. This
+is treated as a non-fatal error, with an informational message informing
+the system administrator that the updated Tx topology did not apply. This
+allows the device to load and function with the default Tx scheduler
+topology, rather than failing to load entirely.
+
+Note that this use of CORER will not result in loops with future PFs
+attempting to also load the invalid Tx topology configuration. The first PF
+will acquire the global configuration lock as part of programming the DDP.
+Each PF after this will attempt to acquire the global lock as part of
+programming the Tx topology, and will fail with the indication from
+firmware that global configuration is already complete. Tx scheduler
+topology configuration is only performed during driver init (probe or
+devlink reload) and not during cleanup for a CORER that happens after probe
+completes.
+
+Fixes: 91427e6d9030 ("ice: Support 5 layer topology")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ddp.c  | 44 ++++++++++++++++-------
+ drivers/net/ethernet/intel/ice/ice_main.c | 16 ++++++---
+ 2 files changed, 43 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c
+index 351824dc3c624..1d3e1b188d22c 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ddp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c
+@@ -2376,7 +2376,13 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
+  * The function will apply the new Tx topology from the package buffer
+  * if available.
+  *
+- * Return: zero when update was successful, negative values otherwise.
++ * Return:
++ * * 0 - Successfully applied topology configuration.
++ * * -EBUSY - Failed to acquire global configuration lock.
++ * * -EEXIST - Topology configuration has already been applied.
++ * * -EIO - Unable to apply topology configuration.
++ * * -ENODEV - Failed to re-initialize device after applying configuration.
++ * * Other negative error codes indicate unexpected failures.
+  */
+ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+ {
+@@ -2409,7 +2415,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
+-              return status;
++              return -EIO;
+       }
+       /* Is default topology already applied ? */
+@@ -2496,31 +2502,45 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+                                ICE_GLOBAL_CFG_LOCK_TIMEOUT);
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n");
+-              return status;
++              return -EBUSY;
+       }
+       /* Check if reset was triggered already. */
+       reg = rd32(hw, GLGEN_RSTAT);
+       if (reg & GLGEN_RSTAT_DEVSTATE_M) {
+-              /* Reset is in progress, re-init the HW again */
+               ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer topology might be applied already\n");
+               ice_check_reset(hw);
+-              return 0;
++              /* Reset is in progress, re-init the HW again */
++              goto reinit_hw;
+       }
+       /* Set new topology */
+       status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);
+       if (status) {
+-              ice_debug(hw, ICE_DBG_INIT, "Failed setting Tx topology\n");
+-              return status;
++              ice_debug(hw, ICE_DBG_INIT, "Failed to set Tx topology, status %pe\n",
++                        ERR_PTR(status));
++              /* only report -EIO here as the caller checks the error value
++               * and reports an informational error message informing that
++               * the driver failed to program Tx topology.
++               */
++              status = -EIO;
+       }
+-      /* New topology is updated, delay 1 second before issuing the CORER */
++      /* Even if Tx topology config failed, we need to CORE reset here to
++       * clear the global configuration lock. Delay 1 second to allow
++       * hardware to settle then issue a CORER
++       */
+       msleep(1000);
+       ice_reset(hw, ICE_RESET_CORER);
+-      /* CORER will clear the global lock, so no explicit call
+-       * required for release.
+-       */
++      ice_check_reset(hw);
++
++reinit_hw:
++      /* Since we triggered a CORER, re-initialize hardware */
++      ice_deinit_hw(hw);
++      if (ice_init_hw(hw)) {
++              ice_debug(hw, ICE_DBG_INIT, "Failed to re-init hardware after setting Tx topology\n");
++              return -ENODEV;
++      }
+-      return 0;
++      return status;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index 0a11b4281092e..d42892c8c5a12 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -4532,17 +4532,23 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
+                       dev_info(dev, "Tx scheduling layers switching feature disabled\n");
+               else
+                       dev_info(dev, "Tx scheduling layers switching feature enabled\n");
+-              /* if there was a change in topology ice_cfg_tx_topo triggered
+-               * a CORER and we need to re-init hw
++              return 0;
++      } else if (err == -ENODEV) {
++              /* If we failed to re-initialize the device, we can no longer
++               * continue loading.
+                */
+-              ice_deinit_hw(hw);
+-              err = ice_init_hw(hw);
+-
++              dev_warn(dev, "Failed to initialize hardware after applying Tx scheduling configuration.\n");
+               return err;
+       } else if (err == -EIO) {
+               dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n");
++              return 0;
++      } else if (err == -EEXIST) {
++              return 0;
+       }
++      /* Do not treat this as a fatal error. */
++      dev_info(dev, "Failed to apply Tx scheduling configuration, err %pe\n",
++               ERR_PTR(err));
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.16/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch b/queue-6.16/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
new file mode 100644 (file)
index 0000000..21ae7bd
--- /dev/null
@@ -0,0 +1,46 @@
+From 5dc4ef77970f0bf5bdd95ce69e795fb29e76a9bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Aug 2025 17:53:10 +0200
+Subject: ice: fix incorrect counter for buffer allocation failures
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit b1a0c977c6f1130f7dd125ee3db8c2435d7e3d41 ]
+
+Currently, the driver increments `alloc_page_failed` when buffer allocation fails
+in `ice_clean_rx_irq()`. However, this counter is intended for page allocation
+failures, not buffer allocation issues.
+
+This patch corrects the counter by incrementing `alloc_buf_failed` instead,
+ensuring accurate statistics reporting for buffer allocation failures.
+
+Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
+Reported-by: Jacob Keller <jacob.e.keller@intel.com>
+Suggested-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Priya Singh <priyax.singh@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 0e5107fe62ad5..c50cf3ad190e9 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -1295,7 +1295,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+                       skb = ice_construct_skb(rx_ring, xdp);
+               /* exit if we failed to retrieve a buffer */
+               if (!skb) {
+-                      rx_ring->ring_stats->rx_stats.alloc_page_failed++;
++                      rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
+                       xdp_verdict = ICE_XDP_CONSUMED;
+               }
+               ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+-- 
+2.50.1
+
diff --git a/queue-6.16/ice-fix-null-pointer-dereference-in-ice_unplug_aux_d.patch b/queue-6.16/ice-fix-null-pointer-dereference-in-ice_unplug_aux_d.patch
new file mode 100644 (file)
index 0000000..e62d98d
--- /dev/null
@@ -0,0 +1,94 @@
+From d76a3425c637dceb622a9a7e458ba6d762b395e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jun 2025 07:26:40 -0700
+Subject: ice: fix NULL pointer dereference in ice_unplug_aux_dev() on reset
+
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+
+[ Upstream commit 60dfe2434eed13082f26eb7409665dfafb38fa51 ]
+
+Issuing a reset when the driver is loaded without RDMA support, will
+results in a crash as it attempts to remove RDMA's non-existent auxbus
+device:
+echo 1 > /sys/class/net/<if>/device/reset
+
+BUG: kernel NULL pointer dereference, address: 0000000000000008
+...
+RIP: 0010:ice_unplug_aux_dev+0x29/0x70 [ice]
+...
+Call Trace:
+<TASK>
+ice_prepare_for_reset+0x77/0x260 [ice]
+pci_dev_save_and_disable+0x2c/0x70
+pci_reset_function+0x88/0x130
+reset_store+0x5a/0xa0
+kernfs_fop_write_iter+0x15e/0x210
+vfs_write+0x273/0x520
+ksys_write+0x6b/0xe0
+do_syscall_64+0x79/0x3b0
+entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+ice_unplug_aux_dev() checks pf->cdev_info->adev for NULL pointer, but
+pf->cdev_info will also be NULL, leading to the deref in the trace above.
+
+Introduce a flag to be set when the creation of the auxbus device is
+successful, to avoid multiple NULL pointer checks in ice_unplug_aux_dev().
+
+Fixes: c24a65b6a27c7 ("iidc/ice/irdma: Update IDC to support multiple consumers")
+Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice.h     |  1 +
+ drivers/net/ethernet/intel/ice/ice_idc.c | 10 ++++++----
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
+index ddd0ad68185b4..0ef11b7ab477e 100644
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -509,6 +509,7 @@ enum ice_pf_flags {
+       ICE_FLAG_LINK_LENIENT_MODE_ENA,
+       ICE_FLAG_PLUG_AUX_DEV,
+       ICE_FLAG_UNPLUG_AUX_DEV,
++      ICE_FLAG_AUX_DEV_CREATED,
+       ICE_FLAG_MTU_CHANGED,
+       ICE_FLAG_GNSS,                  /* GNSS successfully initialized */
+       ICE_FLAG_DPLL,                  /* SyncE/PTP dplls initialized */
+diff --git a/drivers/net/ethernet/intel/ice/ice_idc.c b/drivers/net/ethernet/intel/ice/ice_idc.c
+index 6ab53e430f912..420d45c2558b6 100644
+--- a/drivers/net/ethernet/intel/ice/ice_idc.c
++++ b/drivers/net/ethernet/intel/ice/ice_idc.c
+@@ -336,6 +336,7 @@ int ice_plug_aux_dev(struct ice_pf *pf)
+       mutex_lock(&pf->adev_mutex);
+       cdev->adev = adev;
+       mutex_unlock(&pf->adev_mutex);
++      set_bit(ICE_FLAG_AUX_DEV_CREATED, pf->flags);
+       return 0;
+ }
+@@ -347,15 +348,16 @@ void ice_unplug_aux_dev(struct ice_pf *pf)
+ {
+       struct auxiliary_device *adev;
++      if (!test_and_clear_bit(ICE_FLAG_AUX_DEV_CREATED, pf->flags))
++              return;
++
+       mutex_lock(&pf->adev_mutex);
+       adev = pf->cdev_info->adev;
+       pf->cdev_info->adev = NULL;
+       mutex_unlock(&pf->adev_mutex);
+-      if (adev) {
+-              auxiliary_device_delete(adev);
+-              auxiliary_device_uninit(adev);
+-      }
++      auxiliary_device_delete(adev);
++      auxiliary_device_uninit(adev);
+ }
+ /**
+-- 
+2.50.1
+
diff --git a/queue-6.16/ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch b/queue-6.16/ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch
new file mode 100644 (file)
index 0000000..753a391
--- /dev/null
@@ -0,0 +1,202 @@
+From bf4e8ccd3b905cfc321b00fa297589c80e071d1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Aug 2025 15:27:12 -0700
+Subject: ice: use fixed adapter index for E825C embedded devices
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 5c5e5b52bf05c7fe88768318c041052c5fac36b8 ]
+
+The ice_adapter structure is used by the ice driver to connect multiple
+physical functions of a device in software. It was introduced by
+commit 0e2bddf9e5f9 ("ice: add ice_adapter for shared data across PFs on
+the same NIC") and is primarily used for PTP support, as well as for
+handling certain cross-PF synchronization.
+
+The original design of ice_adapter used PCI address information to
+determine which devices should be connected. This was extended to support
+E825C devices by commit fdb7f54700b1 ("ice: Initial support for E825C
+hardware in ice_adapter"), which used the device ID for E825C devices
+instead of the PCI address.
+
+Later, commit 0093cb194a75 ("ice: use DSN instead of PCI BDF for
+ice_adapter index") replaced the use of Bus/Device/Function addressing with
+use of the device serial number.
+
+E825C devices may appear in "Dual NAC" configuration which has multiple
+physical devices tied to the same clock source and which need to use the
+same ice_adapter. Unfortunately, each "NAC" has its own NVM which has its
+own unique Device Serial Number. Thus, use of the DSN for connecting
+ice_adapter does not work properly. It "worked" in the pre-production
+systems because the DSN was not initialized on the test NVMs and all the
+NACs had the same zero'd serial number.
+
+Since we cannot rely on the DSN, lets fall back to the logic in the
+original E825C support which used the device ID. This is safe for E825C
+only because of the embedded nature of the device. It isn't a discreet
+adapter that can be plugged into an arbitrary system. All E825C devices on
+a given system are connected to the same clock source and need to be
+configured through the same PTP clock.
+
+To make this separation clear, reserve bit 63 of the 64-bit index values as
+a "fixed index" indicator. Always clear this bit when using the device
+serial number as an index.
+
+For E825C, use a fixed value defined as the 0x579C E825C backplane device
+ID bitwise ORed with the fixed index indicator. This is slightly different
+than the original logic of just using the device ID directly. Doing so
+prevents a potential issue with systems where only one of the NACs is
+connected with an external PHY over SGMII. In that case, one NAC would
+have the E825C_SGMII device ID, but the other would not.
+
+Separate the determination of the full 64-bit index from the 32-bit
+reduction logic. Provide both ice_adapter_index() and a wrapping
+ice_adapter_xa_index() which handles reducing the index to a long on 32-bit
+systems. As before, cache the full index value in the adapter structure to
+warn about collisions.
+
+This fixes issues with E825C not initializing PTP on both NACs, due to
+failure to connect the appropriate devices to the same ice_adapter.
+
+Fixes: 0093cb194a75 ("ice: use DSN instead of PCI BDF for ice_adapter index")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_adapter.c | 49 +++++++++++++++-----
+ drivers/net/ethernet/intel/ice/ice_adapter.h |  4 +-
+ 2 files changed, 40 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c b/drivers/net/ethernet/intel/ice/ice_adapter.c
+index 66e070095d1bb..10285995c9edd 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.c
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.c
+@@ -13,16 +13,45 @@
+ static DEFINE_XARRAY(ice_adapters);
+ static DEFINE_MUTEX(ice_adapters_mutex);
+-static unsigned long ice_adapter_index(u64 dsn)
++#define ICE_ADAPTER_FIXED_INDEX       BIT_ULL(63)
++
++#define ICE_ADAPTER_INDEX_E825C       \
++      (ICE_DEV_ID_E825C_BACKPLANE | ICE_ADAPTER_FIXED_INDEX)
++
++static u64 ice_adapter_index(struct pci_dev *pdev)
+ {
++      switch (pdev->device) {
++      case ICE_DEV_ID_E825C_BACKPLANE:
++      case ICE_DEV_ID_E825C_QSFP:
++      case ICE_DEV_ID_E825C_SFP:
++      case ICE_DEV_ID_E825C_SGMII:
++              /* E825C devices have multiple NACs which are connected to the
++               * same clock source, and which must share the same
++               * ice_adapter structure. We can't use the serial number since
++               * each NAC has its own NVM generated with its own unique
++               * Device Serial Number. Instead, rely on the embedded nature
++               * of the E825C devices, and use a fixed index. This relies on
++               * the fact that all E825C physical functions in a given
++               * system are part of the same overall device.
++               */
++              return ICE_ADAPTER_INDEX_E825C;
++      default:
++              return pci_get_dsn(pdev) & ~ICE_ADAPTER_FIXED_INDEX;
++      }
++}
++
++static unsigned long ice_adapter_xa_index(struct pci_dev *pdev)
++{
++      u64 index = ice_adapter_index(pdev);
++
+ #if BITS_PER_LONG == 64
+-      return dsn;
++      return index;
+ #else
+-      return (u32)dsn ^ (u32)(dsn >> 32);
++      return (u32)index ^ (u32)(index >> 32);
+ #endif
+ }
+-static struct ice_adapter *ice_adapter_new(u64 dsn)
++static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev)
+ {
+       struct ice_adapter *adapter;
+@@ -30,7 +59,7 @@ static struct ice_adapter *ice_adapter_new(u64 dsn)
+       if (!adapter)
+               return NULL;
+-      adapter->device_serial_number = dsn;
++      adapter->index = ice_adapter_index(pdev);
+       spin_lock_init(&adapter->ptp_gltsyn_time_lock);
+       refcount_set(&adapter->refcount, 1);
+@@ -63,24 +92,23 @@ static void ice_adapter_free(struct ice_adapter *adapter)
+  */
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+ {
+-      u64 dsn = pci_get_dsn(pdev);
+       struct ice_adapter *adapter;
+       unsigned long index;
+       int err;
+-      index = ice_adapter_index(dsn);
++      index = ice_adapter_xa_index(pdev);
+       scoped_guard(mutex, &ice_adapters_mutex) {
+               err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
+               if (err == -EBUSY) {
+                       adapter = xa_load(&ice_adapters, index);
+                       refcount_inc(&adapter->refcount);
+-                      WARN_ON_ONCE(adapter->device_serial_number != dsn);
++                      WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
+                       return adapter;
+               }
+               if (err)
+                       return ERR_PTR(err);
+-              adapter = ice_adapter_new(dsn);
++              adapter = ice_adapter_new(pdev);
+               if (!adapter)
+                       return ERR_PTR(-ENOMEM);
+               xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
+@@ -99,11 +127,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+  */
+ void ice_adapter_put(struct pci_dev *pdev)
+ {
+-      u64 dsn = pci_get_dsn(pdev);
+       struct ice_adapter *adapter;
+       unsigned long index;
+-      index = ice_adapter_index(dsn);
++      index = ice_adapter_xa_index(pdev);
+       scoped_guard(mutex, &ice_adapters_mutex) {
+               adapter = xa_load(&ice_adapters, index);
+               if (WARN_ON(!adapter))
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h b/drivers/net/ethernet/intel/ice/ice_adapter.h
+index ac15c0d2bc1a4..409467847c753 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.h
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h
+@@ -32,7 +32,7 @@ struct ice_port_list {
+  * @refcount: Reference count. struct ice_pf objects hold the references.
+  * @ctrl_pf: Control PF of the adapter
+  * @ports: Ports list
+- * @device_serial_number: DSN cached for collision detection on 32bit systems
++ * @index: 64-bit index cached for collision detection on 32bit systems
+  */
+ struct ice_adapter {
+       refcount_t refcount;
+@@ -41,7 +41,7 @@ struct ice_adapter {
+       struct ice_pf *ctrl_pf;
+       struct ice_port_list ports;
+-      u64 device_serial_number;
++      u64 index;
+ };
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev);
+-- 
+2.50.1
+
diff --git a/queue-6.16/idpf-add-support-for-tx-refillqs-in-flow-scheduling-.patch b/queue-6.16/idpf-add-support-for-tx-refillqs-in-flow-scheduling-.patch
new file mode 100644 (file)
index 0000000..4c9e8fd
--- /dev/null
@@ -0,0 +1,287 @@
+From cf3ac9bc83ae584e60d711360dba3efd7ed75909 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jul 2025 11:42:18 -0700
+Subject: idpf: add support for Tx refillqs in flow scheduling mode
+
+From: Joshua Hay <joshua.a.hay@intel.com>
+
+[ Upstream commit cb83b559bea39f207ee214ee2972657e8576ed18 ]
+
+In certain production environments, it is possible for completion tags
+to collide, meaning N packets with the same completion tag are in flight
+at the same time. In this environment, any given Tx queue is effectively
+used to send both slower traffic and higher throughput traffic
+simultaneously. This is the result of a customer's specific
+configuration in the device pipeline, the details of which Intel cannot
+provide. This configuration results in a small number of out-of-order
+completions, i.e., a small number of packets in flight. The existing
+guardrails in the driver only protect against a large number of packets
+in flight. The slower flow completions are delayed which causes the
+out-of-order completions. The fast flow will continue sending traffic
+and generating tags. Because tags are generated on the fly, the fast
+flow eventually uses the same tag for a packet that is still in flight
+from the slower flow. The driver has no idea which packet it should
+clean when it processes the completion with that tag, but it will look
+for the packet on the buffer ring before the hash table.  If the slower
+flow packet completion is processed first, it will end up cleaning the
+fast flow packet on the ring prematurely. This leaves the descriptor
+ring in a bad state resulting in a crash or Tx timeout.
+
+In summary, generating a tag when a packet is sent can lead to the same
+tag being associated with multiple packets. This can lead to resource
+leaks, crashes, and/or Tx timeouts.
+
+Before we can replace the tag generation, we need a new mechanism for
+the send path to know what tag to use next. The driver will allocate and
+initialize a refillq for each TxQ with all of the possible free tag
+values. During send, the driver grabs the next free tag from the refillq
+from next_to_clean. While cleaning the packet, the clean routine posts
+the tag back to the refillq's next_to_use to indicate that it is now
+free to use.
+
+This mechanism works exactly the same way as the existing Rx refill
+queues, which post the cleaned buffer IDs back to the buffer queue to be
+reposted to HW. Since we're using the refillqs for both Rx and Tx now,
+genericize some of the existing refillq support.
+
+Note: the refillqs will not be used yet. This is only demonstrating how
+they will be used to pass free tags back to the send path.
+
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: b61dfa9bc443 ("idpf: simplify and fix splitq Tx packet rollback error path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c | 93 +++++++++++++++++++--
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h |  8 +-
+ 2 files changed, 91 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index 89185d1b8485e..b26d054013354 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -139,6 +139,9 @@ static void idpf_tx_desc_rel(struct idpf_tx_queue *txq)
+       if (!txq->desc_ring)
+               return;
++      if (txq->refillq)
++              kfree(txq->refillq->ring);
++
+       dmam_free_coherent(txq->dev, txq->size, txq->desc_ring, txq->dma);
+       txq->desc_ring = NULL;
+       txq->next_to_use = 0;
+@@ -244,6 +247,7 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
+                             struct idpf_tx_queue *tx_q)
+ {
+       struct device *dev = tx_q->dev;
++      struct idpf_sw_queue *refillq;
+       int err;
+       err = idpf_tx_buf_alloc_all(tx_q);
+@@ -267,6 +271,29 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
+       tx_q->next_to_clean = 0;
+       idpf_queue_set(GEN_CHK, tx_q);
++      if (!idpf_queue_has(FLOW_SCH_EN, tx_q))
++              return 0;
++
++      refillq = tx_q->refillq;
++      refillq->desc_count = tx_q->desc_count;
++      refillq->ring = kcalloc(refillq->desc_count, sizeof(u32),
++                              GFP_KERNEL);
++      if (!refillq->ring) {
++              err = -ENOMEM;
++              goto err_alloc;
++      }
++
++      for (unsigned int i = 0; i < refillq->desc_count; i++)
++              refillq->ring[i] =
++                      FIELD_PREP(IDPF_RFL_BI_BUFID_M, i) |
++                      FIELD_PREP(IDPF_RFL_BI_GEN_M,
++                                 idpf_queue_has(GEN_CHK, refillq));
++
++      /* Go ahead and flip the GEN bit since this counts as filling
++       * up the ring, i.e. we already ring wrapped.
++       */
++      idpf_queue_change(GEN_CHK, refillq);
++
+       return 0;
+ err_alloc:
+@@ -603,18 +630,18 @@ static int idpf_rx_hdr_buf_alloc_all(struct idpf_buf_queue *bufq)
+ }
+ /**
+- * idpf_rx_post_buf_refill - Post buffer id to refill queue
++ * idpf_post_buf_refill - Post buffer id to refill queue
+  * @refillq: refill queue to post to
+  * @buf_id: buffer id to post
+  */
+-static void idpf_rx_post_buf_refill(struct idpf_sw_queue *refillq, u16 buf_id)
++static void idpf_post_buf_refill(struct idpf_sw_queue *refillq, u16 buf_id)
+ {
+       u32 nta = refillq->next_to_use;
+       /* store the buffer ID and the SW maintained GEN bit to the refillq */
+       refillq->ring[nta] =
+-              FIELD_PREP(IDPF_RX_BI_BUFID_M, buf_id) |
+-              FIELD_PREP(IDPF_RX_BI_GEN_M,
++              FIELD_PREP(IDPF_RFL_BI_BUFID_M, buf_id) |
++              FIELD_PREP(IDPF_RFL_BI_GEN_M,
+                          idpf_queue_has(GEN_CHK, refillq));
+       if (unlikely(++nta == refillq->desc_count)) {
+@@ -995,6 +1022,11 @@ static void idpf_txq_group_rel(struct idpf_vport *vport)
+               struct idpf_txq_group *txq_grp = &vport->txq_grps[i];
+               for (j = 0; j < txq_grp->num_txq; j++) {
++                      if (flow_sch_en) {
++                              kfree(txq_grp->txqs[j]->refillq);
++                              txq_grp->txqs[j]->refillq = NULL;
++                      }
++
+                       kfree(txq_grp->txqs[j]);
+                       txq_grp->txqs[j] = NULL;
+               }
+@@ -1414,6 +1446,13 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, u16 num_txq)
+                       }
+                       idpf_queue_set(FLOW_SCH_EN, q);
++
++                      q->refillq = kzalloc(sizeof(*q->refillq), GFP_KERNEL);
++                      if (!q->refillq)
++                              goto err_alloc;
++
++                      idpf_queue_set(GEN_CHK, q->refillq);
++                      idpf_queue_set(RFL_GEN_CHK, q->refillq);
+               }
+               if (!split)
+@@ -2005,6 +2044,8 @@ static void idpf_tx_handle_rs_completion(struct idpf_tx_queue *txq,
+       compl_tag = le16_to_cpu(desc->q_head_compl_tag.compl_tag);
++      idpf_post_buf_refill(txq->refillq, compl_tag);
++
+       /* If we didn't clean anything on the ring, this packet must be
+        * in the hash table. Go clean it there.
+        */
+@@ -2364,6 +2405,37 @@ static unsigned int idpf_tx_splitq_bump_ntu(struct idpf_tx_queue *txq, u16 ntu)
+       return ntu;
+ }
++/**
++ * idpf_tx_get_free_buf_id - get a free buffer ID from the refill queue
++ * @refillq: refill queue to get buffer ID from
++ * @buf_id: return buffer ID
++ *
++ * Return: true if a buffer ID was found, false if not
++ */
++static bool idpf_tx_get_free_buf_id(struct idpf_sw_queue *refillq,
++                                  u16 *buf_id)
++{
++      u32 ntc = refillq->next_to_clean;
++      u32 refill_desc;
++
++      refill_desc = refillq->ring[ntc];
++
++      if (unlikely(idpf_queue_has(RFL_GEN_CHK, refillq) !=
++                   !!(refill_desc & IDPF_RFL_BI_GEN_M)))
++              return false;
++
++      *buf_id = FIELD_GET(IDPF_RFL_BI_BUFID_M, refill_desc);
++
++      if (unlikely(++ntc == refillq->desc_count)) {
++              idpf_queue_change(RFL_GEN_CHK, refillq);
++              ntc = 0;
++      }
++
++      refillq->next_to_clean = ntc;
++
++      return true;
++}
++
+ /**
+  * idpf_tx_splitq_map - Build the Tx flex descriptor
+  * @tx_q: queue to send buffer on
+@@ -2912,6 +2984,13 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+       }
+       if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
++              if (unlikely(!idpf_tx_get_free_buf_id(tx_q->refillq,
++                                                    &tx_params.compl_tag))) {
++                      u64_stats_update_begin(&tx_q->stats_sync);
++                      u64_stats_inc(&tx_q->q_stats.q_busy);
++                      u64_stats_update_end(&tx_q->stats_sync);
++              }
++
+               tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE;
+               tx_params.eop_cmd = IDPF_TXD_FLEX_FLOW_CMD_EOP;
+               /* Set the RE bit to catch any packets that may have not been
+@@ -3464,7 +3543,7 @@ static int idpf_rx_splitq_clean(struct idpf_rx_queue *rxq, int budget)
+ skip_data:
+               rx_buf->page = NULL;
+-              idpf_rx_post_buf_refill(refillq, buf_id);
++              idpf_post_buf_refill(refillq, buf_id);
+               IDPF_RX_BUMP_NTC(rxq, ntc);
+               /* skip if it is non EOP desc */
+@@ -3572,10 +3651,10 @@ static void idpf_rx_clean_refillq(struct idpf_buf_queue *bufq,
+               bool failure;
+               if (idpf_queue_has(RFL_GEN_CHK, refillq) !=
+-                  !!(refill_desc & IDPF_RX_BI_GEN_M))
++                  !!(refill_desc & IDPF_RFL_BI_GEN_M))
+                       break;
+-              buf_id = FIELD_GET(IDPF_RX_BI_BUFID_M, refill_desc);
++              buf_id = FIELD_GET(IDPF_RFL_BI_BUFID_M, refill_desc);
+               failure = idpf_rx_update_bufq_desc(bufq, buf_id, buf_desc);
+               if (failure)
+                       break;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index 36a0f828a6f80..6924bee6ff5bd 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -107,8 +107,8 @@ do {                                                               \
+  */
+ #define IDPF_TX_SPLITQ_RE_MIN_GAP     64
+-#define IDPF_RX_BI_GEN_M              BIT(16)
+-#define IDPF_RX_BI_BUFID_M            GENMASK(15, 0)
++#define IDPF_RFL_BI_GEN_M             BIT(16)
++#define IDPF_RFL_BI_BUFID_M           GENMASK(15, 0)
+ #define IDPF_RXD_EOF_SPLITQ           VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_EOF_M
+ #define IDPF_RXD_EOF_SINGLEQ          VIRTCHNL2_RX_BASE_DESC_STATUS_EOF_M
+@@ -621,6 +621,7 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64,
+  * @cleaned_pkts: Number of packets cleaned for the above said case
+  * @tx_max_bufs: Max buffers that can be transmitted with scatter-gather
+  * @stash: Tx buffer stash for Flow-based scheduling mode
++ * @refillq: Pointer to refill queue
+  * @compl_tag_bufid_m: Completion tag buffer id mask
+  * @compl_tag_cur_gen: Used to keep track of current completion tag generation
+  * @compl_tag_gen_max: To determine when compl_tag_cur_gen should be reset
+@@ -670,6 +671,7 @@ struct idpf_tx_queue {
+       u16 tx_max_bufs;
+       struct idpf_txq_stash *stash;
++      struct idpf_sw_queue *refillq;
+       u16 compl_tag_bufid_m;
+       u16 compl_tag_cur_gen;
+@@ -691,7 +693,7 @@ struct idpf_tx_queue {
+       __cacheline_group_end_aligned(cold);
+ };
+ libeth_cacheline_set_assert(struct idpf_tx_queue, 64,
+-                          112 + sizeof(struct u64_stats_sync),
++                          120 + sizeof(struct u64_stats_sync),
+                           24);
+ /**
+-- 
+2.50.1
+
diff --git a/queue-6.16/idpf-replace-flow-scheduling-buffer-ring-with-buffer.patch b/queue-6.16/idpf-replace-flow-scheduling-buffer-ring-with-buffer.patch
new file mode 100644 (file)
index 0000000..fdb0a8b
--- /dev/null
@@ -0,0 +1,533 @@
+From a7154cdd667ee1957f44f24f1f88e5da13a9c495 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jul 2025 11:42:21 -0700
+Subject: idpf: replace flow scheduling buffer ring with buffer pool
+
+From: Joshua Hay <joshua.a.hay@intel.com>
+
+[ Upstream commit 5f417d551324d2894168b362f2429d120ab06243 ]
+
+Replace the TxQ buffer ring with one large pool/array of buffers (only
+for flow scheduling). This eliminates the tag generation and makes it
+impossible for a tag to be associated with more than one packet.
+
+The completion tag passed to HW through the descriptor is the index into
+the array. That same completion tag is posted back to the driver in the
+completion descriptor, and used to index into the array to quickly
+retrieve the buffer during cleaning.  In this way, the tags are treated
+as a fix sized resource. If all tags are in use, no more packets can be
+sent on that particular queue (until some are freed up). The tag pool
+size is 64K since the completion tag width is 16 bits.
+
+For each packet, the driver pulls a free tag from the refillq to get the
+next free buffer index. When cleaning is complete, the tag is posted
+back to the refillq. A multi-frag packet spans multiple buffers in the
+driver, therefore it uses multiple buffer indexes/tags from the pool.
+Each frag pulls from the refillq to get the next free buffer index.
+These are tracked in a next_buf field that replaces the completion tag
+field in the buffer struct. This chains the buffers together so that the
+packet can be cleaned from the starting completion tag taken from the
+completion descriptor, then from the next_buf field for each subsequent
+buffer.
+
+In case of a dma_mapping_error occurs or the refillq runs out of free
+buf_ids, the packet will execute the rollback error path. This unmaps
+any buffers previously mapped for the packet. Since several free
+buf_ids could have already been pulled from the refillq, we need to
+restore its original state as well. Otherwise, the buf_ids/tags
+will be leaked and not used again until the queue is reallocated.
+
+Descriptor completions only advance the descriptor ring index to "clean"
+the descriptors. The packet completions only clean the buffers
+associated with the given packet completion tag and do not update the
+descriptor ring index.
+
+When operating in queue based scheduling mode, the array still acts as a
+ring and will only have TxQ descriptor count entries. The tx_bufs are
+still associated 1:1 with the descriptor ring entries and we can use the
+conventional indexing mechanisms.
+
+Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
+Signed-off-by: Luigi Rizzo <lrizzo@google.com>
+Signed-off-by: Brian Vazquez <brianvv@google.com>
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c | 204 +++++++++-----------
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h |  10 +-
+ 2 files changed, 103 insertions(+), 111 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index 7c758e7281ab5..89fedc2ef247b 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -13,6 +13,7 @@ struct idpf_tx_stash {
+       struct libeth_sqe buf;
+ };
++#define idpf_tx_buf_next(buf)         (*(u32 *)&(buf)->priv)
+ #define idpf_tx_buf_compl_tag(buf)    (*(u32 *)&(buf)->priv)
+ LIBETH_SQE_CHECK_PRIV(u32);
+@@ -91,7 +92,7 @@ static void idpf_tx_buf_rel_all(struct idpf_tx_queue *txq)
+               return;
+       /* Free all the Tx buffer sk_buffs */
+-      for (i = 0; i < txq->desc_count; i++)
++      for (i = 0; i < txq->buf_pool_size; i++)
+               libeth_tx_complete(&txq->tx_buf[i], &cp);
+       kfree(txq->tx_buf);
+@@ -199,14 +200,17 @@ static void idpf_tx_desc_rel_all(struct idpf_vport *vport)
+ static int idpf_tx_buf_alloc_all(struct idpf_tx_queue *tx_q)
+ {
+       struct idpf_buf_lifo *buf_stack;
+-      int buf_size;
+       int i;
+       /* Allocate book keeping buffers only. Buffers to be supplied to HW
+        * are allocated by kernel network stack and received as part of skb
+        */
+-      buf_size = sizeof(struct idpf_tx_buf) * tx_q->desc_count;
+-      tx_q->tx_buf = kzalloc(buf_size, GFP_KERNEL);
++      if (idpf_queue_has(FLOW_SCH_EN, tx_q))
++              tx_q->buf_pool_size = U16_MAX;
++      else
++              tx_q->buf_pool_size = tx_q->desc_count;
++      tx_q->tx_buf = kcalloc(tx_q->buf_pool_size, sizeof(*tx_q->tx_buf),
++                             GFP_KERNEL);
+       if (!tx_q->tx_buf)
+               return -ENOMEM;
+@@ -275,7 +279,7 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
+               return 0;
+       refillq = tx_q->refillq;
+-      refillq->desc_count = tx_q->desc_count;
++      refillq->desc_count = tx_q->buf_pool_size;
+       refillq->ring = kcalloc(refillq->desc_count, sizeof(u32),
+                               GFP_KERNEL);
+       if (!refillq->ring) {
+@@ -1867,6 +1871,12 @@ static bool idpf_tx_splitq_clean(struct idpf_tx_queue *tx_q, u16 end,
+       struct idpf_tx_buf *tx_buf;
+       bool clean_complete = true;
++      if (descs_only) {
++              /* Bump ring index to mark as cleaned. */
++              tx_q->next_to_clean = end;
++              return true;
++      }
++
+       tx_desc = &tx_q->flex_tx[ntc];
+       next_pending_desc = &tx_q->flex_tx[end];
+       tx_buf = &tx_q->tx_buf[ntc];
+@@ -1933,87 +1943,43 @@ do {                                                   \
+ } while (0)
+ /**
+- * idpf_tx_clean_buf_ring - clean flow scheduling TX queue buffers
++ * idpf_tx_clean_bufs - clean flow scheduling TX queue buffers
+  * @txq: queue to clean
+- * @compl_tag: completion tag of packet to clean (from completion descriptor)
++ * @buf_id: packet's starting buffer ID, from completion descriptor
+  * @cleaned: pointer to stats struct to track cleaned packets/bytes
+  * @budget: Used to determine if we are in netpoll
+  *
+- * Cleans all buffers associated with the input completion tag either from the
+- * TX buffer ring or from the hash table if the buffers were previously
+- * stashed. Returns the byte/segment count for the cleaned packet associated
+- * this completion tag.
++ * Clean all buffers associated with the packet starting at buf_id. Returns the
++ * byte/segment count for the cleaned packet.
+  */
+-static bool idpf_tx_clean_buf_ring(struct idpf_tx_queue *txq, u16 compl_tag,
+-                                 struct libeth_sq_napi_stats *cleaned,
+-                                 int budget)
++static bool idpf_tx_clean_bufs(struct idpf_tx_queue *txq, u32 buf_id,
++                             struct libeth_sq_napi_stats *cleaned,
++                             int budget)
+ {
+-      u16 idx = compl_tag & txq->compl_tag_bufid_m;
+       struct idpf_tx_buf *tx_buf = NULL;
+       struct libeth_cq_pp cp = {
+               .dev    = txq->dev,
+               .ss     = cleaned,
+               .napi   = budget,
+       };
+-      u16 ntc, orig_idx = idx;
+-
+-      tx_buf = &txq->tx_buf[idx];
+-
+-      if (unlikely(tx_buf->type <= LIBETH_SQE_CTX ||
+-                   idpf_tx_buf_compl_tag(tx_buf) != compl_tag))
+-              return false;
++      tx_buf = &txq->tx_buf[buf_id];
+       if (tx_buf->type == LIBETH_SQE_SKB) {
+               if (skb_shinfo(tx_buf->skb)->tx_flags & SKBTX_IN_PROGRESS)
+                       idpf_tx_read_tstamp(txq, tx_buf->skb);
+               libeth_tx_complete(tx_buf, &cp);
++              idpf_post_buf_refill(txq->refillq, buf_id);
+       }
+-      idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf);
++      while (idpf_tx_buf_next(tx_buf) != IDPF_TXBUF_NULL) {
++              buf_id = idpf_tx_buf_next(tx_buf);
+-      while (idpf_tx_buf_compl_tag(tx_buf) == compl_tag) {
++              tx_buf = &txq->tx_buf[buf_id];
+               libeth_tx_complete(tx_buf, &cp);
+-              idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf);
++              idpf_post_buf_refill(txq->refillq, buf_id);
+       }
+-      /*
+-       * It's possible the packet we just cleaned was an out of order
+-       * completion, which means we can stash the buffers starting from
+-       * the original next_to_clean and reuse the descriptors. We need
+-       * to compare the descriptor ring next_to_clean packet's "first" buffer
+-       * to the "first" buffer of the packet we just cleaned to determine if
+-       * this is the case. Howevever, next_to_clean can point to either a
+-       * reserved buffer that corresponds to a context descriptor used for the
+-       * next_to_clean packet (TSO packet) or the "first" buffer (single
+-       * packet). The orig_idx from the packet we just cleaned will always
+-       * point to the "first" buffer. If next_to_clean points to a reserved
+-       * buffer, let's bump ntc once and start the comparison from there.
+-       */
+-      ntc = txq->next_to_clean;
+-      tx_buf = &txq->tx_buf[ntc];
+-
+-      if (tx_buf->type == LIBETH_SQE_CTX)
+-              idpf_tx_clean_buf_ring_bump_ntc(txq, ntc, tx_buf);
+-
+-      /*
+-       * If ntc still points to a different "first" buffer, clean the
+-       * descriptor ring and stash all of the buffers for later cleaning. If
+-       * we cannot stash all of the buffers, next_to_clean will point to the
+-       * "first" buffer of the packet that could not be stashed and cleaning
+-       * will start there next time.
+-       */
+-      if (unlikely(tx_buf != &txq->tx_buf[orig_idx] &&
+-                   !idpf_tx_splitq_clean(txq, orig_idx, budget, cleaned,
+-                                         true)))
+-              return true;
+-
+-      /*
+-       * Otherwise, update next_to_clean to reflect the cleaning that was
+-       * done above.
+-       */
+-      txq->next_to_clean = idx;
+-
+       return true;
+ }
+@@ -2044,12 +2010,10 @@ static void idpf_tx_handle_rs_completion(struct idpf_tx_queue *txq,
+       compl_tag = le16_to_cpu(desc->q_head_compl_tag.compl_tag);
+-      idpf_post_buf_refill(txq->refillq, compl_tag);
+-
+       /* If we didn't clean anything on the ring, this packet must be
+        * in the hash table. Go clean it there.
+        */
+-      if (!idpf_tx_clean_buf_ring(txq, compl_tag, cleaned, budget))
++      if (!idpf_tx_clean_bufs(txq, compl_tag, cleaned, budget))
+               idpf_tx_clean_stashed_bufs(txq, compl_tag, cleaned, budget);
+ }
+@@ -2362,7 +2326,7 @@ static unsigned int idpf_tx_splitq_bump_ntu(struct idpf_tx_queue *txq, u16 ntu)
+  * Return: true if a buffer ID was found, false if not
+  */
+ static bool idpf_tx_get_free_buf_id(struct idpf_sw_queue *refillq,
+-                                  u16 *buf_id)
++                                  u32 *buf_id)
+ {
+       u32 ntc = refillq->next_to_clean;
+       u32 refill_desc;
+@@ -2395,25 +2359,34 @@ static void idpf_tx_splitq_pkt_err_unmap(struct idpf_tx_queue *txq,
+                                        struct idpf_tx_splitq_params *params,
+                                        struct idpf_tx_buf *first)
+ {
++      struct idpf_sw_queue *refillq = txq->refillq;
+       struct libeth_sq_napi_stats ss = { };
+       struct idpf_tx_buf *tx_buf = first;
+       struct libeth_cq_pp cp = {
+               .dev    = txq->dev,
+               .ss     = &ss,
+       };
+-      u32 idx = 0;
+       u64_stats_update_begin(&txq->stats_sync);
+       u64_stats_inc(&txq->q_stats.dma_map_errs);
+       u64_stats_update_end(&txq->stats_sync);
+-      do {
++      libeth_tx_complete(tx_buf, &cp);
++      while (idpf_tx_buf_next(tx_buf) != IDPF_TXBUF_NULL) {
++              tx_buf = &txq->tx_buf[idpf_tx_buf_next(tx_buf)];
+               libeth_tx_complete(tx_buf, &cp);
+-              idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf);
+-      } while (idpf_tx_buf_compl_tag(tx_buf) == params->compl_tag);
++      }
+       /* Update tail in case netdev_xmit_more was previously true. */
+       idpf_tx_buf_hw_update(txq, params->prev_ntu, false);
++
++      if (!refillq)
++              return;
++
++      /* Restore refillq state to avoid leaking tags. */
++      if (params->prev_refill_gen != idpf_queue_has(RFL_GEN_CHK, refillq))
++              idpf_queue_change(RFL_GEN_CHK, refillq);
++      refillq->next_to_clean = params->prev_refill_ntc;
+ }
+ /**
+@@ -2437,6 +2410,7 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+       struct netdev_queue *nq;
+       struct sk_buff *skb;
+       skb_frag_t *frag;
++      u32 next_buf_id;
+       u16 td_cmd = 0;
+       dma_addr_t dma;
+@@ -2454,18 +2428,16 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+       tx_buf = first;
+       first->nr_frags = 0;
+-      params->compl_tag =
+-              (tx_q->compl_tag_cur_gen << tx_q->compl_tag_gen_s) | i;
+-
+       for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
+               unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED;
+-              if (unlikely(dma_mapping_error(tx_q->dev, dma)))
++              if (unlikely(dma_mapping_error(tx_q->dev, dma))) {
++                      idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL;
+                       return idpf_tx_splitq_pkt_err_unmap(tx_q, params,
+                                                           first);
++              }
+               first->nr_frags++;
+-              idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag;
+               tx_buf->type = LIBETH_SQE_FRAG;
+               /* record length, and DMA address */
+@@ -2521,29 +2493,14 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+                                                 max_data);
+                       if (unlikely(++i == tx_q->desc_count)) {
+-                              tx_buf = tx_q->tx_buf;
+                               tx_desc = &tx_q->flex_tx[0];
+                               i = 0;
+                               tx_q->compl_tag_cur_gen =
+                                       IDPF_TX_ADJ_COMPL_TAG_GEN(tx_q);
+                       } else {
+-                              tx_buf++;
+                               tx_desc++;
+                       }
+-                      /* Since this packet has a buffer that is going to span
+-                       * multiple descriptors, it's going to leave holes in
+-                       * to the TX buffer ring. To ensure these holes do not
+-                       * cause issues in the cleaning routines, we will clear
+-                       * them of any stale data and assign them the same
+-                       * completion tag as the current packet. Then when the
+-                       * packet is being cleaned, the cleaning routines will
+-                       * simply pass over these holes and finish cleaning the
+-                       * rest of the packet.
+-                       */
+-                      tx_buf->type = LIBETH_SQE_EMPTY;
+-                      idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag;
+-
+                       /* Adjust the DMA offset and the remaining size of the
+                        * fragment.  On the first iteration of this loop,
+                        * max_data will be >= 12K and <= 16K-1.  On any
+@@ -2568,15 +2525,26 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+               idpf_tx_splitq_build_desc(tx_desc, params, td_cmd, size);
+               if (unlikely(++i == tx_q->desc_count)) {
+-                      tx_buf = tx_q->tx_buf;
+                       tx_desc = &tx_q->flex_tx[0];
+                       i = 0;
+                       tx_q->compl_tag_cur_gen = IDPF_TX_ADJ_COMPL_TAG_GEN(tx_q);
+               } else {
+-                      tx_buf++;
+                       tx_desc++;
+               }
++              if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
++                      if (unlikely(!idpf_tx_get_free_buf_id(tx_q->refillq,
++                                                            &next_buf_id))) {
++                              idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL;
++                              return idpf_tx_splitq_pkt_err_unmap(tx_q, params,
++                                                                  first);
++                      }
++              } else {
++                      next_buf_id = i;
++              }
++              idpf_tx_buf_next(tx_buf) = next_buf_id;
++              tx_buf = &tx_q->tx_buf[next_buf_id];
++
+               size = skb_frag_size(frag);
+               data_len -= size;
+@@ -2591,6 +2559,7 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+       /* write last descriptor with RS and EOP bits */
+       first->rs_idx = i;
++      idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL;
+       td_cmd |= params->eop_cmd;
+       idpf_tx_splitq_build_desc(tx_desc, params, td_cmd, size);
+       i = idpf_tx_splitq_bump_ntu(tx_q, i);
+@@ -2799,8 +2768,6 @@ idpf_tx_splitq_get_ctx_desc(struct idpf_tx_queue *txq)
+       union idpf_flex_tx_ctx_desc *desc;
+       int i = txq->next_to_use;
+-      txq->tx_buf[i].type = LIBETH_SQE_CTX;
+-
+       /* grab the next descriptor */
+       desc = &txq->flex_ctx[i];
+       txq->next_to_use = idpf_tx_splitq_bump_ntu(txq, i);
+@@ -2910,6 +2877,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+       struct idpf_tx_buf *first;
+       unsigned int count;
+       int tso, idx;
++      u32 buf_id;
+       count = idpf_tx_desc_count_required(tx_q, skb);
+       if (unlikely(!count))
+@@ -2953,26 +2921,28 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+               idpf_tx_set_tstamp_desc(ctx_desc, idx);
+       }
+-      /* record the location of the first descriptor for this packet */
+-      first = &tx_q->tx_buf[tx_q->next_to_use];
+-      first->skb = skb;
++      if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
++              struct idpf_sw_queue *refillq = tx_q->refillq;
+-      if (tso) {
+-              first->packets = tx_params.offload.tso_segs;
+-              first->bytes = skb->len +
+-                      ((first->packets - 1) * tx_params.offload.tso_hdr_len);
+-      } else {
+-              first->packets = 1;
+-              first->bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
+-      }
++              /* Save refillq state in case of a packet rollback.  Otherwise,
++               * the tags will be leaked since they will be popped from the
++               * refillq but never reposted during cleaning.
++               */
++              tx_params.prev_refill_gen =
++                      idpf_queue_has(RFL_GEN_CHK, refillq);
++              tx_params.prev_refill_ntc = refillq->next_to_clean;
+-      if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
+               if (unlikely(!idpf_tx_get_free_buf_id(tx_q->refillq,
+-                                                    &tx_params.compl_tag))) {
+-                      u64_stats_update_begin(&tx_q->stats_sync);
+-                      u64_stats_inc(&tx_q->q_stats.q_busy);
+-                      u64_stats_update_end(&tx_q->stats_sync);
++                                                    &buf_id))) {
++                      if (tx_params.prev_refill_gen !=
++                          idpf_queue_has(RFL_GEN_CHK, refillq))
++                              idpf_queue_change(RFL_GEN_CHK, refillq);
++                      refillq->next_to_clean = tx_params.prev_refill_ntc;
++
++                      tx_q->next_to_use = tx_params.prev_ntu;
++                      return idpf_tx_drop_skb(tx_q, skb);
+               }
++              tx_params.compl_tag = buf_id;
+               tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE;
+               tx_params.eop_cmd = IDPF_TXD_FLEX_FLOW_CMD_EOP;
+@@ -2990,6 +2960,8 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+                       tx_params.offload.td_cmd |= IDPF_TXD_FLEX_FLOW_CMD_CS_EN;
+       } else {
++              buf_id = tx_q->next_to_use;
++
+               tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_L2TAG1_L2TAG2;
+               tx_params.eop_cmd = IDPF_TXD_LAST_DESC_CMD;
+@@ -2997,6 +2969,18 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+                       tx_params.offload.td_cmd |= IDPF_TX_FLEX_DESC_CMD_CS_EN;
+       }
++      first = &tx_q->tx_buf[buf_id];
++      first->skb = skb;
++
++      if (tso) {
++              first->packets = tx_params.offload.tso_segs;
++              first->bytes = skb->len +
++                      ((first->packets - 1) * tx_params.offload.tso_hdr_len);
++      } else {
++              first->packets = 1;
++              first->bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
++      }
++
+       idpf_tx_splitq_map(tx_q, &tx_params, first);
+       return NETDEV_TX_OK;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index c4070806be05c..a30b68504d73c 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -136,6 +136,8 @@ do {                                                               \
+       ((++(txq)->compl_tag_cur_gen) >= (txq)->compl_tag_gen_max ? \
+       0 : (txq)->compl_tag_cur_gen)
++#define IDPF_TXBUF_NULL                       U32_MAX
++
+ #define IDPF_TXD_LAST_DESC_CMD (IDPF_TX_DESC_CMD_EOP | IDPF_TX_DESC_CMD_RS)
+ #define IDPF_TX_FLAGS_TSO             BIT(0)
+@@ -196,6 +198,8 @@ struct idpf_tx_offload_params {
+  * @td_tag: Descriptor tunneling tag
+  * @offload: Offload parameters
+  * @prev_ntu: stored TxQ next_to_use in case of rollback
++ * @prev_refill_ntc: stored refillq next_to_clean in case of packet rollback
++ * @prev_refill_gen: stored refillq generation bit in case of packet rollback
+  */
+ struct idpf_tx_splitq_params {
+       enum idpf_tx_desc_dtype_value dtype;
+@@ -208,6 +212,8 @@ struct idpf_tx_splitq_params {
+       struct idpf_tx_offload_params offload;
+       u16 prev_ntu;
++      u16 prev_refill_ntc;
++      bool prev_refill_gen;
+ };
+ enum idpf_tx_ctx_desc_eipt_offload {
+@@ -636,6 +642,7 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64,
+  * @size: Length of descriptor ring in bytes
+  * @dma: Physical address of ring
+  * @q_vector: Backreference to associated vector
++ * @buf_pool_size: Total number of idpf_tx_buf
+  */
+ struct idpf_tx_queue {
+       __cacheline_group_begin_aligned(read_mostly);
+@@ -693,11 +700,12 @@ struct idpf_tx_queue {
+       dma_addr_t dma;
+       struct idpf_q_vector *q_vector;
++      u32 buf_pool_size;
+       __cacheline_group_end_aligned(cold);
+ };
+ libeth_cacheline_set_assert(struct idpf_tx_queue, 64,
+                           120 + sizeof(struct u64_stats_sync),
+-                          24);
++                          32);
+ /**
+  * struct idpf_buf_queue - software structure representing a buffer queue
+-- 
+2.50.1
+
diff --git a/queue-6.16/idpf-simplify-and-fix-splitq-tx-packet-rollback-erro.patch b/queue-6.16/idpf-simplify-and-fix-splitq-tx-packet-rollback-erro.patch
new file mode 100644 (file)
index 0000000..7f980a3
--- /dev/null
@@ -0,0 +1,268 @@
+From dca28759d10ab4cbc9756cb1d4d866d7ac99a427 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jul 2025 11:42:20 -0700
+Subject: idpf: simplify and fix splitq Tx packet rollback error path
+
+From: Joshua Hay <joshua.a.hay@intel.com>
+
+[ Upstream commit b61dfa9bc4430ad82b96d3a7c1c485350f91b467 ]
+
+Move (and rename) the existing rollback logic to singleq.c since that
+will be the only consumer. Create a simplified splitq specific rollback
+function to loop through and unmap tx_bufs based on the completion tag.
+This is critical before replacing the Tx buffer ring with the buffer
+pool since the previous rollback indexing will not work to unmap the
+chained buffers from the pool.
+
+Cache the next_to_use index before any portion of the packet is put on
+the descriptor ring. In case of an error, the rollback will bump tail to
+the correct next_to_use value. Because the splitq path now supports
+different types of context descriptors (and potentially multiple in the
+future), this will take care of rolling back any and all context
+descriptors encoded on the ring for the erroneous packet. The previous
+rollback logic was broken for PTP packets since it would not account for
+the PTP context descriptor.
+
+Fixes: 1a49cf814fe1 ("idpf: add Tx timestamp flows")
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/intel/idpf/idpf_singleq_txrx.c   | 57 +++++++++++-
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c   | 91 ++++++++-----------
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h   |  5 +-
+ 3 files changed, 95 insertions(+), 58 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+index 993c354aa27ad..a3b3261bbdfa7 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+@@ -179,6 +179,58 @@ static int idpf_tx_singleq_csum(struct sk_buff *skb,
+       return 1;
+ }
++/**
++ * idpf_tx_singleq_dma_map_error - handle TX DMA map errors
++ * @txq: queue to send buffer on
++ * @skb: send buffer
++ * @first: original first buffer info buffer for packet
++ * @idx: starting point on ring to unwind
++ */
++static void idpf_tx_singleq_dma_map_error(struct idpf_tx_queue *txq,
++                                        struct sk_buff *skb,
++                                        struct idpf_tx_buf *first, u16 idx)
++{
++      struct libeth_sq_napi_stats ss = { };
++      struct libeth_cq_pp cp = {
++              .dev    = txq->dev,
++              .ss     = &ss,
++      };
++
++      u64_stats_update_begin(&txq->stats_sync);
++      u64_stats_inc(&txq->q_stats.dma_map_errs);
++      u64_stats_update_end(&txq->stats_sync);
++
++      /* clear dma mappings for failed tx_buf map */
++      for (;;) {
++              struct idpf_tx_buf *tx_buf;
++
++              tx_buf = &txq->tx_buf[idx];
++              libeth_tx_complete(tx_buf, &cp);
++              if (tx_buf == first)
++                      break;
++              if (idx == 0)
++                      idx = txq->desc_count;
++              idx--;
++      }
++
++      if (skb_is_gso(skb)) {
++              union idpf_tx_flex_desc *tx_desc;
++
++              /* If we failed a DMA mapping for a TSO packet, we will have
++               * used one additional descriptor for a context
++               * descriptor. Reset that here.
++               */
++              tx_desc = &txq->flex_tx[idx];
++              memset(tx_desc, 0, sizeof(*tx_desc));
++              if (idx == 0)
++                      idx = txq->desc_count;
++              idx--;
++      }
++
++      /* Update tail in case netdev_xmit_more was previously true */
++      idpf_tx_buf_hw_update(txq, idx, false);
++}
++
+ /**
+  * idpf_tx_singleq_map - Build the Tx base descriptor
+  * @tx_q: queue to send buffer on
+@@ -219,8 +271,9 @@ static void idpf_tx_singleq_map(struct idpf_tx_queue *tx_q,
+       for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
+               unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED;
+-              if (dma_mapping_error(tx_q->dev, dma))
+-                      return idpf_tx_dma_map_error(tx_q, skb, first, i);
++              if (unlikely(dma_mapping_error(tx_q->dev, dma)))
++                      return idpf_tx_singleq_dma_map_error(tx_q, skb,
++                                                           first, i);
+               /* record length, and DMA address */
+               dma_unmap_len_set(tx_buf, len, size);
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index b26d054013354..7c758e7281ab5 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -2337,57 +2337,6 @@ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+       return count;
+ }
+-/**
+- * idpf_tx_dma_map_error - handle TX DMA map errors
+- * @txq: queue to send buffer on
+- * @skb: send buffer
+- * @first: original first buffer info buffer for packet
+- * @idx: starting point on ring to unwind
+- */
+-void idpf_tx_dma_map_error(struct idpf_tx_queue *txq, struct sk_buff *skb,
+-                         struct idpf_tx_buf *first, u16 idx)
+-{
+-      struct libeth_sq_napi_stats ss = { };
+-      struct libeth_cq_pp cp = {
+-              .dev    = txq->dev,
+-              .ss     = &ss,
+-      };
+-
+-      u64_stats_update_begin(&txq->stats_sync);
+-      u64_stats_inc(&txq->q_stats.dma_map_errs);
+-      u64_stats_update_end(&txq->stats_sync);
+-
+-      /* clear dma mappings for failed tx_buf map */
+-      for (;;) {
+-              struct idpf_tx_buf *tx_buf;
+-
+-              tx_buf = &txq->tx_buf[idx];
+-              libeth_tx_complete(tx_buf, &cp);
+-              if (tx_buf == first)
+-                      break;
+-              if (idx == 0)
+-                      idx = txq->desc_count;
+-              idx--;
+-      }
+-
+-      if (skb_is_gso(skb)) {
+-              union idpf_tx_flex_desc *tx_desc;
+-
+-              /* If we failed a DMA mapping for a TSO packet, we will have
+-               * used one additional descriptor for a context
+-               * descriptor. Reset that here.
+-               */
+-              tx_desc = &txq->flex_tx[idx];
+-              memset(tx_desc, 0, sizeof(*tx_desc));
+-              if (idx == 0)
+-                      idx = txq->desc_count;
+-              idx--;
+-      }
+-
+-      /* Update tail in case netdev_xmit_more was previously true */
+-      idpf_tx_buf_hw_update(txq, idx, false);
+-}
+-
+ /**
+  * idpf_tx_splitq_bump_ntu - adjust NTU and generation
+  * @txq: the tx ring to wrap
+@@ -2436,6 +2385,37 @@ static bool idpf_tx_get_free_buf_id(struct idpf_sw_queue *refillq,
+       return true;
+ }
++/**
++ * idpf_tx_splitq_pkt_err_unmap - Unmap buffers and bump tail in case of error
++ * @txq: Tx queue to unwind
++ * @params: pointer to splitq params struct
++ * @first: starting buffer for packet to unmap
++ */
++static void idpf_tx_splitq_pkt_err_unmap(struct idpf_tx_queue *txq,
++                                       struct idpf_tx_splitq_params *params,
++                                       struct idpf_tx_buf *first)
++{
++      struct libeth_sq_napi_stats ss = { };
++      struct idpf_tx_buf *tx_buf = first;
++      struct libeth_cq_pp cp = {
++              .dev    = txq->dev,
++              .ss     = &ss,
++      };
++      u32 idx = 0;
++
++      u64_stats_update_begin(&txq->stats_sync);
++      u64_stats_inc(&txq->q_stats.dma_map_errs);
++      u64_stats_update_end(&txq->stats_sync);
++
++      do {
++              libeth_tx_complete(tx_buf, &cp);
++              idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf);
++      } while (idpf_tx_buf_compl_tag(tx_buf) == params->compl_tag);
++
++      /* Update tail in case netdev_xmit_more was previously true. */
++      idpf_tx_buf_hw_update(txq, params->prev_ntu, false);
++}
++
+ /**
+  * idpf_tx_splitq_map - Build the Tx flex descriptor
+  * @tx_q: queue to send buffer on
+@@ -2480,8 +2460,9 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+       for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
+               unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED;
+-              if (dma_mapping_error(tx_q->dev, dma))
+-                      return idpf_tx_dma_map_error(tx_q, skb, first, i);
++              if (unlikely(dma_mapping_error(tx_q->dev, dma)))
++                      return idpf_tx_splitq_pkt_err_unmap(tx_q, params,
++                                                          first);
+               first->nr_frags++;
+               idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag;
+@@ -2922,7 +2903,9 @@ static void idpf_tx_set_tstamp_desc(union idpf_flex_tx_ctx_desc *ctx_desc,
+ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+                                       struct idpf_tx_queue *tx_q)
+ {
+-      struct idpf_tx_splitq_params tx_params = { };
++      struct idpf_tx_splitq_params tx_params = {
++              .prev_ntu = tx_q->next_to_use,
++      };
+       union idpf_flex_tx_ctx_desc *ctx_desc;
+       struct idpf_tx_buf *first;
+       unsigned int count;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index 6924bee6ff5bd..c4070806be05c 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -195,6 +195,7 @@ struct idpf_tx_offload_params {
+  * @compl_tag: Associated tag for completion
+  * @td_tag: Descriptor tunneling tag
+  * @offload: Offload parameters
++ * @prev_ntu: stored TxQ next_to_use in case of rollback
+  */
+ struct idpf_tx_splitq_params {
+       enum idpf_tx_desc_dtype_value dtype;
+@@ -205,6 +206,8 @@ struct idpf_tx_splitq_params {
+       };
+       struct idpf_tx_offload_params offload;
++
++      u16 prev_ntu;
+ };
+ enum idpf_tx_ctx_desc_eipt_offload {
+@@ -1039,8 +1042,6 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
+                          bool xmit_more);
+ unsigned int idpf_size_to_txd_count(unsigned int size);
+ netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb);
+-void idpf_tx_dma_map_error(struct idpf_tx_queue *txq, struct sk_buff *skb,
+-                         struct idpf_tx_buf *first, u16 ring_idx);
+ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+                                        struct sk_buff *skb);
+ void idpf_tx_timeout(struct net_device *netdev, unsigned int txqueue);
+-- 
+2.50.1
+
diff --git a/queue-6.16/idpf-stop-tx-if-there-are-insufficient-buffer-resour.patch b/queue-6.16/idpf-stop-tx-if-there-are-insufficient-buffer-resour.patch
new file mode 100644 (file)
index 0000000..9a5f9ac
--- /dev/null
@@ -0,0 +1,190 @@
+From 2cadb2bfbdf6ed29b3948a66eb3a87f12a4991bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jul 2025 11:42:22 -0700
+Subject: idpf: stop Tx if there are insufficient buffer resources
+
+From: Joshua Hay <joshua.a.hay@intel.com>
+
+[ Upstream commit 0c3f135e840d4a2ba4253e15d530ec61bc30718e ]
+
+The Tx refillq logic will cause packets to be silently dropped if there
+are not enough buffer resources available to send a packet in flow
+scheduling mode. Instead, determine how many buffers are needed along
+with number of descriptors. Make sure there are enough of both resources
+to send the packet, and stop the queue if not.
+
+Fixes: 7292af042bcf ("idpf: fix a race in txq wakeup")
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/intel/idpf/idpf_singleq_txrx.c   |  4 +-
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c   | 47 +++++++++++++------
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h   | 15 +++++-
+ 3 files changed, 47 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+index a3b3261bbdfa7..bf9b820c83303 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+@@ -415,11 +415,11 @@ netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb,
+ {
+       struct idpf_tx_offload_params offload = { };
+       struct idpf_tx_buf *first;
++      u32 count, buf_count = 1;
+       int csum, tso, needed;
+-      unsigned int count;
+       __be16 protocol;
+-      count = idpf_tx_desc_count_required(tx_q, skb);
++      count = idpf_tx_res_count_required(tx_q, skb, &buf_count);
+       if (unlikely(!count))
+               return idpf_tx_drop_skb(tx_q, skb);
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index 89fedc2ef247b..cd83243e7c765 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -2189,15 +2189,22 @@ void idpf_tx_splitq_build_flow_desc(union idpf_tx_flex_desc *desc,
+       desc->flow.qw1.compl_tag = cpu_to_le16(params->compl_tag);
+ }
+-/* Global conditions to tell whether the txq (and related resources)
+- * has room to allow the use of "size" descriptors.
++/**
++ * idpf_tx_splitq_has_room - check if enough Tx splitq resources are available
++ * @tx_q: the queue to be checked
++ * @descs_needed: number of descriptors required for this packet
++ * @bufs_needed: number of Tx buffers required for this packet
++ *
++ * Return: 0 if no room available, 1 otherwise
+  */
+-static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size)
++static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 descs_needed,
++                           u32 bufs_needed)
+ {
+-      if (IDPF_DESC_UNUSED(tx_q) < size ||
++      if (IDPF_DESC_UNUSED(tx_q) < descs_needed ||
+           IDPF_TX_COMPLQ_PENDING(tx_q->txq_grp) >
+               IDPF_TX_COMPLQ_OVERFLOW_THRESH(tx_q->txq_grp->complq) ||
+-          IDPF_TX_BUF_RSV_LOW(tx_q))
++          IDPF_TX_BUF_RSV_LOW(tx_q) ||
++          idpf_tx_splitq_get_free_bufs(tx_q->refillq) < bufs_needed)
+               return 0;
+       return 1;
+ }
+@@ -2206,14 +2213,21 @@ static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size)
+  * idpf_tx_maybe_stop_splitq - 1st level check for Tx splitq stop conditions
+  * @tx_q: the queue to be checked
+  * @descs_needed: number of descriptors required for this packet
++ * @bufs_needed: number of buffers needed for this packet
+  *
+- * Returns 0 if stop is not needed
++ * Return: 0 if stop is not needed
+  */
+ static int idpf_tx_maybe_stop_splitq(struct idpf_tx_queue *tx_q,
+-                                   unsigned int descs_needed)
++                                   u32 descs_needed,
++                                   u32 bufs_needed)
+ {
++      /* Since we have multiple resources to check for splitq, our
++       * start,stop_thrs becomes a boolean check instead of a count
++       * threshold.
++       */
+       if (netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
+-                                    idpf_txq_has_room(tx_q, descs_needed),
++                                    idpf_txq_has_room(tx_q, descs_needed,
++                                                      bufs_needed),
+                                     1, 1))
+               return 0;
+@@ -2255,14 +2269,16 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
+ }
+ /**
+- * idpf_tx_desc_count_required - calculate number of Tx descriptors needed
++ * idpf_tx_res_count_required - get number of Tx resources needed for this pkt
+  * @txq: queue to send buffer on
+  * @skb: send buffer
++ * @bufs_needed: (output) number of buffers needed for this skb.
+  *
+- * Returns number of data descriptors needed for this skb.
++ * Return: number of data descriptors and buffers needed for this skb.
+  */
+-unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+-                                       struct sk_buff *skb)
++unsigned int idpf_tx_res_count_required(struct idpf_tx_queue *txq,
++                                      struct sk_buff *skb,
++                                      u32 *bufs_needed)
+ {
+       const struct skb_shared_info *shinfo;
+       unsigned int count = 0, i;
+@@ -2273,6 +2289,7 @@ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+               return count;
+       shinfo = skb_shinfo(skb);
++      *bufs_needed += shinfo->nr_frags;
+       for (i = 0; i < shinfo->nr_frags; i++) {
+               unsigned int size;
+@@ -2875,11 +2892,11 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+       };
+       union idpf_flex_tx_ctx_desc *ctx_desc;
+       struct idpf_tx_buf *first;
+-      unsigned int count;
++      u32 count, buf_count = 1;
+       int tso, idx;
+       u32 buf_id;
+-      count = idpf_tx_desc_count_required(tx_q, skb);
++      count = idpf_tx_res_count_required(tx_q, skb, &buf_count);
+       if (unlikely(!count))
+               return idpf_tx_drop_skb(tx_q, skb);
+@@ -2889,7 +2906,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+       /* Check for splitq specific TX resources */
+       count += (IDPF_TX_DESCS_PER_CACHE_LINE + tso);
+-      if (idpf_tx_maybe_stop_splitq(tx_q, count)) {
++      if (idpf_tx_maybe_stop_splitq(tx_q, count, buf_count)) {
+               idpf_tx_buf_hw_update(tx_q, tx_q->next_to_use, false);
+               return NETDEV_TX_BUSY;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index a30b68504d73c..54b314ceee738 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -1023,6 +1023,17 @@ static inline void idpf_vport_intr_set_wb_on_itr(struct idpf_q_vector *q_vector)
+              reg->dyn_ctl);
+ }
++/**
++ * idpf_tx_splitq_get_free_bufs - get number of free buf_ids in refillq
++ * @refillq: pointer to refillq containing buf_ids
++ */
++static inline u32 idpf_tx_splitq_get_free_bufs(struct idpf_sw_queue *refillq)
++{
++      return (refillq->next_to_use > refillq->next_to_clean ?
++              0 : refillq->desc_count) +
++             refillq->next_to_use - refillq->next_to_clean - 1;
++}
++
+ int idpf_vport_singleq_napi_poll(struct napi_struct *napi, int budget);
+ void idpf_vport_init_num_qs(struct idpf_vport *vport,
+                           struct virtchnl2_create_vport *vport_msg);
+@@ -1050,8 +1061,8 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
+                          bool xmit_more);
+ unsigned int idpf_size_to_txd_count(unsigned int size);
+ netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb);
+-unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+-                                       struct sk_buff *skb);
++unsigned int idpf_tx_res_count_required(struct idpf_tx_queue *txq,
++                                      struct sk_buff *skb, u32 *buf_count);
+ void idpf_tx_timeout(struct net_device *netdev, unsigned int txqueue);
+ netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb,
+                                 struct idpf_tx_queue *tx_q);
+-- 
+2.50.1
+
diff --git a/queue-6.16/io_uring-kbuf-always-use-read_once-to-read-ring-prov.patch b/queue-6.16/io_uring-kbuf-always-use-read_once-to-read-ring-prov.patch
new file mode 100644 (file)
index 0000000..0a6228a
--- /dev/null
@@ -0,0 +1,91 @@
+From da5bd9f66dc7d690893f04e767e861e3027f0cc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:27:30 -0600
+Subject: io_uring/kbuf: always use READ_ONCE() to read ring provided buffer
+ lengths
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 98b6fa62c84f2e129161e976a5b9b3cb4ccd117b ]
+
+Since the buffers are mapped from userspace, it is prudent to use
+READ_ONCE() to read the value into a local variable, and use that for
+any other actions taken. Having a stable read of the buffer length
+avoids worrying about it changing after checking, or being read multiple
+times.
+
+Similarly, the buffer may well change in between it being picked and
+being committed. Ensure the looping for incremental ring buffer commit
+stops if it hits a zero sized buffer, as no further progress can be made
+at that point.
+
+Fixes: ae98dbf43d75 ("io_uring/kbuf: add support for incremental buffer consumption")
+Link: https://lore.kernel.org/io-uring/tencent_000C02641F6250C856D0C26228DE29A3D30A@qq.com/
+Reported-by: Qingyue Zhang <chunzhennn@qq.com>
+Reported-by: Suoxing Zhang <aftern00n@qq.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/kbuf.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
+index 81a13338dfab3..19a8bde5e1e1c 100644
+--- a/io_uring/kbuf.c
++++ b/io_uring/kbuf.c
+@@ -36,15 +36,19 @@ static bool io_kbuf_inc_commit(struct io_buffer_list *bl, int len)
+ {
+       while (len) {
+               struct io_uring_buf *buf;
+-              u32 this_len;
++              u32 buf_len, this_len;
+               buf = io_ring_head_to_buf(bl->buf_ring, bl->head, bl->mask);
+-              this_len = min_t(u32, len, buf->len);
+-              buf->len -= this_len;
+-              if (buf->len) {
++              buf_len = READ_ONCE(buf->len);
++              this_len = min_t(u32, len, buf_len);
++              buf_len -= this_len;
++              /* Stop looping for invalid buffer length of 0 */
++              if (buf_len || !this_len) {
+                       buf->addr += this_len;
++                      buf->len = buf_len;
+                       return false;
+               }
++              buf->len = 0;
+               bl->head++;
+               len -= this_len;
+       }
+@@ -159,6 +163,7 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
+       __u16 tail, head = bl->head;
+       struct io_uring_buf *buf;
+       void __user *ret;
++      u32 buf_len;
+       tail = smp_load_acquire(&br->tail);
+       if (unlikely(tail == head))
+@@ -168,8 +173,9 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
+               req->flags |= REQ_F_BL_EMPTY;
+       buf = io_ring_head_to_buf(br, head, bl->mask);
+-      if (*len == 0 || *len > buf->len)
+-              *len = buf->len;
++      buf_len = READ_ONCE(buf->len);
++      if (*len == 0 || *len > buf_len)
++              *len = buf_len;
+       req->flags |= REQ_F_BUFFER_RING | REQ_F_BUFFERS_COMMIT;
+       req->buf_list = bl;
+       req->buf_index = buf->bid;
+@@ -265,7 +271,7 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg,
+       req->buf_index = buf->bid;
+       do {
+-              u32 len = buf->len;
++              u32 len = READ_ONCE(buf->len);
+               /* truncate end piece, if needed, for non partial buffers */
+               if (len > arg->max_len) {
+-- 
+2.50.1
+
diff --git a/queue-6.16/io_uring-kbuf-fix-signedness-in-this_len-calculation.patch b/queue-6.16/io_uring-kbuf-fix-signedness-in-this_len-calculation.patch
new file mode 100644 (file)
index 0000000..bc876c6
--- /dev/null
@@ -0,0 +1,41 @@
+From 421bf961a2272005ac98df29928415485679707c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 19:43:39 +0800
+Subject: io_uring/kbuf: fix signedness in this_len calculation
+
+From: Qingyue Zhang <chunzhennn@qq.com>
+
+[ Upstream commit c64eff368ac676e8540344d27a3de47e0ad90d21 ]
+
+When importing and using buffers, buf->len is considered unsigned.
+However, buf->len is converted to signed int when committing. This can
+lead to unexpected behavior if the buffer is large enough to be
+interpreted as a negative value. Make min_t calculation unsigned.
+
+Fixes: ae98dbf43d75 ("io_uring/kbuf: add support for incremental buffer consumption")
+Co-developed-by: Suoxing Zhang <aftern00n@qq.com>
+Signed-off-by: Suoxing Zhang <aftern00n@qq.com>
+Signed-off-by: Qingyue Zhang <chunzhennn@qq.com>
+Link: https://lore.kernel.org/r/tencent_4DBB3674C0419BEC2C0C525949DA410CA307@qq.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/kbuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
+index f2d2cc319faac..81a13338dfab3 100644
+--- a/io_uring/kbuf.c
++++ b/io_uring/kbuf.c
+@@ -39,7 +39,7 @@ static bool io_kbuf_inc_commit(struct io_buffer_list *bl, int len)
+               u32 this_len;
+               buf = io_ring_head_to_buf(bl->buf_ring, bl->head, bl->mask);
+-              this_len = min_t(int, len, buf->len);
++              this_len = min_t(u32, len, buf->len);
+               buf->len -= this_len;
+               if (buf->len) {
+                       buf->addr += this_len;
+-- 
+2.50.1
+
diff --git a/queue-6.16/ixgbe-fix-ixgbe_orom_civd_info-struct-layout.patch b/queue-6.16/ixgbe-fix-ixgbe_orom_civd_info-struct-layout.patch
new file mode 100644 (file)
index 0000000..c15c048
--- /dev/null
@@ -0,0 +1,57 @@
+From 18b6731550c67fe1a8e40dc0250f7f94588a8a3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Jul 2025 14:45:33 +0200
+Subject: ixgbe: fix ixgbe_orom_civd_info struct layout
+
+From: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+
+[ Upstream commit ed913b343dcf9f623e7436fa1a153c89b22d109b ]
+
+The current layout of struct ixgbe_orom_civd_info causes incorrect data
+storage due to compiler-inserted padding. This results in issues when
+writing OROM data into the structure.
+
+Add the __packed attribute to ensure the structure layout matches the
+expected binary format without padding.
+
+Fixes: 70db0788a262 ("ixgbe: read the OROM version information")
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c      | 2 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+index 71ea25de1bac7..754c176fd4a7a 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+@@ -3123,7 +3123,7 @@ static int ixgbe_get_orom_ver_info(struct ixgbe_hw *hw,
+       if (err)
+               return err;
+-      combo_ver = le32_to_cpu(civd.combo_ver);
++      combo_ver = get_unaligned_le32(&civd.combo_ver);
+       orom->major = (u8)FIELD_GET(IXGBE_OROM_VER_MASK, combo_ver);
+       orom->patch = (u8)FIELD_GET(IXGBE_OROM_VER_PATCH_MASK, combo_ver);
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h
+index 09df67f03cf47..38a41d81de0fa 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h
+@@ -1150,7 +1150,7 @@ struct ixgbe_orom_civd_info {
+       __le32 combo_ver;       /* Combo Image Version number */
+       u8 combo_name_len;      /* Length of the unicode combo image version string, max of 32 */
+       __le16 combo_name[32];  /* Unicode string representing the Combo Image version */
+-};
++} __packed;
+ /* Function specific capabilities */
+ struct ixgbe_hw_func_caps {
+-- 
+2.50.1
+
diff --git a/queue-6.16/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch b/queue-6.16/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch
new file mode 100644 (file)
index 0000000..17f0d5b
--- /dev/null
@@ -0,0 +1,112 @@
+From 38d1b038f519229ebb42c1ea1affc52ac3a7191b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 13:44:35 +0000
+Subject: l2tp: do not use sock_hold() in pppol2tp_session_get_sock()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9b8c88f875c04d4cb9111bd5dd9291c7e9691bf5 ]
+
+pppol2tp_session_get_sock() is using RCU, it must be ready
+for sk_refcnt being zero.
+
+Commit ee40fb2e1eb5 ("l2tp: protect sock pointer of
+struct pppol2tp_session with RCU") was correct because it
+had a call_rcu(..., pppol2tp_put_sk) which was later removed in blamed commit.
+
+pppol2tp_recv() can use pppol2tp_session_get_sock() as well.
+
+Fixes: c5cbaef992d6 ("l2tp: refactor ppp socket/session relationship")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Chapman <jchapman@katalix.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Link: https://patch.msgid.link/20250826134435.1683435-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_ppp.c | 25 ++++++++-----------------
+ 1 file changed, 8 insertions(+), 17 deletions(-)
+
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index fc5c2fd8f34c7..5e12e7ce17d8a 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -129,22 +129,12 @@ static const struct ppp_channel_ops pppol2tp_chan_ops = {
+ static const struct proto_ops pppol2tp_ops;
+-/* Retrieves the pppol2tp socket associated to a session.
+- * A reference is held on the returned socket, so this function must be paired
+- * with sock_put().
+- */
++/* Retrieves the pppol2tp socket associated to a session. */
+ static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session)
+ {
+       struct pppol2tp_session *ps = l2tp_session_priv(session);
+-      struct sock *sk;
+-
+-      rcu_read_lock();
+-      sk = rcu_dereference(ps->sk);
+-      if (sk)
+-              sock_hold(sk);
+-      rcu_read_unlock();
+-      return sk;
++      return rcu_dereference(ps->sk);
+ }
+ /* Helpers to obtain tunnel/session contexts from sockets.
+@@ -206,14 +196,13 @@ static int pppol2tp_recvmsg(struct socket *sock, struct msghdr *msg,
+ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
+ {
+-      struct pppol2tp_session *ps = l2tp_session_priv(session);
+-      struct sock *sk = NULL;
++      struct sock *sk;
+       /* If the socket is bound, send it in to PPP's input queue. Otherwise
+        * queue it on the session socket.
+        */
+       rcu_read_lock();
+-      sk = rcu_dereference(ps->sk);
++      sk = pppol2tp_session_get_sock(session);
+       if (!sk)
+               goto no_sock;
+@@ -510,13 +499,14 @@ static void pppol2tp_show(struct seq_file *m, void *arg)
+       struct l2tp_session *session = arg;
+       struct sock *sk;
++      rcu_read_lock();
+       sk = pppol2tp_session_get_sock(session);
+       if (sk) {
+               struct pppox_sock *po = pppox_sk(sk);
+               seq_printf(m, "   interface %s\n", ppp_dev_name(&po->chan));
+-              sock_put(sk);
+       }
++      rcu_read_unlock();
+ }
+ static void pppol2tp_session_init(struct l2tp_session *session)
+@@ -1530,6 +1520,7 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+               port = ntohs(inet->inet_sport);
+       }
++      rcu_read_lock();
+       sk = pppol2tp_session_get_sock(session);
+       if (sk) {
+               state = sk->sk_state;
+@@ -1565,8 +1556,8 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+               struct pppox_sock *po = pppox_sk(sk);
+               seq_printf(m, "   interface %s\n", ppp_dev_name(&po->chan));
+-              sock_put(sk);
+       }
++      rcu_read_unlock();
+ }
+ static int pppol2tp_seq_show(struct seq_file *m, void *v)
+-- 
+2.50.1
+
diff --git a/queue-6.16/misdn-hfcpci-fix-warning-when-deleting-uninitialized.patch b/queue-6.16/misdn-hfcpci-fix-warning-when-deleting-uninitialized.patch
new file mode 100644 (file)
index 0000000..15b2fc1
--- /dev/null
@@ -0,0 +1,104 @@
+From 1829c7b209ea7661fd39c8d960e072ec6060acd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 20:11:36 +0200
+Subject: mISDN: hfcpci: Fix warning when deleting uninitialized timer
+
+From: Vladimir Riabchun <ferr.lambarginio@gmail.com>
+
+[ Upstream commit 97766512a9951b9fd6fc97f1b93211642bb0b220 ]
+
+With CONFIG_DEBUG_OBJECTS_TIMERS unloading hfcpci module leads
+to the following splat:
+
+[  250.215892] ODEBUG: assert_init not available (active state 0) object: ffffffffc01a3dc0 object type: timer_list hint: 0x0
+[  250.217520] WARNING: CPU: 0 PID: 233 at lib/debugobjects.c:612 debug_print_object+0x1b6/0x2c0
+[  250.218775] Modules linked in: hfcpci(-) mISDN_core
+[  250.219537] CPU: 0 UID: 0 PID: 233 Comm: rmmod Not tainted 6.17.0-rc2-g6f713187ac98 #2 PREEMPT(voluntary)
+[  250.220940] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[  250.222377] RIP: 0010:debug_print_object+0x1b6/0x2c0
+[  250.223131] Code: fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 75 4f 41 56 48 8b 14 dd a0 4e 01 9f 48 89 ee 48 c7 c7 20 46 01 9f e8 cb 84d
+[  250.225805] RSP: 0018:ffff888015ea7c08 EFLAGS: 00010286
+[  250.226608] RAX: 0000000000000000 RBX: 0000000000000005 RCX: ffffffff9be93a95
+[  250.227708] RDX: 1ffff1100d945138 RSI: 0000000000000008 RDI: ffff88806ca289c0
+[  250.228993] RBP: ffffffff9f014a00 R08: 0000000000000001 R09: ffffed1002bd4f39
+[  250.230043] R10: ffff888015ea79cf R11: 0000000000000001 R12: 0000000000000001
+[  250.231185] R13: ffffffff9eea0520 R14: 0000000000000000 R15: ffff888015ea7cc8
+[  250.232454] FS:  00007f3208f01540(0000) GS:ffff8880caf5a000(0000) knlGS:0000000000000000
+[  250.233851] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  250.234856] CR2: 00007f32090a7421 CR3: 0000000004d63000 CR4: 00000000000006f0
+[  250.236117] Call Trace:
+[  250.236599]  <TASK>
+[  250.236967]  ? trace_irq_enable.constprop.0+0xd4/0x130
+[  250.237920]  debug_object_assert_init+0x1f6/0x310
+[  250.238762]  ? __pfx_debug_object_assert_init+0x10/0x10
+[  250.239658]  ? __lock_acquire+0xdea/0x1c70
+[  250.240369]  __try_to_del_timer_sync+0x69/0x140
+[  250.241172]  ? __pfx___try_to_del_timer_sync+0x10/0x10
+[  250.242058]  ? __timer_delete_sync+0xc6/0x120
+[  250.242842]  ? lock_acquire+0x30/0x80
+[  250.243474]  ? __timer_delete_sync+0xc6/0x120
+[  250.244262]  __timer_delete_sync+0x98/0x120
+[  250.245015]  HFC_cleanup+0x10/0x20 [hfcpci]
+[  250.245704]  __do_sys_delete_module+0x348/0x510
+[  250.246461]  ? __pfx___do_sys_delete_module+0x10/0x10
+[  250.247338]  do_syscall_64+0xc1/0x360
+[  250.247924]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fix this by initializing hfc_tl timer with DEFINE_TIMER macro.
+Also, use mod_timer instead of manual timeout update.
+
+Fixes: 87c5fa1bb426 ("mISDN: Add different different timer settings for hfc-pci")
+Fixes: 175302f6b79e ("mISDN: hfcpci: Fix use-after-free bug in hfcpci_softirq")
+Signed-off-by: Vladimir Riabchun <ferr.lambarginio@gmail.com>
+Link: https://patch.msgid.link/aKiy2D_LiWpQ5kXq@vova-pc
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/isdn/hardware/mISDN/hfcpci.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
+index 2b05722d4dbe8..ea8a0ab47afd8 100644
+--- a/drivers/isdn/hardware/mISDN/hfcpci.c
++++ b/drivers/isdn/hardware/mISDN/hfcpci.c
+@@ -39,12 +39,13 @@
+ #include "hfc_pci.h"
++static void hfcpci_softirq(struct timer_list *unused);
+ static const char *hfcpci_revision = "2.0";
+ static int HFC_cnt;
+ static uint debug;
+ static uint poll, tics;
+-static struct timer_list hfc_tl;
++static DEFINE_TIMER(hfc_tl, hfcpci_softirq);
+ static unsigned long hfc_jiffies;
+ MODULE_AUTHOR("Karsten Keil");
+@@ -2305,8 +2306,7 @@ hfcpci_softirq(struct timer_list *unused)
+               hfc_jiffies = jiffies + 1;
+       else
+               hfc_jiffies += tics;
+-      hfc_tl.expires = hfc_jiffies;
+-      add_timer(&hfc_tl);
++      mod_timer(&hfc_tl, hfc_jiffies);
+ }
+ static int __init
+@@ -2332,10 +2332,8 @@ HFC_init(void)
+       if (poll != HFCPCI_BTRANS_THRESHOLD) {
+               printk(KERN_INFO "%s: Using alternative poll value of %d\n",
+                      __func__, poll);
+-              timer_setup(&hfc_tl, hfcpci_softirq, 0);
+-              hfc_tl.expires = jiffies + tics;
+-              hfc_jiffies = hfc_tl.expires;
+-              add_timer(&hfc_tl);
++              hfc_jiffies = jiffies + tics;
++              mod_timer(&hfc_tl, hfc_jiffies);
+       } else
+               tics = 0; /* indicate the use of controller's timer */
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-dlink-fix-multicast-stats-being-counted-incorrec.patch b/queue-6.16/net-dlink-fix-multicast-stats-being-counted-incorrec.patch
new file mode 100644 (file)
index 0000000..744ac5d
--- /dev/null
@@ -0,0 +1,46 @@
+From 6b0c1bc755a9956062fe94d5bd766251e6c28769 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index da9b7715df050..f828f38cd7682 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1091,7 +1091,7 @@ get_stats (struct net_device *dev)
+       dev->stats.rx_bytes += dr32(OctetRcvOk);
+       dev->stats.tx_bytes += dr32(OctetXmtOk);
+-      dev->stats.multicast = dr32(McstFramesRcvdOk);
++      dev->stats.multicast += dr32(McstFramesRcvdOk);
+       dev->stats.collisions += dr32(SingleColFrames)
+                            +  dr32(MultiColFrames);
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch b/queue-6.16/net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch
new file mode 100644 (file)
index 0000000..1fd75d1
--- /dev/null
@@ -0,0 +1,122 @@
+From b91ffc09095d33e7d0ed1e1375b91bb7f9ea3892 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 04:56:27 -0700
+Subject: net: hv_netvsc: fix loss of early receive events from host during
+ channel open.
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 9448ccd853368582efa9db05db344f8bb9dffe0f ]
+
+The hv_netvsc driver currently enables NAPI after opening the primary and
+subchannels. This ordering creates a race: if the Hyper-V host places data
+in the host -> guest ring buffer and signals the channel before
+napi_enable() has been called, the channel callback will run but
+napi_schedule_prep() will return false. As a result, the NAPI poller never
+gets scheduled, the data in the ring buffer is not consumed, and the
+receive queue may remain permanently stuck until another interrupt happens
+to arrive.
+
+Fix this by enabling NAPI and registering it with the RX/TX queues before
+vmbus channel is opened. This guarantees that any early host signal after
+open will correctly trigger NAPI scheduling and the ring buffer will be
+drained.
+
+Fixes: 76bb5db5c749d ("netvsc: fix use after free on module removal")
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20250825115627.GA32189@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/netvsc.c       | 17 ++++++++---------
+ drivers/net/hyperv/rndis_filter.c | 23 ++++++++++++++++-------
+ 2 files changed, 24 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 720104661d7f2..60a4629fe6ba7 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1812,6 +1812,11 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+       /* Enable NAPI handler before init callbacks */
+       netif_napi_add(ndev, &net_device->chan_table[0].napi, netvsc_poll);
++      napi_enable(&net_device->chan_table[0].napi);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
++                           &net_device->chan_table[0].napi);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
++                           &net_device->chan_table[0].napi);
+       /* Open the channel */
+       device->channel->next_request_id_callback = vmbus_next_request_id;
+@@ -1831,12 +1836,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+       /* Channel is opened */
+       netdev_dbg(ndev, "hv_netvsc channel opened successfully\n");
+-      napi_enable(&net_device->chan_table[0].napi);
+-      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
+-                           &net_device->chan_table[0].napi);
+-      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
+-                           &net_device->chan_table[0].napi);
+-
+       /* Connect with the NetVsp */
+       ret = netvsc_connect_vsp(device, net_device, device_info);
+       if (ret != 0) {
+@@ -1854,14 +1853,14 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+ close:
+       RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
+-      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
+-      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
+-      napi_disable(&net_device->chan_table[0].napi);
+       /* Now, we can close the channel safely */
+       vmbus_close(device->channel);
+ cleanup:
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
++      netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
++      napi_disable(&net_device->chan_table[0].napi);
+       netif_napi_del(&net_device->chan_table[0].napi);
+ cleanup2:
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+index 9e73959e61ee0..c35f9685b6bf0 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1252,17 +1252,26 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+       new_sc->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes);
+       new_sc->max_pkt_size = NETVSC_MAX_PKT_SIZE;
++      /* Enable napi before opening the vmbus channel to avoid races
++       * as the host placing data on the host->guest ring may be left
++       * out if napi was not enabled.
++       */
++      napi_enable(&nvchan->napi);
++      netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++                           &nvchan->napi);
++      netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++                           &nvchan->napi);
++
+       ret = vmbus_open(new_sc, netvsc_ring_bytes,
+                        netvsc_ring_bytes, NULL, 0,
+                        netvsc_channel_cb, nvchan);
+-      if (ret == 0) {
+-              napi_enable(&nvchan->napi);
+-              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
+-                                   &nvchan->napi);
+-              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
+-                                   &nvchan->napi);
+-      } else {
++      if (ret != 0) {
+               netdev_notice(ndev, "sub channel open failed: %d\n", ret);
++              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++                                   NULL);
++              netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++                                   NULL);
++              napi_disable(&nvchan->napi);
+       }
+       if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn)
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-ipv4-fix-regression-in-local-broadcast-routes.patch b/queue-6.16/net-ipv4-fix-regression-in-local-broadcast-routes.patch
new file mode 100644 (file)
index 0000000..2ca3033
--- /dev/null
@@ -0,0 +1,57 @@
+From d9782636188e1f62d4cd5d8dbe706dfc2d95bec0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 7b8e80c4f1d98..bf82434c3541b 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2573,12 +2573,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+                   !netif_is_l3_master(dev_out))
+                       return ERR_PTR(-EINVAL);
+-      if (ipv4_is_lbcast(fl4->daddr))
++      if (ipv4_is_lbcast(fl4->daddr)) {
+               type = RTN_BROADCAST;
+-      else if (ipv4_is_multicast(fl4->daddr))
++
++              /* reset fi to prevent gateway resolution */
++              fi = NULL;
++      } else if (ipv4_is_multicast(fl4->daddr)) {
+               type = RTN_MULTICAST;
+-      else if (ipv4_is_zeronet(fl4->daddr))
++      } else if (ipv4_is_zeronet(fl4->daddr)) {
+               return ERR_PTR(-EINVAL);
++      }
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-macb-disable-clocks-once.patch b/queue-6.16/net-macb-disable-clocks-once.patch
new file mode 100644 (file)
index 0000000..3c5d480
--- /dev/null
@@ -0,0 +1,49 @@
+From b703a736b8f2b12f097cb66b5dafb77ebd64086b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 10:30:22 -0400
+Subject: net: macb: Disable clocks once
+
+From: Neil Mandir <neil.mandir@seco.com>
+
+[ Upstream commit dac978e51cce0c1f00a14c4a82f81d387f79b2d4 ]
+
+When the driver is removed the clocks are disabled twice: once in
+macb_remove and a second time by runtime pm. Disable wakeup in remove so
+all the clocks are disabled and skip the second call to macb_clks_disable.
+Always suspend the device as we always set it active in probe.
+
+Fixes: d54f89af6cc4 ("net: macb: Add pm runtime support")
+Signed-off-by: Neil Mandir <neil.mandir@seco.com>
+Co-developed-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Link: https://patch.msgid.link/20250826143022.935521-1-sean.anderson@linux.dev
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index 3cb50e5385d49..d949d2ba6cb9f 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5396,14 +5396,11 @@ static void macb_remove(struct platform_device *pdev)
+               mdiobus_unregister(bp->mii_bus);
+               mdiobus_free(bp->mii_bus);
++              device_set_wakeup_enable(&bp->pdev->dev, 0);
+               cancel_work_sync(&bp->hresp_err_bh_work);
+               pm_runtime_disable(&pdev->dev);
+               pm_runtime_dont_use_autosuspend(&pdev->dev);
+-              if (!pm_runtime_suspended(&pdev->dev)) {
+-                      macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk,
+-                                        bp->rx_clk, bp->tsu_clk);
+-                      pm_runtime_set_suspended(&pdev->dev);
+-              }
++              pm_runtime_set_suspended(&pdev->dev);
+               phylink_destroy(bp->phylink);
+               free_netdev(dev);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-macb-fix-offset-error-in-gem_update_stats.patch b/queue-6.16/net-macb-fix-offset-error-in-gem_update_stats.patch
new file mode 100644 (file)
index 0000000..dcfaaa6
--- /dev/null
@@ -0,0 +1,39 @@
+From 8b9d06182a3f8a7376da2ab4a399368497d5e016 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 13:21:34 -0400
+Subject: net: macb: Fix offset error in gem_update_stats
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit 16c8a3a67ec799fc731919e3e51be9af6cdf541d ]
+
+hw_stats now has only one variable for tx_octets/rx_octets, so we should
+only increment p once, not twice. This would cause the statistics to be
+reported under the wrong categories in `ethtool -S --all-groups` (which
+uses hw_stats) but not `ethtool -S` (which uses ethtool_stats).
+
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Fixes: f6af690a295a ("net: cadence: macb: Report standard stats")
+Link: https://patch.msgid.link/20250825172134.681861-1-sean.anderson@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index c1e904e4a01f4..3cb50e5385d49 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -3090,7 +3090,7 @@ static void gem_update_stats(struct macb *bp)
+                       /* Add GEM_OCTTXH, GEM_OCTRXH */
+                       val = bp->macb_reg_readl(bp, offset + 4);
+                       bp->ethtool_stats[i] += ((u64)val) << 32;
+-                      *(p++) += ((u64)val) << 32;
++                      *p += ((u64)val) << 32;
+               }
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-macb-fix-unregister_netdev-call-order-in-macb_re.patch b/queue-6.16/net-macb-fix-unregister_netdev-call-order-in-macb_re.patch
new file mode 100644 (file)
index 0000000..2a21d40
--- /dev/null
@@ -0,0 +1,63 @@
+From d010a9d7bef5b40cf6489d517fabf1c4257e548d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Aug 2025 07:25:27 +0800
+Subject: net: macb: fix unregister_netdev call order in macb_remove()
+
+From: luoguangfei <15388634752@163.com>
+
+[ Upstream commit 01b9128c5db1b470575d07b05b67ffa3cb02ebf1 ]
+
+When removing a macb device, the driver calls phy_exit() before
+unregister_netdev(). This leads to a WARN from kernfs:
+
+  ------------[ cut here ]------------
+  kernfs: can not remove 'attached_dev', no directory
+  WARNING: CPU: 1 PID: 27146 at fs/kernfs/dir.c:1683
+  Call trace:
+    kernfs_remove_by_name_ns+0xd8/0xf0
+    sysfs_remove_link+0x24/0x58
+    phy_detach+0x5c/0x168
+    phy_disconnect+0x4c/0x70
+    phylink_disconnect_phy+0x6c/0xc0 [phylink]
+    macb_close+0x6c/0x170 [macb]
+    ...
+    macb_remove+0x60/0x168 [macb]
+    platform_remove+0x5c/0x80
+    ...
+
+The warning happens because the PHY is being exited while the netdev
+is still registered. The correct order is to unregister the netdev
+before shutting down the PHY and cleaning up the MDIO bus.
+
+Fix this by moving unregister_netdev() ahead of phy_exit() in
+macb_remove().
+
+Fixes: 8b73fa3ae02b ("net: macb: Added ZynqMP-specific initialization")
+Signed-off-by: luoguangfei <15388634752@163.com>
+Link: https://patch.msgid.link/20250818232527.1316-1-15388634752@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index d1f1ae5ea161c..c1e904e4a01f4 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5391,11 +5391,11 @@ static void macb_remove(struct platform_device *pdev)
+       if (dev) {
+               bp = netdev_priv(dev);
++              unregister_netdev(dev);
+               phy_exit(bp->sgmii_phy);
+               mdiobus_unregister(bp->mii_bus);
+               mdiobus_free(bp->mii_bus);
+-              unregister_netdev(dev);
+               cancel_work_sync(&bp->hresp_err_bh_work);
+               pm_runtime_disable(&pdev->dev);
+               pm_runtime_dont_use_autosuspend(&pdev->dev);
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch b/queue-6.16/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
new file mode 100644 (file)
index 0000000..060712a
--- /dev/null
@@ -0,0 +1,259 @@
+From 281d01b35caaf4e893362835eee2e4855dbbd0ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:29 +0300
+Subject: net/mlx5: Fix lockdep assertion on sync reset unload event
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 902a8bc23a24882200f57cadc270e15a2cfaf2bb ]
+
+Fix lockdep assertion triggered during sync reset unload event. When the
+sync reset flow is initiated using the devlink reload fw_activate
+option, the PF already holds the devlink lock while handling unload
+event. In this case, delegate sync reset unload event handling back to
+the devlink callback process to avoid double-locking and resolve the
+lockdep warning.
+
+Kernel log:
+WARNING: CPU: 9 PID: 1578 at devl_assert_locked+0x31/0x40
+[...]
+Call Trace:
+<TASK>
+ mlx5_unload_one_devl_locked+0x2c/0xc0 [mlx5_core]
+ mlx5_sync_reset_unload_event+0xaf/0x2f0 [mlx5_core]
+ process_one_work+0x222/0x640
+ worker_thread+0x199/0x350
+ kthread+0x10b/0x230
+ ? __pfx_worker_thread+0x10/0x10
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x8e/0x100
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+</TASK>
+
+Fixes: 7a9770f1bfea ("net/mlx5: Handle sync reset unload event")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-7-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c |   2 +-
+ .../ethernet/mellanox/mlx5/core/fw_reset.c    | 120 ++++++++++--------
+ .../ethernet/mellanox/mlx5/core/fw_reset.h    |   1 +
+ 3 files changed, 69 insertions(+), 54 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 42c70862095e9..ca03dbcb07da0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+       if (err)
+               return err;
+-      mlx5_unload_one_devl_locked(dev, false);
++      mlx5_sync_reset_unload_flow(dev, true);
+       err = mlx5_health_wait_pci_up(dev);
+       if (err)
+               NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 69933addd921e..38b9b184ae01b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -12,7 +12,8 @@ enum {
+       MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+       MLX5_FW_RESET_FLAGS_PENDING_COMP,
+       MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+-      MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
++      MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
++      MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
+ };
+ struct mlx5_fw_reset {
+@@ -219,7 +220,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
+       return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false);
+ }
+-static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded)
++static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ {
+       struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
+       struct devlink *devlink = priv_to_devlink(dev);
+@@ -228,8 +229,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload
+       if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
+               complete(&fw_reset->done);
+       } else {
+-              if (!unloaded)
+-                      mlx5_unload_one(dev, false);
++              mlx5_sync_reset_unload_flow(dev, false);
+               if (mlx5_health_wait_pci_up(dev))
+                       mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+               else
+@@ -272,7 +272,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work)
+       mlx5_sync_reset_clear_reset_requested(dev, false);
+       mlx5_enter_error_state(dev, true);
+-      mlx5_fw_reset_complete_reload(dev, false);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ #define MLX5_RESET_POLL_INTERVAL      (HZ / 10)
+@@ -586,6 +586,65 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
+       return err;
+ }
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked)
++{
++      struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++      unsigned long timeout;
++      int poll_freq = 20;
++      bool reset_action;
++      u8 rst_state;
++      int err;
++
++      if (locked)
++              mlx5_unload_one_devl_locked(dev, false);
++      else
++              mlx5_unload_one(dev, false);
++
++      if (!test_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags))
++              return;
++
++      mlx5_set_fw_rst_ack(dev);
++      mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
++
++      reset_action = false;
++      timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
++      do {
++              rst_state = mlx5_get_fw_rst_state(dev);
++              if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
++                  rst_state == MLX5_FW_RST_STATE_IDLE) {
++                      reset_action = true;
++                      break;
++              }
++              if (rst_state == MLX5_FW_RST_STATE_DROP_MODE) {
++                      mlx5_core_info(dev, "Sync Reset Drop mode ack\n");
++                      mlx5_set_fw_rst_ack(dev);
++                      poll_freq = 1000;
++              }
++              msleep(poll_freq);
++      } while (!time_after(jiffies, timeout));
++
++      if (!reset_action) {
++              mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
++                            rst_state);
++              fw_reset->ret = -ETIMEDOUT;
++              goto done;
++      }
++
++      mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n",
++                     rst_state);
++      if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
++              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
++              if (err) {
++                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n",
++                                     err);
++                      fw_reset->ret = err;
++              }
++      }
++
++done:
++      clear_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+@@ -613,17 +672,13 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+       mlx5_enter_error_state(dev, true);
+ done:
+       fw_reset->ret = err;
+-      mlx5_fw_reset_complete_reload(dev, false);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset;
+       struct mlx5_core_dev *dev;
+-      unsigned long timeout;
+-      int poll_freq = 20;
+-      bool reset_action;
+-      u8 rst_state;
+       int err;
+       fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work);
+@@ -632,6 +687,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, false))
+               return;
++      set_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n");
+       err = mlx5_cmd_fast_teardown_hca(dev);
+@@ -640,49 +696,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+       else
+               mlx5_enter_error_state(dev, true);
+-      if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
+-              mlx5_unload_one_devl_locked(dev, false);
+-      else
+-              mlx5_unload_one(dev, false);
+-
+-      mlx5_set_fw_rst_ack(dev);
+-      mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
+-
+-      reset_action = false;
+-      timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
+-      do {
+-              rst_state = mlx5_get_fw_rst_state(dev);
+-              if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
+-                  rst_state == MLX5_FW_RST_STATE_IDLE) {
+-                      reset_action = true;
+-                      break;
+-              }
+-              if (rst_state == MLX5_FW_RST_STATE_DROP_MODE) {
+-                      mlx5_core_info(dev, "Sync Reset Drop mode ack\n");
+-                      mlx5_set_fw_rst_ack(dev);
+-                      poll_freq = 1000;
+-              }
+-              msleep(poll_freq);
+-      } while (!time_after(jiffies, timeout));
+-
+-      if (!reset_action) {
+-              mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
+-                            rst_state);
+-              fw_reset->ret = -ETIMEDOUT;
+-              goto done;
+-      }
+-
+-      mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
+-      if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+-              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+-              if (err) {
+-                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
+-                      fw_reset->ret = err;
+-              }
+-      }
+-
+-done:
+-      mlx5_fw_reset_complete_reload(dev, true);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index ea527d06a85f0..d5b28525c960d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -12,6 +12,7 @@ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+ int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev,
+                                    struct netlink_ext_ack *extack);
+ void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev);
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5-hws-fix-memory-leak-in-hws_action_get_share.patch b/queue-6.16/net-mlx5-hws-fix-memory-leak-in-hws_action_get_share.patch
new file mode 100644 (file)
index 0000000..cb11784
--- /dev/null
@@ -0,0 +1,43 @@
+From 33771cea1d889a84185b92f2898522d15ff9be36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:25 +0300
+Subject: net/mlx5: HWS, Fix memory leak in hws_action_get_shared_stc_nic error
+ flow
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit a630f83592cdad1253523a1b760cfe78fef6cd9c ]
+
+When an invalid stc_type is provided, the function allocates memory for
+shared_stc but jumps to unlock_and_out without freeing it, causing a
+memory leak.
+
+Fix by jumping to free_shared_stc label instead to ensure proper cleanup.
+
+Fixes: 504e536d9010 ("net/mlx5: HWS, added actions handling")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-3-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
+index 447ea3f8722ce..8e4a085f4a2ec 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
+@@ -117,7 +117,7 @@ static int hws_action_get_shared_stc_nic(struct mlx5hws_context *ctx,
+               mlx5hws_err(ctx, "No such stc_type: %d\n", stc_type);
+               pr_warn("HWS: Invalid stc_type: %d\n", stc_type);
+               ret = -EINVAL;
+-              goto unlock_and_out;
++              goto free_shared_stc;
+       }
+       ret = mlx5hws_action_alloc_single_stc(ctx, &stc_attr, tbl_type,
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5-hws-fix-memory-leak-in-hws_pool_buddy_init-.patch b/queue-6.16/net-mlx5-hws-fix-memory-leak-in-hws_pool_buddy_init-.patch
new file mode 100644 (file)
index 0000000..a322d23
--- /dev/null
@@ -0,0 +1,40 @@
+From e9ade0be9921b5663a464f3185d1ead12186db04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:24 +0300
+Subject: net/mlx5: HWS, Fix memory leak in hws_pool_buddy_init error path
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit 2c0a959bebdc1ada13cf9a8242f177c5400299e6 ]
+
+In the error path of hws_pool_buddy_init(), the buddy allocator cleanup
+doesn't free the allocator structure itself, causing a memory leak.
+
+Add the missing kfree() to properly release all allocated memory.
+
+Fixes: c61afff94373 ("net/mlx5: HWS, added memory management handling")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-2-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
+index 7e37d6e9eb836..7b5071c3df368 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
+@@ -124,6 +124,7 @@ static int hws_pool_buddy_init(struct mlx5hws_pool *pool)
+               mlx5hws_err(pool->ctx, "Failed to create resource type: %d size %zu\n",
+                           pool->type, pool->alloc_log_sz);
+               mlx5hws_buddy_cleanup(buddy);
++              kfree(buddy);
+               return -ENOMEM;
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5-hws-fix-pattern-destruction-in-mlx5hws_pat_.patch b/queue-6.16/net-mlx5-hws-fix-pattern-destruction-in-mlx5hws_pat_.patch
new file mode 100644 (file)
index 0000000..198e850
--- /dev/null
@@ -0,0 +1,50 @@
+From 5bab21b73b609b4281b26bfaf50c90fd54eabd62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:27 +0300
+Subject: net/mlx5: HWS, Fix pattern destruction in mlx5hws_pat_get_pattern
+ error path
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit 00a50e4e8974cbf5d6a1dc91cfa5cce4aa7af05a ]
+
+In mlx5hws_pat_get_pattern(), when mlx5hws_pat_add_pattern_to_cache()
+fails, the function attempts to clean up the pattern created by
+mlx5hws_cmd_header_modify_pattern_create(). However, it incorrectly
+uses *pattern_id which hasn't been set yet, instead of the local
+ptrn_id variable that contains the actual pattern ID.
+
+This results in attempting to destroy a pattern using uninitialized
+data from the output parameter, rather than the valid pattern ID
+returned by the firmware.
+
+Use ptrn_id instead of *pattern_id in the cleanup path to properly
+destroy the created pattern.
+
+Fixes: aefc15a0fa1c ("net/mlx5: HWS, added modify header pattern and args handling")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-5-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
+index 622fd579f1407..d56271a9e4f01 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
+@@ -279,7 +279,7 @@ int mlx5hws_pat_get_pattern(struct mlx5hws_context *ctx,
+       return ret;
+ clean_pattern:
+-      mlx5hws_cmd_header_modify_pattern_destroy(ctx->mdev, *pattern_id);
++      mlx5hws_cmd_header_modify_pattern_destroy(ctx->mdev, ptrn_id);
+ out_unlock:
+       mutex_unlock(&ctx->pattern_cache->lock);
+       return ret;
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5-hws-fix-uninitialized-variables-in-mlx5hws_.patch b/queue-6.16/net-mlx5-hws-fix-uninitialized-variables-in-mlx5hws_.patch
new file mode 100644 (file)
index 0000000..7388e5a
--- /dev/null
@@ -0,0 +1,55 @@
+From b52c3d3d4495e8a6f23fbe6aa141d7a38f758288 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:26 +0300
+Subject: net/mlx5: HWS, Fix uninitialized variables in mlx5hws_pat_calc_nop
+ error flow
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit 24b6e53140475b56cadcccd4e82a93aa5bacf1eb ]
+
+In mlx5hws_pat_calc_nop(), src_field and dst_field are passed to
+hws_action_modify_get_target_fields() which should set their values.
+However, if an invalid action type is encountered, these variables
+remain uninitialized and are later used to update prev_src_field
+and prev_dst_field.
+
+Initialize both variables to INVALID_FIELD to ensure they have
+defined values in all code paths.
+
+Fixes: 01e035fd0380 ("net/mlx5: HWS, handle modify header actions dependency")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-4-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c    | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
+index 51e4c551e0efd..622fd579f1407 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
+@@ -527,7 +527,6 @@ int mlx5hws_pat_calc_nop(__be64 *pattern, size_t num_actions,
+                        u32 *nop_locations, __be64 *new_pat)
+ {
+       u16 prev_src_field = INVALID_FIELD, prev_dst_field = INVALID_FIELD;
+-      u16 src_field, dst_field;
+       u8 action_type;
+       bool dependent;
+       size_t i, j;
+@@ -539,6 +538,9 @@ int mlx5hws_pat_calc_nop(__be64 *pattern, size_t num_actions,
+               return 0;
+       for (i = 0, j = 0; i < num_actions; i++, j++) {
++              u16 src_field = INVALID_FIELD;
++              u16 dst_field = INVALID_FIELD;
++
+               if (j >= max_actions)
+                       return -EINVAL;
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5-nack-sync-reset-when-sfs-are-present.patch b/queue-6.16/net-mlx5-nack-sync-reset-when-sfs-are-present.patch
new file mode 100644 (file)
index 0000000..5b39a42
--- /dev/null
@@ -0,0 +1,100 @@
+From 05d9daaf424c0a3fd15abd814a683e4f5889a7d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:30 +0300
+Subject: net/mlx5: Nack sync reset when SFs are present
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 26e42ec7712d392d561964514b1f253b1a96f42d ]
+
+If PF (Physical Function) has SFs (Sub-Functions), since the SFs are not
+taking part in the synchronization flow, sync reset can lead to fatal
+error on the SFs, as the function will be closed unexpectedly from the
+SF point of view.
+
+Add a check to prevent sync reset when there are SFs on a PF device
+which is not ECPF, as ECPF is teardowned gracefully before reset.
+
+Fixes: 92501fa6e421 ("net/mlx5: Ack on sync_reset_request only if PF can do reset_now")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-8-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c   |  6 ++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 10 ++++++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h      |  6 ++++++
+ 3 files changed, 22 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 38b9b184ae01b..22995131824a0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -6,6 +6,7 @@
+ #include "fw_reset.h"
+ #include "diag/fw_tracer.h"
+ #include "lib/tout.h"
++#include "sf/sf.h"
+ enum {
+       MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+@@ -428,6 +429,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev,
+               return false;
+       }
++      if (!mlx5_core_is_ecpf(dev) && !mlx5_sf_table_empty(dev)) {
++              mlx5_core_warn(dev, "SFs should be removed before reset\n");
++              return false;
++      }
++
+ #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)
+       if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) {
+               err = mlx5_check_hotplug_interrupt(dev, bridge);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index 0864ba625c07d..3304f25cc8055 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -518,3 +518,13 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+       WARN_ON(!xa_empty(&table->function_ids));
+       kfree(table);
+ }
++
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++      struct mlx5_sf_table *table = dev->priv.sf_table;
++
++      if (!table)
++              return true;
++
++      return xa_empty(&table->function_ids);
++}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+index 860f9ddb7107b..89559a37997ad 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+@@ -17,6 +17,7 @@ void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev);
+ int mlx5_sf_table_init(struct mlx5_core_dev *dev);
+ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev);
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev);
+ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+                            const struct devlink_port_new_attrs *add_attr,
+@@ -61,6 +62,11 @@ static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ {
+ }
++static inline bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++      return true;
++}
++
+ #endif
+ #endif
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5-prevent-flow-steering-mode-changes-in-switc.patch b/queue-6.16/net-mlx5-prevent-flow-steering-mode-changes-in-switc.patch
new file mode 100644 (file)
index 0000000..c274bc4
--- /dev/null
@@ -0,0 +1,59 @@
+From d879216ed12f956d2f9bedd42664259713764d4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:31 +0300
+Subject: net/mlx5: Prevent flow steering mode changes in switchdev mode
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit cf9a8627b9a369ba01d37be6f71b297beb688faa ]
+
+Changing flow steering modes is not allowed when eswitch is in switchdev
+mode. This fix ensures that any steering mode change, including to
+firmware steering, is correctly blocked while eswitch mode is switchdev.
+
+Fixes: e890acd5ff18 ("net/mlx5: Add devlink flow_steering_mode parameter")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-9-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+index 3dd9a6f407092..29ce09af59aef 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+@@ -3706,6 +3706,13 @@ static int mlx5_fs_mode_validate(struct devlink *devlink, u32 id,
+       char *value = val.vstr;
+       u8 eswitch_mode;
++      eswitch_mode = mlx5_eswitch_mode(dev);
++      if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
++              NL_SET_ERR_MSG_FMT_MOD(extack,
++                                     "Changing fs mode is not supported when eswitch offloads enabled.");
++              return -EOPNOTSUPP;
++      }
++
+       if (!strcmp(value, "dmfs"))
+               return 0;
+@@ -3731,14 +3738,6 @@ static int mlx5_fs_mode_validate(struct devlink *devlink, u32 id,
+               return -EINVAL;
+       }
+-      eswitch_mode = mlx5_eswitch_mode(dev);
+-      if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
+-              NL_SET_ERR_MSG_FMT_MOD(extack,
+-                                     "Moving to %s is not supported when eswitch offloads enabled.",
+-                                     value);
+-              return -EOPNOTSUPP;
+-      }
+-
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch b/queue-6.16/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
new file mode 100644 (file)
index 0000000..489d65e
--- /dev/null
@@ -0,0 +1,51 @@
+From 310697ae325b9272c640c1a2dd619dc6f61f11ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:28 +0300
+Subject: net/mlx5: Reload auxiliary drivers on fw_activate
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 34cc6a54914f478c93e176450fae6313404f9f74 ]
+
+The devlink reload fw_activate command performs firmware activation
+followed by driver reload, while devlink reload driver_reinit triggers
+only driver reload. However, the driver reload logic differs between the
+two modes, as on driver_reinit mode mlx5 also reloads auxiliary drivers,
+while in fw_activate mode the auxiliary drivers are suspended where
+applicable.
+
+Additionally, following the cited commit, if the device has multiple PFs,
+the behavior during fw_activate may vary between PFs: one PF may suspend
+auxiliary drivers, while another reloads them.
+
+Align devlink dev reload fw_activate behavior with devlink dev reload
+driver_reinit, to reload all auxiliary drivers.
+
+Fixes: 72ed5d5624af ("net/mlx5: Suspend auxiliary devices only in case of PCI device suspend")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 73cd746443788..42c70862095e9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+       if (err)
+               return err;
+-      mlx5_unload_one_devl_locked(dev, true);
++      mlx5_unload_one_devl_locked(dev, false);
+       err = mlx5_health_wait_pci_up(dev);
+       if (err)
+               NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5e-set-local-xoff-after-fw-update.patch b/queue-6.16/net-mlx5e-set-local-xoff-after-fw-update.patch
new file mode 100644 (file)
index 0000000..04bb81e
--- /dev/null
@@ -0,0 +1,50 @@
+From 1a5f7b91dfb061c7f29c4ef835799f17b393c8e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+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 3efa8bf1d14ef..4720523813b97 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -575,7 +575,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+               if (err)
+                       return err;
+       }
+-      priv->dcbx.xoff = xoff;
+       /* Apply the settings */
+       if (update_buffer) {
+@@ -584,6 +583,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                       return err;
+       }
++      priv->dcbx.xoff = xoff;
++
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch b/queue-6.16/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
new file mode 100644 (file)
index 0000000..abc4a06
--- /dev/null
@@ -0,0 +1,100 @@
+From 784a79caec6b854bee33120df11512feea4c406c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h         | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c   | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+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 f4a19ffbb641c..66d276a1be836 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -66,11 +66,23 @@ struct mlx5e_port_buffer {
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_NETWORK_BUFFER];
+ };
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++                              u32 change, unsigned int mtu,
++                              void *pfc,
++                              u32 *buffer_size,
++                              u8 *prio2buffer)
++{
++      return 0;
++}
++#endif
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 16d818943487b..f0142d32b648f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -48,6 +48,7 @@
+ #include "en.h"
+ #include "en/dim.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2985,9 +2986,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+       struct mlx5e_params *params = &priv->channels.params;
+       struct net_device *netdev = priv->netdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
+-      u16 mtu;
++      u16 mtu, prev_mtu;
+       int err;
++      mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+       err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+       if (err)
+               return err;
+@@ -2997,6 +3000,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+               netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+                           __func__, mtu, params->sw_mtu);
++      if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++              err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++                                                    NULL, NULL, NULL);
++              if (err) {
++                      netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++                                  __func__, mtu, err, prev_mtu);
++
++                      mlx5e_set_mtu(mdev, params, prev_mtu);
++                      return err;
++              }
++      }
++
+       params->sw_mtu = mtu;
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch b/queue-6.16/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
new file mode 100644 (file)
index 0000000..195199c
--- /dev/null
@@ -0,0 +1,46 @@
+From 0f30b7f9a5dfe4a88629518119b3fa45cfaaa66f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index f0142d32b648f..e39c51cfc8e6c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -136,6 +136,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+       if (up) {
+               netdev_info(priv->netdev, "Link up\n");
+               netif_carrier_on(priv->netdev);
++              mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++                                              NULL, NULL, NULL);
+       } else {
+               netdev_info(priv->netdev, "Link down\n");
+               netif_carrier_off(priv->netdev);
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-rose-convert-use-field-to-refcount_t.patch b/queue-6.16/net-rose-convert-use-field-to-refcount_t.patch
new file mode 100644 (file)
index 0000000..2c67cac
--- /dev/null
@@ -0,0 +1,370 @@
+From ef9af2c7c72b0ddc7509ef210721ac47284b540d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:56 +0900
+Subject: net: rose: convert 'use' field to refcount_t
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit d860d1faa6b2ce3becfdb8b0c2b048ad31800061 ]
+
+The 'use' field in struct rose_neigh is used as a reference counter but
+lacks atomicity. This can lead to race conditions where a rose_neigh
+structure is freed while still being referenced by other code paths.
+
+For example, when rose_neigh->use becomes zero during an ioctl operation
+via rose_rt_ioctl(), the structure may be removed while its timer is
+still active, potentially causing use-after-free issues.
+
+This patch changes the type of 'use' from unsigned short to refcount_t and
+updates all code paths to use rose_neigh_hold() and rose_neigh_put() which
+operate reference counts atomically.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-3-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h    | 18 +++++++++++++-----
+ net/rose/af_rose.c    | 13 +++++++------
+ net/rose/rose_in.c    | 12 ++++++------
+ net/rose/rose_route.c | 33 ++++++++++++++++++---------------
+ net/rose/rose_timer.c |  2 +-
+ 5 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 174b4f605d849..2b5491bbf39ab 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H 
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+       ax25_cb                 *ax25;
+       struct net_device               *dev;
+       unsigned short          count;
+-      unsigned short          use;
++      refcount_t              use;
+       unsigned int            number;
+       char                    restarted;
+       char                    dce_mode;
+@@ -151,12 +152,19 @@ struct rose_sock {
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++      refcount_inc(&rose_neigh->use);
++}
++
+ static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
+ {
+-      if (rose_neigh->ax25)
+-              ax25_cb_put(rose_neigh->ax25);
+-      kfree(rose_neigh->digipeat);
+-      kfree(rose_neigh);
++      if (refcount_dec_and_test(&rose_neigh->use)) {
++              if (rose_neigh->ax25)
++                      ax25_cb_put(rose_neigh->ax25);
++              kfree(rose_neigh->digipeat);
++              kfree(rose_neigh);
++      }
+ }
+ /* af_rose.c */
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index 4e72b636a46a5..543f9e8ebb693 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+               if (rose->neighbour == neigh) {
+                       rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour = NULL;
+               }
+       }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+               if (rose->device == dev) {
+                       rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+                       if (rose->neighbour)
+-                              rose->neighbour->use--;
++                              rose_neigh_put(rose->neighbour);
+                       netdev_put(rose->device, &rose->dev_tracker);
+                       rose->device = NULL;
+               }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+               break;
+       case ROSE_STATE_2:
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               release_sock(sk);
+               rose_disconnect(sk, 0, -1, -1);
+               lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       rose->lci = rose_new_lci(rose->neighbour);
+       if (!rose->lci) {
+               err = -ENETUNREACH;
++              rose_neigh_put(rose->neighbour);
+               goto out_release;
+       }
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+               dev = rose_dev_first();
+               if (!dev) {
+                       err = -ENETUNREACH;
++                      rose_neigh_put(rose->neighbour);
+                       goto out_release;
+               }
+               user = ax25_findbyuid(current_euid());
+               if (!user) {
+                       err = -EINVAL;
++                      rose_neigh_put(rose->neighbour);
+                       dev_put(dev);
+                       goto out_release;
+               }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       rose->state = ROSE_STATE_1;
+-      rose->neighbour->use++;
+-
+       rose_write_internal(sk, ROSE_CALL_REQUEST);
+       rose_start_heartbeat(sk);
+       rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
+                            GFP_ATOMIC);
+       make_rose->facilities    = facilities;
+-      make_rose->neighbour->use++;
++      rose_neigh_hold(make_rose->neighbour);
+       if (rose_sk(sk)->defer) {
+               make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b4..7caae93937ee9 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       case ROSE_CLEAR_CONFIRMATION:
+               rose_disconnect(sk, 0, -1, -1);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety
+       if (frametype == ROSE_CLEAR_REQUEST) {
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose_sk(sk)->neighbour->use--;
++              rose_neigh_put(rose_sk(sk)->neighbour);
+       }
+       return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 0c44c416f4853..8efb9033c057c 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+               rose_neigh->ax25      = NULL;
+               rose_neigh->dev       = dev;
+               rose_neigh->count     = 0;
+-              rose_neigh->use       = 0;
+               rose_neigh->dce_mode  = 0;
+               rose_neigh->loopback  = 0;
+               rose_neigh->number    = rose_neigh_no++;
+               rose_neigh->restarted = 0;
++              refcount_set(&rose_neigh->use, 1);
+               skb_queue_head_init(&rose_neigh->queue);
+@@ -255,10 +255,10 @@ static void rose_remove_route(struct rose_route *rose_route)
+       struct rose_route *s;
+       if (rose_route->neigh1 != NULL)
+-              rose_route->neigh1->use--;
++              rose_neigh_put(rose_route->neigh1);
+       if (rose_route->neigh2 != NULL)
+-              rose_route->neigh2->use--;
++              rose_neigh_put(rose_route->neigh2);
+       if ((s = rose_route_list) == rose_route) {
+               rose_route_list = rose_route->next;
+@@ -323,7 +323,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0) {
++                      if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
+                               rose_neigh_put(rose_neigh);
+                       }
+@@ -375,11 +375,11 @@ void rose_add_loopback_neigh(void)
+       sn->ax25      = NULL;
+       sn->dev       = NULL;
+       sn->count     = 0;
+-      sn->use       = 0;
+       sn->dce_mode  = 1;
+       sn->loopback  = 1;
+       sn->number    = rose_neigh_no++;
+       sn->restarted = 1;
++      refcount_set(&sn->use, 1);
+       skb_queue_head_init(&sn->queue);
+@@ -561,8 +561,7 @@ static int rose_clear_routes(void)
+               s          = rose_neigh;
+               rose_neigh = rose_neigh->next;
+-              if (s->use == 0 && !s->loopback) {
+-                      s->count = 0;
++              if (!s->loopback) {
+                       rose_remove_neigh(s);
+                       rose_neigh_put(s);
+               }
+@@ -680,6 +679,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+                       for (i = 0; i < node->count; i++) {
+                               if (node->neighbour[i]->restarted) {
+                                       res = node->neighbour[i];
++                                      rose_neigh_hold(node->neighbour[i]);
+                                       goto out;
+                               }
+                       }
+@@ -691,6 +691,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+                               for (i = 0; i < node->count; i++) {
+                                       if (!rose_ftimer_running(node->neighbour[i])) {
+                                               res = node->neighbour[i];
++                                              rose_neigh_hold(node->neighbour[i]);
+                                               goto out;
+                                       }
+                                       failed = 1;
+@@ -780,13 +781,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
+               }
+               if (rose_route->neigh1 == rose_neigh) {
+-                      rose_route->neigh1->use--;
++                      rose_neigh_put(rose_route->neigh1);
+                       rose_route->neigh1 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+               }
+               if (rose_route->neigh2 == rose_neigh) {
+-                      rose_route->neigh2->use--;
++                      rose_neigh_put(rose_route->neigh2);
+                       rose_route->neigh2 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+               }
+@@ -915,7 +916,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+                       rose_clear_queues(sk);
+                       rose->cause      = ROSE_NETWORK_CONGESTION;
+                       rose->diagnostic = 0;
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour  = NULL;
+                       rose->lci        = 0;
+                       rose->state      = ROSE_STATE_0;
+@@ -1040,12 +1041,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+               rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
+-              goto out;
++              goto put_neigh;
+       }
+       if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+               rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+-              goto out;
++              goto put_neigh;
+       }
+       rose_route->lci1      = lci;
+@@ -1058,8 +1059,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_route->lci2      = new_lci;
+       rose_route->neigh2    = new_neigh;
+-      rose_route->neigh1->use++;
+-      rose_route->neigh2->use++;
++      rose_neigh_hold(rose_route->neigh1);
++      rose_neigh_hold(rose_route->neigh2);
+       rose_route->next = rose_route_list;
+       rose_route_list  = rose_route;
+@@ -1071,6 +1072,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_transmit_link(skb, rose_route->neigh2);
+       res = 1;
++put_neigh:
++      rose_neigh_put(new_neigh);
+ out:
+       spin_unlock_bh(&rose_route_list_lock);
+       spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1186,7 +1189,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         rose_neigh->use,
++                         refcount_read(&rose_neigh->use) - 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 020369c49587f..bb60a1654d612 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+               break;
+       case ROSE_STATE_2:      /* T3 */
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               rose_disconnect(sk, ETIMEDOUT, -1, -1);
+               break;
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-rose-include-node-references-in-rose_neigh-refco.patch b/queue-6.16/net-rose-include-node-references-in-rose_neigh-refco.patch
new file mode 100644 (file)
index 0000000..e4eb8d2
--- /dev/null
@@ -0,0 +1,142 @@
+From ca4b6653dbe36488e0e6e4174ff6c19817d58eb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:57 +0900
+Subject: net: rose: include node references in rose_neigh refcount
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit da9c9c877597170b929a6121a68dcd3dd9a80f45 ]
+
+Current implementation maintains two separate reference counting
+mechanisms: the 'count' field in struct rose_neigh tracks references from
+rose_node structures, while the 'use' field (now refcount_t) tracks
+references from rose_sock.
+
+This patch merges these two reference counting systems using 'use' field
+for proper reference management. Specifically, this patch adds incrementing
+and decrementing of rose_neigh->use when rose_neigh->count is incremented
+or decremented.
+
+This patch also modifies rose_rt_free(), rose_rt_device_down() and
+rose_clear_route() to properly release references to rose_neigh objects
+before freeing a rose_node through rose_remove_node().
+
+These changes ensure rose_neigh structures are properly freed only when
+all references, including those from rose_node structures, are released.
+As a result, this resolves a slab-use-after-free issue reported by Syzbot.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+942297eecf7d2d61d1f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=942297eecf7d2d61d1f1
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-4-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/rose_route.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 8efb9033c057c..1adee1fbc2ed1 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+                       }
+               }
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+               goto out;
+       }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+               rose_node->neighbour[rose_node->count] = rose_neigh;
+               rose_node->count++;
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+       }
+ out:
+@@ -322,6 +324,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+       for (i = 0; i < rose_node->count; i++) {
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
++                      rose_neigh_put(rose_neigh);
+                       if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
+@@ -430,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+       rose_node_list  = rose_node;
+       rose_loopback_neigh->count++;
++      rose_neigh_hold(rose_loopback_neigh);
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -461,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+       rose_remove_node(rose_node);
+       rose_loopback_neigh->count--;
++      rose_neigh_put(rose_loopback_neigh);
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -500,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+                               memmove(&t->neighbour[i], &t->neighbour[i + 1],
+                                       sizeof(t->neighbour[0]) *
+                                               (t->count - i));
++                              rose_neigh_put(s);
+                       }
+                       if (t->count <= 0)
+@@ -543,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+       struct rose_neigh *s, *rose_neigh;
+       struct rose_node  *t, *rose_node;
++      int i;
+       spin_lock_bh(&rose_node_list_lock);
+       spin_lock_bh(&rose_neigh_list_lock);
+@@ -553,8 +560,12 @@ static int rose_clear_routes(void)
+       while (rose_node != NULL) {
+               t         = rose_node;
+               rose_node = rose_node->next;
+-              if (!t->loopback)
++
++              if (!t->loopback) {
++                      for (i = 0; i < rose_node->count; i++)
++                              rose_neigh_put(t->neighbour[i]);
+                       rose_remove_node(t);
++              }
+       }
+       while (rose_neigh != NULL) {
+@@ -1189,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         refcount_read(&rose_neigh->use) - 1,
++                         refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1294,6 +1305,7 @@ void __exit rose_rt_free(void)
+       struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+       struct rose_node  *t, *rose_node  = rose_node_list;
+       struct rose_route *u, *rose_route = rose_route_list;
++      int i;
+       while (rose_neigh != NULL) {
+               s          = rose_neigh;
+@@ -1307,6 +1319,8 @@ void __exit rose_rt_free(void)
+               t         = rose_node;
+               rose_node = rose_node->next;
++              for (i = 0; i < t->count; i++)
++                      rose_neigh_put(t->neighbour[i]);
+               rose_remove_node(t);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-rose-split-remove-and-free-operations-in-rose_re.patch b/queue-6.16/net-rose-split-remove-and-free-operations-in-rose_re.patch
new file mode 100644 (file)
index 0000000..ec2df9f
--- /dev/null
@@ -0,0 +1,115 @@
+From 4487615c0f452d270b59460ed8ef914d2d8e035b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:55 +0900
+Subject: net: rose: split remove and free operations in rose_remove_neigh()
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit dcb34659028f856c423a29ef9b4e2571d203444d ]
+
+The current rose_remove_neigh() performs two distinct operations:
+1. Removes rose_neigh from rose_neigh_list
+2. Frees the rose_neigh structure
+
+Split these operations into separate functions to improve maintainability
+and prepare for upcoming refcount_t conversion. The timer cleanup remains
+in rose_remove_neigh() because free operations can be called from timer
+itself.
+
+This patch introduce rose_neigh_put() to handle the freeing of rose_neigh
+structures and modify rose_remove_neigh() to handle removal only.
+
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-2-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h    |  8 ++++++++
+ net/rose/rose_route.c | 15 ++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa3..174b4f605d849 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -151,6 +151,14 @@ struct rose_sock {
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++      if (rose_neigh->ax25)
++              ax25_cb_put(rose_neigh->ax25);
++      kfree(rose_neigh->digipeat);
++      kfree(rose_neigh);
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int  sysctl_rose_restart_request_timeout;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index b72bf8a08d489..0c44c416f4853 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,20 +234,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+       if ((s = rose_neigh_list) == rose_neigh) {
+               rose_neigh_list = rose_neigh->next;
+-              if (rose_neigh->ax25)
+-                      ax25_cb_put(rose_neigh->ax25);
+-              kfree(rose_neigh->digipeat);
+-              kfree(rose_neigh);
+               return;
+       }
+       while (s != NULL && s->next != NULL) {
+               if (s->next == rose_neigh) {
+                       s->next = rose_neigh->next;
+-                      if (rose_neigh->ax25)
+-                              ax25_cb_put(rose_neigh->ax25);
+-                      kfree(rose_neigh->digipeat);
+-                      kfree(rose_neigh);
+                       return;
+               }
+@@ -331,8 +323,10 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0)
++                      if (rose_neigh->count == 0 && rose_neigh->use == 0) {
+                               rose_remove_neigh(rose_neigh);
++                              rose_neigh_put(rose_neigh);
++                      }
+                       rose_node->count--;
+@@ -513,6 +507,7 @@ void rose_rt_device_down(struct net_device *dev)
+               }
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       spin_unlock_bh(&rose_neigh_list_lock);
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -569,6 +564,7 @@ static int rose_clear_routes(void)
+               if (s->use == 0 && !s->loopback) {
+                       s->count = 0;
+                       rose_remove_neigh(s);
++                      rose_neigh_put(s);
+               }
+       }
+@@ -1301,6 +1297,7 @@ void __exit rose_rt_free(void)
+               rose_neigh = rose_neigh->next;
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       while (rose_node != NULL) {
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch b/queue-6.16/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
new file mode 100644 (file)
index 0000000..0efaaf0
--- /dev/null
@@ -0,0 +1,68 @@
+From 8aaa1bd4504f820f97e1827466d72d86c2058d4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:54 +0800
+Subject: net: stmmac: Set CIC bit only for TX queues with COE
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit b1eded580ab28119de0b0f21efe37ee2b4419144 ]
+
+Currently, in the AF_XDP transmit paths, the CIC bit of
+TX Desc3 is set for all packets. Setting this bit for
+packets transmitting through queues that don't support
+checksum offloading causes the TX DMA to get stuck after
+transmitting some packets. This patch ensures the CIC bit
+of TX Desc3 is set only if the TX queue supports checksum
+offloading.
+
+Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-3-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index e0fb06af1f940..36082d4917bcc 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2584,6 +2584,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+       struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
+       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
+       struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
++      bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+       struct xsk_buff_pool *pool = tx_q->xsk_pool;
+       unsigned int entry = tx_q->cur_tx;
+       struct dma_desc *tx_desc = NULL;
+@@ -2671,7 +2672,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+               }
+               stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
+-                                     true, priv->mode, true, true,
++                                     csum, priv->mode, true, true,
+                                      xdp_desc.len);
+               stmmac_enable_dma_transmission(priv, priv->ioaddr, queue);
+@@ -4983,6 +4984,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ {
+       struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
+       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
++      bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+       unsigned int entry = tx_q->cur_tx;
+       struct dma_desc *tx_desc;
+       dma_addr_t dma_addr;
+@@ -5034,7 +5036,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+       stmmac_set_desc_addr(priv, tx_desc, dma_addr);
+       stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len,
+-                             true, priv->mode, true, true,
++                             csum, priv->mode, true, true,
+                              xdpf->len);
+       tx_q->tx_count_frames++;
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-stmmac-xgmac-correct-supported-speed-modes.patch b/queue-6.16/net-stmmac-xgmac-correct-supported-speed-modes.patch
new file mode 100644 (file)
index 0000000..12c73bd
--- /dev/null
@@ -0,0 +1,96 @@
+From 1c085336f1ad4c97ae5197d3a69c46fd521df342 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:53 +0800
+Subject: net: stmmac: xgmac: Correct supported speed modes
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 42ef11b2bff5b6a2910c28d2ea47cc00e0fbcaec ]
+
+Correct supported speed modes as per the XGMAC databook.
+Commit 9cb54af214a7 ("net: stmmac: Fix IP-cores specific
+MAC capabilities") removes support for 10M, 100M and
+1000HD. 1000HD is not supported by XGMAC IP, but it does
+support 10M and 100M FD mode for XGMAC version >= 2_20,
+and it also supports 10M and 100M HD mode if the HDSEL bit
+is set in the MAC_HW_FEATURE0 reg. This commit enables support
+for 10M and 100M speed modes for XGMAC IP based on XGMAC
+version and MAC capabilities.
+
+Fixes: 9cb54af214a7 ("net: stmmac: Fix IP-cores specific MAC capabilities")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-2-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 13 +++++++++++--
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c  |  5 +++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+index 6cadf8de4fdfd..00e929bf280ba 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+@@ -49,6 +49,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
+       writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
+ }
++static void dwxgmac2_update_caps(struct stmmac_priv *priv)
++{
++      if (!priv->dma_cap.mbps_10_100)
++              priv->hw->link.caps &= ~(MAC_10 | MAC_100);
++      else if (!priv->dma_cap.half_duplex)
++              priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD);
++}
++
+ static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
+ {
+       u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
+@@ -1424,6 +1432,7 @@ static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en,
+ const struct stmmac_ops dwxgmac210_ops = {
+       .core_init = dwxgmac2_core_init,
++      .update_caps = dwxgmac2_update_caps,
+       .set_mac = dwxgmac2_set_mac,
+       .rx_ipc = dwxgmac2_rx_ipc,
+       .rx_queue_enable = dwxgmac2_rx_queue_enable,
+@@ -1532,8 +1541,8 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
+               mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+       mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+-                       MAC_1000FD | MAC_2500FD | MAC_5000FD |
+-                       MAC_10000FD;
++                       MAC_10 | MAC_100 | MAC_1000FD |
++                       MAC_2500FD | MAC_5000FD | MAC_10000FD;
+       mac->link.duplex = 0;
+       mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
+       mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 7201a38842651..4d6bb995d8d84 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -382,8 +382,11 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
+ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+                                  struct dma_features *dma_cap)
+ {
++      struct stmmac_priv *priv;
+       u32 hw_cap;
++      priv = container_of(dma_cap, struct stmmac_priv, dma_cap);
++
+       /* MAC HW feature 0 */
+       hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
+       dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31;
+@@ -406,6 +409,8 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+       dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
+       dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3;
+       dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
++      if (dma_cap->mbps_1000 && priv->synopsys_id >= DWXGMAC_CORE_2_20)
++              dma_cap->mbps_10_100 = 1;
+       /* MAC HW feature 1 */
+       hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
+-- 
+2.50.1
+
diff --git a/queue-6.16/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch b/queue-6.16/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
new file mode 100644 (file)
index 0000000..c53ebae
--- /dev/null
@@ -0,0 +1,49 @@
+From 0c55c97c9343a3b833ffa81a41a8b8d39183281e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5dcc95bc0ad28..7201a38842651 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -203,10 +203,6 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+       }
+       writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+-      /* Enable MTL RX overflow */
+-      value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+-      writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+-- 
+2.50.1
+
diff --git a/queue-6.16/octeontx2-af-fix-nix-x2p-calibration-failures.patch b/queue-6.16/octeontx2-af-fix-nix-x2p-calibration-failures.patch
new file mode 100644 (file)
index 0000000..9c15397
--- /dev/null
@@ -0,0 +1,79 @@
+From ed23e35ef99918fd70b98941eaf46976dd02648e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 16:28:05 +0530
+Subject: Octeontx2-af: Fix NIX X2P calibration failures
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit d280233fc86692f495d5e08092e5422bc2f583a8 ]
+
+Before configuring the NIX block, the AF driver initiates the
+"NIX block X2P bus calibration" and verifies that NIX interfaces
+such as CGX and LBK are active and functioning correctly.
+
+On few silicon variants(CNF10KA and CNF10KB), X2P calibration failures
+have been observed on some CGX blocks that are not mapped to the NIX block.
+
+Since both NIX-mapped and non-NIX-mapped CGX blocks share the same
+VENDOR,DEVICE,SUBSYS_DEVID, it's not possible to skip probe based on
+these parameters.
+
+This patch introuduces "is_cgx_mapped_to_nix" API to detect and skip
+probe of non NIX mapped CGX blocks.
+
+Fixes: aba53d5dbcea ("octeontx2-af: NIX block admin queue init")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Link: https://patch.msgid.link/20250822105805.2236528-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/cgx.c |  7 +++++++
+ drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 14 ++++++++++++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+index 971993586fb49..442305463cc0a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+@@ -1940,6 +1940,13 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+               goto err_release_regions;
+       }
++      if (!is_cn20k(pdev) &&
++          !is_cgx_mapped_to_nix(pdev->subsystem_device, cgx->cgx_id)) {
++              dev_notice(dev, "CGX %d not mapped to NIX, skipping probe\n",
++                         cgx->cgx_id);
++              goto err_release_regions;
++      }
++
+       cgx->lmac_count = cgx->mac_ops->get_nr_lmacs(cgx);
+       if (!cgx->lmac_count) {
+               dev_notice(dev, "CGX %d LMAC count is zero, skipping probe\n", cgx->cgx_id);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+index 5c179df1f1673..9cdb7431f558c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+@@ -761,6 +761,20 @@ static inline bool is_cn10kb(struct rvu *rvu)
+       return false;
+ }
++static inline bool is_cgx_mapped_to_nix(unsigned short id, u8 cgx_id)
++{
++      /* On CNF10KA and CNF10KB silicons only two CGX blocks are connected
++       * to NIX.
++       */
++      if (id == PCI_SUBSYS_DEVID_CNF10K_A || id == PCI_SUBSYS_DEVID_CNF10K_B)
++              return cgx_id <= 1;
++
++      return !(cgx_id && !(id == PCI_SUBSYS_DEVID_96XX ||
++                           id == PCI_SUBSYS_DEVID_98XX ||
++                           id == PCI_SUBSYS_DEVID_CN10K_A ||
++                           id == PCI_SUBSYS_DEVID_CN10K_B));
++}
++
+ static inline bool is_rvu_npc_hash_extract_en(struct rvu *rvu)
+ {
+       u64 npc_const3;
+-- 
+2.50.1
+
diff --git a/queue-6.16/octeontx2-set-appropriate-pf-vf-masks-and-shifts-bas.patch b/queue-6.16/octeontx2-set-appropriate-pf-vf-masks-and-shifts-bas.patch
new file mode 100644 (file)
index 0000000..5c42d5f
--- /dev/null
@@ -0,0 +1,1597 @@
+From 57543e65e58d97f5b4ab29823a0643b02c1f3ac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 16:31:51 +0530
+Subject: octeontx2: Set appropriate PF, VF masks and shifts based on silicon
+
+From: Subbaraya Sundeep <sbhatta@marvell.com>
+
+[ Upstream commit 25d51ebf0f54f9c2424f28bb29125cf24f120df0 ]
+
+Number of RVU PFs on CN20K silicon have increased to 96 from maximum
+of 32 that were supported on earlier silicons. Every RVU PF and VF is
+identified by HW using a 16bit PF_FUNC value. Due to the change in
+Max number of PFs in CN20K, the bit encoding of this PF_FUNC has changed.
+
+This patch handles the change by using helper functions(using silicon
+check) to use PF,VF masks and shifts to support both new silicon CN20K,
+OcteonTx series. These helper functions are used in different modules.
+
+Also moved the NIX AF register offset macros to other files which
+will be posted in coming patches.
+
+Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
+Signed-off-by: Sai Krishna <saikrishnag@marvell.com>
+Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
+Link: https://patch.msgid.link/1749639716-13868-2-git-send-email-sbhatta@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d280233fc866 ("Octeontx2-af: Fix NIX X2P calibration failures")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../marvell/octeontx2/otx2_cpt_common.h       |  5 +-
+ .../marvell/octeontx2/otx2_cptpf_mbox.c       | 13 ++--
+ .../marvell/octeontx2/otx2_cptpf_ucode.c      |  4 +-
+ .../marvell/octeontx2/otx2_cptvf_mbox.c       |  6 +-
+ .../marvell/octeontx2/af/mcs_rvu_if.c         |  6 +-
+ .../net/ethernet/marvell/octeontx2/af/rvu.c   | 30 ++++----
+ .../net/ethernet/marvell/octeontx2/af/rvu.h   | 52 +++++++++++---
+ .../ethernet/marvell/octeontx2/af/rvu_cgx.c   | 68 +++++++++----------
+ .../ethernet/marvell/octeontx2/af/rvu_cn10k.c |  4 +-
+ .../ethernet/marvell/octeontx2/af/rvu_cpt.c   |  4 +-
+ .../marvell/octeontx2/af/rvu_debugfs.c        | 22 +++---
+ .../ethernet/marvell/octeontx2/af/rvu_nix.c   | 54 ++++++++-------
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c   |  8 ++-
+ .../marvell/octeontx2/af/rvu_npc_hash.c       | 16 ++---
+ .../marvell/octeontx2/af/rvu_npc_hash.h       |  4 +-
+ .../ethernet/marvell/octeontx2/af/rvu_rep.c   | 13 ++--
+ .../ethernet/marvell/octeontx2/af/rvu_sdp.c   | 10 +--
+ .../marvell/octeontx2/af/rvu_switch.c         |  8 +--
+ .../marvell/octeontx2/nic/cn10k_ipsec.c       |  2 +-
+ .../marvell/octeontx2/nic/cn10k_ipsec.h       |  2 +-
+ .../marvell/octeontx2/nic/otx2_common.h       | 11 +--
+ .../ethernet/marvell/octeontx2/nic/otx2_pf.c  | 21 +++---
+ .../ethernet/marvell/octeontx2/nic/otx2_reg.h | 30 --------
+ .../ethernet/marvell/octeontx2/nic/otx2_tc.c  |  3 +-
+ .../net/ethernet/marvell/octeontx2/nic/rep.c  |  7 +-
+ include/linux/soc/marvell/silicons.h          | 25 +++++++
+ 26 files changed, 225 insertions(+), 203 deletions(-)
+ create mode 100644 include/linux/soc/marvell/silicons.h
+
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h b/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
+index d529bcb03775f..062def303dcea 100644
+--- a/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
++++ b/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
+@@ -18,9 +18,8 @@
+ #define OTX2_CPT_MAX_VFS_NUM 128
+ #define OTX2_CPT_RVU_FUNC_ADDR_S(blk, slot, offs) \
+               (((blk) << 20) | ((slot) << 12) | (offs))
+-#define OTX2_CPT_RVU_PFFUNC(pf, func) \
+-              ((((pf) & RVU_PFVF_PF_MASK) << RVU_PFVF_PF_SHIFT) | \
+-              (((func) & RVU_PFVF_FUNC_MASK) << RVU_PFVF_FUNC_SHIFT))
++
++#define OTX2_CPT_RVU_PFFUNC(pdev, pf, func) rvu_make_pcifunc(pdev, pf, func)
+ #define OTX2_CPT_INVALID_CRYPTO_ENG_GRP 0xFF
+ #define OTX2_CPT_NAME_LENGTH 64
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
+index 12c0e966fa65f..b4b2d3d1cbc2a 100644
+--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
++++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
+@@ -142,7 +142,7 @@ static int send_inline_ipsec_inbound_msg(struct otx2_cptpf_dev *cptpf,
+       memset(req, 0, sizeof(*req));
+       req->hdr.id = MBOX_MSG_CPT_INLINE_IPSEC_CFG;
+       req->hdr.sig = OTX2_MBOX_REQ_SIG;
+-      req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptpf->pf_id, 0);
++      req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptpf->pdev, cptpf->pf_id, 0);
+       req->dir = CPT_INLINE_INBOUND;
+       req->slot = slot;
+       req->sso_pf_func_ovrd = cptpf->sso_pf_func_ovrd;
+@@ -184,7 +184,8 @@ static int rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, u8 egrp,
+               nix_req->gen_cfg.opcode = cpt_inline_rx_opcode(pdev);
+       nix_req->gen_cfg.param1 = req->param1;
+       nix_req->gen_cfg.param2 = req->param2;
+-      nix_req->inst_qsel.cpt_pf_func = OTX2_CPT_RVU_PFFUNC(cptpf->pf_id, 0);
++      nix_req->inst_qsel.cpt_pf_func =
++              OTX2_CPT_RVU_PFFUNC(cptpf->pdev, cptpf->pf_id, 0);
+       nix_req->inst_qsel.cpt_slot = 0;
+       ret = otx2_cpt_send_mbox_msg(&cptpf->afpf_mbox, pdev);
+       if (ret)
+@@ -392,9 +393,8 @@ void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work)
+               msg = (struct mbox_msghdr *)(mdev->mbase + offset);
+               /* Set which VF sent this message based on mbox IRQ */
+-              msg->pcifunc = ((u16)cptpf->pf_id << RVU_PFVF_PF_SHIFT) |
+-                              ((vf->vf_id + 1) & RVU_PFVF_FUNC_MASK);
+-
++              msg->pcifunc = rvu_make_pcifunc(cptpf->pdev, cptpf->pf_id,
++                                              (vf->vf_id + 1));
+               err = cptpf_handle_vf_req(cptpf, vf, msg,
+                                         msg->next_msgoff - offset);
+               /*
+@@ -469,8 +469,7 @@ static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
+       switch (msg->id) {
+       case MBOX_MSG_READY:
+-              cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) &
+-                              RVU_PFVF_PF_MASK;
++              cptpf->pf_id = rvu_get_pf(cptpf->pdev, msg->pcifunc);
+               break;
+       case MBOX_MSG_MSIX_OFFSET:
+               rsp_msix = (struct msix_offset_rsp *) msg;
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
+index 56645b3eb7175..cc47e361089a0 100644
+--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
++++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
+@@ -176,7 +176,9 @@ static int cptx_set_ucode_base(struct otx2_cpt_eng_grp_info *eng_grp,
+       /* Set PF number for microcode fetches */
+       ret = otx2_cpt_write_af_reg(&cptpf->afpf_mbox, cptpf->pdev,
+                                   CPT_AF_PF_FUNC,
+-                                  cptpf->pf_id << RVU_PFVF_PF_SHIFT, blkaddr);
++                                  rvu_make_pcifunc(cptpf->pdev,
++                                                   cptpf->pf_id, 0),
++                                  blkaddr);
+       if (ret)
+               return ret;
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c
+index 931b72580fd9f..92e49babd79af 100644
+--- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c
++++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c
+@@ -189,7 +189,7 @@ int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type)
+       }
+       req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;
+       req->hdr.sig = OTX2_MBOX_REQ_SIG;
+-      req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
++      req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
+       req->eng_type = eng_type;
+       return otx2_cpt_send_mbox_msg(mbox, pdev);
+@@ -210,7 +210,7 @@ int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf)
+       }
+       req->id = MBOX_MSG_GET_KVF_LIMITS;
+       req->sig = OTX2_MBOX_REQ_SIG;
+-      req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
++      req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
+       return otx2_cpt_send_mbox_msg(mbox, pdev);
+ }
+@@ -230,7 +230,7 @@ int otx2_cptvf_send_caps_msg(struct otx2_cptvf_dev *cptvf)
+       }
+       req->id = MBOX_MSG_GET_CAPS;
+       req->sig = OTX2_MBOX_REQ_SIG;
+-      req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
++      req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
+       return otx2_cpt_send_mbox_msg(mbox, pdev);
+ }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
+index 0277d226293e9..d7030dfa5dad2 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
+@@ -97,7 +97,7 @@ int mcs_add_intr_wq_entry(struct mcs *mcs, struct mcs_intr_event *event)
+       if (pcifunc & RVU_PFVF_FUNC_MASK)
+               pfvf = &mcs->vf[rvu_get_hwvf(rvu, pcifunc)];
+       else
+-              pfvf = &mcs->pf[rvu_get_pf(pcifunc)];
++              pfvf = &mcs->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+       event->intr_mask &= pfvf->intr_mask;
+@@ -123,7 +123,7 @@ static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
+       struct mcs_intr_info *req;
+       int pf;
+-      pf = rvu_get_pf(event->pcifunc);
++      pf = rvu_get_pf(rvu->pdev, event->pcifunc);
+       mutex_lock(&rvu->mbox_lock);
+@@ -193,7 +193,7 @@ int rvu_mbox_handler_mcs_intr_cfg(struct rvu *rvu,
+       if (pcifunc & RVU_PFVF_FUNC_MASK)
+               pfvf = &mcs->vf[rvu_get_hwvf(rvu, pcifunc)];
+       else
+-              pfvf = &mcs->pf[rvu_get_pf(pcifunc)];
++              pfvf = &mcs->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+       mcs->pf_map[0] = pcifunc;
+       pfvf->intr_mask = req->intr_mask;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+index a8025f0486c9f..39f664d60ecff 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+@@ -294,7 +294,7 @@ int rvu_get_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc)
+               devnum = rvu_get_hwvf(rvu, pcifunc);
+       } else {
+               is_pf = true;
+-              devnum = rvu_get_pf(pcifunc);
++              devnum = rvu_get_pf(rvu->pdev, pcifunc);
+       }
+       /* Check if the 'pcifunc' has a NIX LF from 'BLKADDR_NIX0' or
+@@ -359,7 +359,7 @@ static void rvu_update_rsrc_map(struct rvu *rvu, struct rvu_pfvf *pfvf,
+               devnum = rvu_get_hwvf(rvu, pcifunc);
+       } else {
+               is_pf = true;
+-              devnum = rvu_get_pf(pcifunc);
++              devnum = rvu_get_pf(rvu->pdev, pcifunc);
+       }
+       block->fn_map[lf] = attach ? pcifunc : 0;
+@@ -400,11 +400,6 @@ static void rvu_update_rsrc_map(struct rvu *rvu, struct rvu_pfvf *pfvf,
+       rvu_write64(rvu, BLKADDR_RVUM, reg | (devnum << 16), num_lfs);
+ }
+-inline int rvu_get_pf(u16 pcifunc)
+-{
+-      return (pcifunc >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
+-}
+-
+ void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf)
+ {
+       u64 cfg;
+@@ -422,7 +417,7 @@ int rvu_get_hwvf(struct rvu *rvu, int pcifunc)
+       int pf, func;
+       u64 cfg;
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       func = pcifunc & RVU_PFVF_FUNC_MASK;
+       /* Get first HWVF attached to this PF */
+@@ -437,7 +432,7 @@ struct rvu_pfvf *rvu_get_pfvf(struct rvu *rvu, int pcifunc)
+       if (pcifunc & RVU_PFVF_FUNC_MASK)
+               return &rvu->hwvf[rvu_get_hwvf(rvu, pcifunc)];
+       else
+-              return &rvu->pf[rvu_get_pf(pcifunc)];
++              return &rvu->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+ }
+ static bool is_pf_func_valid(struct rvu *rvu, u16 pcifunc)
+@@ -445,7 +440,7 @@ static bool is_pf_func_valid(struct rvu *rvu, u16 pcifunc)
+       int pf, vf, nvfs;
+       u64 cfg;
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       if (pf >= rvu->hw->total_pfs)
+               return false;
+@@ -1487,7 +1482,7 @@ int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
+       pf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
+       /* All CGX mapped PFs are set with assigned NIX block during init */
+-      if (is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) {
++      if (is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc))) {
+               blkaddr = pf->nix_blkaddr;
+       } else if (is_lbk_vf(rvu, pcifunc)) {
+               vf = pcifunc - 1;
+@@ -1501,7 +1496,7 @@ int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
+       }
+       /* if SDP1 then the blkaddr is NIX1 */
+-      if (is_sdp_pfvf(pcifunc) && pf->sdp_info->node_id == 1)
++      if (is_sdp_pfvf(rvu, pcifunc) && pf->sdp_info->node_id == 1)
+               blkaddr = BLKADDR_NIX1;
+       switch (blkaddr) {
+@@ -2006,7 +2001,7 @@ int rvu_mbox_handler_vf_flr(struct rvu *rvu, struct msg_req *req,
+       vf = pcifunc & RVU_PFVF_FUNC_MASK;
+       cfg = rvu_read64(rvu, BLKADDR_RVUM,
+-                       RVU_PRIV_PFX_CFG(rvu_get_pf(pcifunc)));
++                       RVU_PRIV_PFX_CFG(rvu_get_pf(rvu->pdev, pcifunc)));
+       numvfs = (cfg >> 12) & 0xFF;
+       if (vf && vf <= numvfs)
+@@ -2229,9 +2224,8 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll)
+               /* Set which PF/VF sent this message based on mbox IRQ */
+               switch (type) {
+               case TYPE_AFPF:
+-                      msg->pcifunc &=
+-                              ~(RVU_PFVF_PF_MASK << RVU_PFVF_PF_SHIFT);
+-                      msg->pcifunc |= (devid << RVU_PFVF_PF_SHIFT);
++                      msg->pcifunc &= rvu_pcifunc_pf_mask(rvu->pdev);
++                      msg->pcifunc |= rvu_make_pcifunc(rvu->pdev, devid, 0);
+                       break;
+               case TYPE_AFVF:
+                       msg->pcifunc &=
+@@ -2249,7 +2243,7 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll)
+               if (msg->pcifunc & RVU_PFVF_FUNC_MASK)
+                       dev_warn(rvu->dev, "Error %d when processing message %s (0x%x) from PF%d:VF%d\n",
+                                err, otx2_mbox_id2name(msg->id),
+-                               msg->id, rvu_get_pf(msg->pcifunc),
++                               msg->id, rvu_get_pf(rvu->pdev, msg->pcifunc),
+                                (msg->pcifunc & RVU_PFVF_FUNC_MASK) - 1);
+               else
+                       dev_warn(rvu->dev, "Error %d when processing message %s (0x%x) from PF%d\n",
+@@ -2773,7 +2767,7 @@ static void rvu_flr_handler(struct work_struct *work)
+       cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf));
+       numvfs = (cfg >> 12) & 0xFF;
+-      pcifunc  = pf << RVU_PFVF_PF_SHIFT;
++      pcifunc  = rvu_make_pcifunc(rvu->pdev, pf, 0);
+       for (vf = 0; vf < numvfs; vf++)
+               __rvu_flr_handler(rvu, (pcifunc | (vf + 1)));
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+index 48f66292ad5c5..5c179df1f1673 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+@@ -10,6 +10,7 @@
+ #include <linux/pci.h>
+ #include <net/devlink.h>
++#include <linux/soc/marvell/silicons.h>
+ #include "rvu_struct.h"
+ #include "rvu_devlink.h"
+@@ -43,10 +44,34 @@
+ #define MAX_CPT_BLKS                          2
+ /* PF_FUNC */
+-#define RVU_PFVF_PF_SHIFT     10
+-#define RVU_PFVF_PF_MASK      0x3F
+-#define RVU_PFVF_FUNC_SHIFT   0
+-#define RVU_PFVF_FUNC_MASK    0x3FF
++#define RVU_OTX2_PFVF_PF_SHIFT                        10
++#define RVU_OTX2_PFVF_PF_MASK                 0x3F
++#define RVU_PFVF_FUNC_SHIFT                   0
++#define RVU_PFVF_FUNC_MASK                    0x3FF
++#define RVU_CN20K_PFVF_PF_SHIFT                       9
++#define RVU_CN20K_PFVF_PF_MASK                        0x7F
++
++static inline u16 rvu_make_pcifunc(struct pci_dev *pdev, int pf, int func)
++{
++      if (is_cn20k(pdev))
++              return ((pf & RVU_CN20K_PFVF_PF_MASK) <<
++                      RVU_CN20K_PFVF_PF_SHIFT) |
++                      ((func & RVU_PFVF_FUNC_MASK) <<
++                      RVU_PFVF_FUNC_SHIFT);
++      else
++              return ((pf & RVU_OTX2_PFVF_PF_MASK) <<
++                      RVU_OTX2_PFVF_PF_SHIFT) |
++                      ((func & RVU_PFVF_FUNC_MASK) <<
++                      RVU_PFVF_FUNC_SHIFT);
++}
++
++static inline int rvu_pcifunc_pf_mask(struct pci_dev *pdev)
++{
++      if (is_cn20k(pdev))
++              return ~(RVU_CN20K_PFVF_PF_MASK << RVU_CN20K_PFVF_PF_SHIFT);
++      else
++              return ~(RVU_OTX2_PFVF_PF_MASK << RVU_OTX2_PFVF_PF_SHIFT);
++}
+ #ifdef CONFIG_DEBUG_FS
+ struct dump_ctx {
+@@ -836,7 +861,6 @@ int rvu_alloc_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc);
+ void rvu_free_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc, int start);
+ bool rvu_rsrc_check_contig(struct rsrc_bmap *rsrc, int nrsrc);
+ u16 rvu_get_rsrc_mapcount(struct rvu_pfvf *pfvf, int blkaddr);
+-int rvu_get_pf(u16 pcifunc);
+ struct rvu_pfvf *rvu_get_pfvf(struct rvu *rvu, int pcifunc);
+ void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf);
+ bool is_block_implemented(struct rvu_hwinfo *hw, int blkaddr);
+@@ -865,8 +889,8 @@ void rvu_aq_free(struct rvu *rvu, struct admin_queue *aq);
+ /* SDP APIs */
+ int rvu_sdp_init(struct rvu *rvu);
+-bool is_sdp_pfvf(u16 pcifunc);
+-bool is_sdp_pf(u16 pcifunc);
++bool is_sdp_pfvf(struct rvu *rvu, u16 pcifunc);
++bool is_sdp_pf(struct rvu *rvu, u16 pcifunc);
+ bool is_sdp_vf(struct rvu *rvu, u16 pcifunc);
+ static inline bool is_rep_dev(struct rvu *rvu, u16 pcifunc)
+@@ -877,11 +901,21 @@ static inline bool is_rep_dev(struct rvu *rvu, u16 pcifunc)
+       return false;
+ }
++static inline int rvu_get_pf(struct pci_dev *pdev, u16 pcifunc)
++{
++      if (is_cn20k(pdev))
++              return (pcifunc >> RVU_CN20K_PFVF_PF_SHIFT) &
++                      RVU_CN20K_PFVF_PF_MASK;
++      else
++              return (pcifunc >> RVU_OTX2_PFVF_PF_SHIFT) &
++                      RVU_OTX2_PFVF_PF_MASK;
++}
++
+ /* CGX APIs */
+ static inline bool is_pf_cgxmapped(struct rvu *rvu, u8 pf)
+ {
+       return (pf >= PF_CGXMAP_BASE && pf <= rvu->cgx_mapped_pfs) &&
+-              !is_sdp_pf(pf << RVU_PFVF_PF_SHIFT);
++              !is_sdp_pf(rvu, rvu_make_pcifunc(rvu->pdev, pf, 0));
+ }
+ static inline void rvu_get_cgx_lmac_id(u8 map, u8 *cgx_id, u8 *lmac_id)
+@@ -893,7 +927,7 @@ static inline void rvu_get_cgx_lmac_id(u8 map, u8 *cgx_id, u8 *lmac_id)
+ static inline bool is_cgx_vf(struct rvu *rvu, u16 pcifunc)
+ {
+       return ((pcifunc & RVU_PFVF_FUNC_MASK) &&
+-              is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)));
++              is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)));
+ }
+ #define M(_name, _id, fn_name, req, rsp)                              \
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+index d0331b0e0bfd4..b79db887ab9b2 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+@@ -457,7 +457,7 @@ int rvu_cgx_exit(struct rvu *rvu)
+ inline bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc)
+ {
+       if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
+-          !is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
++          !is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)))
+               return false;
+       return true;
+ }
+@@ -484,7 +484,7 @@ void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable)
+ int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+       void *cgxd;
+@@ -501,7 +501,7 @@ int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start)
+ int rvu_cgx_tx_enable(struct rvu *rvu, u16 pcifunc, bool enable)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+       void *cgxd;
+@@ -526,7 +526,7 @@ int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable)
+ void rvu_cgx_disable_dmac_entries(struct rvu *rvu, u16 pcifunc)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       int i = 0, lmac_count = 0;
+       struct mac_ops *mac_ops;
+       u8 max_dmac_filters;
+@@ -577,7 +577,7 @@ int rvu_mbox_handler_cgx_stop_rxtx(struct rvu *rvu, struct msg_req *req,
+ static int rvu_lmac_get_stats(struct rvu *rvu, struct msg_req *req,
+                             void *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       struct mac_ops *mac_ops;
+       int stat = 0, err = 0;
+       u64 tx_stat, rx_stat;
+@@ -633,7 +633,7 @@ int rvu_mbox_handler_rpm_stats(struct rvu *rvu, struct msg_req *req,
+ int rvu_mbox_handler_cgx_stats_rst(struct rvu *rvu, struct msg_req *req,
+                                  struct msg_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       struct rvu_pfvf *parent_pf;
+       struct mac_ops *mac_ops;
+       u8 cgx_idx, lmac;
+@@ -663,7 +663,7 @@ int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
+                                  struct msg_req *req,
+                                  struct cgx_fec_stats_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       struct mac_ops *mac_ops;
+       u8 cgx_idx, lmac;
+       void *cgxd;
+@@ -681,7 +681,7 @@ int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
+                                     struct cgx_mac_addr_set_or_get *req,
+                                     struct cgx_mac_addr_set_or_get *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -701,7 +701,7 @@ int rvu_mbox_handler_cgx_mac_addr_add(struct rvu *rvu,
+                                     struct cgx_mac_addr_add_req *req,
+                                     struct cgx_mac_addr_add_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       int rc = 0;
+@@ -725,7 +725,7 @@ int rvu_mbox_handler_cgx_mac_addr_del(struct rvu *rvu,
+                                     struct cgx_mac_addr_del_req *req,
+                                     struct msg_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -743,7 +743,7 @@ int rvu_mbox_handler_cgx_mac_max_entries_get(struct rvu *rvu,
+                                            struct cgx_max_dmac_entries_get_rsp
+                                            *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       /* If msg is received from PFs(which are not mapped to CGX LMACs)
+@@ -769,7 +769,7 @@ int rvu_mbox_handler_cgx_mac_addr_get(struct rvu *rvu,
+                                     struct cgx_mac_addr_set_or_get *req,
+                                     struct cgx_mac_addr_set_or_get *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       int rc = 0;
+       u64 cfg;
+@@ -790,7 +790,7 @@ int rvu_mbox_handler_cgx_promisc_enable(struct rvu *rvu, struct msg_req *req,
+                                       struct msg_rsp *rsp)
+ {
+       u16 pcifunc = req->hdr.pcifunc;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -809,7 +809,7 @@ int rvu_mbox_handler_cgx_promisc_enable(struct rvu *rvu, struct msg_req *req,
+ int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req,
+                                        struct msg_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -828,7 +828,7 @@ int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req,
+ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+ {
+       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+       void *cgxd;
+@@ -864,7 +864,7 @@ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+ int rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu *rvu, struct msg_req *req,
+                                      struct msg_rsp *rsp)
+ {
+-      if (!is_pf_cgxmapped(rvu, rvu_get_pf(req->hdr.pcifunc)))
++      if (!is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, req->hdr.pcifunc)))
+               return -EPERM;
+       return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, true);
+@@ -878,7 +878,7 @@ int rvu_mbox_handler_cgx_ptp_rx_disable(struct rvu *rvu, struct msg_req *req,
+ static int rvu_cgx_config_linkevents(struct rvu *rvu, u16 pcifunc, bool en)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_cgx_config_permitted(rvu, pcifunc))
+@@ -917,7 +917,7 @@ int rvu_mbox_handler_cgx_get_linkinfo(struct rvu *rvu, struct msg_req *req,
+       u8 cgx_id, lmac_id;
+       int pf, err;
+-      pf = rvu_get_pf(req->hdr.pcifunc);
++      pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       if (!is_pf_cgxmapped(rvu, pf))
+               return -ENODEV;
+@@ -933,7 +933,7 @@ int rvu_mbox_handler_cgx_features_get(struct rvu *rvu,
+                                     struct msg_req *req,
+                                     struct cgx_features_info_msg *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_idx, lmac;
+       void *cgxd;
+@@ -975,7 +975,7 @@ u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac)
+ static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+@@ -1005,7 +1005,7 @@ int rvu_mbox_handler_cgx_intlbk_disable(struct rvu *rvu, struct msg_req *req,
+ int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u8 rx_pfc = 0, tx_pfc = 0;
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+@@ -1046,7 +1046,7 @@ int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
+                                      struct cgx_pause_frm_cfg *req,
+                                      struct cgx_pause_frm_cfg *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+       int err = 0;
+@@ -1073,7 +1073,7 @@ int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
+ int rvu_mbox_handler_cgx_get_phy_fec_stats(struct rvu *rvu, struct msg_req *req,
+                                          struct msg_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_pf_cgxmapped(rvu, pf))
+@@ -1106,7 +1106,7 @@ int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id,
+       /* Assumes LF of a PF and all of its VF belongs to the same
+        * NIX block
+        */
+-      pcifunc = pf << RVU_PFVF_PF_SHIFT;
++      pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+       if (blkaddr < 0)
+               return 0;
+@@ -1133,10 +1133,10 @@ int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start)
+       struct rvu_pfvf *parent_pf, *pfvf;
+       int cgx_users, err = 0;
+-      if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
++      if (!is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)))
+               return 0;
+-      parent_pf = &rvu->pf[rvu_get_pf(pcifunc)];
++      parent_pf = &rvu->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+       pfvf = rvu_get_pfvf(rvu, pcifunc);
+       mutex_lock(&rvu->cgx_cfg_lock);
+@@ -1179,7 +1179,7 @@ int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
+                                      struct fec_mode *req,
+                                      struct fec_mode *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_pf_cgxmapped(rvu, pf))
+@@ -1195,7 +1195,7 @@ int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
+ int rvu_mbox_handler_cgx_get_aux_link_info(struct rvu *rvu, struct msg_req *req,
+                                          struct cgx_fw_data *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!rvu->fwdata)
+@@ -1222,7 +1222,7 @@ int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
+                                      struct cgx_set_link_mode_req *req,
+                                      struct cgx_set_link_mode_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_idx, lmac;
+       void *cgxd;
+@@ -1238,7 +1238,7 @@ int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
+ int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
+                                       struct msg_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -1256,7 +1256,7 @@ int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
+                                        struct cgx_mac_addr_update_req *req,
+                                        struct cgx_mac_addr_update_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -1272,7 +1272,7 @@ int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
+ int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause,
+                              u8 rx_pause, u16 pfc_en)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u8 rx_8023 = 0, tx_8023 = 0;
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+@@ -1310,7 +1310,7 @@ int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
+                                           struct cgx_pfc_cfg *req,
+                                           struct cgx_pfc_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+       void *cgxd;
+@@ -1335,7 +1335,7 @@ int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
+ void rvu_mac_reset(struct rvu *rvu, u16 pcifunc)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       struct mac_ops *mac_ops;
+       struct cgx *cgxd;
+       u8 cgx, lmac;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
+index 4a3370a40dd88..05adc54535eb3 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
+@@ -66,7 +66,7 @@ static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val,
+ #define LMT_MAP_TBL_W1_OFF  8
+ static u32 rvu_get_lmtst_tbl_index(struct rvu *rvu, u16 pcifunc)
+ {
+-      return ((rvu_get_pf(pcifunc) * LMT_MAX_VFS) +
++      return ((rvu_get_pf(rvu->pdev, pcifunc) * LMT_MAX_VFS) +
+               (pcifunc & RVU_PFVF_FUNC_MASK)) * LMT_MAPTBL_ENTRY_SIZE;
+ }
+@@ -83,7 +83,7 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
+       mutex_lock(&rvu->rsrc_lock);
+       rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_REQ, iova);
+-      pf = rvu_get_pf(pcifunc) & RVU_PFVF_PF_MASK;
++      pf = rvu_get_pf(rvu->pdev, pcifunc) & RVU_OTX2_PFVF_PF_MASK;
+       val = BIT_ULL(63) | BIT_ULL(14) | BIT_ULL(13) | pf << 8 |
+             ((pcifunc & RVU_PFVF_FUNC_MASK) & 0xFF);
+       rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TXN_REQ, val);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
+index 3c5bbaf12e594..f404117bf6c8c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
+@@ -410,7 +410,7 @@ static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc)
+ {
+       int cpt_pf_num = rvu->cpt_pf_num;
+-      if (rvu_get_pf(pcifunc) != cpt_pf_num)
++      if (rvu_get_pf(rvu->pdev, pcifunc) != cpt_pf_num)
+               return false;
+       if (pcifunc & RVU_PFVF_FUNC_MASK)
+               return false;
+@@ -422,7 +422,7 @@ static bool is_cpt_vf(struct rvu *rvu, u16 pcifunc)
+ {
+       int cpt_pf_num = rvu->cpt_pf_num;
+-      if (rvu_get_pf(pcifunc) != cpt_pf_num)
++      if (rvu_get_pf(rvu->pdev, pcifunc) != cpt_pf_num)
+               return false;
+       if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+               return false;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+index c827da6264712..0c20642f81b9b 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+@@ -688,7 +688,7 @@ static int get_max_column_width(struct rvu *rvu)
+       for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
+               for (vf = 0; vf <= rvu->hw->total_vfs; vf++) {
+-                      pcifunc = pf << 10 | vf;
++                      pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf);
+                       if (!pcifunc)
+                               continue;
+@@ -759,7 +759,7 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,
+               for (vf = 0; vf <= rvu->hw->total_vfs; vf++) {
+                       off = 0;
+                       flag = 0;
+-                      pcifunc = pf << 10 | vf;
++                      pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf);
+                       if (!pcifunc)
+                               continue;
+@@ -842,7 +842,7 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
+               cgx[0] = 0;
+               lmac[0] = 0;
+-              pcifunc = pf << 10;
++              pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+               pfvf = rvu_get_pfvf(rvu, pcifunc);
+               if (pfvf->nix_blkaddr == BLKADDR_NIX0)
+@@ -2623,10 +2623,10 @@ static int rvu_dbg_nix_band_prof_ctx_display(struct seq_file *m, void *unused)
+                       pcifunc = ipolicer->pfvf_map[idx];
+                       if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+                               seq_printf(m, "Allocated to :: PF %d\n",
+-                                         rvu_get_pf(pcifunc));
++                                         rvu_get_pf(rvu->pdev, pcifunc));
+                       else
+                               seq_printf(m, "Allocated to :: PF %d VF %d\n",
+-                                         rvu_get_pf(pcifunc),
++                                         rvu_get_pf(rvu->pdev, pcifunc),
+                                          (pcifunc & RVU_PFVF_FUNC_MASK) - 1);
+                       print_band_prof_ctx(m, &aq_rsp.prof);
+               }
+@@ -2983,10 +2983,10 @@ static void rvu_print_npc_mcam_info(struct seq_file *s,
+       if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+               seq_printf(s, "\n\t\t Device \t\t: PF%d\n",
+-                         rvu_get_pf(pcifunc));
++                         rvu_get_pf(rvu->pdev, pcifunc));
+       else
+               seq_printf(s, "\n\t\t Device \t\t: PF%d VF%d\n",
+-                         rvu_get_pf(pcifunc),
++                         rvu_get_pf(rvu->pdev, pcifunc),
+                          (pcifunc & RVU_PFVF_FUNC_MASK) - 1);
+       if (entry_acnt) {
+@@ -3049,13 +3049,13 @@ static int rvu_dbg_npc_mcam_info_display(struct seq_file *filp, void *unsued)
+       seq_puts(filp, "\n\t\t Current allocation\n");
+       seq_puts(filp, "\t\t====================\n");
+       for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
+-              pcifunc = (pf << RVU_PFVF_PF_SHIFT);
++              pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+               rvu_print_npc_mcam_info(filp, pcifunc, blkaddr);
+               cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf));
+               numvfs = (cfg >> 12) & 0xFF;
+               for (vf = 0; vf < numvfs; vf++) {
+-                      pcifunc = (pf << RVU_PFVF_PF_SHIFT) | (vf + 1);
++                      pcifunc = rvu_make_pcifunc(rvu->pdev, pf, (vf + 1));
+                       rvu_print_npc_mcam_info(filp, pcifunc, blkaddr);
+               }
+       }
+@@ -3326,7 +3326,7 @@ static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)
+       mutex_lock(&mcam->lock);
+       list_for_each_entry(iter, &mcam->mcam_rules, list) {
+-              pf = (iter->owner >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
++              pf = rvu_get_pf(rvu->pdev, iter->owner);
+               seq_printf(s, "\n\tInstalled by: PF%d ", pf);
+               if (iter->owner & RVU_PFVF_FUNC_MASK) {
+@@ -3344,7 +3344,7 @@ static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)
+               rvu_dbg_npc_mcam_show_flows(s, iter);
+               if (is_npc_intf_rx(iter->intf)) {
+                       target = iter->rx_action.pf_func;
+-                      pf = (target >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
++                      pf = rvu_get_pf(rvu->pdev, target);
+                       seq_printf(s, "\tForward to: PF%d ", pf);
+                       if (target & RVU_PFVF_FUNC_MASK) {
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index 613655fcd34f4..bdf4d852c15de 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -315,7 +315,8 @@ static bool is_valid_txschq(struct rvu *rvu, int blkaddr,
+       if (lvl >= hw->cap.nix_tx_aggr_lvl) {
+               if ((nix_get_tx_link(rvu, map_func) !=
+                    nix_get_tx_link(rvu, pcifunc)) &&
+-                   (rvu_get_pf(map_func) != rvu_get_pf(pcifunc)))
++                   (rvu_get_pf(rvu->pdev, map_func) !=
++                              rvu_get_pf(rvu->pdev, pcifunc)))
+                       return false;
+               else
+                       return true;
+@@ -339,7 +340,7 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf,
+       bool from_vf;
+       int err;
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK &&
+           type != NIX_INTF_TYPE_SDP)
+               return 0;
+@@ -416,7 +417,7 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf,
+               break;
+       case NIX_INTF_TYPE_SDP:
+               from_vf = !!(pcifunc & RVU_PFVF_FUNC_MASK);
+-              parent_pf = &rvu->pf[rvu_get_pf(pcifunc)];
++              parent_pf = &rvu->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+               sdp_info = parent_pf->sdp_info;
+               if (!sdp_info) {
+                       dev_err(rvu->dev, "Invalid sdp_info pointer\n");
+@@ -590,12 +591,12 @@ static int nix_bp_disable(struct rvu *rvu,
+       u16 chan_v;
+       u64 cfg;
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       type = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
+       if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK)
+               return 0;
+-      if (is_sdp_pfvf(pcifunc))
++      if (is_sdp_pfvf(rvu, pcifunc))
+               type = NIX_INTF_TYPE_SDP;
+       if (cpt_link && !rvu->hw->cpt_links)
+@@ -736,9 +737,9 @@ static int nix_bp_enable(struct rvu *rvu,
+       u16 chan_v;
+       u64 cfg;
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       type = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
+-      if (is_sdp_pfvf(pcifunc))
++      if (is_sdp_pfvf(rvu, pcifunc))
+               type = NIX_INTF_TYPE_SDP;
+       /* Enable backpressure only for CGX mapped PFs and LBK/SDP interface */
+@@ -1674,7 +1675,7 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
+       }
+       intf = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
+-      if (is_sdp_pfvf(pcifunc))
++      if (is_sdp_pfvf(rvu, pcifunc))
+               intf = NIX_INTF_TYPE_SDP;
+       err = nix_interface_init(rvu, pcifunc, intf, nixlf, rsp,
+@@ -1798,7 +1799,8 @@ int rvu_mbox_handler_nix_mark_format_cfg(struct rvu *rvu,
+       rc = rvu_nix_reserve_mark_format(rvu, nix_hw, blkaddr, cfg);
+       if (rc < 0) {
+               dev_err(rvu->dev, "No mark_format_ctl for (pf:%d, vf:%d)",
+-                      rvu_get_pf(pcifunc), pcifunc & RVU_PFVF_FUNC_MASK);
++                      rvu_get_pf(rvu->pdev,  pcifunc),
++                                 pcifunc & RVU_PFVF_FUNC_MASK);
+               return NIX_AF_ERR_MARK_CFG_FAIL;
+       }
+@@ -2050,7 +2052,7 @@ static void nix_clear_tx_xoff(struct rvu *rvu, int blkaddr,
+ static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc)
+ {
+       struct rvu_hwinfo *hw = rvu->hw;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u8 cgx_id = 0, lmac_id = 0;
+       if (is_lbk_vf(rvu, pcifunc)) {/* LBK links */
+@@ -2068,7 +2070,7 @@ static void nix_get_txschq_range(struct rvu *rvu, u16 pcifunc,
+                                int link, int *start, int *end)
+ {
+       struct rvu_hwinfo *hw = rvu->hw;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       /* LBK links */
+       if (is_lbk_vf(rvu, pcifunc) || is_rep_dev(rvu, pcifunc)) {
+@@ -2426,7 +2428,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr,
+ {
+       struct nix_smq_flush_ctx *smq_flush_ctx;
+       int err, restore_tx_en = 0, i;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u8 cgx_id = 0, lmac_id = 0;
+       u16 tl2_tl3_link_schq;
+       u8 link, link_level;
+@@ -2820,7 +2822,7 @@ void rvu_nix_tx_tl2_cfg(struct rvu *rvu, int blkaddr, u16 pcifunc,
+ {
+       struct rvu_hwinfo *hw = rvu->hw;
+       int lbk_link_start, lbk_links;
+-      u8 pf = rvu_get_pf(pcifunc);
++      u8 pf = rvu_get_pf(rvu->pdev, pcifunc);
+       int schq;
+       u64 cfg;
+@@ -3190,7 +3192,8 @@ static int nix_blk_setup_mce(struct rvu *rvu, struct nix_hw *nix_hw,
+       err = rvu_nix_blk_aq_enq_inst(rvu, nix_hw, &aq_req, NULL);
+       if (err) {
+               dev_err(rvu->dev, "Failed to setup Bcast MCE for PF%d:VF%d\n",
+-                      rvu_get_pf(pcifunc), pcifunc & RVU_PFVF_FUNC_MASK);
++                      rvu_get_pf(rvu->pdev, pcifunc),
++                              pcifunc & RVU_PFVF_FUNC_MASK);
+               return err;
+       }
+       return 0;
+@@ -3458,7 +3461,7 @@ int nix_update_mce_list(struct rvu *rvu, u16 pcifunc,
+               dev_err(rvu->dev,
+                       "%s: Idx %d > max MCE idx %d, for PF%d bcast list\n",
+                       __func__, idx, mce_list->max,
+-                      pcifunc >> RVU_PFVF_PF_SHIFT);
++                      rvu_get_pf(rvu->pdev, pcifunc));
+               return -EINVAL;
+       }
+@@ -3510,7 +3513,8 @@ void nix_get_mce_list(struct rvu *rvu, u16 pcifunc, int type,
+       struct rvu_pfvf *pfvf;
+       if (!hw->cap.nix_rx_multicast ||
+-          !is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc & ~RVU_PFVF_FUNC_MASK))) {
++          !is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev,
++                           pcifunc & ~RVU_PFVF_FUNC_MASK))) {
+               *mce_list = NULL;
+               *mce_idx = 0;
+               return;
+@@ -3544,13 +3548,13 @@ static int nix_update_mce_rule(struct rvu *rvu, u16 pcifunc,
+       int pf;
+       /* skip multicast pkt replication for AF's VFs & SDP links */
+-      if (is_lbk_vf(rvu, pcifunc) || is_sdp_pfvf(pcifunc))
++      if (is_lbk_vf(rvu, pcifunc) || is_sdp_pfvf(rvu, pcifunc))
+               return 0;
+       if (!hw->cap.nix_rx_multicast)
+               return 0;
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       if (!is_pf_cgxmapped(rvu, pf))
+               return 0;
+@@ -3619,7 +3623,7 @@ static int nix_setup_mce_tables(struct rvu *rvu, struct nix_hw *nix_hw)
+               for (idx = 0; idx < (numvfs + 1); idx++) {
+                       /* idx-0 is for PF, followed by VFs */
+-                      pcifunc = (pf << RVU_PFVF_PF_SHIFT);
++                      pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+                       pcifunc |= idx;
+                       /* Add dummy entries now, so that we don't have to check
+                        * for whether AQ_OP should be INIT/WRITE later on.
+@@ -4554,7 +4558,7 @@ int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,
+ static void nix_find_link_frs(struct rvu *rvu,
+                             struct nix_frs_cfg *req, u16 pcifunc)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       struct rvu_pfvf *pfvf;
+       int maxlen, minlen;
+       int numvfs, hwvf;
+@@ -4601,7 +4605,7 @@ int rvu_mbox_handler_nix_set_hw_frs(struct rvu *rvu, struct nix_frs_cfg *req,
+ {
+       struct rvu_hwinfo *hw = rvu->hw;
+       u16 pcifunc = req->hdr.pcifunc;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       int blkaddr, link = -1;
+       struct nix_hw *nix_hw;
+       struct rvu_pfvf *pfvf;
+@@ -5251,7 +5255,7 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
+       rvu_switch_update_rules(rvu, pcifunc, true);
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
+               rvu_rep_notify_pfvf_state(rvu, pcifunc, true);
+@@ -5284,7 +5288,7 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
+       rvu_switch_update_rules(rvu, pcifunc, false);
+       rvu_cgx_tx_enable(rvu, pcifunc, true);
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
+               rvu_rep_notify_pfvf_state(rvu, pcifunc, false);
+       return 0;
+@@ -5296,7 +5300,7 @@ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
+ {
+       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+       struct hwctx_disable_req ctx_req;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       struct mac_ops *mac_ops;
+       u8 cgx_id, lmac_id;
+       u64 sa_base;
+@@ -5385,7 +5389,7 @@ static int rvu_nix_lf_ptp_tx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+       int nixlf;
+       u64 cfg;
+-      pf = rvu_get_pf(pcifunc);
++      pf = rvu_get_pf(rvu->pdev, pcifunc);
+       if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_PTP))
+               return 0;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index da15bb4511788..c7c70429eb6c1 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -147,7 +147,9 @@ static int npc_get_ucast_mcam_index(struct npc_mcam *mcam, u16 pcifunc,
+ int npc_get_nixlf_mcam_index(struct npc_mcam *mcam,
+                            u16 pcifunc, int nixlf, int type)
+ {
+-      int pf = rvu_get_pf(pcifunc);
++      struct rvu_hwinfo *hw = container_of(mcam, struct rvu_hwinfo, mcam);
++      struct rvu *rvu = hw->rvu;
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       int index;
+       /* Check if this is for a PF */
+@@ -698,7 +700,7 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
+       /* RX_ACTION set to MCAST for CGX PF's */
+       if (hw->cap.nix_rx_multicast && pfvf->use_mce_list &&
+-          is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) {
++          is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc))) {
+               *(u64 *)&action = 0;
+               action.op = NIX_RX_ACTIONOP_MCAST;
+               pfvf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
+@@ -3434,7 +3436,7 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
+ {
+       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+       int blkaddr, nixlf, rc, intf_mode;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u64 rxpkind, txpkind;
+       u8 cgx_id, lmac_id;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c
+index d2661e7fabdb4..999f6d93c7fe8 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c
+@@ -1465,7 +1465,7 @@ static int rvu_npc_exact_update_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_
+ int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
+ {
+       struct npc_exact_table *table;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u8 cgx_id, lmac_id;
+       u32 drop_mcam_idx;
+       bool *promisc;
+@@ -1512,7 +1512,7 @@ int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
+ int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
+ {
+       struct npc_exact_table *table;
+-      int pf = rvu_get_pf(pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u8 cgx_id, lmac_id;
+       u32 drop_mcam_idx;
+       bool *promisc;
+@@ -1560,7 +1560,7 @@ int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
+ int rvu_npc_exact_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
+                                struct msg_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u32 seq_id = req->index;
+       struct rvu_pfvf *pfvf;
+       u8 cgx_id, lmac_id;
+@@ -1593,7 +1593,7 @@ int rvu_npc_exact_mac_addr_update(struct rvu *rvu,
+                                 struct cgx_mac_addr_update_req *req,
+                                 struct cgx_mac_addr_update_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       struct npc_exact_table_entry *entry;
+       struct npc_exact_table *table;
+       struct rvu_pfvf *pfvf;
+@@ -1675,7 +1675,7 @@ int rvu_npc_exact_mac_addr_add(struct rvu *rvu,
+                              struct cgx_mac_addr_add_req *req,
+                              struct cgx_mac_addr_add_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       struct rvu_pfvf *pfvf;
+       u8 cgx_id, lmac_id;
+       int rc = 0;
+@@ -1711,7 +1711,7 @@ int rvu_npc_exact_mac_addr_del(struct rvu *rvu,
+                              struct cgx_mac_addr_del_req *req,
+                              struct msg_rsp *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       int rc;
+       rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
+@@ -1736,7 +1736,7 @@ int rvu_npc_exact_mac_addr_del(struct rvu *rvu,
+ int rvu_npc_exact_mac_addr_set(struct rvu *rvu, struct cgx_mac_addr_set_or_get *req,
+                              struct cgx_mac_addr_set_or_get *rsp)
+ {
+-      int pf = rvu_get_pf(req->hdr.pcifunc);
++      int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+       u32 seq_id = req->index;
+       struct rvu_pfvf *pfvf;
+       u8 cgx_id, lmac_id;
+@@ -2001,7 +2001,7 @@ int rvu_npc_exact_init(struct rvu *rvu)
+               }
+               /* Filter rules are only for PF */
+-              pcifunc = RVU_PFFUNC(i, 0);
++              pcifunc = RVU_PFFUNC(rvu->pdev, i, 0);
+               dev_dbg(rvu->dev,
+                       "%s:Drop rule cgx=%d lmac=%d chan(val=0x%llx, mask=0x%llx\n",
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h
+index 57a09328d46b5..cb25cf478f1fd 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h
+@@ -139,9 +139,7 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = {
+ #define NPC_MCAM_DROP_RULE_MAX 30
+ #define NPC_MCAM_SDP_DROP_RULE_IDX 0
+-#define RVU_PFFUNC(pf, func)  \
+-      ((((pf) & RVU_PFVF_PF_MASK) << RVU_PFVF_PF_SHIFT) | \
+-      (((func) & RVU_PFVF_FUNC_MASK) << RVU_PFVF_FUNC_SHIFT))
++#define RVU_PFFUNC(pdev, pf, func) rvu_make_pcifunc(pdev, pf, func)
+ enum npc_exact_opc_type {
+       NPC_EXACT_OPC_MEM,
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
+index 32953cca108c8..03099bc570bd5 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
+@@ -39,7 +39,7 @@ static int rvu_rep_up_notify(struct rvu *rvu, struct rep_event *event)
+       struct rep_event *msg;
+       int pf;
+-      pf = rvu_get_pf(event->pcifunc);
++      pf = rvu_get_pf(rvu->pdev, event->pcifunc);
+       if (event->event & RVU_EVENT_MAC_ADDR_CHANGE)
+               ether_addr_copy(pfvf->mac_addr, event->evt_data.mac);
+@@ -114,10 +114,10 @@ int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable)
+       struct rep_event *req;
+       int pf;
+-      if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
++      if (!is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)))
+               return 0;
+-      pf = rvu_get_pf(rvu->rep_pcifunc);
++      pf = rvu_get_pf(rvu->pdev, rvu->rep_pcifunc);
+       mutex_lock(&rvu->mbox_lock);
+       req = otx2_mbox_alloc_msg_rep_event_up_notify(rvu, pf);
+@@ -325,7 +325,7 @@ int rvu_rep_install_mcam_rules(struct rvu *rvu)
+               if (!is_pf_cgxmapped(rvu, pf))
+                       continue;
+-              pcifunc = pf << RVU_PFVF_PF_SHIFT;
++              pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+               rvu_get_nix_blkaddr(rvu, pcifunc);
+               rep = true;
+               for (i = 0; i < 2; i++) {
+@@ -345,8 +345,7 @@ int rvu_rep_install_mcam_rules(struct rvu *rvu)
+               rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
+               for (vf = 0; vf < numvfs; vf++) {
+-                      pcifunc = pf << RVU_PFVF_PF_SHIFT |
+-                                ((vf + 1) & RVU_PFVF_FUNC_MASK);
++                      pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf + 1);
+                       rvu_get_nix_blkaddr(rvu, pcifunc);
+                       /* Skip installimg rules if nixlf is not attached */
+@@ -454,7 +453,7 @@ int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
+       for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
+               if (!is_pf_cgxmapped(rvu, pf))
+                       continue;
+-              pcifunc = pf << RVU_PFVF_PF_SHIFT;
++              pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+               rvu->rep2pfvf_map[rep] = pcifunc;
+               rsp->rep_pf_map[rep] = pcifunc;
+               rep++;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+index 38cfe148f4b74..e4a5f9fa6fd46 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+@@ -17,9 +17,9 @@
+ /* SDP PF number */
+ static int sdp_pf_num[MAX_SDP] = {-1, -1};
+-bool is_sdp_pfvf(u16 pcifunc)
++bool is_sdp_pfvf(struct rvu *rvu, u16 pcifunc)
+ {
+-      u16 pf = rvu_get_pf(pcifunc);
++      u16 pf = rvu_get_pf(rvu->pdev, pcifunc);
+       u32 found = 0, i = 0;
+       while (i < MAX_SDP) {
+@@ -34,9 +34,9 @@ bool is_sdp_pfvf(u16 pcifunc)
+       return true;
+ }
+-bool is_sdp_pf(u16 pcifunc)
++bool is_sdp_pf(struct rvu *rvu, u16 pcifunc)
+ {
+-      return (is_sdp_pfvf(pcifunc) &&
++      return (is_sdp_pfvf(rvu, pcifunc) &&
+               !(pcifunc & RVU_PFVF_FUNC_MASK));
+ }
+@@ -46,7 +46,7 @@ bool is_sdp_vf(struct rvu *rvu, u16 pcifunc)
+       if (!(pcifunc & ~RVU_PFVF_FUNC_MASK))
+               return (rvu->vf_devid == RVU_SDP_VF_DEVID);
+-      return (is_sdp_pfvf(pcifunc) &&
++      return (is_sdp_pfvf(rvu, pcifunc) &&
+               !!(pcifunc & RVU_PFVF_FUNC_MASK));
+ }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
+index 268efb7c1c15d..49ce38685a7e6 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
+@@ -93,7 +93,7 @@ static int rvu_switch_install_rules(struct rvu *rvu)
+               if (!is_pf_cgxmapped(rvu, pf))
+                       continue;
+-              pcifunc = pf << 10;
++              pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+               /* rvu_get_nix_blkaddr sets up the corresponding NIX block
+                * address and NIX RX and TX interfaces for a pcifunc.
+                * Generally it is called during attach call of a pcifunc but it
+@@ -126,7 +126,7 @@ static int rvu_switch_install_rules(struct rvu *rvu)
+               rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
+               for (vf = 0; vf < numvfs; vf++) {
+-                      pcifunc = pf << 10 | ((vf + 1) & 0x3FF);
++                      pcifunc = rvu_make_pcifunc(rvu->pdev, pf, (vf + 1));
+                       rvu_get_nix_blkaddr(rvu, pcifunc);
+                       err = rvu_switch_install_rx_rule(rvu, pcifunc, 0x0);
+@@ -236,7 +236,7 @@ void rvu_switch_disable(struct rvu *rvu)
+               if (!is_pf_cgxmapped(rvu, pf))
+                       continue;
+-              pcifunc = pf << 10;
++              pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+               err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF);
+               if (err)
+                       dev_err(rvu->dev,
+@@ -248,7 +248,7 @@ void rvu_switch_disable(struct rvu *rvu)
+               rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
+               for (vf = 0; vf < numvfs; vf++) {
+-                      pcifunc = pf << 10 | ((vf + 1) & 0x3FF);
++                      pcifunc = rvu_make_pcifunc(rvu->pdev, pf, (vf + 1));
+                       err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF);
+                       if (err)
+                               dev_err(rvu->dev,
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
+index a6500e3673f24..c691f07221540 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
+@@ -481,7 +481,7 @@ static int cn10k_outb_write_sa(struct otx2_nic *pf, struct qmem *sa_info)
+               goto set_available;
+       /* Trigger CTX flush to write dirty data back to DRAM */
+-      reg_val = FIELD_PREP(CPT_LF_CTX_FLUSH, sa_iova >> 7);
++      reg_val = FIELD_PREP(CPT_LF_CTX_FLUSH_CPTR, sa_iova >> 7);
+       otx2_write64(pf, CN10K_CPT_LF_CTX_FLUSH, reg_val);
+ set_available:
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
+index 9965df0faa3e7..43fbce0d60390 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
+@@ -220,7 +220,7 @@ struct cpt_sg_s {
+ #define CPT_LF_Q_SIZE_DIV40 GENMASK_ULL(14, 0)
+ /* CPT LF CTX Flush Register */
+-#define CPT_LF_CTX_FLUSH GENMASK_ULL(45, 0)
++#define CPT_LF_CTX_FLUSH_CPTR GENMASK_ULL(45, 0)
+ #ifdef CONFIG_XFRM_OFFLOAD
+ int cn10k_ipsec_init(struct net_device *netdev);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index 5a6739d3a0688..f4fc915a0b5f1 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -28,6 +28,7 @@
+ #include "otx2_reg.h"
+ #include "otx2_txrx.h"
+ #include "otx2_devlink.h"
++#include <rvu.h>
+ #include <rvu_trace.h>
+ #include "qos.h"
+ #include "rep.h"
+@@ -900,21 +901,11 @@ MBOX_UP_MCS_MESSAGES
+ /* Time to wait before watchdog kicks off */
+ #define OTX2_TX_TIMEOUT               (100 * HZ)
+-#define       RVU_PFVF_PF_SHIFT       10
+-#define       RVU_PFVF_PF_MASK        0x3F
+-#define       RVU_PFVF_FUNC_SHIFT     0
+-#define       RVU_PFVF_FUNC_MASK      0x3FF
+-
+ static inline bool is_otx2_vf(u16 pcifunc)
+ {
+       return !!(pcifunc & RVU_PFVF_FUNC_MASK);
+ }
+-static inline int rvu_get_pf(u16 pcifunc)
+-{
+-      return (pcifunc >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
+-}
+-
+ static inline dma_addr_t otx2_dma_map_page(struct otx2_nic *pfvf,
+                                          struct page *page,
+                                          size_t offset, size_t size,
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index 74d0b6bac600a..c6d2f2249cc35 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -206,7 +206,8 @@ static int otx2_register_flr_me_intr(struct otx2_nic *pf, int numvfs)
+       /* Register ME interrupt handler*/
+       irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFME0 * NAME_SIZE];
+-      snprintf(irq_name, NAME_SIZE, "RVUPF%d_ME0", rvu_get_pf(pf->pcifunc));
++      snprintf(irq_name, NAME_SIZE, "RVUPF%d_ME0",
++               rvu_get_pf(pf->pdev, pf->pcifunc));
+       ret = request_irq(pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_VFME0),
+                         otx2_pf_me_intr_handler, 0, irq_name, pf);
+       if (ret) {
+@@ -216,7 +217,8 @@ static int otx2_register_flr_me_intr(struct otx2_nic *pf, int numvfs)
+       /* Register FLR interrupt handler */
+       irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFFLR0 * NAME_SIZE];
+-      snprintf(irq_name, NAME_SIZE, "RVUPF%d_FLR0", rvu_get_pf(pf->pcifunc));
++      snprintf(irq_name, NAME_SIZE, "RVUPF%d_FLR0",
++               rvu_get_pf(pf->pdev, pf->pcifunc));
+       ret = request_irq(pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_VFFLR0),
+                         otx2_pf_flr_intr_handler, 0, irq_name, pf);
+       if (ret) {
+@@ -228,7 +230,7 @@ static int otx2_register_flr_me_intr(struct otx2_nic *pf, int numvfs)
+       if (numvfs > 64) {
+               irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFME1 * NAME_SIZE];
+               snprintf(irq_name, NAME_SIZE, "RVUPF%d_ME1",
+-                       rvu_get_pf(pf->pcifunc));
++                       rvu_get_pf(pf->pdev, pf->pcifunc));
+               ret = request_irq(pci_irq_vector
+                                 (pf->pdev, RVU_PF_INT_VEC_VFME1),
+                                 otx2_pf_me_intr_handler, 0, irq_name, pf);
+@@ -238,7 +240,7 @@ static int otx2_register_flr_me_intr(struct otx2_nic *pf, int numvfs)
+               }
+               irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFFLR1 * NAME_SIZE];
+               snprintf(irq_name, NAME_SIZE, "RVUPF%d_FLR1",
+-                       rvu_get_pf(pf->pcifunc));
++                       rvu_get_pf(pf->pdev, pf->pcifunc));
+               ret = request_irq(pci_irq_vector
+                                 (pf->pdev, RVU_PF_INT_VEC_VFFLR1),
+                                 otx2_pf_flr_intr_handler, 0, irq_name, pf);
+@@ -701,7 +703,7 @@ static int otx2_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
+       irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFPF_MBOX0 * NAME_SIZE];
+       if (pf->pcifunc)
+               snprintf(irq_name, NAME_SIZE,
+-                       "RVUPF%d_VF Mbox0", rvu_get_pf(pf->pcifunc));
++                       "RVUPF%d_VF Mbox0", rvu_get_pf(pf->pdev, pf->pcifunc));
+       else
+               snprintf(irq_name, NAME_SIZE, "RVUPF_VF Mbox0");
+       err = request_irq(pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_VFPF_MBOX0),
+@@ -717,7 +719,8 @@ static int otx2_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
+               irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFPF_MBOX1 * NAME_SIZE];
+               if (pf->pcifunc)
+                       snprintf(irq_name, NAME_SIZE,
+-                               "RVUPF%d_VF Mbox1", rvu_get_pf(pf->pcifunc));
++                               "RVUPF%d_VF Mbox1",
++                               rvu_get_pf(pf->pdev, pf->pcifunc));
+               else
+                       snprintf(irq_name, NAME_SIZE, "RVUPF_VF Mbox1");
+               err = request_irq(pci_irq_vector(pf->pdev,
+@@ -1972,7 +1975,7 @@ int otx2_open(struct net_device *netdev)
+       if (err) {
+               dev_err(pf->dev,
+                       "RVUPF%d: IRQ registration failed for QERR\n",
+-                      rvu_get_pf(pf->pcifunc));
++                      rvu_get_pf(pf->pdev, pf->pcifunc));
+               goto err_disable_napi;
+       }
+@@ -1990,7 +1993,7 @@ int otx2_open(struct net_device *netdev)
+               if (name_len >= NAME_SIZE) {
+                       dev_err(pf->dev,
+                               "RVUPF%d: IRQ registration failed for CQ%d, irq name is too long\n",
+-                              rvu_get_pf(pf->pcifunc), qidx);
++                              rvu_get_pf(pf->pdev, pf->pcifunc), qidx);
+                       err = -EINVAL;
+                       goto err_free_cints;
+               }
+@@ -2001,7 +2004,7 @@ int otx2_open(struct net_device *netdev)
+               if (err) {
+                       dev_err(pf->dev,
+                               "RVUPF%d: IRQ registration failed for CQ%d\n",
+-                              rvu_get_pf(pf->pcifunc), qidx);
++                              rvu_get_pf(pf->pdev, pf->pcifunc), qidx);
+                       goto err_free_cints;
+               }
+               vec++;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h
+index e3aee6e362151..858f084b9d474 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h
+@@ -138,36 +138,6 @@
+ #define       NIX_LF_CINTX_ENA_W1S(a)         (NIX_LFBASE | 0xD40 | (a) << 12)
+ #define       NIX_LF_CINTX_ENA_W1C(a)         (NIX_LFBASE | 0xD50 | (a) << 12)
+-/* NIX AF transmit scheduler registers */
+-#define NIX_AF_SMQX_CFG(a)            (0x700 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_SDP_LINK_CFG(a)   (0xB10 | (u64)(a) << 16)
+-#define NIX_AF_TL1X_SCHEDULE(a)               (0xC00 | (u64)(a) << 16)
+-#define NIX_AF_TL1X_CIR(a)            (0xC20 | (u64)(a) << 16)
+-#define NIX_AF_TL1X_TOPOLOGY(a)               (0xC80 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_PARENT(a)         (0xE88 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_SCHEDULE(a)               (0xE00 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_TOPOLOGY(a)               (0xE80 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_CIR(a)            (0xE20 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_PIR(a)            (0xE30 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_PARENT(a)         (0x1088 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_SCHEDULE(a)               (0x1000 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_SHAPE(a)          (0x1010 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_CIR(a)            (0x1020 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_PIR(a)            (0x1030 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_TOPOLOGY(a)               (0x1080 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_PARENT(a)         (0x1288 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_SCHEDULE(a)               (0x1200 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_SHAPE(a)          (0x1210 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_CIR(a)            (0x1220 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_PIR(a)            (0x1230 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_TOPOLOGY(a)               (0x1280 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_SCHEDULE(a)               (0x1400 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_SHAPE(a)          (0x1410 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_CIR(a)            (0x1420 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_PIR(a)            (0x1430 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_PARENT(a)         (0x1480 | (u64)(a) << 16)
+-#define NIX_AF_TL3_TL2X_LINKX_CFG(a, b)       (0x1700 | (u64)(a) << 16 | (b) << 3)
+-
+ /* LMT LF registers */
+ #define LMT_LFBASE                    BIT_ULL(RVU_FUNC_BLKADDR_SHIFT)
+ #define LMT_LF_LMTLINEX(a)            (LMT_LFBASE | 0x000 | (a) << 12)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+index 9a226ca744254..5f80b23c5335c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+@@ -467,7 +467,8 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic,
+                       target = act->dev;
+                       if (target->dev.parent) {
+                               priv = netdev_priv(target);
+-                              if (rvu_get_pf(nic->pcifunc) != rvu_get_pf(priv->pcifunc)) {
++                              if (rvu_get_pf(nic->pdev, nic->pcifunc) !=
++                                      rvu_get_pf(nic->pdev, priv->pcifunc)) {
+                                       NL_SET_ERR_MSG_MOD(extack,
+                                                          "can't redirect to other pf/vf");
+                                       return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+index d97be15d80561..b476733a02345 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+@@ -244,10 +244,10 @@ static int rvu_rep_devlink_port_register(struct rep_dev *rep)
+       if (!(rep->pcifunc & RVU_PFVF_FUNC_MASK)) {
+               attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+-              attrs.phys.port_number = rvu_get_pf(rep->pcifunc);
++              attrs.phys.port_number = rvu_get_pf(priv->pdev, rep->pcifunc);
+       } else {
+               attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF;
+-              attrs.pci_vf.pf = rvu_get_pf(rep->pcifunc);
++              attrs.pci_vf.pf = rvu_get_pf(priv->pdev, rep->pcifunc);
+               attrs.pci_vf.vf = rep->pcifunc & RVU_PFVF_FUNC_MASK;
+       }
+@@ -683,7 +683,8 @@ int rvu_rep_create(struct otx2_nic *priv, struct netlink_ext_ack *extack)
+               rep->pcifunc = pcifunc;
+               snprintf(ndev->name, sizeof(ndev->name), "Rpf%dvf%d",
+-                       rvu_get_pf(pcifunc), (pcifunc & RVU_PFVF_FUNC_MASK));
++                       rvu_get_pf(priv->pdev, pcifunc),
++                       (pcifunc & RVU_PFVF_FUNC_MASK));
+               ndev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
+                              NETIF_F_IPV6_CSUM | NETIF_F_RXHASH |
+diff --git a/include/linux/soc/marvell/silicons.h b/include/linux/soc/marvell/silicons.h
+new file mode 100644
+index 0000000000000..66bb9bfaf17d5
+--- /dev/null
++++ b/include/linux/soc/marvell/silicons.h
+@@ -0,0 +1,25 @@
++/* SPDX-License-Identifier: GPL-2.0-only
++ * Copyright (C) 2024 Marvell.
++ */
++
++#ifndef __SOC_SILICON_H
++#define __SOC_SILICON_H
++
++#include <linux/types.h>
++#include <linux/pci.h>
++
++#if defined(CONFIG_ARM64)
++
++#define CN20K_CHIPID  0x20
++/*
++ * Silicon check for CN20K family
++ */
++static inline bool is_cn20k(struct pci_dev *pdev)
++{
++      return (pdev->subsystem_device & 0xFF) == CN20K_CHIPID;
++}
++#else
++#define is_cn20k(pdev)                ((void)(pdev), 0)
++#endif
++
++#endif /* __SOC_SILICON_H */
+-- 
+2.50.1
+
diff --git a/queue-6.16/octeontx2-vf-fix-max-packet-length-errors.patch b/queue-6.16/octeontx2-vf-fix-max-packet-length-errors.patch
new file mode 100644 (file)
index 0000000..6256088
--- /dev/null
@@ -0,0 +1,156 @@
+From 650741f3c3c07fe4b4ca8278ea3f501591d98e1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 11:55:28 +0530
+Subject: Octeontx2-vf: Fix max packet length errors
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit a64494aafc56939564e3e9e57f99df5c27204e04 ]
+
+Once driver submits the packets to the hardware, each packet
+traverse through multiple transmit levels in the following
+order:
+       SMQ -> TL4 -> TL3 -> TL2 -> TL1
+
+The SMQ supports configurable minimum and maximum packet sizes.
+It enters to a hang state, if driver submits packets with
+out of bound lengths.
+
+To avoid the same, implement packet length validation before
+submitting packets to the hardware. Increment tx_dropped counter
+on failure.
+
+Fixes: 3184fb5ba96e ("octeontx2-vf: Virtual function driver support")
+Fixes: 22f858796758 ("octeontx2-pf: Add basic net_device_ops")
+Fixes: 3ca6c4c882a7 ("octeontx2-pf: Add packet transmission support")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Link: https://patch.msgid.link/20250821062528.1697992-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/nic/otx2_common.c    |  4 +++-
+ .../ethernet/marvell/octeontx2/nic/otx2_common.h    |  1 +
+ .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c    |  3 +++
+ .../net/ethernet/marvell/octeontx2/nic/otx2_vf.c    | 10 ++++++++++
+ drivers/net/ethernet/marvell/octeontx2/nic/rep.c    | 13 ++++++++++++-
+ drivers/net/ethernet/marvell/octeontx2/nic/rep.h    |  1 +
+ 6 files changed, 30 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index 6b5c9536d26d3..6f7b608261d9c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -124,7 +124,9 @@ void otx2_get_dev_stats(struct otx2_nic *pfvf)
+                              dev_stats->rx_ucast_frames;
+       dev_stats->tx_bytes = OTX2_GET_TX_STATS(TX_OCTS);
+-      dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP);
++      dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP) +
++                             (unsigned long)atomic_long_read(&dev_stats->tx_discards);
++
+       dev_stats->tx_bcast_frames = OTX2_GET_TX_STATS(TX_BCAST);
+       dev_stats->tx_mcast_frames = OTX2_GET_TX_STATS(TX_MCAST);
+       dev_stats->tx_ucast_frames = OTX2_GET_TX_STATS(TX_UCAST);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index ca0e6ab12cebe..5a6739d3a0688 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -149,6 +149,7 @@ struct otx2_dev_stats {
+       u64 tx_bcast_frames;
+       u64 tx_mcast_frames;
+       u64 tx_drops;
++      atomic_long_t tx_discards;
+ };
+ /* Driver counted stats */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index db7c466fdc39e..74d0b6bac600a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -2153,6 +2153,7 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
+ {
+       struct otx2_nic *pf = netdev_priv(netdev);
+       int qidx = skb_get_queue_mapping(skb);
++      struct otx2_dev_stats *dev_stats;
+       struct otx2_snd_queue *sq;
+       struct netdev_queue *txq;
+       int sq_idx;
+@@ -2165,6 +2166,8 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
+       /* Check for minimum and maximum packet length */
+       if (skb->len <= ETH_HLEN ||
+           (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) {
++              dev_stats = &pf->hw.dev_stats;
++              atomic_long_inc(&dev_stats->tx_discards);
+               dev_kfree_skb(skb);
+               return NETDEV_TX_OK;
+       }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+index 8a8b598bd389b..76dd2e965cf03 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+@@ -391,9 +391,19 @@ static netdev_tx_t otx2vf_xmit(struct sk_buff *skb, struct net_device *netdev)
+ {
+       struct otx2_nic *vf = netdev_priv(netdev);
+       int qidx = skb_get_queue_mapping(skb);
++      struct otx2_dev_stats *dev_stats;
+       struct otx2_snd_queue *sq;
+       struct netdev_queue *txq;
++      /* Check for minimum and maximum packet length */
++      if (skb->len <= ETH_HLEN ||
++          (!skb_shinfo(skb)->gso_size && skb->len > vf->tx_max_pktlen)) {
++              dev_stats = &vf->hw.dev_stats;
++              atomic_long_inc(&dev_stats->tx_discards);
++              dev_kfree_skb(skb);
++              return NETDEV_TX_OK;
++      }
++
+       sq = &vf->qset.sq[qidx];
+       txq = netdev_get_tx_queue(netdev, qidx);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+index 2cd3da3b68432..d97be15d80561 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+@@ -371,7 +371,8 @@ static void rvu_rep_get_stats(struct work_struct *work)
+       stats->rx_mcast_frames = rsp->rx.mcast;
+       stats->tx_bytes = rsp->tx.octs;
+       stats->tx_frames = rsp->tx.ucast + rsp->tx.bcast + rsp->tx.mcast;
+-      stats->tx_drops = rsp->tx.drop;
++      stats->tx_drops = rsp->tx.drop +
++                        (unsigned long)atomic_long_read(&stats->tx_discards);
+ exit:
+       mutex_unlock(&priv->mbox.lock);
+ }
+@@ -418,6 +419,16 @@ static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device *dev)
+       struct otx2_nic *pf = rep->mdev;
+       struct otx2_snd_queue *sq;
+       struct netdev_queue *txq;
++      struct rep_stats *stats;
++
++      /* Check for minimum and maximum packet length */
++      if (skb->len <= ETH_HLEN ||
++          (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) {
++              stats = &rep->stats;
++              atomic_long_inc(&stats->tx_discards);
++              dev_kfree_skb(skb);
++              return NETDEV_TX_OK;
++      }
+       sq = &pf->qset.sq[rep->rep_id];
+       txq = netdev_get_tx_queue(dev, 0);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.h b/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
+index 38446b3e4f13c..5bc9e2c7d800b 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
+@@ -27,6 +27,7 @@ struct rep_stats {
+       u64 tx_bytes;
+       u64 tx_frames;
+       u64 tx_drops;
++      atomic_long_t tx_discards;
+ };
+ struct rep_dev {
+-- 
+2.50.1
+
diff --git a/queue-6.16/of-reserved_mem-restructure-call-site-for-dma_contig.patch b/queue-6.16/of-reserved_mem-restructure-call-site-for-dma_contig.patch
new file mode 100644 (file)
index 0000000..575cbe4
--- /dev/null
@@ -0,0 +1,101 @@
+From 011cc4693733b49f9ce512a632963bc49f95b7ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Aug 2025 10:24:21 -0700
+Subject: of: reserved_mem: Restructure call site for
+ dma_contiguous_early_fixup()
+
+From: Oreoluwa Babatunde <oreoluwa.babatunde@oss.qualcomm.com>
+
+[ Upstream commit 2c223f7239f376a90d71903ec474ba887cf21d94 ]
+
+Restructure the call site for dma_contiguous_early_fixup() to
+where the reserved_mem nodes are being parsed from the DT so that
+dma_mmu_remap[] is populated before dma_contiguous_remap() is called.
+
+Fixes: 8a6e02d0c00e ("of: reserved_mem: Restructure how the reserved memory regions are processed")
+Signed-off-by: Oreoluwa Babatunde <oreoluwa.babatunde@oss.qualcomm.com>
+Tested-by: William Zhang <william.zhang@broadcom.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20250806172421.2748302-1-oreoluwa.babatunde@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/of_reserved_mem.c | 16 ++++++++++++----
+ include/linux/dma-map-ops.h  |  3 +++
+ kernel/dma/contiguous.c      |  2 --
+ 3 files changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
+index d3b7c4ae429c7..2e9ea751ed2df 100644
+--- a/drivers/of/of_reserved_mem.c
++++ b/drivers/of/of_reserved_mem.c
+@@ -25,6 +25,7 @@
+ #include <linux/memblock.h>
+ #include <linux/kmemleak.h>
+ #include <linux/cma.h>
++#include <linux/dma-map-ops.h>
+ #include "of_private.h"
+@@ -175,13 +176,17 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
+               base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+               size = dt_mem_next_cell(dt_root_size_cells, &prop);
+-              if (size &&
+-                  early_init_dt_reserve_memory(base, size, nomap) == 0)
++              if (size && early_init_dt_reserve_memory(base, size, nomap) == 0) {
++                      /* Architecture specific contiguous memory fixup. */
++                      if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++                          of_get_flat_dt_prop(node, "reusable", NULL))
++                              dma_contiguous_early_fixup(base, size);
+                       pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
+                               uname, &base, (unsigned long)(size / SZ_1M));
+-              else
++              } else {
+                       pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
+                              uname, &base, (unsigned long)(size / SZ_1M));
++              }
+               len -= t_len;
+       }
+@@ -472,7 +477,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
+                      uname, (unsigned long)(size / SZ_1M));
+               return -ENOMEM;
+       }
+-
++      /* Architecture specific contiguous memory fixup. */
++      if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++          of_get_flat_dt_prop(node, "reusable", NULL))
++              dma_contiguous_early_fixup(base, size);
+       /* Save region in the reserved_mem array */
+       fdt_reserved_mem_save_node(node, uname, base, size);
+       return 0;
+diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
+index f48e5fb88bd5d..332b80c42b6f3 100644
+--- a/include/linux/dma-map-ops.h
++++ b/include/linux/dma-map-ops.h
+@@ -153,6 +153,9 @@ static inline void dma_free_contiguous(struct device *dev, struct page *page,
+ {
+       __free_pages(page, get_order(size));
+ }
++static inline void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
++{
++}
+ #endif /* CONFIG_DMA_CMA*/
+ #ifdef CONFIG_DMA_DECLARE_COHERENT
+diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
+index 67af8a55185d9..d9b9dcba6ff7c 100644
+--- a/kernel/dma/contiguous.c
++++ b/kernel/dma/contiguous.c
+@@ -483,8 +483,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
+               pr_err("Reserved memory: unable to setup CMA region\n");
+               return err;
+       }
+-      /* Architecture specific contiguous memory fixup. */
+-      dma_contiguous_early_fixup(rmem->base, rmem->size);
+       if (default_cma)
+               dma_contiguous_default_area = cma;
+-- 
+2.50.1
+
diff --git a/queue-6.16/page_pool-fix-incorrect-mp_ops-error-handling.patch b/queue-6.16/page_pool-fix-incorrect-mp_ops-error-handling.patch
new file mode 100644 (file)
index 0000000..2fbf095
--- /dev/null
@@ -0,0 +1,46 @@
+From c53ae8ac389477d45e1cc59d48be124c3c8e7ff8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 03:03:46 +0000
+Subject: page_pool: fix incorrect mp_ops error handling
+
+From: Mina Almasry <almasrymina@google.com>
+
+[ Upstream commit abadf0ff63be488dc502ecfc9f622929a21b7117 ]
+
+Minor fix to the memory provider error handling, we should be jumping to
+free_ptr_ring in this error case rather than returning directly.
+
+Found by code-inspection.
+
+Cc: skhawaja@google.com
+
+Fixes: b400f4b87430 ("page_pool: Set `dma_sync` to false for devmem memory provider")
+Signed-off-by: Mina Almasry <almasrymina@google.com>
+Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
+Link: https://patch.msgid.link/20250821030349.705244-1-almasrymina@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/page_pool.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/page_pool.c b/net/core/page_pool.c
+index 368412baad264..e14d743554ec1 100644
+--- a/net/core/page_pool.c
++++ b/net/core/page_pool.c
+@@ -287,8 +287,10 @@ static int page_pool_init(struct page_pool *pool,
+       }
+       if (pool->mp_ops) {
+-              if (!pool->dma_map || !pool->dma_sync)
+-                      return -EOPNOTSUPP;
++              if (!pool->dma_map || !pool->dma_sync) {
++                      err = -EOPNOTSUPP;
++                      goto free_ptr_ring;
++              }
+               if (WARN_ON(!is_kernel_rodata((unsigned long)pool->mp_ops))) {
+                       err = -EFAULT;
+-- 
+2.50.1
+
diff --git a/queue-6.16/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch b/queue-6.16/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
new file mode 100644 (file)
index 0000000..843a53d
--- /dev/null
@@ -0,0 +1,135 @@
+From 203965066ac6acb399e44104df66d14c343cebad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h      |  4 ++++
+ drivers/net/phy/mscc/mscc_main.c |  4 +---
+ drivers/net/phy/mscc/mscc_ptp.c  | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 58c6d47fbe046..2bfe314ef881c 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -481,6 +481,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -495,6 +496,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+       return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+       return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index c3209cf00e960..ac9b6130ef502 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2338,9 +2338,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *priv = phydev->priv;
+-
+-      skb_queue_purge(&priv->rx_skbs_list);
++      vsc8584_ptp_deinit(phydev);
+ }
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index de6c7312e8f29..72847320cb652 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1298,7 +1298,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *vsc8531 = phydev->priv;
+       static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+       static const u8  ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+       u32 val;
+@@ -1515,17 +1514,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+       vsc85xx_ts_eth_cmp1_sig(phydev);
+-      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+-      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+-      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+-      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
+-      phydev->mii_ts = &vsc8531->mii_ts;
+-
+-      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+-      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+-                                                   &phydev->mdio.dev);
+-      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++      return 0;
+ }
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1552,6 +1541,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+       return 0;
+ }
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++      struct vsc8531_private *vsc8531 = phydev->priv;
++
++      if (vsc8531->ptp->ptp_clock) {
++              ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++              skb_queue_purge(&vsc8531->rx_skbs_list);
++      }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+       struct vsc8531_private *priv = phydev->priv;
+@@ -1612,7 +1611,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+       vsc8531->ptp->phydev = phydev;
+-      return 0;
++      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
++      phydev->mii_ts = &vsc8531->mii_ts;
++
++      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++                                                   &phydev->mdio.dev);
++      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+-- 
+2.50.1
+
diff --git a/queue-6.16/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch b/queue-6.16/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
new file mode 100644 (file)
index 0000000..a4f0882
--- /dev/null
@@ -0,0 +1,68 @@
+From c95e064ba88c7e1c685a340d958000e362bea7a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf..7209d00a9c257 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+       }
+-      switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++      switch (inst_no_rt & ~KVM_MASK_RB) {
+       case KVM_INST_MTSRIN:
+               if (features & KVM_MAGIC_FEAT_SR) {
+                       u32 inst_rb = _inst & KVM_MASK_RB;
+                       kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+               }
+               break;
+-#endif
+       }
++#endif
+-      switch (_inst) {
+ #ifdef CONFIG_BOOKE
++      switch (_inst) {
+       case KVM_INST_WRTEEI_0:
+               kvm_patch_ins_wrteei_0(inst);
+               break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+       case KVM_INST_WRTEEI_1:
+               kvm_patch_ins_wrtee(inst, 0, 1);
+               break;
+-#endif
+       }
++#endif
+ }
+ extern u32 kvm_template_start[];
+-- 
+2.50.1
+
diff --git a/queue-6.16/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch b/queue-6.16/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
new file mode 100644 (file)
index 0000000..850ab6c
--- /dev/null
@@ -0,0 +1,72 @@
+From fa513dc18c41cbc491a7e1c04372864eab73042d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+  sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+  sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+  sctp_get_port net/sctp/socket.c:8523 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+  x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+  do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+  sctp_get_port net/sctp/socket.c:8515 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index a9ed2ccab1bdb..2bb5e19e10caa 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -546,7 +546,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+       addr->v6.sin6_family = AF_INET6;
+       addr->v6.sin6_port = 0;
++      addr->v6.sin6_flowinfo = 0;
+       addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++      addr->v6.sin6_scope_id = 0;
+ }
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+-- 
+2.50.1
+
index 848ae1e826b01a5b9e3c94444129b29648673c10..445048d92ab892b3d28fb979ba3467ee2cec7fb1 100644 (file)
@@ -25,3 +25,79 @@ erofs-fix-atomic-context-detection-when-config_debug.patch
 io_uring-io-wq-add-check-free-worker-before-create-n.patch
 platform-x86-int3472-add-hpd-pin-support.patch
 vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+drm-msm-defer-fd_install-in-submit-ioctl.patch
+of-reserved_mem-restructure-call-site-for-dma_contig.patch
+hid-intel-thc-hid-intel-quicki2c-fix-acpi-dsd-icrs-i.patch
+hid-intel-thc-hid-intel-thc-fix-incorrect-pointer-ar.patch
+hid-intel-thc-hid-intel-quicki2c-enhance-driver-re-i.patch
+drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch
+drm-msm-dpu-correct-dpu_plane_virtual_atomic_check.patch
+drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch
+drm-mediatek-add-error-handling-for-old-state-crtc-i.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+hid-input-rename-hidinput_set_battery_charge_status.patch
+hid-input-report-battery-status-changes-immediately.patch
+idpf-add-support-for-tx-refillqs-in-flow-scheduling-.patch
+idpf-simplify-and-fix-splitq-tx-packet-rollback-erro.patch
+idpf-replace-flow-scheduling-buffer-ring-with-buffer.patch
+idpf-stop-tx-if-there-are-insufficient-buffer-resour.patch
+net-macb-fix-unregister_netdev-call-order-in-macb_re.patch
+bluetooth-hci_conn-make-unacked-packet-handling-more.patch
+bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
+bluetooth-hci_event-mark-connection-as-closed-during.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+bluetooth-hci_event-disconnect-device-when-big-sync-.patch
+bluetooth-hci_sync-fix-set_local_name-race-condition.patch
+page_pool-fix-incorrect-mp_ops-error-handling.patch
+octeontx2-vf-fix-max-packet-length-errors.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
+drm-nouveau-remove-unused-memory-target-test.patch
+ice-fix-null-pointer-dereference-in-ice_unplug_aux_d.patch
+ice-don-t-leave-device-non-functional-if-tx-schedule.patch
+ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch
+ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
+ixgbe-fix-ixgbe_orom_civd_info-struct-layout.patch
+dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
+drm-msm-dpu-add-a-null-ptr-check-for-dpu_encoder_nee.patch
+octeontx2-set-appropriate-pf-vf-masks-and-shifts-bas.patch
+octeontx2-af-fix-nix-x2p-calibration-failures.patch
+misdn-hfcpci-fix-warning-when-deleting-uninitialized.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+efi-stmm-fix-incorrect-buffer-allocation-method.patch
+drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch
+drm-xe-vm-don-t-pin-the-vm_resv-during-validation.patch
+drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch
+block-validate-qos-before-calling-__rq_qos_done_bio.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+net-macb-fix-offset-error-in-gem_update_stats.patch
+bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch
+bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch
+bnxt_en-fix-stats-context-reservation-logic.patch
+net-mlx5-hws-fix-memory-leak-in-hws_pool_buddy_init-.patch
+net-mlx5-hws-fix-memory-leak-in-hws_action_get_share.patch
+net-mlx5-hws-fix-uninitialized-variables-in-mlx5hws_.patch
+net-mlx5-hws-fix-pattern-destruction-in-mlx5hws_pat_.patch
+net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
+net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
+net-mlx5-nack-sync-reset-when-sfs-are-present.patch
+net-mlx5-prevent-flow-steering-mode-changes-in-switc.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+net-stmmac-xgmac-correct-supported-speed-modes.patch
+net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
+net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch
+io_uring-kbuf-fix-signedness-in-this_len-calculation.patch
+net-rose-split-remove-and-free-operations-in-rose_re.patch
+net-rose-convert-use-field-to-refcount_t.patch
+net-rose-include-node-references-in-rose_neigh-refco.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch
+fbnic-move-phylink-resume-out-of-service_task-and-in.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
+net-macb-disable-clocks-once.patch
+io_uring-kbuf-always-use-read_once-to-read-ring-prov.patch
+drm-mediatek-mtk_hdmi-fix-inverted-parameters-in-som.patch
diff --git a/queue-6.6/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch b/queue-6.6/atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
new file mode 100644 (file)
index 0000000..0c21e58
--- /dev/null
@@ -0,0 +1,192 @@
+From b5f82bcf10808933c86a10e78ef2e0f3efb0e4ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+  struct atmtcp_control {
+       struct atmtcp_hdr hdr;  /* must be first */
+  ...
+       atm_kptr_t vcc;         /* both directions */
+  ...
+  } __ATM_API_ALIGN;
+
+  typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+  1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+  2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS:  00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 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+0x19b/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
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c   | 17 ++++++++++++++---
+ include/linux/atmdev.h |  1 +
+ net/atm/common.c       | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index ff558908897f3..9c83fb29b2f1b 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+         return NULL;
+ }
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++      struct atmtcp_hdr *hdr;
++
++      if (skb->len < sizeof(struct atmtcp_hdr))
++              return -EINVAL;
++
++      hdr = (struct atmtcp_hdr *)skb->data;
++      if (hdr->length == ATMTCP_HDR_MAGIC)
++              return -EINVAL;
++
++      return 0;
++}
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+       struct sk_buff *new_skb;
+       int result = 0;
+-      if (skb->len < sizeof(struct atmtcp_hdr))
+-              goto done;
+-
+       dev = vcc->dev_data;
+       hdr = (struct atmtcp_hdr *) skb->data;
+       if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+       .close          = atmtcp_c_close,
++      .pre_send       = atmtcp_c_pre_send,
+       .send           = atmtcp_c_send
+ };
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+       int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+                           void __user *arg);
+ #endif
++      int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+       int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+       int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 9cc82acbc7358..48bb3f66a3f2a 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+       skb->dev = NULL; /* for paths shared with net_device interfaces */
+       if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+-              atm_return_tx(vcc, skb);
+-              kfree_skb(skb);
+               error = -EFAULT;
+-              goto out;
++              goto free_skb;
+       }
+       if (eff != size)
+               memset(skb->data + size, 0, eff-size);
++
++      if (vcc->dev->ops->pre_send) {
++              error = vcc->dev->ops->pre_send(vcc, skb);
++              if (error)
++                      goto free_skb;
++      }
++
+       error = vcc->dev->ops->send(vcc, skb);
+       error = error ? error : size;
+ out:
+       release_sock(sk);
+       return error;
++free_skb:
++      atm_return_tx(vcc, skb);
++      kfree_skb(skb);
++      goto out;
+ }
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+-- 
+2.50.1
+
diff --git a/queue-6.6/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch b/queue-6.6/bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
new file mode 100644 (file)
index 0000000..b255bb7
--- /dev/null
@@ -0,0 +1,47 @@
+From 4fc487d1c4efa2becb85150b0763d1918b00dcee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index a07ad1c99a4b0..5eed23b8d6c33 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4392,7 +4392,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+               if (!conn)
+                       continue;
+-              conn->sent -= count;
++              /* Check if there is really enough packets outstanding before
++               * attempting to decrease the sent counter otherwise it could
++               * underflow..
++               */
++              if (conn->sent >= count) {
++                      conn->sent -= count;
++              } else {
++                      bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++                                  conn, conn->sent, count);
++                      conn->sent = 0;
++              }
+               switch (conn->type) {
+               case ACL_LINK:
+-- 
+2.50.1
+
diff --git a/queue-6.6/bluetooth-hci_event-mark-connection-as-closed-during.patch b/queue-6.6/bluetooth-hci_event-mark-connection-as-closed-during.patch
new file mode 100644 (file)
index 0000000..fbc7f83
--- /dev/null
@@ -0,0 +1,80 @@
+From e96a8d41136d799832dc0a75f3ef866fed855b78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:27 +0200
+Subject: Bluetooth: hci_event: Mark connection as closed during suspend
+ disconnect
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit b7fafbc499b5ee164018eb0eefe9027f5a6aaad2 ]
+
+When suspending, the disconnect command for an active Bluetooth
+connection could be issued, but the corresponding
+`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
+completes the suspend process. This can lead to an inconsistent state.
+
+On resume, the controller may auto-accept reconnections from the same
+device (due to suspend event filters), but these new connections are
+rejected by the kernel which still has connection objects from before
+suspend. Resulting in errors like:
+```
+kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
+kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
+connection
+```
+
+This is a btmon snippet that shows the issue:
+```
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+        Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+        Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+      Disconnect (0x01|0x0006) ncmd 2
+        Status: Success (0x00)
+[...]
+// Host suspends with the event filter set for the device
+// On resume, the device tries to reconnect with a new handle
+
+> HCI Event: Connect Complete (0x03) plen 11
+        Status: Success (0x00)
+        Handle: 2
+        Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+
+// Kernel ignores this event because there is an existing connection
+with
+// handle 1
+```
+
+By explicitly setting the connection state to BT_CLOSED we can ensure a
+consistent state, even if we don't receive the disconnect complete event
+in time.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index fb5e4e4858f77..a07ad1c99a4b0 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2707,6 +2707,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+               goto done;
+       }
++      /* During suspend, mark connection as closed immediately
++       * since we might not receive HCI_EV_DISCONN_COMPLETE
++       */
++      if (hdev->suspended)
++              conn->state = BT_CLOSED;
++
+       mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+       if (conn->type == ACL_LINK) {
+-- 
+2.50.1
+
diff --git a/queue-6.6/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch b/queue-6.6/bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
new file mode 100644 (file)
index 0000000..57d390a
--- /dev/null
@@ -0,0 +1,84 @@
+From 20ddcc5dba9be8ec57cb33fae759b1ba02e0815e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:26 +0200
+Subject: Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit 2f050a5392b7a0928bf836d9891df4851463512c ]
+
+When the host sends an HCI_OP_DISCONNECT command, the controller may
+respond with the status HCI_ERROR_UNKNOWN_CONN_ID (0x02). E.g. this can
+happen on resume from suspend, if the link was terminated by the remote
+device before the event mask was correctly set.
+
+This is a btmon snippet that shows the issue:
+```
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+      L2CAP: Disconnection Request (0x06) ident 5 len 4
+        Destination CID: 65
+        Source CID: 72
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+      L2CAP: Disconnection Response (0x07) ident 5 len 4
+        Destination CID: 65
+        Source CID: 72
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+      L2CAP: Disconnection Request (0x06) ident 6 len 4
+        Destination CID: 64
+        Source CID: 71
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+      L2CAP: Disconnection Response (0x07) ident 6 len 4
+        Destination CID: 64
+        Source CID: 71
+< HCI Command: Set Event Mask (0x03|0x0001) plen 8
+        Mask: 0x3dbff807fffbffff
+          Inquiry Complete
+          Inquiry Result
+          Connection Complete
+          Connection Request
+          Disconnection Complete
+          Authentication Complete
+[...]
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+        Handle: 3 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+        Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+      Disconnect (0x01|0x0006) ncmd 1
+        Status: Unknown Connection Identifier (0x02)
+```
+
+Currently, the hci_cs_disconnect function treats any non-zero status
+as a command failure. This can be misleading because the connection is
+indeed being terminated and the controller is confirming that is has no
+knowledge of that connection handle. Meaning that the initial request of
+disconnecting a device should be treated as done.
+
+With this change we allow the function to proceed, following the success
+path, which correctly calls `mgmt_device_disconnected` and ensures a
+consistent state.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index c06010c0d8829..fb5e4e4858f77 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2692,7 +2692,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+       if (!conn)
+               goto unlock;
+-      if (status) {
++      if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+               mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+                                      conn->dst_type, status);
+-- 
+2.50.1
+
diff --git a/queue-6.6/bluetooth-hci_sync-fix-set_local_name-race-condition.patch b/queue-6.6/bluetooth-hci_sync-fix-set_local_name-race-condition.patch
new file mode 100644 (file)
index 0000000..2f9b3ce
--- /dev/null
@@ -0,0 +1,90 @@
+From f89392b975eceaa442c3fc8ea797d98242860861 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 12:20:55 +0300
+Subject: Bluetooth: hci_sync: fix set_local_name race condition
+
+From: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+
+[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]
+
+Function set_name_sync() uses hdev->dev_name field to send
+HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
+is called after mgmt cmd was queued, so it is possible that function
+set_name_sync() will read old name value.
+
+This change adds name as a parameter for function hci_update_name_sync()
+to avoid race condition.
+
+Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
+Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+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>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_sync.c         | 6 +++---
+ net/bluetooth/mgmt.c             | 5 ++++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 3cb2d10cac930..e2e588b08fe90 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -72,7 +72,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 01aca07707117..020f1809fc994 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3491,13 +3491,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+       return hci_write_scan_enable_sync(hdev, scan);
+ }
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+       struct hci_cp_write_local_name cp;
+       memset(&cp, 0, sizeof(cp));
+-      memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++      memcpy(cp.name, name, sizeof(cp.name));
+       return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+                                           sizeof(cp), &cp,
+@@ -3550,7 +3550,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+                       hci_write_fast_connectable_sync(hdev, false);
+               hci_update_scan_sync(hdev);
+               hci_update_class_sync(hdev);
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, hdev->dev_name);
+               hci_update_eir_sync(hdev);
+       }
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 82fa8c28438f2..9b01eaaa0eb2d 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3819,8 +3819,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++      struct mgmt_pending_cmd *cmd = data;
++      struct mgmt_cp_set_local_name *cp = cmd->param;
++
+       if (lmp_bredr_capable(hdev)) {
+-              hci_update_name_sync(hdev);
++              hci_update_name_sync(hdev, cp->name);
+               hci_update_eir_sync(hdev);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.6/drm-msm-defer-fd_install-in-submit-ioctl.patch b/queue-6.6/drm-msm-defer-fd_install-in-submit-ioctl.patch
new file mode 100644 (file)
index 0000000..de36f58
--- /dev/null
@@ -0,0 +1,59 @@
+From a03fa1a6628bde0d8f40b6af39118a4b88397457 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jul 2025 13:28:22 -0700
+Subject: drm/msm: Defer fd_install in SUBMIT ioctl
+
+From: Rob Clark <robin.clark@oss.qualcomm.com>
+
+[ Upstream commit f22853435bbd1e9836d0dce7fd99c040b94c2bf1 ]
+
+Avoid fd_install() until there are no more potential error paths, to
+avoid put_unused_fd() after the fd is made visible to userspace.
+
+Fixes: 68dc6c2d5eec ("drm/msm: Fix submit error-path leaks")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665363/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index bbe4f1665b603..dc142f9e4f602 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -981,12 +981,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+       if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+               sync_file = sync_file_create(submit->user_fence);
+-              if (!sync_file) {
++              if (!sync_file)
+                       ret = -ENOMEM;
+-              } else {
+-                      fd_install(out_fence_fd, sync_file->file);
+-                      args->fence_fd = out_fence_fd;
+-              }
+       }
+       submit_attach_object_fences(submit);
+@@ -1013,10 +1009,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ out_unlock:
+       mutex_unlock(&queue->lock);
+ out_post_unlock:
+-      if (ret && (out_fence_fd >= 0)) {
+-              put_unused_fd(out_fence_fd);
++      if (ret) {
++              if (out_fence_fd >= 0)
++                      put_unused_fd(out_fence_fd);
+               if (sync_file)
+                       fput(sync_file->file);
++      } else if (sync_file) {
++              fd_install(out_fence_fd, sync_file->file);
++              args->fence_fd = out_fence_fd;
+       }
+       if (!IS_ERR_OR_NULL(submit)) {
+-- 
+2.50.1
+
diff --git a/queue-6.6/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch b/queue-6.6/drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
new file mode 100644 (file)
index 0000000..730dac5
--- /dev/null
@@ -0,0 +1,39 @@
+From fc83643fe0827a46683640052a4287ae9bf5109b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:03 -0500
+Subject: drm/nouveau: remove unused increment in gm200_flcn_pio_imem_wr
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit f529b8915543fb9ceb732cec5571f7fe12bc9530 ]
+
+The 'tag' parameter is passed by value and is not actually used after
+being incremented, so remove the increment.  It's the function that calls
+gm200_flcn_pio_imem_wr that is supposed to (and does) increment 'tag'.
+
+Fixes: 0e44c2170876 ("drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)")
+Reviewed-by: Philipp Stanner <phasta@kernel.org>
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-2-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index b7da3ab44c277..6a004c6e67425 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -103,7 +103,7 @@ gm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 i
+ static void
+ gm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
+ {
+-      nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag++);
++      nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag);
+       while (len >= 4) {
+               nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
+               img += 4;
+-- 
+2.50.1
+
diff --git a/queue-6.6/drm-nouveau-remove-unused-memory-target-test.patch b/queue-6.6/drm-nouveau-remove-unused-memory-target-test.patch
new file mode 100644 (file)
index 0000000..0ce1da3
--- /dev/null
@@ -0,0 +1,57 @@
+From fc29d890a49f334fc8a809b2a8b2381604528a56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:04 -0500
+Subject: drm/nouveau: remove unused memory target test
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit 64c722b5e7f6b909b0e448e580f64628a0d76208 ]
+
+The memory target check is a hold-over from a refactor.  It's harmless
+but distracting, so just remove it.
+
+Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs")
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-3-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index 6a004c6e67425..7c43397c19e61 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -249,9 +249,11 @@ int
+ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ {
+       struct nvkm_falcon *falcon = fw->falcon;
+-      int target, ret;
++      int ret;
+       if (fw->inst) {
++              int target;
++
+               nvkm_falcon_mask(falcon, 0x048, 0x00000001, 0x00000001);
+               switch (nvkm_memory_target(fw->inst)) {
+@@ -285,15 +287,6 @@ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+       }
+       if (fw->boot) {
+-              switch (nvkm_memory_target(&fw->fw.mem.memory)) {
+-              case NVKM_MEM_TARGET_VRAM: target = 4; break;
+-              case NVKM_MEM_TARGET_HOST: target = 5; break;
+-              case NVKM_MEM_TARGET_NCOH: target = 6; break;
+-              default:
+-                      WARN_ON(1);
+-                      return -EINVAL;
+-              }
+-
+               ret = nvkm_falcon_pio_wr(falcon, fw->boot, 0, 0,
+                                        IMEM, falcon->code.limit - fw->boot_size, fw->boot_size,
+                                        fw->boot_addr >> 8, false);
+-- 
+2.50.1
+
diff --git a/queue-6.6/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch b/queue-6.6/dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
new file mode 100644 (file)
index 0000000..5f96f4c
--- /dev/null
@@ -0,0 +1,39 @@
+From cfa3271a53d1cc123f2329f18fe2256bc3265c45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Aug 2025 11:36:54 +0300
+Subject: dt-bindings: display/msm: qcom,mdp5: drop lut clock
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 7ab3b7579a6d2660a3425b9ea93b9a140b07f49c ]
+
+None of MDP5 platforms have a LUT clock on the display-controller, it
+was added by the mistake. Drop it, fixing DT warnings on MSM8976 /
+MSM8956 platforms. Technically it's an ABI break, but no other platforms
+are affected.
+
+Fixes: 385c8ac763b3 ("dt-bindings: display/msm: convert MDP5 schema to YAML format")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Patchwork: https://patchwork.freedesktop.org/patch/667822/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+index 91c774f106ceb..ab1196d1ec2dd 100644
+--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
++++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+@@ -59,7 +59,6 @@ properties:
+           - const: bus
+           - const: core
+           - const: vsync
+-          - const: lut
+           - const: tbu
+           - const: tbu_rt
+         # MSM8996 has additional iommu clock
+-- 
+2.50.1
+
diff --git a/queue-6.6/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch b/queue-6.6/efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
new file mode 100644 (file)
index 0000000..c7e6250
--- /dev/null
@@ -0,0 +1,77 @@
+From 4bd779158a3bfc1c9c06f418a2df5d81a7ce02b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+  BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+  Call trace:
+   kasan_check_range+0xe8/0x190
+   __asan_loadN+0x1c/0x28
+   memcmp+0x98/0xd0
+   efivarfs_d_compare+0x68/0xd8
+   __d_lookup_rcu_op_compare+0x178/0x218
+   __d_lookup_rcu+0x1f8/0x228
+   d_alloc_parallel+0x150/0x648
+   lookup_open.isra.0+0x5f0/0x8d0
+   open_last_lookups+0x264/0x828
+   path_openat+0x130/0x3f8
+   do_filp_open+0x114/0x248
+   do_sys_openat2+0x340/0x3c0
+   __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+  T1                   T2
+  lookup_open
+   ->lookup
+    simple_lookup
+     d_add
+     // invalid dentry is added to hash list
+
+                       lookup_open
+                        d_alloc_parallel
+                         __d_lookup_rcu
+                          __d_lookup_rcu_op_compare
+                           hlist_bl_for_each_entry_rcu
+                           // invalid dentry can be retrieved
+                            ->d_compare
+                             efivarfs_d_compare
+                             // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 586c5709dfb55..34438981ddd80 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -90,6 +90,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+       int guid = len - EFI_VARIABLE_GUID_LEN;
++      /* Parallel lookups may produce a temporary invalid filename */
++      if (guid <= 0)
++              return 1;
++
+       if (name->len != len)
+               return 1;
+-- 
+2.50.1
+
diff --git a/queue-6.6/hid-input-rename-hidinput_set_battery_charge_status.patch b/queue-6.6/hid-input-rename-hidinput_set_battery_charge_status.patch
new file mode 100644 (file)
index 0000000..59a4a99
--- /dev/null
@@ -0,0 +1,147 @@
+From c0e020b69ab9cc830030b0eb40c9d9a68875e070 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:39 +0200
+Subject: HID: input: rename hidinput_set_battery_charge_status()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit a82231b2a8712d0218fc286a9b0da328d419a3f4 ]
+
+In preparation for a patch fixing a bug affecting
+hidinput_set_battery_charge_status(), rename the function to
+hidinput_update_battery_charge_status() and move it up so it can be used
+by hidinput_update_battery().
+
+Refactor, no functional changes.
+
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Stable-dep-of: e94536e1d181 ("HID: input: report battery status changes immediately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input-test.c | 10 +++++-----
+ drivers/hid/hid-input.c      | 38 ++++++++++++++++++------------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7..6f5c71660d823 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+ #include <kunit/test.h>
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+       struct hid_device *dev;
+       bool handled;
+@@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
+       dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+-      handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+       KUNIT_EXPECT_FALSE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
+-      handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++      handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
+       KUNIT_EXPECT_TRUE(test, handled);
+       KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
+ }
+ static struct kunit_case hid_input_tests[] = {
+-      KUNIT_CASE(hid_test_input_set_battery_charge_status),
++      KUNIT_CASE(hid_test_input_update_battery_charge_status),
+       KUNIT_CASE(hid_test_input_get_battery_property),
+       { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 9d80635a91ebd..b372b74f3e24b 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -595,6 +595,20 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+       dev->battery = NULL;
+ }
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
++{
++      switch (usage) {
++      case HID_BAT_CHARGING:
++              dev->battery_charge_status = value ?
++                                           POWER_SUPPLY_STATUS_CHARGING :
++                                           POWER_SUPPLY_STATUS_DISCHARGING;
++              return true;
++      }
++
++      return false;
++}
++
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+       int capacity;
+@@ -617,20 +631,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
+               power_supply_changed(dev->battery);
+       }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
+-{
+-      switch (usage) {
+-      case HID_BAT_CHARGING:
+-              dev->battery_charge_status = value ?
+-                                           POWER_SUPPLY_STATUS_CHARGING :
+-                                           POWER_SUPPLY_STATUS_DISCHARGING;
+-              return true;
+-      }
+-
+-      return false;
+-}
+ #else  /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+                                 struct hid_field *field, bool is_percentage)
+@@ -642,14 +642,14 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++                                                unsigned int usage, int value)
+ {
++      return false;
+ }
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+-                                             unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+-      return false;
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,7 +1515,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+               return;
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++              bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+               if (!handled)
+                       hidinput_update_battery(hid, value);
+-- 
+2.50.1
+
diff --git a/queue-6.6/hid-input-report-battery-status-changes-immediately.patch b/queue-6.6/hid-input-report-battery-status-changes-immediately.patch
new file mode 100644 (file)
index 0000000..bf86962
--- /dev/null
@@ -0,0 +1,97 @@
+From 9c99b289313b7897a310c5628ed9ba80accbe2f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:40 +0200
+Subject: HID: input: report battery status changes immediately
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit e94536e1d1818b0989aa19b443b7089f50133c35 ]
+
+Previously, the battery status (charging/discharging) was not reported
+immediately to user-space. 
+
+For most input devices, this wasn't problematic because changing their
+battery status requires connecting them to a different bus.
+For example, a gamepad would report a discharging status while
+connected via Bluetooth and a charging status while connected via USB.
+
+However, certain devices are not connected or disconnected when their
+battery status changes. For example, a phone battery changes its status
+without connecting or disconnecting it.
+In these cases, the battery status was not reported immediately to user
+space.
+
+Report battery status changes immediately to user space to support
+these kinds of devices.
+
+Fixes: a608dc1c0639 ("HID: input: map battery system charging")
+Reported-by: 卢国宏 <luguohong@xiaomi.com>
+Closes: https://lore.kernel.org/linux-input/aI49Im0sGb6fpgc8@fedora/T/
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index b372b74f3e24b..f5c217ac4bfaa 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -609,13 +609,19 @@ static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+       return false;
+ }
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++                                  int value)
+ {
+       int capacity;
+       if (!dev->battery)
+               return;
++      if (hidinput_update_battery_charge_status(dev, usage, value)) {
++              power_supply_changed(dev->battery);
++              return;
++      }
++
+       if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+               return;
+@@ -642,13 +648,8 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+-static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+-                                                unsigned int usage, int value)
+-{
+-      return false;
+-}
+-
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++                                  int value)
+ {
+ }
+ #endif        /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+               return;
+       if (usage->type == EV_PWR) {
+-              bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+-
+-              if (!handled)
+-                      hidinput_update_battery(hid, value);
+-
++              hidinput_update_battery(hid, usage->hid, value);
+               return;
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.6/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch b/queue-6.6/ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
new file mode 100644 (file)
index 0000000..83db42f
--- /dev/null
@@ -0,0 +1,46 @@
+From 542aaf000548c5e1c84555586ca0c1086792d8c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Aug 2025 17:53:10 +0200
+Subject: ice: fix incorrect counter for buffer allocation failures
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit b1a0c977c6f1130f7dd125ee3db8c2435d7e3d41 ]
+
+Currently, the driver increments `alloc_page_failed` when buffer allocation fails
+in `ice_clean_rx_irq()`. However, this counter is intended for page allocation
+failures, not buffer allocation issues.
+
+This patch corrects the counter by incrementing `alloc_buf_failed` instead,
+ensuring accurate statistics reporting for buffer allocation failures.
+
+Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
+Reported-by: Jacob Keller <jacob.e.keller@intel.com>
+Suggested-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Priya Singh <priyax.singh@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index e7084c6aab6da..eae4376c68595 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -1297,7 +1297,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+                       skb = ice_construct_skb(rx_ring, xdp);
+               /* exit if we failed to retrieve a buffer */
+               if (!skb) {
+-                      rx_ring->ring_stats->rx_stats.alloc_page_failed++;
++                      rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
+                       xdp_verdict = ICE_XDP_CONSUMED;
+               }
+               ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+-- 
+2.50.1
+
diff --git a/queue-6.6/ice-gather-page_count-s-of-each-frag-right-before-xd.patch b/queue-6.6/ice-gather-page_count-s-of-each-frag-right-before-xd.patch
new file mode 100644 (file)
index 0000000..75ec3dc
--- /dev/null
@@ -0,0 +1,97 @@
+From f1efbf972a288ff9f706dd2c69e6745f21199b32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 16:01:17 +0100
+Subject: ice: gather page_count()'s of each frag right before XDP prog call
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+[ Upstream commit 11c4aa074d547d825b19cd8d9f288254d89d805c ]
+
+If we store the pgcnt on few fragments while being in the middle of
+gathering the whole frame and we stumbled upon DD bit not being set, we
+terminate the NAPI Rx processing loop and come back later on. Then on
+next NAPI execution we work on previously stored pgcnt.
+
+Imagine that second half of page was used actively by networking stack
+and by the time we came back, stack is not busy with this page anymore
+and decremented the refcnt. The page reuse algorithm in this case should
+be good to reuse the page but given the old refcnt it will not do so and
+attempt to release the page via page_frag_cache_drain() with
+pagecnt_bias used as an arg. This in turn will result in negative refcnt
+on struct page, which was initially observed by Xu Du.
+
+Therefore, move the page count storage from ice_get_rx_buf() to a place
+where we are sure that whole frame has been collected, but before
+calling XDP program as it internally can also change the page count of
+fragments belonging to xdp_buff.
+
+Fixes: ac0753391195 ("ice: Store page count inside ice_rx_buf")
+Reported-and-tested-by: Xu Du <xudu@redhat.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Co-developed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Tested-by: Chandan Kumar Rout <chandanx.rout@intel.com> (A Contingent Worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: b1a0c977c6f1 ("ice: fix incorrect counter for buffer allocation failures")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 27 ++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 46f10f32924ee..beb5c8643fe7d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -924,7 +924,6 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size,
+       struct ice_rx_buf *rx_buf;
+       rx_buf = &rx_ring->rx_buf[ntc];
+-      rx_buf->pgcnt = page_count(rx_buf->page);
+       prefetchw(rx_buf->page);
+       if (!size)
+@@ -940,6 +939,31 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size,
+       return rx_buf;
+ }
++/**
++ * ice_get_pgcnts - grab page_count() for gathered fragments
++ * @rx_ring: Rx descriptor ring to store the page counts on
++ *
++ * This function is intended to be called right before running XDP
++ * program so that the page recycling mechanism will be able to take
++ * a correct decision regarding underlying pages; this is done in such
++ * way as XDP program can change the refcount of page
++ */
++static void ice_get_pgcnts(struct ice_rx_ring *rx_ring)
++{
++      u32 nr_frags = rx_ring->nr_frags + 1;
++      u32 idx = rx_ring->first_desc;
++      struct ice_rx_buf *rx_buf;
++      u32 cnt = rx_ring->count;
++
++      for (int i = 0; i < nr_frags; i++) {
++              rx_buf = &rx_ring->rx_buf[idx];
++              rx_buf->pgcnt = page_count(rx_buf->page);
++
++              if (++idx == cnt)
++                      idx = 0;
++      }
++}
++
+ /**
+  * ice_build_skb - Build skb around an existing buffer
+  * @rx_ring: Rx descriptor ring to transact packets on
+@@ -1243,6 +1267,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+               if (ice_is_non_eop(rx_ring, rx_desc))
+                       continue;
++              ice_get_pgcnts(rx_ring);
+               ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc);
+               if (rx_buf->act == ICE_XDP_PASS)
+                       goto construct_skb;
+-- 
+2.50.1
+
diff --git a/queue-6.6/ice-introduce-ice_xdp_buff.patch b/queue-6.6/ice-introduce-ice_xdp_buff.patch
new file mode 100644 (file)
index 0000000..6863d82
--- /dev/null
@@ -0,0 +1,150 @@
+From a5a6221a29b14c86f4ff94984cbe9bd80c30aea0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 22:08:33 +0100
+Subject: ice: Introduce ice_xdp_buff
+
+From: Larysa Zaremba <larysa.zaremba@intel.com>
+
+[ Upstream commit d951c14ad237b087f0d1377c44932fcc0b322c40 ]
+
+In order to use XDP hints via kfuncs we need to put
+RX descriptor and miscellaneous data next to xdp_buff.
+Same as in hints implementations in other drivers, we achieve
+this through putting xdp_buff into a child structure.
+
+Currently, xdp_buff is stored in the ring structure,
+so replace it with union that includes child structure.
+This way enough memory is available while existing XDP code
+remains isolated from hints.
+
+Minimum size of the new child structure (ice_xdp_buff) is exactly
+64 bytes (single cache line). To place it at the start of a cache line,
+move 'next' field from CL1 to CL4, as it isn't used often. This still
+leaves 192 bits available in CL3 for packet context extensions.
+
+Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Link: https://lore.kernel.org/r/20231205210847.28460-5-larysa.zaremba@intel.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Stable-dep-of: b1a0c977c6f1 ("ice: fix incorrect counter for buffer allocation failures")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c     |  7 +++++--
+ drivers/net/ethernet/intel/ice/ice_txrx.h     | 18 +++++++++++++++---
+ drivers/net/ethernet/intel/ice/ice_txrx_lib.h | 10 ++++++++++
+ 3 files changed, 30 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index f5023ac9ab832..46f10f32924ee 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -528,13 +528,14 @@ int ice_setup_rx_ring(struct ice_rx_ring *rx_ring)
+  * @xdp_prog: XDP program to run
+  * @xdp_ring: ring to be used for XDP_TX action
+  * @rx_buf: Rx buffer to store the XDP action
++ * @eop_desc: Last descriptor in packet to read metadata from
+  *
+  * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
+  */
+ static void
+ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+           struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring,
+-          struct ice_rx_buf *rx_buf)
++          struct ice_rx_buf *rx_buf, union ice_32b_rx_flex_desc *eop_desc)
+ {
+       unsigned int ret = ICE_XDP_PASS;
+       u32 act;
+@@ -542,6 +543,8 @@ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+       if (!xdp_prog)
+               goto exit;
++      ice_xdp_meta_set_desc(xdp, eop_desc);
++
+       act = bpf_prog_run_xdp(xdp_prog, xdp);
+       switch (act) {
+       case XDP_PASS:
+@@ -1240,7 +1243,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+               if (ice_is_non_eop(rx_ring, rx_desc))
+                       continue;
+-              ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf);
++              ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc);
+               if (rx_buf->act == ICE_XDP_PASS)
+                       goto construct_skb;
+               total_rx_bytes += xdp_get_buff_len(xdp);
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
+index 407d4c320097f..ad2d286bd359d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
+@@ -257,6 +257,14 @@ enum ice_rx_dtype {
+       ICE_RX_DTYPE_SPLIT_ALWAYS       = 2,
+ };
++struct ice_xdp_buff {
++      struct xdp_buff xdp_buff;
++      const union ice_32b_rx_flex_desc *eop_desc;
++};
++
++/* Required for compatibility with xdp_buffs from xsk_pool */
++static_assert(offsetof(struct ice_xdp_buff, xdp_buff) == 0);
++
+ /* indices into GLINT_ITR registers */
+ #define ICE_RX_ITR    ICE_IDX_ITR0
+ #define ICE_TX_ITR    ICE_IDX_ITR1
+@@ -298,7 +306,6 @@ enum ice_dynamic_itr {
+ /* descriptor ring, associated with a VSI */
+ struct ice_rx_ring {
+       /* CL1 - 1st cacheline starts here */
+-      struct ice_rx_ring *next;       /* pointer to next ring in q_vector */
+       void *desc;                     /* Descriptor ring memory */
+       struct device *dev;             /* Used for DMA mapping */
+       struct net_device *netdev;      /* netdev ring maps to */
+@@ -310,12 +317,16 @@ struct ice_rx_ring {
+       u16 count;                      /* Number of descriptors */
+       u16 reg_idx;                    /* HW register index of the ring */
+       u16 next_to_alloc;
+-      /* CL2 - 2nd cacheline starts here */
++
+       union {
+               struct ice_rx_buf *rx_buf;
+               struct xdp_buff **xdp_buf;
+       };
+-      struct xdp_buff xdp;
++      /* CL2 - 2nd cacheline starts here */
++      union {
++              struct ice_xdp_buff xdp_ext;
++              struct xdp_buff xdp;
++      };
+       /* CL3 - 3rd cacheline starts here */
+       struct bpf_prog *xdp_prog;
+       u16 rx_offset;
+@@ -332,6 +343,7 @@ struct ice_rx_ring {
+       /* CL4 - 4th cacheline starts here */
+       struct ice_channel *ch;
+       struct ice_tx_ring *xdp_ring;
++      struct ice_rx_ring *next;       /* pointer to next ring in q_vector */
+       struct xsk_buff_pool *xsk_pool;
+       u32 nr_frags;
+       dma_addr_t dma;                 /* physical address of ring */
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+index b0e56675f98b2..00971f8491358 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+@@ -164,4 +164,14 @@ ice_process_skb_fields(struct ice_rx_ring *rx_ring,
+                      struct sk_buff *skb, u16 ptype);
+ void
+ ice_receive_skb(struct ice_rx_ring *rx_ring, struct sk_buff *skb, u16 vlan_tag);
++
++static inline void
++ice_xdp_meta_set_desc(struct xdp_buff *xdp,
++                    union ice_32b_rx_flex_desc *eop_desc)
++{
++      struct ice_xdp_buff *xdp_ext = container_of(xdp, struct ice_xdp_buff,
++                                                  xdp_buff);
++
++      xdp_ext->eop_desc = eop_desc;
++}
+ #endif /* !_ICE_TXRX_LIB_H_ */
+-- 
+2.50.1
+
diff --git a/queue-6.6/ice-stop-storing-xdp-verdict-within-ice_rx_buf.patch b/queue-6.6/ice-stop-storing-xdp-verdict-within-ice_rx_buf.patch
new file mode 100644 (file)
index 0000000..101c7aa
--- /dev/null
@@ -0,0 +1,274 @@
+From 995eca567db21c04c41f7106762898c7fabae519 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 16:01:18 +0100
+Subject: ice: stop storing XDP verdict within ice_rx_buf
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+[ Upstream commit 468a1952df78f65c5991b7ac885c8b5b7dd87bab ]
+
+Idea behind having ice_rx_buf::act was to simplify and speed up the Rx
+data path by walking through buffers that were representing cleaned HW
+Rx descriptors. Since it caused us a major headache recently and we
+rolled back to old approach that 'puts' Rx buffers right after running
+XDP prog/creating skb, this is useless now and should be removed.
+
+Get rid of ice_rx_buf::act and related logic. We still need to take care
+of a corner case where XDP program releases a particular fragment.
+
+Make ice_run_xdp() to return its result and use it within
+ice_put_rx_mbuf().
+
+Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Tested-by: Chandan Kumar Rout <chandanx.rout@intel.com> (A Contingent Worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: b1a0c977c6f1 ("ice: fix incorrect counter for buffer allocation failures")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c     | 62 +++++++++++--------
+ drivers/net/ethernet/intel/ice/ice_txrx.h     |  1 -
+ drivers/net/ethernet/intel/ice/ice_txrx_lib.h | 43 -------------
+ 3 files changed, 36 insertions(+), 70 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index beb5c8643fe7d..e7084c6aab6da 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -527,15 +527,14 @@ int ice_setup_rx_ring(struct ice_rx_ring *rx_ring)
+  * @xdp: xdp_buff used as input to the XDP program
+  * @xdp_prog: XDP program to run
+  * @xdp_ring: ring to be used for XDP_TX action
+- * @rx_buf: Rx buffer to store the XDP action
+  * @eop_desc: Last descriptor in packet to read metadata from
+  *
+  * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
+  */
+-static void
++static u32
+ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+           struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring,
+-          struct ice_rx_buf *rx_buf, union ice_32b_rx_flex_desc *eop_desc)
++          union ice_32b_rx_flex_desc *eop_desc)
+ {
+       unsigned int ret = ICE_XDP_PASS;
+       u32 act;
+@@ -574,7 +573,7 @@ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+               ret = ICE_XDP_CONSUMED;
+       }
+ exit:
+-      ice_set_rx_bufs_act(xdp, rx_ring, ret);
++      return ret;
+ }
+ /**
+@@ -860,10 +859,8 @@ ice_add_xdp_frag(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+               xdp_buff_set_frags_flag(xdp);
+       }
+-      if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) {
+-              ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED);
++      if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS))
+               return -ENOMEM;
+-      }
+       __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page,
+                                  rx_buf->page_offset, size);
+@@ -1076,12 +1073,12 @@ ice_construct_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
+                               rx_buf->page_offset + headlen, size,
+                               xdp->frame_sz);
+       } else {
+-              /* buffer is unused, change the act that should be taken later
+-               * on; data was copied onto skb's linear part so there's no
++              /* buffer is unused, restore biased page count in Rx buffer;
++               * data was copied onto skb's linear part so there's no
+                * need for adjusting page offset and we can reuse this buffer
+                * as-is
+                */
+-              rx_buf->act = ICE_SKB_CONSUMED;
++              rx_buf->pagecnt_bias++;
+       }
+       if (unlikely(xdp_buff_has_frags(xdp))) {
+@@ -1134,29 +1131,34 @@ ice_put_rx_buf(struct ice_rx_ring *rx_ring, struct ice_rx_buf *rx_buf)
+  * @xdp: XDP buffer carrying linear + frags part
+  * @xdp_xmit: XDP_TX/XDP_REDIRECT verdict storage
+  * @ntc: a current next_to_clean value to be stored at rx_ring
++ * @verdict: return code from XDP program execution
+  *
+  * Walk through gathered fragments and satisfy internal page
+  * recycle mechanism; we take here an action related to verdict
+  * returned by XDP program;
+  */
+ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+-                          u32 *xdp_xmit, u32 ntc)
++                          u32 *xdp_xmit, u32 ntc, u32 verdict)
+ {
+       u32 nr_frags = rx_ring->nr_frags + 1;
+       u32 idx = rx_ring->first_desc;
+       u32 cnt = rx_ring->count;
++      u32 post_xdp_frags = 1;
+       struct ice_rx_buf *buf;
+       int i;
+-      for (i = 0; i < nr_frags; i++) {
++      if (unlikely(xdp_buff_has_frags(xdp)))
++              post_xdp_frags += xdp_get_shared_info_from_buff(xdp)->nr_frags;
++
++      for (i = 0; i < post_xdp_frags; i++) {
+               buf = &rx_ring->rx_buf[idx];
+-              if (buf->act & (ICE_XDP_TX | ICE_XDP_REDIR)) {
++              if (verdict & (ICE_XDP_TX | ICE_XDP_REDIR)) {
+                       ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+-                      *xdp_xmit |= buf->act;
+-              } else if (buf->act & ICE_XDP_CONSUMED) {
++                      *xdp_xmit |= verdict;
++              } else if (verdict & ICE_XDP_CONSUMED) {
+                       buf->pagecnt_bias++;
+-              } else if (buf->act == ICE_XDP_PASS) {
++              } else if (verdict == ICE_XDP_PASS) {
+                       ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+               }
+@@ -1165,6 +1167,17 @@ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+               if (++idx == cnt)
+                       idx = 0;
+       }
++      /* handle buffers that represented frags released by XDP prog;
++       * for these we keep pagecnt_bias as-is; refcount from struct page
++       * has been decremented within XDP prog and we do not have to increase
++       * the biased refcnt
++       */
++      for (; i < nr_frags; i++) {
++              buf = &rx_ring->rx_buf[idx];
++              ice_put_rx_buf(rx_ring, buf);
++              if (++idx == cnt)
++                      idx = 0;
++      }
+       xdp->data = NULL;
+       rx_ring->first_desc = ntc;
+@@ -1191,9 +1204,9 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+       struct ice_tx_ring *xdp_ring = NULL;
+       struct bpf_prog *xdp_prog = NULL;
+       u32 ntc = rx_ring->next_to_clean;
++      u32 cached_ntu, xdp_verdict;
+       u32 cnt = rx_ring->count;
+       u32 xdp_xmit = 0;
+-      u32 cached_ntu;
+       bool failure;
+       xdp_prog = READ_ONCE(rx_ring->xdp_prog);
+@@ -1257,7 +1270,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+                       xdp_prepare_buff(xdp, hard_start, offset, size, !!offset);
+                       xdp_buff_clear_frags_flag(xdp);
+               } else if (ice_add_xdp_frag(rx_ring, xdp, rx_buf, size)) {
+-                      ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc);
++                      ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc, ICE_XDP_CONSUMED);
+                       break;
+               }
+               if (++ntc == cnt)
+@@ -1268,13 +1281,13 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+                       continue;
+               ice_get_pgcnts(rx_ring);
+-              ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc);
+-              if (rx_buf->act == ICE_XDP_PASS)
++              xdp_verdict = ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_desc);
++              if (xdp_verdict == ICE_XDP_PASS)
+                       goto construct_skb;
+               total_rx_bytes += xdp_get_buff_len(xdp);
+               total_rx_pkts++;
+-              ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc);
++              ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+               continue;
+ construct_skb:
+@@ -1285,12 +1298,9 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+               /* exit if we failed to retrieve a buffer */
+               if (!skb) {
+                       rx_ring->ring_stats->rx_stats.alloc_page_failed++;
+-                      rx_buf->act = ICE_XDP_CONSUMED;
+-                      if (unlikely(xdp_buff_has_frags(xdp)))
+-                              ice_set_rx_bufs_act(xdp, rx_ring,
+-                                                  ICE_XDP_CONSUMED);
++                      xdp_verdict = ICE_XDP_CONSUMED;
+               }
+-              ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc);
++              ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+               if (!skb)
+                       break;
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
+index ad2d286bd359d..53a155dde3e32 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
+@@ -201,7 +201,6 @@ struct ice_rx_buf {
+       struct page *page;
+       unsigned int page_offset;
+       unsigned int pgcnt;
+-      unsigned int act;
+       unsigned int pagecnt_bias;
+ };
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+index 00971f8491358..41efafc5eb386 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+@@ -5,49 +5,6 @@
+ #define _ICE_TXRX_LIB_H_
+ #include "ice.h"
+-/**
+- * ice_set_rx_bufs_act - propagate Rx buffer action to frags
+- * @xdp: XDP buffer representing frame (linear and frags part)
+- * @rx_ring: Rx ring struct
+- * act: action to store onto Rx buffers related to XDP buffer parts
+- *
+- * Set action that should be taken before putting Rx buffer from first frag
+- * to the last.
+- */
+-static inline void
+-ice_set_rx_bufs_act(struct xdp_buff *xdp, const struct ice_rx_ring *rx_ring,
+-                  const unsigned int act)
+-{
+-      u32 sinfo_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags;
+-      u32 nr_frags = rx_ring->nr_frags + 1;
+-      u32 idx = rx_ring->first_desc;
+-      u32 cnt = rx_ring->count;
+-      struct ice_rx_buf *buf;
+-
+-      for (int i = 0; i < nr_frags; i++) {
+-              buf = &rx_ring->rx_buf[idx];
+-              buf->act = act;
+-
+-              if (++idx == cnt)
+-                      idx = 0;
+-      }
+-
+-      /* adjust pagecnt_bias on frags freed by XDP prog */
+-      if (sinfo_frags < rx_ring->nr_frags && act == ICE_XDP_CONSUMED) {
+-              u32 delta = rx_ring->nr_frags - sinfo_frags;
+-
+-              while (delta) {
+-                      if (idx == 0)
+-                              idx = cnt - 1;
+-                      else
+-                              idx--;
+-                      buf = &rx_ring->rx_buf[idx];
+-                      buf->pagecnt_bias--;
+-                      delta--;
+-              }
+-      }
+-}
+-
+ /**
+  * ice_test_staterr - tests bits in Rx descriptor status and error fields
+  * @status_err_n: Rx descriptor status_error0 or status_error1 bits
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-dlink-fix-multicast-stats-being-counted-incorrec.patch b/queue-6.6/net-dlink-fix-multicast-stats-being-counted-incorrec.patch
new file mode 100644 (file)
index 0000000..efc3d3f
--- /dev/null
@@ -0,0 +1,46 @@
+From 873765c16ba313611e466623793a24b8e13469af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index fad5a72d3b167..f1208591ed67e 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1092,7 +1092,7 @@ get_stats (struct net_device *dev)
+       dev->stats.rx_bytes += dr32(OctetRcvOk);
+       dev->stats.tx_bytes += dr32(OctetXmtOk);
+-      dev->stats.multicast = dr32(McstFramesRcvdOk);
++      dev->stats.multicast += dr32(McstFramesRcvdOk);
+       dev->stats.collisions += dr32(SingleColFrames)
+                            +  dr32(MultiColFrames);
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-ipv4-fix-regression-in-local-broadcast-routes.patch b/queue-6.6/net-ipv4-fix-regression-in-local-broadcast-routes.patch
new file mode 100644 (file)
index 0000000..ca9ad6f
--- /dev/null
@@ -0,0 +1,57 @@
+From 1ed62904f05e264e2cf8232c0ee98ef03c920dee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 8672ebbace980..20f5c8307443d 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2547,12 +2547,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+                   !netif_is_l3_master(dev_out))
+                       return ERR_PTR(-EINVAL);
+-      if (ipv4_is_lbcast(fl4->daddr))
++      if (ipv4_is_lbcast(fl4->daddr)) {
+               type = RTN_BROADCAST;
+-      else if (ipv4_is_multicast(fl4->daddr))
++
++              /* reset fi to prevent gateway resolution */
++              fi = NULL;
++      } else if (ipv4_is_multicast(fl4->daddr)) {
+               type = RTN_MULTICAST;
+-      else if (ipv4_is_zeronet(fl4->daddr))
++      } else if (ipv4_is_zeronet(fl4->daddr)) {
+               return ERR_PTR(-EINVAL);
++      }
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5-add-device-cap-for-supporting-hot-reset-in-.patch b/queue-6.6/net-mlx5-add-device-cap-for-supporting-hot-reset-in-.patch
new file mode 100644 (file)
index 0000000..09e4e23
--- /dev/null
@@ -0,0 +1,64 @@
+From 15f719a86bda9471820e5d022e59ac3d60d69ae5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 13:17:51 -0700
+Subject: net/mlx5: Add device cap for supporting hot reset in sync reset flow
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 9947204cdad97d22d171039019a4aad4d6899cdd ]
+
+New devices with new FW can support sync reset for firmware activate
+using hot reset. Add capability for supporting it and add MFRL field to
+query from FW which type of PCI reset method to use while handling sync
+reset events.
+
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20240911201757.1505453-10-saeed@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 902a8bc23a24 ("net/mlx5: Fix lockdep assertion on sync reset unload event")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mlx5/mlx5_ifc.h | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index 9106771bb92f0..4913d364e9774 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -1731,7 +1731,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
+       u8         reserved_at_328[0x2];
+       u8         relaxed_ordering_read[0x1];
+       u8         log_max_pd[0x5];
+-      u8         reserved_at_330[0x6];
++      u8         reserved_at_330[0x5];
++      u8         pcie_reset_using_hotreset_method[0x1];
+       u8         pci_sync_for_fw_update_with_driver_unload[0x1];
+       u8         vnic_env_cnt_steering_fail[0x1];
+       u8         vport_counter_local_loopback[0x1];
+@@ -10824,6 +10825,11 @@ struct mlx5_ifc_mcda_reg_bits {
+       u8         data[][0x20];
+ };
++enum {
++      MLX5_MFRL_REG_PCI_RESET_METHOD_LINK_TOGGLE = 0,
++      MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET = 1,
++};
++
+ enum {
+       MLX5_MFRL_REG_RESET_STATE_IDLE = 0,
+       MLX5_MFRL_REG_RESET_STATE_IN_NEGOTIATION = 1,
+@@ -10851,7 +10857,8 @@ struct mlx5_ifc_mfrl_reg_bits {
+       u8         pci_sync_for_fw_update_start[0x1];
+       u8         pci_sync_for_fw_update_resp[0x2];
+       u8         rst_type_sel[0x3];
+-      u8         reserved_at_28[0x4];
++      u8         pci_reset_req_method[0x3];
++      u8         reserved_at_2b[0x1];
+       u8         reset_state[0x4];
+       u8         reset_type[0x8];
+       u8         reset_level[0x8];
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5-add-support-for-sync-reset-using-hot-reset.patch b/queue-6.6/net-mlx5-add-support-for-sync-reset-using-hot-reset.patch
new file mode 100644 (file)
index 0000000..65c9853
--- /dev/null
@@ -0,0 +1,208 @@
+From 67f945582744ec16678dfbbc9b5b2c3e6cfdf89e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 13:17:52 -0700
+Subject: net/mlx5: Add support for sync reset using hot reset
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 57502f62678ced0149d415324931bde37b42885a ]
+
+On device that supports sync reset for firmware activate using hot
+reset, the driver queries the required reset method while handling the
+sync reset request. If the required reset method is hot reset, the
+driver will use pci_reset_bus() to reset the PCI link instead of the
+link toggle.
+
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20240911201757.1505453-11-saeed@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 902a8bc23a24 ("net/mlx5: Fix lockdep assertion on sync reset unload event")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/fw_reset.c    | 82 +++++++++++++++----
+ .../net/ethernet/mellanox/mlx5/core/main.c    |  3 +
+ 2 files changed, 69 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 6b17346aa4cef..a1c2dd7f5c2c0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -26,6 +26,7 @@ struct mlx5_fw_reset {
+       struct work_struct reset_now_work;
+       struct work_struct reset_abort_work;
+       unsigned long reset_flags;
++      u8 reset_method;
+       struct timer_list timer;
+       struct completion done;
+       int ret;
+@@ -94,7 +95,7 @@ static int mlx5_reg_mfrl_set(struct mlx5_core_dev *dev, u8 reset_level,
+ }
+ static int mlx5_reg_mfrl_query(struct mlx5_core_dev *dev, u8 *reset_level,
+-                             u8 *reset_type, u8 *reset_state)
++                             u8 *reset_type, u8 *reset_state, u8 *reset_method)
+ {
+       u32 out[MLX5_ST_SZ_DW(mfrl_reg)] = {};
+       u32 in[MLX5_ST_SZ_DW(mfrl_reg)] = {};
+@@ -110,13 +111,26 @@ static int mlx5_reg_mfrl_query(struct mlx5_core_dev *dev, u8 *reset_level,
+               *reset_type = MLX5_GET(mfrl_reg, out, reset_type);
+       if (reset_state)
+               *reset_state = MLX5_GET(mfrl_reg, out, reset_state);
++      if (reset_method)
++              *reset_method = MLX5_GET(mfrl_reg, out, pci_reset_req_method);
+       return 0;
+ }
+ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_type)
+ {
+-      return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL);
++      return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL, NULL);
++}
++
++static int mlx5_fw_reset_get_reset_method(struct mlx5_core_dev *dev,
++                                        u8 *reset_method)
++{
++      if (!MLX5_CAP_GEN(dev, pcie_reset_using_hotreset_method)) {
++              *reset_method = MLX5_MFRL_REG_PCI_RESET_METHOD_LINK_TOGGLE;
++              return 0;
++      }
++
++      return mlx5_reg_mfrl_query(dev, NULL, NULL, NULL, reset_method);
+ }
+ static int mlx5_fw_reset_get_reset_state_err(struct mlx5_core_dev *dev,
+@@ -124,7 +138,7 @@ static int mlx5_fw_reset_get_reset_state_err(struct mlx5_core_dev *dev,
+ {
+       u8 reset_state;
+-      if (mlx5_reg_mfrl_query(dev, NULL, NULL, &reset_state))
++      if (mlx5_reg_mfrl_query(dev, NULL, NULL, &reset_state, NULL))
+               goto out;
+       if (!reset_state)
+@@ -402,7 +416,11 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
+       struct mlx5_core_dev *dev = fw_reset->dev;
+       int err;
+-      if (test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
++      err = mlx5_fw_reset_get_reset_method(dev, &fw_reset->reset_method);
++      if (err)
++              mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err);
++
++      if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
+           !mlx5_is_reset_now_capable(dev)) {
+               err = mlx5_fw_reset_set_reset_sync_nack(dev);
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s",
+@@ -419,21 +437,15 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack. Device reset is expected.\n");
+ }
+-static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
++static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev, u16 dev_id)
+ {
+       struct pci_bus *bridge_bus = dev->pdev->bus;
+       struct pci_dev *bridge = bridge_bus->self;
+       unsigned long timeout;
+       struct pci_dev *sdev;
+-      u16 reg16, dev_id;
+       int cap, err;
++      u16 reg16;
+-      err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
+-      if (err)
+-              return pcibios_err_to_errno(err);
+-      err = mlx5_check_dev_ids(dev, dev_id);
+-      if (err)
+-              return err;
+       cap = pci_find_capability(bridge, PCI_CAP_ID_EXP);
+       if (!cap)
+               return -EOPNOTSUPP;
+@@ -503,6 +515,44 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
+       return err;
+ }
++static int mlx5_pci_reset_bus(struct mlx5_core_dev *dev)
++{
++      if (!MLX5_CAP_GEN(dev, pcie_reset_using_hotreset_method))
++              return -EOPNOTSUPP;
++
++      return pci_reset_bus(dev->pdev);
++}
++
++static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
++{
++      u16 dev_id;
++      int err;
++
++      err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
++      if (err)
++              return pcibios_err_to_errno(err);
++      err = mlx5_check_dev_ids(dev, dev_id);
++      if (err)
++              return err;
++
++      switch (reset_method) {
++      case MLX5_MFRL_REG_PCI_RESET_METHOD_LINK_TOGGLE:
++              err = mlx5_pci_link_toggle(dev, dev_id);
++              if (err)
++                      mlx5_core_warn(dev, "mlx5_pci_link_toggle failed\n");
++              break;
++      case MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET:
++              err = mlx5_pci_reset_bus(dev);
++              if (err)
++                      mlx5_core_warn(dev, "mlx5_pci_reset_bus failed\n");
++              break;
++      default:
++              return -EOPNOTSUPP;
++      }
++
++      return err;
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+@@ -521,9 +571,9 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+               goto done;
+       }
+-      err = mlx5_pci_link_toggle(dev);
++      err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+       if (err) {
+-              mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, no reset done, err %d\n", err);
++              mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, no reset done, err %d\n", err);
+               set_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags);
+       }
+@@ -585,9 +635,9 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+       mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
+       if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+-              err = mlx5_pci_link_toggle(dev);
++              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+               if (err) {
+-                      mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, err %d\n", err);
++                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
+                       fw_reset->ret = err;
+               }
+       }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 62a85f09b52fd..8a11e410f7c13 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -627,6 +627,9 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
+       if (MLX5_CAP_GEN_MAX(dev, pci_sync_for_fw_update_with_driver_unload))
+               MLX5_SET(cmd_hca_cap, set_hca_cap,
+                        pci_sync_for_fw_update_with_driver_unload, 1);
++      if (MLX5_CAP_GEN_MAX(dev, pcie_reset_using_hotreset_method))
++              MLX5_SET(cmd_hca_cap, set_hca_cap,
++                       pcie_reset_using_hotreset_method, 1);
+       if (MLX5_CAP_GEN_MAX(dev, num_vhca_ports))
+               MLX5_SET(cmd_hca_cap,
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5-call-mlx5_sf_id_erase-once-in-mlx5_sf_deall.patch b/queue-6.6/net-mlx5-call-mlx5_sf_id_erase-once-in-mlx5_sf_deall.patch
new file mode 100644 (file)
index 0000000..17be371
--- /dev/null
@@ -0,0 +1,63 @@
+From a9d4f19c2bd7009548765f7889228d5b65f048c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 13:43:42 +0200
+Subject: net/mlx5: Call mlx5_sf_id_erase() once in mlx5_sf_dealloc()
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit 2597ee190b4eb48d3b7d35b7bb2cc18046ae087e ]
+
+Before every call of mlx5_sf_dealloc(), there is a call to
+mlx5_sf_id_erase(). So move it to the beginning of mlx5_sf_dealloc().
+Also remove redundant mlx5_sf_id_erase() call from mlx5_sf_free()
+as it is called only from mlx5_sf_dealloc().
+
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 26e42ec7712d ("net/mlx5: Nack sync reset when SFs are present")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index e34a8f88c518c..1dd01701df20e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -111,7 +111,6 @@ mlx5_sf_alloc(struct mlx5_sf_table *table, struct mlx5_eswitch *esw,
+ static void mlx5_sf_free(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
+-      mlx5_sf_id_erase(table, sf);
+       mlx5_sf_hw_table_sf_free(table->dev, sf->controller, sf->id);
+       trace_mlx5_sf_free(table->dev, sf->port_index, sf->controller, sf->hw_fn_id);
+       kfree(sf);
+@@ -361,6 +360,8 @@ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+ static void mlx5_sf_dealloc(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
++      mlx5_sf_id_erase(table, sf);
++
+       if (sf->hw_state == MLX5_VHCA_STATE_ALLOCATED) {
+               mlx5_sf_free(table, sf);
+       } else if (mlx5_sf_is_active(sf)) {
+@@ -401,7 +402,6 @@ int mlx5_devlink_sf_port_del(struct devlink *devlink,
+       }
+       mlx5_eswitch_unload_sf_vport(esw, sf->hw_fn_id);
+-      mlx5_sf_id_erase(table, sf);
+       mutex_lock(&table->sf_state_lock);
+       mlx5_sf_dealloc(table, sf);
+@@ -473,7 +473,6 @@ static void mlx5_sf_deactivate_all(struct mlx5_sf_table *table)
+        */
+       xa_for_each(&table->port_indices, index, sf) {
+               mlx5_eswitch_unload_sf_vport(esw, sf->hw_fn_id);
+-              mlx5_sf_id_erase(table, sf);
+               mlx5_sf_dealloc(table, sf);
+       }
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5-convert-sf-port_indices-xarray-to-function_.patch b/queue-6.6/net-mlx5-convert-sf-port_indices-xarray-to-function_.patch
new file mode 100644 (file)
index 0000000..dc5cae5
--- /dev/null
@@ -0,0 +1,112 @@
+From e8e34b31f43733bc8af5b694cf341343cb4884bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 11:33:16 +0200
+Subject: net/mlx5: Convert SF port_indices xarray to function_ids xarray
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit 2284a4836251b3dee348172f69ac84157aa7b03e ]
+
+No need to lookup for sf by a port index. Convert the xarray to have
+function id as an index and optimize the remaining function id
+based lookup.
+
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 26e42ec7712d ("net/mlx5: Nack sync reset when SFs are present")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/sf/devlink.c  | 29 +++++++------------
+ 1 file changed, 11 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index 4711dcfe8ba83..3f0ac2d1dde68 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -29,7 +29,7 @@ static void *mlx5_sf_by_dl_port(struct devlink_port *dl_port)
+ struct mlx5_sf_table {
+       struct mlx5_core_dev *dev; /* To refer from notifier context. */
+-      struct xarray port_indices; /* port index based lookup. */
++      struct xarray function_ids; /* function id based lookup. */
+       refcount_t refcount;
+       struct completion disable_complete;
+       struct mutex sf_state_lock; /* Serializes sf state among user cmds & vhca event handler. */
+@@ -40,24 +40,17 @@ struct mlx5_sf_table {
+ static struct mlx5_sf *
+ mlx5_sf_lookup_by_function_id(struct mlx5_sf_table *table, unsigned int fn_id)
+ {
+-      unsigned long index;
+-      struct mlx5_sf *sf;
+-
+-      xa_for_each(&table->port_indices, index, sf) {
+-              if (sf->hw_fn_id == fn_id)
+-                      return sf;
+-      }
+-      return NULL;
++      return xa_load(&table->function_ids, fn_id);
+ }
+-static int mlx5_sf_id_insert(struct mlx5_sf_table *table, struct mlx5_sf *sf)
++static int mlx5_sf_function_id_insert(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
+-      return xa_insert(&table->port_indices, sf->port_index, sf, GFP_KERNEL);
++      return xa_insert(&table->function_ids, sf->hw_fn_id, sf, GFP_KERNEL);
+ }
+-static void mlx5_sf_id_erase(struct mlx5_sf_table *table, struct mlx5_sf *sf)
++static void mlx5_sf_function_id_erase(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
+-      xa_erase(&table->port_indices, sf->port_index);
++      xa_erase(&table->function_ids, sf->hw_fn_id);
+ }
+ static struct mlx5_sf *
+@@ -94,7 +87,7 @@ mlx5_sf_alloc(struct mlx5_sf_table *table, struct mlx5_eswitch *esw,
+       sf->hw_state = MLX5_VHCA_STATE_ALLOCATED;
+       sf->controller = controller;
+-      err = mlx5_sf_id_insert(table, sf);
++      err = mlx5_sf_function_id_insert(table, sf);
+       if (err)
+               goto insert_err;
+@@ -347,7 +340,7 @@ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+ static void mlx5_sf_dealloc(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
+-      mlx5_sf_id_erase(table, sf);
++      mlx5_sf_function_id_erase(table, sf);
+       if (sf->hw_state == MLX5_VHCA_STATE_ALLOCATED) {
+               mlx5_sf_free(table, sf);
+@@ -451,7 +444,7 @@ static void mlx5_sf_deactivate_all(struct mlx5_sf_table *table)
+       /* At this point, no new user commands can start and no vhca event can
+        * arrive. It is safe to destroy all user created SFs.
+        */
+-      xa_for_each(&table->port_indices, index, sf) {
++      xa_for_each(&table->function_ids, index, sf) {
+               mlx5_eswitch_unload_sf_vport(esw, sf->hw_fn_id);
+               mlx5_sf_dealloc(table, sf);
+       }
+@@ -510,7 +503,7 @@ int mlx5_sf_table_init(struct mlx5_core_dev *dev)
+       mutex_init(&table->sf_state_lock);
+       table->dev = dev;
+-      xa_init(&table->port_indices);
++      xa_init(&table->function_ids);
+       dev->priv.sf_table = table;
+       refcount_set(&table->refcount, 0);
+       table->esw_nb.notifier_call = mlx5_sf_esw_event;
+@@ -545,6 +538,6 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+       mlx5_esw_event_notifier_unregister(dev->priv.eswitch, &table->esw_nb);
+       WARN_ON(refcount_read(&table->refcount));
+       mutex_destroy(&table->sf_state_lock);
+-      WARN_ON(!xa_empty(&table->port_indices));
++      WARN_ON(!xa_empty(&table->function_ids));
+       kfree(table);
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch b/queue-6.6/net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
new file mode 100644 (file)
index 0000000..b7c5ce8
--- /dev/null
@@ -0,0 +1,247 @@
+From 879ac7b238ecec0f9e67a75e763f9557f23314b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:29 +0300
+Subject: net/mlx5: Fix lockdep assertion on sync reset unload event
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 902a8bc23a24882200f57cadc270e15a2cfaf2bb ]
+
+Fix lockdep assertion triggered during sync reset unload event. When the
+sync reset flow is initiated using the devlink reload fw_activate
+option, the PF already holds the devlink lock while handling unload
+event. In this case, delegate sync reset unload event handling back to
+the devlink callback process to avoid double-locking and resolve the
+lockdep warning.
+
+Kernel log:
+WARNING: CPU: 9 PID: 1578 at devl_assert_locked+0x31/0x40
+[...]
+Call Trace:
+<TASK>
+ mlx5_unload_one_devl_locked+0x2c/0xc0 [mlx5_core]
+ mlx5_sync_reset_unload_event+0xaf/0x2f0 [mlx5_core]
+ process_one_work+0x222/0x640
+ worker_thread+0x199/0x350
+ kthread+0x10b/0x230
+ ? __pfx_worker_thread+0x10/0x10
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x8e/0x100
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+</TASK>
+
+Fixes: 7a9770f1bfea ("net/mlx5: Handle sync reset unload event")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-7-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c |   2 +-
+ .../ethernet/mellanox/mlx5/core/fw_reset.c    | 108 ++++++++++--------
+ .../ethernet/mellanox/mlx5/core/fw_reset.h    |   1 +
+ 3 files changed, 63 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index f2d1f7cad7e72..8489b5087d9c6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+       if (err)
+               return err;
+-      mlx5_unload_one_devl_locked(dev, false);
++      mlx5_sync_reset_unload_flow(dev, true);
+       err = mlx5_health_wait_pci_up(dev);
+       if (err)
+               NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index a1c2dd7f5c2c0..b9986a2656083 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -12,7 +12,8 @@ enum {
+       MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+       MLX5_FW_RESET_FLAGS_PENDING_COMP,
+       MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+-      MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
++      MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
++      MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
+ };
+ struct mlx5_fw_reset {
+@@ -217,7 +218,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
+       return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false);
+ }
+-static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded)
++static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ {
+       struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
+       struct devlink *devlink = priv_to_devlink(dev);
+@@ -226,8 +227,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload
+       if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
+               complete(&fw_reset->done);
+       } else {
+-              if (!unloaded)
+-                      mlx5_unload_one(dev, false);
++              mlx5_sync_reset_unload_flow(dev, false);
+               if (mlx5_health_wait_pci_up(dev))
+                       mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+               else
+@@ -270,7 +270,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work)
+       mlx5_sync_reset_clear_reset_requested(dev, false);
+       mlx5_enter_error_state(dev, true);
+-      mlx5_fw_reset_complete_reload(dev, false);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ #define MLX5_RESET_POLL_INTERVAL      (HZ / 10)
+@@ -553,6 +553,59 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
+       return err;
+ }
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked)
++{
++      struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++      unsigned long timeout;
++      bool reset_action;
++      u8 rst_state;
++      int err;
++
++      if (locked)
++              mlx5_unload_one_devl_locked(dev, false);
++      else
++              mlx5_unload_one(dev, false);
++
++      if (!test_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags))
++              return;
++
++      mlx5_set_fw_rst_ack(dev);
++      mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
++
++      reset_action = false;
++      timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
++      do {
++              rst_state = mlx5_get_fw_rst_state(dev);
++              if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
++                  rst_state == MLX5_FW_RST_STATE_IDLE) {
++                      reset_action = true;
++                      break;
++              }
++              msleep(20);
++      } while (!time_after(jiffies, timeout));
++
++      if (!reset_action) {
++              mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
++                            rst_state);
++              fw_reset->ret = -ETIMEDOUT;
++              goto done;
++      }
++
++      mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n",
++                     rst_state);
++      if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
++              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
++              if (err) {
++                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n",
++                                     err);
++                      fw_reset->ret = err;
++              }
++      }
++
++done:
++      clear_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+@@ -580,16 +633,13 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+       mlx5_enter_error_state(dev, true);
+ done:
+       fw_reset->ret = err;
+-      mlx5_fw_reset_complete_reload(dev, false);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ {
+       struct mlx5_fw_reset *fw_reset;
+       struct mlx5_core_dev *dev;
+-      unsigned long timeout;
+-      bool reset_action;
+-      u8 rst_state;
+       int err;
+       fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work);
+@@ -598,6 +648,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, false))
+               return;
++      set_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n");
+       err = mlx5_cmd_fast_teardown_hca(dev);
+@@ -606,44 +657,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+       else
+               mlx5_enter_error_state(dev, true);
+-      if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
+-              mlx5_unload_one_devl_locked(dev, false);
+-      else
+-              mlx5_unload_one(dev, false);
+-
+-      mlx5_set_fw_rst_ack(dev);
+-      mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
+-
+-      reset_action = false;
+-      timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
+-      do {
+-              rst_state = mlx5_get_fw_rst_state(dev);
+-              if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
+-                  rst_state == MLX5_FW_RST_STATE_IDLE) {
+-                      reset_action = true;
+-                      break;
+-              }
+-              msleep(20);
+-      } while (!time_after(jiffies, timeout));
+-
+-      if (!reset_action) {
+-              mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
+-                            rst_state);
+-              fw_reset->ret = -ETIMEDOUT;
+-              goto done;
+-      }
+-
+-      mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
+-      if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+-              err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+-              if (err) {
+-                      mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
+-                      fw_reset->ret = err;
+-              }
+-      }
+-
+-done:
+-      mlx5_fw_reset_complete_reload(dev, true);
++      mlx5_fw_reset_complete_reload(dev);
+ }
+ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index ea527d06a85f0..d5b28525c960d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -12,6 +12,7 @@ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+ int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev,
+                                    struct netlink_ext_ack *extack);
+ void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev);
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5-nack-sync-reset-when-sfs-are-present.patch b/queue-6.6/net-mlx5-nack-sync-reset-when-sfs-are-present.patch
new file mode 100644 (file)
index 0000000..d0ee892
--- /dev/null
@@ -0,0 +1,100 @@
+From b21262d4f99e687d7fc8da8ccc2760a8444a2c3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:30 +0300
+Subject: net/mlx5: Nack sync reset when SFs are present
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 26e42ec7712d392d561964514b1f253b1a96f42d ]
+
+If PF (Physical Function) has SFs (Sub-Functions), since the SFs are not
+taking part in the synchronization flow, sync reset can lead to fatal
+error on the SFs, as the function will be closed unexpectedly from the
+SF point of view.
+
+Add a check to prevent sync reset when there are SFs on a PF device
+which is not ECPF, as ECPF is teardowned gracefully before reset.
+
+Fixes: 92501fa6e421 ("net/mlx5: Ack on sync_reset_request only if PF can do reset_now")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-8-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c   |  6 ++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 10 ++++++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h      |  6 ++++++
+ 3 files changed, 22 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index b9986a2656083..1547704c89767 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -6,6 +6,7 @@
+ #include "fw_reset.h"
+ #include "diag/fw_tracer.h"
+ #include "lib/tout.h"
++#include "sf/sf.h"
+ enum {
+       MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+@@ -397,6 +398,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev)
+               return false;
+       }
++      if (!mlx5_core_is_ecpf(dev) && !mlx5_sf_table_empty(dev)) {
++              mlx5_core_warn(dev, "SFs should be removed before reset\n");
++              return false;
++      }
++
+ #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)
+       err = mlx5_check_hotplug_interrupt(dev);
+       if (err)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index 3f0ac2d1dde68..c9089f2ec5f25 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -541,3 +541,13 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+       WARN_ON(!xa_empty(&table->function_ids));
+       kfree(table);
+ }
++
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++      struct mlx5_sf_table *table = dev->priv.sf_table;
++
++      if (!table)
++              return true;
++
++      return xa_empty(&table->function_ids);
++}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+index 860f9ddb7107b..89559a37997ad 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+@@ -17,6 +17,7 @@ void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev);
+ int mlx5_sf_table_init(struct mlx5_core_dev *dev);
+ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev);
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev);
+ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+                            const struct devlink_port_new_attrs *add_attr,
+@@ -61,6 +62,11 @@ static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ {
+ }
++static inline bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++      return true;
++}
++
+ #endif
+ #endif
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch b/queue-6.6/net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
new file mode 100644 (file)
index 0000000..9b9ab40
--- /dev/null
@@ -0,0 +1,51 @@
+From 422436abfb60fb8c885b171070635649ce062a8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:28 +0300
+Subject: net/mlx5: Reload auxiliary drivers on fw_activate
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 34cc6a54914f478c93e176450fae6313404f9f74 ]
+
+The devlink reload fw_activate command performs firmware activation
+followed by driver reload, while devlink reload driver_reinit triggers
+only driver reload. However, the driver reload logic differs between the
+two modes, as on driver_reinit mode mlx5 also reloads auxiliary drivers,
+while in fw_activate mode the auxiliary drivers are suspended where
+applicable.
+
+Additionally, following the cited commit, if the device has multiple PFs,
+the behavior during fw_activate may vary between PFs: one PF may suspend
+auxiliary drivers, while another reloads them.
+
+Align devlink dev reload fw_activate behavior with devlink dev reload
+driver_reinit, to reload all auxiliary drivers.
+
+Fixes: 72ed5d5624af ("net/mlx5: Suspend auxiliary devices only in case of PCI device suspend")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index f66788a2ed77e..f2d1f7cad7e72 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+       if (err)
+               return err;
+-      mlx5_unload_one_devl_locked(dev, true);
++      mlx5_unload_one_devl_locked(dev, false);
+       err = mlx5_health_wait_pci_up(dev);
+       if (err)
+               NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5-use-devlink-port-pointer-to-get-the-pointer.patch b/queue-6.6/net-mlx5-use-devlink-port-pointer-to-get-the-pointer.patch
new file mode 100644 (file)
index 0000000..3933aba
--- /dev/null
@@ -0,0 +1,145 @@
+From 4003b3bacd9920125af73f19eb1dfd88d7f4ccc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 13:59:34 +0200
+Subject: net/mlx5: Use devlink port pointer to get the pointer of container SF
+ struct
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit 9caeb1475c3e852bcfa6332227c6bb2feaa8eb23 ]
+
+Benefit from the fact that struct devlink_port is eventually embedded
+in struct mlx5_sf and use container_of() macro to get it instead of the
+xarray lookup in every devlink port op.
+
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 26e42ec7712d ("net/mlx5: Nack sync reset when SFs are present")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/sf/devlink.c  | 44 +++++--------------
+ 1 file changed, 12 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index 1dd01701df20e..4711dcfe8ba83 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -20,6 +20,13 @@ struct mlx5_sf {
+       u16 hw_state;
+ };
++static void *mlx5_sf_by_dl_port(struct devlink_port *dl_port)
++{
++      struct mlx5_devlink_port *mlx5_dl_port = mlx5_devlink_port_get(dl_port);
++
++      return container_of(mlx5_dl_port, struct mlx5_sf, dl_port);
++}
++
+ struct mlx5_sf_table {
+       struct mlx5_core_dev *dev; /* To refer from notifier context. */
+       struct xarray port_indices; /* port index based lookup. */
+@@ -30,12 +37,6 @@ struct mlx5_sf_table {
+       struct notifier_block vhca_nb;
+ };
+-static struct mlx5_sf *
+-mlx5_sf_lookup_by_index(struct mlx5_sf_table *table, unsigned int port_index)
+-{
+-      return xa_load(&table->port_indices, port_index);
+-}
+-
+ static struct mlx5_sf *
+ mlx5_sf_lookup_by_function_id(struct mlx5_sf_table *table, unsigned int fn_id)
+ {
+@@ -171,26 +172,19 @@ int mlx5_devlink_sf_port_fn_state_get(struct devlink_port *dl_port,
+                                     struct netlink_ext_ack *extack)
+ {
+       struct mlx5_core_dev *dev = devlink_priv(dl_port->devlink);
++      struct mlx5_sf *sf = mlx5_sf_by_dl_port(dl_port);
+       struct mlx5_sf_table *table;
+-      struct mlx5_sf *sf;
+-      int err = 0;
+       table = mlx5_sf_table_try_get(dev);
+       if (!table)
+               return -EOPNOTSUPP;
+-      sf = mlx5_sf_lookup_by_index(table, dl_port->index);
+-      if (!sf) {
+-              err = -EOPNOTSUPP;
+-              goto sf_err;
+-      }
+       mutex_lock(&table->sf_state_lock);
+       *state = mlx5_sf_to_devlink_state(sf->hw_state);
+       *opstate = mlx5_sf_to_devlink_opstate(sf->hw_state);
+       mutex_unlock(&table->sf_state_lock);
+-sf_err:
+       mlx5_sf_table_put(table);
+-      return err;
++      return 0;
+ }
+ static int mlx5_sf_activate(struct mlx5_core_dev *dev, struct mlx5_sf *sf,
+@@ -256,8 +250,8 @@ int mlx5_devlink_sf_port_fn_state_set(struct devlink_port *dl_port,
+                                     struct netlink_ext_ack *extack)
+ {
+       struct mlx5_core_dev *dev = devlink_priv(dl_port->devlink);
++      struct mlx5_sf *sf = mlx5_sf_by_dl_port(dl_port);
+       struct mlx5_sf_table *table;
+-      struct mlx5_sf *sf;
+       int err;
+       table = mlx5_sf_table_try_get(dev);
+@@ -266,14 +260,7 @@ int mlx5_devlink_sf_port_fn_state_set(struct devlink_port *dl_port,
+                                  "Port state set is only supported in eswitch switchdev mode or SF ports are disabled.");
+               return -EOPNOTSUPP;
+       }
+-      sf = mlx5_sf_lookup_by_index(table, dl_port->index);
+-      if (!sf) {
+-              err = -ENODEV;
+-              goto out;
+-      }
+-
+       err = mlx5_sf_state_set(dev, table, sf, state, extack);
+-out:
+       mlx5_sf_table_put(table);
+       return err;
+ }
+@@ -384,10 +371,9 @@ int mlx5_devlink_sf_port_del(struct devlink *devlink,
+                            struct netlink_ext_ack *extack)
+ {
+       struct mlx5_core_dev *dev = devlink_priv(devlink);
++      struct mlx5_sf *sf = mlx5_sf_by_dl_port(dl_port);
+       struct mlx5_eswitch *esw = dev->priv.eswitch;
+       struct mlx5_sf_table *table;
+-      struct mlx5_sf *sf;
+-      int err = 0;
+       table = mlx5_sf_table_try_get(dev);
+       if (!table) {
+@@ -395,20 +381,14 @@ int mlx5_devlink_sf_port_del(struct devlink *devlink,
+                                  "Port del is only supported in eswitch switchdev mode or SF ports are disabled.");
+               return -EOPNOTSUPP;
+       }
+-      sf = mlx5_sf_lookup_by_index(table, dl_port->index);
+-      if (!sf) {
+-              err = -ENODEV;
+-              goto sf_err;
+-      }
+       mlx5_eswitch_unload_sf_vport(esw, sf->hw_fn_id);
+       mutex_lock(&table->sf_state_lock);
+       mlx5_sf_dealloc(table, sf);
+       mutex_unlock(&table->sf_state_lock);
+-sf_err:
+       mlx5_sf_table_put(table);
+-      return err;
++      return 0;
+ }
+ static bool mlx5_sf_state_update_check(const struct mlx5_sf *sf, u8 new_state)
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5e-set-local-xoff-after-fw-update.patch b/queue-6.6/net-mlx5e-set-local-xoff-after-fw-update.patch
new file mode 100644 (file)
index 0000000..86fb419
--- /dev/null
@@ -0,0 +1,50 @@
+From d8f10dce13db9cb33c70242c5defdb7a34e0ed09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+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 3efa8bf1d14ef..4720523813b97 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -575,7 +575,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+               if (err)
+                       return err;
+       }
+-      priv->dcbx.xoff = xoff;
+       /* Apply the settings */
+       if (update_buffer) {
+@@ -584,6 +583,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                       return err;
+       }
++      priv->dcbx.xoff = xoff;
++
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch b/queue-6.6/net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
new file mode 100644 (file)
index 0000000..97a1039
--- /dev/null
@@ -0,0 +1,100 @@
+From 77fc8620dc459df9fabc242ff50f80487757a7a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h         | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c   | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+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 f4a19ffbb641c..66d276a1be836 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -66,11 +66,23 @@ struct mlx5e_port_buffer {
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_NETWORK_BUFFER];
+ };
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++                              u32 change, unsigned int mtu,
++                              void *pfc,
++                              u32 *buffer_size,
++                              u8 *prio2buffer)
++{
++      return 0;
++}
++#endif
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 5c6f01abdcb91..09ba60b2e744b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -44,6 +44,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2722,9 +2723,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+       struct mlx5e_params *params = &priv->channels.params;
+       struct net_device *netdev = priv->netdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
+-      u16 mtu;
++      u16 mtu, prev_mtu;
+       int err;
++      mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+       err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+       if (err)
+               return err;
+@@ -2734,6 +2737,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+               netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+                           __func__, mtu, params->sw_mtu);
++      if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++              err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++                                                    NULL, NULL, NULL);
++              if (err) {
++                      netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++                                  __func__, mtu, err, prev_mtu);
++
++                      mlx5e_set_mtu(mdev, params, prev_mtu);
++                      return err;
++              }
++      }
++
+       params->sw_mtu = mtu;
+       return 0;
+ }
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch b/queue-6.6/net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
new file mode 100644 (file)
index 0000000..ad5d38b
--- /dev/null
@@ -0,0 +1,46 @@
+From 9cf9b2f104bdf25466fc38648440c45456850785 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 09ba60b2e744b..d378aa55f22f9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -109,6 +109,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+       if (up) {
+               netdev_info(priv->netdev, "Link up\n");
+               netif_carrier_on(priv->netdev);
++              mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++                                              NULL, NULL, NULL);
+       } else {
+               netdev_info(priv->netdev, "Link down\n");
+               netif_carrier_off(priv->netdev);
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-rose-convert-use-field-to-refcount_t.patch b/queue-6.6/net-rose-convert-use-field-to-refcount_t.patch
new file mode 100644 (file)
index 0000000..0cd4709
--- /dev/null
@@ -0,0 +1,370 @@
+From ea4d53c4008cae4f229baffd5cb00438bce6437d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:56 +0900
+Subject: net: rose: convert 'use' field to refcount_t
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit d860d1faa6b2ce3becfdb8b0c2b048ad31800061 ]
+
+The 'use' field in struct rose_neigh is used as a reference counter but
+lacks atomicity. This can lead to race conditions where a rose_neigh
+structure is freed while still being referenced by other code paths.
+
+For example, when rose_neigh->use becomes zero during an ioctl operation
+via rose_rt_ioctl(), the structure may be removed while its timer is
+still active, potentially causing use-after-free issues.
+
+This patch changes the type of 'use' from unsigned short to refcount_t and
+updates all code paths to use rose_neigh_hold() and rose_neigh_put() which
+operate reference counts atomically.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-3-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h    | 18 +++++++++++++-----
+ net/rose/af_rose.c    | 13 +++++++------
+ net/rose/rose_in.c    | 12 ++++++------
+ net/rose/rose_route.c | 33 ++++++++++++++++++---------------
+ net/rose/rose_timer.c |  2 +-
+ 5 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 174b4f605d849..2b5491bbf39ab 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H 
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+       ax25_cb                 *ax25;
+       struct net_device               *dev;
+       unsigned short          count;
+-      unsigned short          use;
++      refcount_t              use;
+       unsigned int            number;
+       char                    restarted;
+       char                    dce_mode;
+@@ -151,12 +152,19 @@ struct rose_sock {
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++      refcount_inc(&rose_neigh->use);
++}
++
+ static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
+ {
+-      if (rose_neigh->ax25)
+-              ax25_cb_put(rose_neigh->ax25);
+-      kfree(rose_neigh->digipeat);
+-      kfree(rose_neigh);
++      if (refcount_dec_and_test(&rose_neigh->use)) {
++              if (rose_neigh->ax25)
++                      ax25_cb_put(rose_neigh->ax25);
++              kfree(rose_neigh->digipeat);
++              kfree(rose_neigh);
++      }
+ }
+ /* af_rose.c */
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index 66e9ceaaa43a1..614695444b6ac 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+               if (rose->neighbour == neigh) {
+                       rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour = NULL;
+               }
+       }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+               if (rose->device == dev) {
+                       rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+                       if (rose->neighbour)
+-                              rose->neighbour->use--;
++                              rose_neigh_put(rose->neighbour);
+                       netdev_put(rose->device, &rose->dev_tracker);
+                       rose->device = NULL;
+               }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+               break;
+       case ROSE_STATE_2:
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               release_sock(sk);
+               rose_disconnect(sk, 0, -1, -1);
+               lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       rose->lci = rose_new_lci(rose->neighbour);
+       if (!rose->lci) {
+               err = -ENETUNREACH;
++              rose_neigh_put(rose->neighbour);
+               goto out_release;
+       }
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+               dev = rose_dev_first();
+               if (!dev) {
+                       err = -ENETUNREACH;
++                      rose_neigh_put(rose->neighbour);
+                       goto out_release;
+               }
+               user = ax25_findbyuid(current_euid());
+               if (!user) {
+                       err = -EINVAL;
++                      rose_neigh_put(rose->neighbour);
+                       dev_put(dev);
+                       goto out_release;
+               }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       rose->state = ROSE_STATE_1;
+-      rose->neighbour->use++;
+-
+       rose_write_internal(sk, ROSE_CALL_REQUEST);
+       rose_start_heartbeat(sk);
+       rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
+                            GFP_ATOMIC);
+       make_rose->facilities    = facilities;
+-      make_rose->neighbour->use++;
++      rose_neigh_hold(make_rose->neighbour);
+       if (rose_sk(sk)->defer) {
+               make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b4..7caae93937ee9 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       case ROSE_CLEAR_CONFIRMATION:
+               rose_disconnect(sk, 0, -1, -1);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
+       case ROSE_CLEAR_REQUEST:
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               break;
+       default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety
+       if (frametype == ROSE_CLEAR_REQUEST) {
+               rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+               rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+-              rose_sk(sk)->neighbour->use--;
++              rose_neigh_put(rose_sk(sk)->neighbour);
+       }
+       return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index b406b1e0fb1e7..42460da0854d5 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+               rose_neigh->ax25      = NULL;
+               rose_neigh->dev       = dev;
+               rose_neigh->count     = 0;
+-              rose_neigh->use       = 0;
+               rose_neigh->dce_mode  = 0;
+               rose_neigh->loopback  = 0;
+               rose_neigh->number    = rose_neigh_no++;
+               rose_neigh->restarted = 0;
++              refcount_set(&rose_neigh->use, 1);
+               skb_queue_head_init(&rose_neigh->queue);
+@@ -255,10 +255,10 @@ static void rose_remove_route(struct rose_route *rose_route)
+       struct rose_route *s;
+       if (rose_route->neigh1 != NULL)
+-              rose_route->neigh1->use--;
++              rose_neigh_put(rose_route->neigh1);
+       if (rose_route->neigh2 != NULL)
+-              rose_route->neigh2->use--;
++              rose_neigh_put(rose_route->neigh2);
+       if ((s = rose_route_list) == rose_route) {
+               rose_route_list = rose_route->next;
+@@ -323,7 +323,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0) {
++                      if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
+                               rose_neigh_put(rose_neigh);
+                       }
+@@ -375,11 +375,11 @@ void rose_add_loopback_neigh(void)
+       sn->ax25      = NULL;
+       sn->dev       = NULL;
+       sn->count     = 0;
+-      sn->use       = 0;
+       sn->dce_mode  = 1;
+       sn->loopback  = 1;
+       sn->number    = rose_neigh_no++;
+       sn->restarted = 1;
++      refcount_set(&sn->use, 1);
+       skb_queue_head_init(&sn->queue);
+@@ -561,8 +561,7 @@ static int rose_clear_routes(void)
+               s          = rose_neigh;
+               rose_neigh = rose_neigh->next;
+-              if (s->use == 0 && !s->loopback) {
+-                      s->count = 0;
++              if (!s->loopback) {
+                       rose_remove_neigh(s);
+                       rose_neigh_put(s);
+               }
+@@ -680,6 +679,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+                       for (i = 0; i < node->count; i++) {
+                               if (node->neighbour[i]->restarted) {
+                                       res = node->neighbour[i];
++                                      rose_neigh_hold(node->neighbour[i]);
+                                       goto out;
+                               }
+                       }
+@@ -691,6 +691,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+                               for (i = 0; i < node->count; i++) {
+                                       if (!rose_ftimer_running(node->neighbour[i])) {
+                                               res = node->neighbour[i];
++                                              rose_neigh_hold(node->neighbour[i]);
+                                               goto out;
+                                       }
+                                       failed = 1;
+@@ -780,13 +781,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
+               }
+               if (rose_route->neigh1 == rose_neigh) {
+-                      rose_route->neigh1->use--;
++                      rose_neigh_put(rose_route->neigh1);
+                       rose_route->neigh1 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+               }
+               if (rose_route->neigh2 == rose_neigh) {
+-                      rose_route->neigh2->use--;
++                      rose_neigh_put(rose_route->neigh2);
+                       rose_route->neigh2 = NULL;
+                       rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+               }
+@@ -915,7 +916,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+                       rose_clear_queues(sk);
+                       rose->cause      = ROSE_NETWORK_CONGESTION;
+                       rose->diagnostic = 0;
+-                      rose->neighbour->use--;
++                      rose_neigh_put(rose->neighbour);
+                       rose->neighbour  = NULL;
+                       rose->lci        = 0;
+                       rose->state      = ROSE_STATE_0;
+@@ -1040,12 +1041,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+               rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
+-              goto out;
++              goto put_neigh;
+       }
+       if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+               rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+-              goto out;
++              goto put_neigh;
+       }
+       rose_route->lci1      = lci;
+@@ -1058,8 +1059,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_route->lci2      = new_lci;
+       rose_route->neigh2    = new_neigh;
+-      rose_route->neigh1->use++;
+-      rose_route->neigh2->use++;
++      rose_neigh_hold(rose_route->neigh1);
++      rose_neigh_hold(rose_route->neigh2);
+       rose_route->next = rose_route_list;
+       rose_route_list  = rose_route;
+@@ -1071,6 +1072,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+       rose_transmit_link(skb, rose_route->neigh2);
+       res = 1;
++put_neigh:
++      rose_neigh_put(new_neigh);
+ out:
+       spin_unlock_bh(&rose_route_list_lock);
+       spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1186,7 +1189,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         rose_neigh->use,
++                         refcount_read(&rose_neigh->use) - 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 1525773e94aa1..c52d7d20c5199 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+               break;
+       case ROSE_STATE_2:      /* T3 */
+-              rose->neighbour->use--;
++              rose_neigh_put(rose->neighbour);
+               rose_disconnect(sk, ETIMEDOUT, -1, -1);
+               break;
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-rose-include-node-references-in-rose_neigh-refco.patch b/queue-6.6/net-rose-include-node-references-in-rose_neigh-refco.patch
new file mode 100644 (file)
index 0000000..566c313
--- /dev/null
@@ -0,0 +1,142 @@
+From ef0b2fc4f9ca9e4f777ccb13eaae3ba3ce851928 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:57 +0900
+Subject: net: rose: include node references in rose_neigh refcount
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit da9c9c877597170b929a6121a68dcd3dd9a80f45 ]
+
+Current implementation maintains two separate reference counting
+mechanisms: the 'count' field in struct rose_neigh tracks references from
+rose_node structures, while the 'use' field (now refcount_t) tracks
+references from rose_sock.
+
+This patch merges these two reference counting systems using 'use' field
+for proper reference management. Specifically, this patch adds incrementing
+and decrementing of rose_neigh->use when rose_neigh->count is incremented
+or decremented.
+
+This patch also modifies rose_rt_free(), rose_rt_device_down() and
+rose_clear_route() to properly release references to rose_neigh objects
+before freeing a rose_node through rose_remove_node().
+
+These changes ensure rose_neigh structures are properly freed only when
+all references, including those from rose_node structures, are released.
+As a result, this resolves a slab-use-after-free issue reported by Syzbot.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+942297eecf7d2d61d1f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=942297eecf7d2d61d1f1
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-4-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/rose_route.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 42460da0854d5..6acbb795c506d 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+                       }
+               }
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+               goto out;
+       }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+               rose_node->neighbour[rose_node->count] = rose_neigh;
+               rose_node->count++;
+               rose_neigh->count++;
++              rose_neigh_hold(rose_neigh);
+       }
+ out:
+@@ -322,6 +324,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+       for (i = 0; i < rose_node->count; i++) {
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
++                      rose_neigh_put(rose_neigh);
+                       if (rose_neigh->count == 0) {
+                               rose_remove_neigh(rose_neigh);
+@@ -430,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+       rose_node_list  = rose_node;
+       rose_loopback_neigh->count++;
++      rose_neigh_hold(rose_loopback_neigh);
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -461,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+       rose_remove_node(rose_node);
+       rose_loopback_neigh->count--;
++      rose_neigh_put(rose_loopback_neigh);
+ out:
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -500,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+                               memmove(&t->neighbour[i], &t->neighbour[i + 1],
+                                       sizeof(t->neighbour[0]) *
+                                               (t->count - i));
++                              rose_neigh_put(s);
+                       }
+                       if (t->count <= 0)
+@@ -543,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+       struct rose_neigh *s, *rose_neigh;
+       struct rose_node  *t, *rose_node;
++      int i;
+       spin_lock_bh(&rose_node_list_lock);
+       spin_lock_bh(&rose_neigh_list_lock);
+@@ -553,8 +560,12 @@ static int rose_clear_routes(void)
+       while (rose_node != NULL) {
+               t         = rose_node;
+               rose_node = rose_node->next;
+-              if (!t->loopback)
++
++              if (!t->loopback) {
++                      for (i = 0; i < rose_node->count; i++)
++                              rose_neigh_put(t->neighbour[i]);
+                       rose_remove_node(t);
++              }
+       }
+       while (rose_neigh != NULL) {
+@@ -1189,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+                          rose_neigh->dev ? rose_neigh->dev->name : "???",
+                          rose_neigh->count,
+-                         refcount_read(&rose_neigh->use) - 1,
++                         refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
+                          (rose_neigh->dce_mode) ? "DCE" : "DTE",
+                          (rose_neigh->restarted) ? "yes" : "no",
+                          ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1294,6 +1305,7 @@ void __exit rose_rt_free(void)
+       struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+       struct rose_node  *t, *rose_node  = rose_node_list;
+       struct rose_route *u, *rose_route = rose_route_list;
++      int i;
+       while (rose_neigh != NULL) {
+               s          = rose_neigh;
+@@ -1307,6 +1319,8 @@ void __exit rose_rt_free(void)
+               t         = rose_node;
+               rose_node = rose_node->next;
++              for (i = 0; i < t->count; i++)
++                      rose_neigh_put(t->neighbour[i]);
+               rose_remove_node(t);
+       }
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-rose-split-remove-and-free-operations-in-rose_re.patch b/queue-6.6/net-rose-split-remove-and-free-operations-in-rose_re.patch
new file mode 100644 (file)
index 0000000..fe05a12
--- /dev/null
@@ -0,0 +1,115 @@
+From 7dcf66da101ce72d7691bf6ecc16b81acb41eca5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:55 +0900
+Subject: net: rose: split remove and free operations in rose_remove_neigh()
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit dcb34659028f856c423a29ef9b4e2571d203444d ]
+
+The current rose_remove_neigh() performs two distinct operations:
+1. Removes rose_neigh from rose_neigh_list
+2. Frees the rose_neigh structure
+
+Split these operations into separate functions to improve maintainability
+and prepare for upcoming refcount_t conversion. The timer cleanup remains
+in rose_remove_neigh() because free operations can be called from timer
+itself.
+
+This patch introduce rose_neigh_put() to handle the freeing of rose_neigh
+structures and modify rose_remove_neigh() to handle removal only.
+
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-2-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h    |  8 ++++++++
+ net/rose/rose_route.c | 15 ++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa3..174b4f605d849 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -151,6 +151,14 @@ struct rose_sock {
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++      if (rose_neigh->ax25)
++              ax25_cb_put(rose_neigh->ax25);
++      kfree(rose_neigh->digipeat);
++      kfree(rose_neigh);
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int  sysctl_rose_restart_request_timeout;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index a7054546f52df..b406b1e0fb1e7 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,20 +234,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+       if ((s = rose_neigh_list) == rose_neigh) {
+               rose_neigh_list = rose_neigh->next;
+-              if (rose_neigh->ax25)
+-                      ax25_cb_put(rose_neigh->ax25);
+-              kfree(rose_neigh->digipeat);
+-              kfree(rose_neigh);
+               return;
+       }
+       while (s != NULL && s->next != NULL) {
+               if (s->next == rose_neigh) {
+                       s->next = rose_neigh->next;
+-                      if (rose_neigh->ax25)
+-                              ax25_cb_put(rose_neigh->ax25);
+-                      kfree(rose_neigh->digipeat);
+-                      kfree(rose_neigh);
+                       return;
+               }
+@@ -331,8 +323,10 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+               if (rose_node->neighbour[i] == rose_neigh) {
+                       rose_neigh->count--;
+-                      if (rose_neigh->count == 0 && rose_neigh->use == 0)
++                      if (rose_neigh->count == 0 && rose_neigh->use == 0) {
+                               rose_remove_neigh(rose_neigh);
++                              rose_neigh_put(rose_neigh);
++                      }
+                       rose_node->count--;
+@@ -513,6 +507,7 @@ void rose_rt_device_down(struct net_device *dev)
+               }
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       spin_unlock_bh(&rose_neigh_list_lock);
+       spin_unlock_bh(&rose_node_list_lock);
+@@ -569,6 +564,7 @@ static int rose_clear_routes(void)
+               if (s->use == 0 && !s->loopback) {
+                       s->count = 0;
+                       rose_remove_neigh(s);
++                      rose_neigh_put(s);
+               }
+       }
+@@ -1301,6 +1297,7 @@ void __exit rose_rt_free(void)
+               rose_neigh = rose_neigh->next;
+               rose_remove_neigh(s);
++              rose_neigh_put(s);
+       }
+       while (rose_node != NULL) {
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-stmmac-rename-phylink_get_caps-callback-to-updat.patch b/queue-6.6/net-stmmac-rename-phylink_get_caps-callback-to-updat.patch
new file mode 100644 (file)
index 0000000..df4aba5
--- /dev/null
@@ -0,0 +1,118 @@
+From c13941d8583162065671e8da74728f84e5e132a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Apr 2024 12:03:05 +0300
+Subject: net: stmmac: Rename phylink_get_caps() callback to update_caps()
+
+From: Serge Semin <fancer.lancer@gmail.com>
+
+[ Upstream commit dc144baeb4fbfa0d91ce9c3875307566f58704ec ]
+
+Since recent commits the stmmac_ops::phylink_get_caps() callback has no
+longer been responsible for the phylink MAC capabilities getting, but
+merely updates the MAC capabilities in the mac_device_info::link::caps
+field. Rename the callback to comply with the what the method does now.
+
+Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
+Reviewed-by: Romain Gantois <romain.gantois@bootlin.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 42ef11b2bff5 ("net: stmmac: xgmac: Correct supported speed modes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 8 ++++----
+ drivers/net/ethernet/stmicro/stmmac/hwif.h        | 8 ++++----
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++---
+ 3 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+index a9837985a483d..bdb4f527289d2 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+@@ -69,7 +69,7 @@ static void dwmac4_core_init(struct mac_device_info *hw,
+               init_waitqueue_head(&priv->tstamp_busy_wait);
+ }
+-static void dwmac4_phylink_get_caps(struct stmmac_priv *priv)
++static void dwmac4_update_caps(struct stmmac_priv *priv)
+ {
+       if (priv->plat->tx_queues_to_use > 1)
+               priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD | MAC_1000HD);
+@@ -1161,7 +1161,7 @@ static int dwmac4_config_l4_filter(struct mac_device_info *hw, u32 filter_no,
+ const struct stmmac_ops dwmac4_ops = {
+       .core_init = dwmac4_core_init,
+-      .phylink_get_caps = dwmac4_phylink_get_caps,
++      .update_caps = dwmac4_update_caps,
+       .set_mac = stmmac_set_mac,
+       .rx_ipc = dwmac4_rx_ipc_enable,
+       .rx_queue_enable = dwmac4_rx_queue_enable,
+@@ -1204,7 +1204,7 @@ const struct stmmac_ops dwmac4_ops = {
+ const struct stmmac_ops dwmac410_ops = {
+       .core_init = dwmac4_core_init,
+-      .phylink_get_caps = dwmac4_phylink_get_caps,
++      .update_caps = dwmac4_update_caps,
+       .set_mac = stmmac_dwmac4_set_mac,
+       .rx_ipc = dwmac4_rx_ipc_enable,
+       .rx_queue_enable = dwmac4_rx_queue_enable,
+@@ -1253,7 +1253,7 @@ const struct stmmac_ops dwmac410_ops = {
+ const struct stmmac_ops dwmac510_ops = {
+       .core_init = dwmac4_core_init,
+-      .phylink_get_caps = dwmac4_phylink_get_caps,
++      .update_caps = dwmac4_update_caps,
+       .set_mac = stmmac_dwmac4_set_mac,
+       .rx_ipc = dwmac4_rx_ipc_enable,
+       .rx_queue_enable = dwmac4_rx_queue_enable,
+diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
+index 47fb8e1646c2e..ee9a7d98648b0 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
+@@ -300,8 +300,8 @@ struct stmmac_est;
+ struct stmmac_ops {
+       /* MAC core initialization */
+       void (*core_init)(struct mac_device_info *hw, struct net_device *dev);
+-      /* Get phylink capabilities */
+-      void (*phylink_get_caps)(struct stmmac_priv *priv);
++      /* Update MAC capabilities */
++      void (*update_caps)(struct stmmac_priv *priv);
+       /* Enable the MAC RX/TX */
+       void (*set_mac)(void __iomem *ioaddr, bool enable);
+       /* Enable and verify that the IPC module is supported */
+@@ -423,8 +423,8 @@ struct stmmac_ops {
+ #define stmmac_core_init(__priv, __args...) \
+       stmmac_do_void_callback(__priv, mac, core_init, __args)
+-#define stmmac_mac_phylink_get_caps(__priv) \
+-      stmmac_do_void_callback(__priv, mac, phylink_get_caps, __priv)
++#define stmmac_mac_update_caps(__priv) \
++      stmmac_do_void_callback(__priv, mac, update_caps, __priv)
+ #define stmmac_mac_set(__priv, __args...) \
+       stmmac_do_void_callback(__priv, mac, set_mac, __args)
+ #define stmmac_rx_ipc(__priv, __args...) \
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 615d25a0e46be..fa8ee0624f2f2 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1230,8 +1230,8 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
+               xpcs_get_interfaces(priv->hw->xpcs,
+                                   priv->phylink_config.supported_interfaces);
+-      /* Get the MAC specific capabilities */
+-      stmmac_mac_phylink_get_caps(priv);
++      /* Refresh the MAC-specific capabilities */
++      stmmac_mac_update_caps(priv);
+       priv->phylink_config.mac_capabilities = priv->hw->link.caps;
+@@ -7232,7 +7232,7 @@ int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt)
+                       priv->rss.table[i] = ethtool_rxfh_indir_default(i,
+                                                                       rx_cnt);
+-      stmmac_mac_phylink_get_caps(priv);
++      stmmac_mac_update_caps(priv);
+       priv->phylink_config.mac_capabilities = priv->hw->link.caps;
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch b/queue-6.6/net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
new file mode 100644 (file)
index 0000000..e38b916
--- /dev/null
@@ -0,0 +1,68 @@
+From 70d5703b835a692e70b28d80b73eb51b16e492fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:54 +0800
+Subject: net: stmmac: Set CIC bit only for TX queues with COE
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit b1eded580ab28119de0b0f21efe37ee2b4419144 ]
+
+Currently, in the AF_XDP transmit paths, the CIC bit of
+TX Desc3 is set for all packets. Setting this bit for
+packets transmitting through queues that don't support
+checksum offloading causes the TX DMA to get stuck after
+transmitting some packets. This patch ensures the CIC bit
+of TX Desc3 is set only if the TX queue supports checksum
+offloading.
+
+Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-3-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index fa8ee0624f2f2..ff5389a8efc33 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2426,6 +2426,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+       struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
+       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
+       struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
++      bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+       struct xsk_buff_pool *pool = tx_q->xsk_pool;
+       unsigned int entry = tx_q->cur_tx;
+       struct dma_desc *tx_desc = NULL;
+@@ -2496,7 +2497,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+               }
+               stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
+-                                     true, priv->mode, true, true,
++                                     csum, priv->mode, true, true,
+                                      xdp_desc.len);
+               stmmac_enable_dma_transmission(priv, priv->ioaddr);
+@@ -4789,6 +4790,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ {
+       struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
+       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
++      bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+       unsigned int entry = tx_q->cur_tx;
+       struct dma_desc *tx_desc;
+       dma_addr_t dma_addr;
+@@ -4833,7 +4835,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+       stmmac_set_desc_addr(priv, tx_desc, dma_addr);
+       stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len,
+-                             true, priv->mode, true, true,
++                             csum, priv->mode, true, true,
+                              xdpf->len);
+       tx_q->tx_count_frames++;
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-stmmac-xgmac-correct-supported-speed-modes.patch b/queue-6.6/net-stmmac-xgmac-correct-supported-speed-modes.patch
new file mode 100644 (file)
index 0000000..2f7725b
--- /dev/null
@@ -0,0 +1,96 @@
+From c3be2a69b1d2e2d1b8e80a1b63e29db53152f337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:53 +0800
+Subject: net: stmmac: xgmac: Correct supported speed modes
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 42ef11b2bff5b6a2910c28d2ea47cc00e0fbcaec ]
+
+Correct supported speed modes as per the XGMAC databook.
+Commit 9cb54af214a7 ("net: stmmac: Fix IP-cores specific
+MAC capabilities") removes support for 10M, 100M and
+1000HD. 1000HD is not supported by XGMAC IP, but it does
+support 10M and 100M FD mode for XGMAC version >= 2_20,
+and it also supports 10M and 100M HD mode if the HDSEL bit
+is set in the MAC_HW_FEATURE0 reg. This commit enables support
+for 10M and 100M speed modes for XGMAC IP based on XGMAC
+version and MAC capabilities.
+
+Fixes: 9cb54af214a7 ("net: stmmac: Fix IP-cores specific MAC capabilities")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-2-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 13 +++++++++++--
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c  |  5 +++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+index 052566f5b7f36..0bcb378fa0bc9 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+@@ -47,6 +47,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
+       writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
+ }
++static void dwxgmac2_update_caps(struct stmmac_priv *priv)
++{
++      if (!priv->dma_cap.mbps_10_100)
++              priv->hw->link.caps &= ~(MAC_10 | MAC_100);
++      else if (!priv->dma_cap.half_duplex)
++              priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD);
++}
++
+ static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
+ {
+       u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
+@@ -1583,6 +1591,7 @@ static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *
+ const struct stmmac_ops dwxgmac210_ops = {
+       .core_init = dwxgmac2_core_init,
++      .update_caps = dwxgmac2_update_caps,
+       .set_mac = dwxgmac2_set_mac,
+       .rx_ipc = dwxgmac2_rx_ipc,
+       .rx_queue_enable = dwxgmac2_rx_queue_enable,
+@@ -1705,8 +1714,8 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
+               mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+       mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+-                       MAC_1000FD | MAC_2500FD | MAC_5000FD |
+-                       MAC_10000FD;
++                       MAC_10 | MAC_100 | MAC_1000FD |
++                       MAC_2500FD | MAC_5000FD | MAC_10000FD;
+       mac->link.duplex = 0;
+       mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
+       mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 37c4258fef794..b2c03cb65c7cc 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -382,8 +382,11 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
+ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+                                  struct dma_features *dma_cap)
+ {
++      struct stmmac_priv *priv;
+       u32 hw_cap;
++      priv = container_of(dma_cap, struct stmmac_priv, dma_cap);
++
+       /* MAC HW feature 0 */
+       hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
+       dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31;
+@@ -406,6 +409,8 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+       dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
+       dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3;
+       dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
++      if (dma_cap->mbps_1000 && priv->synopsys_id >= DWXGMAC_CORE_2_20)
++              dma_cap->mbps_10_100 = 1;
+       /* MAC HW feature 1 */
+       hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
+-- 
+2.50.1
+
diff --git a/queue-6.6/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch b/queue-6.6/net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
new file mode 100644 (file)
index 0000000..a634b74
--- /dev/null
@@ -0,0 +1,49 @@
+From 5fbfd8e6fa5005293c49fc6d46ea7b9a12ac785d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 05ea74e937939..37c4258fef794 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -203,10 +203,6 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+       }
+       writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+-      /* Enable MTL RX overflow */
+-      value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+-      writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+-- 
+2.50.1
+
diff --git a/queue-6.6/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch b/queue-6.6/phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
new file mode 100644 (file)
index 0000000..2ca950f
--- /dev/null
@@ -0,0 +1,135 @@
+From ab8b27d03d86e08bfd0667fd0965c5dbeab92974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h      |  4 ++++
+ drivers/net/phy/mscc/mscc_main.c |  4 +---
+ drivers/net/phy/mscc/mscc_ptp.c  | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index cdb343779a8fb..4ba6e32cf6d8d 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -476,6 +476,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -490,6 +491,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+       return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+       return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index 3de72d9cc22bd..3a932b30f4358 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2337,9 +2337,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *priv = phydev->priv;
+-
+-      skb_queue_purge(&priv->rx_skbs_list);
++      vsc8584_ptp_deinit(phydev);
+ }
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index add1a9ee721af..1f6237705b44b 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1297,7 +1297,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+-      struct vsc8531_private *vsc8531 = phydev->priv;
+       static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+       static const u8  ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+       u32 val;
+@@ -1514,17 +1513,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+       vsc85xx_ts_eth_cmp1_sig(phydev);
+-      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+-      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+-      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+-      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
+-      phydev->mii_ts = &vsc8531->mii_ts;
+-
+-      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+-      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+-                                                   &phydev->mdio.dev);
+-      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++      return 0;
+ }
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1551,6 +1540,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+       return 0;
+ }
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++      struct vsc8531_private *vsc8531 = phydev->priv;
++
++      if (vsc8531->ptp->ptp_clock) {
++              ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++              skb_queue_purge(&vsc8531->rx_skbs_list);
++      }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+       struct vsc8531_private *priv = phydev->priv;
+@@ -1608,7 +1607,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+       vsc8531->ptp->phydev = phydev;
+-      return 0;
++      vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++      vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++      vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++      vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
++      phydev->mii_ts = &vsc8531->mii_ts;
++
++      memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++      vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++                                                   &phydev->mdio.dev);
++      return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+-- 
+2.50.1
+
diff --git a/queue-6.6/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch b/queue-6.6/powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
new file mode 100644 (file)
index 0000000..ed85575
--- /dev/null
@@ -0,0 +1,68 @@
+From cfe438e147daae11209186e775761e2046c90a6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf..7209d00a9c257 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+       }
+-      switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++      switch (inst_no_rt & ~KVM_MASK_RB) {
+       case KVM_INST_MTSRIN:
+               if (features & KVM_MAGIC_FEAT_SR) {
+                       u32 inst_rb = _inst & KVM_MASK_RB;
+                       kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+               }
+               break;
+-#endif
+       }
++#endif
+-      switch (_inst) {
+ #ifdef CONFIG_BOOKE
++      switch (_inst) {
+       case KVM_INST_WRTEEI_0:
+               kvm_patch_ins_wrteei_0(inst);
+               break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+       case KVM_INST_WRTEEI_1:
+               kvm_patch_ins_wrtee(inst, 0, 1);
+               break;
+-#endif
+       }
++#endif
+ }
+ extern u32 kvm_template_start[];
+-- 
+2.50.1
+
diff --git a/queue-6.6/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch b/queue-6.6/sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
new file mode 100644 (file)
index 0000000..c257aa9
--- /dev/null
@@ -0,0 +1,72 @@
+From a320809ab02399bdd639e1c8797621bf26bc94e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+  sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+  sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+  sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+  sctp_get_port net/sctp/socket.c:8523 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+  x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+  do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+  sctp_get_port net/sctp/socket.c:8515 [inline]
+  sctp_listen_start net/sctp/socket.c:8567 [inline]
+  sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+  __sys_listen_socket net/socket.c:1912 [inline]
+  __sys_listen net/socket.c:1927 [inline]
+  __do_sys_listen net/socket.c:1932 [inline]
+  __se_sys_listen net/socket.c:1930 [inline]
+  __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 717828e531621..0673857cb3d8b 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -547,7 +547,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+       addr->v6.sin6_family = AF_INET6;
+       addr->v6.sin6_port = 0;
++      addr->v6.sin6_flowinfo = 0;
+       addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++      addr->v6.sin6_scope_id = 0;
+ }
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+-- 
+2.50.1
+
index c20bf8bd678bcbf4afe705306fdc21228b990468..9d008b55dc3c860db75aea0d275b86e4b98032e2 100644 (file)
@@ -14,3 +14,42 @@ acpi-ec-add-device-to-acpi_ec_no_wakeup-qurik-list.patch
 nfs-fold-nfs_page_group_lock_subrequests-into-nfs_lock_and_join_requests.patch
 nfs-fix-a-race-when-updating-an-existing-write.patch
 vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+drm-msm-defer-fd_install-in-submit-ioctl.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+hid-input-rename-hidinput_set_battery_charge_status.patch
+hid-input-report-battery-status-changes-immediately.patch
+bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
+bluetooth-hci_event-mark-connection-as-closed-during.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+bluetooth-hci_sync-fix-set_local_name-race-condition.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
+drm-nouveau-remove-unused-memory-target-test.patch
+ice-introduce-ice_xdp_buff.patch
+ice-gather-page_count-s-of-each-frag-right-before-xd.patch
+ice-stop-storing-xdp-verdict-within-ice_rx_buf.patch
+ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
+dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
+net-mlx5-add-device-cap-for-supporting-hot-reset-in-.patch
+net-mlx5-add-support-for-sync-reset-using-hot-reset.patch
+net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
+net-mlx5-call-mlx5_sf_id_erase-once-in-mlx5_sf_deall.patch
+net-mlx5-use-devlink-port-pointer-to-get-the-pointer.patch
+net-mlx5-convert-sf-port_indices-xarray-to-function_.patch
+net-mlx5-nack-sync-reset-when-sfs-are-present.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+net-stmmac-rename-phylink_get_caps-callback-to-updat.patch
+net-stmmac-xgmac-correct-supported-speed-modes.patch
+net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
+net-rose-split-remove-and-free-operations-in-rose_re.patch
+net-rose-convert-use-field-to-refcount_t.patch
+net-rose-include-node-references-in-rose_neigh-refco.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch