From b50e4e2ad54ed517aa89e2963ab2a836bba50b89 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 22 Feb 2026 18:31:07 -0500 Subject: [PATCH] Fixes for all trees Signed-off-by: Sasha Levin --- ...alid-deref-of-rawdata-when-export_bi.patch | 85 ++ ...r-fix-null-sock-in-aa_sock_file_perm.patch | 44 + ...rmor-fix-rlimit-for-posix-cpu-timers.patch | 40 + ...uaf-in-rlb_arp_recv-during-bond-up-d.patch | 108 ++ ...d-leaf-access-in-btrfs_quota_enable-.patch | 52 + ...ernor-when-only-one-idle-state-is-av.patch | 59 + ...free-_dsm-package-when-no-connectors.patch | 40 + ...v6-fix-a-race-in-ip6_sock_set_v6only.patch | 53 + ...an-rcu-grace-period-in-macvlan_commo.patch | 116 ++ ...ndmsg-should-not-discard-payload_len.patch | 50 + ...-catc-enable-basic-endpoint-checking.patch | 111 ++ ...ntrack_h323-don-t-pass-uninitialised.patch | 58 + ...ding-tc_actions-cleanup-temporary-fi.patch | 86 ++ ...ding-tc_actions-use-ncat-instead-of-.patch | 85 ++ ...ding-vxlan_bridge_1d-fix-test-failur.patch | 78 ++ ...tc_restrictions-fix-test-failure-wit.patch | 57 + ...ctions-don-t-dump-2mb-of-0-to-stdout.patch | 57 + queue-5.10/series | 19 + ...tc-use-correct-api-for-mac-addresses.patch | 98 ++ ...ct-zero-queue-configuration-from-gue.patch | 57 + ...maining-for_each_possible_cpu-to-use.patch | 55 + ...alid-deref-of-rawdata-when-export_bi.patch | 85 ++ ...r-fix-null-sock-in-aa_sock_file_perm.patch | 44 + ...rmor-fix-rlimit-for-posix-cpu-timers.patch | 40 + ...vert-fix-missing-lock-in-fsl_xcvr_mo.patch | 52 + ...uaf-in-rlb_arp_recv-during-bond-up-d.patch | 108 ++ .../bpftool-fix-truncated-netlink-dumps.patch | 73 ++ ...d-leaf-access-in-btrfs_quota_enable-.patch | 52 + ...ernor-when-only-one-idle-state-is-av.patch | 59 + ...free-_dsm-package-when-no-connectors.patch | 40 + ...b-out-of-bounds-read-in-deleteindexe.patch | 51 + ...-infinite-loops-caused-by-the-next-v.patch | 58 + ...v6-fix-a-race-in-ip6_sock_set_v6only.patch | 53 + ...an-rcu-grace-period-in-macvlan_commo.patch | 116 ++ ...ndmsg-should-not-discard-payload_len.patch | 50 + ...on_once-when-accessing-forward-path-.patch | 39 + ...ntrack_h323-don-t-pass-uninitialised.patch | 58 + ...ix-default-entries-mcam-entry-action.patch | 85 ++ ...ding-vxlan_bridge_1d-fix-test-failur.patch | 78 ++ ...tc_restrictions-fix-test-failure-wit.patch | 57 + ...ctions-don-t-dump-2mb-of-0-to-stdout.patch | 57 + queue-5.15/series | 22 + ...ct-zero-queue-configuration-from-gue.patch | 57 + ...maining-for_each_possible_cpu-to-use.patch | 55 + ...ed-power-resource-quirk-for-thundero.patch | 67 + ...alid-deref-of-rawdata-when-export_bi.patch | 85 ++ ...r-fix-null-sock-in-aa_sock_file_perm.patch | 44 + ...rmor-fix-rlimit-for-posix-cpu-timers.patch | 40 + ...vert-fix-missing-lock-in-fsl_xcvr_mo.patch | 52 + ...s-tdm-use-param-rate-if-not-provided.patch | 55 + ...uaf-in-rlb_arp_recv-during-bond-up-d.patch | 108 ++ .../bpftool-fix-truncated-netlink-dumps.patch | 73 ++ ...d-leaf-access-in-btrfs_quota_enable-.patch | 52 + ...ernor-when-only-one-idle-state-is-av.patch | 59 + ...use-same-max-plane-scaling-limits-fo.patch | 78 ++ ...free-_dsm-package-when-no-connectors.patch | 40 + ...b-out-of-bounds-read-in-deleteindexe.patch | 51 + ...-infinite-loops-caused-by-the-next-v.patch | 58 + ...er_sec-and-icmp_msgs_burst-sysctls-b.patch | 145 +++ ...lobal.credit-and-icmp_global.stamp-t.patch | 168 +++ ...ssible-overflow-in-icmp_global_allow.patch | 41 + ...sock_net-in-ping_get_port-and-ping_l.patch | 84 ++ ...v6-fix-a-race-in-ip6_sock_set_v6only.patch | 53 + ...an-rcu-grace-period-in-macvlan_commo.patch | 116 ++ ...add-missing-lock-protection-in-ocelo.patch | 62 + ...extract-ocelot_xmit_timestamp-helper.patch | 93 ++ ...split-xmit-into-fdma-and-register-in.patch | 100 ++ ...ndmsg-should-not-discard-payload_len.patch | 50 + ...on_once-when-accessing-forward-path-.patch | 39 + ...9x-fix-dwrr-cost-max-to-match-hardwa.patch | 48 + ...-lan969x-fix-ptp-clock-max_adj-value.patch | 53 + ...-catc-enable-basic-endpoint-checking.patch | 111 ++ ...ntrack_h323-don-t-pass-uninitialised.patch | 58 + ...les-fix-use-after-free-in-nf_tables_.patch | 54 + ...ix-default-entries-mcam-entry-action.patch | 85 ++ ...g-annotate-data-races-in-ping_lookup.patch | 118 ++ ...g-convert-hlist_nulls-to-plain-hlist.patch | 162 +++ ...g-sort-config-s390-select-list-again.patch | 54 + ...kexec_sig-available-when-config_modu.patch | 61 + ...ec-refactor-for-kernel-kconfig.kexec.patch | 128 ++ ...h_want_hugetlb_page_optimize_vmemmap.patch | 83 ++ ...ding-vxlan_bridge_1d-fix-test-failur.patch | 78 ++ ...ding-vxlan_bridge_1d_ipv6-fix-test-f.patch | 69 ++ ...tc_restrictions-fix-test-failure-wit.patch | 57 + ...ctions-don-t-dump-2mb-of-0-to-stdout.patch | 57 + queue-6.1/series | 43 + ...ct-zero-queue-configuration-from-gue.patch | 57 + ...n-adjust-event-notification-routines.patch | 262 ++++ ...-device_init_wakeup-earlier-during-p.patch | 67 + ...convert-the-driver-to-a-platform-one.patch | 211 ++++ ...all-notifier-for-system-events-as-we.patch | 76 ++ ...-send-key_power-for-acpi_button_noti.patch | 50 + ...maining-for_each_possible_cpu-to-use.patch | 55 + ...ed-power-resource-quirk-for-thundero.patch | 67 + ...pparmor-to-handle-unaligned-dfa-tabl.patch | 108 ++ ...er-cpu-hold-underflow-in-aa_get_buff.patch | 43 + ...label-to-return-state-from-compount-.patch | 74 ++ ...alid-deref-of-rawdata-when-export_bi.patch | 85 ++ ...r-fix-null-sock-in-aa_sock_file_perm.patch | 44 + ...imize-table-creation-from-possibly-u.patch | 79 ++ ...rmor-fix-rlimit-for-posix-cpu-timers.patch | 40 + ...abel_match-return-a-consistent-value.patch | 80 ++ ...apply_modes_to_perms-from-label_matc.patch | 53 + ...enomem-in-unpack_perms_table-upon-al.patch | 44 + ...261-fix-erroneous-bitmask-logic-in-a.patch | 49 + ...vert-fix-missing-lock-in-fsl_xcvr_mo.patch | 52 + ...s-tdm-use-param-rate-if-not-provided.patch | 55 + ...uaf-in-rlb_arp_recv-during-bond-up-d.patch | 108 ++ .../bpftool-fix-truncated-netlink-dumps.patch | 73 ++ ...d-leaf-access-in-btrfs_quota_enable-.patch | 52 + ...rrect-type-to-initialize-block-reser.patch | 82 ++ ...ernor-when-only-one-idle-state-is-av.patch | 59 + ...fix-out-of-bounds-stream-encoder-ind.patch | 216 ++++ ...reject-cursor-plane-on-dce-when-scal.patch | 69 ++ ...use-same-max-plane-scaling-limits-fo.patch | 78 ++ ...emory-leak-in-amdgpu_acpi_enumerate_.patch | 46 + ...u-fix-memory-leak-in-amdgpu_ras_init.patch | 44 + ...vfree-instead-of-kfree-in-amdgpu_gmc.patch | 44 + ...atch_id-bounds-checking-in-debug-add.patch | 138 +++ ...free-_dsm-package-when-no-connectors.patch | 40 + ...e-add-xe_tile-backpointer-to-xe_mmio.patch | 94 ++ ...io-code-to-pass-vf-substructure-to-s.patch | 75 ++ .../drm-xe-clarify-size-of-mmio-region.patch | 100 ++ ...e-create-dedicated-xe_mmio-structure.patch | 73 ++ ...-avoid-double-adjust-in-64-bit-reads.patch | 61 + ...move-forcewake-to-gt.pm-substructure.patch | 126 ++ ...offset-adjustment-fields-into-struct.patch | 149 +++ ...gt-s-mmio-iomap-from-tile-during-ini.patch | 47 + .../drm-xe-ptl-apply-wa_13011645652.patch | 36 + ...io-interface-to-take-xe_mmio-instead.patch | 437 +++++++ ...witch-mmio_ext-to-use-struct-xe_mmio.patch | 58 + ...rm-xe-xe2_hpg-add-set-of-workarounds.patch | 170 +++ ...ix-handling-of-wa_14019988906-wa_140.patch | 72 ++ ...servation-of-unaccepted-memory-table.patch | 62 + ...b-out-of-bounds-read-in-deleteindexe.patch | 51 + ...fs3-initialize-new-folios-before-use.patch | 43 + ...-infinite-loops-caused-by-the-next-v.patch | 58 + ...ssible-overflow-in-icmp_global_allow.patch | 41 + ...lobal_-credit-stamp-to-a-separate-ca.patch | 57 + ...v6-fix-a-race-in-ip6_sock_set_v6only.patch | 53 + ...-of-bound-access-in-fib6_add_rt2node.patch | 125 ++ ...t-keep-dest_dst-if-dev-is-going-down.patch | 129 ++ ...dd-objtool-to-top-level-clean-target.patch | 71 ++ ...an-rcu-grace-period-in-macvlan_commo.patch | 116 ++ ...-always-update-mdb_n_entries-for-vla.patch | 192 +++ ...ultiport-device-check-over-light-sfs.patch | 55 + ...signed-for-mlx5e_get_max_num_channel.patch | 48 + ...add-missing-lock-protection-in-ocelo.patch | 62 + ...extract-ocelot_xmit_timestamp-helper.patch | 93 ++ ...split-xmit-into-fdma-and-register-in.patch | 100 ++ ...ndmsg-should-not-discard-payload_len.patch | 50 + ...on_once-when-accessing-forward-path-.patch | 39 + ...9x-fix-dwrr-cost-max-to-match-hardwa.patch | 48 + ...-lan969x-fix-ptp-clock-max_adj-value.patch | 53 + ...-catc-enable-basic-endpoint-checking.patch | 111 ++ ...ntrack_h323-don-t-pass-uninitialised.patch | 58 + ...les-fix-use-after-free-in-nf_tables_.patch | 54 + ...overestimation-of-object-pooling-met.patch | 47 + ...ix-default-entries-mcam-entry-action.patch | 85 ++ ...g-annotate-data-races-in-ping_lookup.patch | 118 ++ ...apl_tpmi-remove-fw_bug-from-invalid-.patch | 49 + ...kexec_sig-available-when-config_modu.patch | 61 + ...ding-vxlan_bridge_1d-fix-test-failur.patch | 78 ++ ...ding-vxlan_bridge_1d_ipv6-fix-test-f.patch | 69 ++ ...use-ipc-semaphore-instead-of-sigstop.patch | 241 ++++ ...tc_restrictions-fix-test-failure-wit.patch | 57 + ...ctions-don-t-dump-2mb-of-0-to-stdout.patch | 57 + queue-6.12/series | 83 ++ ...-potential-null-pointer-dereference-.patch | 49 + ...hyperv-fix-error-pointer-dereference.patch | 54 + ...ct-zero-queue-configuration-from-gue.patch | 57 + ...n-adjust-event-notification-routines.patch | 262 ++++ ...-device_init_wakeup-earlier-during-p.patch | 67 + ...convert-the-driver-to-a-platform-one.patch | 211 ++++ ...maining-for_each_possible_cpu-to-use.patch | 55 + ...ed-power-resource-quirk-for-thundero.patch | 67 + ...-for-in_atomic-removal-in-common_fil.patch | 46 + ...pparmor-to-handle-unaligned-dfa-tabl.patch | 108 ++ ...er-cpu-hold-underflow-in-aa_get_buff.patch | 43 + ..._atomic-flag-in-common_mmap-and-comm.patch | 102 ++ ...label-to-return-state-from-compount-.patch | 74 ++ ...olean-argument-in-apparmor_mmap_file.patch | 38 + ...alid-deref-of-rawdata-when-export_bi.patch | 85 ++ ...l-pointer-dereference-in-__unix_need.patch | 62 + ...r-fix-null-sock-in-aa_sock_file_perm.patch | 44 + ...imize-table-creation-from-possibly-u.patch | 79 ++ ...rmor-fix-rlimit-for-posix-cpu-timers.patch | 40 + ...abel_match-return-a-consistent-value.patch | 80 ++ ...eck-for-aa_null-file-to-cover-all-ca.patch | 85 ++ ...apply_modes_to_perms-from-label_matc.patch | 53 + ...enomem-in-unpack_perms_table-upon-al.patch | 44 + ...261-fix-erroneous-bitmask-logic-in-a.patch | 49 + ...vert-fix-missing-lock-in-fsl_xcvr_mo.patch | 52 + ...s-tdm-use-param-rate-if-not-provided.patch | 55 + ...bnge-fix-reserving-resources-from-fw.patch | 41 + ...uaf-in-rlb_arp_recv-during-bond-up-d.patch | 108 ++ ...tf-from-a-fd-array-more-consistently.patch | 51 + ...tential-use-after-free-of-btf-object.patch | 145 +++ .../bpftool-fix-truncated-netlink-dumps.patch | 73 ++ ...d-leaf-access-in-btrfs_quota_enable-.patch | 52 + ...ck-group-critical-section-in-btrfs_f.patch | 65 + ...info-argument-from-btrfs_try_grantin.patch | 147 +++ ...k-group-size-class-when-it-becomes-e.patch | 81 ++ ...rrect-type-to-initialize-block-reser.patch | 82 ++ ...ernor-when-only-one-idle-state-is-av.patch | 59 + ...fix-out-of-bounds-stream-encoder-ind.patch | 216 ++++ ...reject-cursor-plane-on-dce-when-scal.patch | 69 ++ ...use-same-max-plane-scaling-limits-fo.patch | 78 ++ ...emory-leak-in-amdgpu_acpi_enumerate_.patch | 46 + ...u-fix-memory-leak-in-amdgpu_ras_init.patch | 44 + ...pu-move-reset-debug-disable-handling.patch | 238 ++++ ...-enable-queue-resets-unconditionally.patch | 49 + ....2-enable-queue-resets-unconditional.patch | 58 + ...-enable-queue-resets-unconditionally.patch | 51 + ...vfree-instead-of-kfree-in-amdgpu_gmc.patch | 44 + ...atch_id-bounds-checking-in-debug-add.patch | 138 +++ ...free-_dsm-package-when-no-connectors.patch | 40 + ...ct-faults-to-dummy-page-for-wedged-d.patch | 44 + ...fs-fix-parameter-name-omitted-errors.patch | 69 ++ ..._modparam.force_vram_bar_size-signed.patch | 42 + ...-avoid-double-adjust-in-64-bit-reads.patch | 61 + ...ix-handling-of-wa_14019988906-wa_140.patch | 72 ++ ...servation-of-unaccepted-memory-table.patch | 62 + ...fbnic-add-validation-for-mtu-changes.patch | 68 ++ ...nic-advertise-supported-xdp-features.patch | 57 + ...nfigure-rde-settings-for-pause-frame.patch | 145 +++ ...se-fbnic_hdr_bytes_min-from-128-to-2.patch | 43 + ...-fbnic-set-dma_hint_l4-for-all-flows.patch | 61 + ...nic_queue_rde_ctl0_en_hdr_split-on-r.patch | 99 ++ ..._log-race-between-users-and-teardown.patch | 124 ++ ...b-out-of-bounds-read-in-deleteindexe.patch | 51 + ...fs3-initialize-new-folios-before-use.patch | 43 + ...-infinite-loops-caused-by-the-next-v.patch | 58 + ...ly-return-allowed-values-from-amd_fc.patch | 58 + ...ssible-overflow-in-icmp_global_allow.patch | 41 + ...lobal_-credit-stamp-to-a-separate-ca.patch | 57 + ...v6-fix-a-race-in-ip6_sock_set_v6only.patch | 53 + ...-of-bound-access-in-fib6_add_rt2node.patch | 125 ++ ...-obsolete-code-in-icmpv6_xrlim_allow.patch | 95 ++ ...t-keep-dest_dst-if-dev-is-going-down.patch | 129 ++ ...dd-objtool-to-top-level-clean-target.patch | 71 ++ ...id-write-loop-logic-in-bpf_linker__a.patch | 43 + ...an-rcu-grace-period-in-macvlan_commo.patch | 116 ++ ...otection-in-irqfd-resampler-ack-hand.patch | 51 + ...-always-update-mdb_n_entries-for-vla.patch | 192 +++ ...identification-of-write-combining-cq.patch | 87 ++ ...ultiport-device-check-over-light-sfs.patch | 55 + ...adlocks-between-devlink-and-netdev-i.patch | 318 +++++ ...signed-for-mlx5e_get_max_num_channel.patch | 48 + ...add-missing-lock-protection-in-ocelo.patch | 62 + ...extract-ocelot_xmit_timestamp-helper.patch | 93 ++ ...split-xmit-into-fdma-and-register-in.patch | 100 ++ ...net-psp-select-config_skb_extensions.patch | 59 + ...ndmsg-should-not-discard-payload_len.patch | 50 + ...on_once-when-accessing-forward-path-.patch | 39 + ...9x-fix-dwrr-cost-max-to-match-hardwa.patch | 48 + ...-lan969x-fix-ptp-clock-max_adj-value.patch | 53 + ...ix-oops-when-split-header-is-enabled.patch | 79 ++ .../net-stmmac-remove-broken-pcs-code.patch | 284 +++++ ...mmac-replace-has_xxxx-with-core_type.patch | 804 ++++++++++++ ...-catc-enable-basic-endpoint-checking.patch | 111 ++ ...ntrack_h323-don-t-pass-uninitialised.patch | 58 + ...les-fix-use-after-free-in-nf_tables_.patch | 54 + ...overestimation-of-object-pooling-met.patch | 47 + ...ix-default-entries-mcam-entry-action.patch | 85 ++ ...ible-use-after-free-in-ovpn_net_xmit.patch | 113 ++ .../ovpn-fix-vpn-tx-bytes-counting.patch | 60 + ...ser_data-before-overriding-callbacks.patch | 155 +++ ...eref-null-sk_socket-member-after-tcp.patch | 78 ++ ...dow-resource-type-in-pbus_select_win.patch | 70 ++ ...g-annotate-data-races-in-ping_lookup.patch | 118 ++ ...apl_tpmi-remove-fw_bug-from-invalid-.patch | 49 + ...kexec_sig-available-when-config_modu.patch | 61 + ...ding-vxlan_bridge_1d-fix-test-failur.patch | 78 ++ ...ding-vxlan_bridge_1d_ipv6-fix-test-f.patch | 69 ++ ...use-ipc-semaphore-instead-of-sigstop.patch | 241 ++++ ...tc_restrictions-fix-test-failure-wit.patch | 57 + ...lftests-net-lib-fix-jq-parsing-error.patch | 56 + ...sole-increase-port-listening-timeout.patch | 44 + ...sole-remove-log-noise-due-to-socat-e.patch | 70 ++ ...ctions-don-t-dump-2mb-of-0-to-stdout.patch | 57 + queue-6.18/series | 113 ++ ...-potential-null-pointer-dereference-.patch | 49 + ...hyperv-fix-error-pointer-dereference.patch | 54 + ...ct-zero-queue-configuration-from-gue.patch | 57 + ...n-adjust-event-notification-routines.patch | 262 ++++ ...-device_init_wakeup-earlier-during-p.patch | 67 + ...convert-the-driver-to-a-platform-one.patch | 211 ++++ ...maining-for_each_possible_cpu-to-use.patch | 55 + ...ed-power-resource-quirk-for-thundero.patch | 67 + ...-for-in_atomic-removal-in-common_fil.patch | 46 + ...pparmor-to-handle-unaligned-dfa-tabl.patch | 108 ++ ...er-cpu-hold-underflow-in-aa_get_buff.patch | 43 + ..._atomic-flag-in-common_mmap-and-comm.patch | 102 ++ ...label-to-return-state-from-compount-.patch | 74 ++ ...olean-argument-in-apparmor_mmap_file.patch | 38 + ...alid-deref-of-rawdata-when-export_bi.patch | 85 ++ ...l-pointer-dereference-in-__unix_need.patch | 62 + ...r-fix-null-sock-in-aa_sock_file_perm.patch | 44 + ...imize-table-creation-from-possibly-u.patch | 79 ++ ...rmor-fix-rlimit-for-posix-cpu-timers.patch | 40 + ...abel_match-return-a-consistent-value.patch | 80 ++ ...eck-for-aa_null-file-to-cover-all-ca.patch | 85 ++ ...apply_modes_to_perms-from-label_matc.patch | 53 + ...enomem-in-unpack_perms_table-upon-al.patch | 44 + ...261-fix-erroneous-bitmask-logic-in-a.patch | 49 + ...vert-fix-missing-lock-in-fsl_xcvr_mo.patch | 52 + ...s-tdm-use-param-rate-if-not-provided.patch | 55 + ...bnge-fix-reserving-resources-from-fw.patch | 41 + ...uaf-in-rlb_arp_recv-during-bond-up-d.patch | 108 ++ ...tf-from-a-fd-array-more-consistently.patch | 51 + ...tential-use-after-free-of-btf-object.patch | 145 +++ .../bpftool-fix-truncated-netlink-dumps.patch | 73 ++ ...d-leaf-access-in-btrfs_quota_enable-.patch | 52 + ...k-group-size-class-when-it-becomes-e.patch | 81 ++ ...rrect-type-to-initialize-block-reser.patch | 82 ++ ...ernor-when-only-one-idle-state-is-av.patch | 59 + ...ll-zl3073x-fix-ref-frequency-setting.patch | 56 + ...-don-t-call-find_analog_engine-twice.patch | 42 + ...splay-enable-dac-in-dce-link-encoder.patch | 212 ++++ ...fix-dc_link-null-handling-in-hpd-ini.patch | 99 ++ ...fix-out-of-bounds-stream-encoder-ind.patch | 216 ++++ ...initialize-dac-in-dce-link-encoder-u.patch | 74 ++ ...only-use-analog-link-encoder-with-an.patch | 72 ++ ...only-use-analog-stream-encoder-with-.patch | 44 + ...reject-cursor-plane-on-dce-when-scal.patch | 69 ++ ...set-crtc-source-for-dac-using-regist.patch | 276 +++++ ...turn-off-dac-in-dce-link-encoder-usi.patch | 97 ++ ...use-dce-6-link-encoder-for-dce-6-ana.patch | 40 + ...use-same-max-plane-scaling-limits-fo.patch | 78 ++ ...pu-clean-up-the-amdgpu_cs_parser_bos.patch | 50 + ...emory-leak-in-amdgpu_acpi_enumerate_.patch | 46 + ...u-fix-memory-leak-in-amdgpu_ras_init.patch | 44 + ...issing-unwind-in-amdgpu_ib_schedule-.patch | 86 ++ ...-enable-queue-resets-unconditionally.patch | 49 + ....2-enable-queue-resets-unconditional.patch | 58 + ...-enable-queue-resets-unconditionally.patch | 51 + ...vfree-instead-of-kfree-in-amdgpu_gmc.patch | 44 + ...atch_id-bounds-checking-in-debug-add.patch | 138 +++ ...free-_dsm-package-when-no-connectors.patch | 40 + ...ct-faults-to-dummy-page-for-wedged-d.patch | 44 + ...fs-fix-parameter-name-omitted-errors.patch | 69 ++ ..._modparam.force_vram_bar_size-signed.patch | 42 + ...-avoid-double-adjust-in-64-bit-reads.patch | 61 + .../drm-xe-pf-fix-sysfs-initialization.patch | 158 +++ ...reading-media-version-when-media-gt-.patch | 63 + ...ix-handling-of-wa_14019988906-wa_140.patch | 72 ++ ...servation-of-unaccepted-memory-table.patch | 62 + ...fbnic-add-validation-for-mtu-changes.patch | 68 ++ ...nic-advertise-supported-xdp-features.patch | 57 + ...se-fbnic_hdr_bytes_min-from-128-to-2.patch | 43 + ...-fbnic-set-dma_hint_l4-for-all-flows.patch | 61 + ...nic_queue_rde_ctl0_en_hdr_split-on-r.patch | 99 ++ ..._log-race-between-users-and-teardown.patch | 124 ++ ...3-fix-deadlock-in-ni_read_folio_cmpr.patch | 72 ++ ...s_mount_options-leak-in-ntfs_fill_su.patch | 86 ++ ...b-out-of-bounds-read-in-deleteindexe.patch | 51 + ...fs3-initialize-new-folios-before-use.patch | 43 + ...-infinite-loops-caused-by-the-next-v.patch | 58 + ...ni_readpage_cmpr-into-ni_read_folio_.patch | 80 ++ ...ly-return-allowed-values-from-amd_fc.patch | 58 + ...null-dereference-in-linehandle_creat.patch | 42 + ...ssible-overflow-in-icmp_global_allow.patch | 41 + ...lobal_-credit-stamp-to-a-separate-ca.patch | 57 + ...v6-fix-a-race-in-ip6_sock_set_v6only.patch | 53 + ...-of-bound-access-in-fib6_add_rt2node.patch | 125 ++ ...-obsolete-code-in-icmpv6_xrlim_allow.patch | 95 ++ ...t-keep-dest_dst-if-dev-is-going-down.patch | 129 ++ ...v6-extension-headers-for-csum-checks.patch | 203 ++++ ...dd-objtool-to-top-level-clean-target.patch | 71 ++ ...id-write-loop-logic-in-bpf_linker__a.patch | 43 + ...an-rcu-grace-period-in-macvlan_commo.patch | 116 ++ ...otection-in-irqfd-resampler-ack-hand.patch | 51 + ...-always-update-mdb_n_entries-for-vla.patch | 192 +++ ...-zero-copy-skbs-in-skb_attempt_defer.patch | 48 + ...-our-nlmsg-responses-are-initialised.patch | 70 ++ ...identification-of-write-combining-cq.patch | 87 ++ ...ultiport-device-check-over-light-sfs.patch | 55 + ...adlocks-between-devlink-and-netdev-i.patch | 318 +++++ ...sidentification-of-aso-cqe-during-po.patch | 112 ++ ...-add-aso-poll-loop-in-macsec_aso_set.patch | 45 + ...signed-for-mlx5e_get_max_num_channel.patch | 48 + ...add-missing-lock-protection-in-ocelo.patch | 62 + ...extract-ocelot_xmit_timestamp-helper.patch | 93 ++ ...split-xmit-into-fdma-and-register-in.patch | 100 ++ ...net-psp-select-config_skb_extensions.patch | 59 + ...ndmsg-should-not-discard-payload_len.patch | 50 + ...on_once-when-accessing-forward-path-.patch | 39 + ...9x-fix-dwrr-cost-max-to-match-hardwa.patch | 48 + ...-lan969x-fix-ptp-clock-max_adj-value.patch | 53 + ...ix-oops-when-split-header-is-enabled.patch | 79 ++ ...-catc-enable-basic-endpoint-checking.patch | 111 ++ ...ntrack_h323-don-t-pass-uninitialised.patch | 58 + ...les-fix-use-after-free-in-nf_tables_.patch | 54 + ...les-revert-commit_mutex-usage-in-res.patch | 424 +++++++ ...ounter-serialize-reset-with-spinlock.patch | 86 ++ ...ft_quota-use-atomic64_xchg-for-reset.patch | 61 + ...overestimation-of-object-pooling-met.patch | 47 + ...ix-default-entries-mcam-entry-action.patch | 85 ++ ...ible-use-after-free-in-ovpn_net_xmit.patch | 113 ++ .../ovpn-fix-vpn-tx-bytes-counting.patch | 60 + ...ser_data-before-overriding-callbacks.patch | 155 +++ ...eref-null-sk_socket-member-after-tcp.patch | 78 ++ ...p-always-clear-ib-maps-on-bar-update.patch | 82 ++ ...dow-resource-type-in-pbus_select_win.patch | 70 ++ ...g-annotate-data-races-in-ping_lookup.patch | 118 ++ ...apl-remove-incorrect-cpu-check-in-pm.patch | 119 ++ ...apl_tpmi-remove-fw_bug-from-invalid-.patch | 49 + ...tor-mt6363-fix-interrmittent-timeout.patch | 52 + ...kexec_sig-available-when-config_modu.patch | 61 + ...ding-fix-pedit-tests-failure-with-br.patch | 86 ++ ...ding-vxlan_bridge_1d-fix-test-failur.patch | 78 ++ ...ding-vxlan_bridge_1d_ipv6-fix-test-f.patch | 69 ++ ...use-ipc-semaphore-instead-of-sigstop.patch | 241 ++++ ...tc_restrictions-fix-test-failure-wit.patch | 57 + ...lftests-net-lib-fix-jq-parsing-error.patch | 56 + ...sole-increase-port-listening-timeout.patch | 44 + ...ctions-don-t-dump-2mb-of-0-to-stdout.patch | 57 + queue-6.19/series | 139 +++ ...egression-with-mount-options-parsing.patch | 56 + ...-potential-null-pointer-dereference-.patch | 49 + ...ostat-amd-msr-offset-0x611-read-fail.patch | 42 + ...ostat-harden-against-unexpected-valu.patch | 275 +++++ ...hyperv-fix-error-pointer-dereference.patch | 54 + ...ct-zero-queue-configuration-from-gue.patch | 57 + ...maining-for_each_possible_cpu-to-use.patch | 55 + ...ed-power-resource-quirk-for-thundero.patch | 67 + ...label-to-return-state-from-compount-.patch | 74 ++ ...alid-deref-of-rawdata-when-export_bi.patch | 85 ++ ...r-fix-null-sock-in-aa_sock_file_perm.patch | 44 + ...rmor-fix-rlimit-for-posix-cpu-timers.patch | 40 + ...abel_match-return-a-consistent-value.patch | 80 ++ ...-separate-audit-messages-for-file-an.patch | 51 + queue-6.6/apparmor-refcount-the-pdb.patch | 1075 +++++++++++++++++ ...apply_modes_to_perms-from-label_matc.patch | 53 + ...enomem-in-unpack_perms_table-upon-al.patch | 44 + ...passed-in-gfp-flags-in-aa_alloc_null.patch | 44 + ...261-fix-erroneous-bitmask-logic-in-a.patch | 49 + ...vert-fix-missing-lock-in-fsl_xcvr_mo.patch | 52 + ...s-tdm-use-param-rate-if-not-provided.patch | 55 + ...uaf-in-rlb_arp_recv-during-bond-up-d.patch | 108 ++ .../bpftool-fix-truncated-netlink-dumps.patch | 73 ++ ...d-leaf-access-in-btrfs_quota_enable-.patch | 52 + ...eline_group_-begin-end-_aligned-coup.patch | 131 ++ queue-6.6/cache-enforce-cache-groups.patch | 89 ++ ...ernor-when-only-one-idle-state-is-av.patch | 59 + ...use-same-max-plane-scaling-limits-fo.patch | 78 ++ ...emory-leak-in-amdgpu_acpi_enumerate_.patch | 46 + ...u-fix-memory-leak-in-amdgpu_ras_init.patch | 44 + ...ebug-watchpoints-for-logical-devices.patch | 135 +++ ...atch_id-bounds-checking-in-debug-add.patch | 138 +++ ...free-_dsm-package-when-no-connectors.patch | 40 + ...servation-of-unaccepted-memory-table.patch | 62 + ...b-out-of-bounds-read-in-deleteindexe.patch | 51 + ...-infinite-loops-caused-by-the-next-v.patch | 58 + ...er_sec-and-icmp_msgs_burst-sysctls-b.patch | 145 +++ ...lobal.credit-and-icmp_global.stamp-t.patch | 168 +++ ...ssible-overflow-in-icmp_global_allow.patch | 41 + ...lobal_-credit-stamp-to-a-separate-ca.patch | 57 + ...v6-fix-a-race-in-ip6_sock_set_v6only.patch | 53 + ...-of-bound-access-in-fib6_add_rt2node.patch | 125 ++ ...dd-objtool-to-top-level-clean-target.patch | 71 ++ ...an-rcu-grace-period-in-macvlan_commo.patch | 116 ++ ...-always-update-mdb_n_entries-for-vla.patch | 192 +++ ...ultiport-device-check-over-light-sfs.patch | 55 + ...add-missing-lock-protection-in-ocelo.patch | 62 + ...extract-ocelot_xmit_timestamp-helper.patch | 93 ++ ...split-xmit-into-fdma-and-register-in.patch | 100 ++ ...ndmsg-should-not-discard-payload_len.patch | 50 + ...on_once-when-accessing-forward-path-.patch | 39 + ...9x-fix-dwrr-cost-max-to-match-hardwa.patch | 48 + ...-lan969x-fix-ptp-clock-max_adj-value.patch | 53 + ...-catc-enable-basic-endpoint-checking.patch | 111 ++ ...ntrack_h323-don-t-pass-uninitialised.patch | 58 + ...les-fix-use-after-free-in-nf_tables_.patch | 54 + ...anize-netns_ipv4-fast-path-variables.patch | 205 ++++ ...ix-default-entries-mcam-entry-action.patch | 85 ++ ...g-annotate-data-races-in-ping_lookup.patch | 118 ++ ...apl_tpmi-remove-fw_bug-from-invalid-.patch | 49 + ...kexec_sig-available-when-config_modu.patch | 61 + ...ding-vxlan_bridge_1d-fix-test-failur.patch | 78 ++ ...ding-vxlan_bridge_1d_ipv6-fix-test-f.patch | 69 ++ ...sts-memfd-delete-unused-declarations.patch | 101 ++ ...use-ipc-semaphore-instead-of-sigstop.patch | 241 ++++ ...tc_restrictions-fix-test-failure-wit.patch | 57 + ...ctions-don-t-dump-2mb-of-0-to-stdout.patch | 57 + queue-6.6/series | 69 ++ ...-potential-null-pointer-dereference-.patch | 49 + .../spi-wpcm-fiu-fix-uninitialized-res.patch | 40 + ...wpcm-fiu-simplify-with-dev_err_probe.patch | 57 + ...-devm_platform_ioremap_resource_byna.patch | 49 + ...r-ack-while-processing-socket-backlo.patch | 206 ++++ ...cp-set-pingpong-threshold-via-sysctl.patch | 166 +++ ...hyperv-fix-error-pointer-dereference.patch | 54 + ...ct-zero-queue-configuration-from-gue.patch | 57 + 495 files changed, 41453 insertions(+) create mode 100644 queue-5.10/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch create mode 100644 queue-5.10/apparmor-fix-null-sock-in-aa_sock_file_perm.patch create mode 100644 queue-5.10/apparmor-fix-rlimit-for-posix-cpu-timers.patch create mode 100644 queue-5.10/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch create mode 100644 queue-5.10/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch create mode 100644 queue-5.10/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch create mode 100644 queue-5.10/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch create mode 100644 queue-5.10/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch create mode 100644 queue-5.10/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch create mode 100644 queue-5.10/net-rds-rds_sendmsg-should-not-discard-payload_len.patch create mode 100644 queue-5.10/net-usb-catc-enable-basic-endpoint-checking.patch create mode 100644 queue-5.10/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch create mode 100644 queue-5.10/selftests-forwarding-tc_actions-cleanup-temporary-fi.patch create mode 100644 queue-5.10/selftests-forwarding-tc_actions-use-ncat-instead-of-.patch create mode 100644 queue-5.10/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch create mode 100644 queue-5.10/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch create mode 100644 queue-5.10/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch create mode 100644 queue-5.10/usbb-catc-use-correct-api-for-mac-addresses.patch create mode 100644 queue-5.10/xen-netback-reject-zero-queue-configuration-from-gue.patch create mode 100644 queue-5.15/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch create mode 100644 queue-5.15/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch create mode 100644 queue-5.15/apparmor-fix-null-sock-in-aa_sock_file_perm.patch create mode 100644 queue-5.15/apparmor-fix-rlimit-for-posix-cpu-timers.patch create mode 100644 queue-5.15/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch create mode 100644 queue-5.15/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch create mode 100644 queue-5.15/bpftool-fix-truncated-netlink-dumps.patch create mode 100644 queue-5.15/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch create mode 100644 queue-5.15/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch create mode 100644 queue-5.15/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch create mode 100644 queue-5.15/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch create mode 100644 queue-5.15/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch create mode 100644 queue-5.15/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch create mode 100644 queue-5.15/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch create mode 100644 queue-5.15/net-rds-rds_sendmsg-should-not-discard-payload_len.patch create mode 100644 queue-5.15/net-remove-warn_on_once-when-accessing-forward-path-.patch create mode 100644 queue-5.15/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch create mode 100644 queue-5.15/octeontx2-af-fix-default-entries-mcam-entry-action.patch create mode 100644 queue-5.15/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch create mode 100644 queue-5.15/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch create mode 100644 queue-5.15/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch create mode 100644 queue-5.15/xen-netback-reject-zero-queue-configuration-from-gue.patch create mode 100644 queue-6.1/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch create mode 100644 queue-6.1/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch create mode 100644 queue-6.1/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch create mode 100644 queue-6.1/apparmor-fix-null-sock-in-aa_sock_file_perm.patch create mode 100644 queue-6.1/apparmor-fix-rlimit-for-posix-cpu-timers.patch create mode 100644 queue-6.1/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch create mode 100644 queue-6.1/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch create mode 100644 queue-6.1/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch create mode 100644 queue-6.1/bpftool-fix-truncated-netlink-dumps.patch create mode 100644 queue-6.1/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch create mode 100644 queue-6.1/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch create mode 100644 queue-6.1/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch create mode 100644 queue-6.1/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch create mode 100644 queue-6.1/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch create mode 100644 queue-6.1/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch create mode 100644 queue-6.1/icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch create mode 100644 queue-6.1/icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch create mode 100644 queue-6.1/icmp-prevent-possible-overflow-in-icmp_global_allow.patch create mode 100644 queue-6.1/inet-ping-check-sock_net-in-ping_get_port-and-ping_l.patch create mode 100644 queue-6.1/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch create mode 100644 queue-6.1/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch create mode 100644 queue-6.1/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch create mode 100644 queue-6.1/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch create mode 100644 queue-6.1/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch create mode 100644 queue-6.1/net-rds-rds_sendmsg-should-not-discard-payload_len.patch create mode 100644 queue-6.1/net-remove-warn_on_once-when-accessing-forward-path-.patch create mode 100644 queue-6.1/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch create mode 100644 queue-6.1/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch create mode 100644 queue-6.1/net-usb-catc-enable-basic-endpoint-checking.patch create mode 100644 queue-6.1/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch create mode 100644 queue-6.1/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch create mode 100644 queue-6.1/octeontx2-af-fix-default-entries-mcam-entry-action.patch create mode 100644 queue-6.1/ping-annotate-data-races-in-ping_lookup.patch create mode 100644 queue-6.1/ping-convert-hlist_nulls-to-plain-hlist.patch create mode 100644 queue-6.1/s390-kconfig-sort-config-s390-select-list-again.patch create mode 100644 queue-6.1/s390-kexec-make-kexec_sig-available-when-config_modu.patch create mode 100644 queue-6.1/s390-kexec-refactor-for-kernel-kconfig.kexec.patch create mode 100644 queue-6.1/s390-select-arch_want_hugetlb_page_optimize_vmemmap.patch create mode 100644 queue-6.1/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch create mode 100644 queue-6.1/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch create mode 100644 queue-6.1/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch create mode 100644 queue-6.1/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch create mode 100644 queue-6.1/xen-netback-reject-zero-queue-configuration-from-gue.patch create mode 100644 queue-6.12/acpi-button-adjust-event-notification-routines.patch create mode 100644 queue-6.12/acpi-button-call-device_init_wakeup-earlier-during-p.patch create mode 100644 queue-6.12/acpi-button-convert-the-driver-to-a-platform-one.patch create mode 100644 queue-6.12/acpi-button-install-notifier-for-system-events-as-we.patch create mode 100644 queue-6.12/acpi-button-only-send-key_power-for-acpi_button_noti.patch create mode 100644 queue-6.12/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch create mode 100644 queue-6.12/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch create mode 100644 queue-6.12/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch create mode 100644 queue-6.12/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch create mode 100644 queue-6.12/apparmor-fix-aa_label-to-return-state-from-compount-.patch create mode 100644 queue-6.12/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch create mode 100644 queue-6.12/apparmor-fix-null-sock-in-aa_sock_file_perm.patch create mode 100644 queue-6.12/apparmor-fix-optimize-table-creation-from-possibly-u.patch create mode 100644 queue-6.12/apparmor-fix-rlimit-for-posix-cpu-timers.patch create mode 100644 queue-6.12/apparmor-make-label_match-return-a-consistent-value.patch create mode 100644 queue-6.12/apparmor-remove-apply_modes_to_perms-from-label_matc.patch create mode 100644 queue-6.12/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch create mode 100644 queue-6.12/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch create mode 100644 queue-6.12/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch create mode 100644 queue-6.12/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch create mode 100644 queue-6.12/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch create mode 100644 queue-6.12/bpftool-fix-truncated-netlink-dumps.patch create mode 100644 queue-6.12/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch create mode 100644 queue-6.12/btrfs-use-the-correct-type-to-initialize-block-reser.patch create mode 100644 queue-6.12/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch create mode 100644 queue-6.12/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch create mode 100644 queue-6.12/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch create mode 100644 queue-6.12/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch create mode 100644 queue-6.12/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch create mode 100644 queue-6.12/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch create mode 100644 queue-6.12/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch create mode 100644 queue-6.12/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch create mode 100644 queue-6.12/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch create mode 100644 queue-6.12/drm-xe-add-xe_tile-backpointer-to-xe_mmio.patch create mode 100644 queue-6.12/drm-xe-adjust-mmio-code-to-pass-vf-substructure-to-s.patch create mode 100644 queue-6.12/drm-xe-clarify-size-of-mmio-region.patch create mode 100644 queue-6.12/drm-xe-create-dedicated-xe_mmio-structure.patch create mode 100644 queue-6.12/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch create mode 100644 queue-6.12/drm-xe-move-forcewake-to-gt.pm-substructure.patch create mode 100644 queue-6.12/drm-xe-move-gsi-offset-adjustment-fields-into-struct.patch create mode 100644 queue-6.12/drm-xe-populate-gt-s-mmio-iomap-from-tile-during-ini.patch create mode 100644 queue-6.12/drm-xe-ptl-apply-wa_13011645652.patch create mode 100644 queue-6.12/drm-xe-switch-mmio-interface-to-take-xe_mmio-instead.patch create mode 100644 queue-6.12/drm-xe-switch-mmio_ext-to-use-struct-xe_mmio.patch create mode 100644 queue-6.12/drm-xe-xe2_hpg-add-set-of-workarounds.patch create mode 100644 queue-6.12/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch create mode 100644 queue-6.12/efi-fix-reservation-of-unaccepted-memory-table.patch create mode 100644 queue-6.12/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch create mode 100644 queue-6.12/fs-ntfs3-initialize-new-folios-before-use.patch create mode 100644 queue-6.12/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch create mode 100644 queue-6.12/icmp-prevent-possible-overflow-in-icmp_global_allow.patch create mode 100644 queue-6.12/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch create mode 100644 queue-6.12/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch create mode 100644 queue-6.12/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch create mode 100644 queue-6.12/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch create mode 100644 queue-6.12/kbuild-add-objtool-to-top-level-clean-target.patch create mode 100644 queue-6.12/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch create mode 100644 queue-6.12/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch create mode 100644 queue-6.12/net-mlx5-fix-multiport-device-check-over-light-sfs.patch create mode 100644 queue-6.12/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch create mode 100644 queue-6.12/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch create mode 100644 queue-6.12/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch create mode 100644 queue-6.12/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch create mode 100644 queue-6.12/net-rds-rds_sendmsg-should-not-discard-payload_len.patch create mode 100644 queue-6.12/net-remove-warn_on_once-when-accessing-forward-path-.patch create mode 100644 queue-6.12/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch create mode 100644 queue-6.12/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch create mode 100644 queue-6.12/net-usb-catc-enable-basic-endpoint-checking.patch create mode 100644 queue-6.12/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch create mode 100644 queue-6.12/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch create mode 100644 queue-6.12/objpool-fix-the-overestimation-of-object-pooling-met.patch create mode 100644 queue-6.12/octeontx2-af-fix-default-entries-mcam-entry-action.patch create mode 100644 queue-6.12/ping-annotate-data-races-in-ping_lookup.patch create mode 100644 queue-6.12/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch create mode 100644 queue-6.12/s390-kexec-make-kexec_sig-available-when-config_modu.patch create mode 100644 queue-6.12/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch create mode 100644 queue-6.12/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch create mode 100644 queue-6.12/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch create mode 100644 queue-6.12/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch create mode 100644 queue-6.12/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch create mode 100644 queue-6.12/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch create mode 100644 queue-6.12/x86-hyperv-fix-error-pointer-dereference.patch create mode 100644 queue-6.12/xen-netback-reject-zero-queue-configuration-from-gue.patch create mode 100644 queue-6.18/acpi-button-adjust-event-notification-routines.patch create mode 100644 queue-6.18/acpi-button-call-device_init_wakeup-earlier-during-p.patch create mode 100644 queue-6.18/acpi-button-convert-the-driver-to-a-platform-one.patch create mode 100644 queue-6.18/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch create mode 100644 queue-6.18/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch create mode 100644 queue-6.18/apparmor-account-for-in_atomic-removal-in-common_fil.patch create mode 100644 queue-6.18/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch create mode 100644 queue-6.18/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch create mode 100644 queue-6.18/apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch create mode 100644 queue-6.18/apparmor-fix-aa_label-to-return-state-from-compount-.patch create mode 100644 queue-6.18/apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch create mode 100644 queue-6.18/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch create mode 100644 queue-6.18/apparmor-fix-null-pointer-dereference-in-__unix_need.patch create mode 100644 queue-6.18/apparmor-fix-null-sock-in-aa_sock_file_perm.patch create mode 100644 queue-6.18/apparmor-fix-optimize-table-creation-from-possibly-u.patch create mode 100644 queue-6.18/apparmor-fix-rlimit-for-posix-cpu-timers.patch create mode 100644 queue-6.18/apparmor-make-label_match-return-a-consistent-value.patch create mode 100644 queue-6.18/apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch create mode 100644 queue-6.18/apparmor-remove-apply_modes_to_perms-from-label_matc.patch create mode 100644 queue-6.18/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch create mode 100644 queue-6.18/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch create mode 100644 queue-6.18/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch create mode 100644 queue-6.18/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch create mode 100644 queue-6.18/bnge-fix-reserving-resources-from-fw.patch create mode 100644 queue-6.18/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch create mode 100644 queue-6.18/bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch create mode 100644 queue-6.18/bpf-fix-a-potential-use-after-free-of-btf-object.patch create mode 100644 queue-6.18/bpftool-fix-truncated-netlink-dumps.patch create mode 100644 queue-6.18/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch create mode 100644 queue-6.18/btrfs-reduce-block-group-critical-section-in-btrfs_f.patch create mode 100644 queue-6.18/btrfs-remove-fs_info-argument-from-btrfs_try_grantin.patch create mode 100644 queue-6.18/btrfs-reset-block-group-size-class-when-it-becomes-e.patch create mode 100644 queue-6.18/btrfs-use-the-correct-type-to-initialize-block-reser.patch create mode 100644 queue-6.18/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch create mode 100644 queue-6.18/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch create mode 100644 queue-6.18/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch create mode 100644 queue-6.18/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch create mode 100644 queue-6.18/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch create mode 100644 queue-6.18/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch create mode 100644 queue-6.18/drm-amdgpu-move-reset-debug-disable-handling.patch create mode 100644 queue-6.18/drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch create mode 100644 queue-6.18/drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch create mode 100644 queue-6.18/drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch create mode 100644 queue-6.18/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch create mode 100644 queue-6.18/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch create mode 100644 queue-6.18/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch create mode 100644 queue-6.18/drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch create mode 100644 queue-6.18/drm-xe-configfs-fix-parameter-name-omitted-errors.patch create mode 100644 queue-6.18/drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch create mode 100644 queue-6.18/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch create mode 100644 queue-6.18/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch create mode 100644 queue-6.18/efi-fix-reservation-of-unaccepted-memory-table.patch create mode 100644 queue-6.18/eth-fbnic-add-validation-for-mtu-changes.patch create mode 100644 queue-6.18/eth-fbnic-advertise-supported-xdp-features.patch create mode 100644 queue-6.18/eth-fbnic-configure-rde-settings-for-pause-frame.patch create mode 100644 queue-6.18/eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch create mode 100644 queue-6.18/eth-fbnic-set-dma_hint_l4-for-all-flows.patch create mode 100644 queue-6.18/eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch create mode 100644 queue-6.18/fbnic-close-fw_log-race-between-users-and-teardown.patch create mode 100644 queue-6.18/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch create mode 100644 queue-6.18/fs-ntfs3-initialize-new-folios-before-use.patch create mode 100644 queue-6.18/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch create mode 100644 queue-6.18/gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch create mode 100644 queue-6.18/icmp-prevent-possible-overflow-in-icmp_global_allow.patch create mode 100644 queue-6.18/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch create mode 100644 queue-6.18/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch create mode 100644 queue-6.18/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch create mode 100644 queue-6.18/ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch create mode 100644 queue-6.18/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch create mode 100644 queue-6.18/kbuild-add-objtool-to-top-level-clean-target.patch create mode 100644 queue-6.18/libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch create mode 100644 queue-6.18/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch create mode 100644 queue-6.18/mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch create mode 100644 queue-6.18/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch create mode 100644 queue-6.18/net-mlx5-fix-misidentification-of-write-combining-cq.patch create mode 100644 queue-6.18/net-mlx5-fix-multiport-device-check-over-light-sfs.patch create mode 100644 queue-6.18/net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch create mode 100644 queue-6.18/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch create mode 100644 queue-6.18/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch create mode 100644 queue-6.18/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch create mode 100644 queue-6.18/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch create mode 100644 queue-6.18/net-psp-select-config_skb_extensions.patch create mode 100644 queue-6.18/net-rds-rds_sendmsg-should-not-discard-payload_len.patch create mode 100644 queue-6.18/net-remove-warn_on_once-when-accessing-forward-path-.patch create mode 100644 queue-6.18/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch create mode 100644 queue-6.18/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch create mode 100644 queue-6.18/net-stmmac-fix-oops-when-split-header-is-enabled.patch create mode 100644 queue-6.18/net-stmmac-remove-broken-pcs-code.patch create mode 100644 queue-6.18/net-stmmac-replace-has_xxxx-with-core_type.patch create mode 100644 queue-6.18/net-usb-catc-enable-basic-endpoint-checking.patch create mode 100644 queue-6.18/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch create mode 100644 queue-6.18/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch create mode 100644 queue-6.18/objpool-fix-the-overestimation-of-object-pooling-met.patch create mode 100644 queue-6.18/octeontx2-af-fix-default-entries-mcam-entry-action.patch create mode 100644 queue-6.18/ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch create mode 100644 queue-6.18/ovpn-fix-vpn-tx-bytes-counting.patch create mode 100644 queue-6.18/ovpn-set-sk_user_data-before-overriding-callbacks.patch create mode 100644 queue-6.18/ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch create mode 100644 queue-6.18/pci-validate-window-resource-type-in-pbus_select_win.patch create mode 100644 queue-6.18/ping-annotate-data-races-in-ping_lookup.patch create mode 100644 queue-6.18/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch create mode 100644 queue-6.18/s390-kexec-make-kexec_sig-available-when-config_modu.patch create mode 100644 queue-6.18/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch create mode 100644 queue-6.18/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch create mode 100644 queue-6.18/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch create mode 100644 queue-6.18/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch create mode 100644 queue-6.18/selftests-net-lib-fix-jq-parsing-error.patch create mode 100644 queue-6.18/selftests-netconsole-increase-port-listening-timeout.patch create mode 100644 queue-6.18/selftests-netconsole-remove-log-noise-due-to-socat-e.patch create mode 100644 queue-6.18/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch create mode 100644 queue-6.18/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch create mode 100644 queue-6.18/x86-hyperv-fix-error-pointer-dereference.patch create mode 100644 queue-6.18/xen-netback-reject-zero-queue-configuration-from-gue.patch create mode 100644 queue-6.19/acpi-button-adjust-event-notification-routines.patch create mode 100644 queue-6.19/acpi-button-call-device_init_wakeup-earlier-during-p.patch create mode 100644 queue-6.19/acpi-button-convert-the-driver-to-a-platform-one.patch create mode 100644 queue-6.19/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch create mode 100644 queue-6.19/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch create mode 100644 queue-6.19/apparmor-account-for-in_atomic-removal-in-common_fil.patch create mode 100644 queue-6.19/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch create mode 100644 queue-6.19/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch create mode 100644 queue-6.19/apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch create mode 100644 queue-6.19/apparmor-fix-aa_label-to-return-state-from-compount-.patch create mode 100644 queue-6.19/apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch create mode 100644 queue-6.19/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch create mode 100644 queue-6.19/apparmor-fix-null-pointer-dereference-in-__unix_need.patch create mode 100644 queue-6.19/apparmor-fix-null-sock-in-aa_sock_file_perm.patch create mode 100644 queue-6.19/apparmor-fix-optimize-table-creation-from-possibly-u.patch create mode 100644 queue-6.19/apparmor-fix-rlimit-for-posix-cpu-timers.patch create mode 100644 queue-6.19/apparmor-make-label_match-return-a-consistent-value.patch create mode 100644 queue-6.19/apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch create mode 100644 queue-6.19/apparmor-remove-apply_modes_to_perms-from-label_matc.patch create mode 100644 queue-6.19/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch create mode 100644 queue-6.19/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch create mode 100644 queue-6.19/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch create mode 100644 queue-6.19/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch create mode 100644 queue-6.19/bnge-fix-reserving-resources-from-fw.patch create mode 100644 queue-6.19/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch create mode 100644 queue-6.19/bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch create mode 100644 queue-6.19/bpf-fix-a-potential-use-after-free-of-btf-object.patch create mode 100644 queue-6.19/bpftool-fix-truncated-netlink-dumps.patch create mode 100644 queue-6.19/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch create mode 100644 queue-6.19/btrfs-reset-block-group-size-class-when-it-becomes-e.patch create mode 100644 queue-6.19/btrfs-use-the-correct-type-to-initialize-block-reser.patch create mode 100644 queue-6.19/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch create mode 100644 queue-6.19/dpll-zl3073x-fix-ref-frequency-setting.patch create mode 100644 queue-6.19/drm-amd-display-don-t-call-find_analog_engine-twice.patch create mode 100644 queue-6.19/drm-amd-display-enable-dac-in-dce-link-encoder.patch create mode 100644 queue-6.19/drm-amd-display-fix-dc_link-null-handling-in-hpd-ini.patch create mode 100644 queue-6.19/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch create mode 100644 queue-6.19/drm-amd-display-initialize-dac-in-dce-link-encoder-u.patch create mode 100644 queue-6.19/drm-amd-display-only-use-analog-link-encoder-with-an.patch create mode 100644 queue-6.19/drm-amd-display-only-use-analog-stream-encoder-with-.patch create mode 100644 queue-6.19/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch create mode 100644 queue-6.19/drm-amd-display-set-crtc-source-for-dac-using-regist.patch create mode 100644 queue-6.19/drm-amd-display-turn-off-dac-in-dce-link-encoder-usi.patch create mode 100644 queue-6.19/drm-amd-display-use-dce-6-link-encoder-for-dce-6-ana.patch create mode 100644 queue-6.19/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch create mode 100644 queue-6.19/drm-amdgpu-clean-up-the-amdgpu_cs_parser_bos.patch create mode 100644 queue-6.19/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch create mode 100644 queue-6.19/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch create mode 100644 queue-6.19/drm-amdgpu-fix-missing-unwind-in-amdgpu_ib_schedule-.patch create mode 100644 queue-6.19/drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch create mode 100644 queue-6.19/drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch create mode 100644 queue-6.19/drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch create mode 100644 queue-6.19/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch create mode 100644 queue-6.19/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch create mode 100644 queue-6.19/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch create mode 100644 queue-6.19/drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch create mode 100644 queue-6.19/drm-xe-configfs-fix-parameter-name-omitted-errors.patch create mode 100644 queue-6.19/drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch create mode 100644 queue-6.19/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch create mode 100644 queue-6.19/drm-xe-pf-fix-sysfs-initialization.patch create mode 100644 queue-6.19/drm-xe-vf-avoid-reading-media-version-when-media-gt-.patch create mode 100644 queue-6.19/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch create mode 100644 queue-6.19/efi-fix-reservation-of-unaccepted-memory-table.patch create mode 100644 queue-6.19/eth-fbnic-add-validation-for-mtu-changes.patch create mode 100644 queue-6.19/eth-fbnic-advertise-supported-xdp-features.patch create mode 100644 queue-6.19/eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch create mode 100644 queue-6.19/eth-fbnic-set-dma_hint_l4-for-all-flows.patch create mode 100644 queue-6.19/eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch create mode 100644 queue-6.19/fbnic-close-fw_log-race-between-users-and-teardown.patch create mode 100644 queue-6.19/fs-ntfs3-fix-deadlock-in-ni_read_folio_cmpr.patch create mode 100644 queue-6.19/fs-ntfs3-fix-ntfs_mount_options-leak-in-ntfs_fill_su.patch create mode 100644 queue-6.19/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch create mode 100644 queue-6.19/fs-ntfs3-initialize-new-folios-before-use.patch create mode 100644 queue-6.19/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch create mode 100644 queue-6.19/fs-ntfs3-rename-ni_readpage_cmpr-into-ni_read_folio_.patch create mode 100644 queue-6.19/gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch create mode 100644 queue-6.19/gpio-cdev-avoid-null-dereference-in-linehandle_creat.patch create mode 100644 queue-6.19/icmp-prevent-possible-overflow-in-icmp_global_allow.patch create mode 100644 queue-6.19/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch create mode 100644 queue-6.19/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch create mode 100644 queue-6.19/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch create mode 100644 queue-6.19/ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch create mode 100644 queue-6.19/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch create mode 100644 queue-6.19/ipvs-skip-ipv6-extension-headers-for-csum-checks.patch create mode 100644 queue-6.19/kbuild-add-objtool-to-top-level-clean-target.patch create mode 100644 queue-6.19/libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch create mode 100644 queue-6.19/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch create mode 100644 queue-6.19/mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch create mode 100644 queue-6.19/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch create mode 100644 queue-6.19/net-do-not-delay-zero-copy-skbs-in-skb_attempt_defer.patch create mode 100644 queue-6.19/net-mctp-ensure-our-nlmsg-responses-are-initialised.patch create mode 100644 queue-6.19/net-mlx5-fix-misidentification-of-write-combining-cq.patch create mode 100644 queue-6.19/net-mlx5-fix-multiport-device-check-over-light-sfs.patch create mode 100644 queue-6.19/net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch create mode 100644 queue-6.19/net-mlx5e-fix-misidentification-of-aso-cqe-during-po.patch create mode 100644 queue-6.19/net-mlx5e-macsec-add-aso-poll-loop-in-macsec_aso_set.patch create mode 100644 queue-6.19/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch create mode 100644 queue-6.19/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch create mode 100644 queue-6.19/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch create mode 100644 queue-6.19/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch create mode 100644 queue-6.19/net-psp-select-config_skb_extensions.patch create mode 100644 queue-6.19/net-rds-rds_sendmsg-should-not-discard-payload_len.patch create mode 100644 queue-6.19/net-remove-warn_on_once-when-accessing-forward-path-.patch create mode 100644 queue-6.19/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch create mode 100644 queue-6.19/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch create mode 100644 queue-6.19/net-stmmac-fix-oops-when-split-header-is-enabled.patch create mode 100644 queue-6.19/net-usb-catc-enable-basic-endpoint-checking.patch create mode 100644 queue-6.19/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch create mode 100644 queue-6.19/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch create mode 100644 queue-6.19/netfilter-nf_tables-revert-commit_mutex-usage-in-res.patch create mode 100644 queue-6.19/netfilter-nft_counter-serialize-reset-with-spinlock.patch create mode 100644 queue-6.19/netfilter-nft_quota-use-atomic64_xchg-for-reset.patch create mode 100644 queue-6.19/objpool-fix-the-overestimation-of-object-pooling-met.patch create mode 100644 queue-6.19/octeontx2-af-fix-default-entries-mcam-entry-action.patch create mode 100644 queue-6.19/ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch create mode 100644 queue-6.19/ovpn-fix-vpn-tx-bytes-counting.patch create mode 100644 queue-6.19/ovpn-set-sk_user_data-before-overriding-callbacks.patch create mode 100644 queue-6.19/ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch create mode 100644 queue-6.19/pci-dwc-ep-always-clear-ib-maps-on-bar-update.patch create mode 100644 queue-6.19/pci-validate-window-resource-type-in-pbus_select_win.patch create mode 100644 queue-6.19/ping-annotate-data-races-in-ping_lookup.patch create mode 100644 queue-6.19/powercap-intel_rapl-remove-incorrect-cpu-check-in-pm.patch create mode 100644 queue-6.19/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch create mode 100644 queue-6.19/regulator-mt6363-fix-interrmittent-timeout.patch create mode 100644 queue-6.19/s390-kexec-make-kexec_sig-available-when-config_modu.patch create mode 100644 queue-6.19/selftests-forwarding-fix-pedit-tests-failure-with-br.patch create mode 100644 queue-6.19/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch create mode 100644 queue-6.19/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch create mode 100644 queue-6.19/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch create mode 100644 queue-6.19/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch create mode 100644 queue-6.19/selftests-net-lib-fix-jq-parsing-error.patch create mode 100644 queue-6.19/selftests-netconsole-increase-port-listening-timeout.patch create mode 100644 queue-6.19/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch create mode 100644 queue-6.19/smb-client-fix-regression-with-mount-options-parsing.patch create mode 100644 queue-6.19/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch create mode 100644 queue-6.19/tools-power-turbostat-amd-msr-offset-0x611-read-fail.patch create mode 100644 queue-6.19/tools-power-turbostat-harden-against-unexpected-valu.patch create mode 100644 queue-6.19/x86-hyperv-fix-error-pointer-dereference.patch create mode 100644 queue-6.19/xen-netback-reject-zero-queue-configuration-from-gue.patch create mode 100644 queue-6.6/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch create mode 100644 queue-6.6/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch create mode 100644 queue-6.6/apparmor-fix-aa_label-to-return-state-from-compount-.patch create mode 100644 queue-6.6/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch create mode 100644 queue-6.6/apparmor-fix-null-sock-in-aa_sock_file_perm.patch create mode 100644 queue-6.6/apparmor-fix-rlimit-for-posix-cpu-timers.patch create mode 100644 queue-6.6/apparmor-make-label_match-return-a-consistent-value.patch create mode 100644 queue-6.6/apparmor-provide-separate-audit-messages-for-file-an.patch create mode 100644 queue-6.6/apparmor-refcount-the-pdb.patch create mode 100644 queue-6.6/apparmor-remove-apply_modes_to_perms-from-label_matc.patch create mode 100644 queue-6.6/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch create mode 100644 queue-6.6/apparmor-use-passed-in-gfp-flags-in-aa_alloc_null.patch create mode 100644 queue-6.6/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch create mode 100644 queue-6.6/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch create mode 100644 queue-6.6/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch create mode 100644 queue-6.6/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch create mode 100644 queue-6.6/bpftool-fix-truncated-netlink-dumps.patch create mode 100644 queue-6.6/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch create mode 100644 queue-6.6/cache-add-__cacheline_group_-begin-end-_aligned-coup.patch create mode 100644 queue-6.6/cache-enforce-cache-groups.patch create mode 100644 queue-6.6/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch create mode 100644 queue-6.6/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch create mode 100644 queue-6.6/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch create mode 100644 queue-6.6/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch create mode 100644 queue-6.6/drm-amdkfd-fix-debug-watchpoints-for-logical-devices.patch create mode 100644 queue-6.6/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch create mode 100644 queue-6.6/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch create mode 100644 queue-6.6/efi-fix-reservation-of-unaccepted-memory-table.patch create mode 100644 queue-6.6/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch create mode 100644 queue-6.6/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch create mode 100644 queue-6.6/icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch create mode 100644 queue-6.6/icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch create mode 100644 queue-6.6/icmp-prevent-possible-overflow-in-icmp_global_allow.patch create mode 100644 queue-6.6/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch create mode 100644 queue-6.6/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch create mode 100644 queue-6.6/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch create mode 100644 queue-6.6/kbuild-add-objtool-to-top-level-clean-target.patch create mode 100644 queue-6.6/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch create mode 100644 queue-6.6/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch create mode 100644 queue-6.6/net-mlx5-fix-multiport-device-check-over-light-sfs.patch create mode 100644 queue-6.6/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch create mode 100644 queue-6.6/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch create mode 100644 queue-6.6/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch create mode 100644 queue-6.6/net-rds-rds_sendmsg-should-not-discard-payload_len.patch create mode 100644 queue-6.6/net-remove-warn_on_once-when-accessing-forward-path-.patch create mode 100644 queue-6.6/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch create mode 100644 queue-6.6/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch create mode 100644 queue-6.6/net-usb-catc-enable-basic-endpoint-checking.patch create mode 100644 queue-6.6/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch create mode 100644 queue-6.6/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch create mode 100644 queue-6.6/netns-ipv4-reorganize-netns_ipv4-fast-path-variables.patch create mode 100644 queue-6.6/octeontx2-af-fix-default-entries-mcam-entry-action.patch create mode 100644 queue-6.6/ping-annotate-data-races-in-ping_lookup.patch create mode 100644 queue-6.6/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch create mode 100644 queue-6.6/s390-kexec-make-kexec_sig-available-when-config_modu.patch create mode 100644 queue-6.6/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch create mode 100644 queue-6.6/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch create mode 100644 queue-6.6/selftests-memfd-delete-unused-declarations.patch create mode 100644 queue-6.6/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch create mode 100644 queue-6.6/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch create mode 100644 queue-6.6/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch create mode 100644 queue-6.6/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch create mode 100644 queue-6.6/spi-wpcm-fiu-fix-uninitialized-res.patch create mode 100644 queue-6.6/spi-wpcm-fiu-simplify-with-dev_err_probe.patch create mode 100644 queue-6.6/spi-wpcm-fiu-use-devm_platform_ioremap_resource_byna.patch create mode 100644 queue-6.6/tcp-defer-regular-ack-while-processing-socket-backlo.patch create mode 100644 queue-6.6/tcp-set-pingpong-threshold-via-sysctl.patch create mode 100644 queue-6.6/x86-hyperv-fix-error-pointer-dereference.patch create mode 100644 queue-6.6/xen-netback-reject-zero-queue-configuration-from-gue.patch diff --git a/queue-5.10/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch b/queue-5.10/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch new file mode 100644 index 0000000000..bf6524469a --- /dev/null +++ b/queue-5.10/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch @@ -0,0 +1,85 @@ +From d1b706635c08a8bfee34e02d312459a9c8a09be2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 15:58:45 -0300 +Subject: apparmor: fix invalid deref of rawdata when export_binary is unset + +From: Georgia Garcia + +[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ] + +If the export_binary parameter is disabled on runtime, profiles that +were loaded before that will still have their rawdata stored in +apparmorfs, with a symbolic link to the rawdata on the policy +directory. When one of those profiles are replaced, the rawdata is set +to NULL, but when trying to resolve the symbolic links to rawdata for +that profile, it will try to dereference profile->rawdata->name when +profile->rawdata is now NULL causing an oops. Fix it by checking if +rawdata is set. + +[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088 +[ 168.657420] #PF: supervisor read access in kernel mode +[ 168.660619] #PF: error_code(0x0000) - not-present page +[ 168.663613] PGD 0 P4D 0 +[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI +[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary) +[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330 +[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8 +[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282 +[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158 +[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80 +[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000 +[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80 +[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0 +[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000 +[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0 +[ 168.701696] Call Trace: +[ 168.702325] +[ 168.702995] rawdata_get_link_data+0x1c/0x30 +[ 168.704145] vfs_readlink+0xd4/0x160 +[ 168.705152] do_readlinkat+0x114/0x180 +[ 168.706214] __x64_sys_readlink+0x1e/0x30 +[ 168.708653] x64_sys_call+0x1d77/0x26b0 +[ 168.709525] do_syscall_64+0x81/0x500 +[ 168.710348] ? do_statx+0x72/0xb0 +[ 168.711109] ? putname+0x3e/0x80 +[ 168.711845] ? __x64_sys_statx+0xb7/0x100 +[ 168.712711] ? x64_sys_call+0x10fc/0x26b0 +[ 168.713577] ? do_syscall_64+0xbf/0x500 +[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0 +[ 168.715404] ? irqentry_exit+0xb2/0x740 +[ 168.716359] ? exc_page_fault+0x90/0x1b0 +[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement") +Signed-off-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index 06eac22665656..e736936f4f0ba 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -1618,6 +1618,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry, + + label = aa_get_label_rcu(&proxy->label); + profile = labels_profile(label); ++ ++ /* rawdata can be null when aa_g_export_binary is unset during ++ * runtime and a profile is replaced ++ */ ++ if (!profile->rawdata) { ++ aa_put_label(label); ++ return ERR_PTR(-ENOENT); ++ } ++ + depth = profile_depth(profile); + target = gen_symlink_name(depth, profile->rawdata->name, name); + aa_put_label(label); +-- +2.51.0 + diff --git a/queue-5.10/apparmor-fix-null-sock-in-aa_sock_file_perm.patch b/queue-5.10/apparmor-fix-null-sock-in-aa_sock_file_perm.patch new file mode 100644 index 0000000000..0648a0a438 --- /dev/null +++ b/queue-5.10/apparmor-fix-null-sock-in-aa_sock_file_perm.patch @@ -0,0 +1,44 @@ +From ce999fd775d3440d57c7eabf465f2d6a8cc63087 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:07:42 -0800 +Subject: apparmor: fix NULL sock in aa_sock_file_perm + +From: John Johansen + +[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ] + +Deal with the potential that sock and sock-sk can be NULL during +socket setup or teardown. This could lead to an oops. The fix for NULL +pointer dereference in __unix_needs_revalidation shows this is at +least possible for af_unix sockets. While the fix for af_unix sockets +applies for newer mediation this is still the fall back path for older +af_unix mediation and other sockets, so ensure it is covered. + +Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/net.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index fa0e85568450b..fbbfedd253f69 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -182,8 +182,10 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, + struct socket *sock) + { + AA_BUG(!label); +- AA_BUG(!sock); +- AA_BUG(!sock->sk); ++ ++ /* sock && sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return 0; + + return aa_label_sk_perm(label, op, request, sock->sk); + } +-- +2.51.0 + diff --git a/queue-5.10/apparmor-fix-rlimit-for-posix-cpu-timers.patch b/queue-5.10/apparmor-fix-rlimit-for-posix-cpu-timers.patch new file mode 100644 index 0000000000..cddf78fc85 --- /dev/null +++ b/queue-5.10/apparmor-fix-rlimit-for-posix-cpu-timers.patch @@ -0,0 +1,40 @@ +From 254c935f4063985eebcb2bba21b1a749d3eb3ba8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:16:54 -0800 +Subject: apparmor: fix rlimit for posix cpu timers + +From: John Johansen + +[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ] + +Posix cpu timers requires an additional step beyond setting the rlimit. +Refactor the code so its clear when what code is setting the +limit and conditionally update the posix cpu timers when appropriate. + +Fixes: baa73d9e478ff ("posix-timers: Make them configurable") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/resource.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index 1ae4874251a96..f94e416399441 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -182,6 +182,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l) + new->rlimits.limits[j].rlim_max); + /* soft limit should not exceed hard limit */ + rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); ++ if (j == RLIMIT_CPU && ++ rlim->rlim_cur != RLIM_INFINITY && ++ IS_ENABLED(CONFIG_POSIX_TIMERS)) ++ (void) update_rlimit_cpu(current->group_leader, ++ rlim->rlim_cur); + } + } + } +-- +2.51.0 + diff --git a/queue-5.10/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch b/queue-5.10/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch new file mode 100644 index 0000000000..0b15427dcb --- /dev/null +++ b/queue-5.10/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch @@ -0,0 +1,108 @@ +From 315b91d073e9a3225e4a2eae70abb1242d3c8a80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 06:09:19 +0000 +Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down + +From: Hangbin Liu + +[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ] + +The ALB RX path may access rx_hashtbl concurrently with bond +teardown. During rapid bond up/down cycles, rlb_deinitialize() +frees rx_hashtbl while RX handlers are still running, leading +to a null pointer dereference detected by KASAN. + +However, the root cause is that rlb_arp_recv() can still be accessed +after setting recv_probe to NULL, which is actually a use-after-free +(UAF) issue. That is the reason for using the referenced commit in the +Fixes tag. + +[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI +[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef] +[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary) +[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022 +[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding] +[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6 + 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00 +[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206 +[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e +[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8 +[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8 +[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119 +[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810 +[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000 +[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0 +[ 214.310347] Call Trace: +[ 214.313070] +[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding] +[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding] +[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding] +[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710 +[ 214.339199] ? __pfx_arp_process+0x10/0x10 +[ 214.343775] ? sched_balance_find_src_group+0x98/0x630 +[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10 +[ 214.356513] ? arp_rcv+0x307/0x690 +[ 214.360311] ? __pfx_arp_rcv+0x10/0x10 +[ 214.364499] ? __lock_acquire+0x58c/0xbd0 +[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0 +[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10 +[ 214.380743] ? lock_acquire+0x10b/0x140 +[ 214.385026] process_backlog+0x3f1/0x13a0 +[ 214.389502] ? process_backlog+0x3aa/0x13a0 +[ 214.394174] __napi_poll.constprop.0+0x9f/0x370 +[ 214.399233] net_rx_action+0x8c1/0xe60 +[ 214.403423] ? __pfx_net_rx_action+0x10/0x10 +[ 214.408193] ? lock_acquire.part.0+0xbd/0x260 +[ 214.413058] ? sched_clock_cpu+0x6c/0x540 +[ 214.417540] ? mark_held_locks+0x40/0x70 +[ 214.421920] handle_softirqs+0x1fd/0x860 +[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10 +[ 214.431264] ? __neigh_event_send+0x2d6/0xf50 +[ 214.436131] do_softirq+0xb1/0xf0 +[ 214.439830] + +The issue is reproducible by repeatedly running +ip link set bond0 up/down while receiving ARP messages, where +rlb_arp_recv() can race with rlb_deinitialize() and dereference +a freed rx_hashtbl entry. + +Fix this by setting recv_probe to NULL and then calling +synchronize_net() to wait for any concurrent RX processing to finish. +This ensures that no RX handler can access rx_hashtbl after it is freed +in bond_alb_deinitialize(). + +Reported-by: Liang Li +Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()") +Reviewed-by: Nikolay Aleksandrov +Acked-by: Jay Vosburgh +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 1d8a6690527aa..87e23796680b3 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3804,9 +3804,13 @@ static int bond_close(struct net_device *bond_dev) + + bond_work_cancel_all(bond); + bond->send_peer_notif = 0; ++ WRITE_ONCE(bond->recv_probe, NULL); ++ ++ /* Wait for any in-flight RX handlers */ ++ synchronize_net(); ++ + if (bond_is_lb(bond)) + bond_alb_deinitialize(bond); +- bond->recv_probe = NULL; + + if (bond_uses_primary(bond)) { + rcu_read_lock(); +-- +2.51.0 + diff --git a/queue-5.10/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch b/queue-5.10/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch new file mode 100644 index 0000000000..f864eb0929 --- /dev/null +++ b/queue-5.10/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch @@ -0,0 +1,52 @@ +From c0d8ebc4d6ccaa268ca7bb8f21ae5d5da33fa634 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 17:15:53 +0000 +Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not + found + +From: Filipe Manana + +[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ] + +If btrfs_search_slot_for_read() returns 1, it means we did not find any +key greater than or equals to the key we asked for, meaning we have +reached the end of the tree and therefore the path is not valid. If +this happens we need to break out of the loop and stop, instead of +continuing and accessing an invalid path. + +Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/qgroup.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index 647feb72c8b0a..a252f6cca0027 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1090,11 +1090,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) + } + if (ret > 0) { + /* +- * Shouldn't happen, but in case it does we +- * don't need to do the btrfs_next_item, just +- * continue. ++ * Shouldn't happen because the key should still ++ * be there (return 0), but in case it does it ++ * means we have reached the end of the tree - ++ * there are no more leaves with items that have ++ * a key greater than or equals to @found_key, ++ * so just stop the search loop. + */ +- continue; ++ break; + } + } + ret = btrfs_next_item(tree_root, path); +-- +2.51.0 + diff --git a/queue-5.10/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch b/queue-5.10/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch new file mode 100644 index 0000000000..e250c32acb --- /dev/null +++ b/queue-5.10/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch @@ -0,0 +1,59 @@ +From 6aa845a0aeaf0875860b7900406d32d55e21dd10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 00:20:02 +0530 +Subject: cpuidle: Skip governor when only one idle state is available + +From: Aboorva Devarajan + +[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ] + +On certain platforms (PowerNV systems without a power-mgt DT node), +cpuidle may register only a single idle state. In cases where that +single state is a polling state (state 0), the ladder governor may +incorrectly treat state 1 as the first usable state and pass an +out-of-bounds index. This can lead to a NULL enter callback being +invoked, ultimately resulting in a system crash. + +[ 13.342636] cpuidle-powernv : Only Snooze is available +[ 13.351854] Faulting instruction address: 0x00000000 +[ 13.376489] NIP [0000000000000000] 0x0 +[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668 + +Fix this by adding a bail-out in cpuidle_select() that returns state 0 +directly when state_count <= 1, bypassing the governor and keeping the +tick running. + +Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") +Signed-off-by: Aboorva Devarajan +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/cpuidle.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 1c1fa6ac9244a..87a57cee40fcb 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -319,6 +319,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, + int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + bool *stop_tick) + { ++ /* ++ * If there is only a single idle state (or none), there is nothing ++ * meaningful for the governor to choose. Skip the governor and ++ * always use state 0 with the tick running. ++ */ ++ if (drv->state_count <= 1) { ++ *stop_tick = false; ++ return 0; ++ } ++ + return cpuidle_curr_governor->select(drv, dev, stop_tick); + } + +-- +2.51.0 + diff --git a/queue-5.10/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch b/queue-5.10/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch new file mode 100644 index 0000000000..1cb22cd896 --- /dev/null +++ b/queue-5.10/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch @@ -0,0 +1,40 @@ +From 9a76957ed55decb0f0a5807a3980137e4838adc8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jan 2026 08:55:49 +0530 +Subject: drm/i915/acpi: free _DSM package when no connectors + +From: Kaushlendra Kumar + +[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ] + +acpi_evaluate_dsm_typed() returns an ACPI package in pkg. +When pkg->package.count == 0, we returned without freeing pkg, +leaking memory. Free pkg before returning on the empty case. + +Signed-off-by: Kaushlendra Kumar +Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects") +Reviewed-by: Jani Nikula +Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c +index 833d0c1be4f1d..1c01d8370fe94 100644 +--- a/drivers/gpu/drm/i915/display/intel_acpi.c ++++ b/drivers/gpu/drm/i915/display/intel_acpi.c +@@ -86,6 +86,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle) + + if (!pkg->package.count) { + DRM_DEBUG_DRIVER("no connection in _DSM\n"); ++ ACPI_FREE(pkg); + return; + } + +-- +2.51.0 + diff --git a/queue-5.10/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch b/queue-5.10/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch new file mode 100644 index 0000000000..9ea690c38a --- /dev/null +++ b/queue-5.10/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch @@ -0,0 +1,53 @@ +From bc57d951f90a9f9eb6c464f76a84a84f6455ee9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:22:02 +0000 +Subject: ipv6: fix a race in ip6_sock_set_v6only() + +From: Eric Dumazet + +[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ] + +It is unlikely that this function will be ever called +with isk->inet_num being not zero. + +Perform the check on isk->inet_num inside the locked section +for complete safety. + +Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Fernando Fernandez Mancera +Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/ipv6.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 2909233427de0..d7b0710d0d9c1 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -1177,12 +1177,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, + + static inline int ip6_sock_set_v6only(struct sock *sk) + { +- if (inet_sk(sk)->inet_num) +- return -EINVAL; ++ int ret = 0; ++ + lock_sock(sk); +- sk->sk_ipv6only = true; ++ if (inet_sk(sk)->inet_num) ++ ret = -EINVAL; ++ else ++ sk->sk_ipv6only = true; + release_sock(sk); +- return 0; ++ return ret; + } + + static inline void ip6_sock_set_recverr(struct sock *sk) +-- +2.51.0 + diff --git a/queue-5.10/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch b/queue-5.10/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch new file mode 100644 index 0000000000..1046e1d1c2 --- /dev/null +++ b/queue-5.10/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch @@ -0,0 +1,116 @@ +From f82790251ee323c944bfdff6768be06ec1949249 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:25:57 +0000 +Subject: macvlan: observe an RCU grace period in macvlan_common_newlink() + error path + +From: Eric Dumazet + +[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ] + +valis reported that a race condition still happens after my prior patch. + +macvlan_common_newlink() might have made @dev visible before +detecting an error, and its caller will directly call free_netdev(dev). + +We must respect an RCU period, either in macvlan or the core networking +stack. + +After adding a temporary mdelay(1000) in macvlan_forward_source_one() +to open the race window, valis repro was: + +ip link add p1 type veth peer p2 +ip link set address 00:00:00:00:00:20 dev p1 +ip link set up dev p1 +ip link set up dev p2 +ip link add mv0 link p2 type macvlan mode source + +(ip link add invalid% link p2 type macvlan mode source macaddr add +00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4 +PING 1.2.3.4 (1.2.3.4): 56 data bytes +RTNETLINK answers: Invalid argument + +BUG: KASAN: slab-use-after-free in macvlan_forward_source +(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +Read of size 8 at addr ffff888016bb89c0 by task e/175 + +CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +Call Trace: + +dump_stack_lvl (lib/dump_stack.c:123) +print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +kasan_report (mm/kasan/report.c:597) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +? tasklet_init (kernel/softirq.c:983) +macvlan_handle_frame (drivers/net/macvlan.c:501) + +Allocated by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +__kasan_kmalloc (mm/kasan/common.c:419) +__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657 +mm/slub.c:7140) +alloc_netdev_mqs (net/core/dev.c:12012) +rtnl_create_link (net/core/rtnetlink.c:3648) +rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Freed by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +kasan_save_free_info (mm/kasan/generic.c:587) +__kasan_slab_free (mm/kasan/common.c:287) +kfree (mm/slub.c:6674 mm/slub.c:6882) +rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()") +Signed-off-by: Eric Dumazet +Reported-by: valis +Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index cae48b1b7020f..95ae47a7a69dd 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1524,6 +1524,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, + if (create) + macvlan_port_destroy(port->dev); + } ++ /* @dev might have been made visible before an error was detected. ++ * Make sure to observe an RCU grace period before our caller ++ * (rtnl_newlink()) frees it. ++ */ ++ synchronize_net(); + return err; + } + EXPORT_SYMBOL_GPL(macvlan_common_newlink); +-- +2.51.0 + diff --git a/queue-5.10/net-rds-rds_sendmsg-should-not-discard-payload_len.patch b/queue-5.10/net-rds-rds_sendmsg-should-not-discard-payload_len.patch new file mode 100644 index 0000000000..c02cbc1e8f --- /dev/null +++ b/queue-5.10/net-rds-rds_sendmsg-should-not-discard-payload_len.patch @@ -0,0 +1,50 @@ +From 75d56c8462a848ed3c39e319534f8fae4e60f4f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:54:09 -0700 +Subject: net/rds: rds_sendmsg should not discard payload_len + +From: Allison Henderson + +[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ] + +Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with +connection teardown") modifies rds_sendmsg to avoid enqueueing work +while a tear down is in progress. However, it also changed the return +value of rds_sendmsg to that of rds_send_xmit instead of the +payload_len. This means the user may incorrectly receive errno values +when it should have simply received a payload of 0 while the peer +attempts a reconnections. So this patch corrects the teardown handling +code to only use the out error path in that case, thus restoring the +original payload_len return value. + +Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown") +Reviewed-by: Simon Horman +Signed-off-by: Allison Henderson +Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/rds/send.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/rds/send.c b/net/rds/send.c +index 1923eaa91e939..131c59cd5abb0 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1383,9 +1383,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) + else + queue_delayed_work(rds_wq, &cpath->cp_send_w, 1); + rcu_read_unlock(); ++ ++ if (ret) ++ goto out; + } +- if (ret) +- goto out; ++ + rds_message_put(rm); + + for (ind = 0; ind < vct.indx; ind++) +-- +2.51.0 + diff --git a/queue-5.10/net-usb-catc-enable-basic-endpoint-checking.patch b/queue-5.10/net-usb-catc-enable-basic-endpoint-checking.patch new file mode 100644 index 0000000000..8fac4dca55 --- /dev/null +++ b/queue-5.10/net-usb-catc-enable-basic-endpoint-checking.patch @@ -0,0 +1,111 @@ +From 45b6cb1a2915c2c3bb322d998e66e2bcbd74ac33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 21:41:54 +0000 +Subject: net: usb: catc: enable basic endpoint checking + +From: Ziyi Guo + +[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ] + +catc_probe() fills three URBs with hardcoded endpoint pipes without +verifying the endpoint descriptors: + + - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX + - usb_rcvintpipe(usbdev, 2) for interrupt status + +A malformed USB device can present these endpoints with transfer types +that differ from what the driver assumes. + +Add a catc_usb_ep enum for endpoint numbers, replacing magic constants +throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints() +calls after usb_set_interface() to verify endpoint types before use, +rejecting devices with mismatched descriptors at probe time. + +Similar to +- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking") +which fixed the issue in rtl8150. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Suggested-by: Simon Horman +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c +index 6502f78aeddaa..38951608dc572 100644 +--- a/drivers/net/usb/catc.c ++++ b/drivers/net/usb/catc.c +@@ -64,6 +64,16 @@ static const char driver_name[] = "catc"; + #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ + #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ + ++/* ++ * USB endpoints. ++ */ ++ ++enum catc_usb_ep { ++ CATC_USB_EP_CONTROL = 0, ++ CATC_USB_EP_BULK = 1, ++ CATC_USB_EP_INT_IN = 2, ++}; ++ + /* + * Control requests. + */ +@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + u8 broadcast[ETH_ALEN]; + u8 *macbuf; + int pktsz, ret = -ENOMEM; ++ static const u8 bulk_ep_addr[] = { ++ CATC_USB_EP_BULK | USB_DIR_OUT, ++ CATC_USB_EP_BULK | USB_DIR_IN, ++ 0}; ++ static const u8 int_ep_addr[] = { ++ CATC_USB_EP_INT_IN | USB_DIR_IN, ++ 0}; + + macbuf = kmalloc(ETH_ALEN, GFP_KERNEL); + if (!macbuf) +@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + goto fail_mem;; + } + ++ /* Verify that all required endpoints are present */ ++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || ++ !usb_check_int_endpoints(intf, int_ep_addr)) { ++ dev_err(dev, "Missing or invalid endpoints\n"); ++ ret = -ENODEV; ++ goto fail_mem; ++ } ++ + netdev = alloc_etherdev(sizeof(struct catc)); + if (!netdev) + goto fail_mem; +@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), + NULL, NULL, 0, catc_ctrl_done, catc); + +- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), +- NULL, 0, catc_tx_done, catc); ++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK), ++ NULL, 0, catc_tx_done, catc); + +- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), +- catc->rx_buf, pktsz, catc_rx_done, catc); ++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK), ++ catc->rx_buf, pktsz, catc_rx_done, catc); + +- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), +- catc->irq_buf, 2, catc_irq_done, catc, 1); ++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN), ++ catc->irq_buf, 2, catc_irq_done, catc, 1); + + if (!catc->is_f5u011) { + u32 *buf; +-- +2.51.0 + diff --git a/queue-5.10/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch b/queue-5.10/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch new file mode 100644 index 0000000000..1d0f862843 --- /dev/null +++ b/queue-5.10/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch @@ -0,0 +1,58 @@ +From 4cb8b4e0ed6745bf8cb1e15a94bcefe64cf41bcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 12:53:09 +0100 +Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value + +From: Florian Westphal + +[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ] + +Mihail Milev reports: Error: UNINIT (CWE-457): + net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl: + Declaring variable "tuple" without initializer. + net/netfilter/nf_conntrack_h323_main.c:1197:2: + uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find". + net/netfilter/nf_conntrack_expect.c:142:2: + read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash". + + 1195| tuple.dst.protonum = IPPROTO_TCP; + 1196| + 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + 1198| if (exp && exp->master == ct) + 1199| return exp; + +Switch this to a C99 initialiser and set the l3num value. + +Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port") +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_h323_main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c +index 8ba037b76ad3a..106dea9b53a96 100644 +--- a/net/netfilter/nf_conntrack_h323_main.c ++++ b/net/netfilter/nf_conntrack_h323_main.c +@@ -1228,13 +1228,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, + { + struct net *net = nf_ct_net(ct); + struct nf_conntrack_expect *exp; +- struct nf_conntrack_tuple tuple; ++ struct nf_conntrack_tuple tuple = { ++ .src.l3num = nf_ct_l3num(ct), ++ .dst.protonum = IPPROTO_TCP, ++ .dst.u.tcp.port = port, ++ }; + +- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); +- tuple.src.u.tcp.port = 0; + memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); +- tuple.dst.u.tcp.port = port; +- tuple.dst.protonum = IPPROTO_TCP; + + exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + if (exp && exp->master == ct) +-- +2.51.0 + diff --git a/queue-5.10/selftests-forwarding-tc_actions-cleanup-temporary-fi.patch b/queue-5.10/selftests-forwarding-tc_actions-cleanup-temporary-fi.patch new file mode 100644 index 0000000000..1ec9a965e5 --- /dev/null +++ b/queue-5.10/selftests-forwarding-tc_actions-cleanup-temporary-fi.patch @@ -0,0 +1,86 @@ +From c4db528aa9b7cd95633cbab0d45fc5b5a6148e96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Feb 2023 10:52:37 +0100 +Subject: selftests: forwarding: tc_actions: cleanup temporary files when test + is aborted + +From: Davide Caratti + +[ Upstream commit f58531716ced8975a4ade108ef4af35f98722af7 ] + +remove temporary files created by 'mirred_egress_to_ingress_tcp' test +in the cleanup() handler. Also, change variable names to avoid clashing +with globals from lib.sh. + +Suggested-by: Paolo Abeni +Signed-off-by: Davide Caratti +Link: https://lore.kernel.org/r/091649045a017fc00095ecbb75884e5681f7025f.1676368027.git.dcaratti@redhat.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 32b70e62034a ("selftests: tc_actions: don't dump 2MB of \0 to stdout") +Signed-off-by: Sasha Levin +--- + .../selftests/net/forwarding/tc_actions.sh | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index 1e27031288c81..9c2aca8a4b8de 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -155,10 +155,10 @@ gact_trap_test() + + mirred_egress_to_ingress_tcp_test() + { +- local tmpfile=$(mktemp) tmpfile1=$(mktemp) ++ mirred_e2i_tf1=$(mktemp) mirred_e2i_tf2=$(mktemp) + + RET=0 +- dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile ++ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred_e2i_tf1 + tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \ + $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \ + action ct commit nat src addr 192.0.2.2 pipe \ +@@ -174,11 +174,11 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1 & ++ ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & + local rpid=$! +- ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile ++ ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid +- cmp -s $tmpfile $tmpfile1 ++ cmp -s $mirred_e2i_tf1 $mirred_e2i_tf2 + check_err $? "server output check failed" + + $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \ +@@ -195,7 +195,7 @@ mirred_egress_to_ingress_tcp_test() + tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower + tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower + +- rm -f $tmpfile $tmpfile1 ++ rm -f $mirred_e2i_tf1 $mirred_e2i_tf2 + log_test "mirred_egress_to_ingress_tcp ($tcflags)" + } + +@@ -224,6 +224,8 @@ setup_prepare() + + cleanup() + { ++ local tf ++ + pre_cleanup + + switch_destroy +@@ -234,6 +236,8 @@ cleanup() + + ip link set $swp2 address $swp2origmac + ip link set $swp1 address $swp1origmac ++ ++ for tf in $mirred_e2i_tf1 $mirred_e2i_tf2; do rm -f $tf; done + } + + mirred_egress_redirect_test() +-- +2.51.0 + diff --git a/queue-5.10/selftests-forwarding-tc_actions-use-ncat-instead-of-.patch b/queue-5.10/selftests-forwarding-tc_actions-use-ncat-instead-of-.patch new file mode 100644 index 0000000000..e138bd6162 --- /dev/null +++ b/queue-5.10/selftests-forwarding-tc_actions-use-ncat-instead-of-.patch @@ -0,0 +1,85 @@ +From 755dfbf185cd561969fde6a82b938bf0299a8ad2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Aug 2023 17:14:57 +0300 +Subject: selftests: forwarding: tc_actions: Use ncat instead of nc + +From: Ido Schimmel + +[ Upstream commit 5e8670610b93158ffacc3241f835454ff26a3469 ] + +The test relies on 'nc' being the netcat version from the nmap project. +While this seems to be the case on Fedora, it is not the case on Ubuntu, +resulting in failures such as [1]. + +Fix by explicitly using the 'ncat' utility from the nmap project and the +skip the test in case it is not installed. + +[1] + # timeout set to 0 + # selftests: net/forwarding: tc_actions.sh + # TEST: gact drop and ok (skip_hw) [ OK ] + # TEST: mirred egress flower redirect (skip_hw) [ OK ] + # TEST: mirred egress flower mirror (skip_hw) [ OK ] + # TEST: mirred egress matchall mirror (skip_hw) [ OK ] + # TEST: mirred_egress_to_ingress (skip_hw) [ OK ] + # nc: invalid option -- '-' + # usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl] + # [-m minttl] [-O length] [-P proxy_username] [-p source_port] + # [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit] + # [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]] + # [destination] [port] + # nc: invalid option -- '-' + # usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl] + # [-m minttl] [-O length] [-P proxy_username] [-p source_port] + # [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit] + # [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]] + # [destination] [port] + # TEST: mirred_egress_to_ingress_tcp (skip_hw) [FAIL] + # server output check failed + # INFO: Could not test offloaded functionality + not ok 80 selftests: net/forwarding: tc_actions.sh # exit=1 + +Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") +Reported-by: Mirsad Todorovac +Closes: https://lore.kernel.org/netdev/adc5e40d-d040-a65e-eb26-edf47dac5b02@alu.unizg.hr/ +Signed-off-by: Ido Schimmel +Reviewed-by: Petr Machata +Tested-by: Mirsad Todorovac +Reviewed-by: Hangbin Liu +Acked-by: Nikolay Aleksandrov +Link: https://lore.kernel.org/r/20230808141503.4060661-12-idosch@nvidia.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 32b70e62034a ("selftests: tc_actions: don't dump 2MB of \0 to stdout") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_actions.sh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index 9c2aca8a4b8de..dd02ed4cacacb 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -8,6 +8,8 @@ NUM_NETIFS=4 + source tc_common.sh + source lib.sh + ++require_command ncat ++ + tcflags="skip_hw" + + h1_create() +@@ -174,9 +176,9 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & ++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & + local rpid=$! +- ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 ++ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid + cmp -s $mirred_e2i_tf1 $mirred_e2i_tf2 + check_err $? "server output check failed" +-- +2.51.0 + diff --git a/queue-5.10/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch b/queue-5.10/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch new file mode 100644 index 0000000000..58f69c7146 --- /dev/null +++ b/queue-5.10/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch @@ -0,0 +1,78 @@ +From 76eeb913022a8624ffff5c12cc0064712ab3e524 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:05 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with + br_netfilter enabled + +From: Aleksei Oladko + +[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv4 packet contains a zero IP header checksum. After VXLAN +decapsulation, such packets do not pass sanity checks in br_netfilter +and are dropped, which causes the test to fail. + +Fix this by calculating and setting a valid IPv4 header checksum for the +encapsulated packet generated by mausezahn, so that the packet is accepted +by br_netfilter. Fixed by using the payload_template_calc_checksum() / +payload_template_expand_checksum() helpers that are only available +in v6.3 and newer kernels. + +Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index 0ccb1dda099ae..446e31477491c 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -559,6 +559,21 @@ vxlan_encapped_ping_do() + local inner_tos=$1; shift + local outer_tos=$1; shift + ++ local ipv4hdr=$(: ++ )"45:"$( : IP version + IHL ++ )"$inner_tos:"$( : IP TOS ++ )"00:54:"$( : IP total length ++ )"99:83:"$( : IP identification ++ )"40:00:"$( : IP flags + frag off ++ )"40:"$( : IP TTL ++ )"01:"$( : IP proto ++ )"CHECKSUM:"$( : IP header csum ++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 ++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1 ++ ) ++ local checksum=$(payload_template_calc_checksum "$ipv4hdr") ++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum) ++ + $MZ $dev -c $count -d 100msec -q \ + -b $next_hop_mac -B $dest_ip \ + -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(: +@@ -569,16 +584,7 @@ vxlan_encapped_ping_do() + )"$dest_mac:"$( : ETH daddr + )"$(mac_get w2):"$( : ETH saddr + )"08:00:"$( : ETH type +- )"45:"$( : IP version + IHL +- )"$inner_tos:"$( : IP TOS +- )"00:54:"$( : IP total length +- )"99:83:"$( : IP identification +- )"40:00:"$( : IP flags + frag off +- )"40:"$( : IP TTL +- )"01:"$( : IP proto +- )"00:00:"$( : IP header csum +- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 +- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 ++ )"$ipv4hdr:"$( : IPv4 header + )"08:"$( : ICMP type + )"00:"$( : ICMP code + )"8b:f2:"$( : ICMP csum +-- +2.51.0 + diff --git a/queue-5.10/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch b/queue-5.10/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch new file mode 100644 index 0000000000..b1d7ea07e3 --- /dev/null +++ b/queue-5.10/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch @@ -0,0 +1,57 @@ +From a672e0850f7feb5bd7294371491ab45331459178 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 14:53:53 +0100 +Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2 + +From: Ido Schimmel + +[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ] + +As explained in [1], iproute2 started rejecting tc-police burst sizes +that result in an overflow. This can happen when the burst size is high +enough and the rate is low enough. + +A couple of test cases specify such configurations, resulting in +iproute2 errors and test failure. + +Fix by reducing the burst size so that the test will pass with both new +and old iproute2 versions. + +[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/ + +Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions") +Signed-off-by: Ido Schimmel +Signed-off-by: Petr Machata +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +index 553cb9fad5084..9547c0992d423 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +@@ -297,7 +297,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 0.5kbit burst 1m conform-exceed drop/ok ++ action police rate 0.5kbit burst 2k conform-exceed drop/ok + check_fail $? "Incorrect success to add police action with too low rate" + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ +@@ -307,7 +307,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 1.5kbit burst 1m conform-exceed drop/ok ++ action police rate 1.5kbit burst 2k conform-exceed drop/ok + check_err $? "Failed to add police action with low rate" + + tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower +-- +2.51.0 + diff --git a/queue-5.10/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch b/queue-5.10/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch new file mode 100644 index 0000000000..750ba1ec17 --- /dev/null +++ b/queue-5.10/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch @@ -0,0 +1,57 @@ +From b75d703070e22b63b6d5cb86117b799e261bd121 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:51:59 -0800 +Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout + +From: Jakub Kicinski + +[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ] + +Since we started running selftests in NIPA we have been seeing +tc_actions.sh generate a soft lockup warning on ~20% of the runs. +On the pre-netdev foundation setup it was actually a missed irq +splat from the console. Now it's either that or a lockup. + +I initially suspected a socket locking issue since the test +is exercising local loopback with act_mirred. +After hours of staring at this I noticed in strace that ncat +when -o $file is specified _both_ saves the output to the file +and still prints it to stdout. Because the file being sent +is constructed with: + + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred + ^^^^^^^^^ + +the data printed is all \0. Most terminals don't display nul +characters (and neither does vng output capture save them). +But QEMU's serial console still has to poke them thru which +is very slow and causes the lockup (if the file is >600kB). + +Replace the '-o $file' with '> $file'. This speeds the test up +from 2m20s to 18s on debug kernels, and prevents the warnings. + +Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index dd02ed4cacacb..c25aaced2e1f0 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -176,7 +176,7 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & ++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 & + local rpid=$! + ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid +-- +2.51.0 + diff --git a/queue-5.10/series b/queue-5.10/series index 63629a00fc..f7424854d0 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -134,3 +134,22 @@ pinctrl-equilibrium-fix-device-node-reference-leak-i.patch ovl-fix-uninit-value-in-ovl_fill_real.patch iio-sca3000-fix-a-resource-leak-in-sca3000_probe.patch pinctrl-single-fix-refcount-leak-in-pcs_add_gpio_fun.patch +cpuidle-skip-governor-when-only-one-idle-state-is-av.patch +selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch +usbb-catc-use-correct-api-for-mac-addresses.patch +net-usb-catc-enable-basic-endpoint-checking.patch +xen-netback-reject-zero-queue-configuration-from-gue.patch +net-rds-rds_sendmsg-should-not-discard-payload_len.patch +selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch +netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch +ipv6-fix-a-race-in-ip6_sock_set_v6only.patch +selftests-forwarding-tc_actions-cleanup-temporary-fi.patch +selftests-forwarding-tc_actions-use-ncat-instead-of-.patch +selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch +macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch +bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch +apparmor-fix-null-sock-in-aa_sock_file_perm.patch +apparmor-fix-rlimit-for-posix-cpu-timers.patch +apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch +drm-i915-acpi-free-_dsm-package-when-no-connectors.patch +btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch diff --git a/queue-5.10/usbb-catc-use-correct-api-for-mac-addresses.patch b/queue-5.10/usbb-catc-use-correct-api-for-mac-addresses.patch new file mode 100644 index 0000000000..aa0bcc3912 --- /dev/null +++ b/queue-5.10/usbb-catc-use-correct-api-for-mac-addresses.patch @@ -0,0 +1,98 @@ +From c6e39422ee01a2b50e676bf8e257a43be0c48974 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Oct 2021 16:11:21 +0200 +Subject: usbb: catc: use correct API for MAC addresses + +From: Oliver Neukum + +[ Upstream commit 7ce9a701ac8f44798e46dede02b924504dc65a5c ] + +Commit 406f42fa0d3c ("net-next: When a bond have a massive amount +of VLANs...") introduced a rbtree for faster Ethernet address look +up. To maintain netdev->dev_addr in this tree we need to make all +the writes to it got through appropriate helpers. + +In the case of catc we need a new temporary buffer to conform +to the rules for DMA coherency. That in turn necessitates +a reworking of error handling in probe(). + +Signed-off-by: Oliver Neukum +Signed-off-by: David S. Miller +Stable-dep-of: 9e7021d2aeae ("net: usb: catc: enable basic endpoint checking") +Signed-off-by: Sasha Levin +--- + drivers/net/usb/catc.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c +index 97ba67042d126..6502f78aeddaa 100644 +--- a/drivers/net/usb/catc.c ++++ b/drivers/net/usb/catc.c +@@ -770,17 +770,23 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + struct net_device *netdev; + struct catc *catc; + u8 broadcast[ETH_ALEN]; +- int pktsz, ret; ++ u8 *macbuf; ++ int pktsz, ret = -ENOMEM; ++ ++ macbuf = kmalloc(ETH_ALEN, GFP_KERNEL); ++ if (!macbuf) ++ goto error; + + if (usb_set_interface(usbdev, + intf->altsetting->desc.bInterfaceNumber, 1)) { + dev_err(dev, "Can't set altsetting 1.\n"); +- return -EIO; ++ ret = -EIO; ++ goto fail_mem;; + } + + netdev = alloc_etherdev(sizeof(struct catc)); + if (!netdev) +- return -ENOMEM; ++ goto fail_mem; + + catc = netdev_priv(netdev); + +@@ -870,7 +876,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + + dev_dbg(dev, "Getting MAC from SEEROM.\n"); + +- catc_get_mac(catc, netdev->dev_addr); ++ catc_get_mac(catc, macbuf); ++ eth_hw_addr_set(netdev, macbuf); + + dev_dbg(dev, "Setting MAC into registers.\n"); + +@@ -899,7 +906,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + } else { + dev_dbg(dev, "Performing reset\n"); + catc_reset(catc); +- catc_get_mac(catc, netdev->dev_addr); ++ catc_get_mac(catc, macbuf); ++ eth_hw_addr_set(netdev, macbuf); + + dev_dbg(dev, "Setting RX Mode\n"); + catc->rxmode[0] = RxEnable | RxPolarity | RxMultiCast; +@@ -917,6 +925,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + if (ret) + goto fail_clear_intfdata; + ++ kfree(macbuf); + return 0; + + fail_clear_intfdata: +@@ -927,6 +936,9 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + usb_free_urb(catc->rx_urb); + usb_free_urb(catc->irq_urb); + free_netdev(netdev); ++fail_mem: ++ kfree(macbuf); ++error: + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.10/xen-netback-reject-zero-queue-configuration-from-gue.patch b/queue-5.10/xen-netback-reject-zero-queue-configuration-from-gue.patch new file mode 100644 index 0000000000..ae6622d540 --- /dev/null +++ b/queue-5.10/xen-netback-reject-zero-queue-configuration-from-gue.patch @@ -0,0 +1,57 @@ +From 377e986902357b29e2ecc9f719b2f2fde237fdb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:40:40 +0000 +Subject: xen-netback: reject zero-queue configuration from guest + +From: Ziyi Guo + +[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ] + +A malicious or buggy Xen guest can write "0" to the xenbus key +"multi-queue-num-queues". The connect() function in the backend only +validates the upper bound (requested_num_queues > xenvif_max_queues) +but not zero, allowing requested_num_queues=0 to reach +vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers +WARN_ON_ONCE(!size) in __vmalloc_node_range(). + +On systems with panic_on_warn=1, this allows a guest-to-host denial +of service. + +The Xen network interface specification requires +the queue count to be "greater than zero". + +Add a zero check to match the validation already present +in xen-blkback, which has included this +guard since its multi-queue support was added. + +Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues") +Signed-off-by: Ziyi Guo +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/xen-netback/xenbus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index 9ee9ce0493fe6..c47e327039a0a 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -735,10 +735,11 @@ static void connect(struct backend_info *be) + */ + requested_num_queues = xenbus_read_unsigned(dev->otherend, + "multi-queue-num-queues", 1); +- if (requested_num_queues > xenvif_max_queues) { ++ if (requested_num_queues > xenvif_max_queues || ++ requested_num_queues == 0) { + /* buggy or malicious guest */ + xenbus_dev_fatal(dev, -EINVAL, +- "guest requested %u queues, exceeding the maximum of %u.", ++ "guest requested %u queues, but valid range is 1 - %u.", + requested_num_queues, xenvif_max_queues); + return; + } +-- +2.51.0 + diff --git a/queue-5.15/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch b/queue-5.15/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch new file mode 100644 index 0000000000..38f4b246dd --- /dev/null +++ b/queue-5.15/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch @@ -0,0 +1,55 @@ +From ceedd9d1ed7f1cda572ab188ead9141d79863c88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 21:22:54 +0000 +Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs + +From: Sean V Kelley + +[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ] + +per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online +CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> +acpi_cppc_processor_probe(). + +However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all +possible CPUs. In acpi_get_psd_map(), encountering an offline CPU +returns -EFAULT, causing cppc_cpufreq initialization to fail. + +This breaks systems booted with "nosmt" or "nosmt=force". + +Fix by using for_each_online_cpu() in both functions. + +Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests") +Signed-off-by: Sean V Kelley +Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index 0387b293ea76a..572d4d3815fae 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -336,7 +336,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) + end: + if (cmd == CMD_WRITE) { + if (unlikely(ret)) { +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i); + + if (!desc) +@@ -477,7 +477,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data) + else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) + cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; + +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + if (i == cpu) + continue; + +-- +2.51.0 + diff --git a/queue-5.15/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch b/queue-5.15/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch new file mode 100644 index 0000000000..a411c25517 --- /dev/null +++ b/queue-5.15/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch @@ -0,0 +1,85 @@ +From f16de7c17c35be9d64ba6d7e839efb43fb90e73b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 15:58:45 -0300 +Subject: apparmor: fix invalid deref of rawdata when export_binary is unset + +From: Georgia Garcia + +[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ] + +If the export_binary parameter is disabled on runtime, profiles that +were loaded before that will still have their rawdata stored in +apparmorfs, with a symbolic link to the rawdata on the policy +directory. When one of those profiles are replaced, the rawdata is set +to NULL, but when trying to resolve the symbolic links to rawdata for +that profile, it will try to dereference profile->rawdata->name when +profile->rawdata is now NULL causing an oops. Fix it by checking if +rawdata is set. + +[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088 +[ 168.657420] #PF: supervisor read access in kernel mode +[ 168.660619] #PF: error_code(0x0000) - not-present page +[ 168.663613] PGD 0 P4D 0 +[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI +[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary) +[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330 +[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8 +[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282 +[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158 +[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80 +[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000 +[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80 +[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0 +[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000 +[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0 +[ 168.701696] Call Trace: +[ 168.702325] +[ 168.702995] rawdata_get_link_data+0x1c/0x30 +[ 168.704145] vfs_readlink+0xd4/0x160 +[ 168.705152] do_readlinkat+0x114/0x180 +[ 168.706214] __x64_sys_readlink+0x1e/0x30 +[ 168.708653] x64_sys_call+0x1d77/0x26b0 +[ 168.709525] do_syscall_64+0x81/0x500 +[ 168.710348] ? do_statx+0x72/0xb0 +[ 168.711109] ? putname+0x3e/0x80 +[ 168.711845] ? __x64_sys_statx+0xb7/0x100 +[ 168.712711] ? x64_sys_call+0x10fc/0x26b0 +[ 168.713577] ? do_syscall_64+0xbf/0x500 +[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0 +[ 168.715404] ? irqentry_exit+0xb2/0x740 +[ 168.716359] ? exc_page_fault+0x90/0x1b0 +[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement") +Signed-off-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index c70b86f17124a..bd822f13e3253 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -1618,6 +1618,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry, + + label = aa_get_label_rcu(&proxy->label); + profile = labels_profile(label); ++ ++ /* rawdata can be null when aa_g_export_binary is unset during ++ * runtime and a profile is replaced ++ */ ++ if (!profile->rawdata) { ++ aa_put_label(label); ++ return ERR_PTR(-ENOENT); ++ } ++ + depth = profile_depth(profile); + target = gen_symlink_name(depth, profile->rawdata->name, name); + aa_put_label(label); +-- +2.51.0 + diff --git a/queue-5.15/apparmor-fix-null-sock-in-aa_sock_file_perm.patch b/queue-5.15/apparmor-fix-null-sock-in-aa_sock_file_perm.patch new file mode 100644 index 0000000000..581294585b --- /dev/null +++ b/queue-5.15/apparmor-fix-null-sock-in-aa_sock_file_perm.patch @@ -0,0 +1,44 @@ +From 74ed46eb7da8880d97f41884181ec65039077dca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:07:42 -0800 +Subject: apparmor: fix NULL sock in aa_sock_file_perm + +From: John Johansen + +[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ] + +Deal with the potential that sock and sock-sk can be NULL during +socket setup or teardown. This could lead to an oops. The fix for NULL +pointer dereference in __unix_needs_revalidation shows this is at +least possible for af_unix sockets. While the fix for af_unix sockets +applies for newer mediation this is still the fall back path for older +af_unix mediation and other sockets, so ensure it is covered. + +Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/net.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index e0c1b50d6eddc..abdce5e52b026 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -182,8 +182,10 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, + struct socket *sock) + { + AA_BUG(!label); +- AA_BUG(!sock); +- AA_BUG(!sock->sk); ++ ++ /* sock && sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return 0; + + return aa_label_sk_perm(label, op, request, sock->sk); + } +-- +2.51.0 + diff --git a/queue-5.15/apparmor-fix-rlimit-for-posix-cpu-timers.patch b/queue-5.15/apparmor-fix-rlimit-for-posix-cpu-timers.patch new file mode 100644 index 0000000000..63863f86e0 --- /dev/null +++ b/queue-5.15/apparmor-fix-rlimit-for-posix-cpu-timers.patch @@ -0,0 +1,40 @@ +From dc22d9e5476a1b936f1cb77652579d8c741d2ceb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:16:54 -0800 +Subject: apparmor: fix rlimit for posix cpu timers + +From: John Johansen + +[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ] + +Posix cpu timers requires an additional step beyond setting the rlimit. +Refactor the code so its clear when what code is setting the +limit and conditionally update the posix cpu timers when appropriate. + +Fixes: baa73d9e478ff ("posix-timers: Make them configurable") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/resource.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index 1ae4874251a96..f94e416399441 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -182,6 +182,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l) + new->rlimits.limits[j].rlim_max); + /* soft limit should not exceed hard limit */ + rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); ++ if (j == RLIMIT_CPU && ++ rlim->rlim_cur != RLIM_INFINITY && ++ IS_ENABLED(CONFIG_POSIX_TIMERS)) ++ (void) update_rlimit_cpu(current->group_leader, ++ rlim->rlim_cur); + } + } + } +-- +2.51.0 + diff --git a/queue-5.15/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch b/queue-5.15/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch new file mode 100644 index 0000000000..83214410b9 --- /dev/null +++ b/queue-5.15/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch @@ -0,0 +1,52 @@ +From e9e6b8403db314958ee9356134d1830f3c9e16cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 18:57:14 +0000 +Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put() + +From: Ziyi Guo + +[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ] + +This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()"). + +The original patch attempted to acquire the card->controls_rwsem lock in +fsl_xcvr_mode_put(). However, this function is called from the upper ALSA +core function snd_ctl_elem_write(), which already holds the write lock on +controls_rwsem for the whole put operation. So there is no need to simply +hold the lock for fsl_xcvr_activate_ctl() again. + +Acquiring the read lock while holding the write lock in the same thread +results in a deadlock and a hung task, as reported by Alexander Stein. + +Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()") +Reported-by: Alexander Stein +Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/ +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index c4deb09c9a9bc..ae5960b2b6a95 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -203,13 +203,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, + + xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); + +- down_read(&card->snd_card->controls_rwsem); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_ARC)); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_EARC)); +- up_read(&card->snd_card->controls_rwsem); +- + /* Allow playback for SPDIF only */ + rtd = snd_soc_get_pcm_runtime(card, card->dai_link); + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = +-- +2.51.0 + diff --git a/queue-5.15/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch b/queue-5.15/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch new file mode 100644 index 0000000000..3478c8c431 --- /dev/null +++ b/queue-5.15/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch @@ -0,0 +1,108 @@ +From bad74ff3e98960478dddc6604fd593027b166ff7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 06:09:19 +0000 +Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down + +From: Hangbin Liu + +[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ] + +The ALB RX path may access rx_hashtbl concurrently with bond +teardown. During rapid bond up/down cycles, rlb_deinitialize() +frees rx_hashtbl while RX handlers are still running, leading +to a null pointer dereference detected by KASAN. + +However, the root cause is that rlb_arp_recv() can still be accessed +after setting recv_probe to NULL, which is actually a use-after-free +(UAF) issue. That is the reason for using the referenced commit in the +Fixes tag. + +[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI +[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef] +[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary) +[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022 +[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding] +[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6 + 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00 +[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206 +[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e +[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8 +[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8 +[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119 +[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810 +[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000 +[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0 +[ 214.310347] Call Trace: +[ 214.313070] +[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding] +[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding] +[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding] +[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710 +[ 214.339199] ? __pfx_arp_process+0x10/0x10 +[ 214.343775] ? sched_balance_find_src_group+0x98/0x630 +[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10 +[ 214.356513] ? arp_rcv+0x307/0x690 +[ 214.360311] ? __pfx_arp_rcv+0x10/0x10 +[ 214.364499] ? __lock_acquire+0x58c/0xbd0 +[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0 +[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10 +[ 214.380743] ? lock_acquire+0x10b/0x140 +[ 214.385026] process_backlog+0x3f1/0x13a0 +[ 214.389502] ? process_backlog+0x3aa/0x13a0 +[ 214.394174] __napi_poll.constprop.0+0x9f/0x370 +[ 214.399233] net_rx_action+0x8c1/0xe60 +[ 214.403423] ? __pfx_net_rx_action+0x10/0x10 +[ 214.408193] ? lock_acquire.part.0+0xbd/0x260 +[ 214.413058] ? sched_clock_cpu+0x6c/0x540 +[ 214.417540] ? mark_held_locks+0x40/0x70 +[ 214.421920] handle_softirqs+0x1fd/0x860 +[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10 +[ 214.431264] ? __neigh_event_send+0x2d6/0xf50 +[ 214.436131] do_softirq+0xb1/0xf0 +[ 214.439830] + +The issue is reproducible by repeatedly running +ip link set bond0 up/down while receiving ARP messages, where +rlb_arp_recv() can race with rlb_deinitialize() and dereference +a freed rx_hashtbl entry. + +Fix this by setting recv_probe to NULL and then calling +synchronize_net() to wait for any concurrent RX processing to finish. +This ensures that no RX handler can access rx_hashtbl after it is freed +in bond_alb_deinitialize(). + +Reported-by: Liang Li +Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()") +Reviewed-by: Nikolay Aleksandrov +Acked-by: Jay Vosburgh +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 27ed164375411..1323a619db4d2 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4024,9 +4024,13 @@ static int bond_close(struct net_device *bond_dev) + + bond_work_cancel_all(bond); + bond->send_peer_notif = 0; ++ WRITE_ONCE(bond->recv_probe, NULL); ++ ++ /* Wait for any in-flight RX handlers */ ++ synchronize_net(); ++ + if (bond_is_lb(bond)) + bond_alb_deinitialize(bond); +- bond->recv_probe = NULL; + + if (bond_uses_primary(bond)) { + rcu_read_lock(); +-- +2.51.0 + diff --git a/queue-5.15/bpftool-fix-truncated-netlink-dumps.patch b/queue-5.15/bpftool-fix-truncated-netlink-dumps.patch new file mode 100644 index 0000000000..79ca14385b --- /dev/null +++ b/queue-5.15/bpftool-fix-truncated-netlink-dumps.patch @@ -0,0 +1,73 @@ +From d3ee73b60d9a4330582c409d842e0b90afdabc45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 11:41:50 -0800 +Subject: bpftool: Fix truncated netlink dumps + +From: Jakub Kicinski + +[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ] + +Netlink requires that the recv buffer used during dumps is at least +min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will +get truncated. Make sure bpftool follows this requirement, avoid +missing information on systems with large pages. + +Acked-by: Quentin Monnet +Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool") +Signed-off-by: Jakub Kicinski +Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/net.c | 5 ++++- + tools/lib/bpf/netlink.c | 4 +++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c +index 18e5e5faa2aa2..ef7fe8dd50984 100644 +--- a/tools/bpf/bpftool/net.c ++++ b/tools/bpf/bpftool/net.c +@@ -143,7 +143,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + bool multipart = true; + struct nlmsgerr *err; + struct nlmsghdr *nh; +- char buf[4096]; ++ char buf[8192]; + int len, ret; + + while (multipart) { +@@ -188,6 +188,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + return ret; + } + } ++ ++ if (len) ++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len); + } + ret = 0; + done: +diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c +index fadde7d80a51c..00ba40b0a57e2 100644 +--- a/tools/lib/bpf/netlink.c ++++ b/tools/lib/bpf/netlink.c +@@ -127,7 +127,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + struct nlmsghdr *nh; + int len, ret; + +- ret = alloc_iov(&iov, 4096); ++ ret = alloc_iov(&iov, 8192); + if (ret) + goto done; + +@@ -196,6 +196,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + } + } + } ++ if (len) ++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len); + } + ret = 0; + done: +-- +2.51.0 + diff --git a/queue-5.15/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch b/queue-5.15/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch new file mode 100644 index 0000000000..5a00b58cb2 --- /dev/null +++ b/queue-5.15/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch @@ -0,0 +1,52 @@ +From 885307b3a1f27cc4a6909539bc491d7c9d978c32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 17:15:53 +0000 +Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not + found + +From: Filipe Manana + +[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ] + +If btrfs_search_slot_for_read() returns 1, it means we did not find any +key greater than or equals to the key we asked for, meaning we have +reached the end of the tree and therefore the path is not valid. If +this happens we need to break out of the loop and stop, instead of +continuing and accessing an invalid path. + +Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/qgroup.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index 4593ca523490f..208c6813dc681 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1089,11 +1089,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) + } + if (ret > 0) { + /* +- * Shouldn't happen, but in case it does we +- * don't need to do the btrfs_next_item, just +- * continue. ++ * Shouldn't happen because the key should still ++ * be there (return 0), but in case it does it ++ * means we have reached the end of the tree - ++ * there are no more leaves with items that have ++ * a key greater than or equals to @found_key, ++ * so just stop the search loop. + */ +- continue; ++ break; + } + } + ret = btrfs_next_item(tree_root, path); +-- +2.51.0 + diff --git a/queue-5.15/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch b/queue-5.15/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch new file mode 100644 index 0000000000..8f8c165191 --- /dev/null +++ b/queue-5.15/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch @@ -0,0 +1,59 @@ +From 29ab61ff586e9f7aec9443e5c8efa9312939ec6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 00:20:02 +0530 +Subject: cpuidle: Skip governor when only one idle state is available + +From: Aboorva Devarajan + +[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ] + +On certain platforms (PowerNV systems without a power-mgt DT node), +cpuidle may register only a single idle state. In cases where that +single state is a polling state (state 0), the ladder governor may +incorrectly treat state 1 as the first usable state and pass an +out-of-bounds index. This can lead to a NULL enter callback being +invoked, ultimately resulting in a system crash. + +[ 13.342636] cpuidle-powernv : Only Snooze is available +[ 13.351854] Faulting instruction address: 0x00000000 +[ 13.376489] NIP [0000000000000000] 0x0 +[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668 + +Fix this by adding a bail-out in cpuidle_select() that returns state 0 +directly when state_count <= 1, bypassing the governor and keeping the +tick running. + +Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") +Signed-off-by: Aboorva Devarajan +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/cpuidle.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index e371d6972f8d9..20b9f77a8fb02 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -319,6 +319,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, + int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + bool *stop_tick) + { ++ /* ++ * If there is only a single idle state (or none), there is nothing ++ * meaningful for the governor to choose. Skip the governor and ++ * always use state 0 with the tick running. ++ */ ++ if (drv->state_count <= 1) { ++ *stop_tick = false; ++ return 0; ++ } ++ + return cpuidle_curr_governor->select(drv, dev, stop_tick); + } + +-- +2.51.0 + diff --git a/queue-5.15/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch b/queue-5.15/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch new file mode 100644 index 0000000000..195eef1ce9 --- /dev/null +++ b/queue-5.15/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch @@ -0,0 +1,40 @@ +From 0bfb19d035026bf62803e035c73cd0e583454c3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jan 2026 08:55:49 +0530 +Subject: drm/i915/acpi: free _DSM package when no connectors + +From: Kaushlendra Kumar + +[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ] + +acpi_evaluate_dsm_typed() returns an ACPI package in pkg. +When pkg->package.count == 0, we returned without freeing pkg, +leaking memory. Free pkg before returning on the empty case. + +Signed-off-by: Kaushlendra Kumar +Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects") +Reviewed-by: Jani Nikula +Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c +index 68abeaf2d7d4d..63c046cdbad6c 100644 +--- a/drivers/gpu/drm/i915/display/intel_acpi.c ++++ b/drivers/gpu/drm/i915/display/intel_acpi.c +@@ -92,6 +92,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle) + + if (!pkg->package.count) { + DRM_DEBUG_DRIVER("no connection in _DSM\n"); ++ ACPI_FREE(pkg); + return; + } + +-- +2.51.0 + diff --git a/queue-5.15/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch b/queue-5.15/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch new file mode 100644 index 0000000000..982823241d --- /dev/null +++ b/queue-5.15/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch @@ -0,0 +1,51 @@ +From 7cf13b7ca1f15590f7c9cae004bde438454e64a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jan 2026 16:50:24 +0000 +Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot + +From: Jiasheng Jiang + +[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ] + +In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the +entry size ('esize') is retrieved from the log record without adequate +bounds checking. + +Specifically, the code calculates the end of the entry ('e2') using: + e2 = Add2Ptr(e1, esize); + +It then calculates the size for memmove using 'PtrOffset(e2, ...)', +which subtracts the end pointer from the buffer limit. If 'esize' is +maliciously large, 'e2' exceeds the used buffer size. This results in +a negative offset which, when cast to size_t for memmove, interprets +as a massive unsigned integer, leading to a heap buffer overflow. + +This commit adds a check to ensure that the entry size ('esize') strictly +fits within the remaining used space of the index header before performing +memory operations. + +Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fslog.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c +index 6fddedca71f32..d3d006b63b27e 100644 +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3434,6 +3434,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, + + e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off)); + esize = le16_to_cpu(e1->size); ++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize) ++ goto dirty_vol; ++ + e2 = Add2Ptr(e1, esize); + + memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used))); +-- +2.51.0 + diff --git a/queue-5.15/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch b/queue-5.15/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch new file mode 100644 index 0000000000..e5cbe3a404 --- /dev/null +++ b/queue-5.15/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch @@ -0,0 +1,58 @@ +From f4e6dfe6db8f3b51e290b18c9e07f54ba26157ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Dec 2025 11:53:25 +0800 +Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the + same + +From: Edward Adam Davis + +[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ] + +When processing valid within the range [valid : pos), if valid cannot +be retrieved correctly, for example, if the retrieved valid value is +always the same, this can trigger a potential infinite loop, similar +to the hung problem reported by syzbot [1]. + +Adding a check for the valid value within the loop body, and terminating +the loop and returning -EINVAL if the value is the same as the current +value, can prevent this. + +[1] +INFO: task syz.4.21:6056 blocked for more than 143 seconds. +Call Trace: + rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244 + inode_lock include/linux/fs.h:1027 [inline] + ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1 +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index ffb31420085f4..25788df25deeb 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -932,8 +932,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) + goto out; + + if (lcn == SPARSE_LCN) { +- ni->i_valid = valid = +- frame_vbo + ((u64)clen << sbi->cluster_bits); ++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits); ++ if (ni->i_valid == valid) { ++ err = -EINVAL; ++ goto out; ++ } ++ ni->i_valid = valid; + continue; + } + +-- +2.51.0 + diff --git a/queue-5.15/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch b/queue-5.15/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch new file mode 100644 index 0000000000..ac56ab975e --- /dev/null +++ b/queue-5.15/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch @@ -0,0 +1,53 @@ +From ceba0f3b24ea7a45584471a73c8d08a7e12be70c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:22:02 +0000 +Subject: ipv6: fix a race in ip6_sock_set_v6only() + +From: Eric Dumazet + +[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ] + +It is unlikely that this function will be ever called +with isk->inet_num being not zero. + +Perform the check on isk->inet_num inside the locked section +for complete safety. + +Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Fernando Fernandez Mancera +Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/ipv6.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 608943944ce1a..dcae37154d3c2 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -1186,12 +1186,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, + + static inline int ip6_sock_set_v6only(struct sock *sk) + { +- if (inet_sk(sk)->inet_num) +- return -EINVAL; ++ int ret = 0; ++ + lock_sock(sk); +- sk->sk_ipv6only = true; ++ if (inet_sk(sk)->inet_num) ++ ret = -EINVAL; ++ else ++ sk->sk_ipv6only = true; + release_sock(sk); +- return 0; ++ return ret; + } + + static inline void ip6_sock_set_recverr(struct sock *sk) +-- +2.51.0 + diff --git a/queue-5.15/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch b/queue-5.15/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch new file mode 100644 index 0000000000..d2cbfc0478 --- /dev/null +++ b/queue-5.15/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch @@ -0,0 +1,116 @@ +From 48f4fff82b1fca88ec72a9b94544688dc0ff7499 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:25:57 +0000 +Subject: macvlan: observe an RCU grace period in macvlan_common_newlink() + error path + +From: Eric Dumazet + +[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ] + +valis reported that a race condition still happens after my prior patch. + +macvlan_common_newlink() might have made @dev visible before +detecting an error, and its caller will directly call free_netdev(dev). + +We must respect an RCU period, either in macvlan or the core networking +stack. + +After adding a temporary mdelay(1000) in macvlan_forward_source_one() +to open the race window, valis repro was: + +ip link add p1 type veth peer p2 +ip link set address 00:00:00:00:00:20 dev p1 +ip link set up dev p1 +ip link set up dev p2 +ip link add mv0 link p2 type macvlan mode source + +(ip link add invalid% link p2 type macvlan mode source macaddr add +00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4 +PING 1.2.3.4 (1.2.3.4): 56 data bytes +RTNETLINK answers: Invalid argument + +BUG: KASAN: slab-use-after-free in macvlan_forward_source +(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +Read of size 8 at addr ffff888016bb89c0 by task e/175 + +CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +Call Trace: + +dump_stack_lvl (lib/dump_stack.c:123) +print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +kasan_report (mm/kasan/report.c:597) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +? tasklet_init (kernel/softirq.c:983) +macvlan_handle_frame (drivers/net/macvlan.c:501) + +Allocated by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +__kasan_kmalloc (mm/kasan/common.c:419) +__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657 +mm/slub.c:7140) +alloc_netdev_mqs (net/core/dev.c:12012) +rtnl_create_link (net/core/rtnetlink.c:3648) +rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Freed by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +kasan_save_free_info (mm/kasan/generic.c:587) +__kasan_slab_free (mm/kasan/common.c:287) +kfree (mm/slub.c:6674 mm/slub.c:6882) +rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()") +Signed-off-by: Eric Dumazet +Reported-by: valis +Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index e92d7f2f28c17..f2fb958c1f232 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1532,6 +1532,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, + if (create) + macvlan_port_destroy(port->dev); + } ++ /* @dev might have been made visible before an error was detected. ++ * Make sure to observe an RCU grace period before our caller ++ * (rtnl_newlink()) frees it. ++ */ ++ synchronize_net(); + return err; + } + EXPORT_SYMBOL_GPL(macvlan_common_newlink); +-- +2.51.0 + diff --git a/queue-5.15/net-rds-rds_sendmsg-should-not-discard-payload_len.patch b/queue-5.15/net-rds-rds_sendmsg-should-not-discard-payload_len.patch new file mode 100644 index 0000000000..94e78bc0f8 --- /dev/null +++ b/queue-5.15/net-rds-rds_sendmsg-should-not-discard-payload_len.patch @@ -0,0 +1,50 @@ +From 477499c4cd9cec5876ff062386e41bfa72881f10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:54:09 -0700 +Subject: net/rds: rds_sendmsg should not discard payload_len + +From: Allison Henderson + +[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ] + +Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with +connection teardown") modifies rds_sendmsg to avoid enqueueing work +while a tear down is in progress. However, it also changed the return +value of rds_sendmsg to that of rds_send_xmit instead of the +payload_len. This means the user may incorrectly receive errno values +when it should have simply received a payload of 0 while the peer +attempts a reconnections. So this patch corrects the teardown handling +code to only use the out error path in that case, thus restoring the +original payload_len return value. + +Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown") +Reviewed-by: Simon Horman +Signed-off-by: Allison Henderson +Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/rds/send.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/rds/send.c b/net/rds/send.c +index 85c27d9aa33a3..9a23f8f2bcfa7 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1383,9 +1383,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) + else + queue_delayed_work(rds_wq, &cpath->cp_send_w, 1); + rcu_read_unlock(); ++ ++ if (ret) ++ goto out; + } +- if (ret) +- goto out; ++ + rds_message_put(rm); + + for (ind = 0; ind < vct.indx; ind++) +-- +2.51.0 + diff --git a/queue-5.15/net-remove-warn_on_once-when-accessing-forward-path-.patch b/queue-5.15/net-remove-warn_on_once-when-accessing-forward-path-.patch new file mode 100644 index 0000000000..a66617ff62 --- /dev/null +++ b/queue-5.15/net-remove-warn_on_once-when-accessing-forward-path-.patch @@ -0,0 +1,39 @@ +From 0bd08e52b1ed05f785056a0269d88b24ea74e8ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 12:56:39 +0100 +Subject: net: remove WARN_ON_ONCE when accessing forward path array + +From: Pablo Neira Ayuso + +[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ] + +Although unlikely, recent support for IPIP tunnels increases chances of +reaching this WARN_ON_ONCE if userspace manages to build a sufficiently +long forward path. + +Remove it. + +Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 977146a70b8c1..48abe997e6f3b 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -750,7 +750,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) + { + int k = stack->num_paths++; + +- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) ++ if (k >= NET_DEVICE_PATH_STACK_MAX) + return NULL; + + return &stack->path[k]; +-- +2.51.0 + diff --git a/queue-5.15/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch b/queue-5.15/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch new file mode 100644 index 0000000000..834dfba749 --- /dev/null +++ b/queue-5.15/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch @@ -0,0 +1,58 @@ +From 7f7cf2f6096e331f231caf5442bbdf17c37f0baa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 12:53:09 +0100 +Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value + +From: Florian Westphal + +[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ] + +Mihail Milev reports: Error: UNINIT (CWE-457): + net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl: + Declaring variable "tuple" without initializer. + net/netfilter/nf_conntrack_h323_main.c:1197:2: + uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find". + net/netfilter/nf_conntrack_expect.c:142:2: + read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash". + + 1195| tuple.dst.protonum = IPPROTO_TCP; + 1196| + 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + 1198| if (exp && exp->master == ct) + 1199| return exp; + +Switch this to a C99 initialiser and set the l3num value. + +Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port") +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_h323_main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c +index 2eb31ffb3d141..b479dc148d7bf 100644 +--- a/net/netfilter/nf_conntrack_h323_main.c ++++ b/net/netfilter/nf_conntrack_h323_main.c +@@ -1229,13 +1229,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, + { + struct net *net = nf_ct_net(ct); + struct nf_conntrack_expect *exp; +- struct nf_conntrack_tuple tuple; ++ struct nf_conntrack_tuple tuple = { ++ .src.l3num = nf_ct_l3num(ct), ++ .dst.protonum = IPPROTO_TCP, ++ .dst.u.tcp.port = port, ++ }; + +- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); +- tuple.src.u.tcp.port = 0; + memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); +- tuple.dst.u.tcp.port = port; +- tuple.dst.protonum = IPPROTO_TCP; + + exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + if (exp && exp->master == ct) +-- +2.51.0 + diff --git a/queue-5.15/octeontx2-af-fix-default-entries-mcam-entry-action.patch b/queue-5.15/octeontx2-af-fix-default-entries-mcam-entry-action.patch new file mode 100644 index 0000000000..c78248e0a0 --- /dev/null +++ b/queue-5.15/octeontx2-af-fix-default-entries-mcam-entry-action.patch @@ -0,0 +1,85 @@ +From 54d6c02ae2f33ba5a72619db201fc3c76b41a593 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:33:38 +0530 +Subject: octeontx2-af: Fix default entries mcam entry action + +From: Hariprasad Kelam + +[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ] + +As per design, AF should update the default MCAM action only when +mcam_index is -1. A bug in the previous patch caused default entries +to be changed even when the request was not for them. + +Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index") +Signed-off-by: Hariprasad Kelam +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++--------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 84003243e3b75..ddc2879d81f35 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -1047,32 +1047,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, + rvu_write64(rvu, blkaddr, + NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action); + +- /* update the VF flow rule action with the VF default entry action */ +- if (mcam_index < 0) +- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, +- *(u64 *)&action); +- + /* update the action change in default rule */ + pfvf = rvu_get_pfvf(rvu, pcifunc); + if (pfvf->def_ucast_rule) + pfvf->def_ucast_rule->rx_action = action; + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_PROMISC_ENTRY); ++ if (mcam_index < 0) { ++ /* update the VF flow rule action with the VF default ++ * entry action ++ */ ++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, ++ *(u64 *)&action); + +- /* If PF's promiscuous entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_PROMISC_ENTRY); + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_ALLMULTI_ENTRY); +- /* If PF's allmulti entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ /* If PF's promiscuous entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_ALLMULTI_ENTRY); ++ /* If PF's allmulti entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ } + } + + void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, +-- +2.51.0 + diff --git a/queue-5.15/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch b/queue-5.15/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch new file mode 100644 index 0000000000..f30df0a007 --- /dev/null +++ b/queue-5.15/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch @@ -0,0 +1,78 @@ +From 7b75c7643c5e1456760a2ce3863ba7f879c7661b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:05 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with + br_netfilter enabled + +From: Aleksei Oladko + +[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv4 packet contains a zero IP header checksum. After VXLAN +decapsulation, such packets do not pass sanity checks in br_netfilter +and are dropped, which causes the test to fail. + +Fix this by calculating and setting a valid IPv4 header checksum for the +encapsulated packet generated by mausezahn, so that the packet is accepted +by br_netfilter. Fixed by using the payload_template_calc_checksum() / +payload_template_expand_checksum() helpers that are only available +in v6.3 and newer kernels. + +Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index eb307ca37bfa6..002551451a728 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -559,6 +559,21 @@ vxlan_encapped_ping_do() + local inner_tos=$1; shift + local outer_tos=$1; shift + ++ local ipv4hdr=$(: ++ )"45:"$( : IP version + IHL ++ )"$inner_tos:"$( : IP TOS ++ )"00:54:"$( : IP total length ++ )"99:83:"$( : IP identification ++ )"40:00:"$( : IP flags + frag off ++ )"40:"$( : IP TTL ++ )"01:"$( : IP proto ++ )"CHECKSUM:"$( : IP header csum ++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 ++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1 ++ ) ++ local checksum=$(payload_template_calc_checksum "$ipv4hdr") ++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum) ++ + $MZ $dev -c $count -d 100msec -q \ + -b $next_hop_mac -B $dest_ip \ + -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(: +@@ -569,16 +584,7 @@ vxlan_encapped_ping_do() + )"$dest_mac:"$( : ETH daddr + )"$(mac_get w2):"$( : ETH saddr + )"08:00:"$( : ETH type +- )"45:"$( : IP version + IHL +- )"$inner_tos:"$( : IP TOS +- )"00:54:"$( : IP total length +- )"99:83:"$( : IP identification +- )"40:00:"$( : IP flags + frag off +- )"40:"$( : IP TTL +- )"01:"$( : IP proto +- )"00:00:"$( : IP header csum +- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 +- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 ++ )"$ipv4hdr:"$( : IPv4 header + )"08:"$( : ICMP type + )"00:"$( : ICMP code + )"8b:f2:"$( : ICMP csum +-- +2.51.0 + diff --git a/queue-5.15/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch b/queue-5.15/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch new file mode 100644 index 0000000000..1cd3fbb2c0 --- /dev/null +++ b/queue-5.15/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch @@ -0,0 +1,57 @@ +From 83edc467c795d11eb9ef7087b3d2c9b3de32deba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 14:53:53 +0100 +Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2 + +From: Ido Schimmel + +[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ] + +As explained in [1], iproute2 started rejecting tc-police burst sizes +that result in an overflow. This can happen when the burst size is high +enough and the rate is low enough. + +A couple of test cases specify such configurations, resulting in +iproute2 errors and test failure. + +Fix by reducing the burst size so that the test will pass with both new +and old iproute2 versions. + +[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/ + +Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions") +Signed-off-by: Ido Schimmel +Signed-off-by: Petr Machata +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +index 5ec3beb637c82..2e9669408d3b0 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +@@ -316,7 +316,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 0.5kbit burst 1m conform-exceed drop/ok ++ action police rate 0.5kbit burst 2k conform-exceed drop/ok + check_fail $? "Incorrect success to add police action with too low rate" + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ +@@ -326,7 +326,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 1.5kbit burst 1m conform-exceed drop/ok ++ action police rate 1.5kbit burst 2k conform-exceed drop/ok + check_err $? "Failed to add police action with low rate" + + tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower +-- +2.51.0 + diff --git a/queue-5.15/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch b/queue-5.15/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch new file mode 100644 index 0000000000..adb42e7309 --- /dev/null +++ b/queue-5.15/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch @@ -0,0 +1,57 @@ +From d45fe9433273fdc1294b0c1988dbec24248a23ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:51:59 -0800 +Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout + +From: Jakub Kicinski + +[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ] + +Since we started running selftests in NIPA we have been seeing +tc_actions.sh generate a soft lockup warning on ~20% of the runs. +On the pre-netdev foundation setup it was actually a missed irq +splat from the console. Now it's either that or a lockup. + +I initially suspected a socket locking issue since the test +is exercising local loopback with act_mirred. +After hours of staring at this I noticed in strace that ncat +when -o $file is specified _both_ saves the output to the file +and still prints it to stdout. Because the file being sent +is constructed with: + + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred + ^^^^^^^^^ + +the data printed is all \0. Most terminals don't display nul +characters (and neither does vng output capture save them). +But QEMU's serial console still has to poke them thru which +is very slow and causes the lockup (if the file is >600kB). + +Replace the '-o $file' with '> $file'. This speeds the test up +from 2m20s to 18s on debug kernels, and prevents the warnings. + +Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index dd02ed4cacacb..c25aaced2e1f0 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -176,7 +176,7 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & ++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 & + local rpid=$! + ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid +-- +2.51.0 + diff --git a/queue-5.15/series b/queue-5.15/series index 784af445a3..27a0491925 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -150,3 +150,25 @@ pinctrl-qcom-extract-chip-specific-lpass-lpi-code.patch pinctrl-qcom-sm8250-lpass-lpi-fix-i2s2_data_groups-d.patch pinctrl-single-fix-refcount-leak-in-pcs_add_gpio_fun.patch backlight-qcom-wled-support-ovp-values-for-pmi8994.patch +fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch +fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch +acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch +cpuidle-skip-governor-when-only-one-idle-state-is-av.patch +selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch +xen-netback-reject-zero-queue-configuration-from-gue.patch +net-rds-rds_sendmsg-should-not-discard-payload_len.patch +selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch +netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch +net-remove-warn_on_once-when-accessing-forward-path-.patch +ipv6-fix-a-race-in-ip6_sock_set_v6only.patch +bpftool-fix-truncated-netlink-dumps.patch +selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch +macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch +octeontx2-af-fix-default-entries-mcam-entry-action.patch +bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch +apparmor-fix-null-sock-in-aa_sock_file_perm.patch +apparmor-fix-rlimit-for-posix-cpu-timers.patch +apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch +asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch +drm-i915-acpi-free-_dsm-package-when-no-connectors.patch +btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch diff --git a/queue-5.15/xen-netback-reject-zero-queue-configuration-from-gue.patch b/queue-5.15/xen-netback-reject-zero-queue-configuration-from-gue.patch new file mode 100644 index 0000000000..5bc72cc7da --- /dev/null +++ b/queue-5.15/xen-netback-reject-zero-queue-configuration-from-gue.patch @@ -0,0 +1,57 @@ +From ff694238d2d2a922a167f50b0249b3635b221194 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:40:40 +0000 +Subject: xen-netback: reject zero-queue configuration from guest + +From: Ziyi Guo + +[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ] + +A malicious or buggy Xen guest can write "0" to the xenbus key +"multi-queue-num-queues". The connect() function in the backend only +validates the upper bound (requested_num_queues > xenvif_max_queues) +but not zero, allowing requested_num_queues=0 to reach +vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers +WARN_ON_ONCE(!size) in __vmalloc_node_range(). + +On systems with panic_on_warn=1, this allows a guest-to-host denial +of service. + +The Xen network interface specification requires +the queue count to be "greater than zero". + +Add a zero check to match the validation already present +in xen-blkback, which has included this +guard since its multi-queue support was added. + +Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues") +Signed-off-by: Ziyi Guo +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/xen-netback/xenbus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index e85b3c5d4acce..5b78d9172aac9 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -735,10 +735,11 @@ static void connect(struct backend_info *be) + */ + requested_num_queues = xenbus_read_unsigned(dev->otherend, + "multi-queue-num-queues", 1); +- if (requested_num_queues > xenvif_max_queues) { ++ if (requested_num_queues > xenvif_max_queues || ++ requested_num_queues == 0) { + /* buggy or malicious guest */ + xenbus_dev_fatal(dev, -EINVAL, +- "guest requested %u queues, exceeding the maximum of %u.", ++ "guest requested %u queues, but valid range is 1 - %u.", + requested_num_queues, xenvif_max_queues); + return; + } +-- +2.51.0 + diff --git a/queue-6.1/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch b/queue-6.1/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch new file mode 100644 index 0000000000..2d4c4cc33c --- /dev/null +++ b/queue-6.1/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch @@ -0,0 +1,55 @@ +From 2da86bef5424def69b442fa81770395f9c269037 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 21:22:54 +0000 +Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs + +From: Sean V Kelley + +[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ] + +per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online +CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> +acpi_cppc_processor_probe(). + +However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all +possible CPUs. In acpi_get_psd_map(), encountering an offline CPU +returns -EFAULT, causing cppc_cpufreq initialization to fail. + +This breaks systems booted with "nosmt" or "nosmt=force". + +Fix by using for_each_online_cpu() in both functions. + +Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests") +Signed-off-by: Sean V Kelley +Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index c763c25424663..4382340fd9778 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -342,7 +342,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) + end: + if (cmd == CMD_WRITE) { + if (unlikely(ret)) { +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i); + + if (!desc) +@@ -504,7 +504,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data) + else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) + cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; + +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + if (i == cpu) + continue; + +-- +2.51.0 + diff --git a/queue-6.1/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch b/queue-6.1/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch new file mode 100644 index 0000000000..7f201810ba --- /dev/null +++ b/queue-6.1/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch @@ -0,0 +1,67 @@ +From dd456ede3fc0777532444bd3615aa269ddda053e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Feb 2026 00:14:52 +0800 +Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO + +From: Zhai Can + +[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ] + +On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete +NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table +bug (lack of reference), PXP will be shut dow as an "unused" power resource +during initialization, making the NVMe slot #2 + NVIDIA both inaccessible. + +This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check +states of power resources during initialization"). Here are test +results on the three consecutive commits: + +(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization +(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state +(bad) 519d81956ee2 Linux 5.15-rc6 + +On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in +unknown state") this was not an issue because the power resource state +left UNKNOWN thus being ignored. + +See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power +resources on the Toshiba Click Mini") which is another almost identical +case to this one. + +Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization") +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087 +Signed-off-by: Zhai Can +Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/power.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c +index aea8c994caeac..db7b5534931be 100644 +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -1035,6 +1035,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"), + }, + }, ++ { ++ /* ++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power ++ * resource 'PXP' will be shut down on initialization, making ++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're ++ * both controlled by 'PXP'). ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"), ++ } ++ ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.1/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch b/queue-6.1/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch new file mode 100644 index 0000000000..f324dfc627 --- /dev/null +++ b/queue-6.1/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch @@ -0,0 +1,85 @@ +From d3ca5f15edafae7abf866b4885044f245173ad50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 15:58:45 -0300 +Subject: apparmor: fix invalid deref of rawdata when export_binary is unset + +From: Georgia Garcia + +[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ] + +If the export_binary parameter is disabled on runtime, profiles that +were loaded before that will still have their rawdata stored in +apparmorfs, with a symbolic link to the rawdata on the policy +directory. When one of those profiles are replaced, the rawdata is set +to NULL, but when trying to resolve the symbolic links to rawdata for +that profile, it will try to dereference profile->rawdata->name when +profile->rawdata is now NULL causing an oops. Fix it by checking if +rawdata is set. + +[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088 +[ 168.657420] #PF: supervisor read access in kernel mode +[ 168.660619] #PF: error_code(0x0000) - not-present page +[ 168.663613] PGD 0 P4D 0 +[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI +[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary) +[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330 +[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8 +[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282 +[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158 +[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80 +[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000 +[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80 +[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0 +[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000 +[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0 +[ 168.701696] Call Trace: +[ 168.702325] +[ 168.702995] rawdata_get_link_data+0x1c/0x30 +[ 168.704145] vfs_readlink+0xd4/0x160 +[ 168.705152] do_readlinkat+0x114/0x180 +[ 168.706214] __x64_sys_readlink+0x1e/0x30 +[ 168.708653] x64_sys_call+0x1d77/0x26b0 +[ 168.709525] do_syscall_64+0x81/0x500 +[ 168.710348] ? do_statx+0x72/0xb0 +[ 168.711109] ? putname+0x3e/0x80 +[ 168.711845] ? __x64_sys_statx+0xb7/0x100 +[ 168.712711] ? x64_sys_call+0x10fc/0x26b0 +[ 168.713577] ? do_syscall_64+0xbf/0x500 +[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0 +[ 168.715404] ? irqentry_exit+0xb2/0x740 +[ 168.716359] ? exc_page_fault+0x90/0x1b0 +[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement") +Signed-off-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index ce7b2f43c3193..fa518cd82366a 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -1626,6 +1626,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry, + + label = aa_get_label_rcu(&proxy->label); + profile = labels_profile(label); ++ ++ /* rawdata can be null when aa_g_export_binary is unset during ++ * runtime and a profile is replaced ++ */ ++ if (!profile->rawdata) { ++ aa_put_label(label); ++ return ERR_PTR(-ENOENT); ++ } ++ + depth = profile_depth(profile); + target = gen_symlink_name(depth, profile->rawdata->name, name); + aa_put_label(label); +-- +2.51.0 + diff --git a/queue-6.1/apparmor-fix-null-sock-in-aa_sock_file_perm.patch b/queue-6.1/apparmor-fix-null-sock-in-aa_sock_file_perm.patch new file mode 100644 index 0000000000..b62e5655f2 --- /dev/null +++ b/queue-6.1/apparmor-fix-null-sock-in-aa_sock_file_perm.patch @@ -0,0 +1,44 @@ +From 48721e58f139ba11faedf899596f67132c6f2ad0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:07:42 -0800 +Subject: apparmor: fix NULL sock in aa_sock_file_perm + +From: John Johansen + +[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ] + +Deal with the potential that sock and sock-sk can be NULL during +socket setup or teardown. This could lead to an oops. The fix for NULL +pointer dereference in __unix_needs_revalidation shows this is at +least possible for af_unix sockets. While the fix for af_unix sockets +applies for newer mediation this is still the fall back path for older +af_unix mediation and other sockets, so ensure it is covered. + +Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/net.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 7efe4d17273d9..0c980e62dbe7a 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -183,8 +183,10 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, + struct socket *sock) + { + AA_BUG(!label); +- AA_BUG(!sock); +- AA_BUG(!sock->sk); ++ ++ /* sock && sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return 0; + + return aa_label_sk_perm(label, op, request, sock->sk); + } +-- +2.51.0 + diff --git a/queue-6.1/apparmor-fix-rlimit-for-posix-cpu-timers.patch b/queue-6.1/apparmor-fix-rlimit-for-posix-cpu-timers.patch new file mode 100644 index 0000000000..1b862e1c05 --- /dev/null +++ b/queue-6.1/apparmor-fix-rlimit-for-posix-cpu-timers.patch @@ -0,0 +1,40 @@ +From 9b6a63a67221d26db8d31a295265f33fe07411ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:16:54 -0800 +Subject: apparmor: fix rlimit for posix cpu timers + +From: John Johansen + +[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ] + +Posix cpu timers requires an additional step beyond setting the rlimit. +Refactor the code so its clear when what code is setting the +limit and conditionally update the posix cpu timers when appropriate. + +Fixes: baa73d9e478ff ("posix-timers: Make them configurable") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/resource.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index 1ae4874251a96..f94e416399441 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -182,6 +182,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l) + new->rlimits.limits[j].rlim_max); + /* soft limit should not exceed hard limit */ + rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); ++ if (j == RLIMIT_CPU && ++ rlim->rlim_cur != RLIM_INFINITY && ++ IS_ENABLED(CONFIG_POSIX_TIMERS)) ++ (void) update_rlimit_cpu(current->group_leader, ++ rlim->rlim_cur); + } + } + } +-- +2.51.0 + diff --git a/queue-6.1/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch b/queue-6.1/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch new file mode 100644 index 0000000000..7d7e995626 --- /dev/null +++ b/queue-6.1/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch @@ -0,0 +1,52 @@ +From ad39853373cb2b2693c62fe7b88e38f562f7a35a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 18:57:14 +0000 +Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put() + +From: Ziyi Guo + +[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ] + +This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()"). + +The original patch attempted to acquire the card->controls_rwsem lock in +fsl_xcvr_mode_put(). However, this function is called from the upper ALSA +core function snd_ctl_elem_write(), which already holds the write lock on +controls_rwsem for the whole put operation. So there is no need to simply +hold the lock for fsl_xcvr_activate_ctl() again. + +Acquiring the read lock while holding the write lock in the same thread +results in a deadlock and a hung task, as reported by Alexander Stein. + +Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()") +Reported-by: Alexander Stein +Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/ +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index e6c0e6609cbe0..5b61b93772d64 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -203,13 +203,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, + + xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); + +- down_read(&card->snd_card->controls_rwsem); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_ARC)); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_EARC)); +- up_read(&card->snd_card->controls_rwsem); +- + /* Allow playback for SPDIF only */ + rtd = snd_soc_get_pcm_runtime(card, card->dai_link); + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = +-- +2.51.0 + diff --git a/queue-6.1/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch b/queue-6.1/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch new file mode 100644 index 0000000000..324830fd84 --- /dev/null +++ b/queue-6.1/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch @@ -0,0 +1,55 @@ +From a565a9bc5ac852f84a22c34d658934a15fefd996 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 15:18:34 -0500 +Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk + +From: Detlev Casanova + +[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ] + +Drivers will not always call set_sysclk() for all clocks, especially when +default mclk-fs can be used. +When that is the case, use the clock rate set in the params multiplied by the +default mclk-fs. + +Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback") +Signed-off-by: Detlev Casanova +Reported-by: Luca Ceresoli +Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c +index ff743ba0a9441..19eb82583d119 100644 +--- a/sound/soc/rockchip/rockchip_i2s_tdm.c ++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c +@@ -24,6 +24,7 @@ + + #define DRV_NAME "rockchip-i2s-tdm" + ++#define DEFAULT_MCLK_FS 256 + #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ + #define MULTIPLEX_CH_MAX 10 + +@@ -689,6 +690,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, + mclk_rate = i2s_tdm->mclk_rx_freq; + } + ++ /* ++ * When the dai/component driver doesn't need to set mclk-fs for a specific ++ * clock, it can skip the call to set_sysclk() for that clock. ++ * In that case, simply use the clock rate from the params and multiply it by ++ * the default mclk-fs value. ++ */ ++ if (!mclk_rate) ++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params); ++ + err = clk_set_rate(mclk, mclk_rate); + if (err) + return err; +-- +2.51.0 + diff --git a/queue-6.1/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch b/queue-6.1/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch new file mode 100644 index 0000000000..434944845d --- /dev/null +++ b/queue-6.1/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch @@ -0,0 +1,108 @@ +From ac21381e0b47152d4fbe51402b83dfcad5ae61e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 06:09:19 +0000 +Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down + +From: Hangbin Liu + +[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ] + +The ALB RX path may access rx_hashtbl concurrently with bond +teardown. During rapid bond up/down cycles, rlb_deinitialize() +frees rx_hashtbl while RX handlers are still running, leading +to a null pointer dereference detected by KASAN. + +However, the root cause is that rlb_arp_recv() can still be accessed +after setting recv_probe to NULL, which is actually a use-after-free +(UAF) issue. That is the reason for using the referenced commit in the +Fixes tag. + +[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI +[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef] +[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary) +[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022 +[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding] +[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6 + 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00 +[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206 +[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e +[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8 +[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8 +[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119 +[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810 +[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000 +[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0 +[ 214.310347] Call Trace: +[ 214.313070] +[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding] +[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding] +[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding] +[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710 +[ 214.339199] ? __pfx_arp_process+0x10/0x10 +[ 214.343775] ? sched_balance_find_src_group+0x98/0x630 +[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10 +[ 214.356513] ? arp_rcv+0x307/0x690 +[ 214.360311] ? __pfx_arp_rcv+0x10/0x10 +[ 214.364499] ? __lock_acquire+0x58c/0xbd0 +[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0 +[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10 +[ 214.380743] ? lock_acquire+0x10b/0x140 +[ 214.385026] process_backlog+0x3f1/0x13a0 +[ 214.389502] ? process_backlog+0x3aa/0x13a0 +[ 214.394174] __napi_poll.constprop.0+0x9f/0x370 +[ 214.399233] net_rx_action+0x8c1/0xe60 +[ 214.403423] ? __pfx_net_rx_action+0x10/0x10 +[ 214.408193] ? lock_acquire.part.0+0xbd/0x260 +[ 214.413058] ? sched_clock_cpu+0x6c/0x540 +[ 214.417540] ? mark_held_locks+0x40/0x70 +[ 214.421920] handle_softirqs+0x1fd/0x860 +[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10 +[ 214.431264] ? __neigh_event_send+0x2d6/0xf50 +[ 214.436131] do_softirq+0xb1/0xf0 +[ 214.439830] + +The issue is reproducible by repeatedly running +ip link set bond0 up/down while receiving ARP messages, where +rlb_arp_recv() can race with rlb_deinitialize() and dereference +a freed rx_hashtbl entry. + +Fix this by setting recv_probe to NULL and then calling +synchronize_net() to wait for any concurrent RX processing to finish. +This ensures that no RX handler can access rx_hashtbl after it is freed +in bond_alb_deinitialize(). + +Reported-by: Liang Li +Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()") +Reviewed-by: Nikolay Aleksandrov +Acked-by: Jay Vosburgh +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 113a5504c9ebb..8ff1c34b4db63 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4343,9 +4343,13 @@ static int bond_close(struct net_device *bond_dev) + + bond_work_cancel_all(bond); + bond->send_peer_notif = 0; ++ WRITE_ONCE(bond->recv_probe, NULL); ++ ++ /* Wait for any in-flight RX handlers */ ++ synchronize_net(); ++ + if (bond_is_lb(bond)) + bond_alb_deinitialize(bond); +- bond->recv_probe = NULL; + + if (bond_uses_primary(bond)) { + rcu_read_lock(); +-- +2.51.0 + diff --git a/queue-6.1/bpftool-fix-truncated-netlink-dumps.patch b/queue-6.1/bpftool-fix-truncated-netlink-dumps.patch new file mode 100644 index 0000000000..750be61dcf --- /dev/null +++ b/queue-6.1/bpftool-fix-truncated-netlink-dumps.patch @@ -0,0 +1,73 @@ +From 873c4ed7952e8f938a2154dd2ee604da5828c5ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 11:41:50 -0800 +Subject: bpftool: Fix truncated netlink dumps + +From: Jakub Kicinski + +[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ] + +Netlink requires that the recv buffer used during dumps is at least +min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will +get truncated. Make sure bpftool follows this requirement, avoid +missing information on systems with large pages. + +Acked-by: Quentin Monnet +Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool") +Signed-off-by: Jakub Kicinski +Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/net.c | 5 ++++- + tools/lib/bpf/netlink.c | 4 +++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c +index 7c9e86faab6ce..3863c2d986830 100644 +--- a/tools/bpf/bpftool/net.c ++++ b/tools/bpf/bpftool/net.c +@@ -143,7 +143,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + bool multipart = true; + struct nlmsgerr *err; + struct nlmsghdr *nh; +- char buf[4096]; ++ char buf[8192]; + int len, ret; + + while (multipart) { +@@ -188,6 +188,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + return ret; + } + } ++ ++ if (len) ++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len); + } + ret = 0; + done: +diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c +index 35104580870c0..ecd6e03b3ba53 100644 +--- a/tools/lib/bpf/netlink.c ++++ b/tools/lib/bpf/netlink.c +@@ -135,7 +135,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + struct nlmsghdr *nh; + int len, ret; + +- ret = alloc_iov(&iov, 4096); ++ ret = alloc_iov(&iov, 8192); + if (ret) + goto done; + +@@ -204,6 +204,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + } + } + } ++ if (len) ++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len); + } + ret = 0; + done: +-- +2.51.0 + diff --git a/queue-6.1/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch b/queue-6.1/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch new file mode 100644 index 0000000000..d25655372f --- /dev/null +++ b/queue-6.1/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch @@ -0,0 +1,52 @@ +From 8cce61a69e4f233761b9ece32df6c66257f64d29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 17:15:53 +0000 +Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not + found + +From: Filipe Manana + +[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ] + +If btrfs_search_slot_for_read() returns 1, it means we did not find any +key greater than or equals to the key we asked for, meaning we have +reached the end of the tree and therefore the path is not valid. If +this happens we need to break out of the loop and stop, instead of +continuing and accessing an invalid path. + +Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/qgroup.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index b175d0a4b3826..e80d73ad08103 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1123,11 +1123,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) + } + if (ret > 0) { + /* +- * Shouldn't happen, but in case it does we +- * don't need to do the btrfs_next_item, just +- * continue. ++ * Shouldn't happen because the key should still ++ * be there (return 0), but in case it does it ++ * means we have reached the end of the tree - ++ * there are no more leaves with items that have ++ * a key greater than or equals to @found_key, ++ * so just stop the search loop. + */ +- continue; ++ break; + } + } + ret = btrfs_next_item(tree_root, path); +-- +2.51.0 + diff --git a/queue-6.1/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch b/queue-6.1/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch new file mode 100644 index 0000000000..fbf3177b69 --- /dev/null +++ b/queue-6.1/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch @@ -0,0 +1,59 @@ +From c353fd8008c6eb3f6a87f2698e3dd0b06b189fc7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 00:20:02 +0530 +Subject: cpuidle: Skip governor when only one idle state is available + +From: Aboorva Devarajan + +[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ] + +On certain platforms (PowerNV systems without a power-mgt DT node), +cpuidle may register only a single idle state. In cases where that +single state is a polling state (state 0), the ladder governor may +incorrectly treat state 1 as the first usable state and pass an +out-of-bounds index. This can lead to a NULL enter callback being +invoked, ultimately resulting in a system crash. + +[ 13.342636] cpuidle-powernv : Only Snooze is available +[ 13.351854] Faulting instruction address: 0x00000000 +[ 13.376489] NIP [0000000000000000] 0x0 +[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668 + +Fix this by adding a bail-out in cpuidle_select() that returns state 0 +directly when state_count <= 1, bypassing the governor and keeping the +tick running. + +Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") +Signed-off-by: Aboorva Devarajan +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/cpuidle.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index fdd25271106a3..482bf87354a38 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -324,6 +324,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, + int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + bool *stop_tick) + { ++ /* ++ * If there is only a single idle state (or none), there is nothing ++ * meaningful for the governor to choose. Skip the governor and ++ * always use state 0 with the tick running. ++ */ ++ if (drv->state_count <= 1) { ++ *stop_tick = false; ++ return 0; ++ } ++ + return cpuidle_curr_governor->select(drv, dev, stop_tick); + } + +-- +2.51.0 + diff --git a/queue-6.1/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch b/queue-6.1/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch new file mode 100644 index 0000000000..a2981b02b2 --- /dev/null +++ b/queue-6.1/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch @@ -0,0 +1,78 @@ +From 9dff9eea1d2e4245dc2893a00545263c7876f461 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 23:38:28 +0100 +Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp + formats + +From: Mario Kleiner + +[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ] + +The plane scaling hw seems to have the same min/max plane scaling limits +for all 16 bpc / 64 bpp interleaved pixel color formats. + +Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for +all the 16 bpc fixed-point / unorm formats to use the same .fp16 +up/downscaling factor limits as used by the fp16 floating point formats. + +So far, 16 bpc unorm formats were not handled, and the default: path +returned max/min factors for 32 bpp argb8888 formats, which were wrong +and bigger than what many DCE / DCN hw generations could handle. + +The result sometimes was misscaling of framebuffers with +DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616, +DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested +on Polaris11 / DCE-11.2. + +So far this went unnoticed, because only few userspace clients used such +16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they +did not experience this issue. + +With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL +and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland +compositor allowing for direct scanout of these formats, the scaling +hw will be used on these formats if possible for HiDPI display scaling, +so it is important to use the correct hw scaling limits to avoid wrong +display. + +Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50 +on HiDPI displays with scaling enabled. The mutter Wayland compositor now +correctly falls back to scaling via desktop compositing instead of direct +scanout, thereby avoiding wrong image display. For unscaled mode, it +correctly uses direct scanout. + +Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.") +Signed-off-by: Mario Kleiner +Tested-by: Mario Kleiner +Cc: Alex Deucher +Cc: Harry Wentland +Cc: Leo Li +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +index df4cbf81c6b50..b3a1dbeac4839 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +@@ -970,10 +970,15 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev, + *min_downscale = plane_cap->max_downscale_factor.nv12; + break; + ++ /* All 64 bpp formats have the same fp16 scaling limits */ + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: ++ case DRM_FORMAT_XRGB16161616: ++ case DRM_FORMAT_ARGB16161616: ++ case DRM_FORMAT_XBGR16161616: ++ case DRM_FORMAT_ABGR16161616: + *max_upscale = plane_cap->max_upscale_factor.fp16; + *min_downscale = plane_cap->max_downscale_factor.fp16; + break; +-- +2.51.0 + diff --git a/queue-6.1/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch b/queue-6.1/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch new file mode 100644 index 0000000000..7c76799ca6 --- /dev/null +++ b/queue-6.1/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch @@ -0,0 +1,40 @@ +From d8e6fb00b639fb94a1f796d0fb3b65012b493887 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jan 2026 08:55:49 +0530 +Subject: drm/i915/acpi: free _DSM package when no connectors + +From: Kaushlendra Kumar + +[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ] + +acpi_evaluate_dsm_typed() returns an ACPI package in pkg. +When pkg->package.count == 0, we returned without freeing pkg, +leaking memory. Free pkg before returning on the empty case. + +Signed-off-by: Kaushlendra Kumar +Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects") +Reviewed-by: Jani Nikula +Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c +index 9df78e7caa2bd..231b341d968ad 100644 +--- a/drivers/gpu/drm/i915/display/intel_acpi.c ++++ b/drivers/gpu/drm/i915/display/intel_acpi.c +@@ -93,6 +93,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle) + + if (!pkg->package.count) { + DRM_DEBUG_DRIVER("no connection in _DSM\n"); ++ ACPI_FREE(pkg); + return; + } + +-- +2.51.0 + diff --git a/queue-6.1/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch b/queue-6.1/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch new file mode 100644 index 0000000000..ca008c0530 --- /dev/null +++ b/queue-6.1/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch @@ -0,0 +1,51 @@ +From 6f1cc64ea7858912a7be71844538b0a4dcfee919 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jan 2026 16:50:24 +0000 +Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot + +From: Jiasheng Jiang + +[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ] + +In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the +entry size ('esize') is retrieved from the log record without adequate +bounds checking. + +Specifically, the code calculates the end of the entry ('e2') using: + e2 = Add2Ptr(e1, esize); + +It then calculates the size for memmove using 'PtrOffset(e2, ...)', +which subtracts the end pointer from the buffer limit. If 'esize' is +maliciously large, 'e2' exceeds the used buffer size. This results in +a negative offset which, when cast to size_t for memmove, interprets +as a massive unsigned integer, leading to a heap buffer overflow. + +This commit adds a check to ensure that the entry size ('esize') strictly +fits within the remaining used space of the index header before performing +memory operations. + +Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fslog.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c +index 339ce5aa3c75b..7e6937e7d471f 100644 +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3434,6 +3434,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, + + e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off)); + esize = le16_to_cpu(e1->size); ++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize) ++ goto dirty_vol; ++ + e2 = Add2Ptr(e1, esize); + + memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used))); +-- +2.51.0 + diff --git a/queue-6.1/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch b/queue-6.1/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch new file mode 100644 index 0000000000..6c5b3f5809 --- /dev/null +++ b/queue-6.1/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch @@ -0,0 +1,58 @@ +From ca782b5a179f21f9e02f8fbf1e8177538b92f4ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Dec 2025 11:53:25 +0800 +Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the + same + +From: Edward Adam Davis + +[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ] + +When processing valid within the range [valid : pos), if valid cannot +be retrieved correctly, for example, if the retrieved valid value is +always the same, this can trigger a potential infinite loop, similar +to the hung problem reported by syzbot [1]. + +Adding a check for the valid value within the loop body, and terminating +the loop and returning -EINVAL if the value is the same as the current +value, can prevent this. + +[1] +INFO: task syz.4.21:6056 blocked for more than 143 seconds. +Call Trace: + rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244 + inode_lock include/linux/fs.h:1027 [inline] + ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1 +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index 6d9c1dfe9b1b6..f2d1df2c988a9 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -870,8 +870,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) + goto out; + + if (lcn == SPARSE_LCN) { +- ni->i_valid = valid = +- frame_vbo + ((u64)clen << sbi->cluster_bits); ++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits); ++ if (ni->i_valid == valid) { ++ err = -EINVAL; ++ goto out; ++ } ++ ni->i_valid = valid; + continue; + } + +-- +2.51.0 + diff --git a/queue-6.1/icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch b/queue-6.1/icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch new file mode 100644 index 0000000000..3c16ee3f07 --- /dev/null +++ b/queue-6.1/icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch @@ -0,0 +1,145 @@ +From 1b9ddebe1d1b4d865baf4a694ac571e40f089e6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 14:46:41 +0000 +Subject: icmp: icmp_msgs_per_sec and icmp_msgs_burst sysctls become per netns + +From: Eric Dumazet + +[ Upstream commit f17bf505ff89595df5147755e51441632a5dc563 ] + +Previous patch made ICMP rate limits per netns, it makes sense +to allow each netns to change the associated sysctl. + +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20240829144641.3880376-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 034bbd806298 ("icmp: prevent possible overflow in icmp_global_allow()") +Signed-off-by: Sasha Levin +--- + include/net/ip.h | 3 --- + include/net/netns/ipv4.h | 2 ++ + net/ipv4/icmp.c | 9 ++++----- + net/ipv4/sysctl_net_ipv4.c | 32 ++++++++++++++++---------------- + 4 files changed, 22 insertions(+), 24 deletions(-) + +diff --git a/include/net/ip.h b/include/net/ip.h +index 86ae58408148b..1b0722e9b55e4 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -788,9 +788,6 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) + bool icmp_global_allow(struct net *net); + void icmp_global_consume(struct net *net); + +-extern int sysctl_icmp_msgs_per_sec; +-extern int sysctl_icmp_msgs_burst; +- + #ifdef CONFIG_PROC_FS + int ip_misc_proc_init(void); + #endif +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 45988bea57cb2..091482aa76c32 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -83,6 +83,8 @@ struct netns_ipv4 { + u8 sysctl_icmp_errors_use_inbound_ifaddr; + int sysctl_icmp_ratelimit; + int sysctl_icmp_ratemask; ++ int sysctl_icmp_msgs_per_sec; ++ int sysctl_icmp_msgs_burst; + atomic_t icmp_global_credit; + u32 icmp_global_stamp; + u32 ip_rt_min_pmtu; +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index d1660c426a44a..d2c7509135a3f 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -221,9 +221,6 @@ static inline void icmp_xmit_unlock(struct sock *sk) + spin_unlock(&sk->sk_lock.slock); + } + +-int sysctl_icmp_msgs_per_sec __read_mostly = 1000; +-int sysctl_icmp_msgs_burst __read_mostly = 50; +- + /** + * icmp_global_allow - Are we allowed to send one more ICMP message ? + * @net: network namespace +@@ -250,14 +247,14 @@ bool icmp_global_allow(struct net *net) + if (delta < HZ / 50) + return false; + +- incr = READ_ONCE(sysctl_icmp_msgs_per_sec) * delta / HZ; ++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; + if (!incr) + return false; + + if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) { + old = atomic_read(&net->ipv4.icmp_global_credit); + do { +- new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst)); ++ new = min(old + incr, READ_ONCE(net->ipv4.sysctl_icmp_msgs_burst)); + } while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new)); + } + return true; +@@ -1510,6 +1507,8 @@ static int __net_init icmp_sk_init(struct net *net) + net->ipv4.sysctl_icmp_ratelimit = 1 * HZ; + net->ipv4.sysctl_icmp_ratemask = 0x1818; + net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0; ++ net->ipv4.sysctl_icmp_msgs_per_sec = 1000; ++ net->ipv4.sysctl_icmp_msgs_burst = 50; + + return 0; + } +diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c +index 73e5821584c18..6b4c9b0fc9abb 100644 +--- a/net/ipv4/sysctl_net_ipv4.c ++++ b/net/ipv4/sysctl_net_ipv4.c +@@ -519,22 +519,6 @@ static struct ctl_table ipv4_table[] = { + .mode = 0444, + .proc_handler = proc_tcp_available_ulp, + }, +- { +- .procname = "icmp_msgs_per_sec", +- .data = &sysctl_icmp_msgs_per_sec, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, +- }, +- { +- .procname = "icmp_msgs_burst", +- .data = &sysctl_icmp_msgs_burst, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, +- }, + { + .procname = "udp_mem", + .data = &sysctl_udp_mem, +@@ -621,6 +605,22 @@ static struct ctl_table ipv4_net_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec + }, ++ { ++ .procname = "icmp_msgs_per_sec", ++ .data = &init_net.ipv4.sysctl_icmp_msgs_per_sec, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ }, ++ { ++ .procname = "icmp_msgs_burst", ++ .data = &init_net.ipv4.sysctl_icmp_msgs_burst, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ }, + { + .procname = "ping_group_range", + .data = &init_net.ipv4.ping_group_range.range, +-- +2.51.0 + diff --git a/queue-6.1/icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch b/queue-6.1/icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch new file mode 100644 index 0000000000..76a3572aff --- /dev/null +++ b/queue-6.1/icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch @@ -0,0 +1,168 @@ +From 73d8f86cb4e620a3cb7fa954399c17a3c7f09bb7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 14:46:40 +0000 +Subject: icmp: move icmp_global.credit and icmp_global.stamp to per netns + storage + +From: Eric Dumazet + +[ Upstream commit b056b4cd9178f7a1d5d57f7b48b073c29729ddaa ] + +Host wide ICMP ratelimiter should be per netns, to provide better isolation. + +Following patch in this series makes the sysctl per netns. + +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20240829144641.3880376-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 034bbd806298 ("icmp: prevent possible overflow in icmp_global_allow()") +Signed-off-by: Sasha Levin +--- + include/net/ip.h | 4 ++-- + include/net/netns/ipv4.h | 3 ++- + net/ipv4/icmp.c | 26 +++++++++++--------------- + net/ipv6/icmp.c | 4 ++-- + 4 files changed, 17 insertions(+), 20 deletions(-) + +diff --git a/include/net/ip.h b/include/net/ip.h +index 4ee23eb0814a3..86ae58408148b 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -785,8 +785,8 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) + ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0); + } + +-bool icmp_global_allow(void); +-void icmp_global_consume(void); ++bool icmp_global_allow(struct net *net); ++void icmp_global_consume(struct net *net); + + extern int sysctl_icmp_msgs_per_sec; + extern int sysctl_icmp_msgs_burst; +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index ede2ff1da53a3..45988bea57cb2 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -83,7 +83,8 @@ struct netns_ipv4 { + u8 sysctl_icmp_errors_use_inbound_ifaddr; + int sysctl_icmp_ratelimit; + int sysctl_icmp_ratemask; +- ++ atomic_t icmp_global_credit; ++ u32 icmp_global_stamp; + u32 ip_rt_min_pmtu; + int ip_rt_mtu_expires; + int ip_rt_min_advmss; +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 56b240e7f083c..d1660c426a44a 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -224,19 +224,15 @@ static inline void icmp_xmit_unlock(struct sock *sk) + int sysctl_icmp_msgs_per_sec __read_mostly = 1000; + int sysctl_icmp_msgs_burst __read_mostly = 50; + +-static struct { +- atomic_t credit; +- u32 stamp; +-} icmp_global; +- + /** + * icmp_global_allow - Are we allowed to send one more ICMP message ? ++ * @net: network namespace + * + * Uses a token bucket to limit our ICMP messages to ~sysctl_icmp_msgs_per_sec. + * Returns false if we reached the limit and can not send another packet. + * Works in tandem with icmp_global_consume(). + */ +-bool icmp_global_allow(void) ++bool icmp_global_allow(struct net *net) + { + u32 delta, now, oldstamp; + int incr, new, old; +@@ -245,11 +241,11 @@ bool icmp_global_allow(void) + * Then later icmp_global_consume() could consume more credits, + * this is an acceptable race. + */ +- if (atomic_read(&icmp_global.credit) > 0) ++ if (atomic_read(&net->ipv4.icmp_global_credit) > 0) + return true; + + now = jiffies; +- oldstamp = READ_ONCE(icmp_global.stamp); ++ oldstamp = READ_ONCE(net->ipv4.icmp_global_stamp); + delta = min_t(u32, now - oldstamp, HZ); + if (delta < HZ / 50) + return false; +@@ -258,23 +254,23 @@ bool icmp_global_allow(void) + if (!incr) + return false; + +- if (cmpxchg(&icmp_global.stamp, oldstamp, now) == oldstamp) { +- old = atomic_read(&icmp_global.credit); ++ if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) { ++ old = atomic_read(&net->ipv4.icmp_global_credit); + do { + new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst)); +- } while (!atomic_try_cmpxchg(&icmp_global.credit, &old, new)); ++ } while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new)); + } + return true; + } + EXPORT_SYMBOL(icmp_global_allow); + +-void icmp_global_consume(void) ++void icmp_global_consume(struct net *net) + { + int credits = get_random_u32_below(3); + + /* Note: this might make icmp_global.credit negative. */ + if (credits) +- atomic_sub(credits, &icmp_global.credit); ++ atomic_sub(credits, &net->ipv4.icmp_global_credit); + } + EXPORT_SYMBOL(icmp_global_consume); + +@@ -300,7 +296,7 @@ static bool icmpv4_global_allow(struct net *net, int type, int code, + if (icmpv4_mask_allow(net, type, code)) + return true; + +- if (icmp_global_allow()) { ++ if (icmp_global_allow(net)) { + *apply_ratelimit = true; + return true; + } +@@ -337,7 +333,7 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, + if (!rc) + __ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST); + else +- icmp_global_consume(); ++ icmp_global_consume(net); + return rc; + } + +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index 7ba3c642ab3c3..ea1cdacbdcf1b 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -181,7 +181,7 @@ static bool icmpv6_global_allow(struct net *net, int type, + if (icmpv6_mask_allow(net, type)) + return true; + +- if (icmp_global_allow()) { ++ if (icmp_global_allow(net)) { + *apply_ratelimit = true; + return true; + } +@@ -231,7 +231,7 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type, + __ICMP6_INC_STATS(net, ip6_dst_idev(dst), + ICMP6_MIB_RATELIMITHOST); + else +- icmp_global_consume(); ++ icmp_global_consume(net); + dst_release(dst); + return res; + } +-- +2.51.0 + diff --git a/queue-6.1/icmp-prevent-possible-overflow-in-icmp_global_allow.patch b/queue-6.1/icmp-prevent-possible-overflow-in-icmp_global_allow.patch new file mode 100644 index 0000000000..75e4b3bef6 --- /dev/null +++ b/queue-6.1/icmp-prevent-possible-overflow-in-icmp_global_allow.patch @@ -0,0 +1,41 @@ +From fdc2d6979e528116457e540fbf150c1c9d8ef1d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:28 +0000 +Subject: icmp: prevent possible overflow in icmp_global_allow() + +From: Eric Dumazet + +[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ] + +Following expression can overflow +if sysctl_icmp_msgs_per_sec is big enough. + +sysctl_icmp_msgs_per_sec * delta / HZ; + +Fixes: 4cdf507d5452 ("icmp: add a global rate limitation") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/icmp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index d2c7509135a3f..374ec3aba66e3 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -247,7 +247,8 @@ bool icmp_global_allow(struct net *net) + if (delta < HZ / 50) + return false; + +- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; ++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec); ++ incr = div_u64((u64)incr * delta, HZ); + if (!incr) + return false; + +-- +2.51.0 + diff --git a/queue-6.1/inet-ping-check-sock_net-in-ping_get_port-and-ping_l.patch b/queue-6.1/inet-ping-check-sock_net-in-ping_get_port-and-ping_l.patch new file mode 100644 index 0000000000..67850dcedd --- /dev/null +++ b/queue-6.1/inet-ping-check-sock_net-in-ping_get_port-and-ping_l.patch @@ -0,0 +1,84 @@ +From ced56e983f6d395a408560f46cc65346b29c5f88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Aug 2025 15:30:51 +0000 +Subject: inet: ping: check sock_net() in ping_get_port() and ping_lookup() + +From: Eric Dumazet + +[ Upstream commit 59f26d86b2a16f1406f3b42025062b6d1fba5dd5 ] + +We need to check socket netns before considering them in ping_get_port(). +Otherwise, one malicious netns could 'consume' all ports. + +Add corresponding check in ping_lookup(). + +Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Reviewed-by: Yue Haibing +Link: https://patch.msgid.link/20250829153054.474201-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: ad5dfde2a573 ("ping: annotate data-races in ping_lookup()") +Signed-off-by: Sasha Levin +--- + net/ipv4/ping.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index aae5ad6303a97..ee0e2df5d62e0 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -77,6 +77,7 @@ static inline struct hlist_head *ping_hashslot(struct ping_table *table, + + int ping_get_port(struct sock *sk, unsigned short ident) + { ++ struct net *net = sock_net(sk); + struct inet_sock *isk, *isk2; + struct hlist_head *hlist; + struct sock *sk2 = NULL; +@@ -90,9 +91,10 @@ int ping_get_port(struct sock *sk, unsigned short ident) + for (i = 0; i < (1L << 16); i++, result++) { + if (!result) + result++; /* avoid zero */ +- hlist = ping_hashslot(&ping_table, sock_net(sk), +- result); ++ hlist = ping_hashslot(&ping_table, net, result); + sk_for_each(sk2, hlist) { ++ if (!net_eq(sock_net(sk2), net)) ++ continue; + isk2 = inet_sk(sk2); + + if (isk2->inet_num == result) +@@ -108,8 +110,10 @@ int ping_get_port(struct sock *sk, unsigned short ident) + if (i >= (1L << 16)) + goto fail; + } else { +- hlist = ping_hashslot(&ping_table, sock_net(sk), ident); ++ hlist = ping_hashslot(&ping_table, net, ident); + sk_for_each(sk2, hlist) { ++ if (!net_eq(sock_net(sk2), net)) ++ continue; + isk2 = inet_sk(sk2); + + /* BUG? Why is this reuse and not reuseaddr? ping.c +@@ -129,7 +133,7 @@ int ping_get_port(struct sock *sk, unsigned short ident) + pr_debug("was not hashed\n"); + sk_add_node_rcu(sk, hlist); + sock_set_flag(sk, SOCK_RCU_FREE); +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); ++ sock_prot_inuse_add(net, sk->sk_prot, 1); + } + spin_unlock(&ping_table.lock); + return 0; +@@ -188,6 +192,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + } + + sk_for_each_rcu(sk, hslot) { ++ if (!net_eq(sock_net(sk), net)) ++ continue; + isk = inet_sk(sk); + + pr_debug("iterate\n"); +-- +2.51.0 + diff --git a/queue-6.1/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch b/queue-6.1/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch new file mode 100644 index 0000000000..20f2f925e9 --- /dev/null +++ b/queue-6.1/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch @@ -0,0 +1,53 @@ +From 8927e093e9806e3da2f8fade2ae7719cb756f51d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:22:02 +0000 +Subject: ipv6: fix a race in ip6_sock_set_v6only() + +From: Eric Dumazet + +[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ] + +It is unlikely that this function will be ever called +with isk->inet_num being not zero. + +Perform the check on isk->inet_num inside the locked section +for complete safety. + +Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Fernando Fernandez Mancera +Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/ipv6.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 517bdae78614b..3bf743d601e1c 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -1255,12 +1255,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, + + static inline int ip6_sock_set_v6only(struct sock *sk) + { +- if (inet_sk(sk)->inet_num) +- return -EINVAL; ++ int ret = 0; ++ + lock_sock(sk); +- sk->sk_ipv6only = true; ++ if (inet_sk(sk)->inet_num) ++ ret = -EINVAL; ++ else ++ sk->sk_ipv6only = true; + release_sock(sk); +- return 0; ++ return ret; + } + + static inline void ip6_sock_set_recverr(struct sock *sk) +-- +2.51.0 + diff --git a/queue-6.1/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch b/queue-6.1/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch new file mode 100644 index 0000000000..5156024fbb --- /dev/null +++ b/queue-6.1/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch @@ -0,0 +1,116 @@ +From c6786735d3a16fbb6428f83215354f7567a58688 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:25:57 +0000 +Subject: macvlan: observe an RCU grace period in macvlan_common_newlink() + error path + +From: Eric Dumazet + +[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ] + +valis reported that a race condition still happens after my prior patch. + +macvlan_common_newlink() might have made @dev visible before +detecting an error, and its caller will directly call free_netdev(dev). + +We must respect an RCU period, either in macvlan or the core networking +stack. + +After adding a temporary mdelay(1000) in macvlan_forward_source_one() +to open the race window, valis repro was: + +ip link add p1 type veth peer p2 +ip link set address 00:00:00:00:00:20 dev p1 +ip link set up dev p1 +ip link set up dev p2 +ip link add mv0 link p2 type macvlan mode source + +(ip link add invalid% link p2 type macvlan mode source macaddr add +00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4 +PING 1.2.3.4 (1.2.3.4): 56 data bytes +RTNETLINK answers: Invalid argument + +BUG: KASAN: slab-use-after-free in macvlan_forward_source +(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +Read of size 8 at addr ffff888016bb89c0 by task e/175 + +CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +Call Trace: + +dump_stack_lvl (lib/dump_stack.c:123) +print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +kasan_report (mm/kasan/report.c:597) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +? tasklet_init (kernel/softirq.c:983) +macvlan_handle_frame (drivers/net/macvlan.c:501) + +Allocated by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +__kasan_kmalloc (mm/kasan/common.c:419) +__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657 +mm/slub.c:7140) +alloc_netdev_mqs (net/core/dev.c:12012) +rtnl_create_link (net/core/rtnetlink.c:3648) +rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Freed by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +kasan_save_free_info (mm/kasan/generic.c:587) +__kasan_slab_free (mm/kasan/common.c:287) +kfree (mm/slub.c:6674 mm/slub.c:6882) +rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()") +Signed-off-by: Eric Dumazet +Reported-by: valis +Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index 5fb956adc4260..24e36d78a23ae 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1544,6 +1544,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, + if (create) + macvlan_port_destroy(port->dev); + } ++ /* @dev might have been made visible before an error was detected. ++ * Make sure to observe an RCU grace period before our caller ++ * (rtnl_newlink()) frees it. ++ */ ++ synchronize_net(); + return err; + } + EXPORT_SYMBOL_GPL(macvlan_common_newlink); +-- +2.51.0 + diff --git a/queue-6.1/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch b/queue-6.1/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch new file mode 100644 index 0000000000..a8a6ac600a --- /dev/null +++ b/queue-6.1/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch @@ -0,0 +1,62 @@ +From fc8c1f353ffb7f37eeac38ab678e74030ad0cd3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:02 +0000 +Subject: net: mscc: ocelot: add missing lock protection in + ocelot_port_xmit_inj() + +From: Ziyi Guo + +[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ] + +ocelot_port_xmit_inj() calls ocelot_can_inject() and +ocelot_port_inject_frame() without holding the injection group lock. +Both functions contain lockdep_assert_held() for the injection lock, +and the correct caller felix_port_deferred_xmit() properly acquires +the lock using ocelot_lock_inj_grp() before calling these functions. + +Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register +injection path to fix the missing lock protection. The FDMA path is not +affected as it uses its own locking mechanism. + +Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups") +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 14de948f72464..e4f4ea97c55b7 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -606,14 +606,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, + int port = priv->port.index; + u32 rew_op = 0; + +- if (!ocelot_can_inject(ocelot, 0)) ++ ocelot_lock_inj_grp(ocelot, 0); ++ ++ if (!ocelot_can_inject(ocelot, 0)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_BUSY; ++ } + +- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_OK; ++ } + + ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ++ ocelot_unlock_inj_grp(ocelot, 0); ++ + consume_skb(skb); + + return NETDEV_TX_OK; +-- +2.51.0 + diff --git a/queue-6.1/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch b/queue-6.1/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch new file mode 100644 index 0000000000..09950ce084 --- /dev/null +++ b/queue-6.1/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch @@ -0,0 +1,93 @@ +From cf475e5585b6c59c748793c074198aba7d76e2f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:00 +0000 +Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper + +From: Ziyi Guo + +[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ] + +Extract the PTP timestamp handling logic from ocelot_port_xmit() into a +separate ocelot_xmit_timestamp() helper function. This is a pure +refactor with no behavioral change. + +The helper returns false if the skb was consumed (freed) due to a +timestamp request failure, and true if the caller should continue with +frame injection. The rew_op value is returned via pointer. + +This prepares for splitting ocelot_port_xmit() into separate FDMA and +register injection paths in a subsequent patch. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++---------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 50858cc10fef6..38d0c1af10a96 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -560,33 +560,41 @@ static int ocelot_port_stop(struct net_device *dev) + return 0; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, ++ struct sk_buff *skb, u32 *rew_op) + { +- struct ocelot_port_private *priv = netdev_priv(dev); +- struct ocelot_port *ocelot_port = &priv->port; +- struct ocelot *ocelot = ocelot_port->ocelot; +- int port = priv->port.index; +- u32 rew_op = 0; +- +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) +- return NETDEV_TX_BUSY; +- +- /* Check if timestamping is needed */ + if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + struct sk_buff *clone = NULL; + + if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) { + kfree_skb(skb); +- return NETDEV_TX_OK; ++ return false; + } + + if (clone) + OCELOT_SKB_CB(skb)->clone = clone; + +- rew_op = ocelot_ptp_rew_op(skb); ++ *rew_op = ocelot_ptp_rew_op(skb); + } + ++ return true; ++} ++ ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!static_branch_unlikely(&ocelot_fdma_enabled) && ++ !ocelot_can_inject(ocelot, 0)) ++ return NETDEV_TX_BUSY; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ + if (static_branch_unlikely(&ocelot_fdma_enabled)) { + ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); + } else { +-- +2.51.0 + diff --git a/queue-6.1/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch b/queue-6.1/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch new file mode 100644 index 0000000000..3b6bfdef99 --- /dev/null +++ b/queue-6.1/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch @@ -0,0 +1,100 @@ +From b87c2fe91cfc6a078a62e07ed3672e1bab003d54 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:01 +0000 +Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths + +From: Ziyi Guo + +[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ] + +Split ocelot_port_xmit() into two separate functions: +- ocelot_port_xmit_fdma(): handles the FDMA injection path +- ocelot_port_xmit_inj(): handles the register-based injection path + +The top-level ocelot_port_xmit() now dispatches to the appropriate +function based on the ocelot_fdma_enabled static key. + +This is a pure refactor with no behavioral change. Separating the two +code paths makes each one simpler and prepares for adding proper locking +to the register injection path without affecting the FDMA path. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 38d0c1af10a96..14de948f72464 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -580,7 +580,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, + return true; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ ++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); ++ ++ return NETDEV_TX_OK; ++} ++ ++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, ++ struct net_device *dev) + { + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; +@@ -588,24 +606,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) + int port = priv->port.index; + u32 rew_op = 0; + +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) ++ if (!ocelot_can_inject(ocelot, 0)) + return NETDEV_TX_BUSY; + + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + return NETDEV_TX_OK; + +- if (static_branch_unlikely(&ocelot_fdma_enabled)) { +- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); +- } else { +- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); ++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + +- consume_skb(skb); +- } ++ consume_skb(skb); + + return NETDEV_TX_OK; + } + ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ if (static_branch_unlikely(&ocelot_fdma_enabled)) ++ return ocelot_port_xmit_fdma(skb, dev); ++ ++ return ocelot_port_xmit_inj(skb, dev); ++} ++ + enum ocelot_action_type { + OCELOT_MACT_LEARN, + OCELOT_MACT_FORGET, +-- +2.51.0 + diff --git a/queue-6.1/net-rds-rds_sendmsg-should-not-discard-payload_len.patch b/queue-6.1/net-rds-rds_sendmsg-should-not-discard-payload_len.patch new file mode 100644 index 0000000000..e509fce652 --- /dev/null +++ b/queue-6.1/net-rds-rds_sendmsg-should-not-discard-payload_len.patch @@ -0,0 +1,50 @@ +From b1817f119ac9636e9fc973fca7eb59033a326c43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:54:09 -0700 +Subject: net/rds: rds_sendmsg should not discard payload_len + +From: Allison Henderson + +[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ] + +Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with +connection teardown") modifies rds_sendmsg to avoid enqueueing work +while a tear down is in progress. However, it also changed the return +value of rds_sendmsg to that of rds_send_xmit instead of the +payload_len. This means the user may incorrectly receive errno values +when it should have simply received a payload of 0 while the peer +attempts a reconnections. So this patch corrects the teardown handling +code to only use the out error path in that case, thus restoring the +original payload_len return value. + +Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown") +Reviewed-by: Simon Horman +Signed-off-by: Allison Henderson +Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/rds/send.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/rds/send.c b/net/rds/send.c +index 0005fb43f2dfa..8aa06f7e4640c 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1383,9 +1383,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) + else + queue_delayed_work(rds_wq, &cpath->cp_send_w, 1); + rcu_read_unlock(); ++ ++ if (ret) ++ goto out; + } +- if (ret) +- goto out; ++ + rds_message_put(rm); + + for (ind = 0; ind < vct.indx; ind++) +-- +2.51.0 + diff --git a/queue-6.1/net-remove-warn_on_once-when-accessing-forward-path-.patch b/queue-6.1/net-remove-warn_on_once-when-accessing-forward-path-.patch new file mode 100644 index 0000000000..2ce38bc75c --- /dev/null +++ b/queue-6.1/net-remove-warn_on_once-when-accessing-forward-path-.patch @@ -0,0 +1,39 @@ +From aad5ab782f5b2ac6935235acbda3bccdef5813db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 12:56:39 +0100 +Subject: net: remove WARN_ON_ONCE when accessing forward path array + +From: Pablo Neira Ayuso + +[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ] + +Although unlikely, recent support for IPIP tunnels increases chances of +reaching this WARN_ON_ONCE if userspace manages to build a sufficiently +long forward path. + +Remove it. + +Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 69bb7ac73d047..c2ca0b45bd37d 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -695,7 +695,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) + { + int k = stack->num_paths++; + +- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) ++ if (k >= NET_DEVICE_PATH_STACK_MAX) + return NULL; + + return &stack->path[k]; +-- +2.51.0 + diff --git a/queue-6.1/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch b/queue-6.1/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch new file mode 100644 index 0000000000..975771b220 --- /dev/null +++ b/queue-6.1/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch @@ -0,0 +1,48 @@ +From fbdfd52ef54aff85f3f00b6ff8923b0d1b9d10f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 14:44:01 +0100 +Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register + width + +From: Daniel Machon + +[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ] + +DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth +across traffic classes based on per-queue cost values, where lower cost +means higher bandwidth share. + +The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware +register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only +5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to +compute cost values that silently overflow via FIELD_PREP, resulting +in incorrect scheduling weights. + +Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width. + +Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc") +Signed-off-by: Daniel Machon +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +index ced35033a6c5d..b1c6c5c6f16ca 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +@@ -35,7 +35,7 @@ + #define SPX5_SE_BURST_UNIT 4096 + + /* Dwrr */ +-#define SPX5_DWRR_COST_MAX 63 ++#define SPX5_DWRR_COST_MAX 31 + + struct sparx5_shaper { + u32 mode; +-- +2.51.0 + diff --git a/queue-6.1/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch b/queue-6.1/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch new file mode 100644 index 0000000000..b37d26f8b7 --- /dev/null +++ b/queue-6.1/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch @@ -0,0 +1,53 @@ +From 876abfc0b56c986d888d66210b67a51b2815eb19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 12:02:30 +0100 +Subject: net: sparx5/lan969x: fix PTP clock max_adj value + +From: Daniel Machon + +[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ] + +The max_adj field in ptp_clock_info tells userspace how much the PHC +clock frequency can be adjusted. ptp4l reads this and will never request +a correction larger than max_adj. + +On both sparx5 and lan969x the clock offset may never converge because +the servo needs a frequency correction larger than the current max_adj +of 200000 (200 ppm) allows. The servo rails at the max and the offset +stays in the tens of microseconds. + +The hardware has no inherent max adjustment limit; frequency correction +is done by writing a 64-bit clock period increment to CLK_PER_CFG, and +the register has plenty of range. The 200000 value was just an overly +conservative software limit. The max_adj is shared between sparx5 and +lan969x, and the increased value is safe for both. + +Fix this by increasing max_adj to 10000000 (10000 ppm), giving the +servo sufficient headroom. + +Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks") +Signed-off-by: Daniel Machon +Reviewed-by: Maxime Chevallier +Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +index 69e76634f9aa8..9c602f19d43b0 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +@@ -565,7 +565,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) + static struct ptp_clock_info sparx5_ptp_clock_info = { + .owner = THIS_MODULE, + .name = "sparx5 ptp", +- .max_adj = 200000, ++ .max_adj = 10000000, + .gettime64 = sparx5_ptp_gettime64, + .settime64 = sparx5_ptp_settime64, + .adjtime = sparx5_ptp_adjtime, +-- +2.51.0 + diff --git a/queue-6.1/net-usb-catc-enable-basic-endpoint-checking.patch b/queue-6.1/net-usb-catc-enable-basic-endpoint-checking.patch new file mode 100644 index 0000000000..58f847409d --- /dev/null +++ b/queue-6.1/net-usb-catc-enable-basic-endpoint-checking.patch @@ -0,0 +1,111 @@ +From c7ab34984e996eab21806bebca059a434070d042 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 21:41:54 +0000 +Subject: net: usb: catc: enable basic endpoint checking + +From: Ziyi Guo + +[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ] + +catc_probe() fills three URBs with hardcoded endpoint pipes without +verifying the endpoint descriptors: + + - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX + - usb_rcvintpipe(usbdev, 2) for interrupt status + +A malformed USB device can present these endpoints with transfer types +that differ from what the driver assumes. + +Add a catc_usb_ep enum for endpoint numbers, replacing magic constants +throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints() +calls after usb_set_interface() to verify endpoint types before use, +rejecting devices with mismatched descriptors at probe time. + +Similar to +- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking") +which fixed the issue in rtl8150. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Suggested-by: Simon Horman +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c +index ff439ef535ac9..98346cb4ece01 100644 +--- a/drivers/net/usb/catc.c ++++ b/drivers/net/usb/catc.c +@@ -64,6 +64,16 @@ static const char driver_name[] = "catc"; + #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ + #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ + ++/* ++ * USB endpoints. ++ */ ++ ++enum catc_usb_ep { ++ CATC_USB_EP_CONTROL = 0, ++ CATC_USB_EP_BULK = 1, ++ CATC_USB_EP_INT_IN = 2, ++}; ++ + /* + * Control requests. + */ +@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + u8 broadcast[ETH_ALEN]; + u8 *macbuf; + int pktsz, ret = -ENOMEM; ++ static const u8 bulk_ep_addr[] = { ++ CATC_USB_EP_BULK | USB_DIR_OUT, ++ CATC_USB_EP_BULK | USB_DIR_IN, ++ 0}; ++ static const u8 int_ep_addr[] = { ++ CATC_USB_EP_INT_IN | USB_DIR_IN, ++ 0}; + + macbuf = kmalloc(ETH_ALEN, GFP_KERNEL); + if (!macbuf) +@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + goto fail_mem; + } + ++ /* Verify that all required endpoints are present */ ++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || ++ !usb_check_int_endpoints(intf, int_ep_addr)) { ++ dev_err(dev, "Missing or invalid endpoints\n"); ++ ret = -ENODEV; ++ goto fail_mem; ++ } ++ + netdev = alloc_etherdev(sizeof(struct catc)); + if (!netdev) + goto fail_mem; +@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), + NULL, NULL, 0, catc_ctrl_done, catc); + +- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), +- NULL, 0, catc_tx_done, catc); ++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK), ++ NULL, 0, catc_tx_done, catc); + +- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), +- catc->rx_buf, pktsz, catc_rx_done, catc); ++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK), ++ catc->rx_buf, pktsz, catc_rx_done, catc); + +- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), +- catc->irq_buf, 2, catc_irq_done, catc, 1); ++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN), ++ catc->irq_buf, 2, catc_irq_done, catc, 1); + + if (!catc->is_f5u011) { + u32 *buf; +-- +2.51.0 + diff --git a/queue-6.1/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch b/queue-6.1/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch new file mode 100644 index 0000000000..bee27279f6 --- /dev/null +++ b/queue-6.1/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch @@ -0,0 +1,58 @@ +From 66893b72ae77860a5223e9346bbfb3eca5042dfb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 12:53:09 +0100 +Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value + +From: Florian Westphal + +[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ] + +Mihail Milev reports: Error: UNINIT (CWE-457): + net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl: + Declaring variable "tuple" without initializer. + net/netfilter/nf_conntrack_h323_main.c:1197:2: + uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find". + net/netfilter/nf_conntrack_expect.c:142:2: + read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash". + + 1195| tuple.dst.protonum = IPPROTO_TCP; + 1196| + 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + 1198| if (exp && exp->master == ct) + 1199| return exp; + +Switch this to a C99 initialiser and set the l3num value. + +Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port") +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_h323_main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c +index 5a9bce24f3c3d..ed983421e2eb2 100644 +--- a/net/netfilter/nf_conntrack_h323_main.c ++++ b/net/netfilter/nf_conntrack_h323_main.c +@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, + { + struct net *net = nf_ct_net(ct); + struct nf_conntrack_expect *exp; +- struct nf_conntrack_tuple tuple; ++ struct nf_conntrack_tuple tuple = { ++ .src.l3num = nf_ct_l3num(ct), ++ .dst.protonum = IPPROTO_TCP, ++ .dst.u.tcp.port = port, ++ }; + +- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); +- tuple.src.u.tcp.port = 0; + memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); +- tuple.dst.u.tcp.port = port; +- tuple.dst.protonum = IPPROTO_TCP; + + exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + if (exp && exp->master == ct) +-- +2.51.0 + diff --git a/queue-6.1/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch b/queue-6.1/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch new file mode 100644 index 0000000000..0c77263355 --- /dev/null +++ b/queue-6.1/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch @@ -0,0 +1,54 @@ +From 1ea327247645ea488480c1e7dcdf5fcaf9802602 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 21:14:40 +0900 +Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain() + +From: Inseo An + +[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ] + +nf_tables_addchain() publishes the chain to table->chains via +list_add_tail_rcu() (in nft_chain_add()) before registering hooks. +If nf_tables_register_hook() then fails, the error path calls +nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy() +with no RCU grace period in between. + +This creates two use-after-free conditions: + + 1) Control-plane: nf_tables_dump_chains() traverses table->chains + under rcu_read_lock(). A concurrent dump can still be walking + the chain when the error path frees it. + + 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly + installs the IPv4 hook before IPv6 registration fails. Packets + entering nft_do_chain() via the transient IPv4 hook can still be + dereferencing chain->blob_gen_X when the error path frees the + chain. + +Add synchronize_rcu() between nft_chain_del() and the chain destroy +so that all RCU readers -- both dump threads and in-flight packet +evaluation -- have finished before the chain is freed. + +Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain") +Signed-off-by: Inseo An +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 67729d7c913a4..ac36183956515 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2510,6 +2510,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, + + err_register_hook: + nft_chain_del(chain); ++ synchronize_rcu(); + err_chain_add: + nft_trans_destroy(trans); + err_trans: +-- +2.51.0 + diff --git a/queue-6.1/octeontx2-af-fix-default-entries-mcam-entry-action.patch b/queue-6.1/octeontx2-af-fix-default-entries-mcam-entry-action.patch new file mode 100644 index 0000000000..262256aef6 --- /dev/null +++ b/queue-6.1/octeontx2-af-fix-default-entries-mcam-entry-action.patch @@ -0,0 +1,85 @@ +From ed70285c8ce7285d634be3e3cb41b8c030f934ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:33:38 +0530 +Subject: octeontx2-af: Fix default entries mcam entry action + +From: Hariprasad Kelam + +[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ] + +As per design, AF should update the default MCAM action only when +mcam_index is -1. A bug in the previous patch caused default entries +to be changed even when the request was not for them. + +Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index") +Signed-off-by: Hariprasad Kelam +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++--------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 00ef6d201b973..9b8a6046e6dff 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -1070,32 +1070,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, + rvu_write64(rvu, blkaddr, + NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action); + +- /* update the VF flow rule action with the VF default entry action */ +- if (mcam_index < 0) +- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, +- *(u64 *)&action); +- + /* update the action change in default rule */ + pfvf = rvu_get_pfvf(rvu, pcifunc); + if (pfvf->def_ucast_rule) + pfvf->def_ucast_rule->rx_action = action; + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_PROMISC_ENTRY); ++ if (mcam_index < 0) { ++ /* update the VF flow rule action with the VF default ++ * entry action ++ */ ++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, ++ *(u64 *)&action); + +- /* If PF's promiscuous entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_PROMISC_ENTRY); + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_ALLMULTI_ENTRY); +- /* If PF's allmulti entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ /* If PF's promiscuous entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_ALLMULTI_ENTRY); ++ /* If PF's allmulti entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ } + } + + void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, +-- +2.51.0 + diff --git a/queue-6.1/ping-annotate-data-races-in-ping_lookup.patch b/queue-6.1/ping-annotate-data-races-in-ping_lookup.patch new file mode 100644 index 0000000000..c4fd899356 --- /dev/null +++ b/queue-6.1/ping-annotate-data-races-in-ping_lookup.patch @@ -0,0 +1,118 @@ +From 308ea5f2a0f779b41f3637c85608d9d8b2e8e46b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:01:49 +0000 +Subject: ping: annotate data-races in ping_lookup() + +From: Eric Dumazet + +[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ] + +isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if +are read locklessly in ping_lookup(). + +Add READ_ONCE()/WRITE_ONCE() annotations. + +The race on isk->inet_rcv_saddr is probably coming from IPv6 support, +but does not deserve a specific backport. + +Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/ping.c | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index ee0e2df5d62e0..effe91a19a7a2 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -159,7 +159,7 @@ void ping_unhash(struct sock *sk) + pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); + spin_lock(&ping_table.lock); + if (sk_del_node_init_rcu(sk)) { +- isk->inet_num = 0; ++ WRITE_ONCE(isk->inet_num, 0); + isk->inet_sport = 0; + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + } +@@ -192,31 +192,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + } + + sk_for_each_rcu(sk, hslot) { ++ int bound_dev_if; ++ + if (!net_eq(sock_net(sk), net)) + continue; + isk = inet_sk(sk); + + pr_debug("iterate\n"); +- if (isk->inet_num != ident) ++ if (READ_ONCE(isk->inet_num) != ident) + continue; + ++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); + if (skb->protocol == htons(ETH_P_IP) && + sk->sk_family == AF_INET) { ++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr); ++ + pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk, +- (int) isk->inet_num, &isk->inet_rcv_saddr, +- sk->sk_bound_dev_if); ++ ident, &rcv_saddr, ++ bound_dev_if); + +- if (isk->inet_rcv_saddr && +- isk->inet_rcv_saddr != ip_hdr(skb)->daddr) ++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr) + continue; + #if IS_ENABLED(CONFIG_IPV6) + } else if (skb->protocol == htons(ETH_P_IPV6) && + sk->sk_family == AF_INET6) { + + pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk, +- (int) isk->inet_num, ++ ident, + &sk->sk_v6_rcv_saddr, +- sk->sk_bound_dev_if); ++ bound_dev_if); + + if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && + !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, +@@ -227,8 +231,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + continue; + } + +- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && +- sk->sk_bound_dev_if != sdif) ++ if (bound_dev_if && bound_dev_if != dif && ++ bound_dev_if != sdif) + continue; + + goto exit; +@@ -403,7 +407,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr) + if (saddr->sa_family == AF_INET) { + struct inet_sock *isk = inet_sk(sk); + struct sockaddr_in *addr = (struct sockaddr_in *) saddr; +- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr; ++ ++ isk->inet_saddr = addr->sin_addr.s_addr; ++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr); + #if IS_ENABLED(CONFIG_IPV6) + } else if (saddr->sa_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr; +@@ -865,7 +871,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, + struct sk_buff *skb; + int copied, err; + +- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); ++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, ++ READ_ONCE(isk->inet_num)); + + err = -EOPNOTSUPP; + if (flags & MSG_OOB) +-- +2.51.0 + diff --git a/queue-6.1/ping-convert-hlist_nulls-to-plain-hlist.patch b/queue-6.1/ping-convert-hlist_nulls-to-plain-hlist.patch new file mode 100644 index 0000000000..4c956c84bd --- /dev/null +++ b/queue-6.1/ping-convert-hlist_nulls-to-plain-hlist.patch @@ -0,0 +1,162 @@ +From 0e97fd963474046c32a5bbbcb5de5d483a810371 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 May 2023 14:54:43 -0700 +Subject: ping: Convert hlist_nulls to plain hlist. + +From: Kuniyuki Iwashima + +[ Upstream commit f1b5dfe63f6a9eb17948cbaee4da4b66f51ac794 ] + +Since introduced in commit c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP +socket kind"), ping socket does not use SLAB_TYPESAFE_BY_RCU nor check +nulls marker in loops. + +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Stable-dep-of: ad5dfde2a573 ("ping: annotate data-races in ping_lookup()") +Signed-off-by: Sasha Levin +--- + net/ipv4/ping.c | 41 +++++++++++++++-------------------------- + 1 file changed, 15 insertions(+), 26 deletions(-) + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index cadf743ab4f52..aae5ad6303a97 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -49,13 +49,8 @@ + #include + #endif + +-#define ping_portaddr_for_each_entry(__sk, node, list) \ +- hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node) +-#define ping_portaddr_for_each_entry_rcu(__sk, node, list) \ +- hlist_nulls_for_each_entry_rcu(__sk, node, list, sk_nulls_node) +- + struct ping_table { +- struct hlist_nulls_head hash[PING_HTABLE_SIZE]; ++ struct hlist_head hash[PING_HTABLE_SIZE]; + spinlock_t lock; + }; + +@@ -74,17 +69,16 @@ static inline u32 ping_hashfn(const struct net *net, u32 num, u32 mask) + } + EXPORT_SYMBOL_GPL(ping_hash); + +-static inline struct hlist_nulls_head *ping_hashslot(struct ping_table *table, +- struct net *net, unsigned int num) ++static inline struct hlist_head *ping_hashslot(struct ping_table *table, ++ struct net *net, unsigned int num) + { + return &table->hash[ping_hashfn(net, num, PING_HTABLE_MASK)]; + } + + int ping_get_port(struct sock *sk, unsigned short ident) + { +- struct hlist_nulls_node *node; +- struct hlist_nulls_head *hlist; + struct inet_sock *isk, *isk2; ++ struct hlist_head *hlist; + struct sock *sk2 = NULL; + + isk = inet_sk(sk); +@@ -98,7 +92,7 @@ int ping_get_port(struct sock *sk, unsigned short ident) + result++; /* avoid zero */ + hlist = ping_hashslot(&ping_table, sock_net(sk), + result); +- ping_portaddr_for_each_entry(sk2, node, hlist) { ++ sk_for_each(sk2, hlist) { + isk2 = inet_sk(sk2); + + if (isk2->inet_num == result) +@@ -115,7 +109,7 @@ int ping_get_port(struct sock *sk, unsigned short ident) + goto fail; + } else { + hlist = ping_hashslot(&ping_table, sock_net(sk), ident); +- ping_portaddr_for_each_entry(sk2, node, hlist) { ++ sk_for_each(sk2, hlist) { + isk2 = inet_sk(sk2); + + /* BUG? Why is this reuse and not reuseaddr? ping.c +@@ -133,9 +127,8 @@ int ping_get_port(struct sock *sk, unsigned short ident) + isk->inet_num = ident; + if (sk_unhashed(sk)) { + pr_debug("was not hashed\n"); +- sock_hold(sk); ++ sk_add_node_rcu(sk, hlist); + sock_set_flag(sk, SOCK_RCU_FREE); +- hlist_nulls_add_head_rcu(&sk->sk_nulls_node, hlist); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + } + spin_unlock(&ping_table.lock); +@@ -161,9 +154,7 @@ void ping_unhash(struct sock *sk) + + pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); + spin_lock(&ping_table.lock); +- if (sk_hashed(sk)) { +- hlist_nulls_del_init_rcu(&sk->sk_nulls_node); +- sock_put(sk); ++ if (sk_del_node_init_rcu(sk)) { + isk->inet_num = 0; + isk->inet_sport = 0; + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); +@@ -175,10 +166,9 @@ EXPORT_SYMBOL_GPL(ping_unhash); + /* Called under rcu_read_lock() */ + static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + { +- struct hlist_nulls_head *hslot = ping_hashslot(&ping_table, net, ident); ++ struct hlist_head *hslot = ping_hashslot(&ping_table, net, ident); + struct sock *sk = NULL; + struct inet_sock *isk; +- struct hlist_nulls_node *hnode; + int dif, sdif; + + if (skb->protocol == htons(ETH_P_IP)) { +@@ -197,7 +187,7 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + return NULL; + } + +- ping_portaddr_for_each_entry_rcu(sk, hnode, hslot) { ++ sk_for_each_rcu(sk, hslot) { + isk = inet_sk(sk); + + pr_debug("iterate\n"); +@@ -1043,15 +1033,14 @@ static struct sock *ping_get_first(struct seq_file *seq, int start) + + for (state->bucket = start; state->bucket < PING_HTABLE_SIZE; + ++state->bucket) { +- struct hlist_nulls_node *node; +- struct hlist_nulls_head *hslot; ++ struct hlist_head *hslot; + + hslot = &ping_table.hash[state->bucket]; + +- if (hlist_nulls_empty(hslot)) ++ if (hlist_empty(hslot)) + continue; + +- sk_nulls_for_each(sk, node, hslot) { ++ sk_for_each(sk, hslot) { + if (net_eq(sock_net(sk), net) && + sk->sk_family == state->family) + goto found; +@@ -1068,7 +1057,7 @@ static struct sock *ping_get_next(struct seq_file *seq, struct sock *sk) + struct net *net = seq_file_net(seq); + + do { +- sk = sk_nulls_next(sk); ++ sk = sk_next(sk); + } while (sk && (!net_eq(sock_net(sk), net))); + + if (!sk) +@@ -1204,6 +1193,6 @@ void __init ping_init(void) + int i; + + for (i = 0; i < PING_HTABLE_SIZE; i++) +- INIT_HLIST_NULLS_HEAD(&ping_table.hash[i], i); ++ INIT_HLIST_HEAD(&ping_table.hash[i]); + spin_lock_init(&ping_table.lock); + } +-- +2.51.0 + diff --git a/queue-6.1/s390-kconfig-sort-config-s390-select-list-again.patch b/queue-6.1/s390-kconfig-sort-config-s390-select-list-again.patch new file mode 100644 index 0000000000..1191935e89 --- /dev/null +++ b/queue-6.1/s390-kconfig-sort-config-s390-select-list-again.patch @@ -0,0 +1,54 @@ +From 95205166306b73bd8ff367fec4e3ecabeb19eff8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Mar 2023 09:41:06 +0100 +Subject: s390/Kconfig: sort config S390 select list again + +From: Heiko Carstens + +[ Upstream commit 6ca6b58107a8891e4b08087843188fdc5737ec08 ] + +Keep the config S390 select list sorted. + +Signed-off-by: Heiko Carstens +Stable-dep-of: dd3411959b57 ("s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n") +Signed-off-by: Sasha Levin +--- + arch/s390/Kconfig | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index ef87c38a7b841..bceed8361d051 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -120,8 +120,8 @@ config S390 + select ARCH_WANTS_DYNAMIC_TASK_STRUCT + select ARCH_WANTS_NO_INSTR + select ARCH_WANT_DEFAULT_BPF_JIT +- select ARCH_WANT_IPC_PARSE_VERSION + select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP ++ select ARCH_WANT_IPC_PARSE_VERSION + select BUILDTIME_TABLE_SORT + select CLONE_BACKWARDS2 + select DMA_OPS if PCI +@@ -194,6 +194,7 @@ config S390 + select HAVE_PERF_USER_STACK_DUMP + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_RELIABLE_STACKTRACE ++ select HAVE_RETHOOK + select HAVE_RSEQ + select HAVE_SAMPLE_FTRACE_DIRECT + select HAVE_SAMPLE_FTRACE_DIRECT_MULTI +@@ -203,9 +204,9 @@ config S390 + select HAVE_VIRT_CPU_ACCOUNTING_IDLE + select IOMMU_HELPER if PCI + select IOMMU_SUPPORT if PCI ++ select MMU_GATHER_MERGE_VMAS + select MMU_GATHER_NO_GATHER + select MMU_GATHER_RCU_TABLE_FREE +- select MMU_GATHER_MERGE_VMAS + select MODULES_USE_ELF_RELA + select NEED_DMA_MAP_STATE if PCI + select NEED_SG_DMA_LENGTH if PCI +-- +2.51.0 + diff --git a/queue-6.1/s390-kexec-make-kexec_sig-available-when-config_modu.patch b/queue-6.1/s390-kexec-make-kexec_sig-available-when-config_modu.patch new file mode 100644 index 0000000000..6ff57b2312 --- /dev/null +++ b/queue-6.1/s390-kexec-make-kexec_sig-available-when-config_modu.patch @@ -0,0 +1,61 @@ +From d0e348e682c13febce498f807c6fdd2f479087a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 07:29:16 +0100 +Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n + +From: Alexander Egorenkov + +[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ] + +The commit c8424e776b09 ("MODSIGN: Export module signature definitions") +replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the +dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390 +kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT. + +Furthermore, the signature verification in s390 kexec does not require +MODULE_SIG_FORMAT because it requires only the struct module_signature and, +therefore, does not depend on code in kernel/module_signature.c. + +But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is +also incorrect because it makes KEXEC_SIG available on s390 only if some +other arbitrary option (for instance a file system or device driver) +selects it directly or indirectly. + +To properly make KEXEC_SIG available for s390 kernels built with MODULES=y +as well as MODULES=n _and_ also not depend on arbitrary options selecting +SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select +SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y. + +Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions") +Suggested-by: Heiko Carstens +Signed-off-by: Alexander Egorenkov +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index 645ab7c065c8d..f0f96ae84cc70 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -219,6 +219,7 @@ config S390 + select SPARSE_IRQ + select SWIOTLB + select SYSCTL_EXCEPTION_TRACE ++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG + select THREAD_INFO_IN_TASK + select TRACE_IRQFLAGS_SUPPORT + select TTY +@@ -245,7 +246,7 @@ config ARCH_SUPPORTS_KEXEC_FILE + def_bool CRYPTO && CRYPTO_SHA256 && CRYPTO_SHA256_S390 + + config ARCH_SUPPORTS_KEXEC_SIG +- def_bool MODULE_SIG_FORMAT ++ def_bool y + + config ARCH_HAS_KEXEC_PURGATORY + def_bool KEXEC_FILE +-- +2.51.0 + diff --git a/queue-6.1/s390-kexec-refactor-for-kernel-kconfig.kexec.patch b/queue-6.1/s390-kexec-refactor-for-kernel-kconfig.kexec.patch new file mode 100644 index 0000000000..36a6a8cdbd --- /dev/null +++ b/queue-6.1/s390-kexec-refactor-for-kernel-kconfig.kexec.patch @@ -0,0 +1,128 @@ +From d6af6983bb2036fe740cb4127145d0fad0d5aa9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Jul 2023 12:15:43 -0400 +Subject: s390/kexec: refactor for kernel/Kconfig.kexec + +From: Eric DeVolder + +[ Upstream commit 75239cf775b811662f3a9e35e8ea0cd7a98e3fed ] + +The kexec and crash kernel options are provided in the common +kernel/Kconfig.kexec. Utilize the common options and provide +the ARCH_SUPPORTS_ and ARCH_SELECTS_ entries to recreate the +equivalent set of KEXEC and CRASH options. + +Link: https://lkml.kernel.org/r/20230712161545.87870-13-eric.devolder@oracle.com +Signed-off-by: Eric DeVolder +Acked-by: Alexander Gordeev +Signed-off-by: Andrew Morton +Stable-dep-of: dd3411959b57 ("s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n") +Signed-off-by: Sasha Levin +--- + arch/s390/Kconfig | 69 ++++++++++++++++------------------------------- + 1 file changed, 23 insertions(+), 46 deletions(-) + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index bceed8361d051..645ab7c065c8d 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -204,6 +204,7 @@ config S390 + select HAVE_VIRT_CPU_ACCOUNTING_IDLE + select IOMMU_HELPER if PCI + select IOMMU_SUPPORT if PCI ++ select KEXEC + select MMU_GATHER_MERGE_VMAS + select MMU_GATHER_NO_GATHER + select MMU_GATHER_RCU_TABLE_FREE +@@ -234,6 +235,28 @@ config PGTABLE_LEVELS + + source "kernel/livepatch/Kconfig" + ++config ARCH_DEFAULT_KEXEC ++ def_bool y ++ ++config ARCH_SUPPORTS_KEXEC ++ def_bool y ++ ++config ARCH_SUPPORTS_KEXEC_FILE ++ def_bool CRYPTO && CRYPTO_SHA256 && CRYPTO_SHA256_S390 ++ ++config ARCH_SUPPORTS_KEXEC_SIG ++ def_bool MODULE_SIG_FORMAT ++ ++config ARCH_HAS_KEXEC_PURGATORY ++ def_bool KEXEC_FILE ++ ++config ARCH_SUPPORTS_CRASH_DUMP ++ def_bool y ++ help ++ Refer to for more details on this. ++ This option also enables s390 zfcpdump. ++ See also ++ + menu "Processor type and features" + + config HAVE_MARCH_Z10_FEATURES +@@ -480,36 +503,6 @@ config SCHED_TOPOLOGY + + source "kernel/Kconfig.hz" + +-config KEXEC +- def_bool y +- select KEXEC_CORE +- +-config KEXEC_FILE +- bool "kexec file based system call" +- select KEXEC_CORE +- depends on CRYPTO +- depends on CRYPTO_SHA256 +- depends on CRYPTO_SHA256_S390 +- help +- Enable the kexec file based system call. In contrast to the normal +- kexec system call this system call takes file descriptors for the +- kernel and initramfs as arguments. +- +-config ARCH_HAS_KEXEC_PURGATORY +- def_bool y +- depends on KEXEC_FILE +- +-config KEXEC_SIG +- bool "Verify kernel signature during kexec_file_load() syscall" +- depends on KEXEC_FILE && MODULE_SIG_FORMAT +- help +- This option makes kernel signature verification mandatory for +- the kexec_file_load() syscall. +- +- In addition to that option, you need to enable signature +- verification for the corresponding kernel image type being +- loaded in order for this to work. +- + config KERNEL_NOBP + def_bool n + prompt "Enable modified branch prediction for the kernel by default" +@@ -728,22 +721,6 @@ config VFIO_AP + + endmenu + +-menu "Dump support" +- +-config CRASH_DUMP +- bool "kernel crash dumps" +- select KEXEC +- help +- Generate crash dump after being started by kexec. +- Crash dump kernels are loaded in the main kernel with kexec-tools +- into a specially reserved region and then later executed after +- a crash by kdump/kexec. +- Refer to for more details on this. +- This option also enables s390 zfcpdump. +- See also +- +-endmenu +- + config CCW + def_bool y + +-- +2.51.0 + diff --git a/queue-6.1/s390-select-arch_want_hugetlb_page_optimize_vmemmap.patch b/queue-6.1/s390-select-arch_want_hugetlb_page_optimize_vmemmap.patch new file mode 100644 index 0000000000..6d1ee3cc17 --- /dev/null +++ b/queue-6.1/s390-select-arch_want_hugetlb_page_optimize_vmemmap.patch @@ -0,0 +1,83 @@ +From 15f5cbe846e3035b2f30ae88bbf0d4f6c940711b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Jul 2022 11:08:37 +0200 +Subject: s390: select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP + +From: Gerald Schaefer + +[ Upstream commit 00a34d5a99c0631bd780b14cbe3813d0b39c3886 ] + +Enable HUGETLB_PAGE_OPTIMIZE_VMEMMAP for s390. + +With this, vmemmap pages used to back struct pages for compound tail +pages of hugetlb pages are freed and remapped to compound head page +frame as RO, see also Documentation/vm/vmemmap_dedup.rst. + +For 1M hugetlb pages, this results in freeing 3 of 4 vmemmap pages, +saving 12K of memory for each 1M hugetlb page (~1.2%). +/sys/kernel/debug/kernel_page_tables will show the impact: + +---[ vmemmap Area Start ]--- +[...] +0x0000037202d84000-0x0000037202d85000 4K PTE RW NX +0x0000037202d85000-0x0000037202d88000 12K PTE RO NX + +For 2G hugetlb pages, this results in freeing 8191 of 8192 vmemmap +pages, saving 32764K of memory for each 2G hugetlb page (~1.6%) +/sys/kernel/debug/kernel_page_tables will show the impact: + +---[ vmemmap Area Start ]--- +[...] +0x000003720a000000-0x000003720a001000 4K PTE RW NX +0x000003720a001000-0x000003720c000000 32764K PTE RO NX + +The memory savings come with some costs: +- vmemmap mapping for compound hugetlb pages is not a PMD mapping any + more, but split to 4K PTE mappings, and it will not be coalesced back + to PMD mapping after freeing hugetlb pages from the pool. + Apart from theoretical performance impact, this will also (slightly) + relativize the memory savings because of additional 2K PTE pagetable + allocations. +- Workload using "on the fly" hugetlb allocations via + "nr_overcommit_hugepages" instead of using the hugetlb pool via + "nr_hugepages" will suffer from considerably increased fault handling + time, see also description from commit 78f39084b41d + ("mm: hugetlb_vmemmap: add hugetlb_optimize_vmemmap sysctl"). +- Freeing hugetlb pages from the pool will require re-allocation of the + freed struct pages, and therefore needs some memory available to the + kernel. This might fail in memory constrained scenarios. +- For the same reason, memory offline might fail even for ZONE_MOVABLE + when hugetlb pages are present (but not for s390, since we do not + support ARCH_ENABLE_HUGEPAGE_MIGRATION, and therefore cannot have + hugetlb pages in ZONE_MOVABLE). +- General increased complexity and overhead in kernel handling of + compound (head) pages. + +Therefore, this feature is disabled by default, and has to be enabled +explicitly either by adding "hugetlb_free_vmemmap=on" kernel parameter, +or during run-time via "/proc/sys/vm/hugetlb_optimize_vmemmap" sysctl. + +Acked-by: Heiko Carstens +Signed-off-by: Gerald Schaefer +Signed-off-by: Alexander Gordeev +Stable-dep-of: dd3411959b57 ("s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n") +Signed-off-by: Sasha Levin +--- + arch/s390/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index de575af02ffea..ef87c38a7b841 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -121,6 +121,7 @@ config S390 + select ARCH_WANTS_NO_INSTR + select ARCH_WANT_DEFAULT_BPF_JIT + select ARCH_WANT_IPC_PARSE_VERSION ++ select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP + select BUILDTIME_TABLE_SORT + select CLONE_BACKWARDS2 + select DMA_OPS if PCI +-- +2.51.0 + diff --git a/queue-6.1/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch b/queue-6.1/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch new file mode 100644 index 0000000000..cc1b96b0a7 --- /dev/null +++ b/queue-6.1/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch @@ -0,0 +1,78 @@ +From 90cea357a2a3759175455e5615e39542609c040f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:05 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with + br_netfilter enabled + +From: Aleksei Oladko + +[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv4 packet contains a zero IP header checksum. After VXLAN +decapsulation, such packets do not pass sanity checks in br_netfilter +and are dropped, which causes the test to fail. + +Fix this by calculating and setting a valid IPv4 header checksum for the +encapsulated packet generated by mausezahn, so that the packet is accepted +by br_netfilter. Fixed by using the payload_template_calc_checksum() / +payload_template_expand_checksum() helpers that are only available +in v6.3 and newer kernels. + +Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index eb307ca37bfa6..002551451a728 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -559,6 +559,21 @@ vxlan_encapped_ping_do() + local inner_tos=$1; shift + local outer_tos=$1; shift + ++ local ipv4hdr=$(: ++ )"45:"$( : IP version + IHL ++ )"$inner_tos:"$( : IP TOS ++ )"00:54:"$( : IP total length ++ )"99:83:"$( : IP identification ++ )"40:00:"$( : IP flags + frag off ++ )"40:"$( : IP TTL ++ )"01:"$( : IP proto ++ )"CHECKSUM:"$( : IP header csum ++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 ++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1 ++ ) ++ local checksum=$(payload_template_calc_checksum "$ipv4hdr") ++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum) ++ + $MZ $dev -c $count -d 100msec -q \ + -b $next_hop_mac -B $dest_ip \ + -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(: +@@ -569,16 +584,7 @@ vxlan_encapped_ping_do() + )"$dest_mac:"$( : ETH daddr + )"$(mac_get w2):"$( : ETH saddr + )"08:00:"$( : ETH type +- )"45:"$( : IP version + IHL +- )"$inner_tos:"$( : IP TOS +- )"00:54:"$( : IP total length +- )"99:83:"$( : IP identification +- )"40:00:"$( : IP flags + frag off +- )"40:"$( : IP TTL +- )"01:"$( : IP proto +- )"00:00:"$( : IP header csum +- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 +- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 ++ )"$ipv4hdr:"$( : IPv4 header + )"08:"$( : ICMP type + )"00:"$( : ICMP code + )"8b:f2:"$( : ICMP csum +-- +2.51.0 + diff --git a/queue-6.1/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch b/queue-6.1/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch new file mode 100644 index 0000000000..75d579bc90 --- /dev/null +++ b/queue-6.1/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch @@ -0,0 +1,69 @@ +From 8fbd7b6fb4fc01665491deb8e05a1448e45db74f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:06 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with + br_netfilter enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Aleksei Oladko + +[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv6 packet has an incorrect payload length set in the IPv6 header. +After VXLAN decapsulation, such packets do not pass sanity checks in +br_netfilter and are dropped, which causes the test to fail. + +Fix this by setting the correct IPv6 payload length for the encapsulated +packet generated by mausezahn, so that the packet is accepted +by br_netfilter. + +tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +lines 698-706 + + )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + )"80:"$( : ICMPv6.type + )"00:"$( : ICMPv6.code + )"00:"$( : ICMPv6.checksum + ) + +Data after IPv6 header: +• 80: — 1 byte (ICMPv6 type) +• 00: — 1 byte (ICMPv6 code) +• 00: — 1 byte (ICMPv6 checksum, truncated) + +Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match +the actual payload size. + +Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +index bd3f7d492af2b..28284a5aa07a9 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +@@ -695,7 +695,7 @@ vxlan_encapped_ping_do() + )"6"$( : IP version + )"$inner_tos"$( : Traffic class + )"0:00:00:"$( : Flow label +- )"00:08:"$( : Payload length ++ )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr +-- +2.51.0 + diff --git a/queue-6.1/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch b/queue-6.1/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch new file mode 100644 index 0000000000..628ebccc7d --- /dev/null +++ b/queue-6.1/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch @@ -0,0 +1,57 @@ +From 4019b487622092c4074ba5c2b1ed32893e10c8f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 14:53:53 +0100 +Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2 + +From: Ido Schimmel + +[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ] + +As explained in [1], iproute2 started rejecting tc-police burst sizes +that result in an overflow. This can happen when the burst size is high +enough and the rate is low enough. + +A couple of test cases specify such configurations, resulting in +iproute2 errors and test failure. + +Fix by reducing the burst size so that the test will pass with both new +and old iproute2 versions. + +[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/ + +Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions") +Signed-off-by: Ido Schimmel +Signed-off-by: Petr Machata +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +index 0441a18f098b1..aac8ef490feb8 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +@@ -317,7 +317,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 0.5kbit burst 1m conform-exceed drop/ok ++ action police rate 0.5kbit burst 2k conform-exceed drop/ok + check_fail $? "Incorrect success to add police action with too low rate" + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ +@@ -327,7 +327,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 1.5kbit burst 1m conform-exceed drop/ok ++ action police rate 1.5kbit burst 2k conform-exceed drop/ok + check_err $? "Failed to add police action with low rate" + + tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower +-- +2.51.0 + diff --git a/queue-6.1/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch b/queue-6.1/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch new file mode 100644 index 0000000000..44b4d1528e --- /dev/null +++ b/queue-6.1/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch @@ -0,0 +1,57 @@ +From ad1fbdecce232b59495a7e35fa36c013798caf83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:51:59 -0800 +Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout + +From: Jakub Kicinski + +[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ] + +Since we started running selftests in NIPA we have been seeing +tc_actions.sh generate a soft lockup warning on ~20% of the runs. +On the pre-netdev foundation setup it was actually a missed irq +splat from the console. Now it's either that or a lockup. + +I initially suspected a socket locking issue since the test +is exercising local loopback with act_mirred. +After hours of staring at this I noticed in strace that ncat +when -o $file is specified _both_ saves the output to the file +and still prints it to stdout. Because the file being sent +is constructed with: + + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred + ^^^^^^^^^ + +the data printed is all \0. Most terminals don't display nul +characters (and neither does vng output capture save them). +But QEMU's serial console still has to poke them thru which +is very slow and causes the lockup (if the file is >600kB). + +Replace the '-o $file' with '> $file'. This speeds the test up +from 2m20s to 18s on debug kernels, and prevents the warnings. + +Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index b0f5e55d2d0b2..0d891c2045802 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -222,7 +222,7 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & ++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 & + local rpid=$! + ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid +-- +2.51.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 6437e62eff..850d90e05e 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -199,3 +199,46 @@ io_uring-cancel-fix-sequence-matching-for-ioring_asy.patch io_uring-cancel-add-ioring_async_cancel_userdata.patch io_uring-cancel-support-opcode-based-lookup-and-canc.patch io_uring-cancel-de-unionize-file-and-user_data-in-st.patch +fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch +fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch +acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch +acpi-pm-add-unused-power-resource-quirk-for-thundero.patch +cpuidle-skip-governor-when-only-one-idle-state-is-av.patch +selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch +net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch +net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch +net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch +net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch +net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch +net-usb-catc-enable-basic-endpoint-checking.patch +xen-netback-reject-zero-queue-configuration-from-gue.patch +net-rds-rds_sendmsg-should-not-discard-payload_len.patch +selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch +selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch +netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch +net-remove-warn_on_once-when-accessing-forward-path-.patch +netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch +ipv6-fix-a-race-in-ip6_sock_set_v6only.patch +bpftool-fix-truncated-netlink-dumps.patch +ping-convert-hlist_nulls-to-plain-hlist.patch +inet-ping-check-sock_net-in-ping_get_port-and-ping_l.patch +ping-annotate-data-races-in-ping_lookup.patch +selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch +macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch +icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch +icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch +icmp-prevent-possible-overflow-in-icmp_global_allow.patch +octeontx2-af-fix-default-entries-mcam-entry-action.patch +bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch +apparmor-fix-null-sock-in-aa_sock_file_perm.patch +apparmor-fix-rlimit-for-posix-cpu-timers.patch +apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch +asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch +drm-i915-acpi-free-_dsm-package-when-no-connectors.patch +s390-select-arch_want_hugetlb_page_optimize_vmemmap.patch +s390-kconfig-sort-config-s390-select-list-again.patch +s390-kexec-refactor-for-kernel-kconfig.kexec.patch +s390-kexec-make-kexec_sig-available-when-config_modu.patch +btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch +asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch +drm-amd-display-use-same-max-plane-scaling-limits-fo.patch diff --git a/queue-6.1/xen-netback-reject-zero-queue-configuration-from-gue.patch b/queue-6.1/xen-netback-reject-zero-queue-configuration-from-gue.patch new file mode 100644 index 0000000000..ba7c408723 --- /dev/null +++ b/queue-6.1/xen-netback-reject-zero-queue-configuration-from-gue.patch @@ -0,0 +1,57 @@ +From 83ac40857e452e5d2cedb9274b64a24790ef09d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:40:40 +0000 +Subject: xen-netback: reject zero-queue configuration from guest + +From: Ziyi Guo + +[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ] + +A malicious or buggy Xen guest can write "0" to the xenbus key +"multi-queue-num-queues". The connect() function in the backend only +validates the upper bound (requested_num_queues > xenvif_max_queues) +but not zero, allowing requested_num_queues=0 to reach +vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers +WARN_ON_ONCE(!size) in __vmalloc_node_range(). + +On systems with panic_on_warn=1, this allows a guest-to-host denial +of service. + +The Xen network interface specification requires +the queue count to be "greater than zero". + +Add a zero check to match the validation already present +in xen-blkback, which has included this +guard since its multi-queue support was added. + +Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues") +Signed-off-by: Ziyi Guo +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/xen-netback/xenbus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index 001636901ddae..a972b05da96fc 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -735,10 +735,11 @@ static void connect(struct backend_info *be) + */ + requested_num_queues = xenbus_read_unsigned(dev->otherend, + "multi-queue-num-queues", 1); +- if (requested_num_queues > xenvif_max_queues) { ++ if (requested_num_queues > xenvif_max_queues || ++ requested_num_queues == 0) { + /* buggy or malicious guest */ + xenbus_dev_fatal(dev, -EINVAL, +- "guest requested %u queues, exceeding the maximum of %u.", ++ "guest requested %u queues, but valid range is 1 - %u.", + requested_num_queues, xenvif_max_queues); + return; + } +-- +2.51.0 + diff --git a/queue-6.12/acpi-button-adjust-event-notification-routines.patch b/queue-6.12/acpi-button-adjust-event-notification-routines.patch new file mode 100644 index 0000000000..4403af9fad --- /dev/null +++ b/queue-6.12/acpi-button-adjust-event-notification-routines.patch @@ -0,0 +1,262 @@ +From 6a8ae58a1af4312d98a416626d5624a34584cab6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Dec 2025 14:55:09 +0100 +Subject: ACPI: button: Adjust event notification routines + +From: Rafael J. Wysocki + +[ Upstream commit 93dc5db6d47aaa3b4b458ddfddfa3369c24e22f4 ] + +Adjust the event notification routines in the ACPI button driver to +take a struct acpi_button pointer as an argument istead of a struct +acpi_device one where applicable, which allows the use of +acpi_driver_data() to be limited and will facilitate subsequent +changes. + +No intentional functional impact. + +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/2260995.Icojqenx9y@rafael.j.wysocki +Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe") +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 67 +++++++++++++++++++++---------------------- + 1 file changed, 33 insertions(+), 34 deletions(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 3c6dd9b4ba0ad..09a6e4ffe9f20 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -169,6 +169,7 @@ static struct acpi_driver acpi_button_driver = { + }; + + struct acpi_button { ++ struct acpi_device *adev; + unsigned int type; + struct input_dev *input; + char phys[32]; /* for input device */ +@@ -202,9 +203,9 @@ static int acpi_lid_evaluate_state(struct acpi_device *device) + return lid_state ? 1 : 0; + } + +-static int acpi_lid_notify_state(struct acpi_device *device, int state) ++static int acpi_lid_notify_state(struct acpi_button *button, int state) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + ktime_t next_report; + bool do_update; + +@@ -287,18 +288,18 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) + static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq, + void *offset) + { +- struct acpi_device *device = seq->private; ++ struct acpi_button *button = seq->private; + int state; + +- state = acpi_lid_evaluate_state(device); ++ state = acpi_lid_evaluate_state(button->adev); + seq_printf(seq, "state: %s\n", + state < 0 ? "unsupported" : (state ? "open" : "closed")); + return 0; + } + +-static int acpi_button_add_fs(struct acpi_device *device) ++static int acpi_button_add_fs(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + struct proc_dir_entry *entry = NULL; + int ret = 0; + +@@ -333,7 +334,7 @@ static int acpi_button_add_fs(struct acpi_device *device) + /* create /proc/acpi/button/lid/LID/state */ + entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO, + acpi_device_dir(device), acpi_button_state_seq_show, +- device); ++ button); + if (!entry) { + ret = -ENODEV; + goto remove_dev_dir; +@@ -355,9 +356,9 @@ static int acpi_button_add_fs(struct acpi_device *device) + goto done; + } + +-static int acpi_button_remove_fs(struct acpi_device *device) ++static int acpi_button_remove_fs(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + + if (button->type != ACPI_BUTTON_TYPE_LID) + return 0; +@@ -385,9 +386,10 @@ int acpi_lid_open(void) + } + EXPORT_SYMBOL(acpi_lid_open); + +-static int acpi_lid_update_state(struct acpi_device *device, ++static int acpi_lid_update_state(struct acpi_button *button, + bool signal_wakeup) + { ++ struct acpi_device *device = button->adev; + int state; + + state = acpi_lid_evaluate_state(device); +@@ -397,19 +399,17 @@ static int acpi_lid_update_state(struct acpi_device *device, + if (state && signal_wakeup) + acpi_pm_wakeup_event(&device->dev); + +- return acpi_lid_notify_state(device, state); ++ return acpi_lid_notify_state(button, state); + } + +-static void acpi_lid_initialize_state(struct acpi_device *device) ++static void acpi_lid_initialize_state(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); +- + switch (lid_init_state) { + case ACPI_BUTTON_LID_INIT_OPEN: +- (void)acpi_lid_notify_state(device, 1); ++ (void)acpi_lid_notify_state(button, 1); + break; + case ACPI_BUTTON_LID_INIT_METHOD: +- (void)acpi_lid_update_state(device, false); ++ (void)acpi_lid_update_state(button, false); + break; + case ACPI_BUTTON_LID_INIT_IGNORE: + default: +@@ -421,8 +421,8 @@ static void acpi_lid_initialize_state(struct acpi_device *device) + + static void acpi_lid_notify(acpi_handle handle, u32 event, void *data) + { +- struct acpi_device *device = data; +- struct acpi_button *button; ++ struct acpi_button *button = data; ++ struct acpi_device *device = button->adev; + + if (event != ACPI_BUTTON_NOTIFY_STATUS) { + acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", +@@ -430,17 +430,16 @@ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data) + return; + } + +- button = acpi_driver_data(device); + if (!button->lid_state_initialized) + return; + +- acpi_lid_update_state(device, true); ++ acpi_lid_update_state(button, true); + } + + static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + { +- struct acpi_device *device = data; +- struct acpi_button *button; ++ struct acpi_button *button = data; ++ struct acpi_device *device = button->adev; + struct input_dev *input; + int keycode; + +@@ -457,7 +456,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + + acpi_pm_wakeup_event(&device->dev); + +- button = acpi_driver_data(device); + if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) + return; + +@@ -505,7 +503,7 @@ static int acpi_button_resume(struct device *dev) + if (button->type == ACPI_BUTTON_TYPE_LID) { + button->last_state = !!acpi_lid_evaluate_state(device); + button->last_time = ktime_get(); +- acpi_lid_initialize_state(device); ++ acpi_lid_initialize_state(button); + } + + if (button->type == ACPI_BUTTON_TYPE_POWER) { +@@ -521,12 +519,12 @@ static int acpi_button_resume(struct device *dev) + + static int acpi_lid_input_open(struct input_dev *input) + { +- struct acpi_device *device = input_get_drvdata(input); +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_button *button = input_get_drvdata(input); ++ struct acpi_device *device = button->adev; + + button->last_state = !!acpi_lid_evaluate_state(device); + button->last_time = ktime_get(); +- acpi_lid_initialize_state(device); ++ acpi_lid_initialize_state(button); + + return 0; + } +@@ -551,6 +549,7 @@ static int acpi_button_add(struct acpi_device *device) + + device->driver_data = button; + ++ button->adev = device; + button->input = input = input_allocate_device(); + if (!input) { + error = -ENOMEM; +@@ -587,7 +586,7 @@ static int acpi_button_add(struct acpi_device *device) + } + + if (!error) +- error = acpi_button_add_fs(device); ++ error = acpi_button_add_fs(button); + + if (error) { + input_free_device(input); +@@ -617,7 +616,7 @@ static int acpi_button_add(struct acpi_device *device) + break; + } + +- input_set_drvdata(input, device); ++ input_set_drvdata(input, button); + error = input_register_device(input); + if (error) { + input_free_device(input); +@@ -628,17 +627,17 @@ static int acpi_button_add(struct acpi_device *device) + case ACPI_BUS_TYPE_POWER_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_button_event, +- device); ++ button); + break; + case ACPI_BUS_TYPE_SLEEP_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_button_event, +- device); ++ button); + break; + default: + status = acpi_install_notify_handler(device->handle, + ACPI_ALL_NOTIFY, handler, +- device); ++ button); + break; + } + if (ACPI_FAILURE(status)) { +@@ -661,7 +660,7 @@ static int acpi_button_add(struct acpi_device *device) + err_input_unregister: + input_unregister_device(input); + err_remove_fs: +- acpi_button_remove_fs(device); ++ acpi_button_remove_fs(button); + err_free_button: + kfree(button); + return error; +@@ -689,7 +688,7 @@ static void acpi_button_remove(struct acpi_device *device) + } + acpi_os_wait_events_complete(); + +- acpi_button_remove_fs(device); ++ acpi_button_remove_fs(button); + input_unregister_device(button->input); + kfree(button); + } +-- +2.51.0 + diff --git a/queue-6.12/acpi-button-call-device_init_wakeup-earlier-during-p.patch b/queue-6.12/acpi-button-call-device_init_wakeup-earlier-during-p.patch new file mode 100644 index 0000000000..2cfd41c1a2 --- /dev/null +++ b/queue-6.12/acpi-button-call-device_init_wakeup-earlier-during-p.patch @@ -0,0 +1,67 @@ +From 9064761fe082ebf68c6b4f05799c6c7a80afa943 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 15:13:26 +0100 +Subject: ACPI: button: Call device_init_wakeup() earlier during probe + +From: Rafael J. Wysocki + +[ Upstream commit e91f8c5305b92b63c8bac315f95c535d5c1e8fec ] + +Calling device_init_wakeup() after installing a notify handler in which +wakeup events are signaled may cause a wakeup event to be missed if the +device is probed right before a system suspend. + +To avoid this, move the device_init_wakeup() call in acpi_button_probe() +before the notify handler installation and add a corresponding cleanup +to the error path. + +Also carry out wakeup cleanup for the button in acpi_button_remove() +because after that point the notify handler will not run for it and +wakeup events coming from it will not be signaled. + +Fixes: 0d51157dfaac ("ACPI: button: Eliminate the driver notify callback") +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/12854922.O9o76ZdvQC@rafael.j.wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index b899b8745fedd..38bc64d6bdaf3 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -625,6 +625,8 @@ static int acpi_button_probe(struct platform_device *pdev) + goto err_remove_fs; + } + ++ device_init_wakeup(&pdev->dev, true); ++ + switch (device->device_type) { + case ACPI_BUS_TYPE_POWER_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, +@@ -655,11 +657,11 @@ static int acpi_button_probe(struct platform_device *pdev) + lid_device = device; + } + +- device_init_wakeup(&pdev->dev, true); + pr_info("%s [%s]\n", name, acpi_device_bid(device)); + return 0; + + err_input_unregister: ++ device_init_wakeup(&pdev->dev, false); + input_unregister_device(input); + err_remove_fs: + acpi_button_remove_fs(button); +@@ -691,6 +693,8 @@ static void acpi_button_remove(struct platform_device *pdev) + } + acpi_os_wait_events_complete(); + ++ device_init_wakeup(&pdev->dev, false); ++ + acpi_button_remove_fs(button); + input_unregister_device(button->input); + kfree(button); +-- +2.51.0 + diff --git a/queue-6.12/acpi-button-convert-the-driver-to-a-platform-one.patch b/queue-6.12/acpi-button-convert-the-driver-to-a-platform-one.patch new file mode 100644 index 0000000000..d9a0587316 --- /dev/null +++ b/queue-6.12/acpi-button-convert-the-driver-to-a-platform-one.patch @@ -0,0 +1,211 @@ +From 6ce5fd8429d01ae657c5536d6605406e1cdc3036 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Dec 2025 14:57:57 +0100 +Subject: ACPI: button: Convert the driver to a platform one + +From: Rafael J. Wysocki + +[ Upstream commit 52d86401963666423cb9a56d117136c846093db0 ] + +While binding drivers directly to struct acpi_device objects allows +basic functionality to be provided, at least in the majority of cases, +there are some problems with it, related to general consistency, sysfs +layout, power management operation ordering, and code cleanliness. + +Overall, it is better to bind drivers to platform devices than to their +ACPI companions, so convert the ACPI button driver to a platform one. + +While this is not expected to alter functionality, it changes sysfs +layout and so it will be visible to user space. + +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/2461734.NG923GbCHz@rafael.j.wysocki +Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe") +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 61 +++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 29 deletions(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 09a6e4ffe9f20..b899b8745fedd 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + + #define ACPI_BUTTON_CLASS "button" +@@ -145,8 +146,8 @@ static const struct dmi_system_id dmi_lid_quirks[] = { + {} + }; + +-static int acpi_button_add(struct acpi_device *device); +-static void acpi_button_remove(struct acpi_device *device); ++static int acpi_button_probe(struct platform_device *pdev); ++static void acpi_button_remove(struct platform_device *pdev); + + #ifdef CONFIG_PM_SLEEP + static int acpi_button_suspend(struct device *dev); +@@ -157,19 +158,19 @@ static int acpi_button_resume(struct device *dev); + #endif + static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume); + +-static struct acpi_driver acpi_button_driver = { +- .name = "button", +- .class = ACPI_BUTTON_CLASS, +- .ids = button_device_ids, +- .ops = { +- .add = acpi_button_add, +- .remove = acpi_button_remove, ++static struct platform_driver acpi_button_driver = { ++ .probe = acpi_button_probe, ++ .remove = acpi_button_remove, ++ .driver = { ++ .name = "acpi-button", ++ .acpi_match_table = button_device_ids, ++ .pm = &acpi_button_pm, + }, +- .drv.pm = &acpi_button_pm, + }; + + struct acpi_button { + struct acpi_device *adev; ++ struct platform_device *pdev; + unsigned int type; + struct input_dev *input; + char phys[32]; /* for input device */ +@@ -397,7 +398,7 @@ static int acpi_lid_update_state(struct acpi_button *button, + return state; + + if (state && signal_wakeup) +- acpi_pm_wakeup_event(&device->dev); ++ acpi_pm_wakeup_event(&button->pdev->dev); + + return acpi_lid_notify_state(button, state); + } +@@ -454,7 +455,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + return; + } + +- acpi_pm_wakeup_event(&device->dev); ++ acpi_pm_wakeup_event(&button->pdev->dev); + + if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) + return; +@@ -486,8 +487,7 @@ static u32 acpi_button_event(void *data) + #ifdef CONFIG_PM_SLEEP + static int acpi_button_suspend(struct device *dev) + { +- struct acpi_device *device = to_acpi_device(dev); +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_button *button = dev_get_drvdata(dev); + + button->suspended = true; + return 0; +@@ -495,9 +495,9 @@ static int acpi_button_suspend(struct device *dev) + + static int acpi_button_resume(struct device *dev) + { ++ struct acpi_button *button = dev_get_drvdata(dev); ++ struct acpi_device *device = ACPI_COMPANION(dev); + struct input_dev *input; +- struct acpi_device *device = to_acpi_device(dev); +- struct acpi_button *button = acpi_driver_data(device); + + button->suspended = false; + if (button->type == ACPI_BUTTON_TYPE_LID) { +@@ -529,8 +529,9 @@ static int acpi_lid_input_open(struct input_dev *input) + return 0; + } + +-static int acpi_button_add(struct acpi_device *device) ++static int acpi_button_probe(struct platform_device *pdev) + { ++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev); + acpi_notify_handler handler; + struct acpi_button *button; + struct input_dev *input; +@@ -547,8 +548,9 @@ static int acpi_button_add(struct acpi_device *device) + if (!button) + return -ENOMEM; + +- device->driver_data = button; ++ platform_set_drvdata(pdev, button); + ++ button->pdev = pdev; + button->adev = device; + button->input = input = input_allocate_device(); + if (!input) { +@@ -599,7 +601,7 @@ static int acpi_button_add(struct acpi_device *device) + input->phys = button->phys; + input->id.bustype = BUS_HOST; + input->id.product = button->type; +- input->dev.parent = &device->dev; ++ input->dev.parent = &pdev->dev; + + switch (button->type) { + case ACPI_BUTTON_TYPE_POWER: +@@ -653,7 +655,7 @@ static int acpi_button_add(struct acpi_device *device) + lid_device = device; + } + +- device_init_wakeup(&device->dev, true); ++ device_init_wakeup(&pdev->dev, true); + pr_info("%s [%s]\n", name, acpi_device_bid(device)); + return 0; + +@@ -666,9 +668,10 @@ static int acpi_button_add(struct acpi_device *device) + return error; + } + +-static void acpi_button_remove(struct acpi_device *device) ++static void acpi_button_remove(struct platform_device *pdev) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev); ++ struct acpi_button *button = platform_get_drvdata(pdev); + + switch (device->device_type) { + case ACPI_BUS_TYPE_POWER_BUTTON: +@@ -727,7 +730,7 @@ module_param_call(lid_init_state, + NULL, 0644); + MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state"); + +-static int acpi_button_register_driver(struct acpi_driver *driver) ++static int __init acpi_button_init(void) + { + const struct dmi_system_id *dmi_id; + +@@ -743,20 +746,20 @@ static int acpi_button_register_driver(struct acpi_driver *driver) + * Modules such as nouveau.ko and i915.ko have a link time dependency + * on acpi_lid_open(), and would therefore not be loadable on ACPI + * capable kernels booted in non-ACPI mode if the return value of +- * acpi_bus_register_driver() is returned from here with ACPI disabled ++ * platform_driver_register() is returned from here with ACPI disabled + * when this driver is built as a module. + */ + if (acpi_disabled) + return 0; + +- return acpi_bus_register_driver(driver); ++ return platform_driver_register(&acpi_button_driver); + } + +-static void acpi_button_unregister_driver(struct acpi_driver *driver) ++static void __exit acpi_button_exit(void) + { + if (!acpi_disabled) +- acpi_bus_unregister_driver(driver); ++ platform_driver_unregister(&acpi_button_driver); + } + +-module_driver(acpi_button_driver, acpi_button_register_driver, +- acpi_button_unregister_driver); ++module_init(acpi_button_init); ++module_exit(acpi_button_exit); +-- +2.51.0 + diff --git a/queue-6.12/acpi-button-install-notifier-for-system-events-as-we.patch b/queue-6.12/acpi-button-install-notifier-for-system-events-as-we.patch new file mode 100644 index 0000000000..d33cf9af31 --- /dev/null +++ b/queue-6.12/acpi-button-install-notifier-for-system-events-as-we.patch @@ -0,0 +1,76 @@ +From b61cd528a0a6ee4360fa1690867410116cb9f211 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 15:27:09 -0600 +Subject: ACPI: button: Install notifier for system events as well + +From: Mario Limonciello + +[ Upstream commit a7e23ec17feecc7bac0d500cea900cace7b50129 ] + +On some systems when the system is put to sleep pressing the ACPI power +button will cause the EC SCI to try to wake the system by a Notify(DEV, 0x2) +with an intention to wake the system up from suspend. + +This behavior matches the ACPI specification in ACPI 6.4 section +4.8.3.1.1.2 which describes that the AML handler would generate a Notify() +with a code of 0x2 to indicate it was responsible for waking the system. + +This currently doesn't work because acpi_button_add() only configured +`ACPI_DEVICE_NOTIFY` which means that device handler notifications +0x80 through 0xFF are handled. + +To fix the wakeups on such systems, adjust the ACPI button handler to +use `ACPI_ALL_NOTIFY` which will handle all events 0x00 through 0x7F. + +Reported-by: Yijun Shen +Tested-by: Richard Gong +Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/04_ACPI_Hardware_Specification/ACPI_Hardware_Specification.html?highlight=0x2#control-method-power-button +Signed-off-by: Mario Limonciello +Tested-by: Yijun Shen +Link: https://patch.msgid.link/20250303212719.4153485-1-superm1@kernel.org +[ rjw: Removed uneeded semicolon ] +Signed-off-by: Rafael J. Wysocki +Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe") +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 6d7c413982167..7c45b5dc2da73 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -24,6 +24,7 @@ + #define ACPI_BUTTON_CLASS "button" + #define ACPI_BUTTON_FILE_STATE "state" + #define ACPI_BUTTON_TYPE_UNKNOWN 0x00 ++#define ACPI_BUTTON_NOTIFY_WAKE 0x02 + #define ACPI_BUTTON_NOTIFY_STATUS 0x80 + + #define ACPI_BUTTON_SUBCLASS_POWER "power" +@@ -443,7 +444,12 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + struct input_dev *input; + int keycode; + +- if (event != ACPI_BUTTON_NOTIFY_STATUS) { ++ switch (event) { ++ case ACPI_BUTTON_NOTIFY_STATUS: ++ break; ++ case ACPI_BUTTON_NOTIFY_WAKE: ++ break; ++ default: + acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", + event); + return; +@@ -631,7 +637,7 @@ static int acpi_button_add(struct acpi_device *device) + break; + default: + status = acpi_install_notify_handler(device->handle, +- ACPI_DEVICE_NOTIFY, handler, ++ ACPI_ALL_NOTIFY, handler, + device); + break; + } +-- +2.51.0 + diff --git a/queue-6.12/acpi-button-only-send-key_power-for-acpi_button_noti.patch b/queue-6.12/acpi-button-only-send-key_power-for-acpi_button_noti.patch new file mode 100644 index 0000000000..810f924838 --- /dev/null +++ b/queue-6.12/acpi-button-only-send-key_power-for-acpi_button_noti.patch @@ -0,0 +1,50 @@ +From 324f3ad8127ce1ca957c4f1ad1c14d3fa2bd7860 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Apr 2025 09:50:22 -0500 +Subject: ACPI: button: Only send `KEY_POWER` for `ACPI_BUTTON_NOTIFY_STATUS` + +From: Mario Limonciello + +[ Upstream commit a8605b0ed187f53f077a769ce2b52ddb97f3eb42 ] + +Commit a7e23ec17feec ("ACPI: button: Install notifier for system +events as well") modified the ACPI button behavior to send +`ACPI_BUTTON_NOTIFY_WAKE` events. + +This caused a regression on Dell Optiplex 3040 sending `KEY_POWER` +randomly at runtime. + +Adjust logic so that the `ACPI_BUTTON_NOTIFY_WAKE` event will never +send `KEY_POWER`. + +Fixes: a7e23ec17feec ("ACPI: button: Install notifier for system events as well") +Reported-by: Ian Laurie +Closes: https://lore.kernel.org/linux-acpi/CAJZ5v0hbA6bqxHupTh4NZR-GVSb9M5RL7JSb2yQgvYYJg+z2aQ@mail.gmail.com/T/#md8071e480212201f23e4929607386750d3b6bc13 +Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2357044 +Signed-off-by: Mario Limonciello +Tested-by: Ian Laurie +Link: https://patch.msgid.link/20250404145034.2608574-1-superm1@kernel.org +[ rjw: Changelog edits ] +Signed-off-by: Rafael J. Wysocki +Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe") +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 7c45b5dc2da73..3c6dd9b4ba0ad 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -458,7 +458,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + acpi_pm_wakeup_event(&device->dev); + + button = acpi_driver_data(device); +- if (button->suspended) ++ if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) + return; + + input = button->input; +-- +2.51.0 + diff --git a/queue-6.12/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch b/queue-6.12/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch new file mode 100644 index 0000000000..f24022e926 --- /dev/null +++ b/queue-6.12/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch @@ -0,0 +1,55 @@ +From 45d8f2791ce9698768971a6a80d51186e6329729 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 21:22:54 +0000 +Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs + +From: Sean V Kelley + +[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ] + +per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online +CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> +acpi_cppc_processor_probe(). + +However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all +possible CPUs. In acpi_get_psd_map(), encountering an offline CPU +returns -EFAULT, causing cppc_cpufreq initialization to fail. + +This breaks systems booted with "nosmt" or "nosmt=force". + +Fix by using for_each_online_cpu() in both functions. + +Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests") +Signed-off-by: Sean V Kelley +Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index 1e8e2002f81af..c90121cae628a 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -349,7 +349,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) + end: + if (cmd == CMD_WRITE) { + if (unlikely(ret)) { +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i); + + if (!desc) +@@ -511,7 +511,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data) + else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) + cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; + +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + if (i == cpu) + continue; + +-- +2.51.0 + diff --git a/queue-6.12/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch b/queue-6.12/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch new file mode 100644 index 0000000000..13b52f7789 --- /dev/null +++ b/queue-6.12/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch @@ -0,0 +1,67 @@ +From c4d4eeba9f998d5b57f5dea554047af304d8dc0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Feb 2026 00:14:52 +0800 +Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO + +From: Zhai Can + +[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ] + +On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete +NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table +bug (lack of reference), PXP will be shut dow as an "unused" power resource +during initialization, making the NVMe slot #2 + NVIDIA both inaccessible. + +This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check +states of power resources during initialization"). Here are test +results on the three consecutive commits: + +(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization +(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state +(bad) 519d81956ee2 Linux 5.15-rc6 + +On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in +unknown state") this was not an issue because the power resource state +left UNKNOWN thus being ignored. + +See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power +resources on the Toshiba Click Mini") which is another almost identical +case to this one. + +Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization") +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087 +Signed-off-by: Zhai Can +Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/power.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c +index c2c70139c4f1d..ff5fcd541e50f 100644 +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -1035,6 +1035,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"), + }, + }, ++ { ++ /* ++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power ++ * resource 'PXP' will be shut down on initialization, making ++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're ++ * both controlled by 'PXP'). ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"), ++ } ++ ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.12/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch b/queue-6.12/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch new file mode 100644 index 0000000000..9b82e49c2d --- /dev/null +++ b/queue-6.12/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch @@ -0,0 +1,108 @@ +From 1ad6696bb01b57981666096931ecdfb8a2d1080e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:11:07 +0100 +Subject: AppArmor: Allow apparmor to handle unaligned dfa tables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Helge Deller + +[ Upstream commit 64802f731214a51dfe3c6c27636b3ddafd003eb0 ] + +The dfa tables can originate from kernel or userspace and 8-byte alignment +isn't always guaranteed and as such may trigger unaligned memory accesses +on various architectures. Resulting in the following + +[   73.901376] WARNING: CPU: 0 PID: 341 at security/apparmor/match.c:316 aa_dfa_unpack+0x6cc/0x720 +[   74.015867] Modules linked in: binfmt_misc evdev flash sg drm drm_panel_orientation_quirks backlight i2c_core configfs nfnetlink autofs4 ext4 crc16 mbcache jbd2 hid_generic usbhid sr_mod hid cdrom +sd_mod ata_generic ohci_pci ehci_pci ehci_hcd ohci_hcd pata_ali libata sym53c8xx scsi_transport_spi tg3 scsi_mod usbcore libphy scsi_common mdio_bus usb_common +[   74.428977] CPU: 0 UID: 0 PID: 341 Comm: apparmor_parser Not tainted 6.18.0-rc6+ #9 NONE +[   74.536543] Call Trace: +[   74.568561] [<0000000000434c24>] dump_stack+0x8/0x18 +[   74.633757] [<0000000000476438>] __warn+0xd8/0x100 +[   74.696664] [<00000000004296d4>] warn_slowpath_fmt+0x34/0x74 +[   74.771006] [<00000000008db28c>] aa_dfa_unpack+0x6cc/0x720 +[   74.843062] [<00000000008e643c>] unpack_pdb+0xbc/0x7e0 +[   74.910545] [<00000000008e7740>] unpack_profile+0xbe0/0x1300 +[   74.984888] [<00000000008e82e0>] aa_unpack+0xe0/0x6a0 +[   75.051226] [<00000000008e3ec4>] aa_replace_profiles+0x64/0x1160 +[   75.130144] [<00000000008d4d90>] policy_update+0xf0/0x280 +[   75.201057] [<00000000008d4fc8>] profile_replace+0xa8/0x100 +[   75.274258] [<0000000000766bd0>] vfs_write+0x90/0x420 +[   75.340594] [<00000000007670cc>] ksys_write+0x4c/0xe0 +[   75.406932] [<0000000000767174>] sys_write+0x14/0x40 +[   75.472126] [<0000000000406174>] linux_sparc_syscall+0x34/0x44 +[   75.548802] ---[ end trace 0000000000000000 ]--- +[   75.609503] dfa blob stream 0xfff0000008926b96 not aligned. +[   75.682695] Kernel unaligned access at TPC[8db2a8] aa_dfa_unpack+0x6e8/0x720 + +Work around it by using the get_unaligned_xx() helpers. + +Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack") +Reported-by: John Paul Adrian Glaubitz +Closes: https://github.com/sparclinux/issues/issues/30 +Signed-off-by: Helge Deller +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/match.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/security/apparmor/match.c b/security/apparmor/match.c +index 12e036f8ce0f7..4f998715d2942 100644 +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include "include/lib.h" + #include "include/match.h" +@@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize) + /* loaded td_id's start at 1, subtract 1 now to avoid doing + * it every time we use td_id as an index + */ +- th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1; ++ th.td_id = get_unaligned_be16(blob) - 1; + if (th.td_id > YYTD_ID_MAX) + goto out; +- th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2)); +- th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8)); ++ th.td_flags = get_unaligned_be16(blob + 2); ++ th.td_lolen = get_unaligned_be32(blob + 8); + blob += sizeof(struct table_header); + + if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || +@@ -277,14 +278,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) + if (size < sizeof(struct table_set_header)) + goto fail; + +- if (ntohl(*(__be32 *) data) != YYTH_MAGIC) ++ if (get_unaligned_be32(data) != YYTH_MAGIC) + goto fail; + +- hsize = ntohl(*(__be32 *) (data + 4)); ++ hsize = get_unaligned_be32(data + 4); + if (size < hsize) + goto fail; + +- dfa->flags = ntohs(*(__be16 *) (data + 12)); ++ dfa->flags = get_unaligned_be16(data + 12); + if (dfa->flags & ~(YYTH_FLAGS)) + goto fail; + +@@ -293,7 +294,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) + * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) { + * if (hsize < 16 + 4) + * goto fail; +- * dfa->max_oob = ntol(*(__be32 *) (data + 16)); ++ * dfa->max_oob = get_unaligned_be32(data + 16); + * if (dfa->max <= MAX_OOB_SUPPORTED) { + * pr_err("AppArmor DFA OOB greater than supported\n"); + * goto fail; +-- +2.51.0 + diff --git a/queue-6.12/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch b/queue-6.12/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch new file mode 100644 index 0000000000..6fda772019 --- /dev/null +++ b/queue-6.12/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch @@ -0,0 +1,43 @@ +From 8af6641c353af911365e75fa533361253e27e0d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Jan 2026 19:03:07 -0500 +Subject: apparmor: avoid per-cpu hold underflow in aa_get_buffer + +From: Zhengmian Hu + +[ Upstream commit 640cf2f09575c9dc344b3f7be2498d31e3923ead ] + +When aa_get_buffer() pulls from the per-cpu list it unconditionally +decrements cache->hold. If hold reaches 0 while count is still non-zero, +the unsigned decrement wraps to UINT_MAX. This keeps hold non-zero for a +very long time, so aa_put_buffer() never returns buffers to the global +list, which can starve other CPUs and force repeated kmalloc(aa_g_path_max) +allocations. + +Guard the decrement so hold never underflows. +Fixes: ea9bae12d028 ("apparmor: cache buffers on percpu list if there is lock contention") + +Signed-off-by: Zhengmian Hu +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 9a78fd36542d6..8855fb4b88342 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -1863,7 +1863,8 @@ char *aa_get_buffer(bool in_atomic) + if (!list_empty(&cache->head)) { + aa_buf = list_first_entry(&cache->head, union aa_buffer, list); + list_del(&aa_buf->list); +- cache->hold--; ++ if (cache->hold) ++ cache->hold--; + cache->count--; + put_cpu_ptr(&aa_local_buffers); + return &aa_buf->buffer[0]; +-- +2.51.0 + diff --git a/queue-6.12/apparmor-fix-aa_label-to-return-state-from-compount-.patch b/queue-6.12/apparmor-fix-aa_label-to-return-state-from-compount-.patch new file mode 100644 index 0000000000..fa176d4fc1 --- /dev/null +++ b/queue-6.12/apparmor-fix-aa_label-to-return-state-from-compount-.patch @@ -0,0 +1,74 @@ +From d4a5477a36615b09a6447cee7a0fa3ac48664712 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 04:12:02 -0800 +Subject: apparmor: fix aa_label to return state from compount and component + match + +From: John Johansen + +[ Upstream commit 9058798652c8bc0584ed1fb0766a1015046c06e8 ] + +aa-label_match is not correctly returning the state in all cases. +The only reason this didn't cause a error is that all callers currently +ignore the return value. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202602020631.wXgZosyU-lkp@intel.com/ +Fixes: a4c9efa4dbad6 ("apparmor: make label_match return a consistent value") +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 0a96ac6137b02..af25ca6b6b83f 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1346,7 +1346,7 @@ static int label_compound_match(struct aa_profile *profile, + * @request: permissions to request + * @perms: an initialized perms struct to add accumulation to + * +- * Returns: 0 on success else ERROR ++ * Returns: the state the match finished in, may be the none matching state + * + * For the label A//&B//&C this does the perm match for each of A and B and C + * @perms should be preinitialized with allperms OR a previous permission +@@ -1374,7 +1374,7 @@ static int label_components_match(struct aa_profile *profile, + } + + /* no subcomponents visible - no change in perms */ +- return 0; ++ return state; + + next: + tmp = *aa_lookup_perms(rules->policy, state); +@@ -1390,13 +1390,13 @@ static int label_components_match(struct aa_profile *profile, + } + + if ((perms->allow & request) != request) +- return -EACCES; ++ return DFA_NOMATCH; + +- return 0; ++ return state; + + fail: + *perms = nullperms; +- return -EACCES; ++ return DFA_NOMATCH; + } + + /** +@@ -1418,7 +1418,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, + aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, + request, perms); + if ((perms->allow & request) == request) +- return 0; ++ return tmp; + + /* failed compound_match try component matches */ + *perms = allperms; +-- +2.51.0 + diff --git a/queue-6.12/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch b/queue-6.12/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch new file mode 100644 index 0000000000..ccbd880d00 --- /dev/null +++ b/queue-6.12/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch @@ -0,0 +1,85 @@ +From f1c00bca5c7ce315cddeb83035d0c6094a94e9c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 15:58:45 -0300 +Subject: apparmor: fix invalid deref of rawdata when export_binary is unset + +From: Georgia Garcia + +[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ] + +If the export_binary parameter is disabled on runtime, profiles that +were loaded before that will still have their rawdata stored in +apparmorfs, with a symbolic link to the rawdata on the policy +directory. When one of those profiles are replaced, the rawdata is set +to NULL, but when trying to resolve the symbolic links to rawdata for +that profile, it will try to dereference profile->rawdata->name when +profile->rawdata is now NULL causing an oops. Fix it by checking if +rawdata is set. + +[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088 +[ 168.657420] #PF: supervisor read access in kernel mode +[ 168.660619] #PF: error_code(0x0000) - not-present page +[ 168.663613] PGD 0 P4D 0 +[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI +[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary) +[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330 +[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8 +[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282 +[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158 +[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80 +[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000 +[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80 +[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0 +[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000 +[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0 +[ 168.701696] Call Trace: +[ 168.702325] +[ 168.702995] rawdata_get_link_data+0x1c/0x30 +[ 168.704145] vfs_readlink+0xd4/0x160 +[ 168.705152] do_readlinkat+0x114/0x180 +[ 168.706214] __x64_sys_readlink+0x1e/0x30 +[ 168.708653] x64_sys_call+0x1d77/0x26b0 +[ 168.709525] do_syscall_64+0x81/0x500 +[ 168.710348] ? do_statx+0x72/0xb0 +[ 168.711109] ? putname+0x3e/0x80 +[ 168.711845] ? __x64_sys_statx+0xb7/0x100 +[ 168.712711] ? x64_sys_call+0x10fc/0x26b0 +[ 168.713577] ? do_syscall_64+0xbf/0x500 +[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0 +[ 168.715404] ? irqentry_exit+0xb2/0x740 +[ 168.716359] ? exc_page_fault+0x90/0x1b0 +[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement") +Signed-off-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index 01b923d97a446..584b40718ecb7 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -1631,6 +1631,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry, + + label = aa_get_label_rcu(&proxy->label); + profile = labels_profile(label); ++ ++ /* rawdata can be null when aa_g_export_binary is unset during ++ * runtime and a profile is replaced ++ */ ++ if (!profile->rawdata) { ++ aa_put_label(label); ++ return ERR_PTR(-ENOENT); ++ } ++ + depth = profile_depth(profile); + target = gen_symlink_name(depth, profile->rawdata->name, name); + aa_put_label(label); +-- +2.51.0 + diff --git a/queue-6.12/apparmor-fix-null-sock-in-aa_sock_file_perm.patch b/queue-6.12/apparmor-fix-null-sock-in-aa_sock_file_perm.patch new file mode 100644 index 0000000000..79dffd485f --- /dev/null +++ b/queue-6.12/apparmor-fix-null-sock-in-aa_sock_file_perm.patch @@ -0,0 +1,44 @@ +From f97f5c9199c499837d690575a1296941add2dab4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:07:42 -0800 +Subject: apparmor: fix NULL sock in aa_sock_file_perm + +From: John Johansen + +[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ] + +Deal with the potential that sock and sock-sk can be NULL during +socket setup or teardown. This could lead to an oops. The fix for NULL +pointer dereference in __unix_needs_revalidation shows this is at +least possible for af_unix sockets. While the fix for af_unix sockets +applies for newer mediation this is still the fall back path for older +af_unix mediation and other sockets, so ensure it is covered. + +Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/net.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 77413a5191179..f6f749191f601 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -190,8 +190,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, + const char *op, u32 request, struct socket *sock) + { + AA_BUG(!label); +- AA_BUG(!sock); +- AA_BUG(!sock->sk); ++ ++ /* sock && sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return 0; + + return aa_label_sk_perm(subj_cred, label, op, request, sock->sk); + } +-- +2.51.0 + diff --git a/queue-6.12/apparmor-fix-optimize-table-creation-from-possibly-u.patch b/queue-6.12/apparmor-fix-optimize-table-creation-from-possibly-u.patch new file mode 100644 index 0000000000..07f9335310 --- /dev/null +++ b/queue-6.12/apparmor-fix-optimize-table-creation-from-possibly-u.patch @@ -0,0 +1,79 @@ +From cf304558a56dddabe48b36896dd620090269291d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 21:15:04 +0100 +Subject: apparmor: Fix & Optimize table creation from possibly unaligned + memory + +From: Helge Deller + +[ Upstream commit 6fc367bfd4c8886e6b1742aabbd1c0bdc310db3a ] + +Source blob may come from userspace and might be unaligned. +Try to optize the copying process by avoiding unaligned memory accesses. + +- Added Fixes tag +- Added "Fix &" to description as this doesn't just optimize but fixes + a potential unaligned memory access +Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack") +Signed-off-by: Helge Deller +[jj: remove duplicate word "convert" in comment trigger checkpatch warning] +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/include/match.h | 12 +++++++----- + security/apparmor/match.c | 7 +++---- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h +index ae31a8a631fc6..dfc93631b43d8 100644 +--- a/security/apparmor/include/match.h ++++ b/security/apparmor/include/match.h +@@ -102,16 +102,18 @@ struct aa_dfa { + struct table_header *tables[YYTD_ID_TSIZE]; + }; + +-#define byte_to_byte(X) (X) +- + #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \ + do { \ + typeof(LEN) __i; \ + TTYPE *__t = (TTYPE *) TABLE; \ + BTYPE *__b = (BTYPE *) BLOB; \ +- for (__i = 0; __i < LEN; __i++) { \ +- __t[__i] = NTOHX(__b[__i]); \ +- } \ ++ BUILD_BUG_ON(sizeof(TTYPE) != sizeof(BTYPE)); \ ++ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) \ ++ memcpy(__t, __b, (LEN) * sizeof(BTYPE)); \ ++ else /* copy & convert from big-endian */ \ ++ for (__i = 0; __i < LEN; __i++) { \ ++ __t[__i] = NTOHX(&__b[__i]); \ ++ } \ + } while (0) + + static inline size_t table_size(size_t len, size_t el_size) +diff --git a/security/apparmor/match.c b/security/apparmor/match.c +index 4f998715d2942..fae26953619a7 100644 +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -67,14 +67,13 @@ static struct table_header *unpack_table(char *blob, size_t bsize) + table->td_flags = th.td_flags; + table->td_lolen = th.td_lolen; + if (th.td_flags == YYTD_DATA8) +- UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u8, u8, byte_to_byte); ++ memcpy(table->td_data, blob, th.td_lolen); + else if (th.td_flags == YYTD_DATA16) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u16, __be16, be16_to_cpu); ++ u16, __be16, get_unaligned_be16); + else if (th.td_flags == YYTD_DATA32) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u32, __be32, be32_to_cpu); ++ u32, __be32, get_unaligned_be32); + else + goto fail; + /* if table was vmalloced make sure the page tables are synced +-- +2.51.0 + diff --git a/queue-6.12/apparmor-fix-rlimit-for-posix-cpu-timers.patch b/queue-6.12/apparmor-fix-rlimit-for-posix-cpu-timers.patch new file mode 100644 index 0000000000..f49d81acbd --- /dev/null +++ b/queue-6.12/apparmor-fix-rlimit-for-posix-cpu-timers.patch @@ -0,0 +1,40 @@ +From 06992da97d4d87377d0d029eb98c0054f2660090 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:16:54 -0800 +Subject: apparmor: fix rlimit for posix cpu timers + +From: John Johansen + +[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ] + +Posix cpu timers requires an additional step beyond setting the rlimit. +Refactor the code so its clear when what code is setting the +limit and conditionally update the posix cpu timers when appropriate. + +Fixes: baa73d9e478ff ("posix-timers: Make them configurable") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/resource.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index dcc94c3153d51..a7eee815f1215 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -201,6 +201,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l) + rules->rlimits.limits[j].rlim_max); + /* soft limit should not exceed hard limit */ + rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); ++ if (j == RLIMIT_CPU && ++ rlim->rlim_cur != RLIM_INFINITY && ++ IS_ENABLED(CONFIG_POSIX_TIMERS)) ++ (void) update_rlimit_cpu(current->group_leader, ++ rlim->rlim_cur); + } + } + } +-- +2.51.0 + diff --git a/queue-6.12/apparmor-make-label_match-return-a-consistent-value.patch b/queue-6.12/apparmor-make-label_match-return-a-consistent-value.patch new file mode 100644 index 0000000000..41d597e459 --- /dev/null +++ b/queue-6.12/apparmor-make-label_match-return-a-consistent-value.patch @@ -0,0 +1,80 @@ +From 388117496f08de95aaf378729a1aa613da47ab55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 23:59:38 -0800 +Subject: apparmor: make label_match return a consistent value + +From: John Johansen + +[ Upstream commit a4c9efa4dbad6dacad6e8b274e30e814c8353097 ] + +compound match is inconsistent in returning a state or an integer error +this is problemati if the error is ever used as a state in the state +machine + +Fixes: f1bd904175e81 ("apparmor: add the base fns() for domain labels") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 81548248440aa..0a96ac6137b02 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1290,7 +1290,7 @@ static inline aa_state_t match_component(struct aa_profile *profile, + * @request: permissions to request + * @perms: perms struct to set + * +- * Returns: 0 on success else ERROR ++ * Returns: state match stopped at or DFA_NOMATCH if aborted early + * + * For the label A//&B//&C this does the perm match for A//&B//&C + * @perms should be preinitialized with allperms OR a previous permission +@@ -1317,7 +1317,7 @@ static int label_compound_match(struct aa_profile *profile, + + /* no component visible */ + *perms = allperms; +- return 0; ++ return state; + + next: + label_for_each_cont(i, label, tp) { +@@ -1329,14 +1329,11 @@ static int label_compound_match(struct aa_profile *profile, + goto fail; + } + *perms = *aa_lookup_perms(rules->policy, state); +- if ((perms->allow & request) != request) +- return -EACCES; +- +- return 0; ++ return state; + + fail: + *perms = nullperms; +- return state; ++ return DFA_NOMATCH; + } + + /** +@@ -1418,11 +1415,12 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, + struct aa_label *label, aa_state_t state, bool subns, + u32 request, struct aa_perms *perms) + { +- int error = label_compound_match(profile, rules, label, state, subns, +- request, perms); +- if (!error) +- return error; ++ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, ++ request, perms); ++ if ((perms->allow & request) == request) ++ return 0; + ++ /* failed compound_match try component matches */ + *perms = allperms; + return label_components_match(profile, rules, label, state, subns, + request, perms); +-- +2.51.0 + diff --git a/queue-6.12/apparmor-remove-apply_modes_to_perms-from-label_matc.patch b/queue-6.12/apparmor-remove-apply_modes_to_perms-from-label_matc.patch new file mode 100644 index 0000000000..0c9e520129 --- /dev/null +++ b/queue-6.12/apparmor-remove-apply_modes_to_perms-from-label_matc.patch @@ -0,0 +1,53 @@ +From d4fb16102ea0b421cc5322d7236e501a91c27193 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 00:14:36 -0800 +Subject: apparmor: remove apply_modes_to_perms from label_match + +From: John Johansen + +[ Upstream commit b2e27be2948f2f8c38421cd554b5fc9383215648 ] + +The modes shouldn't be applied at the point of label match, it just +results in them being applied multiple times. Instead they should be +applied after which is already being done by all callers so it can +just be dropped from label_match. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value") +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index c71e4615dd460..81548248440aa 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1329,7 +1329,6 @@ static int label_compound_match(struct aa_profile *profile, + goto fail; + } + *perms = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, perms); + if ((perms->allow & request) != request) + return -EACCES; + +@@ -1382,7 +1381,6 @@ static int label_components_match(struct aa_profile *profile, + + next: + tmp = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + label_for_each_cont(i, label, tp) { + if (!aa_ns_visible(profile->ns, tp->ns, subns)) +@@ -1391,7 +1389,6 @@ static int label_components_match(struct aa_profile *profile, + if (!state) + goto fail; + tmp = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + } + +-- +2.51.0 + diff --git a/queue-6.12/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch b/queue-6.12/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch new file mode 100644 index 0000000000..044ae350c7 --- /dev/null +++ b/queue-6.12/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch @@ -0,0 +1,44 @@ +From 4c06525f7bc29d5235ecaeee48a82fe565d4165c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Jan 2026 09:35:57 -0800 +Subject: apparmor: return -ENOMEM in unpack_perms_table upon alloc failure + +From: Ryan Lee + +[ Upstream commit 74b7105e53e80a4072bd3e1a50be7aa15e3f0a01 ] + +In policy_unpack.c:unpack_perms_table, the perms struct is allocated via +kcalloc, with the position being reset if the allocation fails. However, +the error path results in -EPROTO being retured instead of -ENOMEM. Fix +this to return the correct error code. + +Reported-by: Zygmunt Krynicki +Fixes: fd1b2b95a2117 ("apparmor: add the ability for policy to specify a permission table") +Reviewed-by: Tyler Hicks +Signed-off-by: Ryan Lee +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/policy_unpack.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index 3483c595f999f..8f7d6ff5aef60 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -683,8 +683,10 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms) + if (!aa_unpack_array(e, NULL, &size)) + goto fail_reset; + *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL); +- if (!*perms) +- goto fail_reset; ++ if (!*perms) { ++ e->pos = pos; ++ return -ENOMEM; ++ } + for (i = 0; i < size; i++) { + if (!unpack_perm(e, version, &(*perms)[i])) + goto fail; +-- +2.51.0 + diff --git a/queue-6.12/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch b/queue-6.12/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch new file mode 100644 index 0000000000..19833dd9c8 --- /dev/null +++ b/queue-6.12/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch @@ -0,0 +1,49 @@ +From ce2f1844d8b9b2b3c14b218eeaf34f53a4539651 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 11:27:32 +0100 +Subject: ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init + +From: Alexandre Ferrieux + +[ Upstream commit b82fa9b0c26eeb2fde6017f7de2c3c544484efef ] + +The aw88261_dev_reg_update() function sets the Awinic registers in a +rather nonuniform way: + - most registers get directly overwritten from the firmware blob + - but a handful of them need more delicate logic to preserve + some bits from their current value, according to a register- + specific mask +For the latter, the logic is basically + NEW = (OLD & MASK) | (VAL & ~MASK) +However, the ~MASK value is hand-computed, and in the specific case +of the SYSCTRL register, in a buggy way. +This patch restores the proper ~MASK value. + +Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver") +Signed-off-by: Alexandre Ferrieux +Link: https://patch.msgid.link/20260211-aw88261-fwname-v1-1-e24e833a019d@fairphone.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/aw88261.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c +index fb99871578c5a..38f362b022aa3 100644 +--- a/sound/soc/codecs/aw88261.c ++++ b/sound/soc/codecs/aw88261.c +@@ -423,9 +423,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261, + if (ret) + break; + ++ /* keep all three bits from current hw status */ + read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) | + (~AW88261_HMUTE_MASK); +- reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK); ++ reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK); + reg_val |= read_val; + + /* enable uls hmute */ +-- +2.51.0 + diff --git a/queue-6.12/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch b/queue-6.12/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch new file mode 100644 index 0000000000..e89c4785d4 --- /dev/null +++ b/queue-6.12/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch @@ -0,0 +1,52 @@ +From 2b32ec98a143638cc25e791229ccc37468f5c610 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 18:57:14 +0000 +Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put() + +From: Ziyi Guo + +[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ] + +This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()"). + +The original patch attempted to acquire the card->controls_rwsem lock in +fsl_xcvr_mode_put(). However, this function is called from the upper ALSA +core function snd_ctl_elem_write(), which already holds the write lock on +controls_rwsem for the whole put operation. So there is no need to simply +hold the lock for fsl_xcvr_activate_ctl() again. + +Acquiring the read lock while holding the write lock in the same thread +results in a deadlock and a hung task, as reported by Alexander Stein. + +Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()") +Reported-by: Alexander Stein +Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/ +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index d6f00920391d1..656a4d619cdf1 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -216,13 +216,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, + + xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); + +- down_read(&card->snd_card->controls_rwsem); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_ARC)); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_EARC)); +- up_read(&card->snd_card->controls_rwsem); +- + /* Allow playback for SPDIF only */ + rtd = snd_soc_get_pcm_runtime(card, card->dai_link); + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = +-- +2.51.0 + diff --git a/queue-6.12/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch b/queue-6.12/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch new file mode 100644 index 0000000000..5e90d1852d --- /dev/null +++ b/queue-6.12/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch @@ -0,0 +1,55 @@ +From 5916a67367aae1d6ed0017eef97305193ae5a20b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 15:18:34 -0500 +Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk + +From: Detlev Casanova + +[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ] + +Drivers will not always call set_sysclk() for all clocks, especially when +default mclk-fs can be used. +When that is the case, use the clock rate set in the params multiplied by the +default mclk-fs. + +Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback") +Signed-off-by: Detlev Casanova +Reported-by: Luca Ceresoli +Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c +index 7feefeb6b876d..46c338ddefe9f 100644 +--- a/sound/soc/rockchip/rockchip_i2s_tdm.c ++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c +@@ -22,6 +22,7 @@ + + #define DRV_NAME "rockchip-i2s-tdm" + ++#define DEFAULT_MCLK_FS 256 + #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ + #define MULTIPLEX_CH_MAX 10 + +@@ -693,6 +694,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, + mclk_rate = i2s_tdm->mclk_rx_freq; + } + ++ /* ++ * When the dai/component driver doesn't need to set mclk-fs for a specific ++ * clock, it can skip the call to set_sysclk() for that clock. ++ * In that case, simply use the clock rate from the params and multiply it by ++ * the default mclk-fs value. ++ */ ++ if (!mclk_rate) ++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params); ++ + err = clk_set_rate(mclk, mclk_rate); + if (err) + return err; +-- +2.51.0 + diff --git a/queue-6.12/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch b/queue-6.12/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch new file mode 100644 index 0000000000..52b4743b6c --- /dev/null +++ b/queue-6.12/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch @@ -0,0 +1,108 @@ +From bdb60d3dcbdeb46eb6fe2416fe12b02ccd86aa95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 06:09:19 +0000 +Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down + +From: Hangbin Liu + +[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ] + +The ALB RX path may access rx_hashtbl concurrently with bond +teardown. During rapid bond up/down cycles, rlb_deinitialize() +frees rx_hashtbl while RX handlers are still running, leading +to a null pointer dereference detected by KASAN. + +However, the root cause is that rlb_arp_recv() can still be accessed +after setting recv_probe to NULL, which is actually a use-after-free +(UAF) issue. That is the reason for using the referenced commit in the +Fixes tag. + +[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI +[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef] +[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary) +[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022 +[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding] +[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6 + 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00 +[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206 +[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e +[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8 +[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8 +[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119 +[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810 +[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000 +[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0 +[ 214.310347] Call Trace: +[ 214.313070] +[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding] +[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding] +[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding] +[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710 +[ 214.339199] ? __pfx_arp_process+0x10/0x10 +[ 214.343775] ? sched_balance_find_src_group+0x98/0x630 +[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10 +[ 214.356513] ? arp_rcv+0x307/0x690 +[ 214.360311] ? __pfx_arp_rcv+0x10/0x10 +[ 214.364499] ? __lock_acquire+0x58c/0xbd0 +[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0 +[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10 +[ 214.380743] ? lock_acquire+0x10b/0x140 +[ 214.385026] process_backlog+0x3f1/0x13a0 +[ 214.389502] ? process_backlog+0x3aa/0x13a0 +[ 214.394174] __napi_poll.constprop.0+0x9f/0x370 +[ 214.399233] net_rx_action+0x8c1/0xe60 +[ 214.403423] ? __pfx_net_rx_action+0x10/0x10 +[ 214.408193] ? lock_acquire.part.0+0xbd/0x260 +[ 214.413058] ? sched_clock_cpu+0x6c/0x540 +[ 214.417540] ? mark_held_locks+0x40/0x70 +[ 214.421920] handle_softirqs+0x1fd/0x860 +[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10 +[ 214.431264] ? __neigh_event_send+0x2d6/0xf50 +[ 214.436131] do_softirq+0xb1/0xf0 +[ 214.439830] + +The issue is reproducible by repeatedly running +ip link set bond0 up/down while receiving ARP messages, where +rlb_arp_recv() can race with rlb_deinitialize() and dereference +a freed rx_hashtbl entry. + +Fix this by setting recv_probe to NULL and then calling +synchronize_net() to wait for any concurrent RX processing to finish. +This ensures that no RX handler can access rx_hashtbl after it is freed +in bond_alb_deinitialize(). + +Reported-by: Liang Li +Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()") +Reviewed-by: Nikolay Aleksandrov +Acked-by: Jay Vosburgh +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 95456a753b184..dd1f8cad953bf 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4478,9 +4478,13 @@ static int bond_close(struct net_device *bond_dev) + + bond_work_cancel_all(bond); + bond->send_peer_notif = 0; ++ WRITE_ONCE(bond->recv_probe, NULL); ++ ++ /* Wait for any in-flight RX handlers */ ++ synchronize_net(); ++ + if (bond_is_lb(bond)) + bond_alb_deinitialize(bond); +- bond->recv_probe = NULL; + + if (bond_uses_primary(bond)) { + rcu_read_lock(); +-- +2.51.0 + diff --git a/queue-6.12/bpftool-fix-truncated-netlink-dumps.patch b/queue-6.12/bpftool-fix-truncated-netlink-dumps.patch new file mode 100644 index 0000000000..7682fefaef --- /dev/null +++ b/queue-6.12/bpftool-fix-truncated-netlink-dumps.patch @@ -0,0 +1,73 @@ +From 0145936c3c55486f616ee57e3fe3dc837efc5328 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 11:41:50 -0800 +Subject: bpftool: Fix truncated netlink dumps + +From: Jakub Kicinski + +[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ] + +Netlink requires that the recv buffer used during dumps is at least +min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will +get truncated. Make sure bpftool follows this requirement, avoid +missing information on systems with large pages. + +Acked-by: Quentin Monnet +Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool") +Signed-off-by: Jakub Kicinski +Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/net.c | 5 ++++- + tools/lib/bpf/netlink.c | 4 +++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c +index 39f208928cdb5..587403a19af3a 100644 +--- a/tools/bpf/bpftool/net.c ++++ b/tools/bpf/bpftool/net.c +@@ -156,7 +156,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + bool multipart = true; + struct nlmsgerr *err; + struct nlmsghdr *nh; +- char buf[4096]; ++ char buf[8192]; + int len, ret; + + while (multipart) { +@@ -201,6 +201,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + return ret; + } + } ++ ++ if (len) ++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len); + } + ret = 0; + done: +diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c +index 68a2def171751..6f16c4f7b3a43 100644 +--- a/tools/lib/bpf/netlink.c ++++ b/tools/lib/bpf/netlink.c +@@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + struct nlmsghdr *nh; + int len, ret; + +- ret = alloc_iov(&iov, 4096); ++ ret = alloc_iov(&iov, 8192); + if (ret) + goto done; + +@@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + } + } + } ++ if (len) ++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len); + } + ret = 0; + done: +-- +2.51.0 + diff --git a/queue-6.12/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch b/queue-6.12/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch new file mode 100644 index 0000000000..3940e2e820 --- /dev/null +++ b/queue-6.12/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch @@ -0,0 +1,52 @@ +From 0e382b30df484f243a10c067f31de9a966ab1be3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 17:15:53 +0000 +Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not + found + +From: Filipe Manana + +[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ] + +If btrfs_search_slot_for_read() returns 1, it means we did not find any +key greater than or equals to the key we asked for, meaning we have +reached the end of the tree and therefore the path is not valid. If +this happens we need to break out of the loop and stop, instead of +continuing and accessing an invalid path. + +Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/qgroup.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index 4df0ba100f9de..71ccba22752cb 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1199,11 +1199,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info, + } + if (ret > 0) { + /* +- * Shouldn't happen, but in case it does we +- * don't need to do the btrfs_next_item, just +- * continue. ++ * Shouldn't happen because the key should still ++ * be there (return 0), but in case it does it ++ * means we have reached the end of the tree - ++ * there are no more leaves with items that have ++ * a key greater than or equals to @found_key, ++ * so just stop the search loop. + */ +- continue; ++ break; + } + } + ret = btrfs_next_item(tree_root, path); +-- +2.51.0 + diff --git a/queue-6.12/btrfs-use-the-correct-type-to-initialize-block-reser.patch b/queue-6.12/btrfs-use-the-correct-type-to-initialize-block-reser.patch new file mode 100644 index 0000000000..345d095334 --- /dev/null +++ b/queue-6.12/btrfs-use-the-correct-type-to-initialize-block-reser.patch @@ -0,0 +1,82 @@ +From 15f17282fde4fa6c4f8036b7cf54ff4fa482ce65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 18:03:35 +0000 +Subject: btrfs: use the correct type to initialize block reserve for delayed + refs + +From: Filipe Manana + +[ Upstream commit 2155d0c0a761a56ce7ede83a26eb23ea0f935260 ] + +When initializing the delayed refs block reserve for a transaction handle +we are passing a type of BTRFS_BLOCK_RSV_DELOPS, which is meant for +delayed items and not for delayed refs. The correct type for delayed refs +is BTRFS_BLOCK_RSV_DELREFS. + +On release of any excess space reserved in a local delayed refs reserve, +we also should transfer that excess space to the global block reserve +(it it's full, we return to the space info for general availability). + +By initializing a transaction's local delayed refs block reserve with a +type of BTRFS_BLOCK_RSV_DELOPS, we were also causing any excess space +released from the delayed block reserve (fs_info->delayed_block_rsv, used +for delayed inodes and items) to be transferred to the global block +reserve instead of the global delayed refs block reserve. This was an +unintentional change in commit 28270e25c69a ("btrfs: always reserve space +for delayed refs when starting transaction"), but it's not particularly +serious as things tend to cancel out each other most of the time and it's +relatively rare to be anywhere near exhaustion of the global reserve. + +Fix this by initializing a transaction's local delayed refs reserve with +a type of BTRFS_BLOCK_RSV_DELREFS and making btrfs_block_rsv_release() +attempt to transfer unused space from such a reserve into the global block +reserve, just as we did before that commit for when the block reserve is +a delayed refs rsv. + +Reported-by: Alex Lyakas +Link: https://lore.kernel.org/linux-btrfs/CAOcd+r0FHG5LWzTSu=LknwSoqxfw+C00gFAW7fuX71+Z5AfEew@mail.gmail.com/ +Fixes: 28270e25c69a ("btrfs: always reserve space for delayed refs when starting transaction") +Reviewed-by: Alex Lyakas +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-rsv.c | 7 ++++--- + fs/btrfs/transaction.c | 2 +- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c +index a07b9594dc706..a578bd3b32bb0 100644 +--- a/fs/btrfs/block-rsv.c ++++ b/fs/btrfs/block-rsv.c +@@ -280,10 +280,11 @@ u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info, + struct btrfs_block_rsv *target = NULL; + + /* +- * If we are a delayed block reserve then push to the global rsv, +- * otherwise dump into the global delayed reserve if it is not full. ++ * If we are a delayed refs block reserve then push to the global ++ * reserve, otherwise dump into the global delayed refs reserve if it is ++ * not full. + */ +- if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS) ++ if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS) + target = global_rsv; + else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv)) + target = delayed_rsv; +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index b7679f3399407..0ee6b40af65ee 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -726,7 +726,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, + + h->type = type; + INIT_LIST_HEAD(&h->new_bgs); +- btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS); ++ btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS); + + smp_mb(); + if (cur_trans->state >= TRANS_STATE_COMMIT_START && +-- +2.51.0 + diff --git a/queue-6.12/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch b/queue-6.12/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch new file mode 100644 index 0000000000..ff58a9b550 --- /dev/null +++ b/queue-6.12/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch @@ -0,0 +1,59 @@ +From 2cf5eb593262ad4f6dcd28d6bc15d540225e9124 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 00:20:02 +0530 +Subject: cpuidle: Skip governor when only one idle state is available + +From: Aboorva Devarajan + +[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ] + +On certain platforms (PowerNV systems without a power-mgt DT node), +cpuidle may register only a single idle state. In cases where that +single state is a polling state (state 0), the ladder governor may +incorrectly treat state 1 as the first usable state and pass an +out-of-bounds index. This can lead to a NULL enter callback being +invoked, ultimately resulting in a system crash. + +[ 13.342636] cpuidle-powernv : Only Snooze is available +[ 13.351854] Faulting instruction address: 0x00000000 +[ 13.376489] NIP [0000000000000000] 0x0 +[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668 + +Fix this by adding a bail-out in cpuidle_select() that returns state 0 +directly when state_count <= 1, bypassing the governor and keeping the +tick running. + +Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") +Signed-off-by: Aboorva Devarajan +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/cpuidle.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 0e1bbc966135d..2cb11e5a11251 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -353,6 +353,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev, + int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + bool *stop_tick) + { ++ /* ++ * If there is only a single idle state (or none), there is nothing ++ * meaningful for the governor to choose. Skip the governor and ++ * always use state 0 with the tick running. ++ */ ++ if (drv->state_count <= 1) { ++ *stop_tick = false; ++ return 0; ++ } ++ + return cpuidle_curr_governor->select(drv, dev, stop_tick); + } + +-- +2.51.0 + diff --git a/queue-6.12/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch b/queue-6.12/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch new file mode 100644 index 0000000000..934a0dc24a --- /dev/null +++ b/queue-6.12/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch @@ -0,0 +1,216 @@ +From 124b4b435e70d432febfc7e493aa29459889c1d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 20:49:23 +0530 +Subject: drm/amd/display: Fix out-of-bounds stream encoder index v3 + +From: Srinivasan Shanmugam + +[ Upstream commit abde491143e4e12eecc41337910aace4e8d59603 ] + +eng_id can be negative and that stream_enc_regs[] +can be indexed out of bounds. + +eng_id is used directly as an index into stream_enc_regs[], which has +only 5 entries. When eng_id is 5 (ENGINE_ID_DIGF) or negative, this can +access memory past the end of the array. + +Add a bounds check using ARRAY_SIZE() before using eng_id as an index. +The unsigned cast also rejects negative values. + +This avoids out-of-bounds access. + +Fixes the below smatch error: +dcn*_resource.c: stream_encoder_create() may index +stream_enc_regs[eng_id] out of bounds (size 5). + +drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c + 1246 static struct stream_encoder *dcn35_stream_encoder_create( + 1247 enum engine_id eng_id, + 1248 struct dc_context *ctx) + 1249 { + + ... + + 1255 + 1256 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ + 1257 if (eng_id <= ENGINE_ID_DIGF) { + +ENGINE_ID_DIGF is 5. should <= be dc_bios, + 1283 eng_id, vpg, afmt, +--> 1284 &stream_enc_regs[eng_id], + ^^^^^^^^^^^^^^^^^^^^^^^ This stream_enc_regs[] array has 5 elements so we are one element beyond the end of the array. + + ... + + 1287 return &enc1->base; + 1288 } + +v2: use explicit bounds check as suggested by Roman/Dan; avoid unsigned int cast + +v3: The compiler already knows how to compare the two values, so the + cast (int) is not needed. (Roman) + +Fixes: 2728e9c7c842 ("drm/amd/display: add DC changes for DCN351") +Reported-by: Dan Carpenter +Cc: Harry Wentland +Cc: Mario Limonciello +Cc: Alex Hung +Cc: Aurabindo Pillai +Cc: ChiaHsuan Chung +Cc: Roman Li +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Roman Li +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn316/dcn316_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn321/dcn321_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 8 ++++---- + 6 files changed, 24 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +index 9cb72805b8d1a..ad3f229f39cba 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +@@ -1227,12 +1227,12 @@ static struct stream_encoder *dcn315_stream_encoder_create( + /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/ + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +index af82e13029c9e..b2d8383411b21 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +@@ -1221,12 +1221,12 @@ static struct stream_encoder *dcn316_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +index 6b889c8be0ca3..62dbb0f3073c0 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +@@ -1207,12 +1207,12 @@ static struct stream_encoder *dcn32_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn32_vpg_create(ctx, vpg_inst); + afmt = dcn32_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +index 74113c578bac4..84aaa7a5ae30f 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +@@ -1190,12 +1190,12 @@ static struct stream_encoder *dcn321_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn321_vpg_create(ctx, vpg_inst); + afmt = dcn321_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +index 92d5e3252d2d4..90d63e3174344 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +@@ -1272,12 +1272,12 @@ static struct stream_encoder *dcn35_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +index 6e27226cec289..9c72e87b606a2 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +@@ -1252,12 +1252,12 @@ static struct stream_encoder *dcn35_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +-- +2.51.0 + diff --git a/queue-6.12/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch b/queue-6.12/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch new file mode 100644 index 0000000000..4e64df2415 --- /dev/null +++ b/queue-6.12/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch @@ -0,0 +1,69 @@ +From 1e53305523998d46f731657cac406abe8ed50ce4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 18 Jan 2026 15:57:41 +0100 +Subject: drm/amd/display: Reject cursor plane on DCE when scaled differently + than primary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit 41af6215cdbcecd12920f211239479027904abf3 ] + +Currently DCE doesn't support the overlay cursor, so the +dm_crtc_get_cursor_mode() function returns DM_CURSOR_NATIVE_MODE +unconditionally. The outcome is that it doesn't check for the +conditions that would necessitate the overlay cursor, meaning +that it doesn't reject cases where the native cursor mode isn't +supported on DCE. + +Remove the early return from dm_crtc_get_cursor_mode() for +DCE and instead let it perform the necessary checks and +return DM_CURSOR_OVERLAY_MODE. Add a later check that rejects +when DM_CURSOR_OVERLAY_MODE would be used with DCE. + +Fixes: 1b04dcca4fb1 ("drm/amd/display: Introduce overlay cursor mode") +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4600 +Suggested-by: Leo Li +Signed-off-by: Timur Kristóf +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index b146b0529ae7f..45297715f76cf 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -11492,10 +11492,9 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, + + /* Overlay cursor not supported on HW before DCN + * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions +- * as previous DCN generations, so enable native mode on DCN401 in addition to DCE ++ * as previous DCN generations, so enable native mode on DCN401 + */ +- if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 || +- amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { ++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { + *cursor_mode = DM_CURSOR_NATIVE_MODE; + return 0; + } +@@ -11815,6 +11814,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, + * need to be added for DC to not disable a plane by mistake + */ + if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) { ++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) { ++ drm_dbg(dev, "Overlay cursor not supported on DCE\n"); ++ ret = -EINVAL; ++ goto fail; ++ } ++ + ret = drm_atomic_add_affected_planes(state, crtc); + if (ret) + goto fail; +-- +2.51.0 + diff --git a/queue-6.12/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch b/queue-6.12/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch new file mode 100644 index 0000000000..b0aa81fb87 --- /dev/null +++ b/queue-6.12/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch @@ -0,0 +1,78 @@ +From 70c32b1b0f7a2a69e912c19e5f9248619e2b8e34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 23:38:28 +0100 +Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp + formats + +From: Mario Kleiner + +[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ] + +The plane scaling hw seems to have the same min/max plane scaling limits +for all 16 bpc / 64 bpp interleaved pixel color formats. + +Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for +all the 16 bpc fixed-point / unorm formats to use the same .fp16 +up/downscaling factor limits as used by the fp16 floating point formats. + +So far, 16 bpc unorm formats were not handled, and the default: path +returned max/min factors for 32 bpp argb8888 formats, which were wrong +and bigger than what many DCE / DCN hw generations could handle. + +The result sometimes was misscaling of framebuffers with +DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616, +DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested +on Polaris11 / DCE-11.2. + +So far this went unnoticed, because only few userspace clients used such +16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they +did not experience this issue. + +With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL +and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland +compositor allowing for direct scanout of these formats, the scaling +hw will be used on these formats if possible for HiDPI display scaling, +so it is important to use the correct hw scaling limits to avoid wrong +display. + +Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50 +on HiDPI displays with scaling enabled. The mutter Wayland compositor now +correctly falls back to scaling via desktop compositing instead of direct +scanout, thereby avoiding wrong image display. For unscaled mode, it +correctly uses direct scanout. + +Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.") +Signed-off-by: Mario Kleiner +Tested-by: Mario Kleiner +Cc: Alex Deucher +Cc: Harry Wentland +Cc: Leo Li +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +index 62e30942f735d..d98c0efe5608d 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +@@ -1055,10 +1055,15 @@ static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev, + *min_downscale = plane_cap->max_downscale_factor.nv12; + break; + ++ /* All 64 bpp formats have the same fp16 scaling limits */ + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: ++ case DRM_FORMAT_XRGB16161616: ++ case DRM_FORMAT_ARGB16161616: ++ case DRM_FORMAT_XBGR16161616: ++ case DRM_FORMAT_ABGR16161616: + *max_upscale = plane_cap->max_upscale_factor.fp16; + *min_downscale = plane_cap->max_downscale_factor.fp16; + break; +-- +2.51.0 + diff --git a/queue-6.12/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch b/queue-6.12/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch new file mode 100644 index 0000000000..2d619b7681 --- /dev/null +++ b/queue-6.12/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch @@ -0,0 +1,46 @@ +From 290620d7aa998734523bb7c1c41a0094e7e24465 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 09:25:32 +0000 +Subject: drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc() + +From: Zilin Guan + +[ Upstream commit c9be63d565789b56ca7b0197e2cb78a3671f95a8 ] + +In amdgpu_acpi_enumerate_xcc(), if amdgpu_acpi_dev_init() returns -ENOMEM, +the function returns directly without releasing the allocated xcc_info, +resulting in a memory leak. + +Fix this by ensuring that xcc_info is properly freed in the error paths. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects") +Reviewed-by: Lijo Lazar +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +index bebfbc1497d8e..d484804181756 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -1132,8 +1132,10 @@ static int amdgpu_acpi_enumerate_xcc(void) + if (!dev_info) + ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf); + +- if (ret == -ENOMEM) ++ if (ret == -ENOMEM) { ++ kfree(xcc_info); + return ret; ++ } + + if (!dev_info) { + kfree(xcc_info); +-- +2.51.0 + diff --git a/queue-6.12/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch b/queue-6.12/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch new file mode 100644 index 0000000000..db90f43ae8 --- /dev/null +++ b/queue-6.12/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch @@ -0,0 +1,44 @@ +From b1b04edc3dcb97b78db26bf88fd0b6c238c7751c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 08:35:15 +0000 +Subject: drm/amdgpu: Fix memory leak in amdgpu_ras_init() + +From: Zilin Guan + +[ Upstream commit ee41e5b63c8210525c936ee637a2c8d185ce873c ] + +When amdgpu_nbio_ras_sw_init() fails in amdgpu_ras_init(), the function +returns directly without freeing the allocated con structure, leading +to a memory leak. + +Fix this by jumping to the release_con label to properly clean up the +allocated memory before returning the error code. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: fdc94d3a8c88 ("drm/amdgpu: Rework pcie_bif ras sw_init") +Reviewed-by: Tao Zhou +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index d9cdc89d4cde1..bf563904b3fa9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -3643,7 +3643,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev) + * to handle fatal error */ + r = amdgpu_nbio_ras_sw_init(adev); + if (r) +- return r; ++ goto release_con; + + if (adev->nbio.ras && + adev->nbio.ras->init_ras_controller_interrupt) { +-- +2.51.0 + diff --git a/queue-6.12/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch b/queue-6.12/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch new file mode 100644 index 0000000000..8895911ce7 --- /dev/null +++ b/queue-6.12/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch @@ -0,0 +1,44 @@ +From 93e37d05c9ba7d81d5c63aa40d953f1fa32d5ad3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 09:05:42 +0000 +Subject: drm/amdgpu: Use kvfree instead of kfree in + amdgpu_gmc_get_nps_memranges() + +From: Zilin Guan + +[ Upstream commit 0c44d61945c4a80775292d96460aa2f22e62f86c ] + +amdgpu_discovery_get_nps_info() internally allocates memory for ranges +using kvcalloc(), which may use vmalloc() for large allocation. Using +kfree() to release vmalloc memory will lead to a memory corruption. + +Use kvfree() to safely handle both kmalloc and vmalloc allocations. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: b194d21b9bcc ("drm/amdgpu: Use NPS ranges from discovery table") +Reviewed-by: Lijo Lazar +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +index f159641271672..c57893cce9e3d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +@@ -1260,7 +1260,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev, + } + + err: +- kfree(ranges); ++ kvfree(ranges); + + return ret; + } +-- +2.51.0 + diff --git a/queue-6.12/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch b/queue-6.12/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch new file mode 100644 index 0000000000..d1e2e687a3 --- /dev/null +++ b/queue-6.12/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch @@ -0,0 +1,138 @@ +From 7d93e95419a101fb834af2d9ff040c550fa1bd85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 21:18:11 +0530 +Subject: drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Srinivasan Shanmugam + +[ Upstream commit 5a19302cab5cec7ae7f1a60c619951e6c17d8742 ] + +The address watch clear code receives watch_id as an unsigned value +(u32), but some helper functions were using a signed int and checked +bits by shifting with watch_id. + +If a very large watch_id is passed from userspace, it can be converted +to a negative value. This can cause invalid shifts and may access +memory outside the watch_points array. + +drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 + +Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before +using it. Also use BIT(watch_id) to test and clear bits safely. + +This keeps the behavior unchanged for valid watch IDs and avoids +undefined behavior for invalid ones. + +Fixes the below: +drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448 +kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow +'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped + +drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c + 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, + 434 uint32_t watch_id) + 435 { + 436 int r; + 437 + 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) + +kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if +watch_id is larger than INT_MAX it leads to a buffer overflow. +(Negative shifts are undefined). + + 439 return -EINVAL; + 440 + 441 if (!pdd->dev->kfd->shared_resources.enable_mes) { + 442 r = debug_lock_and_unmap(pdd->dev->dqm); + 443 if (r) + 444 return r; + 445 } + 446 + 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false); +--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch( + 449 pdd->dev->adev, + 450 watch_id); + +v2: (as per, Jonathan Kim) + - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to + match the clear path. + - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id(). + +Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation") +Reported-by: Dan Carpenter +Cc: Jonathan Kim +Cc: Felix Kuehling +Cc: Alex Deucher +Cc: Christian König +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Jonathan Kim +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +index a8abc30918013..3a8df47aa5821 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +@@ -401,27 +401,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i + return -ENOMEM; + } + +-static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id) ++static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) + { + spin_lock(&pdd->dev->watch_points_lock); + + /* process owns device watch point so safe to clear */ +- if ((pdd->alloc_watch_ids >> watch_id) & 0x1) { +- pdd->alloc_watch_ids &= ~(0x1 << watch_id); +- pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id); ++ if (pdd->alloc_watch_ids & BIT(watch_id)) { ++ pdd->alloc_watch_ids &= ~BIT(watch_id); ++ pdd->dev->alloc_watch_ids &= ~BIT(watch_id); + } + + spin_unlock(&pdd->dev->watch_points_lock); + } + +-static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id) ++static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) + { + bool owns_watch_id = false; + + spin_lock(&pdd->dev->watch_points_lock); +- owns_watch_id = watch_id < MAX_WATCH_ADDRESSES && +- ((pdd->alloc_watch_ids >> watch_id) & 0x1); +- ++ owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id); + spin_unlock(&pdd->dev->watch_points_lock); + + return owns_watch_id; +@@ -432,6 +430,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, + { + int r; + ++ if (watch_id >= MAX_WATCH_ADDRESSES) ++ return -EINVAL; ++ + if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) + return -EINVAL; + +@@ -469,6 +470,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd, + if (r) + return r; + ++ if (*watch_id >= MAX_WATCH_ADDRESSES) ++ return -EINVAL; ++ + if (!pdd->dev->kfd->shared_resources.enable_mes) { + r = debug_lock_and_unmap(pdd->dev->dqm); + if (r) { +-- +2.51.0 + diff --git a/queue-6.12/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch b/queue-6.12/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch new file mode 100644 index 0000000000..21dad6d60d --- /dev/null +++ b/queue-6.12/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch @@ -0,0 +1,40 @@ +From 0ee5dd8dccbabbe171e9a9badc8018c31ec2a252 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jan 2026 08:55:49 +0530 +Subject: drm/i915/acpi: free _DSM package when no connectors + +From: Kaushlendra Kumar + +[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ] + +acpi_evaluate_dsm_typed() returns an ACPI package in pkg. +When pkg->package.count == 0, we returned without freeing pkg, +leaking memory. Free pkg before returning on the empty case. + +Signed-off-by: Kaushlendra Kumar +Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects") +Reviewed-by: Jani Nikula +Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c +index c3b29a331d725..859fedb9d93ea 100644 +--- a/drivers/gpu/drm/i915/display/intel_acpi.c ++++ b/drivers/gpu/drm/i915/display/intel_acpi.c +@@ -93,6 +93,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle) + + if (!pkg->package.count) { + DRM_DEBUG_DRIVER("no connection in _DSM\n"); ++ ACPI_FREE(pkg); + return; + } + +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-add-xe_tile-backpointer-to-xe_mmio.patch b/queue-6.12/drm-xe-add-xe_tile-backpointer-to-xe_mmio.patch new file mode 100644 index 0000000000..5eb76b43dd --- /dev/null +++ b/queue-6.12/drm-xe-add-xe_tile-backpointer-to-xe_mmio.patch @@ -0,0 +1,94 @@ +From cc6ed325f74431c3804c32e79a79d1b0df1340c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:27 -0700 +Subject: drm/xe: Add xe_tile backpointer to xe_mmio + +From: Matt Roper + +[ Upstream commit 1877c88fa9b9bdbce7a65d7cbd2aa4e29bb514af ] + +Once MMIO operations stop being (incorrectly) tied to a GT, we'll still +need a backpointer for feature checks, message logging, and tracepoints. +Use a tile backpointer since that may allow the most useful debugging +output, while also providing access to the xe_device. + +v2: + - Make backpointer an xe_tile instead of xe_device. (Michal) + +Cc: Michal Wajdeczko +Reviewed-by: Lucas De Marchi # v1 +Signed-off-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-52-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_device_types.h | 3 +++ + drivers/gpu/drm/xe/xe_mmio.c | 3 +++ + drivers/gpu/drm/xe/xe_pci.c | 2 ++ + 3 files changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h +index 56630dabb85f7..ee3d0354c1539 100644 +--- a/drivers/gpu/drm/xe/xe_device_types.h ++++ b/drivers/gpu/drm/xe/xe_device_types.h +@@ -115,6 +115,9 @@ struct xe_mem_region { + * subregions of the overall IO space). + */ + struct xe_mmio { ++ /** @tile: Backpointer to tile, used for tracing */ ++ struct xe_tile *tile; ++ + /** @regs: Map used to access registers. */ + void __iomem *regs; + +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index 2f72516e01327..46924f4042418 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -98,6 +98,7 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size) + for_each_tile(tile, xe, id) { + tile->mmio.regs_size = SZ_4M; + tile->mmio.regs = regs; ++ tile->mmio.tile = tile; + regs += tile_mmio_size; + } + } +@@ -134,6 +135,7 @@ static void mmio_extension_setup(struct xe_device *xe, size_t tile_mmio_size, + for_each_tile(tile, xe, id) { + tile->mmio_ext.regs_size = tile_mmio_ext_size; + tile->mmio_ext.regs = regs; ++ tile->mmio_ext.tile = tile; + regs += tile_mmio_ext_size; + } + } +@@ -180,6 +182,7 @@ int xe_mmio_init(struct xe_device *xe) + /* Setup first tile; other tiles (if present) will be setup later. */ + root_tile->mmio.regs_size = SZ_4M; + root_tile->mmio.regs = xe->mmio.regs; ++ root_tile->mmio.tile = root_tile; + + return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe); + } +diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c +index f7b6ca281dec3..d0cc5d45a2e4b 100644 +--- a/drivers/gpu/drm/xe/xe_pci.c ++++ b/drivers/gpu/drm/xe/xe_pci.c +@@ -710,6 +710,7 @@ static int xe_info_init(struct xe_device *xe, + gt->info.engine_mask = graphics_desc->hw_engine_mask; + gt->mmio.regs = tile->mmio.regs; + gt->mmio.regs_size = tile->mmio.regs_size; ++ gt->mmio.tile = tile; + if (MEDIA_VER(xe) < 13 && media_desc) + gt->info.engine_mask |= media_desc->hw_engine_mask; + +@@ -732,6 +733,7 @@ static int xe_info_init(struct xe_device *xe, + gt->mmio.regs_size = tile->mmio.regs_size; + gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET; + gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH; ++ gt->mmio.tile = tile; + + /* + * FIXME: At the moment multi-tile and standalone media are +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-adjust-mmio-code-to-pass-vf-substructure-to-s.patch b/queue-6.12/drm-xe-adjust-mmio-code-to-pass-vf-substructure-to-s.patch new file mode 100644 index 0000000000..81f11c3cb6 --- /dev/null +++ b/queue-6.12/drm-xe-adjust-mmio-code-to-pass-vf-substructure-to-s.patch @@ -0,0 +1,75 @@ +From fe9092a84569df5233488f011de5b2a05f80bdbf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:28 -0700 +Subject: drm/xe: Adjust mmio code to pass VF substructure to SRIOV code + +From: Matt Roper + +[ Upstream commit 6fb5d1a1d376910700d054d13cefbf0812b444a9 ] + +Although we want to break the GT-centric nature of the MMIO code in the +general driver, the SRIOV handling still relies on data in a VF +substructure of the GT. So add a GT backpointer, but name it +sriov_vf_gt to make it clear that it's only for this one specific +special case and will not be set or usable for anything else. + +v2: + - Store backpointer to the GT itself rather than the SRIOV-specific + substructure. (Michal) + +Cc: Michal Wajdeczko +Reviewed-by: Lucas De Marchi # v1 +Signed-off-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-53-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_device_types.h | 8 ++++++++ + drivers/gpu/drm/xe/xe_pci.c | 5 +++++ + 2 files changed, 13 insertions(+) + +diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h +index ee3d0354c1539..78a1f8b78e269 100644 +--- a/drivers/gpu/drm/xe/xe_device_types.h ++++ b/drivers/gpu/drm/xe/xe_device_types.h +@@ -121,6 +121,14 @@ struct xe_mmio { + /** @regs: Map used to access registers. */ + void __iomem *regs; + ++ /** ++ * @sriov_vf_gt: Backpointer to GT. ++ * ++ * This pointer is only set for GT MMIO regions and only when running ++ * as an SRIOV VF structure ++ */ ++ struct xe_gt *sriov_vf_gt; ++ + /** + * @regs_size: Length of the register region within the map. + * +diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c +index d0cc5d45a2e4b..9d807d9a0807a 100644 +--- a/drivers/gpu/drm/xe/xe_pci.c ++++ b/drivers/gpu/drm/xe/xe_pci.c +@@ -711,6 +711,9 @@ static int xe_info_init(struct xe_device *xe, + gt->mmio.regs = tile->mmio.regs; + gt->mmio.regs_size = tile->mmio.regs_size; + gt->mmio.tile = tile; ++ if (IS_SRIOV_VF(xe)) ++ gt->mmio.sriov_vf_gt = gt; ++ + if (MEDIA_VER(xe) < 13 && media_desc) + gt->info.engine_mask |= media_desc->hw_engine_mask; + +@@ -734,6 +737,8 @@ static int xe_info_init(struct xe_device *xe, + gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET; + gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH; + gt->mmio.tile = tile; ++ if (IS_SRIOV_VF(xe)) ++ gt->mmio.sriov_vf_gt = gt; + + /* + * FIXME: At the moment multi-tile and standalone media are +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-clarify-size-of-mmio-region.patch b/queue-6.12/drm-xe-clarify-size-of-mmio-region.patch new file mode 100644 index 0000000000..8e38f7a276 --- /dev/null +++ b/queue-6.12/drm-xe-clarify-size-of-mmio-region.patch @@ -0,0 +1,100 @@ +From ba0a0a75c5684ad9ea99aa965674e1e0185b5d82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:23 -0700 +Subject: drm/xe: Clarify size of MMIO region + +From: Matt Roper + +[ Upstream commit d4aff99aefa2a3c8999a98f0d52a977b284b9ec9 ] + +xe_mmio currently has a size parameter that is assigned but never used +anywhere. The current values assigned appear to be the size of the BAR +region assigned for the tile (both for registers and other purposes such +as the GGTT). Since the current field isn't being used for anything, +change the assignments to 4MB (the size of the register region on all +current platform) and rename the field to 'regs_size' to more clearly +describe what it represents. We can use this value in later patches to +help ensure no register accesses accidentally go past the end of the +desired register space (which might not be caught easily if they still +fall within the iomap). + +v2: + - s/regs_length/regs_size/ (Lucas) + - Clarify kerneldoc description (Lucas) + +Reviewed-by: Lucas De Marchi +Signed-off-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-48-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_device_types.h | 10 ++++++++-- + drivers/gpu/drm/xe/xe_mmio.c | 10 ++++++++-- + 2 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h +index f06ff5571ab1c..57d778655dcbd 100644 +--- a/drivers/gpu/drm/xe/xe_device_types.h ++++ b/drivers/gpu/drm/xe/xe_device_types.h +@@ -119,8 +119,14 @@ struct xe_mmio { + /** @regs: Map used to access registers. */ + void __iomem *regs; + +- /** @size: Size of the map. */ +- size_t size; ++ /** ++ * @regs_size: Length of the register region within the map. ++ * ++ * The size of the iomap set in *regs is generally larger than the ++ * register mmio space since it includes unused regions and/or ++ * non-register regions such as the GGTT PTEs. ++ */ ++ size_t regs_size; + }; + + /** +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index 3fd462fda6255..f210e7470eae5 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -36,13 +36,19 @@ static void tiles_fini(void *arg) + /* + * On multi-tile devices, partition the BAR space for MMIO on each tile, + * possibly accounting for register override on the number of tiles available. ++ * tile_mmio_size contains both the tile's 4MB register space, as well as ++ * additional space for the GTT and other (possibly unused) regions). + * Resulting memory layout is like below: + * + * .----------------------. <- tile_count * tile_mmio_size + * | .... | + * |----------------------| <- 2 * tile_mmio_size ++ * | tile1 GTT + other | ++ * |----------------------| <- 1 * tile_mmio_size + 4MB + * | tile1->mmio.regs | + * |----------------------| <- 1 * tile_mmio_size ++ * | tile0 GTT + other | ++ * |----------------------| <- 4MB + * | tile0->mmio.regs | + * '----------------------' <- 0MB + */ +@@ -90,7 +96,7 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size) + + regs = xe->mmio.regs; + for_each_tile(tile, xe, id) { +- tile->mmio.size = tile_mmio_size; ++ tile->mmio.regs_size = SZ_4M; + tile->mmio.regs = regs; + regs += tile_mmio_size; + } +@@ -172,7 +178,7 @@ int xe_mmio_init(struct xe_device *xe) + } + + /* Setup first tile; other tiles (if present) will be setup later. */ +- root_tile->mmio.size = SZ_16M; ++ root_tile->mmio.regs_size = SZ_4M; + root_tile->mmio.regs = xe->mmio.regs; + + return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe); +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-create-dedicated-xe_mmio-structure.patch b/queue-6.12/drm-xe-create-dedicated-xe_mmio-structure.patch new file mode 100644 index 0000000000..3a54d8fa40 --- /dev/null +++ b/queue-6.12/drm-xe-create-dedicated-xe_mmio-structure.patch @@ -0,0 +1,73 @@ +From aafc2fdb917dec4782099d9c5753badbd379d4ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:22 -0700 +Subject: drm/xe: Create dedicated xe_mmio structure + +From: Matt Roper + +[ Upstream commit 34953ee349dde9d1733d4af75e929f7fd5fab539 ] + +Pull the 'mmio' substructure from xe_tile out into a dedicated type. +Future patches will expand this structure and then eventually move MMIO +read/write operations over to using this type. + +v2: + - Fix kerneldoc of 'size' field. The rename/refocusing of this field + got moved to the next patch of the series. (Lucas) + - Correct commit message; it's the tile, not the device, mmio that's + been pulled out to a separate type. (Michal) + +Reviewed-by: Lucas De Marchi +Signed-off-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-47-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_device_types.h | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h +index 687f3a9039bb1..f06ff5571ab1c 100644 +--- a/drivers/gpu/drm/xe/xe_device_types.h ++++ b/drivers/gpu/drm/xe/xe_device_types.h +@@ -107,6 +107,22 @@ struct xe_mem_region { + void __iomem *mapping; + }; + ++/** ++ * struct xe_mmio - register mmio structure ++ * ++ * Represents an MMIO region that the CPU may use to access registers. A ++ * region may share its IO map with other regions (e.g., all GTs within a ++ * tile share the same map with their parent tile, but represent different ++ * subregions of the overall IO space). ++ */ ++struct xe_mmio { ++ /** @regs: Map used to access registers. */ ++ void __iomem *regs; ++ ++ /** @size: Size of the map. */ ++ size_t size; ++}; ++ + /** + * struct xe_tile - hardware tile structure + * +@@ -148,13 +164,7 @@ struct xe_tile { + * * 4MB-8MB: reserved + * * 8MB-16MB: global GTT + */ +- struct { +- /** @mmio.size: size of tile's MMIO space */ +- size_t size; +- +- /** @mmio.regs: pointer to tile's MMIO space (starting with registers) */ +- void __iomem *regs; +- } mmio; ++ struct xe_mmio mmio; + + /** + * @mmio_ext: MMIO-extension info for a tile. +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch b/queue-6.12/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch new file mode 100644 index 0000000000..7213eeb52a --- /dev/null +++ b/queue-6.12/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch @@ -0,0 +1,61 @@ +From 5baf6a837a980fa4223241217bb9da5d9154e7bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 16:56:22 +0000 +Subject: drm/xe/mmio: Avoid double-adjust in 64-bit reads + +From: Shuicheng Lin + +[ Upstream commit 4a9b4e1fa52a6aaa1adbb7f759048df14afed54c ] + +xe_mmio_read64_2x32() was adjusting register addresses and then +calling xe_mmio_read32(), which applies the adjustment again. +This may shift accesses twice if adj_offset < adj_limit. There is +no issue currently, as for media gt, adj_offset > adj_limit, so +the 2nd adjust will be a no-op. But it may not work in future. + +To fix it, replace the adjusted-address comparison with a direct +sanity check that ensures the MMIO address adjustment cutoff never +falls within the 8-byte range of a 64-bit register. And let +xe_mmio_read32() handle address translation. + +v2: rewrite the sanity check in a more natural way. (Matt) +v3: Add Fixes tag. (Jani) + +Fixes: 07431945d8ae ("drm/xe: Avoid 64-bit register reads") +Reviewed-by: Matt Roper +Cc: Jani Nikula +Cc: Rodrigo Vivi +Signed-off-by: Shuicheng Lin +Link: https://patch.msgid.link/20260130165621.471408-2-shuicheng.lin@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit a30f999681126b128a43137793ac84b6a5b7443f) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_mmio.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index 9ea0973337eda..449e6c5636712 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -316,11 +316,11 @@ u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) + struct xe_reg reg_udw = { .addr = reg.addr + 0x4 }; + u32 ldw, udw, oldudw, retries; + +- reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr); +- reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr); +- +- /* we shouldn't adjust just one register address */ +- xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4); ++ /* ++ * The two dwords of a 64-bit register can never straddle the offset ++ * adjustment cutoff. ++ */ ++ xe_tile_assert(mmio->tile, !in_range(mmio->adj_limit, reg.addr + 1, 7)); + + oldudw = xe_mmio_read32(mmio, reg_udw); + for (retries = 5; retries; --retries) { +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-move-forcewake-to-gt.pm-substructure.patch b/queue-6.12/drm-xe-move-forcewake-to-gt.pm-substructure.patch new file mode 100644 index 0000000000..e870dd2229 --- /dev/null +++ b/queue-6.12/drm-xe-move-forcewake-to-gt.pm-substructure.patch @@ -0,0 +1,126 @@ +From d8e37c95399d9cb29a359d4f9eabf62dbcd338da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:21 -0700 +Subject: drm/xe: Move forcewake to 'gt.pm' substructure + +From: Matt Roper + +[ Upstream commit 998fde0647671c82f637e299026d951f9b155b37 ] + +Forcewake is a general GT power management concept that isn't specific +to MMIO register access. Move the forcewake information for a GT out of +the 'mmio' substruct and into a 'pm' substruct. Also use the gt_to_fw() +helper in a few more places where it was being open-coded. + +v2: + - Kerneldoc tweaks. (Lucas) + +Reviewed-by: Lucas De Marchi +Signed-off-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-46-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_device.h | 2 +- + drivers/gpu/drm/xe/xe_gt_types.h | 15 ++++++++++++--- + drivers/gpu/drm/xe/xe_reg_sr.c | 9 +++++---- + 3 files changed, 18 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h +index 34620ef855c0c..b662b7652431e 100644 +--- a/drivers/gpu/drm/xe/xe_device.h ++++ b/drivers/gpu/drm/xe/xe_device.h +@@ -138,7 +138,7 @@ static inline bool xe_device_uc_enabled(struct xe_device *xe) + + static inline struct xe_force_wake *gt_to_fw(struct xe_gt *gt) + { +- return >->mmio.fw; ++ return >->pm.fw; + } + + void xe_device_assert_mem_access(struct xe_device *xe); +diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h +index 3d1c51de02687..dd6bbef0bbcd8 100644 +--- a/drivers/gpu/drm/xe/xe_gt_types.h ++++ b/drivers/gpu/drm/xe/xe_gt_types.h +@@ -145,11 +145,9 @@ struct xe_gt { + /** + * @mmio: mmio info for GT. All GTs within a tile share the same + * register space, but have their own copy of GSI registers at a +- * specific offset, as well as their own forcewake handling. ++ * specific offset. + */ + struct { +- /** @mmio.fw: force wake for GT */ +- struct xe_force_wake fw; + /** + * @mmio.adj_limit: adjust MMIO address if address is below this + * value +@@ -159,6 +157,17 @@ struct xe_gt { + u32 adj_offset; + } mmio; + ++ /** ++ * @pm: power management info for GT. The driver uses the GT's ++ * "force wake" interface to wake up specific parts of the GT hardware ++ * from C6 sleep states and ensure the hardware remains awake while it ++ * is being actively used. ++ */ ++ struct { ++ /** @pm.fw: force wake for GT */ ++ struct xe_force_wake fw; ++ } pm; ++ + /** @sriov: virtualization data related to GT */ + union { + /** @sriov.pf: PF data. Valid only if driver is running as PF */ +diff --git a/drivers/gpu/drm/xe/xe_reg_sr.c b/drivers/gpu/drm/xe/xe_reg_sr.c +index 52969c0909659..d3773a9853872 100644 +--- a/drivers/gpu/drm/xe/xe_reg_sr.c ++++ b/drivers/gpu/drm/xe/xe_reg_sr.c +@@ -15,6 +15,7 @@ + + #include "regs/xe_engine_regs.h" + #include "regs/xe_gt_regs.h" ++#include "xe_device.h" + #include "xe_device_types.h" + #include "xe_force_wake.h" + #include "xe_gt.h" +@@ -175,14 +176,14 @@ void xe_reg_sr_apply_mmio(struct xe_reg_sr *sr, struct xe_gt *gt) + + xe_gt_dbg(gt, "Applying %s save-restore MMIOs\n", sr->name); + +- err = xe_force_wake_get(>->mmio.fw, XE_FORCEWAKE_ALL); ++ err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); + if (err) + goto err_force_wake; + + xa_for_each(&sr->xa, reg, entry) + apply_one_mmio(gt, entry); + +- err = xe_force_wake_put(>->mmio.fw, XE_FORCEWAKE_ALL); ++ err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); + XE_WARN_ON(err); + + return; +@@ -208,7 +209,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe) + + drm_dbg(&xe->drm, "Whitelisting %s registers\n", sr->name); + +- err = xe_force_wake_get(>->mmio.fw, XE_FORCEWAKE_ALL); ++ err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); + if (err) + goto err_force_wake; + +@@ -234,7 +235,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe) + xe_mmio_write32(gt, RING_FORCE_TO_NONPRIV(mmio_base, slot), addr); + } + +- err = xe_force_wake_put(>->mmio.fw, XE_FORCEWAKE_ALL); ++ err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); + XE_WARN_ON(err); + + return; +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-move-gsi-offset-adjustment-fields-into-struct.patch b/queue-6.12/drm-xe-move-gsi-offset-adjustment-fields-into-struct.patch new file mode 100644 index 0000000000..acd2ed4c9b --- /dev/null +++ b/queue-6.12/drm-xe-move-gsi-offset-adjustment-fields-into-struct.patch @@ -0,0 +1,149 @@ +From 0789611e82a8445cd9a5d6b5c6367c2f65dd7f6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:24 -0700 +Subject: drm/xe: Move GSI offset adjustment fields into 'struct xe_mmio' + +From: Matt Roper + +[ Upstream commit 9d383916a552784ec35e6d25469fc2da9bcd9948 ] + +By moving the GSI adjustment fields into 'struct xe_mmio' we can replace +the GT's MMIO substructure with another instance of xe_mmio. At the +moment this means MMIO operations wind up pulling information from two +different places (the tile's xe_mmio for the iomap and the GT's xe_mmio +for the adjustment), but we'll address that in future patches. + +The type headers change a bit with this change, meaning that various +files should be including xe_device_types.h instead of (or in addition +to) xe_gt_types.h. + +v2: + - Fix pre-existing kerneldoc typo while moving the fields (Lucas) +v3: + - Add missing '@' in kerneldoc. (Rodrigo) + +Cc: Rodrigo Vivi +Reviewed-by: Lucas De Marchi +Signed-off-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-49-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_assert.h | 2 +- + drivers/gpu/drm/xe/xe_device.h | 1 + + drivers/gpu/drm/xe/xe_device_types.h | 7 ++++++- + drivers/gpu/drm/xe/xe_gt_freq.c | 2 +- + drivers/gpu/drm/xe/xe_gt_printk.h | 2 +- + drivers/gpu/drm/xe/xe_gt_types.h | 11 ++--------- + 6 files changed, 12 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_assert.h b/drivers/gpu/drm/xe/xe_assert.h +index e22bbf57fca75..04d6b95c6d878 100644 +--- a/drivers/gpu/drm/xe/xe_assert.h ++++ b/drivers/gpu/drm/xe/xe_assert.h +@@ -10,7 +10,7 @@ + + #include + +-#include "xe_device_types.h" ++#include "xe_gt_types.h" + #include "xe_step.h" + + /** +diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h +index b662b7652431e..5dad24fc487ca 100644 +--- a/drivers/gpu/drm/xe/xe_device.h ++++ b/drivers/gpu/drm/xe/xe_device.h +@@ -9,6 +9,7 @@ + #include + + #include "xe_device_types.h" ++#include "xe_gt_types.h" + + static inline struct xe_device *to_xe_device(const struct drm_device *dev) + { +diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h +index 57d778655dcbd..2291ac1fa96e1 100644 +--- a/drivers/gpu/drm/xe/xe_device_types.h ++++ b/drivers/gpu/drm/xe/xe_device_types.h +@@ -14,7 +14,6 @@ + + #include "xe_devcoredump_types.h" + #include "xe_heci_gsc.h" +-#include "xe_gt_types.h" + #include "xe_lmtt_types.h" + #include "xe_memirq_types.h" + #include "xe_oa.h" +@@ -127,6 +126,12 @@ struct xe_mmio { + * non-register regions such as the GGTT PTEs. + */ + size_t regs_size; ++ ++ /** @adj_limit: adjust MMIO address if address is below this value */ ++ u32 adj_limit; ++ ++ /** @adj_offset: offset to add to MMIO address when adjusting */ ++ u32 adj_offset; + }; + + /** +diff --git a/drivers/gpu/drm/xe/xe_gt_freq.c b/drivers/gpu/drm/xe/xe_gt_freq.c +index a05fde2c7b122..62a8aa2fdbb0d 100644 +--- a/drivers/gpu/drm/xe/xe_gt_freq.c ++++ b/drivers/gpu/drm/xe/xe_gt_freq.c +@@ -11,9 +11,9 @@ + #include + #include + +-#include "xe_device_types.h" + #include "xe_gt_sysfs.h" + #include "xe_gt_throttle.h" ++#include "xe_gt_types.h" + #include "xe_guc_pc.h" + #include "xe_pm.h" + +diff --git a/drivers/gpu/drm/xe/xe_gt_printk.h b/drivers/gpu/drm/xe/xe_gt_printk.h +index d6228baaff1ef..5dc71394372d6 100644 +--- a/drivers/gpu/drm/xe/xe_gt_printk.h ++++ b/drivers/gpu/drm/xe/xe_gt_printk.h +@@ -8,7 +8,7 @@ + + #include + +-#include "xe_device_types.h" ++#include "xe_gt_types.h" + + #define xe_gt_printk(_gt, _level, _fmt, ...) \ + drm_##_level(>_to_xe(_gt)->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__) +diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h +index dd6bbef0bbcd8..a287b98ee70b4 100644 +--- a/drivers/gpu/drm/xe/xe_gt_types.h ++++ b/drivers/gpu/drm/xe/xe_gt_types.h +@@ -6,6 +6,7 @@ + #ifndef _XE_GT_TYPES_H_ + #define _XE_GT_TYPES_H_ + ++#include "xe_device_types.h" + #include "xe_force_wake_types.h" + #include "xe_gt_idle_types.h" + #include "xe_gt_sriov_pf_types.h" +@@ -147,15 +148,7 @@ struct xe_gt { + * register space, but have their own copy of GSI registers at a + * specific offset. + */ +- struct { +- /** +- * @mmio.adj_limit: adjust MMIO address if address is below this +- * value +- */ +- u32 adj_limit; +- /** @mmio.adj_offset: offect to add to MMIO address when adjusting */ +- u32 adj_offset; +- } mmio; ++ struct xe_mmio mmio; + + /** + * @pm: power management info for GT. The driver uses the GT's +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-populate-gt-s-mmio-iomap-from-tile-during-ini.patch b/queue-6.12/drm-xe-populate-gt-s-mmio-iomap-from-tile-during-ini.patch new file mode 100644 index 0000000000..4124136ab3 --- /dev/null +++ b/queue-6.12/drm-xe-populate-gt-s-mmio-iomap-from-tile-during-ini.patch @@ -0,0 +1,47 @@ +From 9e3477d518759a07742f5cfac9589e24ebe0a976 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:25 -0700 +Subject: drm/xe: Populate GT's mmio iomap from tile during init + +From: Matt Roper + +[ Upstream commit fa599b8c95a7070430703f4908a50141f2c7088c ] + +Each GT should share the same register iomap as its parent tile. Future +patches will switch to access the iomap through the GT's mmio substruct +rather than through the tile. + +Reviewed-by: Lucas De Marchi +Signed-off-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-50-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_pci.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c +index da09c26249f5f..f7b6ca281dec3 100644 +--- a/drivers/gpu/drm/xe/xe_pci.c ++++ b/drivers/gpu/drm/xe/xe_pci.c +@@ -708,6 +708,8 @@ static int xe_info_init(struct xe_device *xe, + gt->info.type = XE_GT_TYPE_MAIN; + gt->info.has_indirect_ring_state = graphics_desc->has_indirect_ring_state; + gt->info.engine_mask = graphics_desc->hw_engine_mask; ++ gt->mmio.regs = tile->mmio.regs; ++ gt->mmio.regs_size = tile->mmio.regs_size; + if (MEDIA_VER(xe) < 13 && media_desc) + gt->info.engine_mask |= media_desc->hw_engine_mask; + +@@ -726,6 +728,8 @@ static int xe_info_init(struct xe_device *xe, + gt->info.type = XE_GT_TYPE_MEDIA; + gt->info.has_indirect_ring_state = media_desc->has_indirect_ring_state; + gt->info.engine_mask = media_desc->hw_engine_mask; ++ gt->mmio.regs = tile->mmio.regs; ++ gt->mmio.regs_size = tile->mmio.regs_size; + gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET; + gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH; + +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-ptl-apply-wa_13011645652.patch b/queue-6.12/drm-xe-ptl-apply-wa_13011645652.patch new file mode 100644 index 0000000000..5f291c149e --- /dev/null +++ b/queue-6.12/drm-xe-ptl-apply-wa_13011645652.patch @@ -0,0 +1,36 @@ +From efcbe96c93bb1bd197bb7251e449ca330abff294 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Jan 2025 10:46:59 -0800 +Subject: drm/xe/ptl: Apply Wa_13011645652 + +From: Vinay Belgaumkar + +[ Upstream commit dddc53806dd2a10e210d5ea08caec6d3f92440b2 ] + +Extend Wa_13011645652 to PTL. + +Signed-off-by: Vinay Belgaumkar +Reviewed-by: Stuart Summers +Signed-off-by: Daniele Ceraolo Spurio +Link: https://patchwork.freedesktop.org/patch/msgid/20250116184659.384874-1-vinay.belgaumkar@intel.com +Stable-dep-of: bc6387a2e0c1 ("drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_wa_oob.rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules +index 93fa2708ee378..e726fcb307905 100644 +--- a/drivers/gpu/drm/xe/xe_wa_oob.rules ++++ b/drivers/gpu/drm/xe/xe_wa_oob.rules +@@ -27,6 +27,7 @@ + 16022287689 GRAPHICS_VERSION(2001) + GRAPHICS_VERSION(2004) + 13011645652 GRAPHICS_VERSION(2004) ++ GRAPHICS_VERSION(3001) + 14022293748 GRAPHICS_VERSION(2001) + GRAPHICS_VERSION(2004) + GRAPHICS_VERSION_RANGE(3000, 3001) +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-switch-mmio-interface-to-take-xe_mmio-instead.patch b/queue-6.12/drm-xe-switch-mmio-interface-to-take-xe_mmio-instead.patch new file mode 100644 index 0000000000..b7d3a820f4 --- /dev/null +++ b/queue-6.12/drm-xe-switch-mmio-interface-to-take-xe_mmio-instead.patch @@ -0,0 +1,437 @@ +From c65929728ab60cbbf4c24061d8f7c3bcfdc7dc8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:29 -0700 +Subject: drm/xe: Switch MMIO interface to take xe_mmio instead of xe_gt + +From: Matt Roper + +[ Upstream commit a84590c5ceb354d2e9f7f6812cfb3a9709e14afa ] + +Since much of the MMIO register access done by the driver is to non-GT +registers, use of 'xe_gt' in these interfaces has been a long-standing +design flaw that's been hard to disentangle. + +To avoid a flag day across the whole driver, munge the function names +and add temporary compatibility macros with the original function names +that can accept either the new xe_mmio or the old xe_gt structure as a +parameter. This will allow us to slowly convert parts of the driver +over to the new interface independently. + +Signed-off-by: Matt Roper +Reviewed-by: Rodrigo Vivi +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-54-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_mmio.c | 131 ++++++++++++++++------------------ + drivers/gpu/drm/xe/xe_mmio.h | 76 +++++++++++++++----- + drivers/gpu/drm/xe/xe_trace.h | 7 +- + 3 files changed, 126 insertions(+), 88 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index 46924f4042418..9ea0973337eda 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -67,16 +67,16 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size) + + /* Possibly override number of tile based on configuration register */ + if (!xe->info.skip_mtcfg) { +- struct xe_gt *gt = xe_root_mmio_gt(xe); ++ struct xe_mmio *mmio = xe_root_tile_mmio(xe); + u8 tile_count; + u32 mtcfg; + + /* + * Although the per-tile mmio regs are not yet initialized, this +- * is fine as it's going to the root gt, that's guaranteed to be +- * initialized earlier in xe_mmio_init() ++ * is fine as it's going to the root tile's mmio, that's ++ * guaranteed to be initialized earlier in xe_mmio_init() + */ +- mtcfg = xe_mmio_read64_2x32(gt, XEHP_MTCFG_ADDR); ++ mtcfg = xe_mmio_read64_2x32(mmio, XEHP_MTCFG_ADDR); + tile_count = REG_FIELD_GET(TILE_COUNT, mtcfg) + 1; + + if (tile_count < xe->info.tile_count) { +@@ -187,116 +187,111 @@ int xe_mmio_init(struct xe_device *xe) + return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe); + } + +-static void mmio_flush_pending_writes(struct xe_gt *gt) ++static void mmio_flush_pending_writes(struct xe_mmio *mmio) + { + #define DUMMY_REG_OFFSET 0x130030 +- struct xe_tile *tile = gt_to_tile(gt); + int i; + +- if (tile->xe->info.platform != XE_LUNARLAKE) ++ if (mmio->tile->xe->info.platform != XE_LUNARLAKE) + return; + + /* 4 dummy writes */ + for (i = 0; i < 4; i++) +- writel(0, tile->mmio.regs + DUMMY_REG_OFFSET); ++ writel(0, mmio->regs + DUMMY_REG_OFFSET); + } + +-u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg) ++u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg) + { +- struct xe_tile *tile = gt_to_tile(gt); +- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); ++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); + u8 val; + + /* Wa_15015404425 */ +- mmio_flush_pending_writes(gt); ++ mmio_flush_pending_writes(mmio); + +- val = readb((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr); +- trace_xe_reg_rw(gt, false, addr, val, sizeof(val)); ++ val = readb(mmio->regs + addr); ++ trace_xe_reg_rw(mmio, false, addr, val, sizeof(val)); + + return val; + } + +-u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg) ++u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg) + { +- struct xe_tile *tile = gt_to_tile(gt); +- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); ++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); + u16 val; + + /* Wa_15015404425 */ +- mmio_flush_pending_writes(gt); ++ mmio_flush_pending_writes(mmio); + +- val = readw((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr); +- trace_xe_reg_rw(gt, false, addr, val, sizeof(val)); ++ val = readw(mmio->regs + addr); ++ trace_xe_reg_rw(mmio, false, addr, val, sizeof(val)); + + return val; + } + +-void xe_mmio_write32(struct xe_gt *gt, struct xe_reg reg, u32 val) ++void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val) + { +- struct xe_tile *tile = gt_to_tile(gt); +- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); ++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); + +- trace_xe_reg_rw(gt, true, addr, val, sizeof(val)); ++ trace_xe_reg_rw(mmio, true, addr, val, sizeof(val)); + +- if (!reg.vf && IS_SRIOV_VF(gt_to_xe(gt))) +- xe_gt_sriov_vf_write32(gt, reg, val); ++ if (!reg.vf && mmio->sriov_vf_gt) ++ xe_gt_sriov_vf_write32(mmio->sriov_vf_gt, reg, val); + else +- writel(val, (reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr); ++ writel(val, mmio->regs + addr); + } + +-u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg) ++u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg) + { +- struct xe_tile *tile = gt_to_tile(gt); +- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); ++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); + u32 val; + + /* Wa_15015404425 */ +- mmio_flush_pending_writes(gt); ++ mmio_flush_pending_writes(mmio); + +- if (!reg.vf && IS_SRIOV_VF(gt_to_xe(gt))) +- val = xe_gt_sriov_vf_read32(gt, reg); ++ if (!reg.vf && mmio->sriov_vf_gt) ++ val = xe_gt_sriov_vf_read32(mmio->sriov_vf_gt, reg); + else +- val = readl((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr); ++ val = readl(mmio->regs + addr); + +- trace_xe_reg_rw(gt, false, addr, val, sizeof(val)); ++ trace_xe_reg_rw(mmio, false, addr, val, sizeof(val)); + + return val; + } + +-u32 xe_mmio_rmw32(struct xe_gt *gt, struct xe_reg reg, u32 clr, u32 set) ++u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set) + { + u32 old, reg_val; + +- old = xe_mmio_read32(gt, reg); ++ old = xe_mmio_read32(mmio, reg); + reg_val = (old & ~clr) | set; +- xe_mmio_write32(gt, reg, reg_val); ++ xe_mmio_write32(mmio, reg, reg_val); + + return old; + } + +-int xe_mmio_write32_and_verify(struct xe_gt *gt, +- struct xe_reg reg, u32 val, u32 mask, u32 eval) ++int __xe_mmio_write32_and_verify(struct xe_mmio *mmio, ++ struct xe_reg reg, u32 val, u32 mask, u32 eval) + { + u32 reg_val; + +- xe_mmio_write32(gt, reg, val); +- reg_val = xe_mmio_read32(gt, reg); ++ xe_mmio_write32(mmio, reg, val); ++ reg_val = xe_mmio_read32(mmio, reg); + + return (reg_val & mask) != eval ? -EINVAL : 0; + } + +-bool xe_mmio_in_range(const struct xe_gt *gt, +- const struct xe_mmio_range *range, +- struct xe_reg reg) ++bool __xe_mmio_in_range(const struct xe_mmio *mmio, ++ const struct xe_mmio_range *range, ++ struct xe_reg reg) + { +- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); ++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); + + return range && addr >= range->start && addr <= range->end; + } + + /** + * xe_mmio_read64_2x32() - Read a 64-bit register as two 32-bit reads +- * @gt: MMIO target GT ++ * @mmio: MMIO target + * @reg: register to read value from + * + * Although Intel GPUs have some 64-bit registers, the hardware officially +@@ -316,21 +311,21 @@ bool xe_mmio_in_range(const struct xe_gt *gt, + * + * Returns the value of the 64-bit register. + */ +-u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg) ++u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) + { + struct xe_reg reg_udw = { .addr = reg.addr + 0x4 }; + u32 ldw, udw, oldudw, retries; + +- reg.addr = xe_mmio_adjusted_addr(gt, reg.addr); +- reg_udw.addr = xe_mmio_adjusted_addr(gt, reg_udw.addr); ++ reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr); ++ reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr); + + /* we shouldn't adjust just one register address */ +- xe_gt_assert(gt, reg_udw.addr == reg.addr + 0x4); ++ xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4); + +- oldudw = xe_mmio_read32(gt, reg_udw); ++ oldudw = xe_mmio_read32(mmio, reg_udw); + for (retries = 5; retries; --retries) { +- ldw = xe_mmio_read32(gt, reg); +- udw = xe_mmio_read32(gt, reg_udw); ++ ldw = xe_mmio_read32(mmio, reg); ++ udw = xe_mmio_read32(mmio, reg_udw); + + if (udw == oldudw) + break; +@@ -338,14 +333,14 @@ u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg) + oldudw = udw; + } + +- xe_gt_WARN(gt, retries == 0, +- "64-bit read of %#x did not stabilize\n", reg.addr); ++ drm_WARN(&mmio->tile->xe->drm, retries == 0, ++ "64-bit read of %#x did not stabilize\n", reg.addr); + + return (u64)udw << 32 | ldw; + } + +-static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, +- u32 *out_val, bool atomic, bool expect_match) ++static int ____xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, ++ u32 *out_val, bool atomic, bool expect_match) + { + ktime_t cur = ktime_get_raw(); + const ktime_t end = ktime_add_us(cur, timeout_us); +@@ -355,7 +350,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v + bool check; + + for (;;) { +- read = xe_mmio_read32(gt, reg); ++ read = xe_mmio_read32(mmio, reg); + + check = (read & mask) == val; + if (!expect_match) +@@ -381,7 +376,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v + } + + if (ret != 0) { +- read = xe_mmio_read32(gt, reg); ++ read = xe_mmio_read32(mmio, reg); + + check = (read & mask) == val; + if (!expect_match) +@@ -399,7 +394,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v + + /** + * xe_mmio_wait32() - Wait for a register to match the desired masked value +- * @gt: MMIO target GT ++ * @mmio: MMIO target + * @reg: register to read value from + * @mask: mask to be applied to the value read from the register + * @val: desired value after applying the mask +@@ -416,15 +411,15 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v + * @timeout_us for different reasons, specially in non-atomic contexts. Thus, + * it is possible that this function succeeds even after @timeout_us has passed. + */ +-int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, +- u32 *out_val, bool atomic) ++int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, ++ u32 *out_val, bool atomic) + { +- return __xe_mmio_wait32(gt, reg, mask, val, timeout_us, out_val, atomic, true); ++ return ____xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, true); + } + + /** + * xe_mmio_wait32_not() - Wait for a register to return anything other than the given masked value +- * @gt: MMIO target GT ++ * @mmio: MMIO target + * @reg: register to read value from + * @mask: mask to be applied to the value read from the register + * @val: value not to be matched after applying the mask +@@ -435,8 +430,8 @@ int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 t + * This function works exactly like xe_mmio_wait32() with the exception that + * @val is expected not to be matched. + */ +-int xe_mmio_wait32_not(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, +- u32 *out_val, bool atomic) ++int __xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, ++ u32 *out_val, bool atomic) + { +- return __xe_mmio_wait32(gt, reg, mask, val, timeout_us, out_val, atomic, false); ++ return ____xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, false); + } +diff --git a/drivers/gpu/drm/xe/xe_mmio.h b/drivers/gpu/drm/xe/xe_mmio.h +index 26551410ecc87..ac6846447c52a 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.h ++++ b/drivers/gpu/drm/xe/xe_mmio.h +@@ -14,25 +14,67 @@ struct xe_reg; + int xe_mmio_init(struct xe_device *xe); + int xe_mmio_probe_tiles(struct xe_device *xe); + +-u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg); +-u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg); +-void xe_mmio_write32(struct xe_gt *gt, struct xe_reg reg, u32 val); +-u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg); +-u32 xe_mmio_rmw32(struct xe_gt *gt, struct xe_reg reg, u32 clr, u32 set); +-int xe_mmio_write32_and_verify(struct xe_gt *gt, struct xe_reg reg, u32 val, u32 mask, u32 eval); +-bool xe_mmio_in_range(const struct xe_gt *gt, const struct xe_mmio_range *range, struct xe_reg reg); +- +-u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg); +-int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, +- u32 *out_val, bool atomic); +-int xe_mmio_wait32_not(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, +- u32 *out_val, bool atomic); +- +-static inline u32 xe_mmio_adjusted_addr(const struct xe_gt *gt, u32 addr) ++/* ++ * Temporary transition helper for xe_gt -> xe_mmio conversion. Allows ++ * continued usage of xe_gt as a parameter to MMIO operations which now ++ * take an xe_mmio structure instead. Will be removed once the driver-wide ++ * conversion is complete. ++ */ ++#define __to_xe_mmio(ptr) \ ++ _Generic(ptr, \ ++ const struct xe_gt *: (&((const struct xe_gt *)(ptr))->mmio), \ ++ struct xe_gt *: (&((struct xe_gt *)(ptr))->mmio), \ ++ const struct xe_mmio *: (ptr), \ ++ struct xe_mmio *: (ptr)) ++ ++u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg); ++#define xe_mmio_read8(p, reg) __xe_mmio_read8(__to_xe_mmio(p), reg) ++ ++u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg); ++#define xe_mmio_read16(p, reg) __xe_mmio_read16(__to_xe_mmio(p), reg) ++ ++void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val); ++#define xe_mmio_write32(p, reg, val) __xe_mmio_write32(__to_xe_mmio(p), reg, val) ++ ++u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg); ++#define xe_mmio_read32(p, reg) __xe_mmio_read32(__to_xe_mmio(p), reg) ++ ++u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set); ++#define xe_mmio_rmw32(p, reg, clr, set) __xe_mmio_rmw32(__to_xe_mmio(p), reg, clr, set) ++ ++int __xe_mmio_write32_and_verify(struct xe_mmio *mmio, struct xe_reg reg, ++ u32 val, u32 mask, u32 eval); ++#define xe_mmio_write32_and_verify(p, reg, val, mask, eval) \ ++ __xe_mmio_write32_and_verify(__to_xe_mmio(p), reg, val, mask, eval) ++ ++bool __xe_mmio_in_range(const struct xe_mmio *mmio, ++ const struct xe_mmio_range *range, struct xe_reg reg); ++#define xe_mmio_in_range(p, range, reg) __xe_mmio_in_range(__to_xe_mmio(p), range, reg) ++ ++u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg); ++#define xe_mmio_read64_2x32(p, reg) __xe_mmio_read64_2x32(__to_xe_mmio(p), reg) ++ ++int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, ++ u32 timeout_us, u32 *out_val, bool atomic); ++#define xe_mmio_wait32(p, reg, mask, val, timeout_us, out_val, atomic) \ ++ __xe_mmio_wait32(__to_xe_mmio(p), reg, mask, val, timeout_us, out_val, atomic) ++ ++int __xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, ++ u32 val, u32 timeout_us, u32 *out_val, bool atomic); ++#define xe_mmio_wait32_not(p, reg, mask, val, timeout_us, out_val, atomic) \ ++ __xe_mmio_wait32_not(__to_xe_mmio(p), reg, mask, val, timeout_us, out_val, atomic) ++ ++static inline u32 __xe_mmio_adjusted_addr(const struct xe_mmio *mmio, u32 addr) + { +- if (addr < gt->mmio.adj_limit) +- addr += gt->mmio.adj_offset; ++ if (addr < mmio->adj_limit) ++ addr += mmio->adj_offset; + return addr; + } ++#define xe_mmio_adjusted_addr(p, addr) __xe_mmio_adjusted_addr(__to_xe_mmio(p), addr) ++ ++static inline struct xe_mmio *xe_root_tile_mmio(struct xe_device *xe) ++{ ++ return &xe->tiles[0].mmio; ++} + + #endif +diff --git a/drivers/gpu/drm/xe/xe_trace.h b/drivers/gpu/drm/xe/xe_trace.h +index 8573d7a87d840..91130ad8999cd 100644 +--- a/drivers/gpu/drm/xe/xe_trace.h ++++ b/drivers/gpu/drm/xe/xe_trace.h +@@ -21,6 +21,7 @@ + #include "xe_vm.h" + + #define __dev_name_xe(xe) dev_name((xe)->drm.dev) ++#define __dev_name_tile(tile) __dev_name_xe(tile_to_xe((tile))) + #define __dev_name_gt(gt) __dev_name_xe(gt_to_xe((gt))) + #define __dev_name_eq(q) __dev_name_gt((q)->gt) + +@@ -342,12 +343,12 @@ DEFINE_EVENT(xe_hw_fence, xe_hw_fence_try_signal, + ); + + TRACE_EVENT(xe_reg_rw, +- TP_PROTO(struct xe_gt *gt, bool write, u32 reg, u64 val, int len), ++ TP_PROTO(struct xe_mmio *mmio, bool write, u32 reg, u64 val, int len), + +- TP_ARGS(gt, write, reg, val, len), ++ TP_ARGS(mmio, write, reg, val, len), + + TP_STRUCT__entry( +- __string(dev, __dev_name_gt(gt)) ++ __string(dev, __dev_name_tile(mmio->tile)) + __field(u64, val) + __field(u32, reg) + __field(u16, write) +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-switch-mmio_ext-to-use-struct-xe_mmio.patch b/queue-6.12/drm-xe-switch-mmio_ext-to-use-struct-xe_mmio.patch new file mode 100644 index 0000000000..76fda48330 --- /dev/null +++ b/queue-6.12/drm-xe-switch-mmio_ext-to-use-struct-xe_mmio.patch @@ -0,0 +1,58 @@ +From ac1a34b188986528c1a427281dd36813bede4f05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:47:26 -0700 +Subject: drm/xe: Switch mmio_ext to use 'struct xe_mmio' + +From: Matt Roper + +[ Upstream commit 960a83799f5bb8634755f0593c591c53ff4acee8 ] + +The mmio_ext stuff is completely unused right now, but it isn't +providing any functionality that couldn't be treated as a regular mmio +space. + +Reviewed-by: Lucas De Marchi +Signed-off-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-51-matthew.d.roper@intel.com +Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_device_types.h | 8 +------- + drivers/gpu/drm/xe/xe_mmio.c | 2 +- + 2 files changed, 2 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h +index 2291ac1fa96e1..56630dabb85f7 100644 +--- a/drivers/gpu/drm/xe/xe_device_types.h ++++ b/drivers/gpu/drm/xe/xe_device_types.h +@@ -182,13 +182,7 @@ struct xe_tile { + * + * Each tile has its own additional 256MB (28-bit) MMIO-extension space. + */ +- struct { +- /** @mmio_ext.size: size of tile's additional MMIO-extension space */ +- size_t size; +- +- /** @mmio_ext.regs: pointer to tile's additional MMIO-extension space */ +- void __iomem *regs; +- } mmio_ext; ++ struct xe_mmio mmio_ext; + + /** @mem: memory management info for tile */ + struct { +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index f210e7470eae5..2f72516e01327 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -132,7 +132,7 @@ static void mmio_extension_setup(struct xe_device *xe, size_t tile_mmio_size, + + regs = xe->mmio.regs + tile_mmio_size * xe->info.tile_count; + for_each_tile(tile, xe, id) { +- tile->mmio_ext.size = tile_mmio_ext_size; ++ tile->mmio_ext.regs_size = tile_mmio_ext_size; + tile->mmio_ext.regs = regs; + regs += tile_mmio_ext_size; + } +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-xe2_hpg-add-set-of-workarounds.patch b/queue-6.12/drm-xe-xe2_hpg-add-set-of-workarounds.patch new file mode 100644 index 0000000000..b2143b1a97 --- /dev/null +++ b/queue-6.12/drm-xe-xe2_hpg-add-set-of-workarounds.patch @@ -0,0 +1,170 @@ +From 60a7c28547a24ee2b8901ac871103eafd1889669 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jun 2025 00:38:03 +0530 +Subject: drm/xe/xe2_hpg: Add set of workarounds + +From: Shekhar Chauhan + +[ Upstream commit a5d221924e13a22c83b682410dcf72422d1c68db ] + +Add set of workarounds for xe2_hpg. + +-v2: Fix xe2_hpg GMD version for some workarounds. +-v3: Removed extra Workaround (Matt Roper) + +Signed-off-by: Shekhar Chauhan +Signed-off-by: Dnyaneshwar Bhadane +Reviewed-by: Matt Roper +Signed-off-by: Matt Roper +Link: https://lore.kernel.org/r/20250605190804.1287289-3-dnyaneshwar.bhadane@intel.com +Stable-dep-of: bc6387a2e0c1 ("drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_wa.c | 46 ++++++++++++++++++------------ + drivers/gpu/drm/xe/xe_wa_oob.rules | 4 +-- + 2 files changed, 29 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c +index aea6034a81079..e8414a56332e7 100644 +--- a/drivers/gpu/drm/xe/xe_wa.c ++++ b/drivers/gpu/drm/xe/xe_wa.c +@@ -492,10 +492,6 @@ static const struct xe_rtp_entry_sr engine_was[] = { + XE_RTP_RULES(GRAPHICS_VERSION(2004), FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0_UDW, ENABLE_SMP_LD_RENDER_SURFACE_CONTROL)) + }, +- { XE_RTP_NAME("16018737384"), +- XE_RTP_RULES(GRAPHICS_VERSION(2004), FUNC(xe_rtp_match_first_render_or_compute)), +- XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS)) +- }, + /* + * These two workarounds are the same, just applying to different + * engines. Although Wa_18032095049 (for the RCS) isn't required on +@@ -522,31 +518,38 @@ static const struct xe_rtp_entry_sr engine_was[] = { + /* Xe2_HPG */ + + { XE_RTP_NAME("16018712365"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ++ FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0_UDW, XE2_ALLOC_DPA_STARVE_FIX_DIS)) + }, + { XE_RTP_NAME("16018737384"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED), ++ FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS)) + }, + { XE_RTP_NAME("14019988906"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ++ FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) + }, + { XE_RTP_NAME("14019877138"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ++ FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) + }, + { XE_RTP_NAME("14020338487"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ++ FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(ROW_CHICKEN3, XE2_EUPEND_CHK_FLUSH_DIS)) + }, + { XE_RTP_NAME("18032247524"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ++ FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0, SEQUENTIAL_ACCESS_UPGRADE_DISABLE)) + }, + { XE_RTP_NAME("14018471104"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ++ FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0_UDW, ENABLE_SMP_LD_RENDER_SURFACE_CONTROL)) + }, + /* +@@ -555,7 +558,7 @@ static const struct xe_rtp_entry_sr engine_was[] = { + * apply this to all engines for simplicity. + */ + { XE_RTP_NAME("16021639441"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002)), + XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0), + GHWSP_CSB_REPORT_DIS | + PPHWSP_CSB_AND_TIMESTAMP_REPORT_DIS, +@@ -567,11 +570,12 @@ static const struct xe_rtp_entry_sr engine_was[] = { + XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0, WR_REQ_CHAINING_DIS)) + }, + { XE_RTP_NAME("14021402888"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE)) + }, +- { XE_RTP_NAME("14021821874"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)), ++ { XE_RTP_NAME("14021821874, 14022954250"), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ++ FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, STK_ID_RESTRICT)) + }, + +@@ -730,7 +734,7 @@ static const struct xe_rtp_entry_sr lrc_was[] = { + XE_RTP_ACTIONS(SET(INSTPM(RENDER_RING_BASE), ENABLE_SEMAPHORE_POLL_BIT)) + }, + { XE_RTP_NAME("18033852989"), +- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2004), ENGINE_CLASS(RENDER)), ++ XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN1, DISABLE_BOTTOM_CLIP_RECTANGLE_TEST)) + }, + { XE_RTP_NAME("14021567978"), +@@ -763,7 +767,7 @@ static const struct xe_rtp_entry_sr lrc_was[] = { + XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN)) + }, + { XE_RTP_NAME("14019386621"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(VF_SCRATCHPAD, XE2_VFG_TED_CREDIT_INTERFACE_DISABLE)) + }, + { XE_RTP_NAME("14020756599"), +@@ -780,13 +784,17 @@ static const struct xe_rtp_entry_sr lrc_was[] = { + DIS_AUTOSTRIP)) + }, + { XE_RTP_NAME("15016589081"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX)) + }, + { XE_RTP_NAME("22021007897"), +- XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN4, SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE)) + }, ++ { XE_RTP_NAME("18033852989"), ++ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN1, DISABLE_BOTTOM_CLIP_RECTANGLE_TEST)) ++ }, + + /* Xe3_LPG */ + { XE_RTP_NAME("14021490052"), +diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules +index e726fcb307905..97d14b2119ecf 100644 +--- a/drivers/gpu/drm/xe/xe_wa_oob.rules ++++ b/drivers/gpu/drm/xe/xe_wa_oob.rules +@@ -28,10 +28,10 @@ + GRAPHICS_VERSION(2004) + 13011645652 GRAPHICS_VERSION(2004) + GRAPHICS_VERSION(3001) +-14022293748 GRAPHICS_VERSION(2001) ++14022293748 GRAPHICS_VERSION_RANGE(2001, 2002) + GRAPHICS_VERSION(2004) + GRAPHICS_VERSION_RANGE(3000, 3001) +-22019794406 GRAPHICS_VERSION(2001) ++22019794406 GRAPHICS_VERSION_RANGE(2001, 2002) + GRAPHICS_VERSION(2004) + GRAPHICS_VERSION_RANGE(3000, 3001) + 22019338487 MEDIA_VERSION(2000) +-- +2.51.0 + diff --git a/queue-6.12/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch b/queue-6.12/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch new file mode 100644 index 0000000000..3de85ec441 --- /dev/null +++ b/queue-6.12/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch @@ -0,0 +1,72 @@ +From 686f333a9d968b67e1ecd40354a69f02b722e3fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 14:05:09 -0800 +Subject: drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138 + +From: Matt Roper + +[ Upstream commit bc6387a2e0c1562faa56ce2a98cef50cab809e08 ] + +The PSS_CHICKEN register has been part of the RCS engine's LRC since it +was first introduced in Xe_LP. That means that any workarounds that +adjust its value (such as Wa_14019988906 and Wa_14019877138) need to be +implemented in the lrc_was[] table so that they become part of the +default LRC from which all subsequent LRCs are copied. Although these +workarounds were implemented correctly on most platforms, they were +incorrectly placed on the engine_was[] table for Xe2_HPG. + +Move the workarounds to the proper lrc_was[] table and switch the +'xe_rtp_match_first_render_or_compute' rule to specifically match the +RCS since that's the engine whose LRC manages the register. + +Bspec: 65182 +Fixes: 7f3ee7d88058 ("drm/xe/xe2hpg: Add initial GT workarounds") +Reviewed-by: Shekhar Chauhan +Link: https://patch.msgid.link/20260205220508.51905-2-matthew.d.roper@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit e04c609eedf4d6748ac0bcada4de1275b034fed6) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_wa.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c +index e8414a56332e7..a2af1a44b0e08 100644 +--- a/drivers/gpu/drm/xe/xe_wa.c ++++ b/drivers/gpu/drm/xe/xe_wa.c +@@ -527,16 +527,6 @@ static const struct xe_rtp_entry_sr engine_was[] = { + FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS)) + }, +- { XE_RTP_NAME("14019988906"), +- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), +- FUNC(xe_rtp_match_first_render_or_compute)), +- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) +- }, +- { XE_RTP_NAME("14019877138"), +- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), +- FUNC(xe_rtp_match_first_render_or_compute)), +- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) +- }, + { XE_RTP_NAME("14020338487"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), + FUNC(xe_rtp_match_first_render_or_compute)), +@@ -774,6 +764,14 @@ static const struct xe_rtp_entry_sr lrc_was[] = { + XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(WM_CHICKEN3, HIZ_PLANE_COMPRESSION_DIS)) + }, ++ { XE_RTP_NAME("14019988906"), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) ++ }, ++ { XE_RTP_NAME("14019877138"), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) ++ }, + { XE_RTP_NAME("14021490052"), + XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(FF_MODE, +-- +2.51.0 + diff --git a/queue-6.12/efi-fix-reservation-of-unaccepted-memory-table.patch b/queue-6.12/efi-fix-reservation-of-unaccepted-memory-table.patch new file mode 100644 index 0000000000..0de4e4a113 --- /dev/null +++ b/queue-6.12/efi-fix-reservation-of-unaccepted-memory-table.patch @@ -0,0 +1,62 @@ +From be91be9a5fe0fadfb98710636e5426ba45359686 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 10:49:56 +0000 +Subject: efi: Fix reservation of unaccepted memory table + +From: Kiryl Shutsemau (Meta) + +[ Upstream commit 0862438c90487e79822d5647f854977d50381505 ] + +The reserve_unaccepted() function incorrectly calculates the size of the +memblock reservation for the unaccepted memory table. It aligns the +size of the table, but fails to account for cases where the table's +starting physical address (efi.unaccepted) is not page-aligned. + +If the table starts at an offset within a page and its end crosses into +a subsequent page that the aligned size does not cover, the end of the +table will not be reserved. This can lead to the table being overwritten +or inaccessible, causing a kernel panic in accept_memory(). + +This issue was observed when starting Intel TDX VMs with specific memory +sizes (e.g., > 64GB). + +Fix this by calculating the end address first (including the unaligned +start) and then aligning it up, ensuring the entire range is covered +by the reservation. + +Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped") +Reported-by: Moritz Sanft +Signed-off-by: Kiryl Shutsemau (Meta) +Reviewed-by: Tom Lendacky +Acked-by: Mike Rapoport (Microsoft) +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/efi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index acabc856fe8a5..0d1a65879a358 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -667,13 +667,13 @@ static __init int match_config_table(const efi_guid_t *guid, + + static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted) + { +- phys_addr_t start, size; ++ phys_addr_t start, end; + + start = PAGE_ALIGN_DOWN(efi.unaccepted); +- size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size); ++ end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size); + +- memblock_add(start, size); +- memblock_reserve(start, size); ++ memblock_add(start, end - start); ++ memblock_reserve(start, end - start); + } + + int __init efi_config_parse_tables(const efi_config_table_t *config_tables, +-- +2.51.0 + diff --git a/queue-6.12/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch b/queue-6.12/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch new file mode 100644 index 0000000000..e7c8f79bea --- /dev/null +++ b/queue-6.12/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch @@ -0,0 +1,51 @@ +From 255bcfc211ce8fbedc9391729d82e053364a5266 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jan 2026 16:50:24 +0000 +Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot + +From: Jiasheng Jiang + +[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ] + +In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the +entry size ('esize') is retrieved from the log record without adequate +bounds checking. + +Specifically, the code calculates the end of the entry ('e2') using: + e2 = Add2Ptr(e1, esize); + +It then calculates the size for memmove using 'PtrOffset(e2, ...)', +which subtracts the end pointer from the buffer limit. If 'esize' is +maliciously large, 'e2' exceeds the used buffer size. This results in +a negative offset which, when cast to size_t for memmove, interprets +as a massive unsigned integer, leading to a heap buffer overflow. + +This commit adds a check to ensure that the entry size ('esize') strictly +fits within the remaining used space of the index header before performing +memory operations. + +Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fslog.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c +index d0d530f4e2b95..5afe00972924c 100644 +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3431,6 +3431,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, + + e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off)); + esize = le16_to_cpu(e1->size); ++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize) ++ goto dirty_vol; ++ + e2 = Add2Ptr(e1, esize); + + memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used))); +-- +2.51.0 + diff --git a/queue-6.12/fs-ntfs3-initialize-new-folios-before-use.patch b/queue-6.12/fs-ntfs3-initialize-new-folios-before-use.patch new file mode 100644 index 0000000000..1a30c20ed1 --- /dev/null +++ b/queue-6.12/fs-ntfs3-initialize-new-folios-before-use.patch @@ -0,0 +1,43 @@ +From cbc98ac10b0277652fb472b50ed7f433327e30d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 23:02:51 +0100 +Subject: fs/ntfs3: Initialize new folios before use + +From: Bartlomiej Kubik + +[ Upstream commit f223ebffa185cc8da934333c5a31ff2d4f992dc9 ] + +KMSAN reports an uninitialized value in longest_match_std(), invoked +from ntfs_compress_write(). When new folios are allocated without being +marked uptodate and ni_read_frame() is skipped because the caller expects +the frame to be completely overwritten, some reserved folios may remain +only partially filled, leaving the rest memory uninitialized. + +Fixes: 584f60ba22f7 ("ntfs3: Convert ntfs_get_frame_pages() to use a folio") +Tested-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com +Reported-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=08d8956768c96a2c52cf + +Signed-off-by: Bartlomiej Kubik +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index f1122ac5be622..23a637cdb0810 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -964,7 +964,7 @@ static int ntfs_get_frame_pages(struct address_space *mapping, pgoff_t index, + + folio = __filemap_get_folio(mapping, index, + FGP_LOCK | FGP_ACCESSED | FGP_CREAT, +- gfp_mask); ++ gfp_mask | __GFP_ZERO); + if (IS_ERR(folio)) { + while (npages--) { + folio = page_folio(pages[npages]); +-- +2.51.0 + diff --git a/queue-6.12/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch b/queue-6.12/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch new file mode 100644 index 0000000000..cae5b0bdcd --- /dev/null +++ b/queue-6.12/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch @@ -0,0 +1,58 @@ +From 4471670577adc7f907688e5f3316bce9575d7f07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Dec 2025 11:53:25 +0800 +Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the + same + +From: Edward Adam Davis + +[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ] + +When processing valid within the range [valid : pos), if valid cannot +be retrieved correctly, for example, if the retrieved valid value is +always the same, this can trigger a potential infinite loop, similar +to the hung problem reported by syzbot [1]. + +Adding a check for the valid value within the loop body, and terminating +the loop and returning -EINVAL if the value is the same as the current +value, can prevent this. + +[1] +INFO: task syz.4.21:6056 blocked for more than 143 seconds. +Call Trace: + rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244 + inode_lock include/linux/fs.h:1027 [inline] + ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1 +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index 23a637cdb0810..3f144a049d710 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -1045,8 +1045,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) + goto out; + + if (lcn == SPARSE_LCN) { +- ni->i_valid = valid = +- frame_vbo + ((u64)clen << sbi->cluster_bits); ++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits); ++ if (ni->i_valid == valid) { ++ err = -EINVAL; ++ goto out; ++ } ++ ni->i_valid = valid; + continue; + } + +-- +2.51.0 + diff --git a/queue-6.12/icmp-prevent-possible-overflow-in-icmp_global_allow.patch b/queue-6.12/icmp-prevent-possible-overflow-in-icmp_global_allow.patch new file mode 100644 index 0000000000..d585377502 --- /dev/null +++ b/queue-6.12/icmp-prevent-possible-overflow-in-icmp_global_allow.patch @@ -0,0 +1,41 @@ +From b90ca27cb0396eecd61d26411e0b8582d27ff4f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:28 +0000 +Subject: icmp: prevent possible overflow in icmp_global_allow() + +From: Eric Dumazet + +[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ] + +Following expression can overflow +if sysctl_icmp_msgs_per_sec is big enough. + +sysctl_icmp_msgs_per_sec * delta / HZ; + +Fixes: 4cdf507d5452 ("icmp: add a global rate limitation") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/icmp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index ee24728fc60bf..8ab51b51cc9b2 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -247,7 +247,8 @@ bool icmp_global_allow(struct net *net) + if (delta < HZ / 50) + return false; + +- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; ++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec); ++ incr = div_u64((u64)incr * delta, HZ); + if (!incr) + return false; + +-- +2.51.0 + diff --git a/queue-6.12/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch b/queue-6.12/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch new file mode 100644 index 0000000000..192e0a40d0 --- /dev/null +++ b/queue-6.12/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch @@ -0,0 +1,57 @@ +From 4b724a8256691d363dec1ebe2d2d5bfbf6d3b3f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:29 +0000 +Subject: inet: move icmp_global_{credit,stamp} to a separate cache line + +From: Eric Dumazet + +[ Upstream commit 87b08913a9ae82082e276d237ece08fc8ee24380 ] + +icmp_global_credit was meant to be changed ~1000 times per second, +but if an admin sets net.ipv4.icmp_msgs_per_sec to a very high value, +icmp_global_credit changes can inflict false sharing to surrounding +fields that are read mostly. + +Move icmp_global_credit and icmp_global_stamp to a separate +cacheline aligned group. + +Fixes: b056b4cd9178 ("icmp: move icmp_global.credit and icmp_global.stamp to per netns storage") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/netns/ipv4.h | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 276f622f35168..a15e9366175ec 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -80,6 +80,12 @@ struct netns_ipv4 { + int sysctl_tcp_rmem[3]; + __cacheline_group_end(netns_ipv4_read_rx); + ++ /* ICMP rate limiter hot cache line. */ ++ __cacheline_group_begin_aligned(icmp); ++ atomic_t icmp_global_credit; ++ u32 icmp_global_stamp; ++ __cacheline_group_end_aligned(icmp); ++ + struct inet_timewait_death_row tcp_death_row; + struct udp_table *udp_table; + +@@ -124,8 +130,7 @@ struct netns_ipv4 { + int sysctl_icmp_ratemask; + int sysctl_icmp_msgs_per_sec; + int sysctl_icmp_msgs_burst; +- atomic_t icmp_global_credit; +- u32 icmp_global_stamp; ++ + u32 ip_rt_min_pmtu; + int ip_rt_mtu_expires; + int ip_rt_min_advmss; +-- +2.51.0 + diff --git a/queue-6.12/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch b/queue-6.12/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch new file mode 100644 index 0000000000..e97b922937 --- /dev/null +++ b/queue-6.12/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch @@ -0,0 +1,53 @@ +From d86a349ae4f2bc297babe4e9ebea98f60c6f8e86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:22:02 +0000 +Subject: ipv6: fix a race in ip6_sock_set_v6only() + +From: Eric Dumazet + +[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ] + +It is unlikely that this function will be ever called +with isk->inet_num being not zero. + +Perform the check on isk->inet_num inside the locked section +for complete safety. + +Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Fernando Fernandez Mancera +Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/ipv6.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 6d52b5584d2fb..2651bd76e5b75 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -1275,12 +1275,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, + + static inline int ip6_sock_set_v6only(struct sock *sk) + { +- if (inet_sk(sk)->inet_num) +- return -EINVAL; ++ int ret = 0; ++ + lock_sock(sk); +- sk->sk_ipv6only = true; ++ if (inet_sk(sk)->inet_num) ++ ret = -EINVAL; ++ else ++ sk->sk_ipv6only = true; + release_sock(sk); +- return 0; ++ return ret; + } + + static inline void ip6_sock_set_recverr(struct sock *sk) +-- +2.51.0 + diff --git a/queue-6.12/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch b/queue-6.12/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch new file mode 100644 index 0000000000..773ae426e8 --- /dev/null +++ b/queue-6.12/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch @@ -0,0 +1,125 @@ +From 5d3b9b8035876d7c8864999ac54b972e51aeb4a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:50:21 +0000 +Subject: ipv6: Fix out-of-bound access in fib6_add_rt2node(). + +From: Kuniyuki Iwashima + +[ Upstream commit 8244f959e2c125c849e569f5b23ed49804cce695 ] + +syzbot reported out-of-bound read in fib6_add_rt2node(). [0] + +When IPv6 route is created with RTA_NH_ID, struct fib6_info +does not have the trailing struct fib6_nh. + +The cited commit started to check !iter->fib6_nh->fib_nh_gw_family +to ensure that rt6_qualify_for_ecmp() will return false for iter. + +If iter->nh is not NULL, rt6_qualify_for_ecmp() returns false anyway. + +Let's check iter->nh before reading iter->fib6_nh and avoid OOB read. + +[0]: +BUG: KASAN: slab-out-of-bounds in fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142 +Read of size 1 at addr ffff8880384ba6de by task syz.0.18/5500 + +CPU: 0 UID: 0 PID: 5500 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full) +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +Call Trace: + + dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:378 [inline] + print_report+0xba/0x230 mm/kasan/report.c:482 + kasan_report+0x117/0x150 mm/kasan/report.c:595 + fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142 + fib6_add_rt2node_nh net/ipv6/ip6_fib.c:1363 [inline] + fib6_add+0x910/0x18c0 net/ipv6/ip6_fib.c:1531 + __ip6_ins_rt net/ipv6/route.c:1351 [inline] + ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3957 + inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660 + rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f9316b9aeb9 +Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007ffd8809b678 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00007f9316e15fa0 RCX: 00007f9316b9aeb9 +RDX: 0000000000000000 RSI: 0000200000004380 RDI: 0000000000000003 +RBP: 00007f9316c08c1f R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007f9316e15fac R14: 00007f9316e15fa0 R15: 00007f9316e15fa0 + + +Allocated by task 5499: + kasan_save_stack mm/kasan/common.c:57 [inline] + kasan_save_track+0x3e/0x80 mm/kasan/common.c:78 + poison_kmalloc_redzone mm/kasan/common.c:398 [inline] + __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415 + kasan_kmalloc include/linux/kasan.h:263 [inline] + __do_kmalloc_node mm/slub.c:5657 [inline] + __kmalloc_noprof+0x40c/0x7e0 mm/slub.c:5669 + kmalloc_noprof include/linux/slab.h:961 [inline] + kzalloc_noprof include/linux/slab.h:1094 [inline] + fib6_info_alloc+0x30/0xf0 net/ipv6/ip6_fib.c:155 + ip6_route_info_create+0x142/0x860 net/ipv6/route.c:3820 + ip6_route_add+0x49/0x1b0 net/ipv6/route.c:3949 + inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660 + rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Fixes: bbf4a17ad9ff ("ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF") +Reported-by: syzbot+707d6a5da1ab9e0c6f9d@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/698cbfba.050a0220.2eeac1.009d.GAE@google.com/ +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Fernando Fernandez Mancera +Reviewed-by: Shigeru Yoshida +Link: https://patch.msgid.link/20260211175133.3657034-1-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index d83430f4a0eff..01c953a39211a 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1139,7 +1139,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_add_gc_list(iter); + } + if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) && +- !iter->fib6_nh->fib_nh_gw_family) { ++ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) { + iter->fib6_flags &= ~RTF_ADDRCONF; + iter->fib6_flags &= ~RTF_PREFIX_RT; + } +-- +2.51.0 + diff --git a/queue-6.12/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch b/queue-6.12/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch new file mode 100644 index 0000000000..8737458b2b --- /dev/null +++ b/queue-6.12/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch @@ -0,0 +1,129 @@ +From f4066fcb6ffb4acf2ae0c3d1b36fa8ce784eac35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 16:58:50 +0200 +Subject: ipvs: do not keep dest_dst if dev is going down + +From: Julian Anastasov + +[ Upstream commit 8fde939b0206afc1d5846217a01a16b9bc8c7896 ] + +There is race between the netdev notifier ip_vs_dst_event() +and the code that caches dst with dev that is going down. +As the FIB can be notified for the closed device after our +handler finishes, it is possible valid route to be returned +and cached resuling in a leaked dev reference until the dest +is not removed. + +To prevent new dest_dst to be attached to dest just after the +handler dropped the old one, add a netif_running() check +to make sure the notifier handler is not currently running +for device that is closing. + +Fixes: 7a4f0761fce3 ("IPVS: init and cleanup restructuring") +Signed-off-by: Julian Anastasov +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_xmit.c | 46 ++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 10 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c +index fa2db17f6298b..8892f261451e9 100644 +--- a/net/netfilter/ipvs/ip_vs_xmit.c ++++ b/net/netfilter/ipvs/ip_vs_xmit.c +@@ -295,6 +295,12 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs, + return true; + } + ++/* rt has device that is down */ ++static bool rt_dev_is_down(const struct net_device *dev) ++{ ++ return dev && !netif_running(dev); ++} ++ + /* Get route to destination or remote server */ + static int + __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, +@@ -310,9 +316,11 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + + if (dest) { + dest_dst = __ip_vs_dst_check(dest); +- if (likely(dest_dst)) ++ if (likely(dest_dst)) { + rt = dst_rtable(dest_dst->dst_cache); +- else { ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.ip; ++ } else { + dest_dst = ip_vs_dest_dst_alloc(); + spin_lock_bh(&dest->dst_lock); + if (!dest_dst) { +@@ -328,14 +336,22 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + ip_vs_dest_dst_free(dest_dst); + goto err_unreach; + } +- __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0); ++ /* It is forbidden to attach dest->dest_dst if ++ * device is going down. ++ */ ++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst))) ++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0); ++ else ++ noref = 0; + spin_unlock_bh(&dest->dst_lock); + IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d\n", + &dest->addr.ip, &dest_dst->dst_saddr.ip, + rcuref_read(&rt->dst.__rcuref)); ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.ip; ++ if (!noref) ++ ip_vs_dest_dst_free(dest_dst); + } +- if (ret_saddr) +- *ret_saddr = dest_dst->dst_saddr.ip; + } else { + noref = 0; + +@@ -472,9 +488,11 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + + if (dest) { + dest_dst = __ip_vs_dst_check(dest); +- if (likely(dest_dst)) ++ if (likely(dest_dst)) { + rt = dst_rt6_info(dest_dst->dst_cache); +- else { ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.in6; ++ } else { + u32 cookie; + + dest_dst = ip_vs_dest_dst_alloc(); +@@ -495,14 +513,22 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + } + rt = dst_rt6_info(dst); + cookie = rt6_get_cookie(rt); +- __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie); ++ /* It is forbidden to attach dest->dest_dst if ++ * device is going down. ++ */ ++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst))) ++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie); ++ else ++ noref = 0; + spin_unlock_bh(&dest->dst_lock); + IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n", + &dest->addr.in6, &dest_dst->dst_saddr.in6, + rcuref_read(&rt->dst.__rcuref)); ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.in6; ++ if (!noref) ++ ip_vs_dest_dst_free(dest_dst); + } +- if (ret_saddr) +- *ret_saddr = dest_dst->dst_saddr.in6; + } else { + noref = 0; + dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm, +-- +2.51.0 + diff --git a/queue-6.12/kbuild-add-objtool-to-top-level-clean-target.patch b/queue-6.12/kbuild-add-objtool-to-top-level-clean-target.patch new file mode 100644 index 0000000000..cad7798d73 --- /dev/null +++ b/queue-6.12/kbuild-add-objtool-to-top-level-clean-target.patch @@ -0,0 +1,71 @@ +From b7a603cf51c5e4f6118e5f1e151febf2f98127a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 13:45:22 -0800 +Subject: kbuild: Add objtool to top-level clean target + +From: Josh Poimboeuf + +[ Upstream commit 68b4fe32d73789dea23e356f468de67c8367ef8f ] + +Objtool is an integral part of the build, make sure it gets cleaned by +"make clean" and "make mrproper". + +Fixes: 442f04c34a1a ("objtool: Add tool to perform compile-time stack metadata validation") +Reported-by: Jens Remus +Closes: https://lore.kernel.org/15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com +Signed-off-by: Josh Poimboeuf +Tested-by: Jens Remus +Link: https://patch.msgid.link/968faf2ed30fa8b3519f79f01a1ecfe7929553e5.1770759919.git.jpoimboe@kernel.org +[nathan: use Closes: instead of Link: per checkpatch.pl] +Signed-off-by: Nathan Chancellor +Signed-off-by: Sasha Levin +--- + Makefile | 11 ++++++++++- + tools/objtool/Makefile | 2 ++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 94c1c8c7f899f..4193928df50c8 100644 +--- a/Makefile ++++ b/Makefile +@@ -1370,6 +1370,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),) + $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean + endif + ++PHONY += objtool_clean ++ ++objtool_O = $(abspath $(objtree))/tools/objtool ++ ++objtool_clean: ++ifneq ($(wildcard $(objtool_O)),) ++ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean ++endif ++ + tools/: FORCE + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ +@@ -1527,7 +1536,7 @@ vmlinuxclean: + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean + $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean) + +-clean: archclean vmlinuxclean resolve_btfids_clean ++clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean + + # mrproper - Delete all generated files, including .config + # +diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile +index bf7f7f84ac625..02d1fccd495f4 100644 +--- a/tools/objtool/Makefile ++++ b/tools/objtool/Makefile +@@ -7,6 +7,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR))) + srctree := $(patsubst %/,%,$(dir $(srctree))) + endif + ++RM ?= rm -f ++ + LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ + ifneq ($(OUTPUT),) + LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd +-- +2.51.0 + diff --git a/queue-6.12/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch b/queue-6.12/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch new file mode 100644 index 0000000000..62a08aca8e --- /dev/null +++ b/queue-6.12/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch @@ -0,0 +1,116 @@ +From ed868f36e6c9d93623a543193eba2732a397e5d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:25:57 +0000 +Subject: macvlan: observe an RCU grace period in macvlan_common_newlink() + error path + +From: Eric Dumazet + +[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ] + +valis reported that a race condition still happens after my prior patch. + +macvlan_common_newlink() might have made @dev visible before +detecting an error, and its caller will directly call free_netdev(dev). + +We must respect an RCU period, either in macvlan or the core networking +stack. + +After adding a temporary mdelay(1000) in macvlan_forward_source_one() +to open the race window, valis repro was: + +ip link add p1 type veth peer p2 +ip link set address 00:00:00:00:00:20 dev p1 +ip link set up dev p1 +ip link set up dev p2 +ip link add mv0 link p2 type macvlan mode source + +(ip link add invalid% link p2 type macvlan mode source macaddr add +00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4 +PING 1.2.3.4 (1.2.3.4): 56 data bytes +RTNETLINK answers: Invalid argument + +BUG: KASAN: slab-use-after-free in macvlan_forward_source +(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +Read of size 8 at addr ffff888016bb89c0 by task e/175 + +CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +Call Trace: + +dump_stack_lvl (lib/dump_stack.c:123) +print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +kasan_report (mm/kasan/report.c:597) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +? tasklet_init (kernel/softirq.c:983) +macvlan_handle_frame (drivers/net/macvlan.c:501) + +Allocated by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +__kasan_kmalloc (mm/kasan/common.c:419) +__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657 +mm/slub.c:7140) +alloc_netdev_mqs (net/core/dev.c:12012) +rtnl_create_link (net/core/rtnetlink.c:3648) +rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Freed by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +kasan_save_free_info (mm/kasan/generic.c:587) +__kasan_slab_free (mm/kasan/common.c:287) +kfree (mm/slub.c:6674 mm/slub.c:6882) +rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()") +Signed-off-by: Eric Dumazet +Reported-by: valis +Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index aaf7d755fc8a1..3770bc84a9445 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1568,6 +1568,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, + if (create) + macvlan_port_destroy(port->dev); + } ++ /* @dev might have been made visible before an error was detected. ++ * Make sure to observe an RCU grace period before our caller ++ * (rtnl_newlink()) frees it. ++ */ ++ synchronize_net(); + return err; + } + EXPORT_SYMBOL_GPL(macvlan_common_newlink); +-- +2.51.0 + diff --git a/queue-6.12/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch b/queue-6.12/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch new file mode 100644 index 0000000000..1fab42af55 --- /dev/null +++ b/queue-6.12/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch @@ -0,0 +1,192 @@ +From aad79e3275af722bcaa51a4ef7bba63109432ee2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 09:00:30 +0200 +Subject: net: bridge: mcast: always update mdb_n_entries for vlan contexts + +From: Nikolay Aleksandrov + +[ Upstream commit 8b769e311a86bb9d15c5658ad283b86fc8f080a2 ] + +syzbot triggered a warning[1] about the number of mdb entries in a context. +It turned out that there are multiple ways to trigger that warning today +(some got added during the years), the root cause of the problem is that +the increase is done conditionally, and over the years these different +conditions increased so there were new ways to trigger the warning, that is +to do a decrease which wasn't paired with a previous increase. + +For example one way to trigger it is with flush: + $ ip l add br0 up type bridge vlan_filtering 1 mcast_snooping 1 + $ ip l add dumdum up master br0 type dummy + $ bridge mdb add dev br0 port dumdum grp 239.0.0.1 permanent vid 1 + $ ip link set dev br0 down + $ ip link set dev br0 type bridge mcast_vlan_snooping 1 + ^^^^ this will enable snooping, but will not update mdb_n_entries + because in __br_multicast_enable_port_ctx() we check !netif_running + $ bridge mdb flush dev br0 + ^^^ this will trigger the warning because it will delete the pg which + we added above, which will try to decrease mdb_n_entries + +Fix the problem by removing the conditional increase and always keep the +count up-to-date while the vlan exists. In order to do that we have to +first initialize it on port-vlan context creation, and then always increase +or decrease the value regardless of mcast options. To keep the current +behaviour we have to enforce the mdb limit only if the context is port's or +if the port-vlan's mcast snooping is enabled. + +[1] + ------------[ cut here ]------------ + n == 0 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline], CPU#0: syz.4.4607/22043 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline], CPU#0: syz.4.4607/22043 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825, CPU#0: syz.4.4607/22043 + Modules linked in: + CPU: 0 UID: 0 PID: 22043 Comm: syz.4.4607 Not tainted syzkaller #0 PREEMPT(full) + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026 + RIP: 0010:br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline] + RIP: 0010:br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline] + RIP: 0010:br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825 + Code: 41 5f 5d e9 04 7a 48 f7 e8 3f 73 5c f7 90 0f 0b 90 e9 cf fd ff ff e8 31 73 5c f7 90 0f 0b 90 e9 16 fd ff ff e8 23 73 5c f7 90 <0f> 0b 90 e9 60 fd ff ff e8 15 73 5c f7 eb 05 e8 0e 73 5c f7 48 8b + RSP: 0018:ffffc9000c207220 EFLAGS: 00010293 + RAX: ffffffff8a68042d RBX: ffff88807c6f1800 RCX: ffff888066e90000 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: 0000000000000000 R08: ffff888066e90000 R09: 000000000000000c + R10: 000000000000000c R11: 0000000000000000 R12: ffff8880303ef800 + R13: dffffc0000000000 R14: ffff888050eb11c4 R15: 1ffff1100a1d6238 + FS: 00007fa45921b6c0(0000) GS:ffff8881256f5000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007fa4591f9ff8 CR3: 0000000081df2000 CR4: 00000000003526f0 + Call Trace: + + br_mdb_flush_pgs net/bridge/br_mdb.c:1525 [inline] + br_mdb_flush net/bridge/br_mdb.c:1544 [inline] + br_mdb_del_bulk+0x5e2/0xb20 net/bridge/br_mdb.c:1561 + rtnl_mdb_del+0x48a/0x640 net/core/rtnetlink.c:-1 + rtnetlink_rcv_msg+0x77e/0xbe0 net/core/rtnetlink.c:6967 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + RIP: 0033:0x7fa45839aeb9 + Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48 + RSP: 002b:00007fa45921b028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e + RAX: ffffffffffffffda RBX: 00007fa458615fa0 RCX: 00007fa45839aeb9 + RDX: 0000000000000000 RSI: 00002000000000c0 RDI: 0000000000000004 + RBP: 00007fa458408c1f R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 + R13: 00007fa458616038 R14: 00007fa458615fa0 R15: 00007fff0b59fae8 + + +Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port") +Reported-by: syzbot+d5d1b7343531d17bd3c5@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/aYrWbRp83MQR1ife@debil/T/#t +Reviewed-by: Ido Schimmel +Signed-off-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20260213070031.1400003-2-nikolay@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/bridge/br_multicast.c | 45 ++++++++++++++++----------------------- + 1 file changed, 18 insertions(+), 27 deletions(-) + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 4227894e35792..9bd2914006df7 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -244,14 +244,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid) + + lockdep_assert_held_once(&port->br->multicast_lock); + +- if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) +- return NULL; +- + /* Take RCU to access the vlan. */ + rcu_read_lock(); + + vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid); +- if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx)) ++ if (vlan) + pmctx = &vlan->port_mcast_ctx; + + rcu_read_unlock(); +@@ -701,7 +698,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx, + u32 max = READ_ONCE(pmctx->mdb_max_entries); + u32 n = READ_ONCE(pmctx->mdb_n_entries); + +- if (max && n >= max) { ++ /* enforce the max limit when it's a port pmctx or a port-vlan pmctx ++ * with snooping enabled ++ */ ++ if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) { + NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u", + what, n, max); + return -E2BIG; +@@ -736,9 +736,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port, + return err; + } + +- /* Only count on the VLAN context if VID is given, and if snooping on +- * that VLAN is enabled. +- */ ++ /* Only count on the VLAN context if VID is given */ + if (!group->vid) + return 0; + +@@ -2010,6 +2008,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port, + timer_setup(&pmctx->ip6_own_query.timer, + br_ip6_multicast_port_query_expired, 0); + #endif ++ /* initialize mdb_n_entries if a new port vlan is being created */ ++ if (vlan) { ++ struct net_bridge_port_group *pg; ++ u32 n = 0; ++ ++ spin_lock_bh(&port->br->multicast_lock); ++ hlist_for_each_entry(pg, &port->mglist, mglist) ++ if (pg->key.addr.vid == vlan->vid) ++ n++; ++ WRITE_ONCE(pmctx->mdb_n_entries, n); ++ spin_unlock_bh(&port->br->multicast_lock); ++ } + } + + void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx) +@@ -2093,25 +2103,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) + br_ip4_multicast_add_router(brmctx, pmctx); + br_ip6_multicast_add_router(brmctx, pmctx); + } +- +- if (br_multicast_port_ctx_is_vlan(pmctx)) { +- struct net_bridge_port_group *pg; +- u32 n = 0; +- +- /* The mcast_n_groups counter might be wrong. First, +- * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries +- * are flushed, thus mcast_n_groups after the toggle does not +- * reflect the true values. And second, permanent entries added +- * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected +- * either. Thus we have to refresh the counter. +- */ +- +- hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) { +- if (pg->key.addr.vid == pmctx->vlan->vid) +- n++; +- } +- WRITE_ONCE(pmctx->mdb_n_entries, n); +- } + } + + static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) +-- +2.51.0 + diff --git a/queue-6.12/net-mlx5-fix-multiport-device-check-over-light-sfs.patch b/queue-6.12/net-mlx5-fix-multiport-device-check-over-light-sfs.patch new file mode 100644 index 0000000000..d257e873aa --- /dev/null +++ b/queue-6.12/net-mlx5-fix-multiport-device-check-over-light-sfs.patch @@ -0,0 +1,55 @@ +From cf8c6198f53b6dc856bd4f7eeb49251a31abf202 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:28:59 +0200 +Subject: net/mlx5: Fix multiport device check over light SFs + +From: Shay Drory + +[ Upstream commit 47bf2e813817159f4d195be83a9b5a640ee6baec ] + +Driver is using num_vhca_ports capability to distinguish between +multiport master device and multiport slave device. num_vhca_ports is a +capability the driver sets according to the MAX num_vhca_ports +capability reported by FW. On the other hand, light SFs doesn't set the +above capbility. + +This leads to wrong results whenever light SFs is checking whether he is +a multiport master or slave. + +Therefore, use the MAX capability to distinguish between master and +slave devices. + +Fixes: e71383fb9cd1 ("net/mlx5: Light probe local SFs") +Signed-off-by: Shay Drory +Reviewed-by: Moshe Shemesh +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-2-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/linux/mlx5/driver.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index 9a8eb644f6707..2e3324578f2ea 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -1297,12 +1297,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev) + static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev) + { + return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) && +- MLX5_CAP_GEN(dev, num_vhca_ports) <= 1; ++ MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1; + } + + static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev) + { +- return MLX5_CAP_GEN(dev, num_vhca_ports) > 1; ++ return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1; + } + + static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev) +-- +2.51.0 + diff --git a/queue-6.12/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch b/queue-6.12/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch new file mode 100644 index 0000000000..18d9e0d383 --- /dev/null +++ b/queue-6.12/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch @@ -0,0 +1,48 @@ +From c217aa17e2756286bf7d6f9841d90c3cf699d360 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:04 +0200 +Subject: net/mlx5e: Use unsigned for mlx5e_get_max_num_channels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cosmin Ratiu + +[ Upstream commit 57a94d4b22b0c6cc5d601e6b6238d78fb923d991 ] + +The max number of channels is always an unsigned int, use the correct +type to fix compilation errors done with strict type checking, e.g.: + +error: call to ‘__compiletime_assert_1110’ declared with attribute + error: min(mlx5e_get_devlink_param_num_doorbells(mdev), + mlx5e_get_max_num_channels(mdev)) signedness error + +Fixes: 74a8dadac17e ("net/mlx5e: Preparations for supporting larger number of channels") +Signed-off-by: Cosmin Ratiu +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-7-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index 8245a149cdf85..0e18906168313 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -176,7 +176,8 @@ static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size) + } + + /* Use this function to get max num channels (rxqs/txqs) only to create netdev */ +-static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) ++static inline unsigned int ++mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) + { + return is_kdump_kernel() ? + MLX5E_MIN_NUM_CHANNELS : +-- +2.51.0 + diff --git a/queue-6.12/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch b/queue-6.12/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch new file mode 100644 index 0000000000..870d0e5dd0 --- /dev/null +++ b/queue-6.12/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch @@ -0,0 +1,62 @@ +From e25102a478b882c2c45f9b86927f4b167d26232a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:02 +0000 +Subject: net: mscc: ocelot: add missing lock protection in + ocelot_port_xmit_inj() + +From: Ziyi Guo + +[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ] + +ocelot_port_xmit_inj() calls ocelot_can_inject() and +ocelot_port_inject_frame() without holding the injection group lock. +Both functions contain lockdep_assert_held() for the injection lock, +and the correct caller felix_port_deferred_xmit() properly acquires +the lock using ocelot_lock_inj_grp() before calling these functions. + +Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register +injection path to fix the missing lock protection. The FDMA path is not +affected as it uses its own locking mechanism. + +Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups") +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index df863657c87de..7df78004dba91 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, + int port = priv->port.index; + u32 rew_op = 0; + +- if (!ocelot_can_inject(ocelot, 0)) ++ ocelot_lock_inj_grp(ocelot, 0); ++ ++ if (!ocelot_can_inject(ocelot, 0)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_BUSY; ++ } + +- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_OK; ++ } + + ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ++ ocelot_unlock_inj_grp(ocelot, 0); ++ + consume_skb(skb); + + return NETDEV_TX_OK; +-- +2.51.0 + diff --git a/queue-6.12/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch b/queue-6.12/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch new file mode 100644 index 0000000000..7c03c84604 --- /dev/null +++ b/queue-6.12/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch @@ -0,0 +1,93 @@ +From 8995c18bcce02c86fc5f6b81d74a264e331a20d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:00 +0000 +Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper + +From: Ziyi Guo + +[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ] + +Extract the PTP timestamp handling logic from ocelot_port_xmit() into a +separate ocelot_xmit_timestamp() helper function. This is a pure +refactor with no behavioral change. + +The helper returns false if the skb was consumed (freed) due to a +timestamp request failure, and true if the caller should continue with +frame injection. The rew_op value is returned via pointer. + +This prepares for splitting ocelot_port_xmit() into separate FDMA and +register injection paths in a subsequent patch. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++---------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 7c9540a717251..5d2d40cb8333d 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -551,33 +551,41 @@ static int ocelot_port_stop(struct net_device *dev) + return 0; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, ++ struct sk_buff *skb, u32 *rew_op) + { +- struct ocelot_port_private *priv = netdev_priv(dev); +- struct ocelot_port *ocelot_port = &priv->port; +- struct ocelot *ocelot = ocelot_port->ocelot; +- int port = priv->port.index; +- u32 rew_op = 0; +- +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) +- return NETDEV_TX_BUSY; +- +- /* Check if timestamping is needed */ + if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + struct sk_buff *clone = NULL; + + if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) { + kfree_skb(skb); +- return NETDEV_TX_OK; ++ return false; + } + + if (clone) + OCELOT_SKB_CB(skb)->clone = clone; + +- rew_op = ocelot_ptp_rew_op(skb); ++ *rew_op = ocelot_ptp_rew_op(skb); + } + ++ return true; ++} ++ ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!static_branch_unlikely(&ocelot_fdma_enabled) && ++ !ocelot_can_inject(ocelot, 0)) ++ return NETDEV_TX_BUSY; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ + if (static_branch_unlikely(&ocelot_fdma_enabled)) { + ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); + } else { +-- +2.51.0 + diff --git a/queue-6.12/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch b/queue-6.12/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch new file mode 100644 index 0000000000..296ce95b45 --- /dev/null +++ b/queue-6.12/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch @@ -0,0 +1,100 @@ +From f320f430a4448bc0ed9143aa5a19a73a17491c31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:01 +0000 +Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths + +From: Ziyi Guo + +[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ] + +Split ocelot_port_xmit() into two separate functions: +- ocelot_port_xmit_fdma(): handles the FDMA injection path +- ocelot_port_xmit_inj(): handles the register-based injection path + +The top-level ocelot_port_xmit() now dispatches to the appropriate +function based on the ocelot_fdma_enabled static key. + +This is a pure refactor with no behavioral change. Separating the two +code paths makes each one simpler and prepares for adding proper locking +to the register injection path without affecting the FDMA path. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 5d2d40cb8333d..df863657c87de 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -571,7 +571,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, + return true; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ ++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); ++ ++ return NETDEV_TX_OK; ++} ++ ++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, ++ struct net_device *dev) + { + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; +@@ -579,24 +597,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) + int port = priv->port.index; + u32 rew_op = 0; + +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) ++ if (!ocelot_can_inject(ocelot, 0)) + return NETDEV_TX_BUSY; + + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + return NETDEV_TX_OK; + +- if (static_branch_unlikely(&ocelot_fdma_enabled)) { +- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); +- } else { +- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); ++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + +- consume_skb(skb); +- } ++ consume_skb(skb); + + return NETDEV_TX_OK; + } + ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ if (static_branch_unlikely(&ocelot_fdma_enabled)) ++ return ocelot_port_xmit_fdma(skb, dev); ++ ++ return ocelot_port_xmit_inj(skb, dev); ++} ++ + enum ocelot_action_type { + OCELOT_MACT_LEARN, + OCELOT_MACT_FORGET, +-- +2.51.0 + diff --git a/queue-6.12/net-rds-rds_sendmsg-should-not-discard-payload_len.patch b/queue-6.12/net-rds-rds_sendmsg-should-not-discard-payload_len.patch new file mode 100644 index 0000000000..a1fe93b81d --- /dev/null +++ b/queue-6.12/net-rds-rds_sendmsg-should-not-discard-payload_len.patch @@ -0,0 +1,50 @@ +From 7c4a15bc60c27c946ce80fbe4585b5484c42d0f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:54:09 -0700 +Subject: net/rds: rds_sendmsg should not discard payload_len + +From: Allison Henderson + +[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ] + +Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with +connection teardown") modifies rds_sendmsg to avoid enqueueing work +while a tear down is in progress. However, it also changed the return +value of rds_sendmsg to that of rds_send_xmit instead of the +payload_len. This means the user may incorrectly receive errno values +when it should have simply received a payload of 0 while the peer +attempts a reconnections. So this patch corrects the teardown handling +code to only use the out error path in that case, thus restoring the +original payload_len return value. + +Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown") +Reviewed-by: Simon Horman +Signed-off-by: Allison Henderson +Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/rds/send.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/rds/send.c b/net/rds/send.c +index 09a2801106549..4a24ee9c22d7c 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1382,9 +1382,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) + else + queue_delayed_work(rds_wq, &cpath->cp_send_w, 1); + rcu_read_unlock(); ++ ++ if (ret) ++ goto out; + } +- if (ret) +- goto out; ++ + rds_message_put(rm); + + for (ind = 0; ind < vct.indx; ind++) +-- +2.51.0 + diff --git a/queue-6.12/net-remove-warn_on_once-when-accessing-forward-path-.patch b/queue-6.12/net-remove-warn_on_once-when-accessing-forward-path-.patch new file mode 100644 index 0000000000..29afb51e4c --- /dev/null +++ b/queue-6.12/net-remove-warn_on_once-when-accessing-forward-path-.patch @@ -0,0 +1,39 @@ +From 40a940b54752c1bddc076a02f1f8e3f7e07e2550 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 12:56:39 +0100 +Subject: net: remove WARN_ON_ONCE when accessing forward path array + +From: Pablo Neira Ayuso + +[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ] + +Although unlikely, recent support for IPIP tunnels increases chances of +reaching this WARN_ON_ONCE if userspace manages to build a sufficiently +long forward path. + +Remove it. + +Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 1d276a26a360d..553317ad6f1b4 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -720,7 +720,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) + { + int k = stack->num_paths++; + +- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) ++ if (k >= NET_DEVICE_PATH_STACK_MAX) + return NULL; + + return &stack->path[k]; +-- +2.51.0 + diff --git a/queue-6.12/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch b/queue-6.12/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch new file mode 100644 index 0000000000..4cc7852bb8 --- /dev/null +++ b/queue-6.12/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch @@ -0,0 +1,48 @@ +From 10f014ce0a4d9fef80ce4fcb2db8c04d8b8571b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 14:44:01 +0100 +Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register + width + +From: Daniel Machon + +[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ] + +DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth +across traffic classes based on per-queue cost values, where lower cost +means higher bandwidth share. + +The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware +register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only +5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to +compute cost values that silently overflow via FIELD_PREP, resulting +in incorrect scheduling weights. + +Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width. + +Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc") +Signed-off-by: Daniel Machon +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +index ced35033a6c5d..b1c6c5c6f16ca 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +@@ -35,7 +35,7 @@ + #define SPX5_SE_BURST_UNIT 4096 + + /* Dwrr */ +-#define SPX5_DWRR_COST_MAX 63 ++#define SPX5_DWRR_COST_MAX 31 + + struct sparx5_shaper { + u32 mode; +-- +2.51.0 + diff --git a/queue-6.12/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch b/queue-6.12/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch new file mode 100644 index 0000000000..c5c8120ee7 --- /dev/null +++ b/queue-6.12/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch @@ -0,0 +1,53 @@ +From e8e8ae079c137b538272d8f452900d418895de65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 12:02:30 +0100 +Subject: net: sparx5/lan969x: fix PTP clock max_adj value + +From: Daniel Machon + +[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ] + +The max_adj field in ptp_clock_info tells userspace how much the PHC +clock frequency can be adjusted. ptp4l reads this and will never request +a correction larger than max_adj. + +On both sparx5 and lan969x the clock offset may never converge because +the servo needs a frequency correction larger than the current max_adj +of 200000 (200 ppm) allows. The servo rails at the max and the offset +stays in the tens of microseconds. + +The hardware has no inherent max adjustment limit; frequency correction +is done by writing a 64-bit clock period increment to CLK_PER_CFG, and +the register has plenty of range. The 200000 value was just an overly +conservative software limit. The max_adj is shared between sparx5 and +lan969x, and the increased value is safe for both. + +Fix this by increasing max_adj to 10000000 (10000 ppm), giving the +servo sufficient headroom. + +Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks") +Signed-off-by: Daniel Machon +Reviewed-by: Maxime Chevallier +Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +index 5a932460db581..6b2dbfbeef377 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +@@ -562,7 +562,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) + static struct ptp_clock_info sparx5_ptp_clock_info = { + .owner = THIS_MODULE, + .name = "sparx5 ptp", +- .max_adj = 200000, ++ .max_adj = 10000000, + .gettime64 = sparx5_ptp_gettime64, + .settime64 = sparx5_ptp_settime64, + .adjtime = sparx5_ptp_adjtime, +-- +2.51.0 + diff --git a/queue-6.12/net-usb-catc-enable-basic-endpoint-checking.patch b/queue-6.12/net-usb-catc-enable-basic-endpoint-checking.patch new file mode 100644 index 0000000000..9787a01920 --- /dev/null +++ b/queue-6.12/net-usb-catc-enable-basic-endpoint-checking.patch @@ -0,0 +1,111 @@ +From a13cfa690161a70bcb9587fe5a17072a4de0c5ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 21:41:54 +0000 +Subject: net: usb: catc: enable basic endpoint checking + +From: Ziyi Guo + +[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ] + +catc_probe() fills three URBs with hardcoded endpoint pipes without +verifying the endpoint descriptors: + + - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX + - usb_rcvintpipe(usbdev, 2) for interrupt status + +A malformed USB device can present these endpoints with transfer types +that differ from what the driver assumes. + +Add a catc_usb_ep enum for endpoint numbers, replacing magic constants +throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints() +calls after usb_set_interface() to verify endpoint types before use, +rejecting devices with mismatched descriptors at probe time. + +Similar to +- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking") +which fixed the issue in rtl8150. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Suggested-by: Simon Horman +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c +index ff439ef535ac9..98346cb4ece01 100644 +--- a/drivers/net/usb/catc.c ++++ b/drivers/net/usb/catc.c +@@ -64,6 +64,16 @@ static const char driver_name[] = "catc"; + #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ + #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ + ++/* ++ * USB endpoints. ++ */ ++ ++enum catc_usb_ep { ++ CATC_USB_EP_CONTROL = 0, ++ CATC_USB_EP_BULK = 1, ++ CATC_USB_EP_INT_IN = 2, ++}; ++ + /* + * Control requests. + */ +@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + u8 broadcast[ETH_ALEN]; + u8 *macbuf; + int pktsz, ret = -ENOMEM; ++ static const u8 bulk_ep_addr[] = { ++ CATC_USB_EP_BULK | USB_DIR_OUT, ++ CATC_USB_EP_BULK | USB_DIR_IN, ++ 0}; ++ static const u8 int_ep_addr[] = { ++ CATC_USB_EP_INT_IN | USB_DIR_IN, ++ 0}; + + macbuf = kmalloc(ETH_ALEN, GFP_KERNEL); + if (!macbuf) +@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + goto fail_mem; + } + ++ /* Verify that all required endpoints are present */ ++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || ++ !usb_check_int_endpoints(intf, int_ep_addr)) { ++ dev_err(dev, "Missing or invalid endpoints\n"); ++ ret = -ENODEV; ++ goto fail_mem; ++ } ++ + netdev = alloc_etherdev(sizeof(struct catc)); + if (!netdev) + goto fail_mem; +@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), + NULL, NULL, 0, catc_ctrl_done, catc); + +- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), +- NULL, 0, catc_tx_done, catc); ++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK), ++ NULL, 0, catc_tx_done, catc); + +- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), +- catc->rx_buf, pktsz, catc_rx_done, catc); ++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK), ++ catc->rx_buf, pktsz, catc_rx_done, catc); + +- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), +- catc->irq_buf, 2, catc_irq_done, catc, 1); ++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN), ++ catc->irq_buf, 2, catc_irq_done, catc, 1); + + if (!catc->is_f5u011) { + u32 *buf; +-- +2.51.0 + diff --git a/queue-6.12/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch b/queue-6.12/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch new file mode 100644 index 0000000000..3ffc8c06a6 --- /dev/null +++ b/queue-6.12/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch @@ -0,0 +1,58 @@ +From 3348a6871396d063e539781376af1d3d1c59f452 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 12:53:09 +0100 +Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value + +From: Florian Westphal + +[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ] + +Mihail Milev reports: Error: UNINIT (CWE-457): + net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl: + Declaring variable "tuple" without initializer. + net/netfilter/nf_conntrack_h323_main.c:1197:2: + uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find". + net/netfilter/nf_conntrack_expect.c:142:2: + read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash". + + 1195| tuple.dst.protonum = IPPROTO_TCP; + 1196| + 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + 1198| if (exp && exp->master == ct) + 1199| return exp; + +Switch this to a C99 initialiser and set the l3num value. + +Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port") +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_h323_main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c +index 5a9bce24f3c3d..ed983421e2eb2 100644 +--- a/net/netfilter/nf_conntrack_h323_main.c ++++ b/net/netfilter/nf_conntrack_h323_main.c +@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, + { + struct net *net = nf_ct_net(ct); + struct nf_conntrack_expect *exp; +- struct nf_conntrack_tuple tuple; ++ struct nf_conntrack_tuple tuple = { ++ .src.l3num = nf_ct_l3num(ct), ++ .dst.protonum = IPPROTO_TCP, ++ .dst.u.tcp.port = port, ++ }; + +- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); +- tuple.src.u.tcp.port = 0; + memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); +- tuple.dst.u.tcp.port = port; +- tuple.dst.protonum = IPPROTO_TCP; + + exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + if (exp && exp->master == ct) +-- +2.51.0 + diff --git a/queue-6.12/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch b/queue-6.12/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch new file mode 100644 index 0000000000..fcbd341251 --- /dev/null +++ b/queue-6.12/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch @@ -0,0 +1,54 @@ +From 615519bb31423c3c520737098c0bbc11e7a6026f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 21:14:40 +0900 +Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain() + +From: Inseo An + +[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ] + +nf_tables_addchain() publishes the chain to table->chains via +list_add_tail_rcu() (in nft_chain_add()) before registering hooks. +If nf_tables_register_hook() then fails, the error path calls +nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy() +with no RCU grace period in between. + +This creates two use-after-free conditions: + + 1) Control-plane: nf_tables_dump_chains() traverses table->chains + under rcu_read_lock(). A concurrent dump can still be walking + the chain when the error path frees it. + + 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly + installs the IPv4 hook before IPv6 registration fails. Packets + entering nft_do_chain() via the transient IPv4 hook can still be + dereferencing chain->blob_gen_X when the error path frees the + chain. + +Add synchronize_rcu() between nft_chain_del() and the chain destroy +so that all RCU readers -- both dump threads and in-flight packet +evaluation -- have finished before the chain is freed. + +Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain") +Signed-off-by: Inseo An +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index f10be72021ddd..8dccd3598166b 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2645,6 +2645,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, + + err_register_hook: + nft_chain_del(chain); ++ synchronize_rcu(); + err_chain_add: + nft_trans_destroy(trans); + err_trans: +-- +2.51.0 + diff --git a/queue-6.12/objpool-fix-the-overestimation-of-object-pooling-met.patch b/queue-6.12/objpool-fix-the-overestimation-of-object-pooling-met.patch new file mode 100644 index 0000000000..7cac1ec034 --- /dev/null +++ b/queue-6.12/objpool-fix-the-overestimation-of-object-pooling-met.patch @@ -0,0 +1,47 @@ +From b5c36b36811c818cd73fc0bfb59341a13d330962 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 21:28:46 +0800 +Subject: objpool: fix the overestimation of object pooling metadata size + +From: zhouwenhao + +[ Upstream commit 5ed4b6b37c647d168ae31035b3f61b705997e043 ] + +objpool uses struct objpool_head to store metadata information, and its +cpu_slots member points to an array of pointers that store the addresses +of the percpu ring arrays. However, the memory size allocated during the +initialization of cpu_slots is nr_cpu_ids * sizeof(struct objpool_slot). +On a 64-bit machine, the size of struct objpool_slot is 16 bytes, which is +twice the size of the actual pointer required, and the extra memory is +never be used, resulting in a waste of memory. Therefore, the memory size +required for cpu_slots needs to be corrected. + +Link: https://lkml.kernel.org/r/20260202132846.68257-1-zhouwenhao7600@gmail.com +Fixes: b4edb8d2d464 ("lib: objpool added: ring-array based lockless MPMC") +Signed-off-by: zhouwenhao +Reviewed-by: Andrew Morton +Cc: "Masami Hiramatsu (Google)" +Cc: Matt Wu +Cc: wuqiang.matt +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + lib/objpool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/objpool.c b/lib/objpool.c +index b998b720c7329..d98fadf1de169 100644 +--- a/lib/objpool.c ++++ b/lib/objpool.c +@@ -142,7 +142,7 @@ int objpool_init(struct objpool_head *pool, int nr_objs, int object_size, + pool->gfp = gfp & ~__GFP_ZERO; + pool->context = context; + pool->release = release; +- slot_size = nr_cpu_ids * sizeof(struct objpool_slot); ++ slot_size = nr_cpu_ids * sizeof(struct objpool_slot *); + pool->cpu_slots = kzalloc(slot_size, pool->gfp); + if (!pool->cpu_slots) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.12/octeontx2-af-fix-default-entries-mcam-entry-action.patch b/queue-6.12/octeontx2-af-fix-default-entries-mcam-entry-action.patch new file mode 100644 index 0000000000..88e967f91f --- /dev/null +++ b/queue-6.12/octeontx2-af-fix-default-entries-mcam-entry-action.patch @@ -0,0 +1,85 @@ +From 0a9a881cb8c1eff217c254ce773060d0e2438087 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:33:38 +0530 +Subject: octeontx2-af: Fix default entries mcam entry action + +From: Hariprasad Kelam + +[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ] + +As per design, AF should update the default MCAM action only when +mcam_index is -1. A bug in the previous patch caused default entries +to be changed even when the request was not for them. + +Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index") +Signed-off-by: Hariprasad Kelam +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++--------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 97722ce8c4cb3..a78923d7811dc 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -1058,32 +1058,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, + rvu_write64(rvu, blkaddr, + NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action); + +- /* update the VF flow rule action with the VF default entry action */ +- if (mcam_index < 0) +- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, +- *(u64 *)&action); +- + /* update the action change in default rule */ + pfvf = rvu_get_pfvf(rvu, pcifunc); + if (pfvf->def_ucast_rule) + pfvf->def_ucast_rule->rx_action = action; + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_PROMISC_ENTRY); ++ if (mcam_index < 0) { ++ /* update the VF flow rule action with the VF default ++ * entry action ++ */ ++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, ++ *(u64 *)&action); + +- /* If PF's promiscuous entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_PROMISC_ENTRY); + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_ALLMULTI_ENTRY); +- /* If PF's allmulti entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ /* If PF's promiscuous entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_ALLMULTI_ENTRY); ++ /* If PF's allmulti entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ } + } + + void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, +-- +2.51.0 + diff --git a/queue-6.12/ping-annotate-data-races-in-ping_lookup.patch b/queue-6.12/ping-annotate-data-races-in-ping_lookup.patch new file mode 100644 index 0000000000..ad9c6ee9a2 --- /dev/null +++ b/queue-6.12/ping-annotate-data-races-in-ping_lookup.patch @@ -0,0 +1,118 @@ +From cdabb11b55aa2ceec7f2b32474fe76500f68b516 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:01:49 +0000 +Subject: ping: annotate data-races in ping_lookup() + +From: Eric Dumazet + +[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ] + +isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if +are read locklessly in ping_lookup(). + +Add READ_ONCE()/WRITE_ONCE() annotations. + +The race on isk->inet_rcv_saddr is probably coming from IPv6 support, +but does not deserve a specific backport. + +Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/ping.c | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index f62b17f59bb4a..0089c1605acfe 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -159,7 +159,7 @@ void ping_unhash(struct sock *sk) + pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); + spin_lock(&ping_table.lock); + if (sk_del_node_init_rcu(sk)) { +- isk->inet_num = 0; ++ WRITE_ONCE(isk->inet_num, 0); + isk->inet_sport = 0; + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + } +@@ -192,31 +192,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + } + + sk_for_each_rcu(sk, hslot) { ++ int bound_dev_if; ++ + if (!net_eq(sock_net(sk), net)) + continue; + isk = inet_sk(sk); + + pr_debug("iterate\n"); +- if (isk->inet_num != ident) ++ if (READ_ONCE(isk->inet_num) != ident) + continue; + ++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); + if (skb->protocol == htons(ETH_P_IP) && + sk->sk_family == AF_INET) { ++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr); ++ + pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk, +- (int) isk->inet_num, &isk->inet_rcv_saddr, +- sk->sk_bound_dev_if); ++ ident, &rcv_saddr, ++ bound_dev_if); + +- if (isk->inet_rcv_saddr && +- isk->inet_rcv_saddr != ip_hdr(skb)->daddr) ++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr) + continue; + #if IS_ENABLED(CONFIG_IPV6) + } else if (skb->protocol == htons(ETH_P_IPV6) && + sk->sk_family == AF_INET6) { + + pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk, +- (int) isk->inet_num, ++ ident, + &sk->sk_v6_rcv_saddr, +- sk->sk_bound_dev_if); ++ bound_dev_if); + + if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && + !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, +@@ -227,8 +231,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + continue; + } + +- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && +- sk->sk_bound_dev_if != sdif) ++ if (bound_dev_if && bound_dev_if != dif && ++ bound_dev_if != sdif) + continue; + + goto exit; +@@ -403,7 +407,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr) + if (saddr->sa_family == AF_INET) { + struct inet_sock *isk = inet_sk(sk); + struct sockaddr_in *addr = (struct sockaddr_in *) saddr; +- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr; ++ ++ isk->inet_saddr = addr->sin_addr.s_addr; ++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr); + #if IS_ENABLED(CONFIG_IPV6) + } else if (saddr->sa_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr; +@@ -860,7 +866,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, + struct sk_buff *skb; + int copied, err; + +- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); ++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, ++ READ_ONCE(isk->inet_num)); + + err = -EOPNOTSUPP; + if (flags & MSG_OOB) +-- +2.51.0 + diff --git a/queue-6.12/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch b/queue-6.12/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch new file mode 100644 index 0000000000..d3f709780d --- /dev/null +++ b/queue-6.12/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch @@ -0,0 +1,49 @@ +From 32e770989a4a7b777e075e6fe7fd28d104262826 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 14:34:01 -0800 +Subject: powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check + +From: Kuppuswamy Sathyanarayanan + +[ Upstream commit c7d54dafa042cf379859dba265fe5afef6fa8770 ] + +On partitioned systems, multiple TPMI instances may exist per package, +but RAPL registers are only valid on one instance since RAPL has +package-scope control. Other instances return invalid versions during +domain parsing, which is expected behavior on such systems. + +Currently this generates a firmware bug warning: + + intel_rapl_tpmi: [Firmware Bug]: Invalid version + +Remove the FW_BUG tag, downgrade to pr_debug(), and update the message +to clarify that invalid versions are expected on partitioned systems +where only one instance can be valid. + +Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver") +Reported-by: Zhang Rui +Signed-off-by: Kuppuswamy Sathyanarayanan +Reviewed-by: Srinivas Pandruvada +Link: https://patch.msgid.link/20260211223401.1575776-1-sathyanarayanan.kuppuswamy@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/intel_rapl_tpmi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c +index 645fd1dc51a98..1618138c5cac1 100644 +--- a/drivers/powercap/intel_rapl_tpmi.c ++++ b/drivers/powercap/intel_rapl_tpmi.c +@@ -156,7 +156,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) + tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; + + if (tpmi_domain_version == TPMI_VERSION_INVALID) { +- pr_warn(FW_BUG "Invalid version\n"); ++ pr_debug("Invalid version, other instances may be valid\n"); + return -ENODEV; + } + +-- +2.51.0 + diff --git a/queue-6.12/s390-kexec-make-kexec_sig-available-when-config_modu.patch b/queue-6.12/s390-kexec-make-kexec_sig-available-when-config_modu.patch new file mode 100644 index 0000000000..829b0c8dd3 --- /dev/null +++ b/queue-6.12/s390-kexec-make-kexec_sig-available-when-config_modu.patch @@ -0,0 +1,61 @@ +From b5f34b15bf28bbd6b40ea56bf5f7aaa24e63ca47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 07:29:16 +0100 +Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n + +From: Alexander Egorenkov + +[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ] + +The commit c8424e776b09 ("MODSIGN: Export module signature definitions") +replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the +dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390 +kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT. + +Furthermore, the signature verification in s390 kexec does not require +MODULE_SIG_FORMAT because it requires only the struct module_signature and, +therefore, does not depend on code in kernel/module_signature.c. + +But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is +also incorrect because it makes KEXEC_SIG available on s390 only if some +other arbitrary option (for instance a file system or device driver) +selects it directly or indirectly. + +To properly make KEXEC_SIG available for s390 kernels built with MODULES=y +as well as MODULES=n _and_ also not depend on arbitrary options selecting +SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select +SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y. + +Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions") +Suggested-by: Heiko Carstens +Signed-off-by: Alexander Egorenkov +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index 1786b30307942..5e6aebf1b739a 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -239,6 +239,7 @@ config S390 + select SPARSE_IRQ + select SWIOTLB + select SYSCTL_EXCEPTION_TRACE ++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG + select THREAD_INFO_IN_TASK + select TRACE_IRQFLAGS_SUPPORT + select TTY +@@ -264,7 +265,7 @@ config ARCH_SUPPORTS_KEXEC_FILE + def_bool y + + config ARCH_SUPPORTS_KEXEC_SIG +- def_bool MODULE_SIG_FORMAT ++ def_bool y + + config ARCH_SUPPORTS_KEXEC_PURGATORY + def_bool y +-- +2.51.0 + diff --git a/queue-6.12/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch b/queue-6.12/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch new file mode 100644 index 0000000000..45fd613540 --- /dev/null +++ b/queue-6.12/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch @@ -0,0 +1,78 @@ +From 26c6cfcf531af3145d76883f014d918349af931e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:05 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with + br_netfilter enabled + +From: Aleksei Oladko + +[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv4 packet contains a zero IP header checksum. After VXLAN +decapsulation, such packets do not pass sanity checks in br_netfilter +and are dropped, which causes the test to fail. + +Fix this by calculating and setting a valid IPv4 header checksum for the +encapsulated packet generated by mausezahn, so that the packet is accepted +by br_netfilter. Fixed by using the payload_template_calc_checksum() / +payload_template_expand_checksum() helpers that are only available +in v6.3 and newer kernels. + +Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index 3f9d50f1ef9ec..1952023c43ba4 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -559,6 +559,21 @@ vxlan_encapped_ping_do() + local inner_tos=$1; shift + local outer_tos=$1; shift + ++ local ipv4hdr=$(: ++ )"45:"$( : IP version + IHL ++ )"$inner_tos:"$( : IP TOS ++ )"00:54:"$( : IP total length ++ )"99:83:"$( : IP identification ++ )"40:00:"$( : IP flags + frag off ++ )"40:"$( : IP TTL ++ )"01:"$( : IP proto ++ )"CHECKSUM:"$( : IP header csum ++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 ++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1 ++ ) ++ local checksum=$(payload_template_calc_checksum "$ipv4hdr") ++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum) ++ + $MZ $dev -c $count -d 100msec -q \ + -b $next_hop_mac -B $dest_ip \ + -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(: +@@ -569,16 +584,7 @@ vxlan_encapped_ping_do() + )"$dest_mac:"$( : ETH daddr + )"$(mac_get w2):"$( : ETH saddr + )"08:00:"$( : ETH type +- )"45:"$( : IP version + IHL +- )"$inner_tos:"$( : IP TOS +- )"00:54:"$( : IP total length +- )"99:83:"$( : IP identification +- )"40:00:"$( : IP flags + frag off +- )"40:"$( : IP TTL +- )"01:"$( : IP proto +- )"00:00:"$( : IP header csum +- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 +- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 ++ )"$ipv4hdr:"$( : IPv4 header + )"08:"$( : ICMP type + )"00:"$( : ICMP code + )"8b:f2:"$( : ICMP csum +-- +2.51.0 + diff --git a/queue-6.12/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch b/queue-6.12/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch new file mode 100644 index 0000000000..1bca06b2b9 --- /dev/null +++ b/queue-6.12/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch @@ -0,0 +1,69 @@ +From f7518edd06fd30c5bdc0e4247ca2cfdb457a2047 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:06 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with + br_netfilter enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Aleksei Oladko + +[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv6 packet has an incorrect payload length set in the IPv6 header. +After VXLAN decapsulation, such packets do not pass sanity checks in +br_netfilter and are dropped, which causes the test to fail. + +Fix this by setting the correct IPv6 payload length for the encapsulated +packet generated by mausezahn, so that the packet is accepted +by br_netfilter. + +tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +lines 698-706 + + )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + )"80:"$( : ICMPv6.type + )"00:"$( : ICMPv6.code + )"00:"$( : ICMPv6.checksum + ) + +Data after IPv6 header: +• 80: — 1 byte (ICMPv6 type) +• 00: — 1 byte (ICMPv6 code) +• 00: — 1 byte (ICMPv6 checksum, truncated) + +Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match +the actual payload size. + +Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +index a603f7b0a08f0..e642feeada0e7 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +@@ -695,7 +695,7 @@ vxlan_encapped_ping_do() + )"6"$( : IP version + )"$inner_tos"$( : Traffic class + )"0:00:00:"$( : Flow label +- )"00:08:"$( : Payload length ++ )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr +-- +2.51.0 + diff --git a/queue-6.12/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch b/queue-6.12/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch new file mode 100644 index 0000000000..beae5b2850 --- /dev/null +++ b/queue-6.12/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch @@ -0,0 +1,241 @@ +From ead92bcb10ad8c0b3653acd376d1d647896233f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 09:38:05 -0500 +Subject: selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT + +From: Aristeu Rozanski + +[ Upstream commit b24335521de92fd2ee22460072b75367ca8860b0 ] + +selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT + +In order to synchronize new processes to test inheritance of memfd_noexec +sysctl, memfd_test sets up the sysctl with a value before creating the new +process. The new process then sends itself a SIGSTOP in order to wait for +the parent to flip the sysctl value and send a SIGCONT signal. + +This would work as intended if it wasn't the fact that the new process is +being created with CLONE_NEWPID, which creates a new PID namespace and the +new process has PID 1 in this namespace. There're restrictions on sending +signals to PID 1 and, although it's relaxed for other than root PID +namespace, it's biting us here. In this specific case the SIGSTOP sent by +the new process is ignored (no error to kill() is returned) and it never +stops its execution. This is usually not noticiable as the parent usually +manages to set the new sysctl value before the child has a chance to run +and the test succeeds. But if you run the test in a loop, it eventually +reproduces: + + while [ 1 ]; do ./memfd_test >log 2>&1 || break; done; cat log + +So this patch replaces the SIGSTOP/SIGCONT synchronization with IPC +semaphore. + +Link: https://lkml.kernel.org/r/a7776389-b3d6-4b18-b438-0b0e3ed1fd3b@work +Fixes: 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests") +Signed-off-by: Aristeu Rozanski +Cc: Aleksa Sarai +Cc: Shuah Khan +Cc: liuye +Cc: Lorenzo Stoakes +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/memfd/memfd_test.c | 113 +++++++++++++++++++-- + 1 file changed, 105 insertions(+), 8 deletions(-) + +diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c +index 0a0b555160280..b518699a71038 100644 +--- a/tools/testing/selftests/memfd/memfd_test.c ++++ b/tools/testing/selftests/memfd/memfd_test.c +@@ -18,6 +18,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + +@@ -39,6 +42,20 @@ + F_SEAL_EXEC) + + #define MFD_NOEXEC_SEAL 0x0008U ++union semun { ++ int val; ++ struct semid_ds *buf; ++ unsigned short int *array; ++ struct seminfo *__buf; ++}; ++ ++/* ++ * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the ++ * child will be PID 1 and can't send SIGSTOP to themselves due special ++ * treatment of the init task, so the SIGSTOP/SIGCONT synchronization ++ * approach can't be used here. ++ */ ++#define SEM_KEY 0xdeadbeef + + /* + * Default is not to test hugetlbfs +@@ -1291,8 +1308,22 @@ static int sysctl_nested(void *arg) + + static int sysctl_nested_wait(void *arg) + { +- /* Wait for a SIGCONT. */ +- kill(getpid(), SIGSTOP); ++ int sem = semget(SEM_KEY, 1, 0600); ++ struct sembuf sembuf; ++ ++ if (sem < 0) { ++ perror("semget:"); ++ abort(); ++ } ++ sembuf.sem_num = 0; ++ sembuf.sem_flg = 0; ++ sembuf.sem_op = 0; ++ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ abort(); ++ } ++ + return sysctl_nested(arg); + } + +@@ -1313,7 +1344,9 @@ static void test_sysctl_sysctl2_failset(void) + + static int sysctl_nested_child(void *arg) + { +- int pid; ++ int pid, sem; ++ union semun semun; ++ struct sembuf sembuf; + + printf("%s nested sysctl 0\n", memfd_str); + sysctl_assert_write("0"); +@@ -1347,23 +1380,53 @@ static int sysctl_nested_child(void *arg) + test_sysctl_sysctl2_failset); + join_thread(pid); + ++ sem = semget(SEM_KEY, 1, IPC_CREAT | 0600); ++ if (sem < 0) { ++ perror("semget:"); ++ return 1; ++ } ++ semun.val = 1; ++ sembuf.sem_op = -1; ++ sembuf.sem_flg = 0; ++ sembuf.sem_num = 0; ++ + /* Verify that the rules are actually inherited after fork. */ + printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str); + sysctl_assert_write("0"); + ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl1_failset); + sysctl_assert_write("1"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str); + sysctl_assert_write("0"); + ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2_failset); + sysctl_assert_write("2"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + /* +@@ -1373,28 +1436,62 @@ static int sysctl_nested_child(void *arg) + */ + printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str); + sysctl_assert_write("2"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2); + sysctl_assert_write("1"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str); + sysctl_assert_write("2"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2); + sysctl_assert_write("0"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str); + sysctl_assert_write("1"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl1); + sysctl_assert_write("0"); +- kill(pid, SIGCONT); ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + ++ semctl(sem, 0, IPC_RMID); ++ + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.12/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch b/queue-6.12/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch new file mode 100644 index 0000000000..3bc5455d65 --- /dev/null +++ b/queue-6.12/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch @@ -0,0 +1,57 @@ +From b9a61defd3b4cc5b777e72b82023e04c0801d846 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 14:53:53 +0100 +Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2 + +From: Ido Schimmel + +[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ] + +As explained in [1], iproute2 started rejecting tc-police burst sizes +that result in an overflow. This can happen when the burst size is high +enough and the rate is low enough. + +A couple of test cases specify such configurations, resulting in +iproute2 errors and test failure. + +Fix by reducing the burst size so that the test will pass with both new +and old iproute2 versions. + +[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/ + +Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions") +Signed-off-by: Ido Schimmel +Signed-off-by: Petr Machata +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +index 0441a18f098b1..aac8ef490feb8 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +@@ -317,7 +317,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 0.5kbit burst 1m conform-exceed drop/ok ++ action police rate 0.5kbit burst 2k conform-exceed drop/ok + check_fail $? "Incorrect success to add police action with too low rate" + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ +@@ -327,7 +327,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 1.5kbit burst 1m conform-exceed drop/ok ++ action police rate 1.5kbit burst 2k conform-exceed drop/ok + check_err $? "Failed to add police action with low rate" + + tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower +-- +2.51.0 + diff --git a/queue-6.12/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch b/queue-6.12/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch new file mode 100644 index 0000000000..f251e81c88 --- /dev/null +++ b/queue-6.12/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch @@ -0,0 +1,57 @@ +From c323066db198394bebc818f8af36b4f75fbe43b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:51:59 -0800 +Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout + +From: Jakub Kicinski + +[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ] + +Since we started running selftests in NIPA we have been seeing +tc_actions.sh generate a soft lockup warning on ~20% of the runs. +On the pre-netdev foundation setup it was actually a missed irq +splat from the console. Now it's either that or a lockup. + +I initially suspected a socket locking issue since the test +is exercising local loopback with act_mirred. +After hours of staring at this I noticed in strace that ncat +when -o $file is specified _both_ saves the output to the file +and still prints it to stdout. Because the file being sent +is constructed with: + + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred + ^^^^^^^^^ + +the data printed is all \0. Most terminals don't display nul +characters (and neither does vng output capture save them). +But QEMU's serial console still has to poke them thru which +is very slow and causes the lockup (if the file is >600kB). + +Replace the '-o $file' with '> $file'. This speeds the test up +from 2m20s to 18s on debug kernels, and prevents the warnings. + +Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index ea89e558672db..86edbc7e2489b 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -223,7 +223,7 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & ++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 & + local rpid=$! + ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid +-- +2.51.0 + diff --git a/queue-6.12/series b/queue-6.12/series index 27c0e89b6f..735ef63cd5 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -354,3 +354,86 @@ backlight-qcom-wled-change-pm8950-wled-configuration.patch dmaengine-fsl-edma-don-t-explicitly-disable-clocks-i.patch drbd-always-set-blk_feat_stable_writes.patch io_uring-cancel-de-unionize-file-and-user_data-in-st.patch +fs-ntfs3-initialize-new-folios-before-use.patch +fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch +fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch +acpi-button-install-notifier-for-system-events-as-we.patch +acpi-button-only-send-key_power-for-acpi_button_noti.patch +acpi-button-adjust-event-notification-routines.patch +acpi-button-convert-the-driver-to-a-platform-one.patch +acpi-button-call-device_init_wakeup-earlier-during-p.patch +acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch +powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch +kbuild-add-objtool-to-top-level-clean-target.patch +selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch +objpool-fix-the-overestimation-of-object-pooling-met.patch +acpi-pm-add-unused-power-resource-quirk-for-thundero.patch +cpuidle-skip-governor-when-only-one-idle-state-is-av.patch +selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch +net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch +net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch +net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch +net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch +ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch +net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch +net-usb-catc-enable-basic-endpoint-checking.patch +xen-netback-reject-zero-queue-configuration-from-gue.patch +net-rds-rds_sendmsg-should-not-discard-payload_len.patch +net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch +selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch +selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch +netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch +ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch +net-remove-warn_on_once-when-accessing-forward-path-.patch +netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch +ipv6-fix-a-race-in-ip6_sock_set_v6only.patch +bpftool-fix-truncated-netlink-dumps.patch +ping-annotate-data-races-in-ping_lookup.patch +selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch +macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch +icmp-prevent-possible-overflow-in-icmp_global_allow.patch +inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch +octeontx2-af-fix-default-entries-mcam-entry-action.patch +bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch +net-mlx5-fix-multiport-device-check-over-light-sfs.patch +net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch +apparmor-fix-null-sock-in-aa_sock_file_perm.patch +apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch +apparmor-fix-optimize-table-creation-from-possibly-u.patch +apparmor-return-enomem-in-unpack_perms_table-upon-al.patch +apparmor-fix-rlimit-for-posix-cpu-timers.patch +apparmor-remove-apply_modes_to_perms-from-label_matc.patch +apparmor-make-label_match-return-a-consistent-value.patch +apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch +apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch +apparmor-fix-aa_label-to-return-state-from-compount-.patch +drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch +drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch +drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch +asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch +drm-i915-acpi-free-_dsm-package-when-no-connectors.patch +asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch +drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch +drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch +drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch +spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch +s390-kexec-make-kexec_sig-available-when-config_modu.patch +drm-xe-move-forcewake-to-gt.pm-substructure.patch +drm-xe-create-dedicated-xe_mmio-structure.patch +drm-xe-clarify-size-of-mmio-region.patch +drm-xe-move-gsi-offset-adjustment-fields-into-struct.patch +drm-xe-populate-gt-s-mmio-iomap-from-tile-during-ini.patch +drm-xe-switch-mmio_ext-to-use-struct-xe_mmio.patch +drm-xe-add-xe_tile-backpointer-to-xe_mmio.patch +drm-xe-adjust-mmio-code-to-pass-vf-substructure-to-s.patch +drm-xe-switch-mmio-interface-to-take-xe_mmio-instead.patch +drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch +drm-xe-ptl-apply-wa_13011645652.patch +drm-xe-xe2_hpg-add-set-of-workarounds.patch +drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch +efi-fix-reservation-of-unaccepted-memory-table.patch +btrfs-use-the-correct-type-to-initialize-block-reser.patch +btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch +x86-hyperv-fix-error-pointer-dereference.patch +asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch +drm-amd-display-use-same-max-plane-scaling-limits-fo.patch diff --git a/queue-6.12/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch b/queue-6.12/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch new file mode 100644 index 0000000000..179732fbf6 --- /dev/null +++ b/queue-6.12/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch @@ -0,0 +1,49 @@ +From cba7b5fc3d93f6b5c198fee5b6da28fe9344f306 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:41:40 +0800 +Subject: spi: wpcm-fiu: Fix potential NULL pointer dereference in + wpcm_fiu_probe() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felix Gu + +[ Upstream commit 888a0a802c467bbe34a42167bdf9d7331333440a ] + +platform_get_resource_byname() can return NULL, which would cause a crash +when passed the pointer to resource_size(). + +Move the fiu->memory_size assignment after the error check for +devm_ioremap_resource() to prevent the potential NULL pointer dereference. + +Fixes: 9838c182471e ("spi: wpcm-fiu: Add direct map support") +Signed-off-by: Felix Gu +Reviewed-by: J. Neuschäfer +Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-wpcm-fiu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c +index a9aee2a6c7dcb..c47b56f0933f1 100644 +--- a/drivers/spi/spi-wpcm-fiu.c ++++ b/drivers/spi/spi-wpcm-fiu.c +@@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); + fiu->memory = devm_ioremap_resource(dev, res); +- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + if (IS_ERR(fiu->memory)) + return dev_err_probe(dev, PTR_ERR(fiu->memory), + "Failed to map flash memory window\n"); + ++ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm"); + + wpcm_fiu_hw_init(fiu); +-- +2.51.0 + diff --git a/queue-6.12/x86-hyperv-fix-error-pointer-dereference.patch b/queue-6.12/x86-hyperv-fix-error-pointer-dereference.patch new file mode 100644 index 0000000000..3d9abba27e --- /dev/null +++ b/queue-6.12/x86-hyperv-fix-error-pointer-dereference.patch @@ -0,0 +1,54 @@ +From 9e49b394a10d793a248231ea18705e0b9e527bf6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 13:09:03 -0600 +Subject: x86/hyperv: Fix error pointer dereference + +From: Ethan Tidmore + +[ Upstream commit 705d01c8d78121ee1634bfc602ac4b0ad1438fab ] + +The function idle_thread_get() can return an error pointer and is not +checked for it. Add check for error pointer. + +Detected by Smatch: +arch/x86/hyperv/hv_vtl.c:126 hv_vtl_bringup_vcpu() error: +'idle' dereferencing possible ERR_PTR() + +Fixes: 2b4b90e053a29 ("x86/hyperv: Use per cpu initial stack for vtl context") +Signed-off-by: Ethan Tidmore +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + arch/x86/hyperv/hv_vtl.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c +index 2510e91b29b08..b135ba5c18710 100644 +--- a/arch/x86/hyperv/hv_vtl.c ++++ b/arch/x86/hyperv/hv_vtl.c +@@ -68,7 +68,7 @@ static void hv_vtl_ap_entry(void) + + static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) + { +- u64 status; ++ u64 status, rsp, rip; + int ret = 0; + struct hv_enable_vp_vtl *input; + unsigned long irq_flags; +@@ -81,9 +81,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) + struct desc_struct *gdt; + + struct task_struct *idle = idle_thread_get(cpu); +- u64 rsp = (unsigned long)idle->thread.sp; ++ if (IS_ERR(idle)) ++ return PTR_ERR(idle); + +- u64 rip = (u64)&hv_vtl_ap_entry; ++ rsp = (unsigned long)idle->thread.sp; ++ rip = (u64)&hv_vtl_ap_entry; + + native_store_gdt(&gdt_ptr); + store_idt(&idt_ptr); +-- +2.51.0 + diff --git a/queue-6.12/xen-netback-reject-zero-queue-configuration-from-gue.patch b/queue-6.12/xen-netback-reject-zero-queue-configuration-from-gue.patch new file mode 100644 index 0000000000..5659f4ef44 --- /dev/null +++ b/queue-6.12/xen-netback-reject-zero-queue-configuration-from-gue.patch @@ -0,0 +1,57 @@ +From 3fd1466f7772791b3b619a35e8f1b4126a63682d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:40:40 +0000 +Subject: xen-netback: reject zero-queue configuration from guest + +From: Ziyi Guo + +[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ] + +A malicious or buggy Xen guest can write "0" to the xenbus key +"multi-queue-num-queues". The connect() function in the backend only +validates the upper bound (requested_num_queues > xenvif_max_queues) +but not zero, allowing requested_num_queues=0 to reach +vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers +WARN_ON_ONCE(!size) in __vmalloc_node_range(). + +On systems with panic_on_warn=1, this allows a guest-to-host denial +of service. + +The Xen network interface specification requires +the queue count to be "greater than zero". + +Add a zero check to match the validation already present +in xen-blkback, which has included this +guard since its multi-queue support was added. + +Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues") +Signed-off-by: Ziyi Guo +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/xen-netback/xenbus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index a78a25b872409..61b547aab286a 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -735,10 +735,11 @@ static void connect(struct backend_info *be) + */ + requested_num_queues = xenbus_read_unsigned(dev->otherend, + "multi-queue-num-queues", 1); +- if (requested_num_queues > xenvif_max_queues) { ++ if (requested_num_queues > xenvif_max_queues || ++ requested_num_queues == 0) { + /* buggy or malicious guest */ + xenbus_dev_fatal(dev, -EINVAL, +- "guest requested %u queues, exceeding the maximum of %u.", ++ "guest requested %u queues, but valid range is 1 - %u.", + requested_num_queues, xenvif_max_queues); + return; + } +-- +2.51.0 + diff --git a/queue-6.18/acpi-button-adjust-event-notification-routines.patch b/queue-6.18/acpi-button-adjust-event-notification-routines.patch new file mode 100644 index 0000000000..9ac165e21b --- /dev/null +++ b/queue-6.18/acpi-button-adjust-event-notification-routines.patch @@ -0,0 +1,262 @@ +From 7ef894ebf106c74baec5924e515a2802ed21d287 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Dec 2025 14:55:09 +0100 +Subject: ACPI: button: Adjust event notification routines + +From: Rafael J. Wysocki + +[ Upstream commit 93dc5db6d47aaa3b4b458ddfddfa3369c24e22f4 ] + +Adjust the event notification routines in the ACPI button driver to +take a struct acpi_button pointer as an argument istead of a struct +acpi_device one where applicable, which allows the use of +acpi_driver_data() to be limited and will facilitate subsequent +changes. + +No intentional functional impact. + +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/2260995.Icojqenx9y@rafael.j.wysocki +Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe") +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 67 +++++++++++++++++++++---------------------- + 1 file changed, 33 insertions(+), 34 deletions(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 3c6dd9b4ba0ad..09a6e4ffe9f20 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -169,6 +169,7 @@ static struct acpi_driver acpi_button_driver = { + }; + + struct acpi_button { ++ struct acpi_device *adev; + unsigned int type; + struct input_dev *input; + char phys[32]; /* for input device */ +@@ -202,9 +203,9 @@ static int acpi_lid_evaluate_state(struct acpi_device *device) + return lid_state ? 1 : 0; + } + +-static int acpi_lid_notify_state(struct acpi_device *device, int state) ++static int acpi_lid_notify_state(struct acpi_button *button, int state) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + ktime_t next_report; + bool do_update; + +@@ -287,18 +288,18 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) + static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq, + void *offset) + { +- struct acpi_device *device = seq->private; ++ struct acpi_button *button = seq->private; + int state; + +- state = acpi_lid_evaluate_state(device); ++ state = acpi_lid_evaluate_state(button->adev); + seq_printf(seq, "state: %s\n", + state < 0 ? "unsupported" : (state ? "open" : "closed")); + return 0; + } + +-static int acpi_button_add_fs(struct acpi_device *device) ++static int acpi_button_add_fs(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + struct proc_dir_entry *entry = NULL; + int ret = 0; + +@@ -333,7 +334,7 @@ static int acpi_button_add_fs(struct acpi_device *device) + /* create /proc/acpi/button/lid/LID/state */ + entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO, + acpi_device_dir(device), acpi_button_state_seq_show, +- device); ++ button); + if (!entry) { + ret = -ENODEV; + goto remove_dev_dir; +@@ -355,9 +356,9 @@ static int acpi_button_add_fs(struct acpi_device *device) + goto done; + } + +-static int acpi_button_remove_fs(struct acpi_device *device) ++static int acpi_button_remove_fs(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + + if (button->type != ACPI_BUTTON_TYPE_LID) + return 0; +@@ -385,9 +386,10 @@ int acpi_lid_open(void) + } + EXPORT_SYMBOL(acpi_lid_open); + +-static int acpi_lid_update_state(struct acpi_device *device, ++static int acpi_lid_update_state(struct acpi_button *button, + bool signal_wakeup) + { ++ struct acpi_device *device = button->adev; + int state; + + state = acpi_lid_evaluate_state(device); +@@ -397,19 +399,17 @@ static int acpi_lid_update_state(struct acpi_device *device, + if (state && signal_wakeup) + acpi_pm_wakeup_event(&device->dev); + +- return acpi_lid_notify_state(device, state); ++ return acpi_lid_notify_state(button, state); + } + +-static void acpi_lid_initialize_state(struct acpi_device *device) ++static void acpi_lid_initialize_state(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); +- + switch (lid_init_state) { + case ACPI_BUTTON_LID_INIT_OPEN: +- (void)acpi_lid_notify_state(device, 1); ++ (void)acpi_lid_notify_state(button, 1); + break; + case ACPI_BUTTON_LID_INIT_METHOD: +- (void)acpi_lid_update_state(device, false); ++ (void)acpi_lid_update_state(button, false); + break; + case ACPI_BUTTON_LID_INIT_IGNORE: + default: +@@ -421,8 +421,8 @@ static void acpi_lid_initialize_state(struct acpi_device *device) + + static void acpi_lid_notify(acpi_handle handle, u32 event, void *data) + { +- struct acpi_device *device = data; +- struct acpi_button *button; ++ struct acpi_button *button = data; ++ struct acpi_device *device = button->adev; + + if (event != ACPI_BUTTON_NOTIFY_STATUS) { + acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", +@@ -430,17 +430,16 @@ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data) + return; + } + +- button = acpi_driver_data(device); + if (!button->lid_state_initialized) + return; + +- acpi_lid_update_state(device, true); ++ acpi_lid_update_state(button, true); + } + + static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + { +- struct acpi_device *device = data; +- struct acpi_button *button; ++ struct acpi_button *button = data; ++ struct acpi_device *device = button->adev; + struct input_dev *input; + int keycode; + +@@ -457,7 +456,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + + acpi_pm_wakeup_event(&device->dev); + +- button = acpi_driver_data(device); + if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) + return; + +@@ -505,7 +503,7 @@ static int acpi_button_resume(struct device *dev) + if (button->type == ACPI_BUTTON_TYPE_LID) { + button->last_state = !!acpi_lid_evaluate_state(device); + button->last_time = ktime_get(); +- acpi_lid_initialize_state(device); ++ acpi_lid_initialize_state(button); + } + + if (button->type == ACPI_BUTTON_TYPE_POWER) { +@@ -521,12 +519,12 @@ static int acpi_button_resume(struct device *dev) + + static int acpi_lid_input_open(struct input_dev *input) + { +- struct acpi_device *device = input_get_drvdata(input); +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_button *button = input_get_drvdata(input); ++ struct acpi_device *device = button->adev; + + button->last_state = !!acpi_lid_evaluate_state(device); + button->last_time = ktime_get(); +- acpi_lid_initialize_state(device); ++ acpi_lid_initialize_state(button); + + return 0; + } +@@ -551,6 +549,7 @@ static int acpi_button_add(struct acpi_device *device) + + device->driver_data = button; + ++ button->adev = device; + button->input = input = input_allocate_device(); + if (!input) { + error = -ENOMEM; +@@ -587,7 +586,7 @@ static int acpi_button_add(struct acpi_device *device) + } + + if (!error) +- error = acpi_button_add_fs(device); ++ error = acpi_button_add_fs(button); + + if (error) { + input_free_device(input); +@@ -617,7 +616,7 @@ static int acpi_button_add(struct acpi_device *device) + break; + } + +- input_set_drvdata(input, device); ++ input_set_drvdata(input, button); + error = input_register_device(input); + if (error) { + input_free_device(input); +@@ -628,17 +627,17 @@ static int acpi_button_add(struct acpi_device *device) + case ACPI_BUS_TYPE_POWER_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_button_event, +- device); ++ button); + break; + case ACPI_BUS_TYPE_SLEEP_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_button_event, +- device); ++ button); + break; + default: + status = acpi_install_notify_handler(device->handle, + ACPI_ALL_NOTIFY, handler, +- device); ++ button); + break; + } + if (ACPI_FAILURE(status)) { +@@ -661,7 +660,7 @@ static int acpi_button_add(struct acpi_device *device) + err_input_unregister: + input_unregister_device(input); + err_remove_fs: +- acpi_button_remove_fs(device); ++ acpi_button_remove_fs(button); + err_free_button: + kfree(button); + return error; +@@ -689,7 +688,7 @@ static void acpi_button_remove(struct acpi_device *device) + } + acpi_os_wait_events_complete(); + +- acpi_button_remove_fs(device); ++ acpi_button_remove_fs(button); + input_unregister_device(button->input); + kfree(button); + } +-- +2.51.0 + diff --git a/queue-6.18/acpi-button-call-device_init_wakeup-earlier-during-p.patch b/queue-6.18/acpi-button-call-device_init_wakeup-earlier-during-p.patch new file mode 100644 index 0000000000..0623a88e08 --- /dev/null +++ b/queue-6.18/acpi-button-call-device_init_wakeup-earlier-during-p.patch @@ -0,0 +1,67 @@ +From 0cbd41fee306283a48dcba36cc7ac48a508c060e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 15:13:26 +0100 +Subject: ACPI: button: Call device_init_wakeup() earlier during probe + +From: Rafael J. Wysocki + +[ Upstream commit e91f8c5305b92b63c8bac315f95c535d5c1e8fec ] + +Calling device_init_wakeup() after installing a notify handler in which +wakeup events are signaled may cause a wakeup event to be missed if the +device is probed right before a system suspend. + +To avoid this, move the device_init_wakeup() call in acpi_button_probe() +before the notify handler installation and add a corresponding cleanup +to the error path. + +Also carry out wakeup cleanup for the button in acpi_button_remove() +because after that point the notify handler will not run for it and +wakeup events coming from it will not be signaled. + +Fixes: 0d51157dfaac ("ACPI: button: Eliminate the driver notify callback") +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/12854922.O9o76ZdvQC@rafael.j.wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index b899b8745fedd..38bc64d6bdaf3 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -625,6 +625,8 @@ static int acpi_button_probe(struct platform_device *pdev) + goto err_remove_fs; + } + ++ device_init_wakeup(&pdev->dev, true); ++ + switch (device->device_type) { + case ACPI_BUS_TYPE_POWER_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, +@@ -655,11 +657,11 @@ static int acpi_button_probe(struct platform_device *pdev) + lid_device = device; + } + +- device_init_wakeup(&pdev->dev, true); + pr_info("%s [%s]\n", name, acpi_device_bid(device)); + return 0; + + err_input_unregister: ++ device_init_wakeup(&pdev->dev, false); + input_unregister_device(input); + err_remove_fs: + acpi_button_remove_fs(button); +@@ -691,6 +693,8 @@ static void acpi_button_remove(struct platform_device *pdev) + } + acpi_os_wait_events_complete(); + ++ device_init_wakeup(&pdev->dev, false); ++ + acpi_button_remove_fs(button); + input_unregister_device(button->input); + kfree(button); +-- +2.51.0 + diff --git a/queue-6.18/acpi-button-convert-the-driver-to-a-platform-one.patch b/queue-6.18/acpi-button-convert-the-driver-to-a-platform-one.patch new file mode 100644 index 0000000000..5b5bcfdae7 --- /dev/null +++ b/queue-6.18/acpi-button-convert-the-driver-to-a-platform-one.patch @@ -0,0 +1,211 @@ +From 04681d258c4a7119c6f042f3e3ff1eb4ed356615 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Dec 2025 14:57:57 +0100 +Subject: ACPI: button: Convert the driver to a platform one + +From: Rafael J. Wysocki + +[ Upstream commit 52d86401963666423cb9a56d117136c846093db0 ] + +While binding drivers directly to struct acpi_device objects allows +basic functionality to be provided, at least in the majority of cases, +there are some problems with it, related to general consistency, sysfs +layout, power management operation ordering, and code cleanliness. + +Overall, it is better to bind drivers to platform devices than to their +ACPI companions, so convert the ACPI button driver to a platform one. + +While this is not expected to alter functionality, it changes sysfs +layout and so it will be visible to user space. + +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/2461734.NG923GbCHz@rafael.j.wysocki +Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe") +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 61 +++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 29 deletions(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 09a6e4ffe9f20..b899b8745fedd 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + + #define ACPI_BUTTON_CLASS "button" +@@ -145,8 +146,8 @@ static const struct dmi_system_id dmi_lid_quirks[] = { + {} + }; + +-static int acpi_button_add(struct acpi_device *device); +-static void acpi_button_remove(struct acpi_device *device); ++static int acpi_button_probe(struct platform_device *pdev); ++static void acpi_button_remove(struct platform_device *pdev); + + #ifdef CONFIG_PM_SLEEP + static int acpi_button_suspend(struct device *dev); +@@ -157,19 +158,19 @@ static int acpi_button_resume(struct device *dev); + #endif + static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume); + +-static struct acpi_driver acpi_button_driver = { +- .name = "button", +- .class = ACPI_BUTTON_CLASS, +- .ids = button_device_ids, +- .ops = { +- .add = acpi_button_add, +- .remove = acpi_button_remove, ++static struct platform_driver acpi_button_driver = { ++ .probe = acpi_button_probe, ++ .remove = acpi_button_remove, ++ .driver = { ++ .name = "acpi-button", ++ .acpi_match_table = button_device_ids, ++ .pm = &acpi_button_pm, + }, +- .drv.pm = &acpi_button_pm, + }; + + struct acpi_button { + struct acpi_device *adev; ++ struct platform_device *pdev; + unsigned int type; + struct input_dev *input; + char phys[32]; /* for input device */ +@@ -397,7 +398,7 @@ static int acpi_lid_update_state(struct acpi_button *button, + return state; + + if (state && signal_wakeup) +- acpi_pm_wakeup_event(&device->dev); ++ acpi_pm_wakeup_event(&button->pdev->dev); + + return acpi_lid_notify_state(button, state); + } +@@ -454,7 +455,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + return; + } + +- acpi_pm_wakeup_event(&device->dev); ++ acpi_pm_wakeup_event(&button->pdev->dev); + + if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) + return; +@@ -486,8 +487,7 @@ static u32 acpi_button_event(void *data) + #ifdef CONFIG_PM_SLEEP + static int acpi_button_suspend(struct device *dev) + { +- struct acpi_device *device = to_acpi_device(dev); +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_button *button = dev_get_drvdata(dev); + + button->suspended = true; + return 0; +@@ -495,9 +495,9 @@ static int acpi_button_suspend(struct device *dev) + + static int acpi_button_resume(struct device *dev) + { ++ struct acpi_button *button = dev_get_drvdata(dev); ++ struct acpi_device *device = ACPI_COMPANION(dev); + struct input_dev *input; +- struct acpi_device *device = to_acpi_device(dev); +- struct acpi_button *button = acpi_driver_data(device); + + button->suspended = false; + if (button->type == ACPI_BUTTON_TYPE_LID) { +@@ -529,8 +529,9 @@ static int acpi_lid_input_open(struct input_dev *input) + return 0; + } + +-static int acpi_button_add(struct acpi_device *device) ++static int acpi_button_probe(struct platform_device *pdev) + { ++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev); + acpi_notify_handler handler; + struct acpi_button *button; + struct input_dev *input; +@@ -547,8 +548,9 @@ static int acpi_button_add(struct acpi_device *device) + if (!button) + return -ENOMEM; + +- device->driver_data = button; ++ platform_set_drvdata(pdev, button); + ++ button->pdev = pdev; + button->adev = device; + button->input = input = input_allocate_device(); + if (!input) { +@@ -599,7 +601,7 @@ static int acpi_button_add(struct acpi_device *device) + input->phys = button->phys; + input->id.bustype = BUS_HOST; + input->id.product = button->type; +- input->dev.parent = &device->dev; ++ input->dev.parent = &pdev->dev; + + switch (button->type) { + case ACPI_BUTTON_TYPE_POWER: +@@ -653,7 +655,7 @@ static int acpi_button_add(struct acpi_device *device) + lid_device = device; + } + +- device_init_wakeup(&device->dev, true); ++ device_init_wakeup(&pdev->dev, true); + pr_info("%s [%s]\n", name, acpi_device_bid(device)); + return 0; + +@@ -666,9 +668,10 @@ static int acpi_button_add(struct acpi_device *device) + return error; + } + +-static void acpi_button_remove(struct acpi_device *device) ++static void acpi_button_remove(struct platform_device *pdev) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev); ++ struct acpi_button *button = platform_get_drvdata(pdev); + + switch (device->device_type) { + case ACPI_BUS_TYPE_POWER_BUTTON: +@@ -727,7 +730,7 @@ module_param_call(lid_init_state, + NULL, 0644); + MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state"); + +-static int acpi_button_register_driver(struct acpi_driver *driver) ++static int __init acpi_button_init(void) + { + const struct dmi_system_id *dmi_id; + +@@ -743,20 +746,20 @@ static int acpi_button_register_driver(struct acpi_driver *driver) + * Modules such as nouveau.ko and i915.ko have a link time dependency + * on acpi_lid_open(), and would therefore not be loadable on ACPI + * capable kernels booted in non-ACPI mode if the return value of +- * acpi_bus_register_driver() is returned from here with ACPI disabled ++ * platform_driver_register() is returned from here with ACPI disabled + * when this driver is built as a module. + */ + if (acpi_disabled) + return 0; + +- return acpi_bus_register_driver(driver); ++ return platform_driver_register(&acpi_button_driver); + } + +-static void acpi_button_unregister_driver(struct acpi_driver *driver) ++static void __exit acpi_button_exit(void) + { + if (!acpi_disabled) +- acpi_bus_unregister_driver(driver); ++ platform_driver_unregister(&acpi_button_driver); + } + +-module_driver(acpi_button_driver, acpi_button_register_driver, +- acpi_button_unregister_driver); ++module_init(acpi_button_init); ++module_exit(acpi_button_exit); +-- +2.51.0 + diff --git a/queue-6.18/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch b/queue-6.18/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch new file mode 100644 index 0000000000..c72da3b62a --- /dev/null +++ b/queue-6.18/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch @@ -0,0 +1,55 @@ +From 697f2a878193ad5ac05f53dbbfa35d3a0bab0cd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 21:22:54 +0000 +Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs + +From: Sean V Kelley + +[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ] + +per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online +CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> +acpi_cppc_processor_probe(). + +However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all +possible CPUs. In acpi_get_psd_map(), encountering an offline CPU +returns -EFAULT, causing cppc_cpufreq initialization to fail. + +This breaks systems booted with "nosmt" or "nosmt=force". + +Fix by using for_each_online_cpu() in both functions. + +Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests") +Signed-off-by: Sean V Kelley +Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index e66e20d1f31b7..b59b0100d03c5 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -362,7 +362,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) + end: + if (cmd == CMD_WRITE) { + if (unlikely(ret)) { +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i); + + if (!desc) +@@ -524,7 +524,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data) + else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) + cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; + +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + if (i == cpu) + continue; + +-- +2.51.0 + diff --git a/queue-6.18/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch b/queue-6.18/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch new file mode 100644 index 0000000000..c628aff686 --- /dev/null +++ b/queue-6.18/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch @@ -0,0 +1,67 @@ +From 16e6728e45c0f7450486d6cb54ad7f7750f9efaf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Feb 2026 00:14:52 +0800 +Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO + +From: Zhai Can + +[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ] + +On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete +NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table +bug (lack of reference), PXP will be shut dow as an "unused" power resource +during initialization, making the NVMe slot #2 + NVIDIA both inaccessible. + +This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check +states of power resources during initialization"). Here are test +results on the three consecutive commits: + +(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization +(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state +(bad) 519d81956ee2 Linux 5.15-rc6 + +On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in +unknown state") this was not an issue because the power resource state +left UNKNOWN thus being ignored. + +See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power +resources on the Toshiba Click Mini") which is another almost identical +case to this one. + +Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization") +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087 +Signed-off-by: Zhai Can +Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/power.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c +index 361a7721a6a87..7da5ae5594a72 100644 +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -1113,6 +1113,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"), + }, + }, ++ { ++ /* ++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power ++ * resource 'PXP' will be shut down on initialization, making ++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're ++ * both controlled by 'PXP'). ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"), ++ } ++ ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.18/apparmor-account-for-in_atomic-removal-in-common_fil.patch b/queue-6.18/apparmor-account-for-in_atomic-removal-in-common_fil.patch new file mode 100644 index 0000000000..a10a3f3363 --- /dev/null +++ b/queue-6.18/apparmor-account-for-in_atomic-removal-in-common_fil.patch @@ -0,0 +1,46 @@ +From b7dc5b1ba28ccb80d5a25de4bbdf12eabcee7922 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jan 2026 11:47:02 -0800 +Subject: apparmor: account for in_atomic removal in common_file_perm + +From: Ryan Lee + +[ Upstream commit 9b829c0aa96e9385b1e9a308d3eb054b95fbeda2 ] + +If we are not in an atomic context in common_file_perm, then we don't have +to use the atomic versions, resulting in improved performance outside of +atomic contexts. + +Signed-off-by: Ryan Lee +Signed-off-by: John Johansen +Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases") +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 4e44bd5bf1d91..5fc99fe8d38a4 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -523,15 +523,14 @@ static int common_file_perm(const char *op, struct file *file, u32 mask) + { + struct aa_label *label; + int error = 0; +- bool needput; + + /* don't reaudit files closed during inheritance */ + if (unlikely(file->f_path.dentry == aa_null.dentry)) + return -EACCES; + +- label = __begin_current_label_crit_section(&needput); ++ label = begin_current_label_crit_section(); + error = aa_file_perm(op, current_cred(), label, file, mask, false); +- __end_current_label_crit_section(label, needput); ++ end_current_label_crit_section(label); + + return error; + } +-- +2.51.0 + diff --git a/queue-6.18/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch b/queue-6.18/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch new file mode 100644 index 0000000000..6d6281dfe6 --- /dev/null +++ b/queue-6.18/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch @@ -0,0 +1,108 @@ +From 81990ddea20e9ae7031e67c9154b243ca9044a1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:11:07 +0100 +Subject: AppArmor: Allow apparmor to handle unaligned dfa tables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Helge Deller + +[ Upstream commit 64802f731214a51dfe3c6c27636b3ddafd003eb0 ] + +The dfa tables can originate from kernel or userspace and 8-byte alignment +isn't always guaranteed and as such may trigger unaligned memory accesses +on various architectures. Resulting in the following + +[   73.901376] WARNING: CPU: 0 PID: 341 at security/apparmor/match.c:316 aa_dfa_unpack+0x6cc/0x720 +[   74.015867] Modules linked in: binfmt_misc evdev flash sg drm drm_panel_orientation_quirks backlight i2c_core configfs nfnetlink autofs4 ext4 crc16 mbcache jbd2 hid_generic usbhid sr_mod hid cdrom +sd_mod ata_generic ohci_pci ehci_pci ehci_hcd ohci_hcd pata_ali libata sym53c8xx scsi_transport_spi tg3 scsi_mod usbcore libphy scsi_common mdio_bus usb_common +[   74.428977] CPU: 0 UID: 0 PID: 341 Comm: apparmor_parser Not tainted 6.18.0-rc6+ #9 NONE +[   74.536543] Call Trace: +[   74.568561] [<0000000000434c24>] dump_stack+0x8/0x18 +[   74.633757] [<0000000000476438>] __warn+0xd8/0x100 +[   74.696664] [<00000000004296d4>] warn_slowpath_fmt+0x34/0x74 +[   74.771006] [<00000000008db28c>] aa_dfa_unpack+0x6cc/0x720 +[   74.843062] [<00000000008e643c>] unpack_pdb+0xbc/0x7e0 +[   74.910545] [<00000000008e7740>] unpack_profile+0xbe0/0x1300 +[   74.984888] [<00000000008e82e0>] aa_unpack+0xe0/0x6a0 +[   75.051226] [<00000000008e3ec4>] aa_replace_profiles+0x64/0x1160 +[   75.130144] [<00000000008d4d90>] policy_update+0xf0/0x280 +[   75.201057] [<00000000008d4fc8>] profile_replace+0xa8/0x100 +[   75.274258] [<0000000000766bd0>] vfs_write+0x90/0x420 +[   75.340594] [<00000000007670cc>] ksys_write+0x4c/0xe0 +[   75.406932] [<0000000000767174>] sys_write+0x14/0x40 +[   75.472126] [<0000000000406174>] linux_sparc_syscall+0x34/0x44 +[   75.548802] ---[ end trace 0000000000000000 ]--- +[   75.609503] dfa blob stream 0xfff0000008926b96 not aligned. +[   75.682695] Kernel unaligned access at TPC[8db2a8] aa_dfa_unpack+0x6e8/0x720 + +Work around it by using the get_unaligned_xx() helpers. + +Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack") +Reported-by: John Paul Adrian Glaubitz +Closes: https://github.com/sparclinux/issues/issues/30 +Signed-off-by: Helge Deller +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/match.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/security/apparmor/match.c b/security/apparmor/match.c +index c5a91600842a1..26e82ba879d44 100644 +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include "include/lib.h" + #include "include/match.h" +@@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize) + /* loaded td_id's start at 1, subtract 1 now to avoid doing + * it every time we use td_id as an index + */ +- th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1; ++ th.td_id = get_unaligned_be16(blob) - 1; + if (th.td_id > YYTD_ID_MAX) + goto out; +- th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2)); +- th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8)); ++ th.td_flags = get_unaligned_be16(blob + 2); ++ th.td_lolen = get_unaligned_be32(blob + 8); + blob += sizeof(struct table_header); + + if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || +@@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) + if (size < sizeof(struct table_set_header)) + goto fail; + +- if (ntohl(*(__be32 *) data) != YYTH_MAGIC) ++ if (get_unaligned_be32(data) != YYTH_MAGIC) + goto fail; + +- hsize = ntohl(*(__be32 *) (data + 4)); ++ hsize = get_unaligned_be32(data + 4); + if (size < hsize) + goto fail; + +- dfa->flags = ntohs(*(__be16 *) (data + 12)); ++ dfa->flags = get_unaligned_be16(data + 12); + if (dfa->flags & ~(YYTH_FLAGS)) + goto fail; + +@@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) + * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) { + * if (hsize < 16 + 4) + * goto fail; +- * dfa->max_oob = ntol(*(__be32 *) (data + 16)); ++ * dfa->max_oob = get_unaligned_be32(data + 16); + * if (dfa->max <= MAX_OOB_SUPPORTED) { + * pr_err("AppArmor DFA OOB greater than supported\n"); + * goto fail; +-- +2.51.0 + diff --git a/queue-6.18/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch b/queue-6.18/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch new file mode 100644 index 0000000000..e24c801b1a --- /dev/null +++ b/queue-6.18/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch @@ -0,0 +1,43 @@ +From 93e3eb98d7b22d429f53aac02dd90de32fd32663 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Jan 2026 19:03:07 -0500 +Subject: apparmor: avoid per-cpu hold underflow in aa_get_buffer + +From: Zhengmian Hu + +[ Upstream commit 640cf2f09575c9dc344b3f7be2498d31e3923ead ] + +When aa_get_buffer() pulls from the per-cpu list it unconditionally +decrements cache->hold. If hold reaches 0 while count is still non-zero, +the unsigned decrement wraps to UINT_MAX. This keeps hold non-zero for a +very long time, so aa_put_buffer() never returns buffers to the global +list, which can starve other CPUs and force repeated kmalloc(aa_g_path_max) +allocations. + +Guard the decrement so hold never underflows. +Fixes: ea9bae12d028 ("apparmor: cache buffers on percpu list if there is lock contention") + +Signed-off-by: Zhengmian Hu +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index be3678d08ed23..13c9bfdf65ff5 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -2136,7 +2136,8 @@ char *aa_get_buffer(bool in_atomic) + if (!list_empty(&cache->head)) { + aa_buf = list_first_entry(&cache->head, union aa_buffer, list); + list_del(&aa_buf->list); +- cache->hold--; ++ if (cache->hold) ++ cache->hold--; + cache->count--; + put_cpu_ptr(&aa_local_buffers); + return &aa_buf->buffer[0]; +-- +2.51.0 + diff --git a/queue-6.18/apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch b/queue-6.18/apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch new file mode 100644 index 0000000000..fa42cec305 --- /dev/null +++ b/queue-6.18/apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch @@ -0,0 +1,102 @@ +From a17e93d7177534497989d09964775ce3a8810144 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jan 2026 23:40:03 -0800 +Subject: apparmor: drop in_atomic flag in common_mmap, and common_file_perm + +From: John Johansen + +[ Upstream commit c3f27ccdb2dce3f0f2814574d06017f46c11fa29 ] + +with the previous changes to mmap the in_atomic flag is now always +false, so drop it. + +Suggested-by: Tyler Hicks +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases") +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index b02c6c8951cd6..4e44bd5bf1d91 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -519,8 +519,7 @@ static void apparmor_file_free_security(struct file *file) + aa_put_label(rcu_access_pointer(ctx->label)); + } + +-static int common_file_perm(const char *op, struct file *file, u32 mask, +- bool in_atomic) ++static int common_file_perm(const char *op, struct file *file, u32 mask) + { + struct aa_label *label; + int error = 0; +@@ -531,7 +530,7 @@ static int common_file_perm(const char *op, struct file *file, u32 mask, + return -EACCES; + + label = __begin_current_label_crit_section(&needput); +- error = aa_file_perm(op, current_cred(), label, file, mask, in_atomic); ++ error = aa_file_perm(op, current_cred(), label, file, mask, false); + __end_current_label_crit_section(label, needput); + + return error; +@@ -539,13 +538,12 @@ static int common_file_perm(const char *op, struct file *file, u32 mask, + + static int apparmor_file_receive(struct file *file) + { +- return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file), +- false); ++ return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file)); + } + + static int apparmor_file_permission(struct file *file, int mask) + { +- return common_file_perm(OP_FPERM, file, mask, false); ++ return common_file_perm(OP_FPERM, file, mask); + } + + static int apparmor_file_lock(struct file *file, unsigned int cmd) +@@ -555,11 +553,11 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd) + if (cmd == F_WRLCK) + mask |= MAY_WRITE; + +- return common_file_perm(OP_FLOCK, file, mask, false); ++ return common_file_perm(OP_FLOCK, file, mask); + } + + static int common_mmap(const char *op, struct file *file, unsigned long prot, +- unsigned long flags, bool in_atomic) ++ unsigned long flags) + { + int mask = 0; + +@@ -577,21 +575,20 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot, + if (prot & PROT_EXEC) + mask |= AA_EXEC_MMAP; + +- return common_file_perm(op, file, mask, in_atomic); ++ return common_file_perm(op, file, mask); + } + + static int apparmor_mmap_file(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) + { +- return common_mmap(OP_FMMAP, file, prot, flags, false); ++ return common_mmap(OP_FMMAP, file, prot, flags); + } + + static int apparmor_file_mprotect(struct vm_area_struct *vma, + unsigned long reqprot, unsigned long prot) + { + return common_mmap(OP_FMPROT, vma->vm_file, prot, +- !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0, +- false); ++ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); + } + + #ifdef CONFIG_IO_URING +-- +2.51.0 + diff --git a/queue-6.18/apparmor-fix-aa_label-to-return-state-from-compount-.patch b/queue-6.18/apparmor-fix-aa_label-to-return-state-from-compount-.patch new file mode 100644 index 0000000000..c8140a0a1c --- /dev/null +++ b/queue-6.18/apparmor-fix-aa_label-to-return-state-from-compount-.patch @@ -0,0 +1,74 @@ +From f980f740bc58df84fb3aba8bd8c7d97d407dc0aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 04:12:02 -0800 +Subject: apparmor: fix aa_label to return state from compount and component + match + +From: John Johansen + +[ Upstream commit 9058798652c8bc0584ed1fb0766a1015046c06e8 ] + +aa-label_match is not correctly returning the state in all cases. +The only reason this didn't cause a error is that all callers currently +ignore the return value. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202602020631.wXgZosyU-lkp@intel.com/ +Fixes: a4c9efa4dbad6 ("apparmor: make label_match return a consistent value") +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 1d3fa5c28d97f..dd6c58f595ba8 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1334,7 +1334,7 @@ static int label_compound_match(struct aa_profile *profile, + * @request: permissions to request + * @perms: an initialized perms struct to add accumulation to + * +- * Returns: 0 on success else ERROR ++ * Returns: the state the match finished in, may be the none matching state + * + * For the label A//&B//&C this does the perm match for each of A and B and C + * @perms should be preinitialized with allperms OR a previous permission +@@ -1362,7 +1362,7 @@ static int label_components_match(struct aa_profile *profile, + } + + /* no subcomponents visible - no change in perms */ +- return 0; ++ return state; + + next: + tmp = *aa_lookup_perms(rules->policy, state); +@@ -1378,13 +1378,13 @@ static int label_components_match(struct aa_profile *profile, + } + + if ((perms->allow & request) != request) +- return -EACCES; ++ return DFA_NOMATCH; + +- return 0; ++ return state; + + fail: + *perms = nullperms; +- return -EACCES; ++ return DFA_NOMATCH; + } + + /** +@@ -1406,7 +1406,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, + aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, + request, perms); + if ((perms->allow & request) == request) +- return 0; ++ return tmp; + + /* failed compound_match try component matches */ + *perms = allperms; +-- +2.51.0 + diff --git a/queue-6.18/apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch b/queue-6.18/apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch new file mode 100644 index 0000000000..11e5a31a97 --- /dev/null +++ b/queue-6.18/apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch @@ -0,0 +1,38 @@ +From 28d7f2b9241cd7084ce1a1294a59c6366b152c68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jan 2026 11:48:54 -0800 +Subject: apparmor: fix boolean argument in apparmor_mmap_file + +From: Ryan Lee + +[ Upstream commit 48d5268e911abcf7674ec33c9b0b3e952be1175e ] + +The previous value of GFP_ATOMIC is an int and not a bool, potentially +resulting in UB when being assigned to a bool. In addition, the mmap hook +is called outside of locks (i.e. in a non-atomic context), so we can pass +a fixed constant value of false instead to common_mmap. + +Signed-off-by: Ryan Lee +Signed-off-by: John Johansen +Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases") +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index b3f7a3258a2cf..b02c6c8951cd6 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -583,7 +583,7 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot, + static int apparmor_mmap_file(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) + { +- return common_mmap(OP_FMMAP, file, prot, flags, GFP_ATOMIC); ++ return common_mmap(OP_FMMAP, file, prot, flags, false); + } + + static int apparmor_file_mprotect(struct vm_area_struct *vma, +-- +2.51.0 + diff --git a/queue-6.18/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch b/queue-6.18/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch new file mode 100644 index 0000000000..f319f98022 --- /dev/null +++ b/queue-6.18/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch @@ -0,0 +1,85 @@ +From 39754f2e1d194ddaef2934efa36e1af28ab6363b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 15:58:45 -0300 +Subject: apparmor: fix invalid deref of rawdata when export_binary is unset + +From: Georgia Garcia + +[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ] + +If the export_binary parameter is disabled on runtime, profiles that +were loaded before that will still have their rawdata stored in +apparmorfs, with a symbolic link to the rawdata on the policy +directory. When one of those profiles are replaced, the rawdata is set +to NULL, but when trying to resolve the symbolic links to rawdata for +that profile, it will try to dereference profile->rawdata->name when +profile->rawdata is now NULL causing an oops. Fix it by checking if +rawdata is set. + +[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088 +[ 168.657420] #PF: supervisor read access in kernel mode +[ 168.660619] #PF: error_code(0x0000) - not-present page +[ 168.663613] PGD 0 P4D 0 +[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI +[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary) +[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330 +[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8 +[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282 +[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158 +[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80 +[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000 +[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80 +[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0 +[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000 +[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0 +[ 168.701696] Call Trace: +[ 168.702325] +[ 168.702995] rawdata_get_link_data+0x1c/0x30 +[ 168.704145] vfs_readlink+0xd4/0x160 +[ 168.705152] do_readlinkat+0x114/0x180 +[ 168.706214] __x64_sys_readlink+0x1e/0x30 +[ 168.708653] x64_sys_call+0x1d77/0x26b0 +[ 168.709525] do_syscall_64+0x81/0x500 +[ 168.710348] ? do_statx+0x72/0xb0 +[ 168.711109] ? putname+0x3e/0x80 +[ 168.711845] ? __x64_sys_statx+0xb7/0x100 +[ 168.712711] ? x64_sys_call+0x10fc/0x26b0 +[ 168.713577] ? do_syscall_64+0xbf/0x500 +[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0 +[ 168.715404] ? irqentry_exit+0xb2/0x740 +[ 168.716359] ? exc_page_fault+0x90/0x1b0 +[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement") +Signed-off-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index 391a586d0557f..7803b973b4c42 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -1639,6 +1639,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry, + + label = aa_get_label_rcu(&proxy->label); + profile = labels_profile(label); ++ ++ /* rawdata can be null when aa_g_export_binary is unset during ++ * runtime and a profile is replaced ++ */ ++ if (!profile->rawdata) { ++ aa_put_label(label); ++ return ERR_PTR(-ENOENT); ++ } ++ + depth = profile_depth(profile); + target = gen_symlink_name(depth, profile->rawdata->name, name); + aa_put_label(label); +-- +2.51.0 + diff --git a/queue-6.18/apparmor-fix-null-pointer-dereference-in-__unix_need.patch b/queue-6.18/apparmor-fix-null-pointer-dereference-in-__unix_need.patch new file mode 100644 index 0000000000..260c319b8e --- /dev/null +++ b/queue-6.18/apparmor-fix-null-pointer-dereference-in-__unix_need.patch @@ -0,0 +1,62 @@ +From 6ca8f1cd024a58c1855efb33d12332dc121bf30e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 16:35:00 +0000 +Subject: apparmor: fix NULL pointer dereference in __unix_needs_revalidation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: System Administrator + +[ Upstream commit e2938ad00b21340c0362562dfedd7cfec0554d67 ] + +When receiving file descriptors via SCM_RIGHTS, both the socket pointer +and the socket's sk pointer can be NULL during socket setup or teardown, +causing NULL pointer dereferences in __unix_needs_revalidation(). + +This is a regression in AppArmor 5.0.0 (kernel 6.17+) where the new +__unix_needs_revalidation() function was added without proper NULL checks. + +The crash manifests as: + BUG: kernel NULL pointer dereference, address: 0x0000000000000018 + RIP: aa_file_perm+0xb7/0x3b0 (or +0xbe/0x3b0, +0xc0/0x3e0) + Call Trace: + apparmor_file_receive+0x42/0x80 + security_file_receive+0x2e/0x50 + receive_fd+0x1d/0xf0 + scm_detach_fds+0xad/0x1c0 + +The function dereferences sock->sk->sk_family without checking if either +sock or sock->sk is NULL first. + +Add NULL checks for both sock and sock->sk before accessing sk_family. + +Fixes: 88fec3526e841 ("apparmor: make sure unix socket labeling is correctly updated.") +Reported-by: Jamin Mc +Closes: https://bugzilla.proxmox.com/show_bug.cgi?id=7083 +Closes: https://gitlab.com/apparmor/apparmor/-/issues/568 +Signed-off-by: Fabian Grünbichler +Signed-off-by: System Administrator +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/file.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/security/apparmor/file.c b/security/apparmor/file.c +index c758204028780..919dbbbc87ab6 100644 +--- a/security/apparmor/file.c ++++ b/security/apparmor/file.c +@@ -578,6 +578,9 @@ static bool __unix_needs_revalidation(struct file *file, struct aa_label *label, + return false; + if (request & NET_PEER_MASK) + return false; ++ /* sock and sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return false; + if (sock->sk->sk_family == PF_UNIX) { + struct aa_sk_ctx *ctx = aa_sock(sock->sk); + +-- +2.51.0 + diff --git a/queue-6.18/apparmor-fix-null-sock-in-aa_sock_file_perm.patch b/queue-6.18/apparmor-fix-null-sock-in-aa_sock_file_perm.patch new file mode 100644 index 0000000000..e52de353d0 --- /dev/null +++ b/queue-6.18/apparmor-fix-null-sock-in-aa_sock_file_perm.patch @@ -0,0 +1,44 @@ +From bc58740ab87fc6aedfae2f5119cff0a5ecac37ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:07:42 -0800 +Subject: apparmor: fix NULL sock in aa_sock_file_perm + +From: John Johansen + +[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ] + +Deal with the potential that sock and sock-sk can be NULL during +socket setup or teardown. This could lead to an oops. The fix for NULL +pointer dereference in __unix_needs_revalidation shows this is at +least possible for af_unix sockets. While the fix for af_unix sockets +applies for newer mediation this is still the fall back path for older +af_unix mediation and other sockets, so ensure it is covered. + +Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/net.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 45cf25605c345..44c04102062f3 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -326,8 +326,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, + struct socket *sock = (struct socket *) file->private_data; + + AA_BUG(!label); +- AA_BUG(!sock); +- AA_BUG(!sock->sk); ++ ++ /* sock && sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return 0; + + if (sock->sk->sk_family == PF_UNIX) + return aa_unix_file_perm(subj_cred, label, op, request, file); +-- +2.51.0 + diff --git a/queue-6.18/apparmor-fix-optimize-table-creation-from-possibly-u.patch b/queue-6.18/apparmor-fix-optimize-table-creation-from-possibly-u.patch new file mode 100644 index 0000000000..56c05eeb70 --- /dev/null +++ b/queue-6.18/apparmor-fix-optimize-table-creation-from-possibly-u.patch @@ -0,0 +1,79 @@ +From bf90f4a6c7be30d9e17de847a880b88144fd4cc3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 21:15:04 +0100 +Subject: apparmor: Fix & Optimize table creation from possibly unaligned + memory + +From: Helge Deller + +[ Upstream commit 6fc367bfd4c8886e6b1742aabbd1c0bdc310db3a ] + +Source blob may come from userspace and might be unaligned. +Try to optize the copying process by avoiding unaligned memory accesses. + +- Added Fixes tag +- Added "Fix &" to description as this doesn't just optimize but fixes + a potential unaligned memory access +Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack") +Signed-off-by: Helge Deller +[jj: remove duplicate word "convert" in comment trigger checkpatch warning] +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/include/match.h | 12 +++++++----- + security/apparmor/match.c | 7 +++---- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h +index 1fbe82f5021b1..0dde8eda3d1a5 100644 +--- a/security/apparmor/include/match.h ++++ b/security/apparmor/include/match.h +@@ -104,16 +104,18 @@ struct aa_dfa { + struct table_header *tables[YYTD_ID_TSIZE]; + }; + +-#define byte_to_byte(X) (X) +- + #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \ + do { \ + typeof(LEN) __i; \ + TTYPE *__t = (TTYPE *) TABLE; \ + BTYPE *__b = (BTYPE *) BLOB; \ +- for (__i = 0; __i < LEN; __i++) { \ +- __t[__i] = NTOHX(__b[__i]); \ +- } \ ++ BUILD_BUG_ON(sizeof(TTYPE) != sizeof(BTYPE)); \ ++ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) \ ++ memcpy(__t, __b, (LEN) * sizeof(BTYPE)); \ ++ else /* copy & convert from big-endian */ \ ++ for (__i = 0; __i < LEN; __i++) { \ ++ __t[__i] = NTOHX(&__b[__i]); \ ++ } \ + } while (0) + + static inline size_t table_size(size_t len, size_t el_size) +diff --git a/security/apparmor/match.c b/security/apparmor/match.c +index 26e82ba879d44..bbeb3be68572f 100644 +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -67,14 +67,13 @@ static struct table_header *unpack_table(char *blob, size_t bsize) + table->td_flags = th.td_flags; + table->td_lolen = th.td_lolen; + if (th.td_flags == YYTD_DATA8) +- UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u8, u8, byte_to_byte); ++ memcpy(table->td_data, blob, th.td_lolen); + else if (th.td_flags == YYTD_DATA16) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u16, __be16, be16_to_cpu); ++ u16, __be16, get_unaligned_be16); + else if (th.td_flags == YYTD_DATA32) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u32, __be32, be32_to_cpu); ++ u32, __be32, get_unaligned_be32); + else + goto fail; + /* if table was vmalloced make sure the page tables are synced +-- +2.51.0 + diff --git a/queue-6.18/apparmor-fix-rlimit-for-posix-cpu-timers.patch b/queue-6.18/apparmor-fix-rlimit-for-posix-cpu-timers.patch new file mode 100644 index 0000000000..c1bb472422 --- /dev/null +++ b/queue-6.18/apparmor-fix-rlimit-for-posix-cpu-timers.patch @@ -0,0 +1,40 @@ +From a92faeff75b9b95efb19f934a2d8a04b7e8fb45f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:16:54 -0800 +Subject: apparmor: fix rlimit for posix cpu timers + +From: John Johansen + +[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ] + +Posix cpu timers requires an additional step beyond setting the rlimit. +Refactor the code so its clear when what code is setting the +limit and conditionally update the posix cpu timers when appropriate. + +Fixes: baa73d9e478ff ("posix-timers: Make them configurable") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/resource.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index 8e80db3ae21c0..64212b39ba4bb 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -196,6 +196,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l) + rules->rlimits.limits[j].rlim_max); + /* soft limit should not exceed hard limit */ + rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); ++ if (j == RLIMIT_CPU && ++ rlim->rlim_cur != RLIM_INFINITY && ++ IS_ENABLED(CONFIG_POSIX_TIMERS)) ++ (void) update_rlimit_cpu(current->group_leader, ++ rlim->rlim_cur); + } + } + } +-- +2.51.0 + diff --git a/queue-6.18/apparmor-make-label_match-return-a-consistent-value.patch b/queue-6.18/apparmor-make-label_match-return-a-consistent-value.patch new file mode 100644 index 0000000000..ba4da646a1 --- /dev/null +++ b/queue-6.18/apparmor-make-label_match-return-a-consistent-value.patch @@ -0,0 +1,80 @@ +From 1b50e53d14a5564ef310d834b10eb8a68e13c47a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 23:59:38 -0800 +Subject: apparmor: make label_match return a consistent value + +From: John Johansen + +[ Upstream commit a4c9efa4dbad6dacad6e8b274e30e814c8353097 ] + +compound match is inconsistent in returning a state or an integer error +this is problemati if the error is ever used as a state in the state +machine + +Fixes: f1bd904175e81 ("apparmor: add the base fns() for domain labels") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 02ee128f53d13..1d3fa5c28d97f 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1278,7 +1278,7 @@ static inline aa_state_t match_component(struct aa_profile *profile, + * @request: permissions to request + * @perms: perms struct to set + * +- * Returns: 0 on success else ERROR ++ * Returns: state match stopped at or DFA_NOMATCH if aborted early + * + * For the label A//&B//&C this does the perm match for A//&B//&C + * @perms should be preinitialized with allperms OR a previous permission +@@ -1305,7 +1305,7 @@ static int label_compound_match(struct aa_profile *profile, + + /* no component visible */ + *perms = allperms; +- return 0; ++ return state; + + next: + label_for_each_cont(i, label, tp) { +@@ -1317,14 +1317,11 @@ static int label_compound_match(struct aa_profile *profile, + goto fail; + } + *perms = *aa_lookup_perms(rules->policy, state); +- if ((perms->allow & request) != request) +- return -EACCES; +- +- return 0; ++ return state; + + fail: + *perms = nullperms; +- return state; ++ return DFA_NOMATCH; + } + + /** +@@ -1406,11 +1403,12 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, + struct aa_label *label, aa_state_t state, bool subns, + u32 request, struct aa_perms *perms) + { +- int error = label_compound_match(profile, rules, label, state, subns, +- request, perms); +- if (!error) +- return error; ++ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, ++ request, perms); ++ if ((perms->allow & request) == request) ++ return 0; + ++ /* failed compound_match try component matches */ + *perms = allperms; + return label_components_match(profile, rules, label, state, subns, + request, perms); +-- +2.51.0 + diff --git a/queue-6.18/apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch b/queue-6.18/apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch new file mode 100644 index 0000000000..1828b33abe --- /dev/null +++ b/queue-6.18/apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch @@ -0,0 +1,85 @@ +From 20e659bd6f569bdd9cd1d48e83db5fd650ebb624 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 13 Sep 2025 02:22:21 -0700 +Subject: apparmor: move check for aa_null file to cover all cases + +From: John Johansen + +[ Upstream commit 4a134723f9f1ad2f3621566259db673350d19cb1 ] + +files with a dentry pointing aa_null.dentry where already rejected as +part of file_inheritance. Unfortunately the check in +common_file_perm() is insufficient to cover all cases causing +unnecessary audit messages without the original files context. + +Eg. +[ 442.886474] audit: type=1400 audit(1704822661.616:329): apparmor="DENIED" operation="file_inherit" class="file" namespace="root//lxd-juju-98527a-0_" profile="snap.lxd.activate" name="/apparmor/.null" pid=9525 comm="snap-exec" + +Further examples of this are in the logs of +https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2120439 +https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1952084 +https://bugs.launchpad.net/snapd/+bug/2049099 + +These messages have no value and should not be sent to the logs. +AppArmor was already filtering the out in some cases but the original +patch did not catch all cases. Fix this by push the existing check +down into two functions that should cover all cases. + +Link: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2122743 +Fixes: 192ca6b55a86 ("apparmor: revalidate files during exec") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/file.c | 12 ++++++++++-- + security/apparmor/lsm.c | 4 ---- + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/security/apparmor/file.c b/security/apparmor/file.c +index 919dbbbc87ab6..7de23e85cd5d0 100644 +--- a/security/apparmor/file.c ++++ b/security/apparmor/file.c +@@ -154,8 +154,12 @@ static int path_name(const char *op, const struct cred *subj_cred, + const char *info = NULL; + int error; + +- error = aa_path_name(path, flags, buffer, name, &info, +- labels_profile(label)->disconnected); ++ /* don't reaudit files closed during inheritance */ ++ if (unlikely(path->dentry == aa_null.dentry)) ++ error = -EACCES; ++ else ++ error = aa_path_name(path, flags, buffer, name, &info, ++ labels_profile(label)->disconnected); + if (error) { + fn_for_each_confined(label, profile, + aa_audit_file(subj_cred, +@@ -616,6 +620,10 @@ int aa_file_perm(const char *op, const struct cred *subj_cred, + AA_BUG(!label); + AA_BUG(!file); + ++ /* don't reaudit files closed during inheritance */ ++ if (unlikely(file->f_path.dentry == aa_null.dentry)) ++ return -EACCES; ++ + fctx = file_ctx(file); + + rcu_read_lock(); +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 5fc99fe8d38a4..be3678d08ed23 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -524,10 +524,6 @@ static int common_file_perm(const char *op, struct file *file, u32 mask) + struct aa_label *label; + int error = 0; + +- /* don't reaudit files closed during inheritance */ +- if (unlikely(file->f_path.dentry == aa_null.dentry)) +- return -EACCES; +- + label = begin_current_label_crit_section(); + error = aa_file_perm(op, current_cred(), label, file, mask, false); + end_current_label_crit_section(label); +-- +2.51.0 + diff --git a/queue-6.18/apparmor-remove-apply_modes_to_perms-from-label_matc.patch b/queue-6.18/apparmor-remove-apply_modes_to_perms-from-label_matc.patch new file mode 100644 index 0000000000..f3287baebc --- /dev/null +++ b/queue-6.18/apparmor-remove-apply_modes_to_perms-from-label_matc.patch @@ -0,0 +1,53 @@ +From ed9f1c4d636efa6eaa38a7b2ae2f39777467312a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 00:14:36 -0800 +Subject: apparmor: remove apply_modes_to_perms from label_match + +From: John Johansen + +[ Upstream commit b2e27be2948f2f8c38421cd554b5fc9383215648 ] + +The modes shouldn't be applied at the point of label match, it just +results in them being applied multiple times. Instead they should be +applied after which is already being done by all callers so it can +just be dropped from label_match. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value") +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 913678f199c35..02ee128f53d13 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1317,7 +1317,6 @@ static int label_compound_match(struct aa_profile *profile, + goto fail; + } + *perms = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, perms); + if ((perms->allow & request) != request) + return -EACCES; + +@@ -1370,7 +1369,6 @@ static int label_components_match(struct aa_profile *profile, + + next: + tmp = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + label_for_each_cont(i, label, tp) { + if (!aa_ns_visible(profile->ns, tp->ns, subns)) +@@ -1379,7 +1377,6 @@ static int label_components_match(struct aa_profile *profile, + if (!state) + goto fail; + tmp = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + } + +-- +2.51.0 + diff --git a/queue-6.18/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch b/queue-6.18/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch new file mode 100644 index 0000000000..fcbb27c47f --- /dev/null +++ b/queue-6.18/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch @@ -0,0 +1,44 @@ +From b16b1469afccd64d710e1b2b75d34ad0d3d9e3c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Jan 2026 09:35:57 -0800 +Subject: apparmor: return -ENOMEM in unpack_perms_table upon alloc failure + +From: Ryan Lee + +[ Upstream commit 74b7105e53e80a4072bd3e1a50be7aa15e3f0a01 ] + +In policy_unpack.c:unpack_perms_table, the perms struct is allocated via +kcalloc, with the position being reset if the allocation fails. However, +the error path results in -EPROTO being retured instead of -ENOMEM. Fix +this to return the correct error code. + +Reported-by: Zygmunt Krynicki +Fixes: fd1b2b95a2117 ("apparmor: add the ability for policy to specify a permission table") +Reviewed-by: Tyler Hicks +Signed-off-by: Ryan Lee +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/policy_unpack.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index 7523971e37d9c..dd602bd5fca99 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -687,8 +687,10 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms) + if (!aa_unpack_array(e, NULL, &size)) + goto fail_reset; + *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL); +- if (!*perms) +- goto fail_reset; ++ if (!*perms) { ++ e->pos = pos; ++ return -ENOMEM; ++ } + for (i = 0; i < size; i++) { + if (!unpack_perm(e, version, &(*perms)[i])) + goto fail; +-- +2.51.0 + diff --git a/queue-6.18/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch b/queue-6.18/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch new file mode 100644 index 0000000000..016b11127f --- /dev/null +++ b/queue-6.18/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch @@ -0,0 +1,49 @@ +From f254d058b5b26383e30693f57ee5dba2a6484043 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 11:27:32 +0100 +Subject: ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init + +From: Alexandre Ferrieux + +[ Upstream commit b82fa9b0c26eeb2fde6017f7de2c3c544484efef ] + +The aw88261_dev_reg_update() function sets the Awinic registers in a +rather nonuniform way: + - most registers get directly overwritten from the firmware blob + - but a handful of them need more delicate logic to preserve + some bits from their current value, according to a register- + specific mask +For the latter, the logic is basically + NEW = (OLD & MASK) | (VAL & ~MASK) +However, the ~MASK value is hand-computed, and in the specific case +of the SYSCTRL register, in a buggy way. +This patch restores the proper ~MASK value. + +Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver") +Signed-off-by: Alexandre Ferrieux +Link: https://patch.msgid.link/20260211-aw88261-fwname-v1-1-e24e833a019d@fairphone.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/aw88261.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c +index de11ae8dd9d9f..124c0a58d08bd 100644 +--- a/sound/soc/codecs/aw88261.c ++++ b/sound/soc/codecs/aw88261.c +@@ -423,9 +423,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261, + if (ret) + break; + ++ /* keep all three bits from current hw status */ + read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) | + (~AW88261_HMUTE_MASK); +- reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK); ++ reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK); + reg_val |= read_val; + + /* enable uls hmute */ +-- +2.51.0 + diff --git a/queue-6.18/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch b/queue-6.18/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch new file mode 100644 index 0000000000..810f026d4a --- /dev/null +++ b/queue-6.18/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch @@ -0,0 +1,52 @@ +From cb05e8172a788cbde295e6db7b66615c1704d8d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 18:57:14 +0000 +Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put() + +From: Ziyi Guo + +[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ] + +This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()"). + +The original patch attempted to acquire the card->controls_rwsem lock in +fsl_xcvr_mode_put(). However, this function is called from the upper ALSA +core function snd_ctl_elem_write(), which already holds the write lock on +controls_rwsem for the whole put operation. So there is no need to simply +hold the lock for fsl_xcvr_activate_ctl() again. + +Acquiring the read lock while holding the write lock in the same thread +results in a deadlock and a hung task, as reported by Alexander Stein. + +Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()") +Reported-by: Alexander Stein +Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/ +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 51669e5fe8888..58db4906a01d5 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -223,13 +223,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, + + xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); + +- down_read(&card->snd_card->controls_rwsem); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_ARC)); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_EARC)); +- up_read(&card->snd_card->controls_rwsem); +- + /* Allow playback for SPDIF only */ + rtd = snd_soc_get_pcm_runtime(card, card->dai_link); + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = +-- +2.51.0 + diff --git a/queue-6.18/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch b/queue-6.18/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch new file mode 100644 index 0000000000..070c81fa60 --- /dev/null +++ b/queue-6.18/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch @@ -0,0 +1,55 @@ +From 4ee1d79222c9696a8af0f94abe85db94e905be2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 15:18:34 -0500 +Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk + +From: Detlev Casanova + +[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ] + +Drivers will not always call set_sysclk() for all clocks, especially when +default mclk-fs can be used. +When that is the case, use the clock rate set in the params multiplied by the +default mclk-fs. + +Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback") +Signed-off-by: Detlev Casanova +Reported-by: Luca Ceresoli +Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c +index d9a1fab7f4031..e4697ee0addc8 100644 +--- a/sound/soc/rockchip/rockchip_i2s_tdm.c ++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c +@@ -22,6 +22,7 @@ + + #define DRV_NAME "rockchip-i2s-tdm" + ++#define DEFAULT_MCLK_FS 256 + #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ + #define MULTIPLEX_CH_MAX 10 + +@@ -665,6 +666,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, + mclk_rate = i2s_tdm->mclk_rx_freq; + } + ++ /* ++ * When the dai/component driver doesn't need to set mclk-fs for a specific ++ * clock, it can skip the call to set_sysclk() for that clock. ++ * In that case, simply use the clock rate from the params and multiply it by ++ * the default mclk-fs value. ++ */ ++ if (!mclk_rate) ++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params); ++ + err = clk_set_rate(mclk, mclk_rate); + if (err) + return err; +-- +2.51.0 + diff --git a/queue-6.18/bnge-fix-reserving-resources-from-fw.patch b/queue-6.18/bnge-fix-reserving-resources-from-fw.patch new file mode 100644 index 0000000000..b496ef9b86 --- /dev/null +++ b/queue-6.18/bnge-fix-reserving-resources-from-fw.patch @@ -0,0 +1,41 @@ +From 9af36c5903f6075496fadfeac7bbd8a0077bee88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 10:57:55 +0530 +Subject: bnge: fix reserving resources from FW + +From: Vikas Gupta + +[ Upstream commit 604530085b2ef484843c723a105b6fd3218b4710 ] + +HWRM_FUNC_CFG is used to reserve resources, whereas HWRM_FUNC_QCFG is +intended for querying resource information from the firmware. +Since __bnge_hwrm_reserve_pf_rings() reserves resources for a specific +PF, the command type should be HWRM_FUNC_CFG. + +Fixes: 627c67f038d2 ("bng_en: Add resource management support") +Signed-off-by: Vikas Gupta +Reviewed-by: Bhargava Chenna Marreddy +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260218052755.4097468-1-vikas.gupta@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +index 198f49b40dbf0..2994f10446a63 100644 +--- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c ++++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +@@ -442,7 +442,7 @@ __bnge_hwrm_reserve_pf_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr) + struct hwrm_func_cfg_input *req; + u32 enables = 0; + +- if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCFG)) ++ if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_CFG)) + return NULL; + + req->fid = cpu_to_le16(0xffff); +-- +2.51.0 + diff --git a/queue-6.18/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch b/queue-6.18/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch new file mode 100644 index 0000000000..5816bbc3ff --- /dev/null +++ b/queue-6.18/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch @@ -0,0 +1,108 @@ +From 13e72c57b9ae043426daa0a565601ef99ab42b8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 06:09:19 +0000 +Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down + +From: Hangbin Liu + +[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ] + +The ALB RX path may access rx_hashtbl concurrently with bond +teardown. During rapid bond up/down cycles, rlb_deinitialize() +frees rx_hashtbl while RX handlers are still running, leading +to a null pointer dereference detected by KASAN. + +However, the root cause is that rlb_arp_recv() can still be accessed +after setting recv_probe to NULL, which is actually a use-after-free +(UAF) issue. That is the reason for using the referenced commit in the +Fixes tag. + +[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI +[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef] +[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary) +[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022 +[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding] +[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6 + 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00 +[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206 +[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e +[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8 +[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8 +[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119 +[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810 +[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000 +[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0 +[ 214.310347] Call Trace: +[ 214.313070] +[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding] +[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding] +[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding] +[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710 +[ 214.339199] ? __pfx_arp_process+0x10/0x10 +[ 214.343775] ? sched_balance_find_src_group+0x98/0x630 +[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10 +[ 214.356513] ? arp_rcv+0x307/0x690 +[ 214.360311] ? __pfx_arp_rcv+0x10/0x10 +[ 214.364499] ? __lock_acquire+0x58c/0xbd0 +[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0 +[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10 +[ 214.380743] ? lock_acquire+0x10b/0x140 +[ 214.385026] process_backlog+0x3f1/0x13a0 +[ 214.389502] ? process_backlog+0x3aa/0x13a0 +[ 214.394174] __napi_poll.constprop.0+0x9f/0x370 +[ 214.399233] net_rx_action+0x8c1/0xe60 +[ 214.403423] ? __pfx_net_rx_action+0x10/0x10 +[ 214.408193] ? lock_acquire.part.0+0xbd/0x260 +[ 214.413058] ? sched_clock_cpu+0x6c/0x540 +[ 214.417540] ? mark_held_locks+0x40/0x70 +[ 214.421920] handle_softirqs+0x1fd/0x860 +[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10 +[ 214.431264] ? __neigh_event_send+0x2d6/0xf50 +[ 214.436131] do_softirq+0xb1/0xf0 +[ 214.439830] + +The issue is reproducible by repeatedly running +ip link set bond0 up/down while receiving ARP messages, where +rlb_arp_recv() can race with rlb_deinitialize() and dereference +a freed rx_hashtbl entry. + +Fix this by setting recv_probe to NULL and then calling +synchronize_net() to wait for any concurrent RX processing to finish. +This ensures that no RX handler can access rx_hashtbl after it is freed +in bond_alb_deinitialize(). + +Reported-by: Liang Li +Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()") +Reviewed-by: Nikolay Aleksandrov +Acked-by: Jay Vosburgh +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 166dff47a029f..dba8f68690947 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4405,9 +4405,13 @@ static int bond_close(struct net_device *bond_dev) + + bond_work_cancel_all(bond); + bond->send_peer_notif = 0; ++ WRITE_ONCE(bond->recv_probe, NULL); ++ ++ /* Wait for any in-flight RX handlers */ ++ synchronize_net(); ++ + if (bond_is_lb(bond)) + bond_alb_deinitialize(bond); +- bond->recv_probe = NULL; + + if (BOND_MODE(bond) == BOND_MODE_8023AD && + bond->params.broadcast_neighbor) +-- +2.51.0 + diff --git a/queue-6.18/bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch b/queue-6.18/bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch new file mode 100644 index 0000000000..6342904917 --- /dev/null +++ b/queue-6.18/bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch @@ -0,0 +1,51 @@ +From b3866b06ee71c5a977553cbeccbb6559c569feac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 21:29:49 +0000 +Subject: bpf: Add a map/btf from a fd array more consistently + +From: Anton Protopopov + +[ Upstream commit b0b1a8583d8e797114e613139e3e3318a1704690 ] + +The add_fd_from_fd_array() function takes a file descriptor as a +parameter and tries to add either map or btf to the corresponding +list of used objects. As was reported by Dan Carpenter, since the +commit c81e4322acf0 ("bpf: Fix a potential use-after-free of BTF +object"), the fdget() is called twice on the file descriptor, and +thus userspace, potentially, can replace the file pointed to by the +file descriptor in between the two calls. On practice, this shouldn't +break anything on the kernel side, but for consistency fix the code +such that only one fdget() is executed. + +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/aY689z7gHNv8rgVO@stanley.mountain/ +Fixes: ccd2d799ed44 ("bpf: Fix a potential use-after-free of BTF object") +Signed-off-by: Anton Protopopov +Link: https://lore.kernel.org/r/20260213212949.759321-1-a.s.protopopov@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index dade674ffe071..c4fa2268dbbc5 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -24098,9 +24098,11 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd) + return 0; + } + +- btf = btf_get_by_fd(fd); +- if (!IS_ERR(btf)) ++ btf = __btf_get_by_fd(f); ++ if (!IS_ERR(btf)) { ++ btf_get(btf); + return __add_used_btf(env, btf); ++ } + + verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd); + return PTR_ERR(map); +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-a-potential-use-after-free-of-btf-object.patch b/queue-6.18/bpf-fix-a-potential-use-after-free-of-btf-object.patch new file mode 100644 index 0000000000..b5f74af1dc --- /dev/null +++ b/queue-6.18/bpf-fix-a-potential-use-after-free-of-btf-object.patch @@ -0,0 +1,145 @@ +From d0c77135f8ab1167897cdaca3131cfb0c04d35a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 13:29:04 +0000 +Subject: bpf: Fix a potential use-after-free of BTF object + +From: Anton Protopopov + +[ Upstream commit ccd2d799ed4467c07f5ee18c2f5c59bcc990822c ] + +Refcounting in the check_pseudo_btf_id() function is incorrect: +the __check_pseudo_btf_id() function might get called with a zero +refcounted btf. Fix this, and patch related code accordingly. + +v3: rephrase a comment (AI) +v2: fix a refcount leak introduced in v1 (AI) + +Reported-by: syzbot+5a0f1995634f7c1dadbf@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=5a0f1995634f7c1dadbf +Fixes: 76145f725532 ("bpf: Refactor check_pseudo_btf_id") +Signed-off-by: Anton Protopopov +Link: https://lore.kernel.org/r/20260209132904.63908-1-a.s.protopopov@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 52 +++++++++++++++++++++---------------------- + 1 file changed, 26 insertions(+), 26 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 4338d233beecf..dade674ffe071 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -20219,29 +20219,29 @@ static int find_btf_percpu_datasec(struct btf *btf) + } + + /* +- * Add btf to the used_btfs array and return the index. (If the btf was +- * already added, then just return the index.) Upon successful insertion +- * increase btf refcnt, and, if present, also refcount the corresponding +- * kernel module. ++ * Add btf to the env->used_btfs array. If needed, refcount the ++ * corresponding kernel module. To simplify caller's logic ++ * in case of error or if btf was added before the function ++ * decreases the btf refcount. + */ + static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf) + { + struct btf_mod_pair *btf_mod; ++ int ret = 0; + int i; + + /* check whether we recorded this BTF (and maybe module) already */ + for (i = 0; i < env->used_btf_cnt; i++) + if (env->used_btfs[i].btf == btf) +- return i; ++ goto ret_put; + + if (env->used_btf_cnt >= MAX_USED_BTFS) { + verbose(env, "The total number of btfs per program has reached the limit of %u\n", + MAX_USED_BTFS); +- return -E2BIG; ++ ret = -E2BIG; ++ goto ret_put; + } + +- btf_get(btf); +- + btf_mod = &env->used_btfs[env->used_btf_cnt]; + btf_mod->btf = btf; + btf_mod->module = NULL; +@@ -20250,12 +20250,18 @@ static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf) + if (btf_is_module(btf)) { + btf_mod->module = btf_try_get_module(btf); + if (!btf_mod->module) { +- btf_put(btf); +- return -ENXIO; ++ ret = -ENXIO; ++ goto ret_put; + } + } + +- return env->used_btf_cnt++; ++ env->used_btf_cnt++; ++ return 0; ++ ++ret_put: ++ /* Either error or this BTF was already added */ ++ btf_put(btf); ++ return ret; + } + + /* replace pseudo btf_id with kernel symbol address */ +@@ -20352,9 +20358,7 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env, + + btf_fd = insn[1].imm; + if (btf_fd) { +- CLASS(fd, f)(btf_fd); +- +- btf = __btf_get_by_fd(f); ++ btf = btf_get_by_fd(btf_fd); + if (IS_ERR(btf)) { + verbose(env, "invalid module BTF object FD specified.\n"); + return -EINVAL; +@@ -20364,17 +20368,17 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env, + verbose(env, "kernel is missing BTF, make sure CONFIG_DEBUG_INFO_BTF=y is specified in Kconfig.\n"); + return -EINVAL; + } ++ btf_get(btf_vmlinux); + btf = btf_vmlinux; + } + + err = __check_pseudo_btf_id(env, insn, aux, btf); +- if (err) ++ if (err) { ++ btf_put(btf); + return err; ++ } + +- err = __add_used_btf(env, btf); +- if (err < 0) +- return err; +- return 0; ++ return __add_used_btf(env, btf); + } + + static bool is_tracing_prog_type(enum bpf_prog_type type) +@@ -24094,13 +24098,9 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd) + return 0; + } + +- btf = __btf_get_by_fd(f); +- if (!IS_ERR(btf)) { +- err = __add_used_btf(env, btf); +- if (err < 0) +- return err; +- return 0; +- } ++ btf = btf_get_by_fd(fd); ++ if (!IS_ERR(btf)) ++ return __add_used_btf(env, btf); + + verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd); + return PTR_ERR(map); +-- +2.51.0 + diff --git a/queue-6.18/bpftool-fix-truncated-netlink-dumps.patch b/queue-6.18/bpftool-fix-truncated-netlink-dumps.patch new file mode 100644 index 0000000000..b1a83ec543 --- /dev/null +++ b/queue-6.18/bpftool-fix-truncated-netlink-dumps.patch @@ -0,0 +1,73 @@ +From 278f42068573532ff42bf144a7a4bc43e14df680 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 11:41:50 -0800 +Subject: bpftool: Fix truncated netlink dumps + +From: Jakub Kicinski + +[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ] + +Netlink requires that the recv buffer used during dumps is at least +min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will +get truncated. Make sure bpftool follows this requirement, avoid +missing information on systems with large pages. + +Acked-by: Quentin Monnet +Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool") +Signed-off-by: Jakub Kicinski +Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/net.c | 5 ++++- + tools/lib/bpf/netlink.c | 4 +++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c +index cfc6f944f7c33..1a06b0b5eef35 100644 +--- a/tools/bpf/bpftool/net.c ++++ b/tools/bpf/bpftool/net.c +@@ -156,7 +156,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + bool multipart = true; + struct nlmsgerr *err; + struct nlmsghdr *nh; +- char buf[4096]; ++ char buf[8192]; + int len, ret; + + while (multipart) { +@@ -201,6 +201,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + return ret; + } + } ++ ++ if (len) ++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len); + } + ret = 0; + done: +diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c +index c997e69d507fe..c9a78fb16f115 100644 +--- a/tools/lib/bpf/netlink.c ++++ b/tools/lib/bpf/netlink.c +@@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + struct nlmsghdr *nh; + int len, ret; + +- ret = alloc_iov(&iov, 4096); ++ ret = alloc_iov(&iov, 8192); + if (ret) + goto done; + +@@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + } + } + } ++ if (len) ++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len); + } + ret = 0; + done: +-- +2.51.0 + diff --git a/queue-6.18/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch b/queue-6.18/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch new file mode 100644 index 0000000000..ca99d3619d --- /dev/null +++ b/queue-6.18/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch @@ -0,0 +1,52 @@ +From cfcb0e598ad8a283cef8cac60b5a5f2b2608b859 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 17:15:53 +0000 +Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not + found + +From: Filipe Manana + +[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ] + +If btrfs_search_slot_for_read() returns 1, it means we did not find any +key greater than or equals to the key we asked for, meaning we have +reached the end of the tree and therefore the path is not valid. If +this happens we need to break out of the loop and stop, instead of +continuing and accessing an invalid path. + +Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/qgroup.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index 7a1dd250e92c0..302bb3ecf39a3 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1157,11 +1157,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info, + } + if (ret > 0) { + /* +- * Shouldn't happen, but in case it does we +- * don't need to do the btrfs_next_item, just +- * continue. ++ * Shouldn't happen because the key should still ++ * be there (return 0), but in case it does it ++ * means we have reached the end of the tree - ++ * there are no more leaves with items that have ++ * a key greater than or equals to @found_key, ++ * so just stop the search loop. + */ +- continue; ++ break; + } + } + ret = btrfs_next_item(tree_root, path); +-- +2.51.0 + diff --git a/queue-6.18/btrfs-reduce-block-group-critical-section-in-btrfs_f.patch b/queue-6.18/btrfs-reduce-block-group-critical-section-in-btrfs_f.patch new file mode 100644 index 0000000000..466f36aac6 --- /dev/null +++ b/queue-6.18/btrfs-reduce-block-group-critical-section-in-btrfs_f.patch @@ -0,0 +1,65 @@ +From 9bab32c05aec361994be65021f40fbd57b907e65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 12:47:26 +0100 +Subject: btrfs: reduce block group critical section in + btrfs_free_reserved_bytes() + +From: Filipe Manana + +[ Upstream commit 8b6fa164ab59f9e3f24e627fe09a0234783e7a8b ] + +There's no need to update the space_info fields (bytes_reserved, +max_extent_size, bytes_readonly, bytes_zone_unusable) while holding the +block group's spinlock. So move those updates to happen after we unlock +the block group (and while holding the space_info locked of course), so +that all we do under the block group's critical section is to update the +block group itself. + +Reviewed-by: Johannes Thumshirn +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: 5870ec7c8fe5 ("btrfs: reset block group size class when it becomes empty") +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 035b04e7658d1..144868f02e2aa 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -3859,21 +3859,24 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes, + bool is_delalloc) + { + struct btrfs_space_info *space_info = cache->space_info; ++ bool bg_ro; + + spin_lock(&space_info->lock); + spin_lock(&cache->lock); +- if (cache->ro) ++ bg_ro = cache->ro; ++ cache->reserved -= num_bytes; ++ if (is_delalloc) ++ cache->delalloc_bytes -= num_bytes; ++ spin_unlock(&cache->lock); ++ ++ if (bg_ro) + space_info->bytes_readonly += num_bytes; + else if (btrfs_is_zoned(cache->fs_info)) + space_info->bytes_zone_unusable += num_bytes; +- cache->reserved -= num_bytes; ++ + space_info->bytes_reserved -= num_bytes; + space_info->max_extent_size = 0; + +- if (is_delalloc) +- cache->delalloc_bytes -= num_bytes; +- spin_unlock(&cache->lock); +- + btrfs_try_granting_tickets(space_info); + spin_unlock(&space_info->lock); + } +-- +2.51.0 + diff --git a/queue-6.18/btrfs-remove-fs_info-argument-from-btrfs_try_grantin.patch b/queue-6.18/btrfs-remove-fs_info-argument-from-btrfs_try_grantin.patch new file mode 100644 index 0000000000..98c295012c --- /dev/null +++ b/queue-6.18/btrfs-remove-fs_info-argument-from-btrfs_try_grantin.patch @@ -0,0 +1,147 @@ +From efa8f81ee52a4da3dd3b11063fc8ebb73b69c0e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 13:57:09 +0100 +Subject: btrfs: remove fs_info argument from btrfs_try_granting_tickets() + +From: Filipe Manana + +[ Upstream commit e3df6408b13a75cf73e543e53453f28261874c6f ] + +We don't need it since we can grab fs_info from the given space_info. +So remove the fs_info argument. + +Reviewed-by: Qu Wenruo +Reviewed-by: Johannes Thumshirn +Reviewed-by: Anand Jain +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: 5870ec7c8fe5 ("btrfs: reset block group size class when it becomes empty") +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 4 ++-- + fs/btrfs/block-rsv.c | 2 +- + fs/btrfs/space-info.c | 14 +++++++------- + fs/btrfs/space-info.h | 5 ++--- + 4 files changed, 12 insertions(+), 13 deletions(-) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 8bf501fbcc0be..035b04e7658d1 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -3836,7 +3836,7 @@ int btrfs_add_reserved_bytes(struct btrfs_block_group *cache, + * that happens. + */ + if (num_bytes < ram_bytes) +- btrfs_try_granting_tickets(cache->fs_info, space_info); ++ btrfs_try_granting_tickets(space_info); + out: + spin_unlock(&cache->lock); + spin_unlock(&space_info->lock); +@@ -3874,7 +3874,7 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes, + cache->delalloc_bytes -= num_bytes; + spin_unlock(&cache->lock); + +- btrfs_try_granting_tickets(cache->fs_info, space_info); ++ btrfs_try_granting_tickets(space_info); + spin_unlock(&space_info->lock); + } + +diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c +index 5ad6de738aee0..75cd35570a287 100644 +--- a/fs/btrfs/block-rsv.c ++++ b/fs/btrfs/block-rsv.c +@@ -387,7 +387,7 @@ void btrfs_update_global_block_rsv(struct btrfs_fs_info *fs_info) + num_bytes = block_rsv->reserved - block_rsv->size; + btrfs_space_info_update_bytes_may_use(sinfo, -num_bytes); + block_rsv->reserved = block_rsv->size; +- btrfs_try_granting_tickets(fs_info, sinfo); ++ btrfs_try_granting_tickets(sinfo); + } + + block_rsv->full = (block_rsv->reserved == block_rsv->size); +diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c +index e5c18a29eb7e6..474ed47095ba7 100644 +--- a/fs/btrfs/space-info.c ++++ b/fs/btrfs/space-info.c +@@ -378,7 +378,7 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info, + btrfs_space_info_update_bytes_zone_unusable(space_info, block_group->zone_unusable); + if (block_group->length > 0) + space_info->full = false; +- btrfs_try_granting_tickets(info, space_info); ++ btrfs_try_granting_tickets(space_info); + spin_unlock(&space_info->lock); + + block_group->space_info = space_info; +@@ -528,9 +528,9 @@ static void remove_ticket(struct btrfs_space_info *space_info, + * This is for space we already have accounted in space_info->bytes_may_use, so + * basically when we're returning space from block_rsv's. + */ +-void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info, +- struct btrfs_space_info *space_info) ++void btrfs_try_granting_tickets(struct btrfs_space_info *space_info) + { ++ struct btrfs_fs_info *fs_info = space_info->fs_info; + struct list_head *head; + enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_NO_FLUSH; + +@@ -1129,7 +1129,7 @@ static bool maybe_fail_all_tickets(struct btrfs_fs_info *fs_info, + * the list. + */ + if (!aborted) +- btrfs_try_granting_tickets(fs_info, space_info); ++ btrfs_try_granting_tickets(space_info); + } + return (tickets_id != space_info->tickets_id); + } +@@ -1549,7 +1549,7 @@ static void priority_reclaim_metadata_space(struct btrfs_fs_info *fs_info, + * ticket in front of a smaller ticket that can now be satisfied with + * the available space. + */ +- btrfs_try_granting_tickets(fs_info, space_info); ++ btrfs_try_granting_tickets(space_info); + spin_unlock(&space_info->lock); + } + +@@ -1577,7 +1577,7 @@ static void priority_reclaim_data_space(struct btrfs_fs_info *fs_info, + + ticket->error = -ENOSPC; + remove_ticket(space_info, ticket); +- btrfs_try_granting_tickets(fs_info, space_info); ++ btrfs_try_granting_tickets(space_info); + spin_unlock(&space_info->lock); + } + +@@ -2200,5 +2200,5 @@ void btrfs_return_free_space(struct btrfs_space_info *space_info, u64 len) + grant: + /* Add to any tickets we may have. */ + if (len) +- btrfs_try_granting_tickets(fs_info, space_info); ++ btrfs_try_granting_tickets(space_info); + } +diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h +index a846f63585c95..596a1e923ddfe 100644 +--- a/fs/btrfs/space-info.h ++++ b/fs/btrfs/space-info.h +@@ -283,8 +283,7 @@ int btrfs_reserve_metadata_bytes(struct btrfs_fs_info *fs_info, + struct btrfs_space_info *space_info, + u64 orig_bytes, + enum btrfs_reserve_flush_enum flush); +-void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info, +- struct btrfs_space_info *space_info); ++void btrfs_try_granting_tickets(struct btrfs_space_info *space_info); + int btrfs_can_overcommit(struct btrfs_fs_info *fs_info, + const struct btrfs_space_info *space_info, u64 bytes, + enum btrfs_reserve_flush_enum flush); +@@ -295,7 +294,7 @@ static inline void btrfs_space_info_free_bytes_may_use( + { + spin_lock(&space_info->lock); + btrfs_space_info_update_bytes_may_use(space_info, -num_bytes); +- btrfs_try_granting_tickets(space_info->fs_info, space_info); ++ btrfs_try_granting_tickets(space_info); + spin_unlock(&space_info->lock); + } + int btrfs_reserve_data_bytes(struct btrfs_space_info *space_info, u64 bytes, +-- +2.51.0 + diff --git a/queue-6.18/btrfs-reset-block-group-size-class-when-it-becomes-e.patch b/queue-6.18/btrfs-reset-block-group-size-class-when-it-becomes-e.patch new file mode 100644 index 0000000000..d4c2f15327 --- /dev/null +++ b/queue-6.18/btrfs-reset-block-group-size-class-when-it-becomes-e.patch @@ -0,0 +1,81 @@ +From b1cb48fca8c9e3dd219aaabb9dd1abe23ca493b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Jan 2026 01:13:38 +0000 +Subject: btrfs: reset block group size class when it becomes empty + +From: Jiasheng Jiang + +[ Upstream commit 5870ec7c8fe57a8b2c65005e5da5efc054faa3e6 ] + +Block group size classes are managed consistently everywhere. +Currently, btrfs_use_block_group_size_class() sets a block group's size +class to specialize it for a specific allocation size. However, this +size class remains "stale" even if the block group becomes completely +empty (both used and reserved bytes reach zero). + +This happens in two scenarios: + +1. When space reservations are freed (e.g., due to errors or transaction + aborts) via btrfs_free_reserved_bytes(). +2. When the last extent in a block group is freed via + btrfs_update_block_group(). + +While size classes are advisory, a stale size class can cause +find_free_extent to unnecessarily skip candidate block groups during +initial search loops. This undermines the purpose of size classes to +reduce fragmentation by keeping block groups restricted to a specific +size class when they could be reused for any size. + +Fix this by resetting the size class to BTRFS_BG_SZ_NONE whenever a +block group's used and reserved counts both reach zero. This ensures +that empty block groups are fully available for any allocation size in +the next cycle. + +Fixes: 52bb7a2166af ("btrfs: introduce size class to block group allocator") +Reviewed-by: Boris Burkov +Signed-off-by: Jiasheng Jiang +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 144868f02e2aa..f7f6d8cb33114 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -3681,6 +3681,14 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans) + return ret; + } + ++static void btrfs_maybe_reset_size_class(struct btrfs_block_group *bg) ++{ ++ lockdep_assert_held(&bg->lock); ++ if (btrfs_block_group_should_use_size_class(bg) && ++ bg->used == 0 && bg->reserved == 0) ++ bg->size_class = BTRFS_BG_SZ_NONE; ++} ++ + int btrfs_update_block_group(struct btrfs_trans_handle *trans, + u64 bytenr, u64 num_bytes, bool alloc) + { +@@ -3745,6 +3753,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans, + old_val -= num_bytes; + cache->used = old_val; + cache->pinned += num_bytes; ++ btrfs_maybe_reset_size_class(cache); + btrfs_space_info_update_bytes_pinned(space_info, num_bytes); + space_info->bytes_used -= num_bytes; + space_info->disk_used -= num_bytes * factor; +@@ -3865,6 +3874,7 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes, + spin_lock(&cache->lock); + bg_ro = cache->ro; + cache->reserved -= num_bytes; ++ btrfs_maybe_reset_size_class(cache); + if (is_delalloc) + cache->delalloc_bytes -= num_bytes; + spin_unlock(&cache->lock); +-- +2.51.0 + diff --git a/queue-6.18/btrfs-use-the-correct-type-to-initialize-block-reser.patch b/queue-6.18/btrfs-use-the-correct-type-to-initialize-block-reser.patch new file mode 100644 index 0000000000..c961d0dd8d --- /dev/null +++ b/queue-6.18/btrfs-use-the-correct-type-to-initialize-block-reser.patch @@ -0,0 +1,82 @@ +From 8303c29de59b2085b4ed7ce6ca15b27d75fc5a54 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 18:03:35 +0000 +Subject: btrfs: use the correct type to initialize block reserve for delayed + refs + +From: Filipe Manana + +[ Upstream commit 2155d0c0a761a56ce7ede83a26eb23ea0f935260 ] + +When initializing the delayed refs block reserve for a transaction handle +we are passing a type of BTRFS_BLOCK_RSV_DELOPS, which is meant for +delayed items and not for delayed refs. The correct type for delayed refs +is BTRFS_BLOCK_RSV_DELREFS. + +On release of any excess space reserved in a local delayed refs reserve, +we also should transfer that excess space to the global block reserve +(it it's full, we return to the space info for general availability). + +By initializing a transaction's local delayed refs block reserve with a +type of BTRFS_BLOCK_RSV_DELOPS, we were also causing any excess space +released from the delayed block reserve (fs_info->delayed_block_rsv, used +for delayed inodes and items) to be transferred to the global block +reserve instead of the global delayed refs block reserve. This was an +unintentional change in commit 28270e25c69a ("btrfs: always reserve space +for delayed refs when starting transaction"), but it's not particularly +serious as things tend to cancel out each other most of the time and it's +relatively rare to be anywhere near exhaustion of the global reserve. + +Fix this by initializing a transaction's local delayed refs reserve with +a type of BTRFS_BLOCK_RSV_DELREFS and making btrfs_block_rsv_release() +attempt to transfer unused space from such a reserve into the global block +reserve, just as we did before that commit for when the block reserve is +a delayed refs rsv. + +Reported-by: Alex Lyakas +Link: https://lore.kernel.org/linux-btrfs/CAOcd+r0FHG5LWzTSu=LknwSoqxfw+C00gFAW7fuX71+Z5AfEew@mail.gmail.com/ +Fixes: 28270e25c69a ("btrfs: always reserve space for delayed refs when starting transaction") +Reviewed-by: Alex Lyakas +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-rsv.c | 7 ++++--- + fs/btrfs/transaction.c | 2 +- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c +index 75cd35570a287..fc378d2038a2d 100644 +--- a/fs/btrfs/block-rsv.c ++++ b/fs/btrfs/block-rsv.c +@@ -278,10 +278,11 @@ u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info, + struct btrfs_block_rsv *target = NULL; + + /* +- * If we are a delayed block reserve then push to the global rsv, +- * otherwise dump into the global delayed reserve if it is not full. ++ * If we are a delayed refs block reserve then push to the global ++ * reserve, otherwise dump into the global delayed refs reserve if it is ++ * not full. + */ +- if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS) ++ if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS) + target = global_rsv; + else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv)) + target = delayed_rsv; +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index b537bba767806..089712b15d603 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -726,7 +726,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, + + h->type = type; + INIT_LIST_HEAD(&h->new_bgs); +- btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS); ++ btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS); + + smp_mb(); + if (cur_trans->state >= TRANS_STATE_COMMIT_START && +-- +2.51.0 + diff --git a/queue-6.18/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch b/queue-6.18/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch new file mode 100644 index 0000000000..e13ca97c62 --- /dev/null +++ b/queue-6.18/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch @@ -0,0 +1,59 @@ +From 98342d22f83c1f37205de6d558a2b7d63909554f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 00:20:02 +0530 +Subject: cpuidle: Skip governor when only one idle state is available + +From: Aboorva Devarajan + +[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ] + +On certain platforms (PowerNV systems without a power-mgt DT node), +cpuidle may register only a single idle state. In cases where that +single state is a polling state (state 0), the ladder governor may +incorrectly treat state 1 as the first usable state and pass an +out-of-bounds index. This can lead to a NULL enter callback being +invoked, ultimately resulting in a system crash. + +[ 13.342636] cpuidle-powernv : Only Snooze is available +[ 13.351854] Faulting instruction address: 0x00000000 +[ 13.376489] NIP [0000000000000000] 0x0 +[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668 + +Fix this by adding a bail-out in cpuidle_select() that returns state 0 +directly when state_count <= 1, bypassing the governor and keeping the +tick running. + +Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") +Signed-off-by: Aboorva Devarajan +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/cpuidle.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 56132e843c991..8950796a493de 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -357,6 +357,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev, + int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + bool *stop_tick) + { ++ /* ++ * If there is only a single idle state (or none), there is nothing ++ * meaningful for the governor to choose. Skip the governor and ++ * always use state 0 with the tick running. ++ */ ++ if (drv->state_count <= 1) { ++ *stop_tick = false; ++ return 0; ++ } ++ + return cpuidle_curr_governor->select(drv, dev, stop_tick); + } + +-- +2.51.0 + diff --git a/queue-6.18/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch b/queue-6.18/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch new file mode 100644 index 0000000000..e45c8a03a9 --- /dev/null +++ b/queue-6.18/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch @@ -0,0 +1,216 @@ +From e9bfb04037f4553b9f09cb85e58c865e4c9fef7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 20:49:23 +0530 +Subject: drm/amd/display: Fix out-of-bounds stream encoder index v3 + +From: Srinivasan Shanmugam + +[ Upstream commit abde491143e4e12eecc41337910aace4e8d59603 ] + +eng_id can be negative and that stream_enc_regs[] +can be indexed out of bounds. + +eng_id is used directly as an index into stream_enc_regs[], which has +only 5 entries. When eng_id is 5 (ENGINE_ID_DIGF) or negative, this can +access memory past the end of the array. + +Add a bounds check using ARRAY_SIZE() before using eng_id as an index. +The unsigned cast also rejects negative values. + +This avoids out-of-bounds access. + +Fixes the below smatch error: +dcn*_resource.c: stream_encoder_create() may index +stream_enc_regs[eng_id] out of bounds (size 5). + +drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c + 1246 static struct stream_encoder *dcn35_stream_encoder_create( + 1247 enum engine_id eng_id, + 1248 struct dc_context *ctx) + 1249 { + + ... + + 1255 + 1256 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ + 1257 if (eng_id <= ENGINE_ID_DIGF) { + +ENGINE_ID_DIGF is 5. should <= be dc_bios, + 1283 eng_id, vpg, afmt, +--> 1284 &stream_enc_regs[eng_id], + ^^^^^^^^^^^^^^^^^^^^^^^ This stream_enc_regs[] array has 5 elements so we are one element beyond the end of the array. + + ... + + 1287 return &enc1->base; + 1288 } + +v2: use explicit bounds check as suggested by Roman/Dan; avoid unsigned int cast + +v3: The compiler already knows how to compare the two values, so the + cast (int) is not needed. (Roman) + +Fixes: 2728e9c7c842 ("drm/amd/display: add DC changes for DCN351") +Reported-by: Dan Carpenter +Cc: Harry Wentland +Cc: Mario Limonciello +Cc: Alex Hung +Cc: Aurabindo Pillai +Cc: ChiaHsuan Chung +Cc: Roman Li +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Roman Li +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn316/dcn316_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn321/dcn321_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 8 ++++---- + 6 files changed, 24 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +index 82cc78c291d82..12c2a0d9fb2a3 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +@@ -1226,12 +1226,12 @@ static struct stream_encoder *dcn315_stream_encoder_create( + /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/ + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +index 636110e48d01b..3c77c14c5a5ed 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +@@ -1220,12 +1220,12 @@ static struct stream_encoder *dcn316_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +index 3965a7f1b64b7..9cace432ce364 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +@@ -1208,12 +1208,12 @@ static struct stream_encoder *dcn32_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn32_vpg_create(ctx, vpg_inst); + afmt = dcn32_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +index ad214986f7ac7..26fd5c03c0147 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +@@ -1189,12 +1189,12 @@ static struct stream_encoder *dcn321_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn321_vpg_create(ctx, vpg_inst); + afmt = dcn321_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +index 06bec7dcc7556..e8d74ceb9dc29 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +@@ -1271,12 +1271,12 @@ static struct stream_encoder *dcn35_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +index 7974e306126e0..532e5d9bc4337 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +@@ -1251,12 +1251,12 @@ static struct stream_encoder *dcn35_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +-- +2.51.0 + diff --git a/queue-6.18/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch b/queue-6.18/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch new file mode 100644 index 0000000000..ce2f2cdf39 --- /dev/null +++ b/queue-6.18/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch @@ -0,0 +1,69 @@ +From cadd35ee3a8f39ab21997e5fa69dffa821709d0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 18 Jan 2026 15:57:41 +0100 +Subject: drm/amd/display: Reject cursor plane on DCE when scaled differently + than primary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit 41af6215cdbcecd12920f211239479027904abf3 ] + +Currently DCE doesn't support the overlay cursor, so the +dm_crtc_get_cursor_mode() function returns DM_CURSOR_NATIVE_MODE +unconditionally. The outcome is that it doesn't check for the +conditions that would necessitate the overlay cursor, meaning +that it doesn't reject cases where the native cursor mode isn't +supported on DCE. + +Remove the early return from dm_crtc_get_cursor_mode() for +DCE and instead let it perform the necessary checks and +return DM_CURSOR_OVERLAY_MODE. Add a later check that rejects +when DM_CURSOR_OVERLAY_MODE would be used with DCE. + +Fixes: 1b04dcca4fb1 ("drm/amd/display: Introduce overlay cursor mode") +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4600 +Suggested-by: Leo Li +Signed-off-by: Timur Kristóf +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 6252afd1d087f..ccf13bb5281bf 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -12027,10 +12027,9 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, + + /* Overlay cursor not supported on HW before DCN + * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions +- * as previous DCN generations, so enable native mode on DCN401 in addition to DCE ++ * as previous DCN generations, so enable native mode on DCN401 + */ +- if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 || +- amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { ++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { + *cursor_mode = DM_CURSOR_NATIVE_MODE; + return 0; + } +@@ -12350,6 +12349,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, + * need to be added for DC to not disable a plane by mistake + */ + if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) { ++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) { ++ drm_dbg(dev, "Overlay cursor not supported on DCE\n"); ++ ret = -EINVAL; ++ goto fail; ++ } ++ + ret = drm_atomic_add_affected_planes(state, crtc); + if (ret) + goto fail; +-- +2.51.0 + diff --git a/queue-6.18/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch b/queue-6.18/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch new file mode 100644 index 0000000000..38bb24c507 --- /dev/null +++ b/queue-6.18/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch @@ -0,0 +1,78 @@ +From 533b1f467c143dc4a77774946b9cdfcde84fa94f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 23:38:28 +0100 +Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp + formats + +From: Mario Kleiner + +[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ] + +The plane scaling hw seems to have the same min/max plane scaling limits +for all 16 bpc / 64 bpp interleaved pixel color formats. + +Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for +all the 16 bpc fixed-point / unorm formats to use the same .fp16 +up/downscaling factor limits as used by the fp16 floating point formats. + +So far, 16 bpc unorm formats were not handled, and the default: path +returned max/min factors for 32 bpp argb8888 formats, which were wrong +and bigger than what many DCE / DCN hw generations could handle. + +The result sometimes was misscaling of framebuffers with +DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616, +DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested +on Polaris11 / DCE-11.2. + +So far this went unnoticed, because only few userspace clients used such +16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they +did not experience this issue. + +With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL +and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland +compositor allowing for direct scanout of these formats, the scaling +hw will be used on these formats if possible for HiDPI display scaling, +so it is important to use the correct hw scaling limits to avoid wrong +display. + +Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50 +on HiDPI displays with scaling enabled. The mutter Wayland compositor now +correctly falls back to scaling via desktop compositing instead of direct +scanout, thereby avoiding wrong image display. For unscaled mode, it +correctly uses direct scanout. + +Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.") +Signed-off-by: Mario Kleiner +Tested-by: Mario Kleiner +Cc: Alex Deucher +Cc: Harry Wentland +Cc: Leo Li +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +index e027798ece032..9bb7475e80bad 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +@@ -1059,10 +1059,15 @@ static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev, + *min_downscale = plane_cap->max_downscale_factor.nv12; + break; + ++ /* All 64 bpp formats have the same fp16 scaling limits */ + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: ++ case DRM_FORMAT_XRGB16161616: ++ case DRM_FORMAT_ARGB16161616: ++ case DRM_FORMAT_XBGR16161616: ++ case DRM_FORMAT_ABGR16161616: + *max_upscale = plane_cap->max_upscale_factor.fp16; + *min_downscale = plane_cap->max_downscale_factor.fp16; + break; +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch b/queue-6.18/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch new file mode 100644 index 0000000000..585943b946 --- /dev/null +++ b/queue-6.18/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch @@ -0,0 +1,46 @@ +From 87e117f06331f4394b6b4bdbd5fce4fce3a638b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 09:25:32 +0000 +Subject: drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc() + +From: Zilin Guan + +[ Upstream commit c9be63d565789b56ca7b0197e2cb78a3671f95a8 ] + +In amdgpu_acpi_enumerate_xcc(), if amdgpu_acpi_dev_init() returns -ENOMEM, +the function returns directly without releasing the allocated xcc_info, +resulting in a memory leak. + +Fix this by ensuring that xcc_info is properly freed in the error paths. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects") +Reviewed-by: Lijo Lazar +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +index 6c62e27b98002..67db986eda3f6 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -1136,8 +1136,10 @@ static int amdgpu_acpi_enumerate_xcc(void) + if (!dev_info) + ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf); + +- if (ret == -ENOMEM) ++ if (ret == -ENOMEM) { ++ kfree(xcc_info); + return ret; ++ } + + if (!dev_info) { + kfree(xcc_info); +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch b/queue-6.18/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch new file mode 100644 index 0000000000..31378efe5e --- /dev/null +++ b/queue-6.18/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch @@ -0,0 +1,44 @@ +From c9ceacba32b5a12d7a85763eb33984acabd78c1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 08:35:15 +0000 +Subject: drm/amdgpu: Fix memory leak in amdgpu_ras_init() + +From: Zilin Guan + +[ Upstream commit ee41e5b63c8210525c936ee637a2c8d185ce873c ] + +When amdgpu_nbio_ras_sw_init() fails in amdgpu_ras_init(), the function +returns directly without freeing the allocated con structure, leading +to a memory leak. + +Fix this by jumping to the release_con label to properly clean up the +allocated memory before returning the error code. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: fdc94d3a8c88 ("drm/amdgpu: Rework pcie_bif ras sw_init") +Reviewed-by: Tao Zhou +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index e0ee211508607..3fd19859055a5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -4137,7 +4137,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev) + * to handle fatal error */ + r = amdgpu_nbio_ras_sw_init(adev); + if (r) +- return r; ++ goto release_con; + + if (adev->nbio.ras && + adev->nbio.ras->init_ras_controller_interrupt) { +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-move-reset-debug-disable-handling.patch b/queue-6.18/drm-amdgpu-move-reset-debug-disable-handling.patch new file mode 100644 index 0000000000..1eafe55b47 --- /dev/null +++ b/queue-6.18/drm-amdgpu-move-reset-debug-disable-handling.patch @@ -0,0 +1,238 @@ +From 74a6d8f77438e6e850422616c3cf260bf2d47d0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 17:01:05 -0400 +Subject: drm/amdgpu: move reset debug disable handling + +From: Alex Deucher + +[ Upstream commit ad0a48e531a3137cec16bb5f8f60c8cc8de06b01 ] + +Move everything to the supported resets masks rather than +having an explicit misc checks for this. + +Reviewed-by: Jesse Zhang +Signed-off-by: Alex Deucher +Stable-dep-of: 46a2cb7d24f2 ("drm/amdgpu/sdma5: enable queue resets unconditionally") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 8 +++----- + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 3 --- + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 3 ++- + drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 6 ++++-- + drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 3 ++- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 +- + drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 6 ++++-- + drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 8 ++++++-- + drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 3 ++- + drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 6 ++++-- + drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 3 ++- + drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 3 ++- + 12 files changed, 32 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +index d020a890a0ea4..630af847f29ff 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +@@ -130,11 +130,9 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) + } + + /* attempt a per ring reset */ +- if (unlikely(adev->debug_disable_gpu_ring_reset)) { +- dev_err(adev->dev, "Ring reset disabled by debug mask\n"); +- } else if (amdgpu_gpu_recovery && +- amdgpu_ring_is_reset_type_supported(ring, AMDGPU_RESET_TYPE_PER_QUEUE) && +- ring->funcs->reset) { ++ if (amdgpu_gpu_recovery && ++ amdgpu_ring_is_reset_type_supported(ring, AMDGPU_RESET_TYPE_PER_QUEUE) && ++ ring->funcs->reset) { + dev_err(adev->dev, "Starting %s ring reset\n", + s_job->sched->name); + r = amdgpu_ring_reset(ring, job->vmid, &job->hw_fence); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +index 5ec5c3ff22bb0..304564ec2f59a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +@@ -460,9 +460,6 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid, + ktime_t deadline; + bool ret; + +- if (unlikely(ring->adev->debug_disable_soft_recovery)) +- return false; +- + deadline = ktime_add_us(ktime_get(), 10000); + + if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence) +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +index 726b2bdfbba33..003bcece715eb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +@@ -4956,7 +4956,8 @@ static int gfx_v10_0_sw_init(struct amdgpu_ip_block *ip_block) + amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]); + adev->gfx.compute_supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]); +- if (!amdgpu_sriov_vf(adev)) { ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) { + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +index c936772c03725..1dd9fd486eecf 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +@@ -1821,13 +1821,15 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block) + case IP_VERSION(11, 0, 3): + if ((adev->gfx.me_fw_version >= 2280) && + (adev->gfx.mec_fw_version >= 2410) && +- !amdgpu_sriov_vf(adev)) { ++ !amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) { + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + } + break; + default: +- if (!amdgpu_sriov_vf(adev)) { ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) { + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +index f80e9e356e252..50e39b9d9df6f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +@@ -1547,7 +1547,8 @@ static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block) + case IP_VERSION(12, 0, 1): + if ((adev->gfx.me_fw_version >= 2660) && + (adev->gfx.mec_fw_version >= 2920) && +- !amdgpu_sriov_vf(adev)) { ++ !amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) { + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +index dd19a97436db9..7d0a2d239b78d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -2409,7 +2409,7 @@ static int gfx_v9_0_sw_init(struct amdgpu_ip_block *ip_block) + amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]); + adev->gfx.compute_supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]); +- if (!amdgpu_sriov_vf(adev)) ++ if (!amdgpu_sriov_vf(adev) && !adev->debug_disable_gpu_ring_reset) + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + + r = amdgpu_gfx_kiq_init(adev, GFX9_MEC_HPD_SIZE, 0); +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +index c90cbe053ef37..a4ebb6c5af557 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +@@ -1149,14 +1149,16 @@ static int gfx_v9_4_3_sw_init(struct amdgpu_ip_block *ip_block) + case IP_VERSION(9, 4, 3): + case IP_VERSION(9, 4, 4): + if ((adev->gfx.mec_fw_version >= 155) && +- !amdgpu_sriov_vf(adev)) { ++ !amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) { + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_PIPE; + } + break; + case IP_VERSION(9, 5, 0): + if ((adev->gfx.mec_fw_version >= 21) && +- !amdgpu_sriov_vf(adev)) { ++ !amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) { + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_PIPE; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +index 36b1ca73c2ed3..a1443990d5c60 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +@@ -2361,11 +2361,15 @@ static void sdma_v4_4_2_update_reset_mask(struct amdgpu_device *adev) + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { + case IP_VERSION(9, 4, 3): + case IP_VERSION(9, 4, 4): +- if ((adev->gfx.mec_fw_version >= 0xb0) && amdgpu_dpm_reset_sdma_is_supported(adev)) ++ if ((adev->gfx.mec_fw_version >= 0xb0) && ++ amdgpu_dpm_reset_sdma_is_supported(adev) && ++ !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + break; + case IP_VERSION(9, 5, 0): +- if ((adev->gfx.mec_fw_version >= 0xf) && amdgpu_dpm_reset_sdma_is_supported(adev)) ++ if ((adev->gfx.mec_fw_version >= 0xf) && ++ amdgpu_dpm_reset_sdma_is_supported(adev) && ++ !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + break; + default: +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +index 7dc67a22a7a01..8ddc4df06a1fd 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +@@ -1429,7 +1429,8 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block) + case IP_VERSION(5, 0, 2): + case IP_VERSION(5, 0, 5): + if ((adev->sdma.instance[0].fw_version >= 35) && +- !amdgpu_sriov_vf(adev)) ++ !amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + break; + default: +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +index 3bd44c24f692d..c6a619514a8ad 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +@@ -1348,12 +1348,14 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block) + case IP_VERSION(5, 2, 3): + case IP_VERSION(5, 2, 4): + if ((adev->sdma.instance[0].fw_version >= 76) && +- !amdgpu_sriov_vf(adev)) ++ !amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + break; + case IP_VERSION(5, 2, 5): + if ((adev->sdma.instance[0].fw_version >= 34) && +- !amdgpu_sriov_vf(adev)) ++ !amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + break; + default: +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +index 3c6568d501994..2170400449872 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +@@ -1356,7 +1356,8 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block) + case IP_VERSION(6, 0, 2): + case IP_VERSION(6, 0, 3): + if ((adev->sdma.instance[0].fw_version >= 21) && +- !amdgpu_sriov_vf(adev)) ++ !amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + break; + default: +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +index 326ecc8d37d21..2b81344dcd668 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +@@ -1337,7 +1337,8 @@ static int sdma_v7_0_sw_init(struct amdgpu_ip_block *ip_block) + + adev->sdma.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); +- if (!amdgpu_sriov_vf(adev)) ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + + r = amdgpu_sdma_sysfs_reset_mask_init(adev); +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch b/queue-6.18/drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch new file mode 100644 index 0000000000..050f7d5b1a --- /dev/null +++ b/queue-6.18/drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch @@ -0,0 +1,49 @@ +From f10f9e13892a74e454ba44c90dc844e547238d5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 11:51:45 -0500 +Subject: drm/amdgpu/sdma5: enable queue resets unconditionally + +From: Alex Deucher + +[ Upstream commit 46a2cb7d24f21132e970cab52359210c3f5ea3c6 ] + +There is no firmware version dependency. + +Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask") +Cc: Jesse Zhang +Reviewed-by: Jesse.Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 15 +++------------ + 1 file changed, 3 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +index 8ddc4df06a1fd..45e2933214a80 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +@@ -1424,18 +1424,9 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block) + + adev->sdma.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); +- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { +- case IP_VERSION(5, 0, 0): +- case IP_VERSION(5, 0, 2): +- case IP_VERSION(5, 0, 5): +- if ((adev->sdma.instance[0].fw_version >= 35) && +- !amdgpu_sriov_vf(adev) && +- !adev->debug_disable_gpu_ring_reset) +- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; +- break; +- default: +- break; +- } ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) ++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + + /* Allocate memory for SDMA IP Dump buffer */ + ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL); +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch b/queue-6.18/drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch new file mode 100644 index 0000000000..31e01b1107 --- /dev/null +++ b/queue-6.18/drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch @@ -0,0 +1,58 @@ +From aff1ed03d87acbd386e105d9d8953e5eb51fdc1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 11:52:46 -0500 +Subject: drm/amdgpu/sdma5.2: enable queue resets unconditionally + +From: Alex Deucher + +[ Upstream commit 314d30ad50622fc0d70da71509f9dff21545be14 ] + +There is no firmware version dependency. This also +enables sdma queue resets on all SDMA 5.2.x based +chips. + +Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask") +Cc: Jesse Zhang +Reviewed-by: Jesse.Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 22 +++------------------- + 1 file changed, 3 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +index c6a619514a8ad..5b982cc91af39 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +@@ -1342,25 +1342,9 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block) + + adev->sdma.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); +- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { +- case IP_VERSION(5, 2, 0): +- case IP_VERSION(5, 2, 2): +- case IP_VERSION(5, 2, 3): +- case IP_VERSION(5, 2, 4): +- if ((adev->sdma.instance[0].fw_version >= 76) && +- !amdgpu_sriov_vf(adev) && +- !adev->debug_disable_gpu_ring_reset) +- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; +- break; +- case IP_VERSION(5, 2, 5): +- if ((adev->sdma.instance[0].fw_version >= 34) && +- !amdgpu_sriov_vf(adev) && +- !adev->debug_disable_gpu_ring_reset) +- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; +- break; +- default: +- break; +- } ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) ++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + + /* Allocate memory for SDMA IP Dump buffer */ + ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL); +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch b/queue-6.18/drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch new file mode 100644 index 0000000000..5db66bae12 --- /dev/null +++ b/queue-6.18/drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch @@ -0,0 +1,51 @@ +From 7fb2238888be8ca211843bf9f65feb152ccedf87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 11:53:51 -0500 +Subject: drm/amdgpu/sdma6: enable queue resets unconditionally + +From: Alex Deucher + +[ Upstream commit 56423871e9eef1dd069bddef895207fa5ce275fe ] + +There is no firmware version dependency. This also +enables sdma queue resets on all SDMA 6.x based +chips. + +Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask") +Cc: Jesse Zhang +Reviewed-by: Jesse.Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 15 +++------------ + 1 file changed, 3 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +index 2170400449872..6809c6d4be5b1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +@@ -1351,18 +1351,9 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block) + + adev->sdma.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); +- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { +- case IP_VERSION(6, 0, 0): +- case IP_VERSION(6, 0, 2): +- case IP_VERSION(6, 0, 3): +- if ((adev->sdma.instance[0].fw_version >= 21) && +- !amdgpu_sriov_vf(adev) && +- !adev->debug_disable_gpu_ring_reset) +- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; +- break; +- default: +- break; +- } ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) ++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + + if (amdgpu_sdma_ras_sw_init(adev)) { + dev_err(adev->dev, "Failed to initialize sdma ras block!\n"); +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch b/queue-6.18/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch new file mode 100644 index 0000000000..a339f1afc6 --- /dev/null +++ b/queue-6.18/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch @@ -0,0 +1,44 @@ +From c71a8b57e674ac23f19b5761eea5add9e3113464 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 09:05:42 +0000 +Subject: drm/amdgpu: Use kvfree instead of kfree in + amdgpu_gmc_get_nps_memranges() + +From: Zilin Guan + +[ Upstream commit 0c44d61945c4a80775292d96460aa2f22e62f86c ] + +amdgpu_discovery_get_nps_info() internally allocates memory for ranges +using kvcalloc(), which may use vmalloc() for large allocation. Using +kfree() to release vmalloc memory will lead to a memory corruption. + +Use kvfree() to safely handle both kmalloc and vmalloc allocations. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: b194d21b9bcc ("drm/amdgpu: Use NPS ranges from discovery table") +Reviewed-by: Lijo Lazar +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +index aef1ba1bdca9e..01ad5cc008a96 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +@@ -1381,7 +1381,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev, + if (!*exp_ranges) + *exp_ranges = range_cnt; + err: +- kfree(ranges); ++ kvfree(ranges); + + return ret; + } +-- +2.51.0 + diff --git a/queue-6.18/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch b/queue-6.18/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch new file mode 100644 index 0000000000..8593ae3406 --- /dev/null +++ b/queue-6.18/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch @@ -0,0 +1,138 @@ +From 231fb5d2f186aaefca650e5203997395d1a32ad0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 21:18:11 +0530 +Subject: drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Srinivasan Shanmugam + +[ Upstream commit 5a19302cab5cec7ae7f1a60c619951e6c17d8742 ] + +The address watch clear code receives watch_id as an unsigned value +(u32), but some helper functions were using a signed int and checked +bits by shifting with watch_id. + +If a very large watch_id is passed from userspace, it can be converted +to a negative value. This can cause invalid shifts and may access +memory outside the watch_points array. + +drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 + +Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before +using it. Also use BIT(watch_id) to test and clear bits safely. + +This keeps the behavior unchanged for valid watch IDs and avoids +undefined behavior for invalid ones. + +Fixes the below: +drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448 +kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow +'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped + +drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c + 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, + 434 uint32_t watch_id) + 435 { + 436 int r; + 437 + 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) + +kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if +watch_id is larger than INT_MAX it leads to a buffer overflow. +(Negative shifts are undefined). + + 439 return -EINVAL; + 440 + 441 if (!pdd->dev->kfd->shared_resources.enable_mes) { + 442 r = debug_lock_and_unmap(pdd->dev->dqm); + 443 if (r) + 444 return r; + 445 } + 446 + 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false); +--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch( + 449 pdd->dev->adev, + 450 watch_id); + +v2: (as per, Jonathan Kim) + - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to + match the clear path. + - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id(). + +Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation") +Reported-by: Dan Carpenter +Cc: Jonathan Kim +Cc: Felix Kuehling +Cc: Alex Deucher +Cc: Christian König +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Jonathan Kim +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +index ba99e0f258aee..986cb297de8f8 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +@@ -401,27 +401,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i + return -ENOMEM; + } + +-static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id) ++static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) + { + spin_lock(&pdd->dev->watch_points_lock); + + /* process owns device watch point so safe to clear */ +- if ((pdd->alloc_watch_ids >> watch_id) & 0x1) { +- pdd->alloc_watch_ids &= ~(0x1 << watch_id); +- pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id); ++ if (pdd->alloc_watch_ids & BIT(watch_id)) { ++ pdd->alloc_watch_ids &= ~BIT(watch_id); ++ pdd->dev->alloc_watch_ids &= ~BIT(watch_id); + } + + spin_unlock(&pdd->dev->watch_points_lock); + } + +-static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id) ++static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) + { + bool owns_watch_id = false; + + spin_lock(&pdd->dev->watch_points_lock); +- owns_watch_id = watch_id < MAX_WATCH_ADDRESSES && +- ((pdd->alloc_watch_ids >> watch_id) & 0x1); +- ++ owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id); + spin_unlock(&pdd->dev->watch_points_lock); + + return owns_watch_id; +@@ -432,6 +430,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, + { + int r; + ++ if (watch_id >= MAX_WATCH_ADDRESSES) ++ return -EINVAL; ++ + if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) + return -EINVAL; + +@@ -469,6 +470,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd, + if (r) + return r; + ++ if (*watch_id >= MAX_WATCH_ADDRESSES) ++ return -EINVAL; ++ + if (!pdd->dev->kfd->shared_resources.enable_mes) { + r = debug_lock_and_unmap(pdd->dev->dqm); + if (r) { +-- +2.51.0 + diff --git a/queue-6.18/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch b/queue-6.18/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch new file mode 100644 index 0000000000..305de20be9 --- /dev/null +++ b/queue-6.18/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch @@ -0,0 +1,40 @@ +From 9e21ea5280336714a9f9e24a3ae19987884c4a78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jan 2026 08:55:49 +0530 +Subject: drm/i915/acpi: free _DSM package when no connectors + +From: Kaushlendra Kumar + +[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ] + +acpi_evaluate_dsm_typed() returns an ACPI package in pkg. +When pkg->package.count == 0, we returned without freeing pkg, +leaking memory. Free pkg before returning on the empty case. + +Signed-off-by: Kaushlendra Kumar +Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects") +Reviewed-by: Jani Nikula +Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c +index 1addd62882413..1e8b9d1756988 100644 +--- a/drivers/gpu/drm/i915/display/intel_acpi.c ++++ b/drivers/gpu/drm/i915/display/intel_acpi.c +@@ -96,6 +96,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle) + + if (!pkg->package.count) { + DRM_DEBUG_DRIVER("no connection in _DSM\n"); ++ ACPI_FREE(pkg); + return; + } + +-- +2.51.0 + diff --git a/queue-6.18/drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch b/queue-6.18/drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch new file mode 100644 index 0000000000..82a38c1da2 --- /dev/null +++ b/queue-6.18/drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch @@ -0,0 +1,44 @@ +From c9bd8a093489c0f777148a40bf4b893e637efcae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 11:26:22 +0530 +Subject: drm/xe/bo: Redirect faults to dummy page for wedged device + +From: Raag Jadav + +[ Upstream commit 4e83a8d58e1c721a89b3ffe15f549007080272e2 ] + +As per uapi documentation[1], the prerequisite for wedged device is to +redirected page faults to a dummy page. Follow it. + +[1] Documentation/gpu/drm-uapi.rst + +v2: Add uapi reference and fixes tag (Matthew Brost) + +Fixes: 7bc00751f877 ("drm/xe: Use device wedged event") +Signed-off-by: Raag Jadav +Reviewed-by: Matthew Brost +Link: https://patch.msgid.link/20260212055622.2054991-1-raag.jadav@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit c020fff70d757612933711dd3cc3751d7d782d3c) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_bo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c +index e2e28ff73925b..a270aef7c4980 100644 +--- a/drivers/gpu/drm/xe/xe_bo.c ++++ b/drivers/gpu/drm/xe/xe_bo.c +@@ -1895,7 +1895,7 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf) + int err = 0; + int idx; + +- if (!drm_dev_enter(&xe->drm, &idx)) ++ if (xe_device_wedged(xe) || !drm_dev_enter(&xe->drm, &idx)) + return ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot); + + ret = xe_bo_cpu_fault_fastpath(vmf, xe, bo, needs_rpm); +-- +2.51.0 + diff --git a/queue-6.18/drm-xe-configfs-fix-parameter-name-omitted-errors.patch b/queue-6.18/drm-xe-configfs-fix-parameter-name-omitted-errors.patch new file mode 100644 index 0000000000..50ea60bb57 --- /dev/null +++ b/queue-6.18/drm-xe-configfs-fix-parameter-name-omitted-errors.patch @@ -0,0 +1,69 @@ +From ebb4e29b7ad45d4c5d476daac69d59fe693ee85d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 20:37:45 +0100 +Subject: drm/xe/configfs: Fix 'parameter name omitted' errors + +From: Michal Wajdeczko + +[ Upstream commit 2a673fb4d787ce6672862cb693112378bff86abb ] + +On some configs and old compilers we can get following build errors: + + ../drivers/gpu/drm/xe/xe_configfs.h: In function 'xe_configfs_get_ctx_restore_mid_bb': + ../drivers/gpu/drm/xe/xe_configfs.h:40:76: error: parameter name omitted + static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class, + ^~~~~~~~~~~~~~~~~~~~ + ../drivers/gpu/drm/xe/xe_configfs.h: In function 'xe_configfs_get_ctx_restore_post_bb': + ../drivers/gpu/drm/xe/xe_configfs.h:42:77: error: parameter name omitted + static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class, + ^~~~~~~~~~~~~~~~~~~~ +when trying to define our configfs stub functions. Fix that. + +Fixes: 7a4756b2fd04 ("drm/xe/lrc: Allow to add user commands mid context switch") +Signed-off-by: Michal Wajdeczko +Cc: Rodrigo Vivi +Reviewed-by: Rodrigo Vivi +Reviewed-by: Shuicheng Lin +Link: https://patch.msgid.link/20260203193745.576-1-michal.wajdeczko@intel.com +(cherry picked from commit f59cde8a2452b392115d2af8f1143a94725f4827) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_configfs.h | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_configfs.h b/drivers/gpu/drm/xe/xe_configfs.h +index c61e0e47ed94c..08cce375ae0f3 100644 +--- a/drivers/gpu/drm/xe/xe_configfs.h ++++ b/drivers/gpu/drm/xe/xe_configfs.h +@@ -19,9 +19,11 @@ void xe_configfs_check_device(struct pci_dev *pdev); + bool xe_configfs_get_survivability_mode(struct pci_dev *pdev); + u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev); + bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev); +-u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class, ++u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, ++ enum xe_engine_class class, + const u32 **cs); +-u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class, ++u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, ++ enum xe_engine_class class, + const u32 **cs); + #else + static inline int xe_configfs_init(void) { return 0; } +@@ -30,9 +32,11 @@ static inline void xe_configfs_check_device(struct pci_dev *pdev) { } + static inline bool xe_configfs_get_survivability_mode(struct pci_dev *pdev) { return false; } + static inline u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev) { return U64_MAX; } + static inline bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev) { return false; } +-static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class, ++static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, ++ enum xe_engine_class class, + const u32 **cs) { return 0; } +-static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class, ++static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, ++ enum xe_engine_class class, + const u32 **cs) { return 0; } + #endif + +-- +2.51.0 + diff --git a/queue-6.18/drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch b/queue-6.18/drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch new file mode 100644 index 0000000000..ef9f989bb7 --- /dev/null +++ b/queue-6.18/drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch @@ -0,0 +1,42 @@ +From ba52df08bb8f158a94838164cc6b3a56638d9e73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 18:18:54 +0000 +Subject: drm/xe: Make xe_modparam.force_vram_bar_size signed + +From: Shuicheng Lin + +[ Upstream commit 1acec6ef0511b92e7974cc5a8768bfd3a659feaf ] + +vram_bar_size is registered as an int module parameter and is documented +to accept negative values to disable BAR resizing. +Store it as an int in xe_modparam as well, so negative values work as +intended and the module_param type matches. + +Fixes: 80742a1aa26e ("drm/xe: Allow to drop vram resizing") +Reviewed-by: Michal Wajdeczko +Signed-off-by: Shuicheng Lin +Link: https://patch.msgid.link/20260202181853.1095736-2-shuicheng.lin@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit 25c9aa4dcb5ef2ad9f354d19f8f1eeb690d1c161) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_module.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h +index 5a3bfea8b7b4c..b668495392701 100644 +--- a/drivers/gpu/drm/xe/xe_module.h ++++ b/drivers/gpu/drm/xe/xe_module.h +@@ -12,7 +12,7 @@ + struct xe_modparam { + bool force_execlist; + bool probe_display; +- u32 force_vram_bar_size; ++ int force_vram_bar_size; + int guc_log_level; + char *guc_firmware_path; + char *huc_firmware_path; +-- +2.51.0 + diff --git a/queue-6.18/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch b/queue-6.18/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch new file mode 100644 index 0000000000..0beeb6f479 --- /dev/null +++ b/queue-6.18/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch @@ -0,0 +1,61 @@ +From bc09ff709096cc0333fd8d0078394e1463864a12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 16:56:22 +0000 +Subject: drm/xe/mmio: Avoid double-adjust in 64-bit reads + +From: Shuicheng Lin + +[ Upstream commit 4a9b4e1fa52a6aaa1adbb7f759048df14afed54c ] + +xe_mmio_read64_2x32() was adjusting register addresses and then +calling xe_mmio_read32(), which applies the adjustment again. +This may shift accesses twice if adj_offset < adj_limit. There is +no issue currently, as for media gt, adj_offset > adj_limit, so +the 2nd adjust will be a no-op. But it may not work in future. + +To fix it, replace the adjusted-address comparison with a direct +sanity check that ensures the MMIO address adjustment cutoff never +falls within the 8-byte range of a 64-bit register. And let +xe_mmio_read32() handle address translation. + +v2: rewrite the sanity check in a more natural way. (Matt) +v3: Add Fixes tag. (Jani) + +Fixes: 07431945d8ae ("drm/xe: Avoid 64-bit register reads") +Reviewed-by: Matt Roper +Cc: Jani Nikula +Cc: Rodrigo Vivi +Signed-off-by: Shuicheng Lin +Link: https://patch.msgid.link/20260130165621.471408-2-shuicheng.lin@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit a30f999681126b128a43137793ac84b6a5b7443f) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_mmio.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index ef6f3ea573a2c..6752881af093a 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -260,11 +260,11 @@ u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) + struct xe_reg reg_udw = { .addr = reg.addr + 0x4 }; + u32 ldw, udw, oldudw, retries; + +- reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr); +- reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr); +- +- /* we shouldn't adjust just one register address */ +- xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4); ++ /* ++ * The two dwords of a 64-bit register can never straddle the offset ++ * adjustment cutoff. ++ */ ++ xe_tile_assert(mmio->tile, !in_range(mmio->adj_limit, reg.addr + 1, 7)); + + oldudw = xe_mmio_read32(mmio, reg_udw); + for (retries = 5; retries; --retries) { +-- +2.51.0 + diff --git a/queue-6.18/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch b/queue-6.18/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch new file mode 100644 index 0000000000..9ec453b6e9 --- /dev/null +++ b/queue-6.18/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch @@ -0,0 +1,72 @@ +From cbf7d860fb7a8249fe0901b603b5840583f041a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 14:05:09 -0800 +Subject: drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138 + +From: Matt Roper + +[ Upstream commit bc6387a2e0c1562faa56ce2a98cef50cab809e08 ] + +The PSS_CHICKEN register has been part of the RCS engine's LRC since it +was first introduced in Xe_LP. That means that any workarounds that +adjust its value (such as Wa_14019988906 and Wa_14019877138) need to be +implemented in the lrc_was[] table so that they become part of the +default LRC from which all subsequent LRCs are copied. Although these +workarounds were implemented correctly on most platforms, they were +incorrectly placed on the engine_was[] table for Xe2_HPG. + +Move the workarounds to the proper lrc_was[] table and switch the +'xe_rtp_match_first_render_or_compute' rule to specifically match the +RCS since that's the engine whose LRC manages the register. + +Bspec: 65182 +Fixes: 7f3ee7d88058 ("drm/xe/xe2hpg: Add initial GT workarounds") +Reviewed-by: Shekhar Chauhan +Link: https://patch.msgid.link/20260205220508.51905-2-matthew.d.roper@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit e04c609eedf4d6748ac0bcada4de1275b034fed6) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_wa.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c +index d209434fd7fc2..2a2e9f2c09163 100644 +--- a/drivers/gpu/drm/xe/xe_wa.c ++++ b/drivers/gpu/drm/xe/xe_wa.c +@@ -567,16 +567,6 @@ static const struct xe_rtp_entry_sr engine_was[] = { + FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS)) + }, +- { XE_RTP_NAME("14019988906"), +- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), +- FUNC(xe_rtp_match_first_render_or_compute)), +- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) +- }, +- { XE_RTP_NAME("14019877138"), +- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), +- FUNC(xe_rtp_match_first_render_or_compute)), +- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) +- }, + { XE_RTP_NAME("14020338487"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), + FUNC(xe_rtp_match_first_render_or_compute)), +@@ -873,6 +863,14 @@ static const struct xe_rtp_entry_sr lrc_was[] = { + XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(WM_CHICKEN3, HIZ_PLANE_COMPRESSION_DIS)) + }, ++ { XE_RTP_NAME("14019988906"), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) ++ }, ++ { XE_RTP_NAME("14019877138"), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) ++ }, + { XE_RTP_NAME("14021490052"), + XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(FF_MODE, +-- +2.51.0 + diff --git a/queue-6.18/efi-fix-reservation-of-unaccepted-memory-table.patch b/queue-6.18/efi-fix-reservation-of-unaccepted-memory-table.patch new file mode 100644 index 0000000000..65b0ca8bc0 --- /dev/null +++ b/queue-6.18/efi-fix-reservation-of-unaccepted-memory-table.patch @@ -0,0 +1,62 @@ +From ba05d9cdaa7e499762e11d6affd7196889b67910 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 10:49:56 +0000 +Subject: efi: Fix reservation of unaccepted memory table + +From: Kiryl Shutsemau (Meta) + +[ Upstream commit 0862438c90487e79822d5647f854977d50381505 ] + +The reserve_unaccepted() function incorrectly calculates the size of the +memblock reservation for the unaccepted memory table. It aligns the +size of the table, but fails to account for cases where the table's +starting physical address (efi.unaccepted) is not page-aligned. + +If the table starts at an offset within a page and its end crosses into +a subsequent page that the aligned size does not cover, the end of the +table will not be reserved. This can lead to the table being overwritten +or inaccessible, causing a kernel panic in accept_memory(). + +This issue was observed when starting Intel TDX VMs with specific memory +sizes (e.g., > 64GB). + +Fix this by calculating the end address first (including the unaligned +start) and then aligning it up, ensuring the entire range is covered +by the reservation. + +Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped") +Reported-by: Moritz Sanft +Signed-off-by: Kiryl Shutsemau (Meta) +Reviewed-by: Tom Lendacky +Acked-by: Mike Rapoport (Microsoft) +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/efi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index fc407d891348f..c3cf5541ed682 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -691,13 +691,13 @@ static __init int match_config_table(const efi_guid_t *guid, + + static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted) + { +- phys_addr_t start, size; ++ phys_addr_t start, end; + + start = PAGE_ALIGN_DOWN(efi.unaccepted); +- size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size); ++ end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size); + +- memblock_add(start, size); +- memblock_reserve(start, size); ++ memblock_add(start, end - start); ++ memblock_reserve(start, end - start); + } + + int __init efi_config_parse_tables(const efi_config_table_t *config_tables, +-- +2.51.0 + diff --git a/queue-6.18/eth-fbnic-add-validation-for-mtu-changes.patch b/queue-6.18/eth-fbnic-add-validation-for-mtu-changes.patch new file mode 100644 index 0000000000..25ec2bb901 --- /dev/null +++ b/queue-6.18/eth-fbnic-add-validation-for-mtu-changes.patch @@ -0,0 +1,68 @@ +From 0967448eeaff2761a98e5742ba3ec4a40412ae20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 09:19:49 -0800 +Subject: eth: fbnic: Add validation for MTU changes + +From: Dimitri Daskalakis + +[ Upstream commit ccd8e87748ad083047d6c8544c5809b7f96cc8df ] + +Increasing the MTU beyond the HDS threshold causes the hardware to +fragment packets across multiple buffers. If a single-buffer XDP program +is attached, the driver will drop all multi-frag frames. While we can't +prevent a remote sender from sending non-TCP packets larger than the MTU, +this will prevent users from inadvertently breaking new TCP streams. + +Traditionally, drivers supported XDP with MTU less than 4Kb +(packet per page). Fbnic currently prevents attaching XDP when MTU is too high. +But it does not prevent increasing MTU after XDP is attached. + +Fixes: 1b0a3950dbd4 ("eth: fbnic: Add XDP pass, drop, abort support") +Signed-off-by: Jakub Kicinski +Signed-off-by: Dimitri Daskalakis +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +index e95be0e7bd9e0..5cbf3ad175a54 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +@@ -262,6 +262,23 @@ static int fbnic_set_mac(struct net_device *netdev, void *p) + return 0; + } + ++static int fbnic_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ struct fbnic_net *fbn = netdev_priv(dev); ++ ++ if (fbnic_check_split_frames(fbn->xdp_prog, new_mtu, fbn->hds_thresh)) { ++ dev_err(&dev->dev, ++ "MTU %d is larger than HDS threshold %d in XDP mode\n", ++ new_mtu, fbn->hds_thresh); ++ ++ return -EINVAL; ++ } ++ ++ WRITE_ONCE(dev->mtu, new_mtu); ++ ++ return 0; ++} ++ + void fbnic_clear_rx_mode(struct fbnic_dev *fbd) + { + struct net_device *netdev = fbd->netdev; +@@ -533,6 +550,7 @@ static const struct net_device_ops fbnic_netdev_ops = { + .ndo_start_xmit = fbnic_xmit_frame, + .ndo_features_check = fbnic_features_check, + .ndo_set_mac_address = fbnic_set_mac, ++ .ndo_change_mtu = fbnic_change_mtu, + .ndo_set_rx_mode = fbnic_set_rx_mode, + .ndo_get_stats64 = fbnic_get_stats64, + .ndo_bpf = fbnic_bpf, +-- +2.51.0 + diff --git a/queue-6.18/eth-fbnic-advertise-supported-xdp-features.patch b/queue-6.18/eth-fbnic-advertise-supported-xdp-features.patch new file mode 100644 index 0000000000..1658a89f84 --- /dev/null +++ b/queue-6.18/eth-fbnic-advertise-supported-xdp-features.patch @@ -0,0 +1,57 @@ +From 4215c7e621fc72897ad6290fe887722445c1c581 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 19:06:20 -0800 +Subject: eth: fbnic: Advertise supported XDP features. + +From: Dimitri Daskalakis + +[ Upstream commit e977fcb3a318b53b47f23b44ac237fceb1b731fe ] + +Drivers are supposed to advertise the XDP features they support. This was +missed while adding XDP support. + +Before: +$ ynl --family netdev --dump dev-get +... + {'ifindex': 3, + 'xdp-features': set(), + 'xdp-rx-metadata-features': set(), + 'xsk-features': set()}, +... + +After: +$ ynl --family netdev --dump dev-get +... + {'ifindex': 3, + 'xdp-features': {'basic', 'rx-sg'}, + 'xdp-rx-metadata-features': set(), + 'xsk-features': set()}, +... + +Fixes: 168deb7b31b2 ("eth: fbnic: Add support for XDP_TX action") +Signed-off-by: Jakub Kicinski +Signed-off-by: Dimitri Daskalakis +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260218030620.3329608-1-dimitri.daskalakis1@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +index 5cbf3ad175a54..cbedaa037cfa8 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +@@ -808,6 +808,8 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd) + netdev->hw_enc_features |= netdev->features; + netdev->features |= NETIF_F_NTUPLE; + ++ netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_RX_SG; ++ + netdev->min_mtu = IPV6_MIN_MTU; + netdev->max_mtu = FBNIC_MAX_JUMBO_FRAME_SIZE - ETH_HLEN; + +-- +2.51.0 + diff --git a/queue-6.18/eth-fbnic-configure-rde-settings-for-pause-frame.patch b/queue-6.18/eth-fbnic-configure-rde-settings-for-pause-frame.patch new file mode 100644 index 0000000000..a2ed94ec26 --- /dev/null +++ b/queue-6.18/eth-fbnic-configure-rde-settings-for-pause-frame.patch @@ -0,0 +1,145 @@ +From d2b99fd71520efd07b71ba3cdf07406eefe47826 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 15:26:10 -0800 +Subject: eth: fbnic: Configure RDE settings for pause frame + +From: Mohsin Bashir + +[ Upstream commit 0135333914d63181f823bd340ae96737c8a820ca ] + +fbnic supports pause frames. When pause frames are enabled presumably +user expects lossless operation from the NIC. Make sure we configure +RDE (Rx DMA Engine) to DROP_NEVER mode to avoid discards due to delays +in fetching Rx descriptors from the host. + +While at it enable DROP_NEVER when NIC only has a single queue +configured. In this case the NIC acts as a FIFO so there's no risk +of head-of-line blocking other queues by making RDE wait. If pause +is disabled this just moves the packet loss from the DMA engine to +the Rx buffer. + +Remove redundant call to fbnic_config_drop_mode_rcq(), introduced by +commit 0cb4c0a13723 ("eth: fbnic: Implement Rx queue +alloc/start/stop/free"). This call does not add value as +fbnic_enable_rcq(), which is called immediately afterward, already +handles this. + +Although we do not support autoneg at this time, preserve tx_pause in +.mac_link_up instead of fbnic_phylink_get_pauseparam() + +Signed-off-by: Mohsin Bashir +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251113232610.1151712-1-mohsin.bashr@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: bbeb3bfbffe0 ("eth: fbnic: set FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT on RDE_CTL0") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/meta/fbnic/fbnic_netdev.h | 2 ++ + .../net/ethernet/meta/fbnic/fbnic_phylink.c | 3 +++ + drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 26 ++++++++++++++++--- + drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 1 + + 4 files changed, 28 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h +index b0a87c57910f2..e6ca23a9957d9 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h +@@ -73,6 +73,8 @@ struct fbnic_net { + + /* Time stamping filter config */ + struct kernel_hwtstamp_config hwtstamp_config; ++ ++ bool tx_pause; + }; + + int __fbnic_open(struct fbnic_net *fbn); +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c +index 7ce3fdd252828..62701923cfe96 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c +@@ -208,6 +208,9 @@ fbnic_phylink_mac_link_up(struct phylink_config *config, + struct fbnic_net *fbn = netdev_priv(netdev); + struct fbnic_dev *fbd = fbn->fbd; + ++ fbn->tx_pause = tx_pause; ++ fbnic_config_drop_mode(fbn, tx_pause); ++ + fbd->mac->link_up(fbd, tx_pause, rx_pause); + } + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +index b1e8ce89870f7..e99d17660230c 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +@@ -2573,11 +2573,15 @@ static void fbnic_enable_bdq(struct fbnic_ring *hpq, struct fbnic_ring *ppq) + } + + static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv, +- struct fbnic_ring *rcq) ++ struct fbnic_ring *rcq, bool tx_pause) + { ++ struct fbnic_net *fbn = netdev_priv(nv->napi.dev); + u32 drop_mode, rcq_ctl; + +- drop_mode = FBNIC_QUEUE_RDE_CTL0_DROP_IMMEDIATE; ++ if (!tx_pause && fbn->num_rx_queues > 1) ++ drop_mode = FBNIC_QUEUE_RDE_CTL0_DROP_IMMEDIATE; ++ else ++ drop_mode = FBNIC_QUEUE_RDE_CTL0_DROP_NEVER; + + /* Specify packet layout */ + rcq_ctl = FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_DROP_MODE_MASK, drop_mode) | +@@ -2587,6 +2591,21 @@ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv, + fbnic_ring_wr32(rcq, FBNIC_QUEUE_RDE_CTL0, rcq_ctl); + } + ++void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause) ++{ ++ int i, t; ++ ++ for (i = 0; i < fbn->num_napi; i++) { ++ struct fbnic_napi_vector *nv = fbn->napi[i]; ++ ++ for (t = 0; t < nv->rxt_count; t++) { ++ struct fbnic_q_triad *qt = &nv->qt[nv->txt_count + t]; ++ ++ fbnic_config_drop_mode_rcq(nv, &qt->cmpl, tx_pause); ++ } ++ } ++} ++ + static void fbnic_config_rim_threshold(struct fbnic_ring *rcq, u16 nv_idx, u32 rx_desc) + { + u32 threshold; +@@ -2636,7 +2655,7 @@ static void fbnic_enable_rcq(struct fbnic_napi_vector *nv, + u32 hds_thresh = fbn->hds_thresh; + u32 rcq_ctl = 0; + +- fbnic_config_drop_mode_rcq(nv, rcq); ++ fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause); + + /* Force lower bound on MAX_HEADER_BYTES. Below this, all frames should + * be split at L4. It would also result in the frames being split at +@@ -2699,7 +2718,6 @@ static void __fbnic_nv_enable(struct fbnic_napi_vector *nv) + &nv->napi); + + fbnic_enable_bdq(&qt->sub0, &qt->sub1); +- fbnic_config_drop_mode_rcq(nv, &qt->cmpl); + fbnic_enable_rcq(nv, &qt->cmpl); + } + } +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +index ca37da5a0b179..27776e844e29b 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +@@ -184,6 +184,7 @@ void fbnic_reset_netif_queues(struct fbnic_net *fbn); + irqreturn_t fbnic_msix_clean_rings(int irq, void *data); + void fbnic_napi_enable(struct fbnic_net *fbn); + void fbnic_napi_disable(struct fbnic_net *fbn); ++void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause); + void fbnic_enable(struct fbnic_net *fbn); + void fbnic_disable(struct fbnic_net *fbn); + void fbnic_flush(struct fbnic_net *fbn); +-- +2.51.0 + diff --git a/queue-6.18/eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch b/queue-6.18/eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch new file mode 100644 index 0000000000..9d25e1a506 --- /dev/null +++ b/queue-6.18/eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch @@ -0,0 +1,43 @@ +From ea1e18ab3a17b2fcba094112b3bfebcaf45822df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:00:42 -0800 +Subject: eth: fbnic: increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes + +From: Bobby Eshleman + +[ Upstream commit bd254115f38db3c046332bb62e8719e0dc7c2b53 ] + +Increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes. The previous minimum +was too small to guarantee that very long L2+L3+L4 headers always fit +within the header buffer. When EN_HDR_SPLIT is disabled and a packet +exceeds MAX_HEADER_BYTES, splitting occurs at that byte offset instead +of the header boundary, resulting in some of the header landing in the +payload page. The increased minimum ensures headers always fit with the +MAX_HEADER_BYTES cut off and land in the header page. + +Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration") +Signed-off-by: Bobby Eshleman +Acked-by: Mohsin Bashir +Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-2-55d050e6f606@meta.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +index 27776e844e29b..51a98f27d5d91 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +@@ -66,7 +66,7 @@ struct fbnic_net; + (4096 - FBNIC_RX_HROOM - FBNIC_RX_TROOM - FBNIC_RX_PAD) + #define FBNIC_HDS_THRESH_DEFAULT \ + (1536 - FBNIC_RX_PAD) +-#define FBNIC_HDR_BYTES_MIN 128 ++#define FBNIC_HDR_BYTES_MIN 256 + + struct fbnic_pkt_buff { + struct xdp_buff buff; +-- +2.51.0 + diff --git a/queue-6.18/eth-fbnic-set-dma_hint_l4-for-all-flows.patch b/queue-6.18/eth-fbnic-set-dma_hint_l4-for-all-flows.patch new file mode 100644 index 0000000000..a6440d5d43 --- /dev/null +++ b/queue-6.18/eth-fbnic-set-dma_hint_l4-for-all-flows.patch @@ -0,0 +1,61 @@ +From b16da16ef967ea7b9cd07b8af90da1a2fd85efc0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:00:43 -0800 +Subject: eth: fbnic: set DMA_HINT_L4 for all flows + +From: Bobby Eshleman + +[ Upstream commit 0f30a31b55c4179fc55613a75ef41d496687d465 ] + +fbnic always advertises ETHTOOL_TCP_DATA_SPLIT_ENABLED via ethtool +.get_ringparam. To enable proper splitting for all flow types, even for +IP/Ethernet flows, this patch sets DMA_HINT_L4 unconditionally for all +RSS and NFC flow steering rules. According to the spec, L4 falls back to +L3 if no valid L4 is found, and L3 falls back to L2 if no L3 is found. +This makes sure that the correct header boundary is used regardless of +traffic type. This is important for zero-copy use cases where we must +ensure that all ZC packets are split correctly. + +Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration") +Signed-off-by: Bobby Eshleman +Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-3-55d050e6f606@meta.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c | 3 +++ + drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 5 ++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +index 95fac020eb93c..08aed4103323e 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +@@ -1142,6 +1142,9 @@ static int fbnic_set_cls_rule_ins(struct fbnic_net *fbn, + return -EINVAL; + } + ++ dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, ++ FBNIC_RCD_HDR_AL_DMA_HINT_L4); ++ + /* Write action table values */ + act_tcam->dest = dest; + act_tcam->rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, hash_idx); +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c +index 7f31e890031c0..42a186db43ea9 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c +@@ -338,9 +338,8 @@ void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn) + else if (tstamp_mask & (1u << flow_type)) + dest |= FBNIC_RPC_ACT_TBL0_TS_ENA; + +- if (act1_value[flow_type] & FBNIC_RPC_TCAM_ACT1_L4_VALID) +- dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, +- FBNIC_RCD_HDR_AL_DMA_HINT_L4); ++ dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, ++ FBNIC_RCD_HDR_AL_DMA_HINT_L4); + + rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, flow_type); + +-- +2.51.0 + diff --git a/queue-6.18/eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch b/queue-6.18/eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch new file mode 100644 index 0000000000..89d952d6e1 --- /dev/null +++ b/queue-6.18/eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch @@ -0,0 +1,99 @@ +From 3fa6110e36d85cf6ce68520a4abe27487253f6c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:00:41 -0800 +Subject: eth: fbnic: set FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT on RDE_CTL0 + +From: Bobby Eshleman + +[ Upstream commit bbeb3bfbffe0279fa47c041658b037fb38a93965 ] + +Fix EN_HDR_SPLIT configuration by writing the field to RDE_CTL0 instead +of RDE_CTL1. + +Because drop mode configuration and header splitting enablement both use +RDE_CTL0, we consolidate these configurations into the single function +fbnic_config_drop_mode. + +Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration") +Signed-off-by: Bobby Eshleman +Acked-by: Mohsin Bashir +Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-1-55d050e6f606@meta.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 25 +++++++++++--------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +index e99d17660230c..fbdf79b6ad2de 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +@@ -2573,7 +2573,8 @@ static void fbnic_enable_bdq(struct fbnic_ring *hpq, struct fbnic_ring *ppq) + } + + static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv, +- struct fbnic_ring *rcq, bool tx_pause) ++ struct fbnic_ring *rcq, bool tx_pause, ++ bool hdr_split) + { + struct fbnic_net *fbn = netdev_priv(nv->napi.dev); + u32 drop_mode, rcq_ctl; +@@ -2586,22 +2587,26 @@ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv, + /* Specify packet layout */ + rcq_ctl = FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_DROP_MODE_MASK, drop_mode) | + FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_HROOM_MASK, FBNIC_RX_HROOM) | +- FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM); ++ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM) | ++ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT, hdr_split); + + fbnic_ring_wr32(rcq, FBNIC_QUEUE_RDE_CTL0, rcq_ctl); + } + +-void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause) ++void fbnic_config_drop_mode(struct fbnic_net *fbn, bool txp) + { ++ bool hds; + int i, t; + ++ hds = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN; ++ + for (i = 0; i < fbn->num_napi; i++) { + struct fbnic_napi_vector *nv = fbn->napi[i]; + + for (t = 0; t < nv->rxt_count; t++) { + struct fbnic_q_triad *qt = &nv->qt[nv->txt_count + t]; + +- fbnic_config_drop_mode_rcq(nv, &qt->cmpl, tx_pause); ++ fbnic_config_drop_mode_rcq(nv, &qt->cmpl, txp, hds); + } + } + } +@@ -2652,20 +2657,18 @@ static void fbnic_enable_rcq(struct fbnic_napi_vector *nv, + { + struct fbnic_net *fbn = netdev_priv(nv->napi.dev); + u32 log_size = fls(rcq->size_mask); +- u32 hds_thresh = fbn->hds_thresh; + u32 rcq_ctl = 0; +- +- fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause); ++ bool hdr_split; ++ u32 hds_thresh; + + /* Force lower bound on MAX_HEADER_BYTES. Below this, all frames should + * be split at L4. It would also result in the frames being split at + * L2/L3 depending on the frame size. + */ +- if (fbn->hds_thresh < FBNIC_HDR_BYTES_MIN) { +- rcq_ctl = FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT; +- hds_thresh = FBNIC_HDR_BYTES_MIN; +- } ++ hdr_split = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN; ++ fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause, hdr_split); + ++ hds_thresh = max(fbn->hds_thresh, FBNIC_HDR_BYTES_MIN); + rcq_ctl |= FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PADLEN_MASK, FBNIC_RX_PAD) | + FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_MAX_HDR_MASK, hds_thresh) | + FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PAYLD_OFF_MASK, +-- +2.51.0 + diff --git a/queue-6.18/fbnic-close-fw_log-race-between-users-and-teardown.patch b/queue-6.18/fbnic-close-fw_log-race-between-users-and-teardown.patch new file mode 100644 index 0000000000..8f479c11a7 --- /dev/null +++ b/queue-6.18/fbnic-close-fw_log-race-between-users-and-teardown.patch @@ -0,0 +1,124 @@ +From 852df3e8f930875453c992ac4b545e97e4ff4358 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 19:13:29 +0000 +Subject: fbnic: close fw_log race between users and teardown + +From: Chengfeng Ye + +[ Upstream commit ee5492fd88cfc079c19fbeac78e9e53b7f6c04f3 ] + +Fixes a theoretical race on fw_log between the teardown path and fw_log +write functions. + +fw_log is written inside fbnic_fw_log_write() and can be reached from +the mailbox handler fbnic_fw_msix_intr(), but fw_log is freed before +IRQ/MBX teardown during cleanup, resulting in a potential data race of +dereferencing a freed/null variable. + +Possible Interleaving Scenario: + CPU0: fbnic_fw_msix_intr() // Entry + fbnic_fw_log_write() + if (fbnic_fw_log_ready()) // true + ... preempt ... + CPU1: fbnic_remove() // Entry + fbnic_fw_log_free() + vfree(log->data_start); + log->data_start = NULL; + CPU0: continues, walks log->entries or writes to log->data_start + +The initialization also has an incorrect order problem, as the fw_log +is currently allocated after MBX setup during initialization. +Fix the problems by adjusting the synchronization order to put +initialization in place before the mailbox is enabled, and not cleared +until after the mailbox has been disabled. + +Fixes: ecc53b1b46c89 ("eth: fbnic: Enable firmware logging") +Signed-off-by: Chengfeng Ye +Link: https://patch.msgid.link/20260211191329.530886-1-dg573847474@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/meta/fbnic/fbnic_fw_log.c | 3 --- + drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 19 ++++++++++++------- + 2 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c +index 85a883dba385f..d8a9a7d7c2375 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c +@@ -51,8 +51,6 @@ int fbnic_fw_log_init(struct fbnic_dev *fbd) + log->data_start = data; + log->data_end = data + FBNIC_FW_LOG_SIZE; + +- fbnic_fw_log_enable(fbd, true); +- + return 0; + } + +@@ -63,7 +61,6 @@ void fbnic_fw_log_free(struct fbnic_dev *fbd) + if (!fbnic_fw_log_ready(fbd)) + return; + +- fbnic_fw_log_disable(fbd); + INIT_LIST_HEAD(&log->entries); + log->size = 0; + vfree(log->data_start); +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c +index 0fa90baad5f88..698b8a85afb31 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c +@@ -303,11 +303,17 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + goto free_irqs; + } + ++ err = fbnic_fw_log_init(fbd); ++ if (err) ++ dev_warn(fbd->dev, ++ "Unable to initialize firmware log buffer: %d\n", ++ err); ++ + err = fbnic_fw_request_mbx(fbd); + if (err) { + dev_err(&pdev->dev, + "Firmware mailbox initialization failure\n"); +- goto free_irqs; ++ goto free_fw_log; + } + + /* Send the request to enable the FW logging to host. Note if this +@@ -315,11 +321,7 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * possible the FW is just too old to support the logging and needs + * to be updated. + */ +- err = fbnic_fw_log_init(fbd); +- if (err) +- dev_warn(fbd->dev, +- "Unable to initialize firmware log buffer: %d\n", +- err); ++ fbnic_fw_log_enable(fbd, true); + + fbnic_devlink_register(fbd); + fbnic_devlink_otp_check(fbd, "error detected during probe"); +@@ -363,6 +365,8 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * firmware updates for fixes. + */ + return 0; ++free_fw_log: ++ fbnic_fw_log_free(fbd); + free_irqs: + fbnic_free_irqs(fbd); + err_destroy_health: +@@ -397,8 +401,9 @@ static void fbnic_remove(struct pci_dev *pdev) + fbnic_hwmon_unregister(fbd); + fbnic_dbg_fbd_exit(fbd); + fbnic_devlink_unregister(fbd); +- fbnic_fw_log_free(fbd); ++ fbnic_fw_log_disable(fbd); + fbnic_fw_free_mbx(fbd); ++ fbnic_fw_log_free(fbd); + fbnic_free_irqs(fbd); + + fbnic_devlink_health_destroy(fbd); +-- +2.51.0 + diff --git a/queue-6.18/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch b/queue-6.18/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch new file mode 100644 index 0000000000..3214d7200e --- /dev/null +++ b/queue-6.18/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch @@ -0,0 +1,51 @@ +From fb9753a59f1270e70a5c2dc6973eb0a094282474 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jan 2026 16:50:24 +0000 +Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot + +From: Jiasheng Jiang + +[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ] + +In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the +entry size ('esize') is retrieved from the log record without adequate +bounds checking. + +Specifically, the code calculates the end of the entry ('e2') using: + e2 = Add2Ptr(e1, esize); + +It then calculates the size for memmove using 'PtrOffset(e2, ...)', +which subtracts the end pointer from the buffer limit. If 'esize' is +maliciously large, 'e2' exceeds the used buffer size. This results in +a negative offset which, when cast to size_t for memmove, interprets +as a massive unsigned integer, leading to a heap buffer overflow. + +This commit adds a check to ensure that the entry size ('esize') strictly +fits within the remaining used space of the index header before performing +memory operations. + +Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fslog.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c +index 38934e6978ece..28bd611f580d9 100644 +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3429,6 +3429,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, + + e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off)); + esize = le16_to_cpu(e1->size); ++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize) ++ goto dirty_vol; ++ + e2 = Add2Ptr(e1, esize); + + memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used))); +-- +2.51.0 + diff --git a/queue-6.18/fs-ntfs3-initialize-new-folios-before-use.patch b/queue-6.18/fs-ntfs3-initialize-new-folios-before-use.patch new file mode 100644 index 0000000000..9e6491401d --- /dev/null +++ b/queue-6.18/fs-ntfs3-initialize-new-folios-before-use.patch @@ -0,0 +1,43 @@ +From 266fe65acab12925f6ae004c2db92141100039cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 23:02:51 +0100 +Subject: fs/ntfs3: Initialize new folios before use + +From: Bartlomiej Kubik + +[ Upstream commit f223ebffa185cc8da934333c5a31ff2d4f992dc9 ] + +KMSAN reports an uninitialized value in longest_match_std(), invoked +from ntfs_compress_write(). When new folios are allocated without being +marked uptodate and ni_read_frame() is skipped because the caller expects +the frame to be completely overwritten, some reserved folios may remain +only partially filled, leaving the rest memory uninitialized. + +Fixes: 584f60ba22f7 ("ntfs3: Convert ntfs_get_frame_pages() to use a folio") +Tested-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com +Reported-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=08d8956768c96a2c52cf + +Signed-off-by: Bartlomiej Kubik +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index 83f0072f0896c..3e61eaf28e088 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -930,7 +930,7 @@ static int ntfs_get_frame_pages(struct address_space *mapping, pgoff_t index, + + folio = __filemap_get_folio(mapping, index, + FGP_LOCK | FGP_ACCESSED | FGP_CREAT, +- gfp_mask); ++ gfp_mask | __GFP_ZERO); + if (IS_ERR(folio)) { + while (npages--) { + folio = page_folio(pages[npages]); +-- +2.51.0 + diff --git a/queue-6.18/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch b/queue-6.18/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch new file mode 100644 index 0000000000..8877622ba1 --- /dev/null +++ b/queue-6.18/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch @@ -0,0 +1,58 @@ +From ffb34cc517631bc47a65514d64443654aebd0082 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Dec 2025 11:53:25 +0800 +Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the + same + +From: Edward Adam Davis + +[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ] + +When processing valid within the range [valid : pos), if valid cannot +be retrieved correctly, for example, if the retrieved valid value is +always the same, this can trigger a potential infinite loop, similar +to the hung problem reported by syzbot [1]. + +Adding a check for the valid value within the loop body, and terminating +the loop and returning -EINVAL if the value is the same as the current +value, can prevent this. + +[1] +INFO: task syz.4.21:6056 blocked for more than 143 seconds. +Call Trace: + rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244 + inode_lock include/linux/fs.h:1027 [inline] + ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1 +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index 3e61eaf28e088..cd7aaeef45fe9 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -1012,8 +1012,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) + goto out; + + if (lcn == SPARSE_LCN) { +- ni->i_valid = valid = +- frame_vbo + ((u64)clen << sbi->cluster_bits); ++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits); ++ if (ni->i_valid == valid) { ++ err = -EINVAL; ++ goto out; ++ } ++ ni->i_valid = valid; + continue; + } + +-- +2.51.0 + diff --git a/queue-6.18/gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch b/queue-6.18/gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch new file mode 100644 index 0000000000..0708a99c24 --- /dev/null +++ b/queue-6.18/gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch @@ -0,0 +1,58 @@ +From 5bca349b9bab6be4d4fc5f8c7b17ccad3ac21eac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:11:49 -0800 +Subject: gpio: amd-fch: ionly return allowed values from amd_fch_gpio_get() + +From: Dmitry Torokhov + +[ Upstream commit fbd03587ba732c612b8a569d1cf5bed72bd3a27c ] + +As of 86ef402d805d ("gpiolib: sanitize the return value of +gpio_chip::get()") gpiolib requires drivers implementing GPIOs to only +return 0, 1 or negative error for the get() callbacks. Ensure that +amd-fch complies with this requirement. + +Fixes: 86ef402d805d ("gpiolib: sanitize the return value of gpio_chip::get()") +Reported-and-tested-by: Tj +Signed-off-by: Dmitry Torokhov +Link: https://patch.msgid.link/aZTlwnvHt2Gho4yN@google.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-amd-fch.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpio/gpio-amd-fch.c b/drivers/gpio/gpio-amd-fch.c +index e6c6c3ec7656e..9f329938202bf 100644 +--- a/drivers/gpio/gpio-amd-fch.c ++++ b/drivers/gpio/gpio-amd-fch.c +@@ -8,6 +8,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -120,15 +121,15 @@ static int amd_fch_gpio_get(struct gpio_chip *gc, + unsigned int offset) + { + unsigned long flags; +- int ret; ++ u32 val; + struct amd_fch_gpio_priv *priv = gpiochip_get_data(gc); + void __iomem *ptr = amd_fch_gpio_addr(priv, offset); + + spin_lock_irqsave(&priv->lock, flags); +- ret = (readl_relaxed(ptr) & AMD_FCH_GPIO_FLAG_READ); ++ val = readl_relaxed(ptr); + spin_unlock_irqrestore(&priv->lock, flags); + +- return ret; ++ return FIELD_GET(AMD_FCH_GPIO_FLAG_READ, val); + } + + static int amd_fch_gpio_request(struct gpio_chip *chip, +-- +2.51.0 + diff --git a/queue-6.18/icmp-prevent-possible-overflow-in-icmp_global_allow.patch b/queue-6.18/icmp-prevent-possible-overflow-in-icmp_global_allow.patch new file mode 100644 index 0000000000..29ef06eb20 --- /dev/null +++ b/queue-6.18/icmp-prevent-possible-overflow-in-icmp_global_allow.patch @@ -0,0 +1,41 @@ +From 7f1341d2edb60172b067945258c78e6c863339c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:28 +0000 +Subject: icmp: prevent possible overflow in icmp_global_allow() + +From: Eric Dumazet + +[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ] + +Following expression can overflow +if sysctl_icmp_msgs_per_sec is big enough. + +sysctl_icmp_msgs_per_sec * delta / HZ; + +Fixes: 4cdf507d5452 ("icmp: add a global rate limitation") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/icmp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 9323ee0a6ac48..3e19a5d465b83 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -248,7 +248,8 @@ bool icmp_global_allow(struct net *net) + if (delta < HZ / 50) + return false; + +- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; ++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec); ++ incr = div_u64((u64)incr * delta, HZ); + if (!incr) + return false; + +-- +2.51.0 + diff --git a/queue-6.18/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch b/queue-6.18/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch new file mode 100644 index 0000000000..c64a5406c3 --- /dev/null +++ b/queue-6.18/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch @@ -0,0 +1,57 @@ +From a60aa7140a3d6ea2ead93d0fd0dd3062459fc506 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:29 +0000 +Subject: inet: move icmp_global_{credit,stamp} to a separate cache line + +From: Eric Dumazet + +[ Upstream commit 87b08913a9ae82082e276d237ece08fc8ee24380 ] + +icmp_global_credit was meant to be changed ~1000 times per second, +but if an admin sets net.ipv4.icmp_msgs_per_sec to a very high value, +icmp_global_credit changes can inflict false sharing to surrounding +fields that are read mostly. + +Move icmp_global_credit and icmp_global_stamp to a separate +cacheline aligned group. + +Fixes: b056b4cd9178 ("icmp: move icmp_global.credit and icmp_global.stamp to per netns storage") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/netns/ipv4.h | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 34eb3aecb3f21..62166da045548 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -87,6 +87,12 @@ struct netns_ipv4 { + int sysctl_tcp_rmem[3]; + __cacheline_group_end(netns_ipv4_read_rx); + ++ /* ICMP rate limiter hot cache line. */ ++ __cacheline_group_begin_aligned(icmp); ++ atomic_t icmp_global_credit; ++ u32 icmp_global_stamp; ++ __cacheline_group_end_aligned(icmp); ++ + struct inet_timewait_death_row tcp_death_row; + struct udp_table *udp_table; + +@@ -139,8 +145,7 @@ struct netns_ipv4 { + int sysctl_icmp_ratemask; + int sysctl_icmp_msgs_per_sec; + int sysctl_icmp_msgs_burst; +- atomic_t icmp_global_credit; +- u32 icmp_global_stamp; ++ + u32 ip_rt_min_pmtu; + int ip_rt_mtu_expires; + int ip_rt_min_advmss; +-- +2.51.0 + diff --git a/queue-6.18/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch b/queue-6.18/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch new file mode 100644 index 0000000000..0b250cca9a --- /dev/null +++ b/queue-6.18/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch @@ -0,0 +1,53 @@ +From f9baf68961d92be290b7176edbc2fedc806773c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:22:02 +0000 +Subject: ipv6: fix a race in ip6_sock_set_v6only() + +From: Eric Dumazet + +[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ] + +It is unlikely that this function will be ever called +with isk->inet_num being not zero. + +Perform the check on isk->inet_num inside the locked section +for complete safety. + +Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Fernando Fernandez Mancera +Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/ipv6.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 2ccdf85f34f16..f0936df7567e3 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -1280,12 +1280,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, + + static inline int ip6_sock_set_v6only(struct sock *sk) + { +- if (inet_sk(sk)->inet_num) +- return -EINVAL; ++ int ret = 0; ++ + lock_sock(sk); +- sk->sk_ipv6only = true; ++ if (inet_sk(sk)->inet_num) ++ ret = -EINVAL; ++ else ++ sk->sk_ipv6only = true; + release_sock(sk); +- return 0; ++ return ret; + } + + static inline void ip6_sock_set_recverr(struct sock *sk) +-- +2.51.0 + diff --git a/queue-6.18/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch b/queue-6.18/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch new file mode 100644 index 0000000000..e62aaf0bdb --- /dev/null +++ b/queue-6.18/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch @@ -0,0 +1,125 @@ +From 493cc1cc2d90d492db06e2fb030bbf47fab9e7ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:50:21 +0000 +Subject: ipv6: Fix out-of-bound access in fib6_add_rt2node(). + +From: Kuniyuki Iwashima + +[ Upstream commit 8244f959e2c125c849e569f5b23ed49804cce695 ] + +syzbot reported out-of-bound read in fib6_add_rt2node(). [0] + +When IPv6 route is created with RTA_NH_ID, struct fib6_info +does not have the trailing struct fib6_nh. + +The cited commit started to check !iter->fib6_nh->fib_nh_gw_family +to ensure that rt6_qualify_for_ecmp() will return false for iter. + +If iter->nh is not NULL, rt6_qualify_for_ecmp() returns false anyway. + +Let's check iter->nh before reading iter->fib6_nh and avoid OOB read. + +[0]: +BUG: KASAN: slab-out-of-bounds in fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142 +Read of size 1 at addr ffff8880384ba6de by task syz.0.18/5500 + +CPU: 0 UID: 0 PID: 5500 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full) +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +Call Trace: + + dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:378 [inline] + print_report+0xba/0x230 mm/kasan/report.c:482 + kasan_report+0x117/0x150 mm/kasan/report.c:595 + fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142 + fib6_add_rt2node_nh net/ipv6/ip6_fib.c:1363 [inline] + fib6_add+0x910/0x18c0 net/ipv6/ip6_fib.c:1531 + __ip6_ins_rt net/ipv6/route.c:1351 [inline] + ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3957 + inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660 + rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f9316b9aeb9 +Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007ffd8809b678 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00007f9316e15fa0 RCX: 00007f9316b9aeb9 +RDX: 0000000000000000 RSI: 0000200000004380 RDI: 0000000000000003 +RBP: 00007f9316c08c1f R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007f9316e15fac R14: 00007f9316e15fa0 R15: 00007f9316e15fa0 + + +Allocated by task 5499: + kasan_save_stack mm/kasan/common.c:57 [inline] + kasan_save_track+0x3e/0x80 mm/kasan/common.c:78 + poison_kmalloc_redzone mm/kasan/common.c:398 [inline] + __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415 + kasan_kmalloc include/linux/kasan.h:263 [inline] + __do_kmalloc_node mm/slub.c:5657 [inline] + __kmalloc_noprof+0x40c/0x7e0 mm/slub.c:5669 + kmalloc_noprof include/linux/slab.h:961 [inline] + kzalloc_noprof include/linux/slab.h:1094 [inline] + fib6_info_alloc+0x30/0xf0 net/ipv6/ip6_fib.c:155 + ip6_route_info_create+0x142/0x860 net/ipv6/route.c:3820 + ip6_route_add+0x49/0x1b0 net/ipv6/route.c:3949 + inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660 + rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Fixes: bbf4a17ad9ff ("ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF") +Reported-by: syzbot+707d6a5da1ab9e0c6f9d@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/698cbfba.050a0220.2eeac1.009d.GAE@google.com/ +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Fernando Fernandez Mancera +Reviewed-by: Shigeru Yoshida +Link: https://patch.msgid.link/20260211175133.3657034-1-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index c6439e30e892a..cc149227b49f4 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1139,7 +1139,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_add_gc_list(iter); + } + if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) && +- !iter->fib6_nh->fib_nh_gw_family) { ++ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) { + iter->fib6_flags &= ~RTF_ADDRCONF; + iter->fib6_flags &= ~RTF_PREFIX_RT; + } +-- +2.51.0 + diff --git a/queue-6.18/ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch b/queue-6.18/ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch new file mode 100644 index 0000000000..2b6d462bbd --- /dev/null +++ b/queue-6.18/ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch @@ -0,0 +1,95 @@ +From 948d9b79c53c81ed65ebf63dac11fa6dd96a4b53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:30 +0000 +Subject: ipv6: icmp: remove obsolete code in icmpv6_xrlim_allow() + +From: Eric Dumazet + +[ Upstream commit 0201eedb69b24a6be9b7c1716287a89c4dde2320 ] + +Following part was needed before the blamed commit, because +inet_getpeer_v6() second argument was the prefix. + + /* Give more bandwidth to wider prefixes. */ + if (rt->rt6i_dst.plen < 128) + tmo >>= ((128 - rt->rt6i_dst.plen)>>5); + +Now inet_getpeer_v6() retrieves hosts, we need to remove +@tmo adjustement or wider prefixes likes /24 allow 8x +more ICMP to be sent for a given ratelimit. + +As we had this issue for a while, this patch changes net.ipv6.icmp.ratelimit +default value from 1000ms to 100ms to avoid potential regressions. + +Also add a READ_ONCE() when reading net->ipv6.sysctl.icmpv6_time. + +Fixes: fd0273d7939f ("ipv6: Remove external dependency on rt6i_dst and rt6i_src") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Cc: Martin KaFai Lau +Link: https://patch.msgid.link/20260216142832.3834174-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + Documentation/networking/ip-sysctl.rst | 7 ++++--- + net/ipv6/af_inet6.c | 2 +- + net/ipv6/icmp.c | 7 +------ + 3 files changed, 6 insertions(+), 10 deletions(-) + +diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst +index a06cb99d66dcd..7a637e87005fe 100644 +--- a/Documentation/networking/ip-sysctl.rst ++++ b/Documentation/networking/ip-sysctl.rst +@@ -3195,12 +3195,13 @@ enhanced_dad - BOOLEAN + =========== + + ratelimit - INTEGER +- Limit the maximal rates for sending ICMPv6 messages. ++ Limit the maximal rates for sending ICMPv6 messages to a particular ++ peer. + + 0 to disable any limiting, +- otherwise the minimal space between responses in milliseconds. ++ otherwise the space between responses in milliseconds. + +- Default: 1000 ++ Default: 100 + + ratemask - list of comma separated ranges + For ICMPv6 message types matching the ranges in the ratemask, limit +diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c +index 1b0314644e0cc..0e8f48835869c 100644 +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -955,7 +955,7 @@ static int __net_init inet6_net_init(struct net *net) + int err = 0; + + net->ipv6.sysctl.bindv6only = 0; +- net->ipv6.sysctl.icmpv6_time = 1*HZ; ++ net->ipv6.sysctl.icmpv6_time = HZ / 10; + net->ipv6.sysctl.icmpv6_echo_ignore_all = 0; + net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0; + net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0; +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index 306eec18e82c1..35b32dcf581ff 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -217,14 +217,9 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type, + } else if (dev && (dev->flags & IFF_LOOPBACK)) { + res = true; + } else { +- struct rt6_info *rt = dst_rt6_info(dst); +- int tmo = net->ipv6.sysctl.icmpv6_time; ++ int tmo = READ_ONCE(net->ipv6.sysctl.icmpv6_time); + struct inet_peer *peer; + +- /* Give more bandwidth to wider prefixes. */ +- if (rt->rt6i_dst.plen < 128) +- tmo >>= ((128 - rt->rt6i_dst.plen)>>5); +- + peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr); + res = inet_peer_xrlim_allow(peer, tmo); + } +-- +2.51.0 + diff --git a/queue-6.18/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch b/queue-6.18/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch new file mode 100644 index 0000000000..f6cf60983a --- /dev/null +++ b/queue-6.18/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch @@ -0,0 +1,129 @@ +From 8d3b11d605b14169844a33faa3bd8039fa1e890a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 16:58:50 +0200 +Subject: ipvs: do not keep dest_dst if dev is going down + +From: Julian Anastasov + +[ Upstream commit 8fde939b0206afc1d5846217a01a16b9bc8c7896 ] + +There is race between the netdev notifier ip_vs_dst_event() +and the code that caches dst with dev that is going down. +As the FIB can be notified for the closed device after our +handler finishes, it is possible valid route to be returned +and cached resuling in a leaked dev reference until the dest +is not removed. + +To prevent new dest_dst to be attached to dest just after the +handler dropped the old one, add a netif_running() check +to make sure the notifier handler is not currently running +for device that is closing. + +Fixes: 7a4f0761fce3 ("IPVS: init and cleanup restructuring") +Signed-off-by: Julian Anastasov +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_xmit.c | 46 ++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 10 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c +index 618fbe1240b54..ecbcdc43263d6 100644 +--- a/net/netfilter/ipvs/ip_vs_xmit.c ++++ b/net/netfilter/ipvs/ip_vs_xmit.c +@@ -295,6 +295,12 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs, + return true; + } + ++/* rt has device that is down */ ++static bool rt_dev_is_down(const struct net_device *dev) ++{ ++ return dev && !netif_running(dev); ++} ++ + /* Get route to destination or remote server */ + static int + __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, +@@ -310,9 +316,11 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + + if (dest) { + dest_dst = __ip_vs_dst_check(dest); +- if (likely(dest_dst)) ++ if (likely(dest_dst)) { + rt = dst_rtable(dest_dst->dst_cache); +- else { ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.ip; ++ } else { + dest_dst = ip_vs_dest_dst_alloc(); + spin_lock_bh(&dest->dst_lock); + if (!dest_dst) { +@@ -328,14 +336,22 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + ip_vs_dest_dst_free(dest_dst); + goto err_unreach; + } +- __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0); ++ /* It is forbidden to attach dest->dest_dst if ++ * device is going down. ++ */ ++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst))) ++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0); ++ else ++ noref = 0; + spin_unlock_bh(&dest->dst_lock); + IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d\n", + &dest->addr.ip, &dest_dst->dst_saddr.ip, + rcuref_read(&rt->dst.__rcuref)); ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.ip; ++ if (!noref) ++ ip_vs_dest_dst_free(dest_dst); + } +- if (ret_saddr) +- *ret_saddr = dest_dst->dst_saddr.ip; + } else { + noref = 0; + +@@ -472,9 +488,11 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + + if (dest) { + dest_dst = __ip_vs_dst_check(dest); +- if (likely(dest_dst)) ++ if (likely(dest_dst)) { + rt = dst_rt6_info(dest_dst->dst_cache); +- else { ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.in6; ++ } else { + u32 cookie; + + dest_dst = ip_vs_dest_dst_alloc(); +@@ -495,14 +513,22 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + } + rt = dst_rt6_info(dst); + cookie = rt6_get_cookie(rt); +- __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie); ++ /* It is forbidden to attach dest->dest_dst if ++ * device is going down. ++ */ ++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst))) ++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie); ++ else ++ noref = 0; + spin_unlock_bh(&dest->dst_lock); + IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n", + &dest->addr.in6, &dest_dst->dst_saddr.in6, + rcuref_read(&rt->dst.__rcuref)); ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.in6; ++ if (!noref) ++ ip_vs_dest_dst_free(dest_dst); + } +- if (ret_saddr) +- *ret_saddr = dest_dst->dst_saddr.in6; + } else { + noref = 0; + dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm, +-- +2.51.0 + diff --git a/queue-6.18/kbuild-add-objtool-to-top-level-clean-target.patch b/queue-6.18/kbuild-add-objtool-to-top-level-clean-target.patch new file mode 100644 index 0000000000..d20afe0b3e --- /dev/null +++ b/queue-6.18/kbuild-add-objtool-to-top-level-clean-target.patch @@ -0,0 +1,71 @@ +From 55f45cd8dad081264b36665a7357e6c71061bc0a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 13:45:22 -0800 +Subject: kbuild: Add objtool to top-level clean target + +From: Josh Poimboeuf + +[ Upstream commit 68b4fe32d73789dea23e356f468de67c8367ef8f ] + +Objtool is an integral part of the build, make sure it gets cleaned by +"make clean" and "make mrproper". + +Fixes: 442f04c34a1a ("objtool: Add tool to perform compile-time stack metadata validation") +Reported-by: Jens Remus +Closes: https://lore.kernel.org/15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com +Signed-off-by: Josh Poimboeuf +Tested-by: Jens Remus +Link: https://patch.msgid.link/968faf2ed30fa8b3519f79f01a1ecfe7929553e5.1770759919.git.jpoimboe@kernel.org +[nathan: use Closes: instead of Link: per checkpatch.pl] +Signed-off-by: Nathan Chancellor +Signed-off-by: Sasha Levin +--- + Makefile | 11 ++++++++++- + tools/objtool/Makefile | 2 ++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index c4b22ec262784..bc34a825aba80 100644 +--- a/Makefile ++++ b/Makefile +@@ -1440,6 +1440,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),) + $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean + endif + ++PHONY += objtool_clean ++ ++objtool_O = $(abspath $(objtree))/tools/objtool ++ ++objtool_clean: ++ifneq ($(wildcard $(objtool_O)),) ++ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean ++endif ++ + tools/: FORCE + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ +@@ -1603,7 +1612,7 @@ vmlinuxclean: + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean + $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean) + +-clean: archclean vmlinuxclean resolve_btfids_clean ++clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean + + # mrproper - Delete all generated files, including .config + # +diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile +index 8c20361dd100e..99d3897e046c6 100644 +--- a/tools/objtool/Makefile ++++ b/tools/objtool/Makefile +@@ -7,6 +7,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR))) + srctree := $(patsubst %/,%,$(dir $(srctree))) + endif + ++RM ?= rm -f ++ + LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ + ifneq ($(OUTPUT),) + LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd +-- +2.51.0 + diff --git a/queue-6.18/libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch b/queue-6.18/libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch new file mode 100644 index 0000000000..024cca57c1 --- /dev/null +++ b/queue-6.18/libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch @@ -0,0 +1,43 @@ +From 58f3c80b91b4d29fdb06c9a283388439b58021df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 15:01:34 -0800 +Subject: libbpf: Fix invalid write loop logic in bpf_linker__add_buf() + +From: Amery Hung + +[ Upstream commit 04999b99e81eaa7b6223ec1c03af3bcb4ac57aaa ] + +Fix bpf_linker__add_buf()'s logic of copying data from memory buffer into +memfd. In the event of short write not writing entire buf_sz bytes into memfd +file, we'll append bytes from the beginning of buf *again* (corrupting ELF +file contents) instead of correctly appending the rest of not-yet-read buf +contents. + +Closes: https://github.com/libbpf/libbpf/issues/945 +Fixes: 6d5e5e5d7ce1 ("libbpf: Extend linker API to support in-memory ELF files") +Signed-off-by: Amery Hung +Signed-off-by: Andrii Nakryiko +Acked-by: Jiri Olsa +Link: https://lore.kernel.org/bpf/20260209230134.3530521-1-ameryhung@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/linker.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c +index 56ae77047bc36..b86b8ae3b6341 100644 +--- a/tools/lib/bpf/linker.c ++++ b/tools/lib/bpf/linker.c +@@ -581,7 +581,7 @@ int bpf_linker__add_buf(struct bpf_linker *linker, void *buf, size_t buf_sz, + + written = 0; + while (written < buf_sz) { +- ret = write(fd, buf, buf_sz); ++ ret = write(fd, buf + written, buf_sz - written); + if (ret < 0) { + ret = -errno; + pr_warn("failed to write '%s': %s\n", filename, errstr(ret)); +-- +2.51.0 + diff --git a/queue-6.18/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch b/queue-6.18/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch new file mode 100644 index 0000000000..e832a9a14e --- /dev/null +++ b/queue-6.18/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch @@ -0,0 +1,116 @@ +From 25fbd119df3980bc8fb1beddb5bab0dca0304971 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:25:57 +0000 +Subject: macvlan: observe an RCU grace period in macvlan_common_newlink() + error path + +From: Eric Dumazet + +[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ] + +valis reported that a race condition still happens after my prior patch. + +macvlan_common_newlink() might have made @dev visible before +detecting an error, and its caller will directly call free_netdev(dev). + +We must respect an RCU period, either in macvlan or the core networking +stack. + +After adding a temporary mdelay(1000) in macvlan_forward_source_one() +to open the race window, valis repro was: + +ip link add p1 type veth peer p2 +ip link set address 00:00:00:00:00:20 dev p1 +ip link set up dev p1 +ip link set up dev p2 +ip link add mv0 link p2 type macvlan mode source + +(ip link add invalid% link p2 type macvlan mode source macaddr add +00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4 +PING 1.2.3.4 (1.2.3.4): 56 data bytes +RTNETLINK answers: Invalid argument + +BUG: KASAN: slab-use-after-free in macvlan_forward_source +(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +Read of size 8 at addr ffff888016bb89c0 by task e/175 + +CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +Call Trace: + +dump_stack_lvl (lib/dump_stack.c:123) +print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +kasan_report (mm/kasan/report.c:597) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +? tasklet_init (kernel/softirq.c:983) +macvlan_handle_frame (drivers/net/macvlan.c:501) + +Allocated by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +__kasan_kmalloc (mm/kasan/common.c:419) +__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657 +mm/slub.c:7140) +alloc_netdev_mqs (net/core/dev.c:12012) +rtnl_create_link (net/core/rtnetlink.c:3648) +rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Freed by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +kasan_save_free_info (mm/kasan/generic.c:587) +__kasan_slab_free (mm/kasan/common.c:287) +kfree (mm/slub.c:6674 mm/slub.c:6882) +rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()") +Signed-off-by: Eric Dumazet +Reported-by: valis +Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index c509228be84d1..4433b8e95b6ac 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1572,6 +1572,11 @@ int macvlan_common_newlink(struct net_device *dev, + if (create) + macvlan_port_destroy(port->dev); + } ++ /* @dev might have been made visible before an error was detected. ++ * Make sure to observe an RCU grace period before our caller ++ * (rtnl_newlink()) frees it. ++ */ ++ synchronize_net(); + return err; + } + EXPORT_SYMBOL_GPL(macvlan_common_newlink); +-- +2.51.0 + diff --git a/queue-6.18/mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch b/queue-6.18/mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch new file mode 100644 index 0000000000..f3fcadf0f8 --- /dev/null +++ b/queue-6.18/mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch @@ -0,0 +1,51 @@ +From 4e63ce5d292c0cf2657fa9439886bcd7474e3024 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 04:40:10 -0500 +Subject: mshv: fix SRCU protection in irqfd resampler ack handler + +From: Li RongQing + +[ Upstream commit 2e7577cd5ddc1f86d1b6c48caf3cfa87dbb14e34 ] + +Replace hlist_for_each_entry_rcu() with hlist_for_each_entry_srcu() +in mshv_irqfd_resampler_ack() to correctly handle SRCU-protected +linked list traversal. + +The function uses SRCU (sleepable RCU) synchronization via +partition->pt_irq_srcu, but was incorrectly using the RCU variant +for list iteration. This could lead to race conditions when the +list is modified concurrently. + +Also add srcu_read_lock_held() assertion as required by +hlist_for_each_entry_srcu() to ensure we're in the proper +read-side critical section. + +Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs") +Signed-off-by: Li RongQing +Reviewed-by: Anirudh Rayabharam (Microsoft) +Acked-by: Stanislav Kinsburskii +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + drivers/hv/mshv_eventfd.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/hv/mshv_eventfd.c b/drivers/hv/mshv_eventfd.c +index 806674722868b..05d643f54f45a 100644 +--- a/drivers/hv/mshv_eventfd.c ++++ b/drivers/hv/mshv_eventfd.c +@@ -87,8 +87,9 @@ static void mshv_irqfd_resampler_ack(struct mshv_irq_ack_notifier *mian) + + idx = srcu_read_lock(&partition->pt_irq_srcu); + +- hlist_for_each_entry_rcu(irqfd, &resampler->rsmplr_irqfd_list, +- irqfd_resampler_hnode) { ++ hlist_for_each_entry_srcu(irqfd, &resampler->rsmplr_irqfd_list, ++ irqfd_resampler_hnode, ++ srcu_read_lock_held(&partition->pt_irq_srcu)) { + if (hv_should_clear_interrupt(irqfd->irqfd_lapic_irq.lapic_control.interrupt_type)) + hv_call_clear_virtual_interrupt(partition->pt_id); + +-- +2.51.0 + diff --git a/queue-6.18/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch b/queue-6.18/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch new file mode 100644 index 0000000000..2c4811e73f --- /dev/null +++ b/queue-6.18/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch @@ -0,0 +1,192 @@ +From 1c9667ad0f6820a0f57947d696c0e982e4b5158d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 09:00:30 +0200 +Subject: net: bridge: mcast: always update mdb_n_entries for vlan contexts + +From: Nikolay Aleksandrov + +[ Upstream commit 8b769e311a86bb9d15c5658ad283b86fc8f080a2 ] + +syzbot triggered a warning[1] about the number of mdb entries in a context. +It turned out that there are multiple ways to trigger that warning today +(some got added during the years), the root cause of the problem is that +the increase is done conditionally, and over the years these different +conditions increased so there were new ways to trigger the warning, that is +to do a decrease which wasn't paired with a previous increase. + +For example one way to trigger it is with flush: + $ ip l add br0 up type bridge vlan_filtering 1 mcast_snooping 1 + $ ip l add dumdum up master br0 type dummy + $ bridge mdb add dev br0 port dumdum grp 239.0.0.1 permanent vid 1 + $ ip link set dev br0 down + $ ip link set dev br0 type bridge mcast_vlan_snooping 1 + ^^^^ this will enable snooping, but will not update mdb_n_entries + because in __br_multicast_enable_port_ctx() we check !netif_running + $ bridge mdb flush dev br0 + ^^^ this will trigger the warning because it will delete the pg which + we added above, which will try to decrease mdb_n_entries + +Fix the problem by removing the conditional increase and always keep the +count up-to-date while the vlan exists. In order to do that we have to +first initialize it on port-vlan context creation, and then always increase +or decrease the value regardless of mcast options. To keep the current +behaviour we have to enforce the mdb limit only if the context is port's or +if the port-vlan's mcast snooping is enabled. + +[1] + ------------[ cut here ]------------ + n == 0 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline], CPU#0: syz.4.4607/22043 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline], CPU#0: syz.4.4607/22043 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825, CPU#0: syz.4.4607/22043 + Modules linked in: + CPU: 0 UID: 0 PID: 22043 Comm: syz.4.4607 Not tainted syzkaller #0 PREEMPT(full) + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026 + RIP: 0010:br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline] + RIP: 0010:br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline] + RIP: 0010:br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825 + Code: 41 5f 5d e9 04 7a 48 f7 e8 3f 73 5c f7 90 0f 0b 90 e9 cf fd ff ff e8 31 73 5c f7 90 0f 0b 90 e9 16 fd ff ff e8 23 73 5c f7 90 <0f> 0b 90 e9 60 fd ff ff e8 15 73 5c f7 eb 05 e8 0e 73 5c f7 48 8b + RSP: 0018:ffffc9000c207220 EFLAGS: 00010293 + RAX: ffffffff8a68042d RBX: ffff88807c6f1800 RCX: ffff888066e90000 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: 0000000000000000 R08: ffff888066e90000 R09: 000000000000000c + R10: 000000000000000c R11: 0000000000000000 R12: ffff8880303ef800 + R13: dffffc0000000000 R14: ffff888050eb11c4 R15: 1ffff1100a1d6238 + FS: 00007fa45921b6c0(0000) GS:ffff8881256f5000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007fa4591f9ff8 CR3: 0000000081df2000 CR4: 00000000003526f0 + Call Trace: + + br_mdb_flush_pgs net/bridge/br_mdb.c:1525 [inline] + br_mdb_flush net/bridge/br_mdb.c:1544 [inline] + br_mdb_del_bulk+0x5e2/0xb20 net/bridge/br_mdb.c:1561 + rtnl_mdb_del+0x48a/0x640 net/core/rtnetlink.c:-1 + rtnetlink_rcv_msg+0x77e/0xbe0 net/core/rtnetlink.c:6967 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + RIP: 0033:0x7fa45839aeb9 + Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48 + RSP: 002b:00007fa45921b028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e + RAX: ffffffffffffffda RBX: 00007fa458615fa0 RCX: 00007fa45839aeb9 + RDX: 0000000000000000 RSI: 00002000000000c0 RDI: 0000000000000004 + RBP: 00007fa458408c1f R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 + R13: 00007fa458616038 R14: 00007fa458615fa0 R15: 00007fff0b59fae8 + + +Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port") +Reported-by: syzbot+d5d1b7343531d17bd3c5@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/aYrWbRp83MQR1ife@debil/T/#t +Reviewed-by: Ido Schimmel +Signed-off-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20260213070031.1400003-2-nikolay@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/bridge/br_multicast.c | 45 ++++++++++++++++----------------------- + 1 file changed, 18 insertions(+), 27 deletions(-) + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 22d12e5459668..5855eb0502085 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -244,14 +244,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid) + + lockdep_assert_held_once(&port->br->multicast_lock); + +- if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) +- return NULL; +- + /* Take RCU to access the vlan. */ + rcu_read_lock(); + + vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid); +- if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx)) ++ if (vlan) + pmctx = &vlan->port_mcast_ctx; + + rcu_read_unlock(); +@@ -701,7 +698,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx, + u32 max = READ_ONCE(pmctx->mdb_max_entries); + u32 n = READ_ONCE(pmctx->mdb_n_entries); + +- if (max && n >= max) { ++ /* enforce the max limit when it's a port pmctx or a port-vlan pmctx ++ * with snooping enabled ++ */ ++ if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) { + NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u", + what, n, max); + return -E2BIG; +@@ -736,9 +736,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port, + return err; + } + +- /* Only count on the VLAN context if VID is given, and if snooping on +- * that VLAN is enabled. +- */ ++ /* Only count on the VLAN context if VID is given */ + if (!group->vid) + return 0; + +@@ -2011,6 +2009,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port, + timer_setup(&pmctx->ip6_own_query.timer, + br_ip6_multicast_port_query_expired, 0); + #endif ++ /* initialize mdb_n_entries if a new port vlan is being created */ ++ if (vlan) { ++ struct net_bridge_port_group *pg; ++ u32 n = 0; ++ ++ spin_lock_bh(&port->br->multicast_lock); ++ hlist_for_each_entry(pg, &port->mglist, mglist) ++ if (pg->key.addr.vid == vlan->vid) ++ n++; ++ WRITE_ONCE(pmctx->mdb_n_entries, n); ++ spin_unlock_bh(&port->br->multicast_lock); ++ } + } + + void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx) +@@ -2094,25 +2104,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) + br_ip4_multicast_add_router(brmctx, pmctx); + br_ip6_multicast_add_router(brmctx, pmctx); + } +- +- if (br_multicast_port_ctx_is_vlan(pmctx)) { +- struct net_bridge_port_group *pg; +- u32 n = 0; +- +- /* The mcast_n_groups counter might be wrong. First, +- * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries +- * are flushed, thus mcast_n_groups after the toggle does not +- * reflect the true values. And second, permanent entries added +- * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected +- * either. Thus we have to refresh the counter. +- */ +- +- hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) { +- if (pg->key.addr.vid == pmctx->vlan->vid) +- n++; +- } +- WRITE_ONCE(pmctx->mdb_n_entries, n); +- } + } + + static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) +-- +2.51.0 + diff --git a/queue-6.18/net-mlx5-fix-misidentification-of-write-combining-cq.patch b/queue-6.18/net-mlx5-fix-misidentification-of-write-combining-cq.patch new file mode 100644 index 0000000000..a9130b3713 --- /dev/null +++ b/queue-6.18/net-mlx5-fix-misidentification-of-write-combining-cq.patch @@ -0,0 +1,87 @@ +From 3f1a49935226ecaceb8405bcb2ca4ec6b2b581f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:01 +0200 +Subject: net/mlx5: Fix misidentification of write combining CQE during poll + loop + +From: Gal Pressman + +[ Upstream commit d451994ebc7d4392610bd4b2ab339b255deb4143 ] + +The write combining completion poll loop uses usleep_range() which can +sleep much longer than requested due to scheduler latency. Under load, +we witnessed a 20ms+ delay until the process was rescheduled, causing +the jiffies based timeout to expire while the thread is sleeping. + +The original do-while loop structure (poll, sleep, check timeout) would +exit without a final poll when waking after timeout, missing a CQE that +arrived during sleep. + +Instead of the open-coded while loop, use the kernel's poll_timeout_us() +which always performs an additional check after the sleep expiration, +and is less error-prone. + +Note: poll_timeout_us() doesn't accept a sleep range, by passing 10 +sleep_us the sleep range effectively changes from 2-10 to 3-10 usecs. + +Fixes: d98995b4bf98 ("net/mlx5: Reimplement write combining test") +Signed-off-by: Gal Pressman +Reviewed-by: Jianbo Liu +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-4-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/wc.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wc.c b/drivers/net/ethernet/mellanox/mlx5/core/wc.c +index 05e5fd777d4f4..8701b7b6a2d51 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/wc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/wc.c +@@ -2,6 +2,7 @@ + // Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + #include ++#include + #include + #include "lib/clock.h" + #include "mlx5_core.h" +@@ -14,7 +15,7 @@ + #define TEST_WC_NUM_WQES 255 + #define TEST_WC_LOG_CQ_SZ (order_base_2(TEST_WC_NUM_WQES)) + #define TEST_WC_SQ_LOG_WQ_SZ TEST_WC_LOG_CQ_SZ +-#define TEST_WC_POLLING_MAX_TIME_JIFFIES msecs_to_jiffies(100) ++#define TEST_WC_POLLING_MAX_TIME_USEC (100 * USEC_PER_MSEC) + + struct mlx5_wc_cq { + /* data path - accessed per cqe */ +@@ -358,7 +359,6 @@ static int mlx5_wc_poll_cq(struct mlx5_wc_sq *sq) + static void mlx5_core_test_wc(struct mlx5_core_dev *mdev) + { + unsigned int offset = 0; +- unsigned long expires; + struct mlx5_wc_sq *sq; + int i, err; + +@@ -388,13 +388,9 @@ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev) + + mlx5_wc_post_nop(sq, &offset, true); + +- expires = jiffies + TEST_WC_POLLING_MAX_TIME_JIFFIES; +- do { +- err = mlx5_wc_poll_cq(sq); +- if (err) +- usleep_range(2, 10); +- } while (mdev->wc_state == MLX5_WC_STATE_UNINITIALIZED && +- time_is_after_jiffies(expires)); ++ poll_timeout_us(mlx5_wc_poll_cq(sq), ++ mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED, 10, ++ TEST_WC_POLLING_MAX_TIME_USEC, false); + + mlx5_wc_destroy_sq(sq); + +-- +2.51.0 + diff --git a/queue-6.18/net-mlx5-fix-multiport-device-check-over-light-sfs.patch b/queue-6.18/net-mlx5-fix-multiport-device-check-over-light-sfs.patch new file mode 100644 index 0000000000..d4eacccf08 --- /dev/null +++ b/queue-6.18/net-mlx5-fix-multiport-device-check-over-light-sfs.patch @@ -0,0 +1,55 @@ +From 24678e834373904435601621dedb34fba2ea8a8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:28:59 +0200 +Subject: net/mlx5: Fix multiport device check over light SFs + +From: Shay Drory + +[ Upstream commit 47bf2e813817159f4d195be83a9b5a640ee6baec ] + +Driver is using num_vhca_ports capability to distinguish between +multiport master device and multiport slave device. num_vhca_ports is a +capability the driver sets according to the MAX num_vhca_ports +capability reported by FW. On the other hand, light SFs doesn't set the +above capbility. + +This leads to wrong results whenever light SFs is checking whether he is +a multiport master or slave. + +Therefore, use the MAX capability to distinguish between master and +slave devices. + +Fixes: e71383fb9cd1 ("net/mlx5: Light probe local SFs") +Signed-off-by: Shay Drory +Reviewed-by: Moshe Shemesh +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-2-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/linux/mlx5/driver.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index 5405ca1038f9e..85c2b3d358ec1 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -1274,12 +1274,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev) + static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev) + { + return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) && +- MLX5_CAP_GEN(dev, num_vhca_ports) <= 1; ++ MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1; + } + + static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev) + { +- return MLX5_CAP_GEN(dev, num_vhca_ports) > 1; ++ return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1; + } + + static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev) +-- +2.51.0 + diff --git a/queue-6.18/net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch b/queue-6.18/net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch new file mode 100644 index 0000000000..df649a576c --- /dev/null +++ b/queue-6.18/net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch @@ -0,0 +1,318 @@ +From 73287f7ddbadea3aaf637e2b8efa7a92d198402b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:03 +0200 +Subject: net/mlx5e: Fix deadlocks between devlink and netdev instance locks + +From: Cosmin Ratiu + +[ Upstream commit 83ac0304a2d77519dae1e54c9713cbe1aedf19c9 ] + +In the mentioned "Fixes" commit, various work tasks triggering devlink +health reporter recovery were switched to use netdev_trylock to protect +against concurrent tear down of the channels being recovered. But this +had the side effect of introducing potential deadlocks because of +incorrect lock ordering. + +The correct lock order is described by the init flow: +probe_one -> mlx5_init_one (acquires devlink lock) +-> mlx5_init_one_devl_locked -> mlx5_register_device +-> mlx5_rescan_drivers_locked -...-> mlx5e_probe -> _mlx5e_probe +-> register_netdev (acquires rtnl lock) +-> register_netdevice (acquires netdev lock) +=> devlink lock -> rtnl lock -> netdev lock. + +But in the current recovery flow, the order is wrong: +mlx5e_tx_err_cqe_work (acquires netdev lock) +-> mlx5e_reporter_tx_err_cqe -> mlx5e_health_report +-> devlink_health_report (acquires devlink lock => boom!) +-> devlink_health_reporter_recover +-> mlx5e_tx_reporter_recover -> mlx5e_tx_reporter_recover_from_ctx +-> mlx5e_tx_reporter_err_cqe_recover + +The same pattern exists in: +mlx5e_reporter_rx_timeout +mlx5e_reporter_tx_ptpsq_unhealthy +mlx5e_reporter_tx_timeout + +Fix these by moving the netdev_trylock calls from the work handlers +lower in the call stack, in the respective recovery functions, where +they are actually necessary. + +Fixes: 8f7b00307bf1 ("net/mlx5e: Convert mlx5 netdevs to instance locking") +Signed-off-by: Cosmin Ratiu +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-6-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 14 ----- + .../mellanox/mlx5/core/en/reporter_rx.c | 13 +++++ + .../mellanox/mlx5/core/en/reporter_tx.c | 52 +++++++++++++++++-- + .../net/ethernet/mellanox/mlx5/core/en_main.c | 40 -------------- + 4 files changed, 61 insertions(+), 58 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +index c93ee969ea647..ec715b158a342 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +@@ -448,22 +448,8 @@ static void mlx5e_ptpsq_unhealthy_work(struct work_struct *work) + { + struct mlx5e_ptpsq *ptpsq = + container_of(work, struct mlx5e_ptpsq, report_unhealthy_work); +- struct mlx5e_txqsq *sq = &ptpsq->txqsq; +- +- /* Recovering the PTP SQ means re-enabling NAPI, which requires the +- * netdev instance lock. However, SQ closing has to wait for this work +- * task to finish while also holding the same lock. So either get the +- * lock or find that the SQ is no longer enabled and thus this work is +- * not relevant anymore. +- */ +- while (!netdev_trylock(sq->netdev)) { +- if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) +- return; +- msleep(20); +- } + + mlx5e_reporter_tx_ptpsq_unhealthy(ptpsq); +- netdev_unlock(sq->netdev); + } + + static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +index b1415992ffa24..a09a7c05820d6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +@@ -1,6 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 + // Copyright (c) 2019 Mellanox Technologies. + ++#include ++ + #include "health.h" + #include "params.h" + #include "txrx.h" +@@ -177,6 +179,16 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx) + rq = ctx; + priv = rq->priv; + ++ /* Acquire netdev instance lock to synchronize with channel close and ++ * reopen flows. Either successfully obtain the lock, or detect that ++ * channels are closing for another reason, making this work no longer ++ * necessary. ++ */ ++ while (!netdev_trylock(rq->netdev)) { ++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state)) ++ return 0; ++ msleep(20); ++ } + mutex_lock(&priv->state_lock); + + eq = rq->cq.mcq.eq; +@@ -186,6 +198,7 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx) + clear_bit(MLX5E_SQ_STATE_ENABLED, &rq->icosq->state); + + mutex_unlock(&priv->state_lock); ++ netdev_unlock(rq->netdev); + + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +index 9e2cf191ed308..9f6454102cf79 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +@@ -1,6 +1,8 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + /* Copyright (c) 2019 Mellanox Technologies. */ + ++#include ++ + #include "health.h" + #include "en/ptp.h" + #include "en/devlink.h" +@@ -78,6 +80,18 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx) + if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) + return 0; + ++ /* Recovering queues means re-enabling NAPI, which requires the netdev ++ * instance lock. However, SQ closing flows have to wait for work tasks ++ * to finish while also holding the netdev instance lock. So either get ++ * the lock or find that the SQ is no longer enabled and thus this work ++ * is not relevant anymore. ++ */ ++ while (!netdev_trylock(dev)) { ++ if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) ++ return 0; ++ msleep(20); ++ } ++ + err = mlx5_core_query_sq_state(mdev, sq->sqn, &state); + if (err) { + netdev_err(dev, "Failed to query SQ 0x%x state. err = %d\n", +@@ -113,9 +127,11 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx) + else + mlx5e_trigger_napi_sched(sq->cq.napi); + ++ netdev_unlock(dev); + return 0; + out: + clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state); ++ netdev_unlock(dev); + return err; + } + +@@ -136,10 +152,24 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) + sq = to_ctx->sq; + eq = sq->cq.mcq.eq; + priv = sq->priv; ++ ++ /* Recovering the TX queues implies re-enabling NAPI, which requires ++ * the netdev instance lock. ++ * However, channel closing flows have to wait for this work to finish ++ * while holding the same lock. So either get the lock or find that ++ * channels are being closed for other reason and this work is not ++ * relevant anymore. ++ */ ++ while (!netdev_trylock(sq->netdev)) { ++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)) ++ return 0; ++ msleep(20); ++ } ++ + err = mlx5e_health_channel_eq_recover(sq->netdev, eq, sq->cq.ch_stats); + if (!err) { + to_ctx->status = 0; /* this sq recovered */ +- return err; ++ goto out; + } + + mutex_lock(&priv->state_lock); +@@ -147,7 +177,7 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) + mutex_unlock(&priv->state_lock); + if (!err) { + to_ctx->status = 1; /* all channels recovered */ +- return err; ++ goto out; + } + + to_ctx->status = err; +@@ -155,7 +185,8 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) + netdev_err(priv->netdev, + "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n", + err); +- ++out: ++ netdev_unlock(sq->netdev); + return err; + } + +@@ -172,10 +203,22 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) + return 0; + + priv = ptpsq->txqsq.priv; ++ netdev = priv->netdev; ++ ++ /* Recovering the PTP SQ means re-enabling NAPI, which requires the ++ * netdev instance lock. However, SQ closing has to wait for this work ++ * task to finish while also holding the same lock. So either get the ++ * lock or find that the SQ is no longer enabled and thus this work is ++ * not relevant anymore. ++ */ ++ while (!netdev_trylock(netdev)) { ++ if (!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state)) ++ return 0; ++ msleep(20); ++ } + + mutex_lock(&priv->state_lock); + chs = &priv->channels; +- netdev = priv->netdev; + + carrier_ok = netif_carrier_ok(netdev); + netif_carrier_off(netdev); +@@ -192,6 +235,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) + netif_carrier_on(netdev); + + mutex_unlock(&priv->state_lock); ++ netdev_unlock(netdev); + + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 59e17b41c3a67..cb993ad2d9ad9 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -688,19 +688,7 @@ static void mlx5e_rq_timeout_work(struct work_struct *timeout_work) + struct mlx5e_rq, + rx_timeout_work); + +- /* Acquire netdev instance lock to synchronize with channel close and +- * reopen flows. Either successfully obtain the lock, or detect that +- * channels are closing for another reason, making this work no longer +- * necessary. +- */ +- while (!netdev_trylock(rq->netdev)) { +- if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state)) +- return; +- msleep(20); +- } +- + mlx5e_reporter_rx_timeout(rq); +- netdev_unlock(rq->netdev); + } + + static int mlx5e_alloc_mpwqe_rq_drop_page(struct mlx5e_rq *rq) +@@ -1997,20 +1985,7 @@ void mlx5e_tx_err_cqe_work(struct work_struct *recover_work) + struct mlx5e_txqsq *sq = container_of(recover_work, struct mlx5e_txqsq, + recover_work); + +- /* Recovering queues means re-enabling NAPI, which requires the netdev +- * instance lock. However, SQ closing flows have to wait for work tasks +- * to finish while also holding the netdev instance lock. So either get +- * the lock or find that the SQ is no longer enabled and thus this work +- * is not relevant anymore. +- */ +- while (!netdev_trylock(sq->netdev)) { +- if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) +- return; +- msleep(20); +- } +- + mlx5e_reporter_tx_err_cqe(sq); +- netdev_unlock(sq->netdev); + } + + static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode) +@@ -5102,19 +5077,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) + struct net_device *netdev = priv->netdev; + int i; + +- /* Recovering the TX queues implies re-enabling NAPI, which requires +- * the netdev instance lock. +- * However, channel closing flows have to wait for this work to finish +- * while holding the same lock. So either get the lock or find that +- * channels are being closed for other reason and this work is not +- * relevant anymore. +- */ +- while (!netdev_trylock(netdev)) { +- if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)) +- return; +- msleep(20); +- } +- + for (i = 0; i < netdev->real_num_tx_queues; i++) { + struct netdev_queue *dev_queue = + netdev_get_tx_queue(netdev, i); +@@ -5127,8 +5089,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) + /* break if tried to reopened channels */ + break; + } +- +- netdev_unlock(netdev); + } + + static void mlx5e_tx_timeout(struct net_device *dev, unsigned int txqueue) +-- +2.51.0 + diff --git a/queue-6.18/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch b/queue-6.18/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch new file mode 100644 index 0000000000..42bae9bb18 --- /dev/null +++ b/queue-6.18/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch @@ -0,0 +1,48 @@ +From 9a24c77a520472de671e9b5eaf6fe9f66dc0ce8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:04 +0200 +Subject: net/mlx5e: Use unsigned for mlx5e_get_max_num_channels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cosmin Ratiu + +[ Upstream commit 57a94d4b22b0c6cc5d601e6b6238d78fb923d991 ] + +The max number of channels is always an unsigned int, use the correct +type to fix compilation errors done with strict type checking, e.g.: + +error: call to ‘__compiletime_assert_1110’ declared with attribute + error: min(mlx5e_get_devlink_param_num_doorbells(mdev), + mlx5e_get_max_num_channels(mdev)) signedness error + +Fixes: 74a8dadac17e ("net/mlx5e: Preparations for supporting larger number of channels") +Signed-off-by: Cosmin Ratiu +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-7-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index b34b85539f3b1..5bced924a24fb 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -179,7 +179,8 @@ static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size) + } + + /* Use this function to get max num channels (rxqs/txqs) only to create netdev */ +-static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) ++static inline unsigned int ++mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) + { + return is_kdump_kernel() ? + MLX5E_MIN_NUM_CHANNELS : +-- +2.51.0 + diff --git a/queue-6.18/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch b/queue-6.18/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch new file mode 100644 index 0000000000..96b0677184 --- /dev/null +++ b/queue-6.18/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch @@ -0,0 +1,62 @@ +From 453eef1864f47a3c47532d19c1f48a9c17a3487d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:02 +0000 +Subject: net: mscc: ocelot: add missing lock protection in + ocelot_port_xmit_inj() + +From: Ziyi Guo + +[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ] + +ocelot_port_xmit_inj() calls ocelot_can_inject() and +ocelot_port_inject_frame() without holding the injection group lock. +Both functions contain lockdep_assert_held() for the injection lock, +and the correct caller felix_port_deferred_xmit() properly acquires +the lock using ocelot_lock_inj_grp() before calling these functions. + +Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register +injection path to fix the missing lock protection. The FDMA path is not +affected as it uses its own locking mechanism. + +Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups") +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index a7966c174b2e2..1b82693204640 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, + int port = priv->port.index; + u32 rew_op = 0; + +- if (!ocelot_can_inject(ocelot, 0)) ++ ocelot_lock_inj_grp(ocelot, 0); ++ ++ if (!ocelot_can_inject(ocelot, 0)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_BUSY; ++ } + +- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_OK; ++ } + + ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ++ ocelot_unlock_inj_grp(ocelot, 0); ++ + consume_skb(skb); + + return NETDEV_TX_OK; +-- +2.51.0 + diff --git a/queue-6.18/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch b/queue-6.18/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch new file mode 100644 index 0000000000..650e2575d8 --- /dev/null +++ b/queue-6.18/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch @@ -0,0 +1,93 @@ +From d55e2f93e6fb62286d58941cb26d79a16ffe4593 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:00 +0000 +Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper + +From: Ziyi Guo + +[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ] + +Extract the PTP timestamp handling logic from ocelot_port_xmit() into a +separate ocelot_xmit_timestamp() helper function. This is a pure +refactor with no behavioral change. + +The helper returns false if the skb was consumed (freed) due to a +timestamp request failure, and true if the caller should continue with +frame injection. The rew_op value is returned via pointer. + +This prepares for splitting ocelot_port_xmit() into separate FDMA and +register injection paths in a subsequent patch. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++---------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 469784d3a1a67..ef4a6c768de9b 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -551,33 +551,41 @@ static int ocelot_port_stop(struct net_device *dev) + return 0; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, ++ struct sk_buff *skb, u32 *rew_op) + { +- struct ocelot_port_private *priv = netdev_priv(dev); +- struct ocelot_port *ocelot_port = &priv->port; +- struct ocelot *ocelot = ocelot_port->ocelot; +- int port = priv->port.index; +- u32 rew_op = 0; +- +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) +- return NETDEV_TX_BUSY; +- +- /* Check if timestamping is needed */ + if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + struct sk_buff *clone = NULL; + + if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) { + kfree_skb(skb); +- return NETDEV_TX_OK; ++ return false; + } + + if (clone) + OCELOT_SKB_CB(skb)->clone = clone; + +- rew_op = ocelot_ptp_rew_op(skb); ++ *rew_op = ocelot_ptp_rew_op(skb); + } + ++ return true; ++} ++ ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!static_branch_unlikely(&ocelot_fdma_enabled) && ++ !ocelot_can_inject(ocelot, 0)) ++ return NETDEV_TX_BUSY; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ + if (static_branch_unlikely(&ocelot_fdma_enabled)) { + ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); + } else { +-- +2.51.0 + diff --git a/queue-6.18/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch b/queue-6.18/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch new file mode 100644 index 0000000000..ec35454ff9 --- /dev/null +++ b/queue-6.18/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch @@ -0,0 +1,100 @@ +From b0e63116d9f10b8c0030d11085e4f9ba15df0adb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:01 +0000 +Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths + +From: Ziyi Guo + +[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ] + +Split ocelot_port_xmit() into two separate functions: +- ocelot_port_xmit_fdma(): handles the FDMA injection path +- ocelot_port_xmit_inj(): handles the register-based injection path + +The top-level ocelot_port_xmit() now dispatches to the appropriate +function based on the ocelot_fdma_enabled static key. + +This is a pure refactor with no behavioral change. Separating the two +code paths makes each one simpler and prepares for adding proper locking +to the register injection path without affecting the FDMA path. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index ef4a6c768de9b..a7966c174b2e2 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -571,7 +571,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, + return true; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ ++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); ++ ++ return NETDEV_TX_OK; ++} ++ ++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, ++ struct net_device *dev) + { + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; +@@ -579,24 +597,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) + int port = priv->port.index; + u32 rew_op = 0; + +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) ++ if (!ocelot_can_inject(ocelot, 0)) + return NETDEV_TX_BUSY; + + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + return NETDEV_TX_OK; + +- if (static_branch_unlikely(&ocelot_fdma_enabled)) { +- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); +- } else { +- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); ++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + +- consume_skb(skb); +- } ++ consume_skb(skb); + + return NETDEV_TX_OK; + } + ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ if (static_branch_unlikely(&ocelot_fdma_enabled)) ++ return ocelot_port_xmit_fdma(skb, dev); ++ ++ return ocelot_port_xmit_inj(skb, dev); ++} ++ + enum ocelot_action_type { + OCELOT_MACT_LEARN, + OCELOT_MACT_FORGET, +-- +2.51.0 + diff --git a/queue-6.18/net-psp-select-config_skb_extensions.patch b/queue-6.18/net-psp-select-config_skb_extensions.patch new file mode 100644 index 0000000000..6e7b74361c --- /dev/null +++ b/queue-6.18/net-psp-select-config_skb_extensions.patch @@ -0,0 +1,59 @@ +From 65bdeecbcc5aa9d6ae751323d9f81e7de3819c22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 11:54:54 +0100 +Subject: net: psp: select CONFIG_SKB_EXTENSIONS + +From: Arnd Bergmann + +[ Upstream commit 6e980df452169f82674f2e650079c1fe0aee343d ] + +psp now uses skb extensions, failing to build when that is disabled: + +In file included from include/net/psp.h:7, + from net/psp/psp_sock.c:9: +include/net/psp/functions.h: In function '__psp_skb_coalesce_diff': +include/net/psp/functions.h:60:13: error: implicit declaration of function 'skb_ext_find'; did you mean 'skb_ext_copy'? [-Wimplicit-function-declaration] + 60 | a = skb_ext_find(one, SKB_EXT_PSP); + | ^~~~~~~~~~~~ + | skb_ext_copy +include/net/psp/functions.h:60:31: error: 'SKB_EXT_PSP' undeclared (first use in this function) + 60 | a = skb_ext_find(one, SKB_EXT_PSP); + | ^~~~~~~~~~~ +include/net/psp/functions.h:60:31: note: each undeclared identifier is reported only once for each function it appears in +include/net/psp/functions.h: In function '__psp_sk_rx_policy_check': +include/net/psp/functions.h:94:53: error: 'SKB_EXT_PSP' undeclared (first use in this function) + 94 | struct psp_skb_ext *pse = skb_ext_find(skb, SKB_EXT_PSP); + | ^~~~~~~~~~~ +net/psp/psp_sock.c: In function 'psp_sock_recv_queue_check': +net/psp/psp_sock.c:164:41: error: 'SKB_EXT_PSP' undeclared (first use in this function) + 164 | pse = skb_ext_find(skb, SKB_EXT_PSP); + | ^~~~~~~~~~~ + +Select the Kconfig symbol as we do from its other users. + +Fixes: 6b46ca260e22 ("net: psp: add socket security association code") +Signed-off-by: Arnd Bergmann +Reviewed-by: Simon Horman +Reviewed-by: Daniel Zahka +Link: https://patch.msgid.link/20260216105500.2382181-1-arnd@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/psp/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/psp/Kconfig b/net/psp/Kconfig +index 371e8771f3bd3..84d6b0f254606 100644 +--- a/net/psp/Kconfig ++++ b/net/psp/Kconfig +@@ -6,6 +6,7 @@ config INET_PSP + bool "PSP Security Protocol support" + depends on INET + select SKB_DECRYPTED ++ select SKB_EXTENSIONS + select SOCK_VALIDATE_XMIT + help + Enable kernel support for the PSP Security Protocol (PSP). +-- +2.51.0 + diff --git a/queue-6.18/net-rds-rds_sendmsg-should-not-discard-payload_len.patch b/queue-6.18/net-rds-rds_sendmsg-should-not-discard-payload_len.patch new file mode 100644 index 0000000000..3d55febc74 --- /dev/null +++ b/queue-6.18/net-rds-rds_sendmsg-should-not-discard-payload_len.patch @@ -0,0 +1,50 @@ +From 0e4f5ddcbfffd9a7ead29ab6108e49c00e780b56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:54:09 -0700 +Subject: net/rds: rds_sendmsg should not discard payload_len + +From: Allison Henderson + +[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ] + +Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with +connection teardown") modifies rds_sendmsg to avoid enqueueing work +while a tear down is in progress. However, it also changed the return +value of rds_sendmsg to that of rds_send_xmit instead of the +payload_len. This means the user may incorrectly receive errno values +when it should have simply received a payload of 0 while the peer +attempts a reconnections. So this patch corrects the teardown handling +code to only use the out error path in that case, thus restoring the +original payload_len return value. + +Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown") +Reviewed-by: Simon Horman +Signed-off-by: Allison Henderson +Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/rds/send.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/rds/send.c b/net/rds/send.c +index 0b3d0ef2f008b..071c5dca969a2 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1382,9 +1382,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) + else + queue_delayed_work(rds_wq, &cpath->cp_send_w, 1); + rcu_read_unlock(); ++ ++ if (ret) ++ goto out; + } +- if (ret) +- goto out; ++ + rds_message_put(rm); + + for (ind = 0; ind < vct.indx; ind++) +-- +2.51.0 + diff --git a/queue-6.18/net-remove-warn_on_once-when-accessing-forward-path-.patch b/queue-6.18/net-remove-warn_on_once-when-accessing-forward-path-.patch new file mode 100644 index 0000000000..d080551443 --- /dev/null +++ b/queue-6.18/net-remove-warn_on_once-when-accessing-forward-path-.patch @@ -0,0 +1,39 @@ +From 5cd4b939e7fe7e93e85a45cf39130aef3b12cb94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 12:56:39 +0100 +Subject: net: remove WARN_ON_ONCE when accessing forward path array + +From: Pablo Neira Ayuso + +[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ] + +Although unlikely, recent support for IPIP tunnels increases chances of +reaching this WARN_ON_ONCE if userspace manages to build a sufficiently +long forward path. + +Remove it. + +Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 5b536860138d1..ff70c902a4196 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -738,7 +738,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) + { + int k = stack->num_paths++; + +- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) ++ if (k >= NET_DEVICE_PATH_STACK_MAX) + return NULL; + + return &stack->path[k]; +-- +2.51.0 + diff --git a/queue-6.18/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch b/queue-6.18/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch new file mode 100644 index 0000000000..133069fc57 --- /dev/null +++ b/queue-6.18/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch @@ -0,0 +1,48 @@ +From c32577e898ced8ffd9cc183f2d4006c5903cfc8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 14:44:01 +0100 +Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register + width + +From: Daniel Machon + +[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ] + +DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth +across traffic classes based on per-queue cost values, where lower cost +means higher bandwidth share. + +The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware +register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only +5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to +compute cost values that silently overflow via FIELD_PREP, resulting +in incorrect scheduling weights. + +Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width. + +Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc") +Signed-off-by: Daniel Machon +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +index 1231a80335d7b..04f76f1e23f60 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +@@ -35,7 +35,7 @@ + #define SPX5_SE_BURST_UNIT 4096 + + /* Dwrr */ +-#define SPX5_DWRR_COST_MAX 63 ++#define SPX5_DWRR_COST_MAX 31 + + struct sparx5_shaper { + u32 mode; +-- +2.51.0 + diff --git a/queue-6.18/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch b/queue-6.18/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch new file mode 100644 index 0000000000..945fd68b07 --- /dev/null +++ b/queue-6.18/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch @@ -0,0 +1,53 @@ +From 0db44c82970f7a71683e80d4424f1bdd1f82e0f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 12:02:30 +0100 +Subject: net: sparx5/lan969x: fix PTP clock max_adj value + +From: Daniel Machon + +[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ] + +The max_adj field in ptp_clock_info tells userspace how much the PHC +clock frequency can be adjusted. ptp4l reads this and will never request +a correction larger than max_adj. + +On both sparx5 and lan969x the clock offset may never converge because +the servo needs a frequency correction larger than the current max_adj +of 200000 (200 ppm) allows. The servo rails at the max and the offset +stays in the tens of microseconds. + +The hardware has no inherent max adjustment limit; frequency correction +is done by writing a 64-bit clock period increment to CLK_PER_CFG, and +the register has plenty of range. The 200000 value was just an overly +conservative software limit. The max_adj is shared between sparx5 and +lan969x, and the increased value is safe for both. + +Fix this by increasing max_adj to 10000000 (10000 ppm), giving the +servo sufficient headroom. + +Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks") +Signed-off-by: Daniel Machon +Reviewed-by: Maxime Chevallier +Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +index 2f168700f63c1..8b2e07821a950 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +@@ -576,7 +576,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) + static struct ptp_clock_info sparx5_ptp_clock_info = { + .owner = THIS_MODULE, + .name = "sparx5 ptp", +- .max_adj = 200000, ++ .max_adj = 10000000, + .gettime64 = sparx5_ptp_gettime64, + .settime64 = sparx5_ptp_settime64, + .adjtime = sparx5_ptp_adjtime, +-- +2.51.0 + diff --git a/queue-6.18/net-stmmac-fix-oops-when-split-header-is-enabled.patch b/queue-6.18/net-stmmac-fix-oops-when-split-header-is-enabled.patch new file mode 100644 index 0000000000..8940fe9bf0 --- /dev/null +++ b/queue-6.18/net-stmmac-fix-oops-when-split-header-is-enabled.patch @@ -0,0 +1,79 @@ +From 6755394ddd4c927dba8e0e244486721da4d3b8b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 17:50:32 -0500 +Subject: net: stmmac: fix oops when split header is enabled + +From: Jie Zhang + +[ Upstream commit babab1b42ed68877ef669a08384becf281ad2582 ] + +For GMAC4, when split header is enabled, in some rare cases, the +hardware does not fill buf2 of the first descriptor with payload. +Thus we cannot assume buf2 is always fully filled if it is not +the last descriptor. Otherwise, the length of buf2 of the second +descriptor will be calculated wrong and cause an oops: + +Unable to handle kernel paging request at virtual address ffff00019246bfc0 +... +x2 : 0000000000000040 x1 : ffff00019246bfc0 x0 : ffff00009246c000 +Call trace: + dcache_inval_poc+0x28/0x58 (P) + dma_direct_sync_single_for_cpu+0x38/0x6c + __dma_sync_single_for_cpu+0x34/0x6c + stmmac_napi_poll_rx+0x8f0/0xb60 + __napi_poll.constprop.0+0x30/0x144 + net_rx_action+0x160/0x274 + handle_softirqs+0x1b8/0x1fc +... + +To fix this, the PL bit-field in RDES3 register is used for all +descriptors, whether it is the last descriptor or not. + +Fixes: ec222003bd94 ("net: stmmac: Prepare to add Split Header support") +Reviewed-by: Jacob Keller +Signed-off-by: Jie Zhang +Link: https://patch.msgid.link/20260209225037.589130-1-jie.zhang@analog.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index a38976c65149c..46299b7925b44 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -4880,13 +4880,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv, + if (!priv->sph) + return 0; + +- /* Not last descriptor */ +- if (status & rx_not_ls) ++ /* For GMAC4, when split header is enabled, in some rare cases, the ++ * hardware does not fill buf2 of the first descriptor with payload. ++ * Thus we cannot assume buf2 is always fully filled if it is not ++ * the last descriptor. Otherwise, the length of buf2 of the second ++ * descriptor will be calculated wrong and cause an oops. ++ * ++ * If this is the last descriptor, 'plen' is the length of the ++ * received packet that was transferred to system memory. ++ * Otherwise, it is the accumulated number of bytes that have been ++ * transferred for the current packet. ++ * ++ * Thus 'plen - len' always gives the correct length of buf2. ++ */ ++ ++ /* Not GMAC4 and not last descriptor */ ++ if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls)) + return priv->dma_conf.dma_buf_sz; + ++ /* GMAC4 or last descriptor */ + plen = stmmac_get_rx_frame_len(priv, p, coe); + +- /* Last descriptor */ + return plen - len; + } + +-- +2.51.0 + diff --git a/queue-6.18/net-stmmac-remove-broken-pcs-code.patch b/queue-6.18/net-stmmac-remove-broken-pcs-code.patch new file mode 100644 index 0000000000..852916350a --- /dev/null +++ b/queue-6.18/net-stmmac-remove-broken-pcs-code.patch @@ -0,0 +1,284 @@ +From 6ab31bf74b22ee9ace5cfdb9dd826d7ad0feb025 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 15:36:46 +0100 +Subject: net: stmmac: remove broken PCS code + +From: Russell King (Oracle) + +[ Upstream commit 813882ae22756bcf9645d405e045c60e5aab0a93 ] + +Changing the netif_carrier_*() state behind phylink's back has always +been prohibited because it messes up with phylinks state tracking, and +means that phylink no longer guarantees to call the mac_link_down() +and mac_link_up() methods at the appropriate times. This was later +documented in the sfp-phylink network driver conversion guide. + +stmmac was converted to phylink in 2019, but nothing was done with the +"PCS" code. Since then, apart from the updates as part of phylink +development, nothing has happened with stmmac to improve its use of +phylink, or even to address this point. + +A couple of years ago, a has_integrated_pcs boolean was added by Bart, +which later became the STMMAC_FLAG_HAS_INTEGRATED_PCS flag, to avoid +manipulating the netif_carrier_*() state. This flag is mis-named, +because whenever the stmmac is synthesized for its native SGMII, TBI +or RTBI interfaces, it has an "integrated PCS". This boolean/flag +actually means "ignore the status from the integrated PCS". + +Discussing with Bart, the reasons for this are lost to the winds of +time (which is why we should always document the reasons in the commit +message.) + +RGMII also has in-band status, and the dwmac cores and stmmac code +supports this but with one bug that saves the day. + +When dwmac cores are synthesised for RGMII only, they do not contain +an integrated PCS, and so priv->dma_cap.pcs is clear, which prevents +(incorrectly) the "RGMII PCS" being used, meaning we don't read the +in-band status. However, a core synthesised for RGMII and also SGMII, +TBI or RTBI will have this capability bit set, thus making these +code paths reachable. + +The Jetson Xavier NX uses RGMII mode to talk to its PHY, and removing +the incorrect check for priv->dma_cap.pcs reveals the theortical issue +with netif_carrier_*() manipulation is real: + +dwc-eth-dwmac 2490000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0 +dwc-eth-dwmac 2490000.ethernet eth0: PHY [stmmac-0:00] driver [RTL8211F Gigabit Ethernet] (irq=141) +dwc-eth-dwmac 2490000.ethernet eth0: No Safety Features support found +dwc-eth-dwmac 2490000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported +dwc-eth-dwmac 2490000.ethernet eth0: registered PTP clock +dwc-eth-dwmac 2490000.ethernet eth0: configuring for phy/rgmii-id link mode +8021q: adding VLAN 0 to HW filter on device eth0 +dwc-eth-dwmac 2490000.ethernet eth0: Adding VLAN ID 0 is not supported +Link is Up - 1000/Full +Link is Down +Link is Up - 1000/Full + +This looks good until one realises that the phylink "Link" status +messages are missing, even when the RJ45 cable is reconnected. Nothing +one can do results in the interface working. The interrupt handler +(which prints those "Link is" messages) always wins over phylink's +resolve worker, meaning phylink never calls the mac_link_up() nor +mac_link_down() methods. + +eth0 also sees no traffic received, and is unable to obtain a DHCP +address: + +3: eth0: mtu 1500 qdisc mq state UP group defa +ult qlen 1000 + link/ether e6:d3:6a:e6:92:de brd ff:ff:ff:ff:ff:ff + RX: bytes packets errors dropped overrun mcast + 0 0 0 0 0 0 + TX: bytes packets errors dropped carrier collsns + 27686 149 0 0 0 0 + +With the STMMAC_FLAG_HAS_INTEGRATED_PCS flag set, which disables the +netif_carrier_*() manipulation then stmmac works normally: + +dwc-eth-dwmac 2490000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0 +dwc-eth-dwmac 2490000.ethernet eth0: PHY [stmmac-0:00] driver [RTL8211F Gigabit Ethernet] (irq=141) +dwc-eth-dwmac 2490000.ethernet eth0: No Safety Features support found +dwc-eth-dwmac 2490000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported +dwc-eth-dwmac 2490000.ethernet eth0: registered PTP clock +dwc-eth-dwmac 2490000.ethernet eth0: configuring for phy/rgmii-id link mode +8021q: adding VLAN 0 to HW filter on device eth0 +dwc-eth-dwmac 2490000.ethernet eth0: Adding VLAN ID 0 is not supported +Link is Up - 1000/Full +dwc-eth-dwmac 2490000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx + +and packets can be transferred. + +This clearly shows that when priv->hw->pcs is set, but +STMMAC_FLAG_HAS_INTEGRATED_PCS is clear, the driver reliably fails. + +Discovering whether a platform falls into this is impossible as +parsing all the dtsi and dts files to find out which use the stmmac +driver, whether any of them use RGMII or SGMII and also depends +whether an external interface is being used. The kernel likely +doesn't contain all dts files either. + +The only driver that sets this flag uses the qcom,sa8775p-ethqos +compatible, and uses SGMII or 2500BASE-X. + +but these are saved from this problem by the incorrect check for +priv->dma_cap.pcs. + +So, we have to assume that for every other platform that uses SGMII +with stmmac is using an external PCS. + +Moreover, ethtool output can be incorrect. With the full-duplex link +negotiated, ethtool reports: + + Speed: 1000Mb/s + Duplex: Half + +because with dwmac4, the full-duplex bit is in bit 16 of the status, +priv->xstats.pcs_duplex becomes BIT(16) for full duplex, but the +ethtool ksettings duplex member is u8 - so becomes zero. Moreover, +the supported, advertised and link partner modes are all "not +reported". + +Finally, ksettings_set() won't be able to set the advertisement on +a PHY if this PCS code is activated, which is incorrect when SGMII +is used with a PHY. + +Thus, remove: +1. the incorrect netif_carrier_*() manipulation. +2. the broken ethtool ksettings code. + +Given that all uses of STMMAC_FLAG_HAS_INTEGRATED_PCS are now gone, +remove the flag from stmmac.h and dwmac-qcom-ethqos.c. + +Reviewed-by: Andrew Lunn +Signed-off-by: Russell King (Oracle) +Tested-by: Maxime Chevallier +Tested-by: Lad Prabhakar +Link: https://patch.msgid.link/E1v9P5y-0000000AolC-1QWH@rmk-PC.armlinux.org.uk +Signed-off-by: Jakub Kicinski +Stable-dep-of: babab1b42ed6 ("net: stmmac: fix oops when split header is enabled") +Signed-off-by: Sasha Levin +--- + .../stmicro/stmmac/dwmac-qcom-ethqos.c | 4 -- + .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 55 ------------------- + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 9 --- + include/linux/stmmac.h | 1 - + 4 files changed, 69 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +index d8fd4d8f6ced7..f62825220cf70 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +@@ -96,7 +96,6 @@ struct ethqos_emac_driver_data { + bool rgmii_config_loopback_en; + bool has_emac_ge_3; + const char *link_clk_name; +- bool has_integrated_pcs; + u32 dma_addr_width; + struct dwmac4_addrs dwmac4_addrs; + bool needs_sgmii_loopback; +@@ -282,7 +281,6 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = { + .rgmii_config_loopback_en = false, + .has_emac_ge_3 = true, + .link_clk_name = "phyaux", +- .has_integrated_pcs = true, + .needs_sgmii_loopback = true, + .dma_addr_width = 36, + .dwmac4_addrs = { +@@ -856,8 +854,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev) + plat_dat->flags |= STMMAC_FLAG_TSO_EN; + if (of_device_is_compatible(np, "qcom,qcs404-ethqos")) + plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI; +- if (data->has_integrated_pcs) +- plat_dat->flags |= STMMAC_FLAG_HAS_INTEGRATED_PCS; + if (data->dma_addr_width) + plat_dat->host_dma_width = data->dma_addr_width; + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +index 39fa1ec92f82f..d89662b48087e 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +@@ -322,47 +322,6 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev, + { + struct stmmac_priv *priv = netdev_priv(dev); + +- if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) && +- (priv->hw->pcs & STMMAC_PCS_RGMII || +- priv->hw->pcs & STMMAC_PCS_SGMII)) { +- u32 supported, advertising, lp_advertising; +- +- if (!priv->xstats.pcs_link) { +- cmd->base.speed = SPEED_UNKNOWN; +- cmd->base.duplex = DUPLEX_UNKNOWN; +- return 0; +- } +- cmd->base.duplex = priv->xstats.pcs_duplex; +- +- cmd->base.speed = priv->xstats.pcs_speed; +- +- /* Encoding of PSE bits is defined in 802.3z, 37.2.1.4 */ +- +- ethtool_convert_link_mode_to_legacy_u32( +- &supported, cmd->link_modes.supported); +- ethtool_convert_link_mode_to_legacy_u32( +- &advertising, cmd->link_modes.advertising); +- ethtool_convert_link_mode_to_legacy_u32( +- &lp_advertising, cmd->link_modes.lp_advertising); +- +- /* Reg49[3] always set because ANE is always supported */ +- cmd->base.autoneg = ADVERTISED_Autoneg; +- supported |= SUPPORTED_Autoneg; +- advertising |= ADVERTISED_Autoneg; +- lp_advertising |= ADVERTISED_Autoneg; +- +- cmd->base.port = PORT_OTHER; +- +- ethtool_convert_legacy_u32_to_link_mode( +- cmd->link_modes.supported, supported); +- ethtool_convert_legacy_u32_to_link_mode( +- cmd->link_modes.advertising, advertising); +- ethtool_convert_legacy_u32_to_link_mode( +- cmd->link_modes.lp_advertising, lp_advertising); +- +- return 0; +- } +- + return phylink_ethtool_ksettings_get(priv->phylink, cmd); + } + +@@ -372,20 +331,6 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev, + { + struct stmmac_priv *priv = netdev_priv(dev); + +- if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) && +- (priv->hw->pcs & STMMAC_PCS_RGMII || +- priv->hw->pcs & STMMAC_PCS_SGMII)) { +- /* Only support ANE */ +- if (cmd->base.autoneg != AUTONEG_ENABLE) +- return -EINVAL; +- +- mutex_lock(&priv->lock); +- stmmac_pcs_ctrl_ane(priv, 1, priv->hw->ps, 0); +- mutex_unlock(&priv->lock); +- +- return 0; +- } +- + return phylink_ethtool_ksettings_set(priv->phylink, cmd); + } + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 0dd17179c85d2..e707abc35e2de 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -6012,15 +6012,6 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv) + for (queue = 0; queue < queues_count; queue++) + stmmac_host_mtl_irq_status(priv, priv->hw, queue); + +- /* PCS link status */ +- if (priv->hw->pcs && +- !(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS)) { +- if (priv->xstats.pcs_link) +- netif_carrier_on(priv->dev); +- else +- netif_carrier_off(priv->dev); +- } +- + stmmac_timestamp_interrupt(priv, priv); + } + } +diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h +index fa1318bac06c4..99022620457ac 100644 +--- a/include/linux/stmmac.h ++++ b/include/linux/stmmac.h +@@ -171,7 +171,6 @@ struct dwmac4_addrs { + u32 mtl_low_cred_offset; + }; + +-#define STMMAC_FLAG_HAS_INTEGRATED_PCS BIT(0) + #define STMMAC_FLAG_SPH_DISABLE BIT(1) + #define STMMAC_FLAG_USE_PHY_WOL BIT(2) + #define STMMAC_FLAG_HAS_SUN8I BIT(3) +-- +2.51.0 + diff --git a/queue-6.18/net-stmmac-replace-has_xxxx-with-core_type.patch b/queue-6.18/net-stmmac-replace-has_xxxx-with-core_type.patch new file mode 100644 index 0000000000..aecc688d3d --- /dev/null +++ b/queue-6.18/net-stmmac-replace-has_xxxx-with-core_type.patch @@ -0,0 +1,804 @@ +From 1a46e2ea67033834f4dab91215980f3221ab92fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 08:26:49 +0100 +Subject: net: stmmac: replace has_xxxx with core_type + +From: Russell King (Oracle) + +[ Upstream commit 26ab9830beabda863766be4a79dc590c7645f4d9 ] + +Replace the has_gmac, has_gmac4 and has_xgmac ints, of which only one +can be set when matching a core to its driver backend, with an +enumerated type carrying the DWMAC core type. + +Tested-by: Maxime Chevallier +Signed-off-by: Russell King (Oracle) +Acked-by: Chen-Yu Tsai +Reviewed-by: Maxime Chevallier +Tested-by: Mohd Ayaan Anwar +Reviewed-by: Bartosz Golaszewski +Link: https://patch.msgid.link/E1vB6ld-0000000BIPy-2Qi4@rmk-PC.armlinux.org.uk +Signed-off-by: Jakub Kicinski +Stable-dep-of: babab1b42ed6 ("net: stmmac: fix oops when split header is enabled") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/common.h | 5 ++ + .../stmicro/stmmac/dwmac-dwc-qos-eth.c | 2 +- + .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 5 +- + .../ethernet/stmicro/stmmac/dwmac-ipq806x.c | 2 +- + .../ethernet/stmicro/stmmac/dwmac-loongson.c | 2 +- + .../ethernet/stmicro/stmmac/dwmac-lpc18xx.c | 2 +- + .../stmicro/stmmac/dwmac-qcom-ethqos.c | 2 +- + .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 4 +- + .../net/ethernet/stmicro/stmmac/dwmac-s32.c | 2 +- + .../ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 +- + .../net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 2 +- + .../net/ethernet/stmicro/stmmac/dwmac-tegra.c | 2 +- + drivers/net/ethernet/stmicro/stmmac/hwif.c | 73 +++++++------------ + .../net/ethernet/stmicro/stmmac/stmmac_est.c | 4 +- + .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 13 ++-- + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 34 +++++---- + .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 14 ++-- + .../net/ethernet/stmicro/stmmac/stmmac_pci.c | 4 +- + .../ethernet/stmicro/stmmac/stmmac_platform.c | 9 +-- + .../net/ethernet/stmicro/stmmac/stmmac_ptp.c | 4 +- + include/linux/stmmac.h | 11 ++- + 21 files changed, 94 insertions(+), 104 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h +index 8f34c9ad457f0..23ec3a59ca8f1 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/common.h ++++ b/drivers/net/ethernet/stmicro/stmmac/common.h +@@ -43,6 +43,11 @@ + #define DWXGMAC_ID 0x76 + #define DWXLGMAC_ID 0x27 + ++static inline bool dwmac_is_xmac(enum dwmac_core_type core_type) ++{ ++ return core_type == DWMAC_CORE_GMAC4 || core_type == DWMAC_CORE_XGMAC; ++} ++ + #define STMMAC_CHAN0 0 /* Always supported and default for all chips */ + + /* TX and RX Descriptor Length, these need to be power of two. +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +index e8539cad4602e..1d30f2fb984f1 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +@@ -109,7 +109,7 @@ static int dwc_eth_dwmac_config_dt(struct platform_device *pdev, + } + + /* dwc-qos needs GMAC4, AAL, TSO and PMT */ +- plat_dat->has_gmac4 = 1; ++ plat_dat->core_type = DWMAC_CORE_GMAC4; + plat_dat->dma_cfg->aal = 1; + plat_dat->flags |= STMMAC_FLAG_TSO_EN; + plat_dat->pmt = 1; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +index e74d00984b889..b2194e414ec1f 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +@@ -565,7 +565,7 @@ static void common_default_data(struct plat_stmmacenet_data *plat) + { + /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ + plat->clk_csr = STMMAC_CSR_20_35M; +- plat->has_gmac = 1; ++ plat->core_type = DWMAC_CORE_GMAC; + plat->force_sf_dma_mode = 1; + + plat->mdio_bus_data->needs_reset = true; +@@ -612,8 +612,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, + plat->pdev = pdev; + plat->phy_addr = -1; + plat->clk_csr = STMMAC_CSR_250_300M; +- plat->has_gmac = 0; +- plat->has_gmac4 = 1; ++ plat->core_type = DWMAC_CORE_GMAC4; + plat->force_sf_dma_mode = 0; + plat->flags |= (STMMAC_FLAG_TSO_EN | STMMAC_FLAG_SPH_DISABLE); + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c +index ca4035cbb55b6..c05f85534f0ca 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c +@@ -473,7 +473,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev) + return err; + } + +- plat_dat->has_gmac = true; ++ plat_dat->core_type = DWMAC_CORE_GMAC; + plat_dat->bsp_priv = gmac; + plat_dat->set_clk_tx_rate = ipq806x_gmac_set_clk_tx_rate; + plat_dat->multicast_filter_bins = 0; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +index 592aa9d636e50..2a3ac0136cdbc 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +@@ -92,7 +92,7 @@ static void loongson_default_data(struct pci_dev *pdev, + + /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ + plat->clk_csr = STMMAC_CSR_20_35M; +- plat->has_gmac = 1; ++ plat->core_type = DWMAC_CORE_GMAC; + plat->force_sf_dma_mode = 1; + + /* Set default value for multicast hash bins */ +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c +index 2562a6d036a2a..6fffc9dfbae55 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c +@@ -41,7 +41,7 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev) + if (IS_ERR(plat_dat)) + return PTR_ERR(plat_dat); + +- plat_dat->has_gmac = true; ++ plat_dat->core_type = DWMAC_CORE_GMAC; + + reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg"); + if (IS_ERR(reg)) { +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +index f62825220cf70..74c208dd86519 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +@@ -846,7 +846,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) + plat_dat->fix_mac_speed = ethqos_fix_mac_speed; + plat_dat->dump_debug_regs = rgmii_dump; + plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config; +- plat_dat->has_gmac4 = 1; ++ plat_dat->core_type = DWMAC_CORE_GMAC4; + if (ethqos->has_emac_ge_3) + plat_dat->dwmac4_addrs = &data->dwmac4_addrs; + plat_dat->pmt = 1; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +index 0786816e05f04..643578266dfca 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +@@ -1751,8 +1751,8 @@ static int rk_gmac_probe(struct platform_device *pdev) + /* If the stmmac is not already selected as gmac4, + * then make sure we fallback to gmac. + */ +- if (!plat_dat->has_gmac4) { +- plat_dat->has_gmac = true; ++ if (plat_dat->core_type != DWMAC_CORE_GMAC4) { ++ plat_dat->core_type = DWMAC_CORE_GMAC; + plat_dat->rx_fifo_size = 4096; + plat_dat->tx_fifo_size = 2048; + } +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c +index 221539d760bc8..ee095ac132037 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c +@@ -146,7 +146,7 @@ static int s32_dwmac_probe(struct platform_device *pdev) + gmac->ioaddr = res.addr; + + /* S32CC core feature set */ +- plat->has_gmac4 = true; ++ plat->core_type = DWMAC_CORE_GMAC4; + plat->pmt = 1; + plat->flags |= STMMAC_FLAG_SPH_DISABLE; + plat->rx_fifo_size = 20480; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +index 354f01184e6cc..2ff5db6d41ca0 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +@@ -497,7 +497,7 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) + plat_dat->pcs_init = socfpga_dwmac_pcs_init; + plat_dat->pcs_exit = socfpga_dwmac_pcs_exit; + plat_dat->select_pcs = socfpga_dwmac_select_pcs; +- plat_dat->has_gmac = true; ++ plat_dat->core_type = DWMAC_CORE_GMAC; + + plat_dat->riwt_off = 1; + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c +index 1eadcf5d1ad63..7f560d78209d1 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c +@@ -136,7 +136,7 @@ static int sun7i_gmac_probe(struct platform_device *pdev) + /* platform data specifying hardware features and callbacks. + * hardware features were copied from Allwinner drivers. */ + plat_dat->tx_coe = 1; +- plat_dat->has_gmac = true; ++ plat_dat->core_type = DWMAC_CORE_GMAC; + plat_dat->bsp_priv = gmac; + plat_dat->init = sun7i_gmac_init; + plat_dat->exit = sun7i_gmac_exit; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c +index dc903b846b1bf..d765acbe37548 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c +@@ -308,7 +308,7 @@ static int tegra_mgbe_probe(struct platform_device *pdev) + goto disable_clks; + } + +- plat->has_xgmac = 1; ++ plat->core_type = DWMAC_CORE_XGMAC; + plat->flags |= STMMAC_FLAG_TSO_EN; + plat->pmt = 1; + plat->bsp_priv = mgbe; +diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c +index 3f7c765dcb797..00083ce525492 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c ++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c +@@ -106,9 +106,7 @@ int stmmac_reset(struct stmmac_priv *priv, void __iomem *ioaddr) + } + + static const struct stmmac_hwif_entry { +- bool gmac; +- bool gmac4; +- bool xgmac; ++ enum dwmac_core_type core_type; + u32 min_id; + u32 dev_id; + const struct stmmac_regs_off regs; +@@ -127,9 +125,7 @@ static const struct stmmac_hwif_entry { + } stmmac_hw[] = { + /* NOTE: New HW versions shall go to the end of this table */ + { +- .gmac = false, +- .gmac4 = false, +- .xgmac = false, ++ .core_type = DWMAC_CORE_MAC100, + .min_id = 0, + .regs = { + .ptp_off = PTP_GMAC3_X_OFFSET, +@@ -146,9 +142,7 @@ static const struct stmmac_hwif_entry { + .setup = dwmac100_setup, + .quirks = stmmac_dwmac1_quirks, + }, { +- .gmac = true, +- .gmac4 = false, +- .xgmac = false, ++ .core_type = DWMAC_CORE_GMAC, + .min_id = 0, + .regs = { + .ptp_off = PTP_GMAC3_X_OFFSET, +@@ -165,9 +159,7 @@ static const struct stmmac_hwif_entry { + .setup = dwmac1000_setup, + .quirks = stmmac_dwmac1_quirks, + }, { +- .gmac = false, +- .gmac4 = true, +- .xgmac = false, ++ .core_type = DWMAC_CORE_GMAC4, + .min_id = 0, + .regs = { + .ptp_off = PTP_GMAC4_OFFSET, +@@ -187,9 +179,7 @@ static const struct stmmac_hwif_entry { + .setup = dwmac4_setup, + .quirks = stmmac_dwmac4_quirks, + }, { +- .gmac = false, +- .gmac4 = true, +- .xgmac = false, ++ .core_type = DWMAC_CORE_GMAC4, + .min_id = DWMAC_CORE_4_00, + .regs = { + .ptp_off = PTP_GMAC4_OFFSET, +@@ -210,9 +200,7 @@ static const struct stmmac_hwif_entry { + .setup = dwmac4_setup, + .quirks = NULL, + }, { +- .gmac = false, +- .gmac4 = true, +- .xgmac = false, ++ .core_type = DWMAC_CORE_GMAC4, + .min_id = DWMAC_CORE_4_10, + .regs = { + .ptp_off = PTP_GMAC4_OFFSET, +@@ -233,9 +221,7 @@ static const struct stmmac_hwif_entry { + .setup = dwmac4_setup, + .quirks = NULL, + }, { +- .gmac = false, +- .gmac4 = true, +- .xgmac = false, ++ .core_type = DWMAC_CORE_GMAC4, + .min_id = DWMAC_CORE_5_10, + .regs = { + .ptp_off = PTP_GMAC4_OFFSET, +@@ -256,9 +242,7 @@ static const struct stmmac_hwif_entry { + .setup = dwmac4_setup, + .quirks = NULL, + }, { +- .gmac = false, +- .gmac4 = false, +- .xgmac = true, ++ .core_type = DWMAC_CORE_XGMAC, + .min_id = DWXGMAC_CORE_2_10, + .dev_id = DWXGMAC_ID, + .regs = { +@@ -280,9 +264,7 @@ static const struct stmmac_hwif_entry { + .setup = dwxgmac2_setup, + .quirks = NULL, + }, { +- .gmac = false, +- .gmac4 = false, +- .xgmac = true, ++ .core_type = DWMAC_CORE_XGMAC, + .min_id = DWXLGMAC_CORE_2_00, + .dev_id = DWXLGMAC_ID, + .regs = { +@@ -308,20 +290,18 @@ static const struct stmmac_hwif_entry { + + int stmmac_hwif_init(struct stmmac_priv *priv) + { +- bool needs_xgmac = priv->plat->has_xgmac; +- bool needs_gmac4 = priv->plat->has_gmac4; +- bool needs_gmac = priv->plat->has_gmac; ++ enum dwmac_core_type core_type = priv->plat->core_type; + const struct stmmac_hwif_entry *entry; + struct mac_device_info *mac; + bool needs_setup = true; + u32 id, dev_id = 0; + int i, ret; + +- if (needs_gmac) { ++ if (core_type == DWMAC_CORE_GMAC) { + id = stmmac_get_id(priv, GMAC_VERSION); +- } else if (needs_gmac4 || needs_xgmac) { ++ } else if (dwmac_is_xmac(core_type)) { + id = stmmac_get_id(priv, GMAC4_VERSION); +- if (needs_xgmac) ++ if (core_type == DWMAC_CORE_XGMAC) + dev_id = stmmac_get_dev_id(priv, GMAC4_VERSION); + } else { + id = 0; +@@ -331,14 +311,16 @@ int stmmac_hwif_init(struct stmmac_priv *priv) + priv->synopsys_id = id; + + /* Lets assume some safe values first */ +- priv->ptpaddr = priv->ioaddr + +- (needs_gmac4 ? PTP_GMAC4_OFFSET : PTP_GMAC3_X_OFFSET); +- priv->mmcaddr = priv->ioaddr + +- (needs_gmac4 ? MMC_GMAC4_OFFSET : MMC_GMAC3_X_OFFSET); +- if (needs_gmac4) ++ if (core_type == DWMAC_CORE_GMAC4) { ++ priv->ptpaddr = priv->ioaddr + PTP_GMAC4_OFFSET; ++ priv->mmcaddr = priv->ioaddr + MMC_GMAC4_OFFSET; + priv->estaddr = priv->ioaddr + EST_GMAC4_OFFSET; +- else if (needs_xgmac) +- priv->estaddr = priv->ioaddr + EST_XGMAC_OFFSET; ++ } else { ++ priv->ptpaddr = priv->ioaddr + PTP_GMAC3_X_OFFSET; ++ priv->mmcaddr = priv->ioaddr + MMC_GMAC3_X_OFFSET; ++ if (core_type == DWMAC_CORE_XGMAC) ++ priv->estaddr = priv->ioaddr + EST_XGMAC_OFFSET; ++ } + + /* Check for HW specific setup first */ + if (priv->plat->setup) { +@@ -355,16 +337,12 @@ int stmmac_hwif_init(struct stmmac_priv *priv) + for (i = ARRAY_SIZE(stmmac_hw) - 1; i >= 0; i--) { + entry = &stmmac_hw[i]; + +- if (needs_gmac ^ entry->gmac) +- continue; +- if (needs_gmac4 ^ entry->gmac4) +- continue; +- if (needs_xgmac ^ entry->xgmac) ++ if (core_type != entry->core_type) + continue; + /* Use synopsys_id var because some setups can override this */ + if (priv->synopsys_id < entry->min_id) + continue; +- if (needs_xgmac && (dev_id ^ entry->dev_id)) ++ if (core_type == DWMAC_CORE_XGMAC && (dev_id ^ entry->dev_id)) + continue; + + /* Only use generic HW helpers if needed */ +@@ -400,6 +378,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv) + } + + dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n", +- id, needs_gmac, needs_gmac4); ++ id, core_type == DWMAC_CORE_GMAC, ++ core_type == DWMAC_CORE_GMAC4); + return -EINVAL; + } +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c +index 4b513d27a9889..afc516059b897 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c +@@ -53,7 +53,7 @@ static int est_configure(struct stmmac_priv *priv, struct stmmac_est *cfg, + } + + ctrl = readl(est_addr + EST_CONTROL); +- if (priv->plat->has_xgmac) { ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) { + ctrl &= ~EST_XGMAC_PTOV; + ctrl |= ((NSEC_PER_SEC / ptp_rate) * EST_XGMAC_PTOV_MUL) << + EST_XGMAC_PTOV_SHIFT; +@@ -148,7 +148,7 @@ static void est_irq_status(struct stmmac_priv *priv, struct net_device *dev, + } + + if (status & EST_BTRE) { +- if (priv->plat->has_xgmac) { ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) { + btrl = FIELD_GET(EST_XGMAC_BTRL, status); + btrl_max = FIELD_MAX(EST_XGMAC_BTRL); + } else { +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +index d89662b48087e..81d4039e1c082 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +@@ -303,9 +303,10 @@ static void stmmac_ethtool_getdrvinfo(struct net_device *dev, + { + struct stmmac_priv *priv = netdev_priv(dev); + +- if (priv->plat->has_gmac || priv->plat->has_gmac4) ++ if (priv->plat->core_type == DWMAC_CORE_GMAC || ++ priv->plat->core_type == DWMAC_CORE_GMAC4) + strscpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver)); +- else if (priv->plat->has_xgmac) ++ else if (priv->plat->core_type == DWMAC_CORE_XGMAC) + strscpy(info->driver, XGMAC_ETHTOOL_NAME, sizeof(info->driver)); + else + strscpy(info->driver, MAC100_ETHTOOL_NAME, +@@ -351,9 +352,9 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev) + { + struct stmmac_priv *priv = netdev_priv(dev); + +- if (priv->plat->has_xgmac) ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) + return XGMAC_REGSIZE * 4; +- else if (priv->plat->has_gmac4) ++ else if (priv->plat->core_type == DWMAC_CORE_GMAC4) + return GMAC4_REG_SPACE_SIZE; + return REG_SPACE_SIZE; + } +@@ -368,12 +369,12 @@ static void stmmac_ethtool_gregs(struct net_device *dev, + stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space); + + /* Copy DMA registers to where ethtool expects them */ +- if (priv->plat->has_gmac4) { ++ if (priv->plat->core_type == DWMAC_CORE_GMAC4) { + /* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */ + memcpy(®_space[ETHTOOL_DMA_OFFSET], + ®_space[GMAC4_DMA_CHAN_BASE_ADDR / 4], + NUM_DWMAC4_DMA_REGS * 4); +- } else if (!priv->plat->has_xgmac) { ++ } else if (priv->plat->core_type != DWMAC_CORE_XGMAC) { + memcpy(®_space[ETHTOOL_DMA_OFFSET], + ®_space[DMA_BUS_MODE / 4], + NUM_DWMAC1000_DMA_REGS * 4); +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index e707abc35e2de..a38976c65149c 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -446,7 +446,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, + if (!priv->hwts_rx_en) + return; + /* For GMAC4, the valid timestamp is from CTX next desc. */ +- if (priv->plat->has_gmac4 || priv->plat->has_xgmac) ++ if (dwmac_is_xmac(priv->plat->core_type)) + desc = np; + + /* Check if timestamp is available */ +@@ -697,7 +697,7 @@ static int stmmac_hwtstamp_get(struct net_device *dev, + static int stmmac_init_tstamp_counter(struct stmmac_priv *priv, + u32 systime_flags) + { +- bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; ++ bool xmac = dwmac_is_xmac(priv->plat->core_type); + struct timespec64 now; + u32 sec_inc = 0; + u64 temp = 0; +@@ -746,7 +746,7 @@ static int stmmac_init_tstamp_counter(struct stmmac_priv *priv, + */ + static int stmmac_init_timestamping(struct stmmac_priv *priv) + { +- bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; ++ bool xmac = dwmac_is_xmac(priv->plat->core_type); + int ret; + + if (priv->plat->ptp_clk_freq_config) +@@ -2398,7 +2398,7 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) + txfifosz = priv->dma_cap.tx_fifo_size; + + /* Split up the shared Tx/Rx FIFO memory on DW QoS Eth and DW XGMAC */ +- if (priv->plat->has_gmac4 || priv->plat->has_xgmac) { ++ if (dwmac_is_xmac(priv->plat->core_type)) { + rxfifosz /= rx_channels_count; + txfifosz /= tx_channels_count; + } +@@ -4514,7 +4514,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) + if (skb_is_gso(skb) && priv->tso) { + if (gso & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) + return stmmac_tso_xmit(skb, dev); +- if (priv->plat->has_gmac4 && (gso & SKB_GSO_UDP_L4)) ++ if (priv->plat->core_type == DWMAC_CORE_GMAC4 && ++ (gso & SKB_GSO_UDP_L4)) + return stmmac_tso_xmit(skb, dev); + } + +@@ -5984,7 +5985,7 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv) + u32 queue; + bool xmac; + +- xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; ++ xmac = dwmac_is_xmac(priv->plat->core_type); + queues_count = (rx_cnt > tx_cnt) ? rx_cnt : tx_cnt; + + if (priv->irq_wake) +@@ -5998,7 +5999,7 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv) + stmmac_fpe_irq_status(priv); + + /* To handle GMAC own interrupts */ +- if ((priv->plat->has_gmac) || xmac) { ++ if (priv->plat->core_type == DWMAC_CORE_GMAC || xmac) { + int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats); + + if (unlikely(status)) { +@@ -6359,7 +6360,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) + (priv->dma_cap.mbps_1000) ? "Y" : "N"); + seq_printf(seq, "\tHalf duplex: %s\n", + (priv->dma_cap.half_duplex) ? "Y" : "N"); +- if (priv->plat->has_xgmac) { ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) { + seq_printf(seq, + "\tNumber of Additional MAC address registers: %d\n", + priv->dma_cap.multi_addr); +@@ -6383,7 +6384,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) + (priv->dma_cap.time_stamp) ? "Y" : "N"); + seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp: %s\n", + (priv->dma_cap.atime_stamp) ? "Y" : "N"); +- if (priv->plat->has_xgmac) ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) + seq_printf(seq, "\tTimestamp System Time Source: %s\n", + dwxgmac_timestamp_source[priv->dma_cap.tssrc]); + seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE): %s\n", +@@ -6392,7 +6393,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) + seq_printf(seq, "\tChecksum Offload in TX: %s\n", + (priv->dma_cap.tx_coe) ? "Y" : "N"); + if (priv->synopsys_id >= DWMAC_CORE_4_00 || +- priv->plat->has_xgmac) { ++ priv->plat->core_type == DWMAC_CORE_XGMAC) { + seq_printf(seq, "\tIP Checksum Offload in RX: %s\n", + (priv->dma_cap.rx_coe) ? "Y" : "N"); + } else { +@@ -7244,8 +7245,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv) + * has to be disable and this can be done by passing the + * riwt_off field from the platform. + */ +- if (((priv->synopsys_id >= DWMAC_CORE_3_50) || +- (priv->plat->has_xgmac)) && (!priv->plat->riwt_off)) { ++ if ((priv->synopsys_id >= DWMAC_CORE_3_50 || ++ priv->plat->core_type == DWMAC_CORE_XGMAC) && ++ !priv->plat->riwt_off) { + priv->use_riwt = 1; + dev_info(priv->device, + "Enable RX Mitigation via HW Watchdog Timer\n"); +@@ -7359,7 +7361,7 @@ static int stmmac_xdp_rx_timestamp(const struct xdp_md *_ctx, u64 *timestamp) + return -ENODATA; + + /* For GMAC4, the valid timestamp is from CTX next desc. */ +- if (priv->plat->has_gmac4 || priv->plat->has_xgmac) ++ if (dwmac_is_xmac(priv->plat->core_type)) + desc_contains_ts = ndesc; + + /* Check if timestamp is available */ +@@ -7515,7 +7517,7 @@ int stmmac_dvr_probe(struct device *device, + + if ((priv->plat->flags & STMMAC_FLAG_TSO_EN) && (priv->dma_cap.tsoen)) { + ndev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6; +- if (priv->plat->has_gmac4) ++ if (priv->plat->core_type == DWMAC_CORE_GMAC4) + ndev->hw_features |= NETIF_F_GSO_UDP_L4; + priv->tso = true; + dev_info(priv->device, "TSO feature enabled\n"); +@@ -7568,7 +7570,7 @@ int stmmac_dvr_probe(struct device *device, + #ifdef STMMAC_VLAN_TAG_USED + /* Both mac100 and gmac support receive VLAN tag detection */ + ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX; +- if (priv->plat->has_gmac4 || priv->plat->has_xgmac) { ++ if (dwmac_is_xmac(priv->plat->core_type)) { + ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX; + priv->hw->hw_vlan_en = true; + } +@@ -7596,7 +7598,7 @@ int stmmac_dvr_probe(struct device *device, + + /* MTU range: 46 - hw-specific max */ + ndev->min_mtu = ETH_ZLEN - ETH_HLEN; +- if (priv->plat->has_xgmac) ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) + ndev->max_mtu = XGMAC_JUMBO_LEN; + else if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00)) + ndev->max_mtu = JUMBO_LEN; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +index f408737f6fc73..2b55b02de380d 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +@@ -301,7 +301,7 @@ static int stmmac_mdio_read_c22(struct mii_bus *bus, int phyaddr, int phyreg) + struct stmmac_priv *priv = netdev_priv(bus->priv); + u32 cmd; + +- if (priv->plat->has_gmac4) ++ if (priv->plat->core_type == DWMAC_CORE_GMAC4) + cmd = MII_GMAC4_READ; + else + cmd = 0; +@@ -344,7 +344,7 @@ static int stmmac_mdio_write_c22(struct mii_bus *bus, int phyaddr, int phyreg, + struct stmmac_priv *priv = netdev_priv(bus->priv); + u32 cmd; + +- if (priv->plat->has_gmac4) ++ if (priv->plat->core_type == DWMAC_CORE_GMAC4) + cmd = MII_GMAC4_WRITE; + else + cmd = MII_ADDR_GWRITE; +@@ -417,7 +417,7 @@ int stmmac_mdio_reset(struct mii_bus *bus) + * on MDC, so perform a dummy mdio read. To be updated for GMAC4 + * if needed. + */ +- if (!priv->plat->has_gmac4) ++ if (priv->plat->core_type != DWMAC_CORE_GMAC4) + writel(0, priv->ioaddr + mii_address); + #endif + return 0; +@@ -528,7 +528,7 @@ static u32 stmmac_clk_csr_set(struct stmmac_priv *priv) + value = 0; + } + +- if (priv->plat->has_xgmac) { ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) { + if (clk_rate > 400000000) + value = 0x5; + else if (clk_rate > 350000000) +@@ -600,7 +600,7 @@ int stmmac_mdio_register(struct net_device *ndev) + + new_bus->name = "stmmac"; + +- if (priv->plat->has_xgmac) { ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) { + new_bus->read = &stmmac_xgmac2_mdio_read_c22; + new_bus->write = &stmmac_xgmac2_mdio_write_c22; + new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45; +@@ -621,7 +621,7 @@ int stmmac_mdio_register(struct net_device *ndev) + } else { + new_bus->read = &stmmac_mdio_read_c22; + new_bus->write = &stmmac_mdio_write_c22; +- if (priv->plat->has_gmac4) { ++ if (priv->plat->core_type == DWMAC_CORE_GMAC4) { + new_bus->read_c45 = &stmmac_mdio_read_c45; + new_bus->write_c45 = &stmmac_mdio_write_c45; + } +@@ -649,7 +649,7 @@ int stmmac_mdio_register(struct net_device *ndev) + } + + /* Looks like we need a dummy read for XGMAC only and C45 PHYs */ +- if (priv->plat->has_xgmac) ++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) + stmmac_xgmac2_mdio_read_c45(new_bus, 0, 0, 0); + + /* If fixed-link is set, skip PHY scanning */ +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +index 4e3aa611fda83..94b3a3b272706 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +@@ -23,7 +23,7 @@ static void common_default_data(struct plat_stmmacenet_data *plat) + { + /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ + plat->clk_csr = STMMAC_CSR_20_35M; +- plat->has_gmac = 1; ++ plat->core_type = DWMAC_CORE_GMAC; + plat->force_sf_dma_mode = 1; + + plat->mdio_bus_data->needs_reset = true; +@@ -76,7 +76,7 @@ static int snps_gmac5_default_data(struct pci_dev *pdev, + int i; + + plat->clk_csr = STMMAC_CSR_250_300M; +- plat->has_gmac4 = 1; ++ plat->core_type = DWMAC_CORE_GMAC4; + plat->force_sf_dma_mode = 1; + plat->flags |= STMMAC_FLAG_TSO_EN; + plat->pmt = 1; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +index 27bcaae07a7f2..fbb92cc6ab598 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +@@ -552,12 +552,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + &pdev->dev, plat->unicast_filter_entries); + plat->multicast_filter_bins = dwmac1000_validate_mcast_bins( + &pdev->dev, plat->multicast_filter_bins); +- plat->has_gmac = 1; ++ plat->core_type = DWMAC_CORE_GMAC; + plat->pmt = 1; + } + + if (of_device_is_compatible(np, "snps,dwmac-3.40a")) { +- plat->has_gmac = 1; ++ plat->core_type = DWMAC_CORE_GMAC; + plat->enh_desc = 1; + plat->tx_coe = 1; + plat->bugged_jumbo = 1; +@@ -565,8 +565,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + } + + if (of_device_compatible_match(np, stmmac_gmac4_compats)) { +- plat->has_gmac4 = 1; +- plat->has_gmac = 0; ++ plat->core_type = DWMAC_CORE_GMAC4; + plat->pmt = 1; + if (of_property_read_bool(np, "snps,tso")) + plat->flags |= STMMAC_FLAG_TSO_EN; +@@ -580,7 +579,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + } + + if (of_device_is_compatible(np, "snps,dwxgmac")) { +- plat->has_xgmac = 1; ++ plat->core_type = DWMAC_CORE_XGMAC; + plat->pmt = 1; + if (of_property_read_bool(np, "snps,tso")) + plat->flags |= STMMAC_FLAG_TSO_EN; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +index 993ff4e87e557..3e30172fa1294 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +@@ -57,7 +57,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta) + bool xmac, est_rst = false; + int ret; + +- xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; ++ xmac = dwmac_is_xmac(priv->plat->core_type); + + if (delta < 0) { + neg_adj = 1; +@@ -344,7 +344,7 @@ void stmmac_ptp_register(struct stmmac_priv *priv) + + /* Calculate the clock domain crossing (CDC) error if necessary */ + priv->plat->cdc_error_adj = 0; +- if (priv->plat->has_gmac4) ++ if (priv->plat->core_type == DWMAC_CORE_GMAC4) + priv->plat->cdc_error_adj = (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate; + + /* Update the ptp clock parameters based on feature discovery, when +diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h +index 99022620457ac..151c81c560c8c 100644 +--- a/include/linux/stmmac.h ++++ b/include/linux/stmmac.h +@@ -171,6 +171,13 @@ struct dwmac4_addrs { + u32 mtl_low_cred_offset; + }; + ++enum dwmac_core_type { ++ DWMAC_CORE_MAC100, ++ DWMAC_CORE_GMAC, ++ DWMAC_CORE_GMAC4, ++ DWMAC_CORE_XGMAC, ++}; ++ + #define STMMAC_FLAG_SPH_DISABLE BIT(1) + #define STMMAC_FLAG_USE_PHY_WOL BIT(2) + #define STMMAC_FLAG_HAS_SUN8I BIT(3) +@@ -186,6 +193,7 @@ struct dwmac4_addrs { + #define STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY BIT(13) + + struct plat_stmmacenet_data { ++ enum dwmac_core_type core_type; + int bus_id; + int phy_addr; + /* MAC ----- optional PCS ----- SerDes ----- optional PHY ----- Media +@@ -219,7 +227,6 @@ struct plat_stmmacenet_data { + struct stmmac_dma_cfg *dma_cfg; + struct stmmac_safety_feature_cfg *safety_feat_cfg; + int clk_csr; +- int has_gmac; + int enh_desc; + int tx_coe; + int rx_coe; +@@ -282,10 +289,8 @@ struct plat_stmmacenet_data { + struct reset_control *stmmac_rst; + struct reset_control *stmmac_ahb_rst; + struct stmmac_axi *axi; +- int has_gmac4; + int rss_en; + int mac_port_sel_speed; +- int has_xgmac; + u8 vlan_fail_q; + struct pci_dev *pdev; + int int_snapshot_num; +-- +2.51.0 + diff --git a/queue-6.18/net-usb-catc-enable-basic-endpoint-checking.patch b/queue-6.18/net-usb-catc-enable-basic-endpoint-checking.patch new file mode 100644 index 0000000000..b4bbdb3e92 --- /dev/null +++ b/queue-6.18/net-usb-catc-enable-basic-endpoint-checking.patch @@ -0,0 +1,111 @@ +From 1ff0dbf09861ba5f9b5ede95dec9d3ebc7f60541 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 21:41:54 +0000 +Subject: net: usb: catc: enable basic endpoint checking + +From: Ziyi Guo + +[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ] + +catc_probe() fills three URBs with hardcoded endpoint pipes without +verifying the endpoint descriptors: + + - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX + - usb_rcvintpipe(usbdev, 2) for interrupt status + +A malformed USB device can present these endpoints with transfer types +that differ from what the driver assumes. + +Add a catc_usb_ep enum for endpoint numbers, replacing magic constants +throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints() +calls after usb_set_interface() to verify endpoint types before use, +rejecting devices with mismatched descriptors at probe time. + +Similar to +- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking") +which fixed the issue in rtl8150. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Suggested-by: Simon Horman +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c +index 6759388692f8e..3c824340ffb06 100644 +--- a/drivers/net/usb/catc.c ++++ b/drivers/net/usb/catc.c +@@ -64,6 +64,16 @@ static const char driver_name[] = "catc"; + #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ + #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ + ++/* ++ * USB endpoints. ++ */ ++ ++enum catc_usb_ep { ++ CATC_USB_EP_CONTROL = 0, ++ CATC_USB_EP_BULK = 1, ++ CATC_USB_EP_INT_IN = 2, ++}; ++ + /* + * Control requests. + */ +@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + u8 broadcast[ETH_ALEN]; + u8 *macbuf; + int pktsz, ret = -ENOMEM; ++ static const u8 bulk_ep_addr[] = { ++ CATC_USB_EP_BULK | USB_DIR_OUT, ++ CATC_USB_EP_BULK | USB_DIR_IN, ++ 0}; ++ static const u8 int_ep_addr[] = { ++ CATC_USB_EP_INT_IN | USB_DIR_IN, ++ 0}; + + macbuf = kmalloc(ETH_ALEN, GFP_KERNEL); + if (!macbuf) +@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + goto fail_mem; + } + ++ /* Verify that all required endpoints are present */ ++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || ++ !usb_check_int_endpoints(intf, int_ep_addr)) { ++ dev_err(dev, "Missing or invalid endpoints\n"); ++ ret = -ENODEV; ++ goto fail_mem; ++ } ++ + netdev = alloc_etherdev(sizeof(struct catc)); + if (!netdev) + goto fail_mem; +@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), + NULL, NULL, 0, catc_ctrl_done, catc); + +- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), +- NULL, 0, catc_tx_done, catc); ++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK), ++ NULL, 0, catc_tx_done, catc); + +- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), +- catc->rx_buf, pktsz, catc_rx_done, catc); ++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK), ++ catc->rx_buf, pktsz, catc_rx_done, catc); + +- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), +- catc->irq_buf, 2, catc_irq_done, catc, 1); ++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN), ++ catc->irq_buf, 2, catc_irq_done, catc, 1); + + if (!catc->is_f5u011) { + u32 *buf; +-- +2.51.0 + diff --git a/queue-6.18/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch b/queue-6.18/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch new file mode 100644 index 0000000000..1a92794815 --- /dev/null +++ b/queue-6.18/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch @@ -0,0 +1,58 @@ +From 6035c395e63907428a3a6a901602a17ba44bfe72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 12:53:09 +0100 +Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value + +From: Florian Westphal + +[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ] + +Mihail Milev reports: Error: UNINIT (CWE-457): + net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl: + Declaring variable "tuple" without initializer. + net/netfilter/nf_conntrack_h323_main.c:1197:2: + uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find". + net/netfilter/nf_conntrack_expect.c:142:2: + read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash". + + 1195| tuple.dst.protonum = IPPROTO_TCP; + 1196| + 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + 1198| if (exp && exp->master == ct) + 1199| return exp; + +Switch this to a C99 initialiser and set the l3num value. + +Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port") +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_h323_main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c +index 14f73872f6477..e35814d68ce30 100644 +--- a/net/netfilter/nf_conntrack_h323_main.c ++++ b/net/netfilter/nf_conntrack_h323_main.c +@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, + { + struct net *net = nf_ct_net(ct); + struct nf_conntrack_expect *exp; +- struct nf_conntrack_tuple tuple; ++ struct nf_conntrack_tuple tuple = { ++ .src.l3num = nf_ct_l3num(ct), ++ .dst.protonum = IPPROTO_TCP, ++ .dst.u.tcp.port = port, ++ }; + +- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); +- tuple.src.u.tcp.port = 0; + memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); +- tuple.dst.u.tcp.port = port; +- tuple.dst.protonum = IPPROTO_TCP; + + exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + if (exp && exp->master == ct) +-- +2.51.0 + diff --git a/queue-6.18/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch b/queue-6.18/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch new file mode 100644 index 0000000000..ff9318685b --- /dev/null +++ b/queue-6.18/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch @@ -0,0 +1,54 @@ +From da026db54ecd7e45e302425d19a34a6077b36af7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 21:14:40 +0900 +Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain() + +From: Inseo An + +[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ] + +nf_tables_addchain() publishes the chain to table->chains via +list_add_tail_rcu() (in nft_chain_add()) before registering hooks. +If nf_tables_register_hook() then fails, the error path calls +nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy() +with no RCU grace period in between. + +This creates two use-after-free conditions: + + 1) Control-plane: nf_tables_dump_chains() traverses table->chains + under rcu_read_lock(). A concurrent dump can still be walking + the chain when the error path frees it. + + 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly + installs the IPv4 hook before IPv6 registration fails. Packets + entering nft_do_chain() via the transient IPv4 hook can still be + dereferencing chain->blob_gen_X when the error path frees the + chain. + +Add synchronize_rcu() between nft_chain_del() and the chain destroy +so that all RCU readers -- both dump threads and in-flight packet +evaluation -- have finished before the chain is freed. + +Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain") +Signed-off-by: Inseo An +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 9051f2c3595a2..df367638cdef0 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2822,6 +2822,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 policy, + + err_register_hook: + nft_chain_del(chain); ++ synchronize_rcu(); + err_chain_add: + nft_trans_destroy(trans); + err_trans: +-- +2.51.0 + diff --git a/queue-6.18/objpool-fix-the-overestimation-of-object-pooling-met.patch b/queue-6.18/objpool-fix-the-overestimation-of-object-pooling-met.patch new file mode 100644 index 0000000000..8a496ed861 --- /dev/null +++ b/queue-6.18/objpool-fix-the-overestimation-of-object-pooling-met.patch @@ -0,0 +1,47 @@ +From c1de1802550dbaf1966f350e694fc0bb3cb348dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 21:28:46 +0800 +Subject: objpool: fix the overestimation of object pooling metadata size + +From: zhouwenhao + +[ Upstream commit 5ed4b6b37c647d168ae31035b3f61b705997e043 ] + +objpool uses struct objpool_head to store metadata information, and its +cpu_slots member points to an array of pointers that store the addresses +of the percpu ring arrays. However, the memory size allocated during the +initialization of cpu_slots is nr_cpu_ids * sizeof(struct objpool_slot). +On a 64-bit machine, the size of struct objpool_slot is 16 bytes, which is +twice the size of the actual pointer required, and the extra memory is +never be used, resulting in a waste of memory. Therefore, the memory size +required for cpu_slots needs to be corrected. + +Link: https://lkml.kernel.org/r/20260202132846.68257-1-zhouwenhao7600@gmail.com +Fixes: b4edb8d2d464 ("lib: objpool added: ring-array based lockless MPMC") +Signed-off-by: zhouwenhao +Reviewed-by: Andrew Morton +Cc: "Masami Hiramatsu (Google)" +Cc: Matt Wu +Cc: wuqiang.matt +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + lib/objpool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/objpool.c b/lib/objpool.c +index b998b720c7329..d98fadf1de169 100644 +--- a/lib/objpool.c ++++ b/lib/objpool.c +@@ -142,7 +142,7 @@ int objpool_init(struct objpool_head *pool, int nr_objs, int object_size, + pool->gfp = gfp & ~__GFP_ZERO; + pool->context = context; + pool->release = release; +- slot_size = nr_cpu_ids * sizeof(struct objpool_slot); ++ slot_size = nr_cpu_ids * sizeof(struct objpool_slot *); + pool->cpu_slots = kzalloc(slot_size, pool->gfp); + if (!pool->cpu_slots) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.18/octeontx2-af-fix-default-entries-mcam-entry-action.patch b/queue-6.18/octeontx2-af-fix-default-entries-mcam-entry-action.patch new file mode 100644 index 0000000000..ad30fef20d --- /dev/null +++ b/queue-6.18/octeontx2-af-fix-default-entries-mcam-entry-action.patch @@ -0,0 +1,85 @@ +From 68ed5a1ccdb8944cab6efc830cb8b41526dfb21c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:33:38 +0530 +Subject: octeontx2-af: Fix default entries mcam entry action + +From: Hariprasad Kelam + +[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ] + +As per design, AF should update the default MCAM action only when +mcam_index is -1. A bug in the previous patch caused default entries +to be changed even when the request was not for them. + +Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index") +Signed-off-by: Hariprasad Kelam +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++--------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index c7c70429eb6c1..8658cb2143dfc 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -1042,32 +1042,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, + rvu_write64(rvu, blkaddr, + NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action); + +- /* update the VF flow rule action with the VF default entry action */ +- if (mcam_index < 0) +- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, +- *(u64 *)&action); +- + /* update the action change in default rule */ + pfvf = rvu_get_pfvf(rvu, pcifunc); + if (pfvf->def_ucast_rule) + pfvf->def_ucast_rule->rx_action = action; + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_PROMISC_ENTRY); ++ if (mcam_index < 0) { ++ /* update the VF flow rule action with the VF default ++ * entry action ++ */ ++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, ++ *(u64 *)&action); + +- /* If PF's promiscuous entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_PROMISC_ENTRY); + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_ALLMULTI_ENTRY); +- /* If PF's allmulti entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ /* If PF's promiscuous entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_ALLMULTI_ENTRY); ++ /* If PF's allmulti entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ } + } + + void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, +-- +2.51.0 + diff --git a/queue-6.18/ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch b/queue-6.18/ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch new file mode 100644 index 0000000000..b79d439f46 --- /dev/null +++ b/queue-6.18/ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch @@ -0,0 +1,113 @@ +From 170ab5b4b8b9112f76e818ab96ec7a9010149ef5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 18:32:49 +0100 +Subject: ovpn: fix possible use-after-free in ovpn_net_xmit + +From: Ralf Lici + +[ Upstream commit a5ec7baa44ea3a1d6aa0ca31c0ad82edf9affe41 ] + +When building the skb_list in ovpn_net_xmit, skb_share_check will free +the original skb if it is shared. The current implementation continues +to use the stale skb pointer for subsequent operations: +- peer lookup, +- skb_dst_drop (even though all segments produced by skb_gso_segment + will have a dst attached), +- ovpn_peer_stats_increment_tx. + +Fix this by moving the peer lookup and skb_dst_drop before segmentation +so that the original skb is still valid when used. Return early if all +segments fail skb_share_check and the list ends up empty. +Also switch ovpn_peer_stats_increment_tx to use skb_list.next; the next +patch fixes the stats logic. + +Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") +Signed-off-by: Ralf Lici +Reviewed-by: Sabrina Dubroca +Signed-off-by: Antonio Quartulli +Signed-off-by: Sasha Levin +--- + drivers/net/ovpn/io.c | 52 ++++++++++++++++++++++++++----------------- + 1 file changed, 31 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c +index 3e9e7f8444b34..f70c58b10599b 100644 +--- a/drivers/net/ovpn/io.c ++++ b/drivers/net/ovpn/io.c +@@ -365,7 +365,27 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + /* verify IP header size in network packet */ + proto = ovpn_ip_check_protocol(skb); + if (unlikely(!proto || skb->protocol != proto)) +- goto drop; ++ goto drop_no_peer; ++ ++ /* retrieve peer serving the destination IP of this packet */ ++ peer = ovpn_peer_get_by_dst(ovpn, skb); ++ if (unlikely(!peer)) { ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): ++ net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n", ++ netdev_name(ovpn->dev), ++ &ip_hdr(skb)->daddr); ++ break; ++ case htons(ETH_P_IPV6): ++ net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n", ++ netdev_name(ovpn->dev), ++ &ipv6_hdr(skb)->daddr); ++ break; ++ } ++ goto drop_no_peer; ++ } ++ /* dst was needed for peer selection - it can now be dropped */ ++ skb_dst_drop(skb); + + if (skb_is_gso(skb)) { + segments = skb_gso_segment(skb, 0); +@@ -396,34 +416,24 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + + __skb_queue_tail(&skb_list, curr); + } +- skb_list.prev->next = NULL; + +- /* retrieve peer serving the destination IP of this packet */ +- peer = ovpn_peer_get_by_dst(ovpn, skb); +- if (unlikely(!peer)) { +- switch (skb->protocol) { +- case htons(ETH_P_IP): +- net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n", +- netdev_name(ovpn->dev), +- &ip_hdr(skb)->daddr); +- break; +- case htons(ETH_P_IPV6): +- net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n", +- netdev_name(ovpn->dev), +- &ipv6_hdr(skb)->daddr); +- break; +- } +- goto drop; ++ /* no segments survived: don't jump to 'drop' because we already ++ * incremented the counter for each failure in the loop ++ */ ++ if (unlikely(skb_queue_empty(&skb_list))) { ++ ovpn_peer_put(peer); ++ return NETDEV_TX_OK; + } +- /* dst was needed for peer selection - it can now be dropped */ +- skb_dst_drop(skb); ++ skb_list.prev->next = NULL; + +- ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb->len); ++ ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb_list.next->len); + ovpn_send(ovpn, skb_list.next, peer); + + return NETDEV_TX_OK; + + drop: ++ ovpn_peer_put(peer); ++drop_no_peer: + dev_dstats_tx_dropped(ovpn->dev); + skb_tx_error(skb); + kfree_skb_list(skb); +-- +2.51.0 + diff --git a/queue-6.18/ovpn-fix-vpn-tx-bytes-counting.patch b/queue-6.18/ovpn-fix-vpn-tx-bytes-counting.patch new file mode 100644 index 0000000000..47cfe55f69 --- /dev/null +++ b/queue-6.18/ovpn-fix-vpn-tx-bytes-counting.patch @@ -0,0 +1,60 @@ +From ccbfc6efc487bd25baadc9f0cbb5732c39b6266a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 18:32:50 +0100 +Subject: ovpn: fix VPN TX bytes counting + +From: Ralf Lici + +[ Upstream commit b660b13d4c6379ca6360f24aaef8c5807fefd237 ] + +In ovpn_net_xmit, after GSO segmentation and segment processing, the +first segment on the list is used to increment VPN TX statistics, which +fails to account for any subsequent segments in the chain. + +Fix this by accumulating the length of every segment that successfully +passes skb_share_check into a tx_bytes variable. This ensures the peer +statistics accurately reflect the total data volume sent, regardless of +whether the original packet was segmented. + +Fixes: 04ca14955f9a ("ovpn: store tunnel and transport statistics") +Signed-off-by: Ralf Lici +Reviewed-by: Sabrina Dubroca +Signed-off-by: Antonio Quartulli +Signed-off-by: Sasha Levin +--- + drivers/net/ovpn/io.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c +index f70c58b10599b..955c9a37e1f8d 100644 +--- a/drivers/net/ovpn/io.c ++++ b/drivers/net/ovpn/io.c +@@ -355,6 +355,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + struct ovpn_priv *ovpn = netdev_priv(dev); + struct sk_buff *segments, *curr, *next; + struct sk_buff_head skb_list; ++ unsigned int tx_bytes = 0; + struct ovpn_peer *peer; + __be16 proto; + int ret; +@@ -414,6 +415,8 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + continue; + } + ++ /* only count what we actually send */ ++ tx_bytes += curr->len; + __skb_queue_tail(&skb_list, curr); + } + +@@ -426,7 +429,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + } + skb_list.prev->next = NULL; + +- ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb_list.next->len); ++ ovpn_peer_stats_increment_tx(&peer->vpn_stats, tx_bytes); + ovpn_send(ovpn, skb_list.next, peer); + + return NETDEV_TX_OK; +-- +2.51.0 + diff --git a/queue-6.18/ovpn-set-sk_user_data-before-overriding-callbacks.patch b/queue-6.18/ovpn-set-sk_user_data-before-overriding-callbacks.patch new file mode 100644 index 0000000000..3eaf0ad65d --- /dev/null +++ b/queue-6.18/ovpn-set-sk_user_data-before-overriding-callbacks.patch @@ -0,0 +1,155 @@ +From a5c2a220108f7ec8169e1e6d562c5a3d1bc7b175 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 18:32:48 +0100 +Subject: ovpn: set sk_user_data before overriding callbacks + +From: Ralf Lici + +[ Upstream commit 93686c472eb7b09a51b97a096449e7092fefcd1f ] + +During initialization, we override socket callbacks and set sk_user_data +to an ovpn_socket instance. Currently, these two operations are +decoupled: callbacks are overridden before sk_user_data is set. While +existing callbacks perform safety checks for NULL or non-ovpn +sk_user_data, this condition causes a "half-formed" state where valid +packets arriving during attachment trigger error logs (e.g., "invoked on +non ovpn socket"). + +Set sk_user_data before overriding the callbacks so that it can be +accessed safely from them. Since we already check that the socket has no +sk_user_data before setting it, this remains safe even if an interrupt +accesses the socket after sk_user_data is set but before the callbacks +are overridden. + +This also requires initializing all protocol-specific fields (such as +tcp_tx_work and peer links) before calling ovpn_socket_attach, ensuring +the ovpn_socket is fully formed before it becomes visible to any +callback. + +Fixes: f6226ae7a0cd ("ovpn: introduce the ovpn_socket object") +Signed-off-by: Ralf Lici +Reviewed-by: Sabrina Dubroca +Signed-off-by: Antonio Quartulli +Signed-off-by: Sasha Levin +--- + drivers/net/ovpn/socket.c | 39 +++++++++++++++++++++------------------ + drivers/net/ovpn/tcp.c | 9 +++++++-- + drivers/net/ovpn/udp.c | 1 + + 3 files changed, 29 insertions(+), 20 deletions(-) + +diff --git a/drivers/net/ovpn/socket.c b/drivers/net/ovpn/socket.c +index 9750871ab65ce..448cee3b3f9fa 100644 +--- a/drivers/net/ovpn/socket.c ++++ b/drivers/net/ovpn/socket.c +@@ -200,6 +200,22 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) + ovpn_sock->sk = sk; + kref_init(&ovpn_sock->refcount); + ++ /* TCP sockets are per-peer, therefore they are linked to their unique ++ * peer ++ */ ++ if (sk->sk_protocol == IPPROTO_TCP) { ++ INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work); ++ ovpn_sock->peer = peer; ++ ovpn_peer_hold(peer); ++ } else if (sk->sk_protocol == IPPROTO_UDP) { ++ /* in UDP we only link the ovpn instance since the socket is ++ * shared among multiple peers ++ */ ++ ovpn_sock->ovpn = peer->ovpn; ++ netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker, ++ GFP_KERNEL); ++ } ++ + /* the newly created ovpn_socket is holding reference to sk, + * therefore we increase its refcounter. + * +@@ -212,29 +228,16 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) + + ret = ovpn_socket_attach(ovpn_sock, sock, peer); + if (ret < 0) { ++ if (sk->sk_protocol == IPPROTO_TCP) ++ ovpn_peer_put(peer); ++ else if (sk->sk_protocol == IPPROTO_UDP) ++ netdev_put(peer->ovpn->dev, &ovpn_sock->dev_tracker); ++ + sock_put(sk); + kfree(ovpn_sock); + ovpn_sock = ERR_PTR(ret); +- goto sock_release; +- } +- +- /* TCP sockets are per-peer, therefore they are linked to their unique +- * peer +- */ +- if (sk->sk_protocol == IPPROTO_TCP) { +- INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work); +- ovpn_sock->peer = peer; +- ovpn_peer_hold(peer); +- } else if (sk->sk_protocol == IPPROTO_UDP) { +- /* in UDP we only link the ovpn instance since the socket is +- * shared among multiple peers +- */ +- ovpn_sock->ovpn = peer->ovpn; +- netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker, +- GFP_KERNEL); + } + +- rcu_assign_sk_user_data(sk, ovpn_sock); + sock_release: + release_sock(sk); + return ovpn_sock; +diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c +index 0d7f30360d874..f0b4e07ba9245 100644 +--- a/drivers/net/ovpn/tcp.c ++++ b/drivers/net/ovpn/tcp.c +@@ -487,6 +487,7 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, + /* make sure no pre-existing encapsulation handler exists */ + if (ovpn_sock->sk->sk_user_data) + return -EBUSY; ++ rcu_assign_sk_user_data(ovpn_sock->sk, ovpn_sock); + + /* only a fully connected socket is expected. Connection should be + * handled in userspace +@@ -495,13 +496,14 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, + net_err_ratelimited("%s: provided TCP socket is not in ESTABLISHED state: %d\n", + netdev_name(peer->ovpn->dev), + ovpn_sock->sk->sk_state); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err; + } + + ret = strp_init(&peer->tcp.strp, ovpn_sock->sk, &cb); + if (ret < 0) { + DEBUG_NET_WARN_ON_ONCE(1); +- return ret; ++ goto err; + } + + INIT_WORK(&peer->tcp.defer_del_work, ovpn_tcp_peer_del_work); +@@ -536,6 +538,9 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, + strp_check_rcv(&peer->tcp.strp); + + return 0; ++err: ++ rcu_assign_sk_user_data(ovpn_sock->sk, NULL); ++ return ret; + } + + static void ovpn_tcp_close(struct sock *sk, long timeout) +diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c +index d6a0f7a0b75d7..272b535ecaad4 100644 +--- a/drivers/net/ovpn/udp.c ++++ b/drivers/net/ovpn/udp.c +@@ -386,6 +386,7 @@ int ovpn_udp_socket_attach(struct ovpn_socket *ovpn_sock, struct socket *sock, + struct ovpn_priv *ovpn) + { + struct udp_tunnel_sock_cfg cfg = { ++ .sk_user_data = ovpn_sock, + .encap_type = UDP_ENCAP_OVPNINUDP, + .encap_rcv = ovpn_udp_encap_recv, + .encap_destroy = ovpn_udp_encap_destroy, +-- +2.51.0 + diff --git a/queue-6.18/ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch b/queue-6.18/ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch new file mode 100644 index 0000000000..d01e55a782 --- /dev/null +++ b/queue-6.18/ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch @@ -0,0 +1,78 @@ +From 367fa4b931d0362f2a7cd70f62136d4e39a3d04f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:31:19 +0100 +Subject: ovpn: tcp - don't deref NULL sk_socket member after tcp_close() + +From: Antonio Quartulli + +[ Upstream commit 94560267d6c41b1ff3fafbab726e3f8a55a6af34 ] + +When deleting a peer in case of keepalive expiration, the peer is +removed from the OpenVPN hashtable and is temporary inserted in a +"release list" for further processing. + +This happens in: +ovpn_peer_keepalive_work() + unlock_ovpn(release_list) + +This processing includes detaching from the socket being used to +talk to this peer, by restoring its original proto and socket +ops/callbacks. + +In case of TCP it may happen that, while the peer is sitting in +the release list, userspace decides to close the socket. +This will result in a concurrent execution of: + +tcp_close(sk) + __tcp_close(sk) + sock_orphan(sk) + sk_set_socket(sk, NULL) + +The last function call will set sk->sk_socket to NULL. + +When the releasing routine is resumed, ovpn_tcp_socket_detach() +will attempt to dereference sk->sk_socket to restore its original +ops member. This operation will crash due to sk->sk_socket being NULL. + +Fix this race condition by testing-and-accessing +sk->sk_socket atomically under sk->sk_callback_lock. + +Link: https://lore.kernel.org/netdev/176996279620.3109699.15382994681575380467@eldamar.lan/ +Link: https://github.com/OpenVPN/ovpn-net-next/issues/29 +Signed-off-by: Antonio Quartulli +Fixes: 11851cbd60ea ("ovpn: implement TCP transport") +Link: https://patch.msgid.link/20260212213130.11497-1-antonio@openvpn.net +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ovpn/tcp.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c +index f0b4e07ba9245..ec2bbc28c1966 100644 +--- a/drivers/net/ovpn/tcp.c ++++ b/drivers/net/ovpn/tcp.c +@@ -199,7 +199,19 @@ void ovpn_tcp_socket_detach(struct ovpn_socket *ovpn_sock) + sk->sk_data_ready = peer->tcp.sk_cb.sk_data_ready; + sk->sk_write_space = peer->tcp.sk_cb.sk_write_space; + sk->sk_prot = peer->tcp.sk_cb.prot; +- sk->sk_socket->ops = peer->tcp.sk_cb.ops; ++ ++ /* tcp_close() may race this function and could set ++ * sk->sk_socket to NULL. It does so by invoking ++ * sock_orphan(), which holds sk_callback_lock before ++ * doing the assignment. ++ * ++ * For this reason we acquire the same lock to avoid ++ * sk_socket to disappear under our feet ++ */ ++ write_lock_bh(&sk->sk_callback_lock); ++ if (sk->sk_socket) ++ sk->sk_socket->ops = peer->tcp.sk_cb.ops; ++ write_unlock_bh(&sk->sk_callback_lock); + + rcu_assign_sk_user_data(sk, NULL); + } +-- +2.51.0 + diff --git a/queue-6.18/pci-validate-window-resource-type-in-pbus_select_win.patch b/queue-6.18/pci-validate-window-resource-type-in-pbus_select_win.patch new file mode 100644 index 0000000000..8acf3a69d7 --- /dev/null +++ b/queue-6.18/pci-validate-window-resource-type-in-pbus_select_win.patch @@ -0,0 +1,70 @@ +From 11e8f743df3ee52818f3cc9670a55990ae596d8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 22:20:57 +0800 +Subject: PCI: Validate window resource type in pbus_select_window_for_type() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kai-Heng Feng + +[ Upstream commit e5f72cb9cea599dc9f5a9b80a33560a1d06f01cc ] + +After ebe091ad81e1 ("PCI: Use pbus_select_window_for_type() during IO +window sizing") and ae88d0b9c57f ("PCI: Use pbus_select_window_for_type() +during mem window sizing"), many bridge windows can't get resources +assigned: + + pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: can't assign; no space + pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: failed to assign + +Those commits replace find_bus_resource_of_type() with +pbus_select_window_for_type(), and the latter lacks resource type +validation. + +Add the resource type validation back to pbus_select_window_for_type() to +match the original behavior. + +Fixes: 74afce3dfcba ("PCI: Add bridge window selection functions") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=221072 +Signed-off-by: Kai-Heng Feng +Signed-off-by: Bjorn Helgaas +Reviewed-by: Ilpo Järvinen +Link: https://patch.msgid.link/20260210142058.82701-1-kaihengf@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/pci/setup-bus.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c +index 4f4890196e63e..cc592ccff5424 100644 +--- a/drivers/pci/setup-bus.c ++++ b/drivers/pci/setup-bus.c +@@ -221,14 +221,21 @@ static struct resource *pbus_select_window_for_type(struct pci_bus *bus, + + switch (iores_type) { + case IORESOURCE_IO: +- return pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); ++ win = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); ++ if (win && (win->flags & IORESOURCE_IO)) ++ return win; ++ return NULL; + + case IORESOURCE_MEM: + mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW); + mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW); + +- if (!(type & IORESOURCE_PREFETCH) || +- !(mmio_pref->flags & IORESOURCE_MEM)) ++ if (mmio && !(mmio->flags & IORESOURCE_MEM)) ++ mmio = NULL; ++ if (mmio_pref && !(mmio_pref->flags & IORESOURCE_MEM)) ++ mmio_pref = NULL; ++ ++ if (!(type & IORESOURCE_PREFETCH) || !mmio_pref) + return mmio; + + if ((type & IORESOURCE_MEM_64) || +-- +2.51.0 + diff --git a/queue-6.18/ping-annotate-data-races-in-ping_lookup.patch b/queue-6.18/ping-annotate-data-races-in-ping_lookup.patch new file mode 100644 index 0000000000..4b4e3f84f5 --- /dev/null +++ b/queue-6.18/ping-annotate-data-races-in-ping_lookup.patch @@ -0,0 +1,118 @@ +From a91ca9f2f24ea8373f4e3e95983db73fcc9e7458 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:01:49 +0000 +Subject: ping: annotate data-races in ping_lookup() + +From: Eric Dumazet + +[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ] + +isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if +are read locklessly in ping_lookup(). + +Add READ_ONCE()/WRITE_ONCE() annotations. + +The race on isk->inet_rcv_saddr is probably coming from IPv6 support, +but does not deserve a specific backport. + +Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/ping.c | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index a5227d23bb0b5..690f486173e01 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -148,7 +148,7 @@ void ping_unhash(struct sock *sk) + pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); + spin_lock(&ping_table.lock); + if (sk_del_node_init_rcu(sk)) { +- isk->inet_num = 0; ++ WRITE_ONCE(isk->inet_num, 0); + isk->inet_sport = 0; + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + } +@@ -181,31 +181,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + } + + sk_for_each_rcu(sk, hslot) { ++ int bound_dev_if; ++ + if (!net_eq(sock_net(sk), net)) + continue; + isk = inet_sk(sk); + + pr_debug("iterate\n"); +- if (isk->inet_num != ident) ++ if (READ_ONCE(isk->inet_num) != ident) + continue; + ++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); + if (skb->protocol == htons(ETH_P_IP) && + sk->sk_family == AF_INET) { ++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr); ++ + pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk, +- (int) isk->inet_num, &isk->inet_rcv_saddr, +- sk->sk_bound_dev_if); ++ ident, &rcv_saddr, ++ bound_dev_if); + +- if (isk->inet_rcv_saddr && +- isk->inet_rcv_saddr != ip_hdr(skb)->daddr) ++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr) + continue; + #if IS_ENABLED(CONFIG_IPV6) + } else if (skb->protocol == htons(ETH_P_IPV6) && + sk->sk_family == AF_INET6) { + + pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk, +- (int) isk->inet_num, ++ ident, + &sk->sk_v6_rcv_saddr, +- sk->sk_bound_dev_if); ++ bound_dev_if); + + if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && + !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, +@@ -216,8 +220,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + continue; + } + +- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && +- sk->sk_bound_dev_if != sdif) ++ if (bound_dev_if && bound_dev_if != dif && ++ bound_dev_if != sdif) + continue; + + goto exit; +@@ -392,7 +396,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr) + if (saddr->sa_family == AF_INET) { + struct inet_sock *isk = inet_sk(sk); + struct sockaddr_in *addr = (struct sockaddr_in *) saddr; +- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr; ++ ++ isk->inet_saddr = addr->sin_addr.s_addr; ++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr); + #if IS_ENABLED(CONFIG_IPV6) + } else if (saddr->sa_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr; +@@ -849,7 +855,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, + struct sk_buff *skb; + int copied, err; + +- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); ++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, ++ READ_ONCE(isk->inet_num)); + + err = -EOPNOTSUPP; + if (flags & MSG_OOB) +-- +2.51.0 + diff --git a/queue-6.18/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch b/queue-6.18/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch new file mode 100644 index 0000000000..f277e64369 --- /dev/null +++ b/queue-6.18/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch @@ -0,0 +1,49 @@ +From c185b1a211879406ec5072b8824b677cbfa5c4d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 14:34:01 -0800 +Subject: powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check + +From: Kuppuswamy Sathyanarayanan + +[ Upstream commit c7d54dafa042cf379859dba265fe5afef6fa8770 ] + +On partitioned systems, multiple TPMI instances may exist per package, +but RAPL registers are only valid on one instance since RAPL has +package-scope control. Other instances return invalid versions during +domain parsing, which is expected behavior on such systems. + +Currently this generates a firmware bug warning: + + intel_rapl_tpmi: [Firmware Bug]: Invalid version + +Remove the FW_BUG tag, downgrade to pr_debug(), and update the message +to clarify that invalid versions are expected on partitioned systems +where only one instance can be valid. + +Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver") +Reported-by: Zhang Rui +Signed-off-by: Kuppuswamy Sathyanarayanan +Reviewed-by: Srinivas Pandruvada +Link: https://patch.msgid.link/20260211223401.1575776-1-sathyanarayanan.kuppuswamy@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/intel_rapl_tpmi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c +index 82201bf4685d4..34c0bd1edd61a 100644 +--- a/drivers/powercap/intel_rapl_tpmi.c ++++ b/drivers/powercap/intel_rapl_tpmi.c +@@ -157,7 +157,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) + tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; + + if (tpmi_domain_version == TPMI_VERSION_INVALID) { +- pr_warn(FW_BUG "Invalid version\n"); ++ pr_debug("Invalid version, other instances may be valid\n"); + return -ENODEV; + } + +-- +2.51.0 + diff --git a/queue-6.18/s390-kexec-make-kexec_sig-available-when-config_modu.patch b/queue-6.18/s390-kexec-make-kexec_sig-available-when-config_modu.patch new file mode 100644 index 0000000000..f85e8ddf1d --- /dev/null +++ b/queue-6.18/s390-kexec-make-kexec_sig-available-when-config_modu.patch @@ -0,0 +1,61 @@ +From 87452ab1651d971a3ea83941cd78fd7774af9130 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 07:29:16 +0100 +Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n + +From: Alexander Egorenkov + +[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ] + +The commit c8424e776b09 ("MODSIGN: Export module signature definitions") +replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the +dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390 +kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT. + +Furthermore, the signature verification in s390 kexec does not require +MODULE_SIG_FORMAT because it requires only the struct module_signature and, +therefore, does not depend on code in kernel/module_signature.c. + +But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is +also incorrect because it makes KEXEC_SIG available on s390 only if some +other arbitrary option (for instance a file system or device driver) +selects it directly or indirectly. + +To properly make KEXEC_SIG available for s390 kernels built with MODULES=y +as well as MODULES=n _and_ also not depend on arbitrary options selecting +SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select +SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y. + +Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions") +Suggested-by: Heiko Carstens +Signed-off-by: Alexander Egorenkov +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index df22b10d91415..e60d2b823e091 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -270,6 +270,7 @@ config S390 + select SPARSE_IRQ + select SWIOTLB + select SYSCTL_EXCEPTION_TRACE ++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG + select THREAD_INFO_IN_TASK + select TRACE_IRQFLAGS_SUPPORT + select TTY +@@ -296,7 +297,7 @@ config ARCH_SUPPORTS_KEXEC_FILE + def_bool y + + config ARCH_SUPPORTS_KEXEC_SIG +- def_bool MODULE_SIG_FORMAT ++ def_bool y + + config ARCH_SUPPORTS_KEXEC_PURGATORY + def_bool y +-- +2.51.0 + diff --git a/queue-6.18/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch b/queue-6.18/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch new file mode 100644 index 0000000000..91cb9d2eb9 --- /dev/null +++ b/queue-6.18/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch @@ -0,0 +1,78 @@ +From ece8a789c000199523e04fb21979b6810c337c82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:05 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with + br_netfilter enabled + +From: Aleksei Oladko + +[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv4 packet contains a zero IP header checksum. After VXLAN +decapsulation, such packets do not pass sanity checks in br_netfilter +and are dropped, which causes the test to fail. + +Fix this by calculating and setting a valid IPv4 header checksum for the +encapsulated packet generated by mausezahn, so that the packet is accepted +by br_netfilter. Fixed by using the payload_template_calc_checksum() / +payload_template_expand_checksum() helpers that are only available +in v6.3 and newer kernels. + +Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index b43816dd998ca..457f41d5e584b 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -567,6 +567,21 @@ vxlan_encapped_ping_do() + local inner_tos=$1; shift + local outer_tos=$1; shift + ++ local ipv4hdr=$(: ++ )"45:"$( : IP version + IHL ++ )"$inner_tos:"$( : IP TOS ++ )"00:54:"$( : IP total length ++ )"99:83:"$( : IP identification ++ )"40:00:"$( : IP flags + frag off ++ )"40:"$( : IP TTL ++ )"01:"$( : IP proto ++ )"CHECKSUM:"$( : IP header csum ++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 ++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1 ++ ) ++ local checksum=$(payload_template_calc_checksum "$ipv4hdr") ++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum) ++ + $MZ $dev -c $count -d 100msec -q \ + -b $next_hop_mac -B $dest_ip \ + -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(: +@@ -577,16 +592,7 @@ vxlan_encapped_ping_do() + )"$dest_mac:"$( : ETH daddr + )"$(mac_get w2):"$( : ETH saddr + )"08:00:"$( : ETH type +- )"45:"$( : IP version + IHL +- )"$inner_tos:"$( : IP TOS +- )"00:54:"$( : IP total length +- )"99:83:"$( : IP identification +- )"40:00:"$( : IP flags + frag off +- )"40:"$( : IP TTL +- )"01:"$( : IP proto +- )"00:00:"$( : IP header csum +- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 +- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 ++ )"$ipv4hdr:"$( : IPv4 header + )"08:"$( : ICMP type + )"00:"$( : ICMP code + )"8b:f2:"$( : ICMP csum +-- +2.51.0 + diff --git a/queue-6.18/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch b/queue-6.18/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch new file mode 100644 index 0000000000..aa7fb184fe --- /dev/null +++ b/queue-6.18/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch @@ -0,0 +1,69 @@ +From c822a675bd483e61c9f3f94350845629fad1f7ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:06 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with + br_netfilter enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Aleksei Oladko + +[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv6 packet has an incorrect payload length set in the IPv6 header. +After VXLAN decapsulation, such packets do not pass sanity checks in +br_netfilter and are dropped, which causes the test to fail. + +Fix this by setting the correct IPv6 payload length for the encapsulated +packet generated by mausezahn, so that the packet is accepted +by br_netfilter. + +tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +lines 698-706 + + )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + )"80:"$( : ICMPv6.type + )"00:"$( : ICMPv6.code + )"00:"$( : ICMPv6.checksum + ) + +Data after IPv6 header: +• 80: — 1 byte (ICMPv6 type) +• 00: — 1 byte (ICMPv6 code) +• 00: — 1 byte (ICMPv6 checksum, truncated) + +Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match +the actual payload size. + +Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +index a603f7b0a08f0..e642feeada0e7 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +@@ -695,7 +695,7 @@ vxlan_encapped_ping_do() + )"6"$( : IP version + )"$inner_tos"$( : Traffic class + )"0:00:00:"$( : Flow label +- )"00:08:"$( : Payload length ++ )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr +-- +2.51.0 + diff --git a/queue-6.18/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch b/queue-6.18/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch new file mode 100644 index 0000000000..29a3c123d2 --- /dev/null +++ b/queue-6.18/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch @@ -0,0 +1,241 @@ +From 61bf23070fa5852a9c7290f269bba687462bc520 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 09:38:05 -0500 +Subject: selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT + +From: Aristeu Rozanski + +[ Upstream commit b24335521de92fd2ee22460072b75367ca8860b0 ] + +selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT + +In order to synchronize new processes to test inheritance of memfd_noexec +sysctl, memfd_test sets up the sysctl with a value before creating the new +process. The new process then sends itself a SIGSTOP in order to wait for +the parent to flip the sysctl value and send a SIGCONT signal. + +This would work as intended if it wasn't the fact that the new process is +being created with CLONE_NEWPID, which creates a new PID namespace and the +new process has PID 1 in this namespace. There're restrictions on sending +signals to PID 1 and, although it's relaxed for other than root PID +namespace, it's biting us here. In this specific case the SIGSTOP sent by +the new process is ignored (no error to kill() is returned) and it never +stops its execution. This is usually not noticiable as the parent usually +manages to set the new sysctl value before the child has a chance to run +and the test succeeds. But if you run the test in a loop, it eventually +reproduces: + + while [ 1 ]; do ./memfd_test >log 2>&1 || break; done; cat log + +So this patch replaces the SIGSTOP/SIGCONT synchronization with IPC +semaphore. + +Link: https://lkml.kernel.org/r/a7776389-b3d6-4b18-b438-0b0e3ed1fd3b@work +Fixes: 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests") +Signed-off-by: Aristeu Rozanski +Cc: Aleksa Sarai +Cc: Shuah Khan +Cc: liuye +Cc: Lorenzo Stoakes +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/memfd/memfd_test.c | 113 +++++++++++++++++++-- + 1 file changed, 105 insertions(+), 8 deletions(-) + +diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c +index 5b993924cc3f5..2ca07ea7202a5 100644 +--- a/tools/testing/selftests/memfd/memfd_test.c ++++ b/tools/testing/selftests/memfd/memfd_test.c +@@ -18,6 +18,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + +@@ -39,6 +42,20 @@ + F_SEAL_EXEC) + + #define MFD_NOEXEC_SEAL 0x0008U ++union semun { ++ int val; ++ struct semid_ds *buf; ++ unsigned short int *array; ++ struct seminfo *__buf; ++}; ++ ++/* ++ * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the ++ * child will be PID 1 and can't send SIGSTOP to themselves due special ++ * treatment of the init task, so the SIGSTOP/SIGCONT synchronization ++ * approach can't be used here. ++ */ ++#define SEM_KEY 0xdeadbeef + + /* + * Default is not to test hugetlbfs +@@ -1333,8 +1350,22 @@ static int sysctl_nested(void *arg) + + static int sysctl_nested_wait(void *arg) + { +- /* Wait for a SIGCONT. */ +- kill(getpid(), SIGSTOP); ++ int sem = semget(SEM_KEY, 1, 0600); ++ struct sembuf sembuf; ++ ++ if (sem < 0) { ++ perror("semget:"); ++ abort(); ++ } ++ sembuf.sem_num = 0; ++ sembuf.sem_flg = 0; ++ sembuf.sem_op = 0; ++ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ abort(); ++ } ++ + return sysctl_nested(arg); + } + +@@ -1355,7 +1386,9 @@ static void test_sysctl_sysctl2_failset(void) + + static int sysctl_nested_child(void *arg) + { +- int pid; ++ int pid, sem; ++ union semun semun; ++ struct sembuf sembuf; + + printf("%s nested sysctl 0\n", memfd_str); + sysctl_assert_write("0"); +@@ -1389,23 +1422,53 @@ static int sysctl_nested_child(void *arg) + test_sysctl_sysctl2_failset); + join_thread(pid); + ++ sem = semget(SEM_KEY, 1, IPC_CREAT | 0600); ++ if (sem < 0) { ++ perror("semget:"); ++ return 1; ++ } ++ semun.val = 1; ++ sembuf.sem_op = -1; ++ sembuf.sem_flg = 0; ++ sembuf.sem_num = 0; ++ + /* Verify that the rules are actually inherited after fork. */ + printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str); + sysctl_assert_write("0"); + ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl1_failset); + sysctl_assert_write("1"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str); + sysctl_assert_write("0"); + ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2_failset); + sysctl_assert_write("2"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + /* +@@ -1415,28 +1478,62 @@ static int sysctl_nested_child(void *arg) + */ + printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str); + sysctl_assert_write("2"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2); + sysctl_assert_write("1"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str); + sysctl_assert_write("2"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2); + sysctl_assert_write("0"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str); + sysctl_assert_write("1"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl1); + sysctl_assert_write("0"); +- kill(pid, SIGCONT); ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + ++ semctl(sem, 0, IPC_RMID); ++ + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.18/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch b/queue-6.18/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch new file mode 100644 index 0000000000..71400bebf9 --- /dev/null +++ b/queue-6.18/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch @@ -0,0 +1,57 @@ +From bce12126b66fc80ef6456edb905659b9b2b4754b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 14:53:53 +0100 +Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2 + +From: Ido Schimmel + +[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ] + +As explained in [1], iproute2 started rejecting tc-police burst sizes +that result in an overflow. This can happen when the burst size is high +enough and the rate is low enough. + +A couple of test cases specify such configurations, resulting in +iproute2 errors and test failure. + +Fix by reducing the burst size so that the test will pass with both new +and old iproute2 versions. + +[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/ + +Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions") +Signed-off-by: Ido Schimmel +Signed-off-by: Petr Machata +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +index 0441a18f098b1..aac8ef490feb8 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +@@ -317,7 +317,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 0.5kbit burst 1m conform-exceed drop/ok ++ action police rate 0.5kbit burst 2k conform-exceed drop/ok + check_fail $? "Incorrect success to add police action with too low rate" + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ +@@ -327,7 +327,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 1.5kbit burst 1m conform-exceed drop/ok ++ action police rate 1.5kbit burst 2k conform-exceed drop/ok + check_err $? "Failed to add police action with low rate" + + tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower +-- +2.51.0 + diff --git a/queue-6.18/selftests-net-lib-fix-jq-parsing-error.patch b/queue-6.18/selftests-net-lib-fix-jq-parsing-error.patch new file mode 100644 index 0000000000..d4ad544cfa --- /dev/null +++ b/queue-6.18/selftests-net-lib-fix-jq-parsing-error.patch @@ -0,0 +1,56 @@ +From 168265ad3d36fecb38483b8266213b1f635be6da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 10:21:46 +0800 +Subject: selftests: net: lib: Fix jq parsing error + +From: Yue Haibing + +[ Upstream commit 10ec0fc0ccc525abc807b0ca8ad5a26a0bd56361 ] + +The testcase failed as below: +$./vlan_bridge_binding.sh +... ++ adf_ip_link_set_up d1 ++ local name=d1 ++ shift ++ ip_link_is_up d1 ++ ip_link_has_flag d1 UP ++ local name=d1 ++ shift ++ local flag=UP ++ shift +++ ip -j link show d1 +++ jq --arg flag UP 'any(.[].flags.[]; . == $flag)' +jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START + (Unix shell quoting issues?) at , line 1: +any(.[].flags.[]; . == $flag) +jq: 1 compile error + +Remove the extra dot (.) after flags array to fix this. + +Fixes: 4baa1d3a5080 ("selftests: net: lib: Add ip_link_has_flag()") +Signed-off-by: Yue Haibing +Reviewed-by: Petr Machata +Link: https://patch.msgid.link/20260211022146.190948-1-yuehaibing@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/lib.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh +index f448bafb3f208..d0306b27fe95e 100644 +--- a/tools/testing/selftests/net/lib.sh ++++ b/tools/testing/selftests/net/lib.sh +@@ -576,7 +576,7 @@ ip_link_has_flag() + local flag=$1; shift + + local state=$(ip -j link show "$name" | +- jq --arg flag "$flag" 'any(.[].flags.[]; . == $flag)') ++ jq --arg flag "$flag" 'any(.[].flags[]; . == $flag)') + [[ $state == true ]] + } + +-- +2.51.0 + diff --git a/queue-6.18/selftests-netconsole-increase-port-listening-timeout.patch b/queue-6.18/selftests-netconsole-increase-port-listening-timeout.patch new file mode 100644 index 0000000000..0ff4f0fb81 --- /dev/null +++ b/queue-6.18/selftests-netconsole-increase-port-listening-timeout.patch @@ -0,0 +1,44 @@ +From 98793afd45c712d524a87c236f24e4f88bc71c59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 16:59:36 -0800 +Subject: selftests: netconsole: Increase port listening timeout + +From: Pin-yen Lin + +[ Upstream commit a68a9bd086c2822d0c629443bd16ad1317afe501 ] + +wait_for_port() can wait up to 2 seconds with the sleep and the polling +in wait_local_port_listen() combined. So, in netcons_basic.sh, the socat +process could die before the test writes to the netconsole. + +Increase the timeout to 3 seconds to make netcons_basic.sh pass +consistently. + +Fixes: 3dc6c76391cb ("selftests: net: Add IPv6 support to netconsole basic tests") +Signed-off-by: Pin-yen Lin +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260210005939.3230550-1-treapking@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +index ae8abff4be409..64d3941576d5d 100644 +--- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh ++++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +@@ -247,8 +247,8 @@ function listen_port_and_save_to() { + SOCAT_MODE="UDP6-LISTEN" + fi + +- # Just wait for 2 seconds +- timeout 2 ip netns exec "${NAMESPACE}" \ ++ # Just wait for 3 seconds ++ timeout 3 ip netns exec "${NAMESPACE}" \ + socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}" 2> /dev/null + } + +-- +2.51.0 + diff --git a/queue-6.18/selftests-netconsole-remove-log-noise-due-to-socat-e.patch b/queue-6.18/selftests-netconsole-remove-log-noise-due-to-socat-e.patch new file mode 100644 index 0000000000..f3cb8d9ca0 --- /dev/null +++ b/queue-6.18/selftests-netconsole-remove-log-noise-due-to-socat-e.patch @@ -0,0 +1,70 @@ +From 3d542821716708d86fd2315a60286fdb4d930f3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Nov 2025 12:24:19 +0000 +Subject: selftests: netconsole: remove log noise due to socat exit + +From: Andre Carvalho + +[ Upstream commit e3b8cbf40c6e60a7a935bd8980884d5741a7a77b ] + +This removes some noise that can be distracting while looking at +selftests by redirecting socat stderr to /dev/null. + +Before this commit, netcons_basic would output: + +Running with target mode: basic (ipv6) +2025/11/29 12:08:03 socat[259] W exiting on signal 15 +2025/11/29 12:08:03 socat[271] W exiting on signal 15 +basic : ipv6 : Test passed +Running with target mode: basic (ipv4) +2025/11/29 12:08:05 socat[329] W exiting on signal 15 +2025/11/29 12:08:05 socat[322] W exiting on signal 15 +basic : ipv4 : Test passed +Running with target mode: extended (ipv6) +2025/11/29 12:08:08 socat[386] W exiting on signal 15 +2025/11/29 12:08:08 socat[386] W exiting on signal 15 +2025/11/29 12:08:08 socat[380] W exiting on signal 15 +extended : ipv6 : Test passed +Running with target mode: extended (ipv4) +2025/11/29 12:08:10 socat[440] W exiting on signal 15 +2025/11/29 12:08:10 socat[435] W exiting on signal 15 +2025/11/29 12:08:10 socat[435] W exiting on signal 15 +extended : ipv4 : Test passed + +After these changes, output looks like: + +Running with target mode: basic (ipv6) +basic : ipv6 : Test passed +Running with target mode: basic (ipv4) +basic : ipv4 : Test passed +Running with target mode: extended (ipv6) +extended : ipv6 : Test passed +Running with target mode: extended (ipv4) +extended : ipv4 : Test passed + +Signed-off-by: Andre Carvalho +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251129-netcons-socat-noise-v1-1-605a0cea8fca@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: a68a9bd086c2 ("selftests: netconsole: Increase port listening timeout") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +index 87f89fd92f8c1..ae8abff4be409 100644 +--- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh ++++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +@@ -249,7 +249,7 @@ function listen_port_and_save_to() { + + # Just wait for 2 seconds + timeout 2 ip netns exec "${NAMESPACE}" \ +- socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}" ++ socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}" 2> /dev/null + } + + # Only validate that the message arrived properly +-- +2.51.0 + diff --git a/queue-6.18/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch b/queue-6.18/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch new file mode 100644 index 0000000000..2f01c578e9 --- /dev/null +++ b/queue-6.18/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch @@ -0,0 +1,57 @@ +From fa08d10ee1af96c1b8e5ecea3d3dc040f40e8331 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:51:59 -0800 +Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout + +From: Jakub Kicinski + +[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ] + +Since we started running selftests in NIPA we have been seeing +tc_actions.sh generate a soft lockup warning on ~20% of the runs. +On the pre-netdev foundation setup it was actually a missed irq +splat from the console. Now it's either that or a lockup. + +I initially suspected a socket locking issue since the test +is exercising local loopback with act_mirred. +After hours of staring at this I noticed in strace that ncat +when -o $file is specified _both_ saves the output to the file +and still prints it to stdout. Because the file being sent +is constructed with: + + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred + ^^^^^^^^^ + +the data printed is all \0. Most terminals don't display nul +characters (and neither does vng output capture save them). +But QEMU's serial console still has to poke them thru which +is very slow and causes the lockup (if the file is >600kB). + +Replace the '-o $file' with '> $file'. This speeds the test up +from 2m20s to 18s on debug kernels, and prevents the warnings. + +Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index ea89e558672db..86edbc7e2489b 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -223,7 +223,7 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & ++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 & + local rpid=$! + ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid +-- +2.51.0 + diff --git a/queue-6.18/series b/queue-6.18/series index e3ab7275e7..b086dff653 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -498,3 +498,116 @@ dmaengine-fsl-edma-don-t-explicitly-disable-clocks-i.patch drbd-always-set-blk_feat_stable_writes.patch io_uring-delay-sqarray-static-branch-disablement.patch io_uring-cancel-de-unionize-file-and-user_data-in-st.patch +fs-ntfs3-initialize-new-folios-before-use.patch +fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch +fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch +acpi-button-adjust-event-notification-routines.patch +acpi-button-convert-the-driver-to-a-platform-one.patch +acpi-button-call-device_init_wakeup-earlier-during-p.patch +acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch +powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch +kbuild-add-objtool-to-top-level-clean-target.patch +selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch +objpool-fix-the-overestimation-of-object-pooling-met.patch +acpi-pm-add-unused-power-resource-quirk-for-thundero.patch +cpuidle-skip-governor-when-only-one-idle-state-is-av.patch +ovpn-set-sk_user_data-before-overriding-callbacks.patch +ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch +ovpn-fix-vpn-tx-bytes-counting.patch +selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch +selftests-net-lib-fix-jq-parsing-error.patch +net-stmmac-remove-broken-pcs-code.patch +net-stmmac-replace-has_xxxx-with-core_type.patch +net-stmmac-fix-oops-when-split-header-is-enabled.patch +net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch +net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch +net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch +net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch +selftests-netconsole-remove-log-noise-due-to-socat-e.patch +selftests-netconsole-increase-port-listening-timeout.patch +ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch +net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch +fbnic-close-fw_log-race-between-users-and-teardown.patch +libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch +bpf-fix-a-potential-use-after-free-of-btf-object.patch +bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch +eth-fbnic-configure-rde-settings-for-pause-frame.patch +eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch +eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch +eth-fbnic-set-dma_hint_l4-for-all-flows.patch +ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch +net-usb-catc-enable-basic-endpoint-checking.patch +xen-netback-reject-zero-queue-configuration-from-gue.patch +net-rds-rds_sendmsg-should-not-discard-payload_len.patch +net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch +selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch +selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch +netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch +ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch +net-remove-warn_on_once-when-accessing-forward-path-.patch +netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch +ipv6-fix-a-race-in-ip6_sock_set_v6only.patch +bpftool-fix-truncated-netlink-dumps.patch +net-psp-select-config_skb_extensions.patch +ping-annotate-data-races-in-ping_lookup.patch +selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch +macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch +eth-fbnic-add-validation-for-mtu-changes.patch +icmp-prevent-possible-overflow-in-icmp_global_allow.patch +inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch +ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch +octeontx2-af-fix-default-entries-mcam-entry-action.patch +eth-fbnic-advertise-supported-xdp-features.patch +bnge-fix-reserving-resources-from-fw.patch +bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch +net-mlx5-fix-multiport-device-check-over-light-sfs.patch +net-mlx5-fix-misidentification-of-write-combining-cq.patch +net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch +net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch +apparmor-fix-null-pointer-dereference-in-__unix_need.patch +apparmor-fix-null-sock-in-aa_sock_file_perm.patch +apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch +apparmor-fix-optimize-table-creation-from-possibly-u.patch +apparmor-return-enomem-in-unpack_perms_table-upon-al.patch +apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch +apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch +apparmor-account-for-in_atomic-removal-in-common_fil.patch +apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch +apparmor-fix-rlimit-for-posix-cpu-timers.patch +apparmor-remove-apply_modes_to_perms-from-label_matc.patch +apparmor-make-label_match-return-a-consistent-value.patch +apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch +apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch +apparmor-fix-aa_label-to-return-state-from-compount-.patch +drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch +drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch +drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch +drm-amdgpu-move-reset-debug-disable-handling.patch +drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch +drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch +drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch +mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch +asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch +drm-i915-acpi-free-_dsm-package-when-no-connectors.patch +asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch +pci-validate-window-resource-type-in-pbus_select_win.patch +drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch +drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch +drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch +spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch +s390-kexec-make-kexec_sig-available-when-config_modu.patch +drm-xe-configfs-fix-parameter-name-omitted-errors.patch +drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch +drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch +drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch +drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch +gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch +efi-fix-reservation-of-unaccepted-memory-table.patch +btrfs-remove-fs_info-argument-from-btrfs_try_grantin.patch +btrfs-reduce-block-group-critical-section-in-btrfs_f.patch +btrfs-reset-block-group-size-class-when-it-becomes-e.patch +btrfs-use-the-correct-type-to-initialize-block-reser.patch +btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch +x86-hyperv-fix-error-pointer-dereference.patch +asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch +drm-amd-display-use-same-max-plane-scaling-limits-fo.patch diff --git a/queue-6.18/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch b/queue-6.18/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch new file mode 100644 index 0000000000..8d431506bb --- /dev/null +++ b/queue-6.18/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch @@ -0,0 +1,49 @@ +From 6fb8cccdfa2759526efeab6c7e01e846d08df482 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:41:40 +0800 +Subject: spi: wpcm-fiu: Fix potential NULL pointer dereference in + wpcm_fiu_probe() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felix Gu + +[ Upstream commit 888a0a802c467bbe34a42167bdf9d7331333440a ] + +platform_get_resource_byname() can return NULL, which would cause a crash +when passed the pointer to resource_size(). + +Move the fiu->memory_size assignment after the error check for +devm_ioremap_resource() to prevent the potential NULL pointer dereference. + +Fixes: 9838c182471e ("spi: wpcm-fiu: Add direct map support") +Signed-off-by: Felix Gu +Reviewed-by: J. Neuschäfer +Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-wpcm-fiu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c +index a9aee2a6c7dcb..c47b56f0933f1 100644 +--- a/drivers/spi/spi-wpcm-fiu.c ++++ b/drivers/spi/spi-wpcm-fiu.c +@@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); + fiu->memory = devm_ioremap_resource(dev, res); +- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + if (IS_ERR(fiu->memory)) + return dev_err_probe(dev, PTR_ERR(fiu->memory), + "Failed to map flash memory window\n"); + ++ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm"); + + wpcm_fiu_hw_init(fiu); +-- +2.51.0 + diff --git a/queue-6.18/x86-hyperv-fix-error-pointer-dereference.patch b/queue-6.18/x86-hyperv-fix-error-pointer-dereference.patch new file mode 100644 index 0000000000..488c466da3 --- /dev/null +++ b/queue-6.18/x86-hyperv-fix-error-pointer-dereference.patch @@ -0,0 +1,54 @@ +From 6de635b0d2ba01deff2d11ae976441c64bb1788a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 13:09:03 -0600 +Subject: x86/hyperv: Fix error pointer dereference + +From: Ethan Tidmore + +[ Upstream commit 705d01c8d78121ee1634bfc602ac4b0ad1438fab ] + +The function idle_thread_get() can return an error pointer and is not +checked for it. Add check for error pointer. + +Detected by Smatch: +arch/x86/hyperv/hv_vtl.c:126 hv_vtl_bringup_vcpu() error: +'idle' dereferencing possible ERR_PTR() + +Fixes: 2b4b90e053a29 ("x86/hyperv: Use per cpu initial stack for vtl context") +Signed-off-by: Ethan Tidmore +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + arch/x86/hyperv/hv_vtl.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c +index 042e8712d8dea..8aafccf7a52c7 100644 +--- a/arch/x86/hyperv/hv_vtl.c ++++ b/arch/x86/hyperv/hv_vtl.c +@@ -105,7 +105,7 @@ static void hv_vtl_ap_entry(void) + + static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) + { +- u64 status; ++ u64 status, rsp, rip; + int ret = 0; + struct hv_enable_vp_vtl *input; + unsigned long irq_flags; +@@ -118,9 +118,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) + struct desc_struct *gdt; + + struct task_struct *idle = idle_thread_get(cpu); +- u64 rsp = (unsigned long)idle->thread.sp; ++ if (IS_ERR(idle)) ++ return PTR_ERR(idle); + +- u64 rip = (u64)&hv_vtl_ap_entry; ++ rsp = (unsigned long)idle->thread.sp; ++ rip = (u64)&hv_vtl_ap_entry; + + native_store_gdt(&gdt_ptr); + store_idt(&idt_ptr); +-- +2.51.0 + diff --git a/queue-6.18/xen-netback-reject-zero-queue-configuration-from-gue.patch b/queue-6.18/xen-netback-reject-zero-queue-configuration-from-gue.patch new file mode 100644 index 0000000000..4decf09386 --- /dev/null +++ b/queue-6.18/xen-netback-reject-zero-queue-configuration-from-gue.patch @@ -0,0 +1,57 @@ +From e5dcdb00001b2b357b4ec6de985d9646e8b2eb6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:40:40 +0000 +Subject: xen-netback: reject zero-queue configuration from guest + +From: Ziyi Guo + +[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ] + +A malicious or buggy Xen guest can write "0" to the xenbus key +"multi-queue-num-queues". The connect() function in the backend only +validates the upper bound (requested_num_queues > xenvif_max_queues) +but not zero, allowing requested_num_queues=0 to reach +vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers +WARN_ON_ONCE(!size) in __vmalloc_node_range(). + +On systems with panic_on_warn=1, this allows a guest-to-host denial +of service. + +The Xen network interface specification requires +the queue count to be "greater than zero". + +Add a zero check to match the validation already present +in xen-blkback, which has included this +guard since its multi-queue support was added. + +Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues") +Signed-off-by: Ziyi Guo +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/xen-netback/xenbus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index a78a25b872409..61b547aab286a 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -735,10 +735,11 @@ static void connect(struct backend_info *be) + */ + requested_num_queues = xenbus_read_unsigned(dev->otherend, + "multi-queue-num-queues", 1); +- if (requested_num_queues > xenvif_max_queues) { ++ if (requested_num_queues > xenvif_max_queues || ++ requested_num_queues == 0) { + /* buggy or malicious guest */ + xenbus_dev_fatal(dev, -EINVAL, +- "guest requested %u queues, exceeding the maximum of %u.", ++ "guest requested %u queues, but valid range is 1 - %u.", + requested_num_queues, xenvif_max_queues); + return; + } +-- +2.51.0 + diff --git a/queue-6.19/acpi-button-adjust-event-notification-routines.patch b/queue-6.19/acpi-button-adjust-event-notification-routines.patch new file mode 100644 index 0000000000..83733f95a2 --- /dev/null +++ b/queue-6.19/acpi-button-adjust-event-notification-routines.patch @@ -0,0 +1,262 @@ +From 3cf8856fd1a42acdd11e46712f0c261ba34d50ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Dec 2025 14:55:09 +0100 +Subject: ACPI: button: Adjust event notification routines + +From: Rafael J. Wysocki + +[ Upstream commit 93dc5db6d47aaa3b4b458ddfddfa3369c24e22f4 ] + +Adjust the event notification routines in the ACPI button driver to +take a struct acpi_button pointer as an argument istead of a struct +acpi_device one where applicable, which allows the use of +acpi_driver_data() to be limited and will facilitate subsequent +changes. + +No intentional functional impact. + +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/2260995.Icojqenx9y@rafael.j.wysocki +Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe") +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 67 +++++++++++++++++++++---------------------- + 1 file changed, 33 insertions(+), 34 deletions(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 3c6dd9b4ba0ad..09a6e4ffe9f20 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -169,6 +169,7 @@ static struct acpi_driver acpi_button_driver = { + }; + + struct acpi_button { ++ struct acpi_device *adev; + unsigned int type; + struct input_dev *input; + char phys[32]; /* for input device */ +@@ -202,9 +203,9 @@ static int acpi_lid_evaluate_state(struct acpi_device *device) + return lid_state ? 1 : 0; + } + +-static int acpi_lid_notify_state(struct acpi_device *device, int state) ++static int acpi_lid_notify_state(struct acpi_button *button, int state) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + ktime_t next_report; + bool do_update; + +@@ -287,18 +288,18 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) + static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq, + void *offset) + { +- struct acpi_device *device = seq->private; ++ struct acpi_button *button = seq->private; + int state; + +- state = acpi_lid_evaluate_state(device); ++ state = acpi_lid_evaluate_state(button->adev); + seq_printf(seq, "state: %s\n", + state < 0 ? "unsupported" : (state ? "open" : "closed")); + return 0; + } + +-static int acpi_button_add_fs(struct acpi_device *device) ++static int acpi_button_add_fs(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + struct proc_dir_entry *entry = NULL; + int ret = 0; + +@@ -333,7 +334,7 @@ static int acpi_button_add_fs(struct acpi_device *device) + /* create /proc/acpi/button/lid/LID/state */ + entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO, + acpi_device_dir(device), acpi_button_state_seq_show, +- device); ++ button); + if (!entry) { + ret = -ENODEV; + goto remove_dev_dir; +@@ -355,9 +356,9 @@ static int acpi_button_add_fs(struct acpi_device *device) + goto done; + } + +-static int acpi_button_remove_fs(struct acpi_device *device) ++static int acpi_button_remove_fs(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = button->adev; + + if (button->type != ACPI_BUTTON_TYPE_LID) + return 0; +@@ -385,9 +386,10 @@ int acpi_lid_open(void) + } + EXPORT_SYMBOL(acpi_lid_open); + +-static int acpi_lid_update_state(struct acpi_device *device, ++static int acpi_lid_update_state(struct acpi_button *button, + bool signal_wakeup) + { ++ struct acpi_device *device = button->adev; + int state; + + state = acpi_lid_evaluate_state(device); +@@ -397,19 +399,17 @@ static int acpi_lid_update_state(struct acpi_device *device, + if (state && signal_wakeup) + acpi_pm_wakeup_event(&device->dev); + +- return acpi_lid_notify_state(device, state); ++ return acpi_lid_notify_state(button, state); + } + +-static void acpi_lid_initialize_state(struct acpi_device *device) ++static void acpi_lid_initialize_state(struct acpi_button *button) + { +- struct acpi_button *button = acpi_driver_data(device); +- + switch (lid_init_state) { + case ACPI_BUTTON_LID_INIT_OPEN: +- (void)acpi_lid_notify_state(device, 1); ++ (void)acpi_lid_notify_state(button, 1); + break; + case ACPI_BUTTON_LID_INIT_METHOD: +- (void)acpi_lid_update_state(device, false); ++ (void)acpi_lid_update_state(button, false); + break; + case ACPI_BUTTON_LID_INIT_IGNORE: + default: +@@ -421,8 +421,8 @@ static void acpi_lid_initialize_state(struct acpi_device *device) + + static void acpi_lid_notify(acpi_handle handle, u32 event, void *data) + { +- struct acpi_device *device = data; +- struct acpi_button *button; ++ struct acpi_button *button = data; ++ struct acpi_device *device = button->adev; + + if (event != ACPI_BUTTON_NOTIFY_STATUS) { + acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", +@@ -430,17 +430,16 @@ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data) + return; + } + +- button = acpi_driver_data(device); + if (!button->lid_state_initialized) + return; + +- acpi_lid_update_state(device, true); ++ acpi_lid_update_state(button, true); + } + + static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + { +- struct acpi_device *device = data; +- struct acpi_button *button; ++ struct acpi_button *button = data; ++ struct acpi_device *device = button->adev; + struct input_dev *input; + int keycode; + +@@ -457,7 +456,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + + acpi_pm_wakeup_event(&device->dev); + +- button = acpi_driver_data(device); + if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) + return; + +@@ -505,7 +503,7 @@ static int acpi_button_resume(struct device *dev) + if (button->type == ACPI_BUTTON_TYPE_LID) { + button->last_state = !!acpi_lid_evaluate_state(device); + button->last_time = ktime_get(); +- acpi_lid_initialize_state(device); ++ acpi_lid_initialize_state(button); + } + + if (button->type == ACPI_BUTTON_TYPE_POWER) { +@@ -521,12 +519,12 @@ static int acpi_button_resume(struct device *dev) + + static int acpi_lid_input_open(struct input_dev *input) + { +- struct acpi_device *device = input_get_drvdata(input); +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_button *button = input_get_drvdata(input); ++ struct acpi_device *device = button->adev; + + button->last_state = !!acpi_lid_evaluate_state(device); + button->last_time = ktime_get(); +- acpi_lid_initialize_state(device); ++ acpi_lid_initialize_state(button); + + return 0; + } +@@ -551,6 +549,7 @@ static int acpi_button_add(struct acpi_device *device) + + device->driver_data = button; + ++ button->adev = device; + button->input = input = input_allocate_device(); + if (!input) { + error = -ENOMEM; +@@ -587,7 +586,7 @@ static int acpi_button_add(struct acpi_device *device) + } + + if (!error) +- error = acpi_button_add_fs(device); ++ error = acpi_button_add_fs(button); + + if (error) { + input_free_device(input); +@@ -617,7 +616,7 @@ static int acpi_button_add(struct acpi_device *device) + break; + } + +- input_set_drvdata(input, device); ++ input_set_drvdata(input, button); + error = input_register_device(input); + if (error) { + input_free_device(input); +@@ -628,17 +627,17 @@ static int acpi_button_add(struct acpi_device *device) + case ACPI_BUS_TYPE_POWER_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_button_event, +- device); ++ button); + break; + case ACPI_BUS_TYPE_SLEEP_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_button_event, +- device); ++ button); + break; + default: + status = acpi_install_notify_handler(device->handle, + ACPI_ALL_NOTIFY, handler, +- device); ++ button); + break; + } + if (ACPI_FAILURE(status)) { +@@ -661,7 +660,7 @@ static int acpi_button_add(struct acpi_device *device) + err_input_unregister: + input_unregister_device(input); + err_remove_fs: +- acpi_button_remove_fs(device); ++ acpi_button_remove_fs(button); + err_free_button: + kfree(button); + return error; +@@ -689,7 +688,7 @@ static void acpi_button_remove(struct acpi_device *device) + } + acpi_os_wait_events_complete(); + +- acpi_button_remove_fs(device); ++ acpi_button_remove_fs(button); + input_unregister_device(button->input); + kfree(button); + } +-- +2.51.0 + diff --git a/queue-6.19/acpi-button-call-device_init_wakeup-earlier-during-p.patch b/queue-6.19/acpi-button-call-device_init_wakeup-earlier-during-p.patch new file mode 100644 index 0000000000..107729a4cc --- /dev/null +++ b/queue-6.19/acpi-button-call-device_init_wakeup-earlier-during-p.patch @@ -0,0 +1,67 @@ +From 83d9fbf06e5510e15fe000aceb8a2e52dbf4a1ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 15:13:26 +0100 +Subject: ACPI: button: Call device_init_wakeup() earlier during probe + +From: Rafael J. Wysocki + +[ Upstream commit e91f8c5305b92b63c8bac315f95c535d5c1e8fec ] + +Calling device_init_wakeup() after installing a notify handler in which +wakeup events are signaled may cause a wakeup event to be missed if the +device is probed right before a system suspend. + +To avoid this, move the device_init_wakeup() call in acpi_button_probe() +before the notify handler installation and add a corresponding cleanup +to the error path. + +Also carry out wakeup cleanup for the button in acpi_button_remove() +because after that point the notify handler will not run for it and +wakeup events coming from it will not be signaled. + +Fixes: 0d51157dfaac ("ACPI: button: Eliminate the driver notify callback") +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/12854922.O9o76ZdvQC@rafael.j.wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index b899b8745fedd..38bc64d6bdaf3 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -625,6 +625,8 @@ static int acpi_button_probe(struct platform_device *pdev) + goto err_remove_fs; + } + ++ device_init_wakeup(&pdev->dev, true); ++ + switch (device->device_type) { + case ACPI_BUS_TYPE_POWER_BUTTON: + status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, +@@ -655,11 +657,11 @@ static int acpi_button_probe(struct platform_device *pdev) + lid_device = device; + } + +- device_init_wakeup(&pdev->dev, true); + pr_info("%s [%s]\n", name, acpi_device_bid(device)); + return 0; + + err_input_unregister: ++ device_init_wakeup(&pdev->dev, false); + input_unregister_device(input); + err_remove_fs: + acpi_button_remove_fs(button); +@@ -691,6 +693,8 @@ static void acpi_button_remove(struct platform_device *pdev) + } + acpi_os_wait_events_complete(); + ++ device_init_wakeup(&pdev->dev, false); ++ + acpi_button_remove_fs(button); + input_unregister_device(button->input); + kfree(button); +-- +2.51.0 + diff --git a/queue-6.19/acpi-button-convert-the-driver-to-a-platform-one.patch b/queue-6.19/acpi-button-convert-the-driver-to-a-platform-one.patch new file mode 100644 index 0000000000..2eaabe62aa --- /dev/null +++ b/queue-6.19/acpi-button-convert-the-driver-to-a-platform-one.patch @@ -0,0 +1,211 @@ +From dd0277042a50c38fee804c39f50c9200163693b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Dec 2025 14:57:57 +0100 +Subject: ACPI: button: Convert the driver to a platform one + +From: Rafael J. Wysocki + +[ Upstream commit 52d86401963666423cb9a56d117136c846093db0 ] + +While binding drivers directly to struct acpi_device objects allows +basic functionality to be provided, at least in the majority of cases, +there are some problems with it, related to general consistency, sysfs +layout, power management operation ordering, and code cleanliness. + +Overall, it is better to bind drivers to platform devices than to their +ACPI companions, so convert the ACPI button driver to a platform one. + +While this is not expected to alter functionality, it changes sysfs +layout and so it will be visible to user space. + +Signed-off-by: Rafael J. Wysocki +Link: https://patch.msgid.link/2461734.NG923GbCHz@rafael.j.wysocki +Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe") +Signed-off-by: Sasha Levin +--- + drivers/acpi/button.c | 61 +++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 29 deletions(-) + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 09a6e4ffe9f20..b899b8745fedd 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + + #define ACPI_BUTTON_CLASS "button" +@@ -145,8 +146,8 @@ static const struct dmi_system_id dmi_lid_quirks[] = { + {} + }; + +-static int acpi_button_add(struct acpi_device *device); +-static void acpi_button_remove(struct acpi_device *device); ++static int acpi_button_probe(struct platform_device *pdev); ++static void acpi_button_remove(struct platform_device *pdev); + + #ifdef CONFIG_PM_SLEEP + static int acpi_button_suspend(struct device *dev); +@@ -157,19 +158,19 @@ static int acpi_button_resume(struct device *dev); + #endif + static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume); + +-static struct acpi_driver acpi_button_driver = { +- .name = "button", +- .class = ACPI_BUTTON_CLASS, +- .ids = button_device_ids, +- .ops = { +- .add = acpi_button_add, +- .remove = acpi_button_remove, ++static struct platform_driver acpi_button_driver = { ++ .probe = acpi_button_probe, ++ .remove = acpi_button_remove, ++ .driver = { ++ .name = "acpi-button", ++ .acpi_match_table = button_device_ids, ++ .pm = &acpi_button_pm, + }, +- .drv.pm = &acpi_button_pm, + }; + + struct acpi_button { + struct acpi_device *adev; ++ struct platform_device *pdev; + unsigned int type; + struct input_dev *input; + char phys[32]; /* for input device */ +@@ -397,7 +398,7 @@ static int acpi_lid_update_state(struct acpi_button *button, + return state; + + if (state && signal_wakeup) +- acpi_pm_wakeup_event(&device->dev); ++ acpi_pm_wakeup_event(&button->pdev->dev); + + return acpi_lid_notify_state(button, state); + } +@@ -454,7 +455,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) + return; + } + +- acpi_pm_wakeup_event(&device->dev); ++ acpi_pm_wakeup_event(&button->pdev->dev); + + if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) + return; +@@ -486,8 +487,7 @@ static u32 acpi_button_event(void *data) + #ifdef CONFIG_PM_SLEEP + static int acpi_button_suspend(struct device *dev) + { +- struct acpi_device *device = to_acpi_device(dev); +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_button *button = dev_get_drvdata(dev); + + button->suspended = true; + return 0; +@@ -495,9 +495,9 @@ static int acpi_button_suspend(struct device *dev) + + static int acpi_button_resume(struct device *dev) + { ++ struct acpi_button *button = dev_get_drvdata(dev); ++ struct acpi_device *device = ACPI_COMPANION(dev); + struct input_dev *input; +- struct acpi_device *device = to_acpi_device(dev); +- struct acpi_button *button = acpi_driver_data(device); + + button->suspended = false; + if (button->type == ACPI_BUTTON_TYPE_LID) { +@@ -529,8 +529,9 @@ static int acpi_lid_input_open(struct input_dev *input) + return 0; + } + +-static int acpi_button_add(struct acpi_device *device) ++static int acpi_button_probe(struct platform_device *pdev) + { ++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev); + acpi_notify_handler handler; + struct acpi_button *button; + struct input_dev *input; +@@ -547,8 +548,9 @@ static int acpi_button_add(struct acpi_device *device) + if (!button) + return -ENOMEM; + +- device->driver_data = button; ++ platform_set_drvdata(pdev, button); + ++ button->pdev = pdev; + button->adev = device; + button->input = input = input_allocate_device(); + if (!input) { +@@ -599,7 +601,7 @@ static int acpi_button_add(struct acpi_device *device) + input->phys = button->phys; + input->id.bustype = BUS_HOST; + input->id.product = button->type; +- input->dev.parent = &device->dev; ++ input->dev.parent = &pdev->dev; + + switch (button->type) { + case ACPI_BUTTON_TYPE_POWER: +@@ -653,7 +655,7 @@ static int acpi_button_add(struct acpi_device *device) + lid_device = device; + } + +- device_init_wakeup(&device->dev, true); ++ device_init_wakeup(&pdev->dev, true); + pr_info("%s [%s]\n", name, acpi_device_bid(device)); + return 0; + +@@ -666,9 +668,10 @@ static int acpi_button_add(struct acpi_device *device) + return error; + } + +-static void acpi_button_remove(struct acpi_device *device) ++static void acpi_button_remove(struct platform_device *pdev) + { +- struct acpi_button *button = acpi_driver_data(device); ++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev); ++ struct acpi_button *button = platform_get_drvdata(pdev); + + switch (device->device_type) { + case ACPI_BUS_TYPE_POWER_BUTTON: +@@ -727,7 +730,7 @@ module_param_call(lid_init_state, + NULL, 0644); + MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state"); + +-static int acpi_button_register_driver(struct acpi_driver *driver) ++static int __init acpi_button_init(void) + { + const struct dmi_system_id *dmi_id; + +@@ -743,20 +746,20 @@ static int acpi_button_register_driver(struct acpi_driver *driver) + * Modules such as nouveau.ko and i915.ko have a link time dependency + * on acpi_lid_open(), and would therefore not be loadable on ACPI + * capable kernels booted in non-ACPI mode if the return value of +- * acpi_bus_register_driver() is returned from here with ACPI disabled ++ * platform_driver_register() is returned from here with ACPI disabled + * when this driver is built as a module. + */ + if (acpi_disabled) + return 0; + +- return acpi_bus_register_driver(driver); ++ return platform_driver_register(&acpi_button_driver); + } + +-static void acpi_button_unregister_driver(struct acpi_driver *driver) ++static void __exit acpi_button_exit(void) + { + if (!acpi_disabled) +- acpi_bus_unregister_driver(driver); ++ platform_driver_unregister(&acpi_button_driver); + } + +-module_driver(acpi_button_driver, acpi_button_register_driver, +- acpi_button_unregister_driver); ++module_init(acpi_button_init); ++module_exit(acpi_button_exit); +-- +2.51.0 + diff --git a/queue-6.19/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch b/queue-6.19/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch new file mode 100644 index 0000000000..02bf7b1655 --- /dev/null +++ b/queue-6.19/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch @@ -0,0 +1,55 @@ +From 830dbf7eac6d0fef5e8ffbb65b2c383f340a377c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 21:22:54 +0000 +Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs + +From: Sean V Kelley + +[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ] + +per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online +CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> +acpi_cppc_processor_probe(). + +However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all +possible CPUs. In acpi_get_psd_map(), encountering an offline CPU +returns -EFAULT, causing cppc_cpufreq initialization to fail. + +This breaks systems booted with "nosmt" or "nosmt=force". + +Fix by using for_each_online_cpu() in both functions. + +Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests") +Signed-off-by: Sean V Kelley +Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index e66e20d1f31b7..b59b0100d03c5 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -362,7 +362,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) + end: + if (cmd == CMD_WRITE) { + if (unlikely(ret)) { +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i); + + if (!desc) +@@ -524,7 +524,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data) + else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) + cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; + +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + if (i == cpu) + continue; + +-- +2.51.0 + diff --git a/queue-6.19/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch b/queue-6.19/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch new file mode 100644 index 0000000000..c6daaa69fd --- /dev/null +++ b/queue-6.19/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch @@ -0,0 +1,67 @@ +From 02b5a6a096df33c81d5f404e281ce8c17e5f4a5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Feb 2026 00:14:52 +0800 +Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO + +From: Zhai Can + +[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ] + +On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete +NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table +bug (lack of reference), PXP will be shut dow as an "unused" power resource +during initialization, making the NVMe slot #2 + NVIDIA both inaccessible. + +This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check +states of power resources during initialization"). Here are test +results on the three consecutive commits: + +(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization +(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state +(bad) 519d81956ee2 Linux 5.15-rc6 + +On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in +unknown state") this was not an issue because the power resource state +left UNKNOWN thus being ignored. + +See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power +resources on the Toshiba Click Mini") which is another almost identical +case to this one. + +Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization") +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087 +Signed-off-by: Zhai Can +Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/power.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c +index 361a7721a6a87..7da5ae5594a72 100644 +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -1113,6 +1113,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"), + }, + }, ++ { ++ /* ++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power ++ * resource 'PXP' will be shut down on initialization, making ++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're ++ * both controlled by 'PXP'). ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"), ++ } ++ ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.19/apparmor-account-for-in_atomic-removal-in-common_fil.patch b/queue-6.19/apparmor-account-for-in_atomic-removal-in-common_fil.patch new file mode 100644 index 0000000000..bd0972b850 --- /dev/null +++ b/queue-6.19/apparmor-account-for-in_atomic-removal-in-common_fil.patch @@ -0,0 +1,46 @@ +From dde4a2b45799fb219342200012ee174df93e65f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jan 2026 11:47:02 -0800 +Subject: apparmor: account for in_atomic removal in common_file_perm + +From: Ryan Lee + +[ Upstream commit 9b829c0aa96e9385b1e9a308d3eb054b95fbeda2 ] + +If we are not in an atomic context in common_file_perm, then we don't have +to use the atomic versions, resulting in improved performance outside of +atomic contexts. + +Signed-off-by: Ryan Lee +Signed-off-by: John Johansen +Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases") +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index e59e9bc7250bf..f47d60d8c40a2 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -524,15 +524,14 @@ static int common_file_perm(const char *op, struct file *file, u32 mask) + { + struct aa_label *label; + int error = 0; +- bool needput; + + /* don't reaudit files closed during inheritance */ + if (unlikely(file->f_path.dentry == aa_null.dentry)) + return -EACCES; + +- label = __begin_current_label_crit_section(&needput); ++ label = begin_current_label_crit_section(); + error = aa_file_perm(op, current_cred(), label, file, mask, false); +- __end_current_label_crit_section(label, needput); ++ end_current_label_crit_section(label); + + return error; + } +-- +2.51.0 + diff --git a/queue-6.19/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch b/queue-6.19/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch new file mode 100644 index 0000000000..9c6792d54d --- /dev/null +++ b/queue-6.19/apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch @@ -0,0 +1,108 @@ +From 1c58ed4ed387c6826da6ec38ff4b6234d568024f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 16:11:07 +0100 +Subject: AppArmor: Allow apparmor to handle unaligned dfa tables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Helge Deller + +[ Upstream commit 64802f731214a51dfe3c6c27636b3ddafd003eb0 ] + +The dfa tables can originate from kernel or userspace and 8-byte alignment +isn't always guaranteed and as such may trigger unaligned memory accesses +on various architectures. Resulting in the following + +[   73.901376] WARNING: CPU: 0 PID: 341 at security/apparmor/match.c:316 aa_dfa_unpack+0x6cc/0x720 +[   74.015867] Modules linked in: binfmt_misc evdev flash sg drm drm_panel_orientation_quirks backlight i2c_core configfs nfnetlink autofs4 ext4 crc16 mbcache jbd2 hid_generic usbhid sr_mod hid cdrom +sd_mod ata_generic ohci_pci ehci_pci ehci_hcd ohci_hcd pata_ali libata sym53c8xx scsi_transport_spi tg3 scsi_mod usbcore libphy scsi_common mdio_bus usb_common +[   74.428977] CPU: 0 UID: 0 PID: 341 Comm: apparmor_parser Not tainted 6.18.0-rc6+ #9 NONE +[   74.536543] Call Trace: +[   74.568561] [<0000000000434c24>] dump_stack+0x8/0x18 +[   74.633757] [<0000000000476438>] __warn+0xd8/0x100 +[   74.696664] [<00000000004296d4>] warn_slowpath_fmt+0x34/0x74 +[   74.771006] [<00000000008db28c>] aa_dfa_unpack+0x6cc/0x720 +[   74.843062] [<00000000008e643c>] unpack_pdb+0xbc/0x7e0 +[   74.910545] [<00000000008e7740>] unpack_profile+0xbe0/0x1300 +[   74.984888] [<00000000008e82e0>] aa_unpack+0xe0/0x6a0 +[   75.051226] [<00000000008e3ec4>] aa_replace_profiles+0x64/0x1160 +[   75.130144] [<00000000008d4d90>] policy_update+0xf0/0x280 +[   75.201057] [<00000000008d4fc8>] profile_replace+0xa8/0x100 +[   75.274258] [<0000000000766bd0>] vfs_write+0x90/0x420 +[   75.340594] [<00000000007670cc>] ksys_write+0x4c/0xe0 +[   75.406932] [<0000000000767174>] sys_write+0x14/0x40 +[   75.472126] [<0000000000406174>] linux_sparc_syscall+0x34/0x44 +[   75.548802] ---[ end trace 0000000000000000 ]--- +[   75.609503] dfa blob stream 0xfff0000008926b96 not aligned. +[   75.682695] Kernel unaligned access at TPC[8db2a8] aa_dfa_unpack+0x6e8/0x720 + +Work around it by using the get_unaligned_xx() helpers. + +Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack") +Reported-by: John Paul Adrian Glaubitz +Closes: https://github.com/sparclinux/issues/issues/30 +Signed-off-by: Helge Deller +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/match.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/security/apparmor/match.c b/security/apparmor/match.c +index c5a91600842a1..26e82ba879d44 100644 +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include "include/lib.h" + #include "include/match.h" +@@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize) + /* loaded td_id's start at 1, subtract 1 now to avoid doing + * it every time we use td_id as an index + */ +- th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1; ++ th.td_id = get_unaligned_be16(blob) - 1; + if (th.td_id > YYTD_ID_MAX) + goto out; +- th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2)); +- th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8)); ++ th.td_flags = get_unaligned_be16(blob + 2); ++ th.td_lolen = get_unaligned_be32(blob + 8); + blob += sizeof(struct table_header); + + if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || +@@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) + if (size < sizeof(struct table_set_header)) + goto fail; + +- if (ntohl(*(__be32 *) data) != YYTH_MAGIC) ++ if (get_unaligned_be32(data) != YYTH_MAGIC) + goto fail; + +- hsize = ntohl(*(__be32 *) (data + 4)); ++ hsize = get_unaligned_be32(data + 4); + if (size < hsize) + goto fail; + +- dfa->flags = ntohs(*(__be16 *) (data + 12)); ++ dfa->flags = get_unaligned_be16(data + 12); + if (dfa->flags & ~(YYTH_FLAGS)) + goto fail; + +@@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) + * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) { + * if (hsize < 16 + 4) + * goto fail; +- * dfa->max_oob = ntol(*(__be32 *) (data + 16)); ++ * dfa->max_oob = get_unaligned_be32(data + 16); + * if (dfa->max <= MAX_OOB_SUPPORTED) { + * pr_err("AppArmor DFA OOB greater than supported\n"); + * goto fail; +-- +2.51.0 + diff --git a/queue-6.19/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch b/queue-6.19/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch new file mode 100644 index 0000000000..0e72c6d95d --- /dev/null +++ b/queue-6.19/apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch @@ -0,0 +1,43 @@ +From 2a404714d96d85754bad4573a562486719f48958 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Jan 2026 19:03:07 -0500 +Subject: apparmor: avoid per-cpu hold underflow in aa_get_buffer + +From: Zhengmian Hu + +[ Upstream commit 640cf2f09575c9dc344b3f7be2498d31e3923ead ] + +When aa_get_buffer() pulls from the per-cpu list it unconditionally +decrements cache->hold. If hold reaches 0 while count is still non-zero, +the unsigned decrement wraps to UINT_MAX. This keeps hold non-zero for a +very long time, so aa_put_buffer() never returns buffers to the global +list, which can starve other CPUs and force repeated kmalloc(aa_g_path_max) +allocations. + +Guard the decrement so hold never underflows. +Fixes: ea9bae12d028 ("apparmor: cache buffers on percpu list if there is lock contention") + +Signed-off-by: Zhengmian Hu +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 8d5d9a966b719..9175fd677ef3d 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -2137,7 +2137,8 @@ char *aa_get_buffer(bool in_atomic) + if (!list_empty(&cache->head)) { + aa_buf = list_first_entry(&cache->head, union aa_buffer, list); + list_del(&aa_buf->list); +- cache->hold--; ++ if (cache->hold) ++ cache->hold--; + cache->count--; + put_cpu_ptr(&aa_local_buffers); + return &aa_buf->buffer[0]; +-- +2.51.0 + diff --git a/queue-6.19/apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch b/queue-6.19/apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch new file mode 100644 index 0000000000..eef55b85b8 --- /dev/null +++ b/queue-6.19/apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch @@ -0,0 +1,102 @@ +From ef3d963f20fb8acb77ca84b275eec4d4e69b1b6e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jan 2026 23:40:03 -0800 +Subject: apparmor: drop in_atomic flag in common_mmap, and common_file_perm + +From: John Johansen + +[ Upstream commit c3f27ccdb2dce3f0f2814574d06017f46c11fa29 ] + +with the previous changes to mmap the in_atomic flag is now always +false, so drop it. + +Suggested-by: Tyler Hicks +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases") +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index acca3d6efdbc8..e59e9bc7250bf 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -520,8 +520,7 @@ static void apparmor_file_free_security(struct file *file) + aa_put_label(rcu_access_pointer(ctx->label)); + } + +-static int common_file_perm(const char *op, struct file *file, u32 mask, +- bool in_atomic) ++static int common_file_perm(const char *op, struct file *file, u32 mask) + { + struct aa_label *label; + int error = 0; +@@ -532,7 +531,7 @@ static int common_file_perm(const char *op, struct file *file, u32 mask, + return -EACCES; + + label = __begin_current_label_crit_section(&needput); +- error = aa_file_perm(op, current_cred(), label, file, mask, in_atomic); ++ error = aa_file_perm(op, current_cred(), label, file, mask, false); + __end_current_label_crit_section(label, needput); + + return error; +@@ -540,13 +539,12 @@ static int common_file_perm(const char *op, struct file *file, u32 mask, + + static int apparmor_file_receive(struct file *file) + { +- return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file), +- false); ++ return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file)); + } + + static int apparmor_file_permission(struct file *file, int mask) + { +- return common_file_perm(OP_FPERM, file, mask, false); ++ return common_file_perm(OP_FPERM, file, mask); + } + + static int apparmor_file_lock(struct file *file, unsigned int cmd) +@@ -556,11 +554,11 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd) + if (cmd == F_WRLCK) + mask |= MAY_WRITE; + +- return common_file_perm(OP_FLOCK, file, mask, false); ++ return common_file_perm(OP_FLOCK, file, mask); + } + + static int common_mmap(const char *op, struct file *file, unsigned long prot, +- unsigned long flags, bool in_atomic) ++ unsigned long flags) + { + int mask = 0; + +@@ -578,21 +576,20 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot, + if (prot & PROT_EXEC) + mask |= AA_EXEC_MMAP; + +- return common_file_perm(op, file, mask, in_atomic); ++ return common_file_perm(op, file, mask); + } + + static int apparmor_mmap_file(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) + { +- return common_mmap(OP_FMMAP, file, prot, flags, false); ++ return common_mmap(OP_FMMAP, file, prot, flags); + } + + static int apparmor_file_mprotect(struct vm_area_struct *vma, + unsigned long reqprot, unsigned long prot) + { + return common_mmap(OP_FMPROT, vma->vm_file, prot, +- !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0, +- false); ++ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); + } + + #ifdef CONFIG_IO_URING +-- +2.51.0 + diff --git a/queue-6.19/apparmor-fix-aa_label-to-return-state-from-compount-.patch b/queue-6.19/apparmor-fix-aa_label-to-return-state-from-compount-.patch new file mode 100644 index 0000000000..12f56c56ff --- /dev/null +++ b/queue-6.19/apparmor-fix-aa_label-to-return-state-from-compount-.patch @@ -0,0 +1,74 @@ +From c9e954da7a926569883b7d807b078863d6aaad38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 04:12:02 -0800 +Subject: apparmor: fix aa_label to return state from compount and component + match + +From: John Johansen + +[ Upstream commit 9058798652c8bc0584ed1fb0766a1015046c06e8 ] + +aa-label_match is not correctly returning the state in all cases. +The only reason this didn't cause a error is that all callers currently +ignore the return value. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202602020631.wXgZosyU-lkp@intel.com/ +Fixes: a4c9efa4dbad6 ("apparmor: make label_match return a consistent value") +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 1d3fa5c28d97f..dd6c58f595ba8 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1334,7 +1334,7 @@ static int label_compound_match(struct aa_profile *profile, + * @request: permissions to request + * @perms: an initialized perms struct to add accumulation to + * +- * Returns: 0 on success else ERROR ++ * Returns: the state the match finished in, may be the none matching state + * + * For the label A//&B//&C this does the perm match for each of A and B and C + * @perms should be preinitialized with allperms OR a previous permission +@@ -1362,7 +1362,7 @@ static int label_components_match(struct aa_profile *profile, + } + + /* no subcomponents visible - no change in perms */ +- return 0; ++ return state; + + next: + tmp = *aa_lookup_perms(rules->policy, state); +@@ -1378,13 +1378,13 @@ static int label_components_match(struct aa_profile *profile, + } + + if ((perms->allow & request) != request) +- return -EACCES; ++ return DFA_NOMATCH; + +- return 0; ++ return state; + + fail: + *perms = nullperms; +- return -EACCES; ++ return DFA_NOMATCH; + } + + /** +@@ -1406,7 +1406,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, + aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, + request, perms); + if ((perms->allow & request) == request) +- return 0; ++ return tmp; + + /* failed compound_match try component matches */ + *perms = allperms; +-- +2.51.0 + diff --git a/queue-6.19/apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch b/queue-6.19/apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch new file mode 100644 index 0000000000..0774d1483b --- /dev/null +++ b/queue-6.19/apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch @@ -0,0 +1,38 @@ +From 6775582be816bb7a873e9b20dcf53cb830308caf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jan 2026 11:48:54 -0800 +Subject: apparmor: fix boolean argument in apparmor_mmap_file + +From: Ryan Lee + +[ Upstream commit 48d5268e911abcf7674ec33c9b0b3e952be1175e ] + +The previous value of GFP_ATOMIC is an int and not a bool, potentially +resulting in UB when being assigned to a bool. In addition, the mmap hook +is called outside of locks (i.e. in a non-atomic context), so we can pass +a fixed constant value of false instead to common_mmap. + +Signed-off-by: Ryan Lee +Signed-off-by: John Johansen +Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases") +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index a87cd60ed2069..acca3d6efdbc8 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -584,7 +584,7 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot, + static int apparmor_mmap_file(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) + { +- return common_mmap(OP_FMMAP, file, prot, flags, GFP_ATOMIC); ++ return common_mmap(OP_FMMAP, file, prot, flags, false); + } + + static int apparmor_file_mprotect(struct vm_area_struct *vma, +-- +2.51.0 + diff --git a/queue-6.19/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch b/queue-6.19/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch new file mode 100644 index 0000000000..f09cc4c76a --- /dev/null +++ b/queue-6.19/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch @@ -0,0 +1,85 @@ +From 4e9afbc90218e04ef8ad4c407b8dfb1dccd0b8cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 15:58:45 -0300 +Subject: apparmor: fix invalid deref of rawdata when export_binary is unset + +From: Georgia Garcia + +[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ] + +If the export_binary parameter is disabled on runtime, profiles that +were loaded before that will still have their rawdata stored in +apparmorfs, with a symbolic link to the rawdata on the policy +directory. When one of those profiles are replaced, the rawdata is set +to NULL, but when trying to resolve the symbolic links to rawdata for +that profile, it will try to dereference profile->rawdata->name when +profile->rawdata is now NULL causing an oops. Fix it by checking if +rawdata is set. + +[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088 +[ 168.657420] #PF: supervisor read access in kernel mode +[ 168.660619] #PF: error_code(0x0000) - not-present page +[ 168.663613] PGD 0 P4D 0 +[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI +[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary) +[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330 +[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8 +[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282 +[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158 +[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80 +[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000 +[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80 +[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0 +[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000 +[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0 +[ 168.701696] Call Trace: +[ 168.702325] +[ 168.702995] rawdata_get_link_data+0x1c/0x30 +[ 168.704145] vfs_readlink+0xd4/0x160 +[ 168.705152] do_readlinkat+0x114/0x180 +[ 168.706214] __x64_sys_readlink+0x1e/0x30 +[ 168.708653] x64_sys_call+0x1d77/0x26b0 +[ 168.709525] do_syscall_64+0x81/0x500 +[ 168.710348] ? do_statx+0x72/0xb0 +[ 168.711109] ? putname+0x3e/0x80 +[ 168.711845] ? __x64_sys_statx+0xb7/0x100 +[ 168.712711] ? x64_sys_call+0x10fc/0x26b0 +[ 168.713577] ? do_syscall_64+0xbf/0x500 +[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0 +[ 168.715404] ? irqentry_exit+0xb2/0x740 +[ 168.716359] ? exc_page_fault+0x90/0x1b0 +[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement") +Signed-off-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index 907bd2667e28c..9252172d50682 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -1644,6 +1644,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry, + + label = aa_get_label_rcu(&proxy->label); + profile = labels_profile(label); ++ ++ /* rawdata can be null when aa_g_export_binary is unset during ++ * runtime and a profile is replaced ++ */ ++ if (!profile->rawdata) { ++ aa_put_label(label); ++ return ERR_PTR(-ENOENT); ++ } ++ + depth = profile_depth(profile); + target = gen_symlink_name(depth, profile->rawdata->name, name); + aa_put_label(label); +-- +2.51.0 + diff --git a/queue-6.19/apparmor-fix-null-pointer-dereference-in-__unix_need.patch b/queue-6.19/apparmor-fix-null-pointer-dereference-in-__unix_need.patch new file mode 100644 index 0000000000..22114c2069 --- /dev/null +++ b/queue-6.19/apparmor-fix-null-pointer-dereference-in-__unix_need.patch @@ -0,0 +1,62 @@ +From 2de19b1fa24e27280c1518f90380ef5d8798e5a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 16:35:00 +0000 +Subject: apparmor: fix NULL pointer dereference in __unix_needs_revalidation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: System Administrator + +[ Upstream commit e2938ad00b21340c0362562dfedd7cfec0554d67 ] + +When receiving file descriptors via SCM_RIGHTS, both the socket pointer +and the socket's sk pointer can be NULL during socket setup or teardown, +causing NULL pointer dereferences in __unix_needs_revalidation(). + +This is a regression in AppArmor 5.0.0 (kernel 6.17+) where the new +__unix_needs_revalidation() function was added without proper NULL checks. + +The crash manifests as: + BUG: kernel NULL pointer dereference, address: 0x0000000000000018 + RIP: aa_file_perm+0xb7/0x3b0 (or +0xbe/0x3b0, +0xc0/0x3e0) + Call Trace: + apparmor_file_receive+0x42/0x80 + security_file_receive+0x2e/0x50 + receive_fd+0x1d/0xf0 + scm_detach_fds+0xad/0x1c0 + +The function dereferences sock->sk->sk_family without checking if either +sock or sock->sk is NULL first. + +Add NULL checks for both sock and sock->sk before accessing sk_family. + +Fixes: 88fec3526e841 ("apparmor: make sure unix socket labeling is correctly updated.") +Reported-by: Jamin Mc +Closes: https://bugzilla.proxmox.com/show_bug.cgi?id=7083 +Closes: https://gitlab.com/apparmor/apparmor/-/issues/568 +Signed-off-by: Fabian Grünbichler +Signed-off-by: System Administrator +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/file.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/security/apparmor/file.c b/security/apparmor/file.c +index c758204028780..919dbbbc87ab6 100644 +--- a/security/apparmor/file.c ++++ b/security/apparmor/file.c +@@ -578,6 +578,9 @@ static bool __unix_needs_revalidation(struct file *file, struct aa_label *label, + return false; + if (request & NET_PEER_MASK) + return false; ++ /* sock and sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return false; + if (sock->sk->sk_family == PF_UNIX) { + struct aa_sk_ctx *ctx = aa_sock(sock->sk); + +-- +2.51.0 + diff --git a/queue-6.19/apparmor-fix-null-sock-in-aa_sock_file_perm.patch b/queue-6.19/apparmor-fix-null-sock-in-aa_sock_file_perm.patch new file mode 100644 index 0000000000..d0db05e1b6 --- /dev/null +++ b/queue-6.19/apparmor-fix-null-sock-in-aa_sock_file_perm.patch @@ -0,0 +1,44 @@ +From 1ff82b6dd23e85350eddd80a3012f0c06174007d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:07:42 -0800 +Subject: apparmor: fix NULL sock in aa_sock_file_perm + +From: John Johansen + +[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ] + +Deal with the potential that sock and sock-sk can be NULL during +socket setup or teardown. This could lead to an oops. The fix for NULL +pointer dereference in __unix_needs_revalidation shows this is at +least possible for af_unix sockets. While the fix for af_unix sockets +applies for newer mediation this is still the fall back path for older +af_unix mediation and other sockets, so ensure it is covered. + +Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/net.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 45cf25605c345..44c04102062f3 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -326,8 +326,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, + struct socket *sock = (struct socket *) file->private_data; + + AA_BUG(!label); +- AA_BUG(!sock); +- AA_BUG(!sock->sk); ++ ++ /* sock && sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return 0; + + if (sock->sk->sk_family == PF_UNIX) + return aa_unix_file_perm(subj_cred, label, op, request, file); +-- +2.51.0 + diff --git a/queue-6.19/apparmor-fix-optimize-table-creation-from-possibly-u.patch b/queue-6.19/apparmor-fix-optimize-table-creation-from-possibly-u.patch new file mode 100644 index 0000000000..8f62e6fa79 --- /dev/null +++ b/queue-6.19/apparmor-fix-optimize-table-creation-from-possibly-u.patch @@ -0,0 +1,79 @@ +From 12e6db0161cccdf915b75e6250423e1686295a63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 21:15:04 +0100 +Subject: apparmor: Fix & Optimize table creation from possibly unaligned + memory + +From: Helge Deller + +[ Upstream commit 6fc367bfd4c8886e6b1742aabbd1c0bdc310db3a ] + +Source blob may come from userspace and might be unaligned. +Try to optize the copying process by avoiding unaligned memory accesses. + +- Added Fixes tag +- Added "Fix &" to description as this doesn't just optimize but fixes + a potential unaligned memory access +Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack") +Signed-off-by: Helge Deller +[jj: remove duplicate word "convert" in comment trigger checkpatch warning] +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/include/match.h | 12 +++++++----- + security/apparmor/match.c | 7 +++---- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h +index 1fbe82f5021b1..0dde8eda3d1a5 100644 +--- a/security/apparmor/include/match.h ++++ b/security/apparmor/include/match.h +@@ -104,16 +104,18 @@ struct aa_dfa { + struct table_header *tables[YYTD_ID_TSIZE]; + }; + +-#define byte_to_byte(X) (X) +- + #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \ + do { \ + typeof(LEN) __i; \ + TTYPE *__t = (TTYPE *) TABLE; \ + BTYPE *__b = (BTYPE *) BLOB; \ +- for (__i = 0; __i < LEN; __i++) { \ +- __t[__i] = NTOHX(__b[__i]); \ +- } \ ++ BUILD_BUG_ON(sizeof(TTYPE) != sizeof(BTYPE)); \ ++ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) \ ++ memcpy(__t, __b, (LEN) * sizeof(BTYPE)); \ ++ else /* copy & convert from big-endian */ \ ++ for (__i = 0; __i < LEN; __i++) { \ ++ __t[__i] = NTOHX(&__b[__i]); \ ++ } \ + } while (0) + + static inline size_t table_size(size_t len, size_t el_size) +diff --git a/security/apparmor/match.c b/security/apparmor/match.c +index 26e82ba879d44..bbeb3be68572f 100644 +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -67,14 +67,13 @@ static struct table_header *unpack_table(char *blob, size_t bsize) + table->td_flags = th.td_flags; + table->td_lolen = th.td_lolen; + if (th.td_flags == YYTD_DATA8) +- UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u8, u8, byte_to_byte); ++ memcpy(table->td_data, blob, th.td_lolen); + else if (th.td_flags == YYTD_DATA16) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u16, __be16, be16_to_cpu); ++ u16, __be16, get_unaligned_be16); + else if (th.td_flags == YYTD_DATA32) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, +- u32, __be32, be32_to_cpu); ++ u32, __be32, get_unaligned_be32); + else + goto fail; + /* if table was vmalloced make sure the page tables are synced +-- +2.51.0 + diff --git a/queue-6.19/apparmor-fix-rlimit-for-posix-cpu-timers.patch b/queue-6.19/apparmor-fix-rlimit-for-posix-cpu-timers.patch new file mode 100644 index 0000000000..4589a7aadc --- /dev/null +++ b/queue-6.19/apparmor-fix-rlimit-for-posix-cpu-timers.patch @@ -0,0 +1,40 @@ +From 89238679ab4113d134e3de283943bad8a1e26864 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:16:54 -0800 +Subject: apparmor: fix rlimit for posix cpu timers + +From: John Johansen + +[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ] + +Posix cpu timers requires an additional step beyond setting the rlimit. +Refactor the code so its clear when what code is setting the +limit and conditionally update the posix cpu timers when appropriate. + +Fixes: baa73d9e478ff ("posix-timers: Make them configurable") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/resource.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index 8e80db3ae21c0..64212b39ba4bb 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -196,6 +196,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l) + rules->rlimits.limits[j].rlim_max); + /* soft limit should not exceed hard limit */ + rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); ++ if (j == RLIMIT_CPU && ++ rlim->rlim_cur != RLIM_INFINITY && ++ IS_ENABLED(CONFIG_POSIX_TIMERS)) ++ (void) update_rlimit_cpu(current->group_leader, ++ rlim->rlim_cur); + } + } + } +-- +2.51.0 + diff --git a/queue-6.19/apparmor-make-label_match-return-a-consistent-value.patch b/queue-6.19/apparmor-make-label_match-return-a-consistent-value.patch new file mode 100644 index 0000000000..7ba88dbbf0 --- /dev/null +++ b/queue-6.19/apparmor-make-label_match-return-a-consistent-value.patch @@ -0,0 +1,80 @@ +From d364a6442dfa54fc090702a086d068278b1ae39b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 23:59:38 -0800 +Subject: apparmor: make label_match return a consistent value + +From: John Johansen + +[ Upstream commit a4c9efa4dbad6dacad6e8b274e30e814c8353097 ] + +compound match is inconsistent in returning a state or an integer error +this is problemati if the error is ever used as a state in the state +machine + +Fixes: f1bd904175e81 ("apparmor: add the base fns() for domain labels") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 02ee128f53d13..1d3fa5c28d97f 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1278,7 +1278,7 @@ static inline aa_state_t match_component(struct aa_profile *profile, + * @request: permissions to request + * @perms: perms struct to set + * +- * Returns: 0 on success else ERROR ++ * Returns: state match stopped at or DFA_NOMATCH if aborted early + * + * For the label A//&B//&C this does the perm match for A//&B//&C + * @perms should be preinitialized with allperms OR a previous permission +@@ -1305,7 +1305,7 @@ static int label_compound_match(struct aa_profile *profile, + + /* no component visible */ + *perms = allperms; +- return 0; ++ return state; + + next: + label_for_each_cont(i, label, tp) { +@@ -1317,14 +1317,11 @@ static int label_compound_match(struct aa_profile *profile, + goto fail; + } + *perms = *aa_lookup_perms(rules->policy, state); +- if ((perms->allow & request) != request) +- return -EACCES; +- +- return 0; ++ return state; + + fail: + *perms = nullperms; +- return state; ++ return DFA_NOMATCH; + } + + /** +@@ -1406,11 +1403,12 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, + struct aa_label *label, aa_state_t state, bool subns, + u32 request, struct aa_perms *perms) + { +- int error = label_compound_match(profile, rules, label, state, subns, +- request, perms); +- if (!error) +- return error; ++ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, ++ request, perms); ++ if ((perms->allow & request) == request) ++ return 0; + ++ /* failed compound_match try component matches */ + *perms = allperms; + return label_components_match(profile, rules, label, state, subns, + request, perms); +-- +2.51.0 + diff --git a/queue-6.19/apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch b/queue-6.19/apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch new file mode 100644 index 0000000000..22e452ffe8 --- /dev/null +++ b/queue-6.19/apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch @@ -0,0 +1,85 @@ +From 9f79861db9d12401d89345e5b1540ff1b31e2067 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 13 Sep 2025 02:22:21 -0700 +Subject: apparmor: move check for aa_null file to cover all cases + +From: John Johansen + +[ Upstream commit 4a134723f9f1ad2f3621566259db673350d19cb1 ] + +files with a dentry pointing aa_null.dentry where already rejected as +part of file_inheritance. Unfortunately the check in +common_file_perm() is insufficient to cover all cases causing +unnecessary audit messages without the original files context. + +Eg. +[ 442.886474] audit: type=1400 audit(1704822661.616:329): apparmor="DENIED" operation="file_inherit" class="file" namespace="root//lxd-juju-98527a-0_" profile="snap.lxd.activate" name="/apparmor/.null" pid=9525 comm="snap-exec" + +Further examples of this are in the logs of +https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2120439 +https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1952084 +https://bugs.launchpad.net/snapd/+bug/2049099 + +These messages have no value and should not be sent to the logs. +AppArmor was already filtering the out in some cases but the original +patch did not catch all cases. Fix this by push the existing check +down into two functions that should cover all cases. + +Link: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2122743 +Fixes: 192ca6b55a86 ("apparmor: revalidate files during exec") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/file.c | 12 ++++++++++-- + security/apparmor/lsm.c | 4 ---- + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/security/apparmor/file.c b/security/apparmor/file.c +index 919dbbbc87ab6..7de23e85cd5d0 100644 +--- a/security/apparmor/file.c ++++ b/security/apparmor/file.c +@@ -154,8 +154,12 @@ static int path_name(const char *op, const struct cred *subj_cred, + const char *info = NULL; + int error; + +- error = aa_path_name(path, flags, buffer, name, &info, +- labels_profile(label)->disconnected); ++ /* don't reaudit files closed during inheritance */ ++ if (unlikely(path->dentry == aa_null.dentry)) ++ error = -EACCES; ++ else ++ error = aa_path_name(path, flags, buffer, name, &info, ++ labels_profile(label)->disconnected); + if (error) { + fn_for_each_confined(label, profile, + aa_audit_file(subj_cred, +@@ -616,6 +620,10 @@ int aa_file_perm(const char *op, const struct cred *subj_cred, + AA_BUG(!label); + AA_BUG(!file); + ++ /* don't reaudit files closed during inheritance */ ++ if (unlikely(file->f_path.dentry == aa_null.dentry)) ++ return -EACCES; ++ + fctx = file_ctx(file); + + rcu_read_lock(); +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index f47d60d8c40a2..8d5d9a966b719 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -525,10 +525,6 @@ static int common_file_perm(const char *op, struct file *file, u32 mask) + struct aa_label *label; + int error = 0; + +- /* don't reaudit files closed during inheritance */ +- if (unlikely(file->f_path.dentry == aa_null.dentry)) +- return -EACCES; +- + label = begin_current_label_crit_section(); + error = aa_file_perm(op, current_cred(), label, file, mask, false); + end_current_label_crit_section(label); +-- +2.51.0 + diff --git a/queue-6.19/apparmor-remove-apply_modes_to_perms-from-label_matc.patch b/queue-6.19/apparmor-remove-apply_modes_to_perms-from-label_matc.patch new file mode 100644 index 0000000000..1cf9bbd6fe --- /dev/null +++ b/queue-6.19/apparmor-remove-apply_modes_to_perms-from-label_matc.patch @@ -0,0 +1,53 @@ +From d674f136f873b74d4a6c844031d52a60e707cb38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 00:14:36 -0800 +Subject: apparmor: remove apply_modes_to_perms from label_match + +From: John Johansen + +[ Upstream commit b2e27be2948f2f8c38421cd554b5fc9383215648 ] + +The modes shouldn't be applied at the point of label match, it just +results in them being applied multiple times. Instead they should be +applied after which is already being done by all callers so it can +just be dropped from label_match. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value") +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 913678f199c35..02ee128f53d13 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1317,7 +1317,6 @@ static int label_compound_match(struct aa_profile *profile, + goto fail; + } + *perms = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, perms); + if ((perms->allow & request) != request) + return -EACCES; + +@@ -1370,7 +1369,6 @@ static int label_components_match(struct aa_profile *profile, + + next: + tmp = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + label_for_each_cont(i, label, tp) { + if (!aa_ns_visible(profile->ns, tp->ns, subns)) +@@ -1379,7 +1377,6 @@ static int label_components_match(struct aa_profile *profile, + if (!state) + goto fail; + tmp = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + } + +-- +2.51.0 + diff --git a/queue-6.19/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch b/queue-6.19/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch new file mode 100644 index 0000000000..32e770a165 --- /dev/null +++ b/queue-6.19/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch @@ -0,0 +1,44 @@ +From 39482724bb541b96c146be11217ece83cfdeb23f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Jan 2026 09:35:57 -0800 +Subject: apparmor: return -ENOMEM in unpack_perms_table upon alloc failure + +From: Ryan Lee + +[ Upstream commit 74b7105e53e80a4072bd3e1a50be7aa15e3f0a01 ] + +In policy_unpack.c:unpack_perms_table, the perms struct is allocated via +kcalloc, with the position being reset if the allocation fails. However, +the error path results in -EPROTO being retured instead of -ENOMEM. Fix +this to return the correct error code. + +Reported-by: Zygmunt Krynicki +Fixes: fd1b2b95a2117 ("apparmor: add the ability for policy to specify a permission table") +Reviewed-by: Tyler Hicks +Signed-off-by: Ryan Lee +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/policy_unpack.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index 7523971e37d9c..dd602bd5fca99 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -687,8 +687,10 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms) + if (!aa_unpack_array(e, NULL, &size)) + goto fail_reset; + *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL); +- if (!*perms) +- goto fail_reset; ++ if (!*perms) { ++ e->pos = pos; ++ return -ENOMEM; ++ } + for (i = 0; i < size; i++) { + if (!unpack_perm(e, version, &(*perms)[i])) + goto fail; +-- +2.51.0 + diff --git a/queue-6.19/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch b/queue-6.19/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch new file mode 100644 index 0000000000..86736d52ba --- /dev/null +++ b/queue-6.19/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch @@ -0,0 +1,49 @@ +From 7d5d36cc29660c6d0fb0e99ff395c943a10cc199 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 11:27:32 +0100 +Subject: ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init + +From: Alexandre Ferrieux + +[ Upstream commit b82fa9b0c26eeb2fde6017f7de2c3c544484efef ] + +The aw88261_dev_reg_update() function sets the Awinic registers in a +rather nonuniform way: + - most registers get directly overwritten from the firmware blob + - but a handful of them need more delicate logic to preserve + some bits from their current value, according to a register- + specific mask +For the latter, the logic is basically + NEW = (OLD & MASK) | (VAL & ~MASK) +However, the ~MASK value is hand-computed, and in the specific case +of the SYSCTRL register, in a buggy way. +This patch restores the proper ~MASK value. + +Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver") +Signed-off-by: Alexandre Ferrieux +Link: https://patch.msgid.link/20260211-aw88261-fwname-v1-1-e24e833a019d@fairphone.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/aw88261.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c +index 8f37bfb974ae4..96b1a85c26aa7 100644 +--- a/sound/soc/codecs/aw88261.c ++++ b/sound/soc/codecs/aw88261.c +@@ -423,9 +423,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261, + if (ret) + break; + ++ /* keep all three bits from current hw status */ + read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) | + (~AW88261_HMUTE_MASK); +- reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK); ++ reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK); + reg_val |= read_val; + + /* enable uls hmute */ +-- +2.51.0 + diff --git a/queue-6.19/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch b/queue-6.19/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch new file mode 100644 index 0000000000..49493db24a --- /dev/null +++ b/queue-6.19/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch @@ -0,0 +1,52 @@ +From 5d8e70762badd7b97f2c9e361bfde92ab2ad377b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 18:57:14 +0000 +Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put() + +From: Ziyi Guo + +[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ] + +This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()"). + +The original patch attempted to acquire the card->controls_rwsem lock in +fsl_xcvr_mode_put(). However, this function is called from the upper ALSA +core function snd_ctl_elem_write(), which already holds the write lock on +controls_rwsem for the whole put operation. So there is no need to simply +hold the lock for fsl_xcvr_activate_ctl() again. + +Acquiring the read lock while holding the write lock in the same thread +results in a deadlock and a hung task, as reported by Alexander Stein. + +Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()") +Reported-by: Alexander Stein +Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/ +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 5de93f458b569..a268fb81a2f86 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -223,13 +223,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, + + xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); + +- down_read(&card->snd_card->controls_rwsem); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_ARC)); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_EARC)); +- up_read(&card->snd_card->controls_rwsem); +- + /* Allow playback for SPDIF only */ + rtd = snd_soc_get_pcm_runtime(card, card->dai_link); + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = +-- +2.51.0 + diff --git a/queue-6.19/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch b/queue-6.19/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch new file mode 100644 index 0000000000..8d25c5be2e --- /dev/null +++ b/queue-6.19/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch @@ -0,0 +1,55 @@ +From db9444eb345e65aeafbf0da9bf27bb65fc19bd95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 15:18:34 -0500 +Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk + +From: Detlev Casanova + +[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ] + +Drivers will not always call set_sysclk() for all clocks, especially when +default mclk-fs can be used. +When that is the case, use the clock rate set in the params multiplied by the +default mclk-fs. + +Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback") +Signed-off-by: Detlev Casanova +Reported-by: Luca Ceresoli +Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c +index 770b9bfbb384a..fc52149ed6ae3 100644 +--- a/sound/soc/rockchip/rockchip_i2s_tdm.c ++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c +@@ -22,6 +22,7 @@ + + #define DRV_NAME "rockchip-i2s-tdm" + ++#define DEFAULT_MCLK_FS 256 + #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ + #define MULTIPLEX_CH_MAX 10 + +@@ -665,6 +666,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, + mclk_rate = i2s_tdm->mclk_rx_freq; + } + ++ /* ++ * When the dai/component driver doesn't need to set mclk-fs for a specific ++ * clock, it can skip the call to set_sysclk() for that clock. ++ * In that case, simply use the clock rate from the params and multiply it by ++ * the default mclk-fs value. ++ */ ++ if (!mclk_rate) ++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params); ++ + err = clk_set_rate(mclk, mclk_rate); + if (err) + return err; +-- +2.51.0 + diff --git a/queue-6.19/bnge-fix-reserving-resources-from-fw.patch b/queue-6.19/bnge-fix-reserving-resources-from-fw.patch new file mode 100644 index 0000000000..0c0193107a --- /dev/null +++ b/queue-6.19/bnge-fix-reserving-resources-from-fw.patch @@ -0,0 +1,41 @@ +From a176234d17b1ef51030f9eb7af99615c86d94bdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 10:57:55 +0530 +Subject: bnge: fix reserving resources from FW + +From: Vikas Gupta + +[ Upstream commit 604530085b2ef484843c723a105b6fd3218b4710 ] + +HWRM_FUNC_CFG is used to reserve resources, whereas HWRM_FUNC_QCFG is +intended for querying resource information from the firmware. +Since __bnge_hwrm_reserve_pf_rings() reserves resources for a specific +PF, the command type should be HWRM_FUNC_CFG. + +Fixes: 627c67f038d2 ("bng_en: Add resource management support") +Signed-off-by: Vikas Gupta +Reviewed-by: Bhargava Chenna Marreddy +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260218052755.4097468-1-vikas.gupta@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +index 198f49b40dbf0..2994f10446a63 100644 +--- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c ++++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +@@ -442,7 +442,7 @@ __bnge_hwrm_reserve_pf_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr) + struct hwrm_func_cfg_input *req; + u32 enables = 0; + +- if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCFG)) ++ if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_CFG)) + return NULL; + + req->fid = cpu_to_le16(0xffff); +-- +2.51.0 + diff --git a/queue-6.19/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch b/queue-6.19/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch new file mode 100644 index 0000000000..a11c2a8de5 --- /dev/null +++ b/queue-6.19/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch @@ -0,0 +1,108 @@ +From 52de9d3f828dceb4b44a1e72a797b762a4a468e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 06:09:19 +0000 +Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down + +From: Hangbin Liu + +[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ] + +The ALB RX path may access rx_hashtbl concurrently with bond +teardown. During rapid bond up/down cycles, rlb_deinitialize() +frees rx_hashtbl while RX handlers are still running, leading +to a null pointer dereference detected by KASAN. + +However, the root cause is that rlb_arp_recv() can still be accessed +after setting recv_probe to NULL, which is actually a use-after-free +(UAF) issue. That is the reason for using the referenced commit in the +Fixes tag. + +[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI +[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef] +[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary) +[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022 +[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding] +[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6 + 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00 +[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206 +[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e +[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8 +[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8 +[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119 +[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810 +[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000 +[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0 +[ 214.310347] Call Trace: +[ 214.313070] +[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding] +[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding] +[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding] +[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710 +[ 214.339199] ? __pfx_arp_process+0x10/0x10 +[ 214.343775] ? sched_balance_find_src_group+0x98/0x630 +[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10 +[ 214.356513] ? arp_rcv+0x307/0x690 +[ 214.360311] ? __pfx_arp_rcv+0x10/0x10 +[ 214.364499] ? __lock_acquire+0x58c/0xbd0 +[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0 +[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10 +[ 214.380743] ? lock_acquire+0x10b/0x140 +[ 214.385026] process_backlog+0x3f1/0x13a0 +[ 214.389502] ? process_backlog+0x3aa/0x13a0 +[ 214.394174] __napi_poll.constprop.0+0x9f/0x370 +[ 214.399233] net_rx_action+0x8c1/0xe60 +[ 214.403423] ? __pfx_net_rx_action+0x10/0x10 +[ 214.408193] ? lock_acquire.part.0+0xbd/0x260 +[ 214.413058] ? sched_clock_cpu+0x6c/0x540 +[ 214.417540] ? mark_held_locks+0x40/0x70 +[ 214.421920] handle_softirqs+0x1fd/0x860 +[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10 +[ 214.431264] ? __neigh_event_send+0x2d6/0xf50 +[ 214.436131] do_softirq+0xb1/0xf0 +[ 214.439830] + +The issue is reproducible by repeatedly running +ip link set bond0 up/down while receiving ARP messages, where +rlb_arp_recv() can race with rlb_deinitialize() and dereference +a freed rx_hashtbl entry. + +Fix this by setting recv_probe to NULL and then calling +synchronize_net() to wait for any concurrent RX processing to finish. +This ensures that no RX handler can access rx_hashtbl after it is freed +in bond_alb_deinitialize(). + +Reported-by: Liang Li +Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()") +Reviewed-by: Nikolay Aleksandrov +Acked-by: Jay Vosburgh +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 47f13d86cb7ef..4c58d1dafcacb 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4314,9 +4314,13 @@ static int bond_close(struct net_device *bond_dev) + + bond_work_cancel_all(bond); + bond->send_peer_notif = 0; ++ WRITE_ONCE(bond->recv_probe, NULL); ++ ++ /* Wait for any in-flight RX handlers */ ++ synchronize_net(); ++ + if (bond_is_lb(bond)) + bond_alb_deinitialize(bond); +- bond->recv_probe = NULL; + + if (BOND_MODE(bond) == BOND_MODE_8023AD && + bond->params.broadcast_neighbor) +-- +2.51.0 + diff --git a/queue-6.19/bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch b/queue-6.19/bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch new file mode 100644 index 0000000000..94bed55527 --- /dev/null +++ b/queue-6.19/bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch @@ -0,0 +1,51 @@ +From a2ab6fb298c00d45b603cec8621670515963fafe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 21:29:49 +0000 +Subject: bpf: Add a map/btf from a fd array more consistently + +From: Anton Protopopov + +[ Upstream commit b0b1a8583d8e797114e613139e3e3318a1704690 ] + +The add_fd_from_fd_array() function takes a file descriptor as a +parameter and tries to add either map or btf to the corresponding +list of used objects. As was reported by Dan Carpenter, since the +commit c81e4322acf0 ("bpf: Fix a potential use-after-free of BTF +object"), the fdget() is called twice on the file descriptor, and +thus userspace, potentially, can replace the file pointed to by the +file descriptor in between the two calls. On practice, this shouldn't +break anything on the kernel side, but for consistency fix the code +such that only one fdget() is executed. + +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/aY689z7gHNv8rgVO@stanley.mountain/ +Fixes: ccd2d799ed44 ("bpf: Fix a potential use-after-free of BTF object") +Signed-off-by: Anton Protopopov +Link: https://lore.kernel.org/r/20260213212949.759321-1-a.s.protopopov@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index a16aca34f5834..fe01edfcc34c6 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -24658,9 +24658,11 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd) + return 0; + } + +- btf = btf_get_by_fd(fd); +- if (!IS_ERR(btf)) ++ btf = __btf_get_by_fd(f); ++ if (!IS_ERR(btf)) { ++ btf_get(btf); + return __add_used_btf(env, btf); ++ } + + verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd); + return PTR_ERR(map); +-- +2.51.0 + diff --git a/queue-6.19/bpf-fix-a-potential-use-after-free-of-btf-object.patch b/queue-6.19/bpf-fix-a-potential-use-after-free-of-btf-object.patch new file mode 100644 index 0000000000..ac1199224d --- /dev/null +++ b/queue-6.19/bpf-fix-a-potential-use-after-free-of-btf-object.patch @@ -0,0 +1,145 @@ +From a96fc583215bd3c53c03b9b7fc92cf3437a6522d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 13:29:04 +0000 +Subject: bpf: Fix a potential use-after-free of BTF object + +From: Anton Protopopov + +[ Upstream commit ccd2d799ed4467c07f5ee18c2f5c59bcc990822c ] + +Refcounting in the check_pseudo_btf_id() function is incorrect: +the __check_pseudo_btf_id() function might get called with a zero +refcounted btf. Fix this, and patch related code accordingly. + +v3: rephrase a comment (AI) +v2: fix a refcount leak introduced in v1 (AI) + +Reported-by: syzbot+5a0f1995634f7c1dadbf@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=5a0f1995634f7c1dadbf +Fixes: 76145f725532 ("bpf: Refactor check_pseudo_btf_id") +Signed-off-by: Anton Protopopov +Link: https://lore.kernel.org/r/20260209132904.63908-1-a.s.protopopov@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 52 +++++++++++++++++++++---------------------- + 1 file changed, 26 insertions(+), 26 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index c9e2e22da3309..a16aca34f5834 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -20685,29 +20685,29 @@ static int find_btf_percpu_datasec(struct btf *btf) + } + + /* +- * Add btf to the used_btfs array and return the index. (If the btf was +- * already added, then just return the index.) Upon successful insertion +- * increase btf refcnt, and, if present, also refcount the corresponding +- * kernel module. ++ * Add btf to the env->used_btfs array. If needed, refcount the ++ * corresponding kernel module. To simplify caller's logic ++ * in case of error or if btf was added before the function ++ * decreases the btf refcount. + */ + static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf) + { + struct btf_mod_pair *btf_mod; ++ int ret = 0; + int i; + + /* check whether we recorded this BTF (and maybe module) already */ + for (i = 0; i < env->used_btf_cnt; i++) + if (env->used_btfs[i].btf == btf) +- return i; ++ goto ret_put; + + if (env->used_btf_cnt >= MAX_USED_BTFS) { + verbose(env, "The total number of btfs per program has reached the limit of %u\n", + MAX_USED_BTFS); +- return -E2BIG; ++ ret = -E2BIG; ++ goto ret_put; + } + +- btf_get(btf); +- + btf_mod = &env->used_btfs[env->used_btf_cnt]; + btf_mod->btf = btf; + btf_mod->module = NULL; +@@ -20716,12 +20716,18 @@ static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf) + if (btf_is_module(btf)) { + btf_mod->module = btf_try_get_module(btf); + if (!btf_mod->module) { +- btf_put(btf); +- return -ENXIO; ++ ret = -ENXIO; ++ goto ret_put; + } + } + +- return env->used_btf_cnt++; ++ env->used_btf_cnt++; ++ return 0; ++ ++ret_put: ++ /* Either error or this BTF was already added */ ++ btf_put(btf); ++ return ret; + } + + /* replace pseudo btf_id with kernel symbol address */ +@@ -20818,9 +20824,7 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env, + + btf_fd = insn[1].imm; + if (btf_fd) { +- CLASS(fd, f)(btf_fd); +- +- btf = __btf_get_by_fd(f); ++ btf = btf_get_by_fd(btf_fd); + if (IS_ERR(btf)) { + verbose(env, "invalid module BTF object FD specified.\n"); + return -EINVAL; +@@ -20830,17 +20834,17 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env, + verbose(env, "kernel is missing BTF, make sure CONFIG_DEBUG_INFO_BTF=y is specified in Kconfig.\n"); + return -EINVAL; + } ++ btf_get(btf_vmlinux); + btf = btf_vmlinux; + } + + err = __check_pseudo_btf_id(env, insn, aux, btf); +- if (err) ++ if (err) { ++ btf_put(btf); + return err; ++ } + +- err = __add_used_btf(env, btf); +- if (err < 0) +- return err; +- return 0; ++ return __add_used_btf(env, btf); + } + + static bool is_tracing_prog_type(enum bpf_prog_type type) +@@ -24654,13 +24658,9 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd) + return 0; + } + +- btf = __btf_get_by_fd(f); +- if (!IS_ERR(btf)) { +- err = __add_used_btf(env, btf); +- if (err < 0) +- return err; +- return 0; +- } ++ btf = btf_get_by_fd(fd); ++ if (!IS_ERR(btf)) ++ return __add_used_btf(env, btf); + + verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd); + return PTR_ERR(map); +-- +2.51.0 + diff --git a/queue-6.19/bpftool-fix-truncated-netlink-dumps.patch b/queue-6.19/bpftool-fix-truncated-netlink-dumps.patch new file mode 100644 index 0000000000..cfe35bc29d --- /dev/null +++ b/queue-6.19/bpftool-fix-truncated-netlink-dumps.patch @@ -0,0 +1,73 @@ +From 7f032f3ee152f3c01d0abb1e9885127d0e65c347 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 11:41:50 -0800 +Subject: bpftool: Fix truncated netlink dumps + +From: Jakub Kicinski + +[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ] + +Netlink requires that the recv buffer used during dumps is at least +min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will +get truncated. Make sure bpftool follows this requirement, avoid +missing information on systems with large pages. + +Acked-by: Quentin Monnet +Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool") +Signed-off-by: Jakub Kicinski +Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/net.c | 5 ++++- + tools/lib/bpf/netlink.c | 4 +++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c +index cfc6f944f7c33..1a06b0b5eef35 100644 +--- a/tools/bpf/bpftool/net.c ++++ b/tools/bpf/bpftool/net.c +@@ -156,7 +156,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + bool multipart = true; + struct nlmsgerr *err; + struct nlmsghdr *nh; +- char buf[4096]; ++ char buf[8192]; + int len, ret; + + while (multipart) { +@@ -201,6 +201,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + return ret; + } + } ++ ++ if (len) ++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len); + } + ret = 0; + done: +diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c +index c997e69d507fe..c9a78fb16f115 100644 +--- a/tools/lib/bpf/netlink.c ++++ b/tools/lib/bpf/netlink.c +@@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + struct nlmsghdr *nh; + int len, ret; + +- ret = alloc_iov(&iov, 4096); ++ ret = alloc_iov(&iov, 8192); + if (ret) + goto done; + +@@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + } + } + } ++ if (len) ++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len); + } + ret = 0; + done: +-- +2.51.0 + diff --git a/queue-6.19/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch b/queue-6.19/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch new file mode 100644 index 0000000000..0c9668b999 --- /dev/null +++ b/queue-6.19/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch @@ -0,0 +1,52 @@ +From 4d543b0b644040e3759c39855a0dbd0f8a7d3d90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 17:15:53 +0000 +Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not + found + +From: Filipe Manana + +[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ] + +If btrfs_search_slot_for_read() returns 1, it means we did not find any +key greater than or equals to the key we asked for, meaning we have +reached the end of the tree and therefore the path is not valid. If +this happens we need to break out of the loop and stop, instead of +continuing and accessing an invalid path. + +Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/qgroup.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index c634e01140514..bed9d1c11c67a 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1137,11 +1137,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info, + } + if (ret > 0) { + /* +- * Shouldn't happen, but in case it does we +- * don't need to do the btrfs_next_item, just +- * continue. ++ * Shouldn't happen because the key should still ++ * be there (return 0), but in case it does it ++ * means we have reached the end of the tree - ++ * there are no more leaves with items that have ++ * a key greater than or equals to @found_key, ++ * so just stop the search loop. + */ +- continue; ++ break; + } + } + ret = btrfs_next_item(tree_root, path); +-- +2.51.0 + diff --git a/queue-6.19/btrfs-reset-block-group-size-class-when-it-becomes-e.patch b/queue-6.19/btrfs-reset-block-group-size-class-when-it-becomes-e.patch new file mode 100644 index 0000000000..1a7d25d9a0 --- /dev/null +++ b/queue-6.19/btrfs-reset-block-group-size-class-when-it-becomes-e.patch @@ -0,0 +1,81 @@ +From 42840cbea92ae30263aea9e6c37b97d826405102 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Jan 2026 01:13:38 +0000 +Subject: btrfs: reset block group size class when it becomes empty + +From: Jiasheng Jiang + +[ Upstream commit 5870ec7c8fe57a8b2c65005e5da5efc054faa3e6 ] + +Block group size classes are managed consistently everywhere. +Currently, btrfs_use_block_group_size_class() sets a block group's size +class to specialize it for a specific allocation size. However, this +size class remains "stale" even if the block group becomes completely +empty (both used and reserved bytes reach zero). + +This happens in two scenarios: + +1. When space reservations are freed (e.g., due to errors or transaction + aborts) via btrfs_free_reserved_bytes(). +2. When the last extent in a block group is freed via + btrfs_update_block_group(). + +While size classes are advisory, a stale size class can cause +find_free_extent to unnecessarily skip candidate block groups during +initial search loops. This undermines the purpose of size classes to +reduce fragmentation by keeping block groups restricted to a specific +size class when they could be reused for any size. + +Fix this by resetting the size class to BTRFS_BG_SZ_NONE whenever a +block group's used and reserved counts both reach zero. This ensures +that empty block groups are fully available for any allocation size in +the next cycle. + +Fixes: 52bb7a2166af ("btrfs: introduce size class to block group allocator") +Reviewed-by: Boris Burkov +Signed-off-by: Jiasheng Jiang +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 08b14449fabeb..c7be37bcbc48d 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -3675,6 +3675,14 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans) + return ret; + } + ++static void btrfs_maybe_reset_size_class(struct btrfs_block_group *bg) ++{ ++ lockdep_assert_held(&bg->lock); ++ if (btrfs_block_group_should_use_size_class(bg) && ++ bg->used == 0 && bg->reserved == 0) ++ bg->size_class = BTRFS_BG_SZ_NONE; ++} ++ + int btrfs_update_block_group(struct btrfs_trans_handle *trans, + u64 bytenr, u64 num_bytes, bool alloc) + { +@@ -3739,6 +3747,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans, + old_val -= num_bytes; + cache->used = old_val; + cache->pinned += num_bytes; ++ btrfs_maybe_reset_size_class(cache); + btrfs_space_info_update_bytes_pinned(space_info, num_bytes); + space_info->bytes_used -= num_bytes; + space_info->disk_used -= num_bytes * factor; +@@ -3867,6 +3876,7 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes, + spin_lock(&cache->lock); + bg_ro = cache->ro; + cache->reserved -= num_bytes; ++ btrfs_maybe_reset_size_class(cache); + if (is_delalloc) + cache->delalloc_bytes -= num_bytes; + spin_unlock(&cache->lock); +-- +2.51.0 + diff --git a/queue-6.19/btrfs-use-the-correct-type-to-initialize-block-reser.patch b/queue-6.19/btrfs-use-the-correct-type-to-initialize-block-reser.patch new file mode 100644 index 0000000000..cc3ef1c910 --- /dev/null +++ b/queue-6.19/btrfs-use-the-correct-type-to-initialize-block-reser.patch @@ -0,0 +1,82 @@ +From fdde98c6aac6383c9d7f7555c71a6d45b4f47104 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 18:03:35 +0000 +Subject: btrfs: use the correct type to initialize block reserve for delayed + refs + +From: Filipe Manana + +[ Upstream commit 2155d0c0a761a56ce7ede83a26eb23ea0f935260 ] + +When initializing the delayed refs block reserve for a transaction handle +we are passing a type of BTRFS_BLOCK_RSV_DELOPS, which is meant for +delayed items and not for delayed refs. The correct type for delayed refs +is BTRFS_BLOCK_RSV_DELREFS. + +On release of any excess space reserved in a local delayed refs reserve, +we also should transfer that excess space to the global block reserve +(it it's full, we return to the space info for general availability). + +By initializing a transaction's local delayed refs block reserve with a +type of BTRFS_BLOCK_RSV_DELOPS, we were also causing any excess space +released from the delayed block reserve (fs_info->delayed_block_rsv, used +for delayed inodes and items) to be transferred to the global block +reserve instead of the global delayed refs block reserve. This was an +unintentional change in commit 28270e25c69a ("btrfs: always reserve space +for delayed refs when starting transaction"), but it's not particularly +serious as things tend to cancel out each other most of the time and it's +relatively rare to be anywhere near exhaustion of the global reserve. + +Fix this by initializing a transaction's local delayed refs reserve with +a type of BTRFS_BLOCK_RSV_DELREFS and making btrfs_block_rsv_release() +attempt to transfer unused space from such a reserve into the global block +reserve, just as we did before that commit for when the block reserve is +a delayed refs rsv. + +Reported-by: Alex Lyakas +Link: https://lore.kernel.org/linux-btrfs/CAOcd+r0FHG5LWzTSu=LknwSoqxfw+C00gFAW7fuX71+Z5AfEew@mail.gmail.com/ +Fixes: 28270e25c69a ("btrfs: always reserve space for delayed refs when starting transaction") +Reviewed-by: Alex Lyakas +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-rsv.c | 7 ++++--- + fs/btrfs/transaction.c | 2 +- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c +index 96cf7a1629870..52fb7d9425917 100644 +--- a/fs/btrfs/block-rsv.c ++++ b/fs/btrfs/block-rsv.c +@@ -276,10 +276,11 @@ u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info, + struct btrfs_block_rsv *target = NULL; + + /* +- * If we are a delayed block reserve then push to the global rsv, +- * otherwise dump into the global delayed reserve if it is not full. ++ * If we are a delayed refs block reserve then push to the global ++ * reserve, otherwise dump into the global delayed refs reserve if it is ++ * not full. + */ +- if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS) ++ if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS) + target = global_rsv; + else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv)) + target = delayed_rsv; +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index e3e0d88d53476..d3e1ba257b9c0 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -726,7 +726,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, + + h->type = type; + INIT_LIST_HEAD(&h->new_bgs); +- btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS); ++ btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS); + + smp_mb(); + if (cur_trans->state >= TRANS_STATE_COMMIT_START && +-- +2.51.0 + diff --git a/queue-6.19/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch b/queue-6.19/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch new file mode 100644 index 0000000000..bea11be102 --- /dev/null +++ b/queue-6.19/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch @@ -0,0 +1,59 @@ +From 866150bfd5cb22356d2f1e86873fa424116a53d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 00:20:02 +0530 +Subject: cpuidle: Skip governor when only one idle state is available + +From: Aboorva Devarajan + +[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ] + +On certain platforms (PowerNV systems without a power-mgt DT node), +cpuidle may register only a single idle state. In cases where that +single state is a polling state (state 0), the ladder governor may +incorrectly treat state 1 as the first usable state and pass an +out-of-bounds index. This can lead to a NULL enter callback being +invoked, ultimately resulting in a system crash. + +[ 13.342636] cpuidle-powernv : Only Snooze is available +[ 13.351854] Faulting instruction address: 0x00000000 +[ 13.376489] NIP [0000000000000000] 0x0 +[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668 + +Fix this by adding a bail-out in cpuidle_select() that returns state 0 +directly when state_count <= 1, bypassing the governor and keeping the +tick running. + +Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") +Signed-off-by: Aboorva Devarajan +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/cpuidle.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index c7876e9e024f9..65fbb8e807b97 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -359,6 +359,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev, + int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + bool *stop_tick) + { ++ /* ++ * If there is only a single idle state (or none), there is nothing ++ * meaningful for the governor to choose. Skip the governor and ++ * always use state 0 with the tick running. ++ */ ++ if (drv->state_count <= 1) { ++ *stop_tick = false; ++ return 0; ++ } ++ + return cpuidle_curr_governor->select(drv, dev, stop_tick); + } + +-- +2.51.0 + diff --git a/queue-6.19/dpll-zl3073x-fix-ref-frequency-setting.patch b/queue-6.19/dpll-zl3073x-fix-ref-frequency-setting.patch new file mode 100644 index 0000000000..0d0513a363 --- /dev/null +++ b/queue-6.19/dpll-zl3073x-fix-ref-frequency-setting.patch @@ -0,0 +1,56 @@ +From 969e0bd9725bd559bd11775bdb27a58c5f9b7d8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 20:40:07 +0100 +Subject: dpll: zl3073x: Fix ref frequency setting + +From: Ivan Vecera + +[ Upstream commit a047497f952831e377564b606dcb74a7cb309384 ] + +The frequency for an input reference is computed as: + + frequency = freq_base * freq_mult * freq_ratio_m / freq_ratio_n + +Before commit 5bc02b190a3fb ("dpll: zl3073x: Cache all reference +properties in zl3073x_ref"), zl3073x_dpll_input_pin_frequency_set() +explicitly wrote 1 to both the REF_RATIO_M and REF_RATIO_N hardware +registers whenever a new frequency was set. This ensured the FEC ratio +was always reset to 1:1 alongside the new base/multiplier values. + +The refactoring in that commit introduced zl3073x_ref_freq_set() to +update the cached ref state, but this helper only sets freq_base and +freq_mult without resetting freq_ratio_m and freq_ratio_n to 1. Because +zl3073x_ref_state_set() uses a compare-and-write strategy, unchanged +ratio fields are never written to the hardware. If the device previously +had non-unity FEC ratio values, they remain in effect after a frequency +change, resulting in an incorrect computed frequency. + +Explicitly set freq_ratio_m and freq_ratio_n to 1 in zl3073x_ref_freq_set() +to restore the original behavior. + +Fixes: 5bc02b190a3fb ("dpll: zl3073x: Cache all reference properties in zl3073x_ref") +Signed-off-by: Ivan Vecera +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260216194007.680416-1-ivecera@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/dpll/zl3073x/ref.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h +index efc7f59cd9f9c..0d8618f5ce8df 100644 +--- a/drivers/dpll/zl3073x/ref.h ++++ b/drivers/dpll/zl3073x/ref.h +@@ -91,6 +91,8 @@ zl3073x_ref_freq_set(struct zl3073x_ref *ref, u32 freq) + + ref->freq_base = base; + ref->freq_mult = mult; ++ ref->freq_ratio_m = 1; ++ ref->freq_ratio_n = 1; + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-don-t-call-find_analog_engine-twice.patch b/queue-6.19/drm-amd-display-don-t-call-find_analog_engine-twice.patch new file mode 100644 index 0000000000..0f11b1c182 --- /dev/null +++ b/queue-6.19/drm-amd-display-don-t-call-find_analog_engine-twice.patch @@ -0,0 +1,42 @@ +From af947cdd935afb34b2ceaa65180f880fc3fdc35f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 12:25:03 +0100 +Subject: drm/amd/display: Don't call find_analog_engine() twice +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit 613b1737abe1bd0a65b49851e777231302095e28 ] + +The analog engine is already there in the link_analog_engine +variable and assigned to enc_init_data.analog_engine already. + +I suspect this was a rebase mistake. + +Fixes: 436d0d22aa70 ("drm/amd/display: Pass proper DAC encoder ID to VBIOS") +Signed-off-by: Timur Kristóf +Tested-by: Mauro Rossi +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/link/link_factory.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c +index d9cb6b6714009..9003e0d314e00 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c ++++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c +@@ -648,7 +648,6 @@ static bool construct_phy(struct dc_link *link, + enc_init_data.channel = get_ddc_line(link); + enc_init_data.hpd_source = get_hpd_line(link); + enc_init_data.transmitter = transmitter_from_encoder; +- enc_init_data.analog_engine = find_analog_engine(link, &enc_init_data.analog_encoder); + enc_init_data.encoder = link_encoder; + enc_init_data.analog_engine = link_analog_engine; + +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-enable-dac-in-dce-link-encoder.patch b/queue-6.19/drm-amd-display-enable-dac-in-dce-link-encoder.patch new file mode 100644 index 0000000000..8bce520b02 --- /dev/null +++ b/queue-6.19/drm-amd-display-enable-dac-in-dce-link-encoder.patch @@ -0,0 +1,212 @@ +From 4a67f7de4ea1675139a264c2daf6a3ad7d8ef763 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 12:25:07 +0100 +Subject: drm/amd/display: Enable DAC in DCE link encoder +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit 4bd8b5f8bcb57b430c35494d8a2471ce5fd7661d ] + +Ensure that the DAC output is enabled at the correct time by +moving it to the DCE link encoder similarly to how digital +outputs are enabled. + +This also removes the call to DAC1EncoderControl from the DCE +HWSS, which always felt like it was a hacky solution. + +Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") +Signed-off-by: Timur Kristóf +Tested-by: Mauro Rossi +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/display/dc/dce/dce_link_encoder.c | 18 +++++++++++++ + .../drm/amd/display/dc/dce/dce_link_encoder.h | 5 ++++ + .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 26 +++++++------------ + .../drm/amd/display/dc/hwss/hw_sequencer.h | 2 ++ + .../drm/amd/display/dc/inc/hw/link_encoder.h | 2 ++ + .../gpu/drm/amd/display/dc/link/link_dpms.c | 14 +++++++++- + 6 files changed, 50 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +index 48a1b3b492e7f..bec8dab156eec 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +@@ -102,6 +102,7 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = { + .enable_dp_output = dce110_link_encoder_enable_dp_output, + .enable_dp_mst_output = dce110_link_encoder_enable_dp_mst_output, + .enable_lvds_output = dce110_link_encoder_enable_lvds_output, ++ .enable_analog_output = dce110_link_encoder_enable_analog_output, + .disable_output = dce110_link_encoder_disable_output, + .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, + .dp_set_phy_pattern = dce110_link_encoder_dp_set_phy_pattern, +@@ -1192,6 +1193,22 @@ void dce110_link_encoder_enable_lvds_output( + } + } + ++void dce110_link_encoder_enable_analog_output( ++ struct link_encoder *enc, ++ uint32_t pixel_clock) ++{ ++ struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); ++ enum bp_result result; ++ ++ result = link_dac_encoder_control(enc110, ENCODER_CONTROL_ENABLE, pixel_clock); ++ ++ if (result != BP_RESULT_OK) { ++ DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", ++ __func__); ++ BREAK_TO_DEBUGGER(); ++ } ++} ++ + /* enables DP PHY output */ + void dce110_link_encoder_enable_dp_output( + struct link_encoder *enc, +@@ -1776,6 +1793,7 @@ static const struct link_encoder_funcs dce60_lnk_enc_funcs = { + .enable_dp_output = dce60_link_encoder_enable_dp_output, + .enable_dp_mst_output = dce60_link_encoder_enable_dp_mst_output, + .enable_lvds_output = dce110_link_encoder_enable_lvds_output, ++ .enable_analog_output = dce110_link_encoder_enable_analog_output, + .disable_output = dce110_link_encoder_disable_output, + .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, + .dp_set_phy_pattern = dce60_link_encoder_dp_set_phy_pattern, +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +index c58b69bc319b7..6870cb619d208 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +@@ -273,6 +273,11 @@ void dce110_link_encoder_enable_lvds_output( + enum clock_source_id clock_source, + uint32_t pixel_clock); + ++/* enables analog output from the DAC */ ++void dce110_link_encoder_enable_analog_output( ++ struct link_encoder *enc, ++ uint32_t pixel_clock); ++ + /* disable PHY output */ + void dce110_link_encoder_disable_output( + struct link_encoder *enc, +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +index c472303276672..5896ce5511ab1 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +@@ -659,20 +659,6 @@ void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) + } + } + +-static void +-dce110_dac_encoder_control(struct pipe_ctx *pipe_ctx, bool enable) +-{ +- struct dc_link *link = pipe_ctx->stream->link; +- struct dc_bios *bios = link->ctx->dc_bios; +- struct bp_encoder_control encoder_control = {0}; +- +- encoder_control.action = enable ? ENCODER_CONTROL_ENABLE : ENCODER_CONTROL_DISABLE; +- encoder_control.engine_id = link->link_enc->analog_engine; +- encoder_control.pixel_clock = pipe_ctx->stream->timing.pix_clk_100hz / 10; +- +- bios->funcs->encoder_control(bios, &encoder_control); +-} +- + void dce110_enable_stream(struct pipe_ctx *pipe_ctx) + { + enum dc_lane_count lane_count = +@@ -703,8 +689,6 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) + + tg->funcs->set_early_control(tg, early_control); + +- if (dc_is_rgb_signal(pipe_ctx->stream->signal)) +- dce110_dac_encoder_control(pipe_ctx, true); + } + + static enum bp_result link_transmitter_control( +@@ -3285,6 +3269,15 @@ void dce110_enable_tmds_link_output(struct dc_link *link, + link->phy_state.symclk_state = SYMCLK_ON_TX_ON; + } + ++static void dce110_enable_analog_link_output( ++ struct dc_link *link, ++ uint32_t pix_clk_100hz) ++{ ++ link->link_enc->funcs->enable_analog_output( ++ link->link_enc, ++ pix_clk_100hz); ++} ++ + void dce110_enable_dp_link_output( + struct dc_link *link, + const struct link_resource *link_res, +@@ -3422,6 +3415,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { + .enable_lvds_link_output = dce110_enable_lvds_link_output, + .enable_tmds_link_output = dce110_enable_tmds_link_output, + .enable_dp_link_output = dce110_enable_dp_link_output, ++ .enable_analog_link_output = dce110_enable_analog_link_output, + .disable_link_output = dce110_disable_link_output, + }; + +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +index 8ed9eea40c564..4f6bd365e055a 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +@@ -1184,6 +1184,8 @@ struct hw_sequencer_funcs { + const struct link_resource *link_res, + enum clock_source_id clock_source, + uint32_t pixel_clock); ++ void (*enable_analog_link_output)(struct dc_link *link, ++ uint32_t pixel_clock); + void (*disable_link_output)(struct dc_link *link, + const struct link_resource *link_res, + enum signal_type signal); +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +index e638325e35ecf..b1a88618c5bf8 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +@@ -130,6 +130,8 @@ struct link_encoder_funcs { + void (*enable_lvds_output)(struct link_encoder *enc, + enum clock_source_id clock_source, + uint32_t pixel_clock); ++ void (*enable_analog_output)(struct link_encoder *enc, ++ uint32_t pixel_clock); + void (*disable_output)(struct link_encoder *link_enc, + enum signal_type signal); + void (*dp_set_lane_settings)(struct link_encoder *enc, +diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +index 6ae1341476171..635f614c06734 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c ++++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +@@ -2208,6 +2208,18 @@ static enum dc_status enable_link_dp_mst( + return enable_link_dp(state, pipe_ctx); + } + ++static enum dc_status enable_link_analog( ++ struct dc_state *state, ++ struct pipe_ctx *pipe_ctx) ++{ ++ struct dc_link *link = pipe_ctx->stream->link; ++ ++ link->dc->hwss.enable_analog_link_output( ++ link, pipe_ctx->stream->timing.pix_clk_100hz); ++ ++ return DC_OK; ++} ++ + static enum dc_status enable_link_virtual(struct pipe_ctx *pipe_ctx) + { + struct dc_link *link = pipe_ctx->stream->link; +@@ -2263,7 +2275,7 @@ static enum dc_status enable_link( + status = DC_OK; + break; + case SIGNAL_TYPE_RGB: +- status = DC_OK; ++ status = enable_link_analog(state, pipe_ctx); + break; + case SIGNAL_TYPE_VIRTUAL: + status = enable_link_virtual(pipe_ctx); +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-fix-dc_link-null-handling-in-hpd-ini.patch b/queue-6.19/drm-amd-display-fix-dc_link-null-handling-in-hpd-ini.patch new file mode 100644 index 0000000000..3bc5dc408f --- /dev/null +++ b/queue-6.19/drm-amd-display-fix-dc_link-null-handling-in-hpd-ini.patch @@ -0,0 +1,99 @@ +From f5a0b3b38eb3e348ada9e691dc02454d66c082ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 20:06:19 +0530 +Subject: drm/amd/display: Fix dc_link NULL handling in HPD init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Srinivasan Shanmugam + +[ Upstream commit 226a40c06a183abaeb7529a4f54d6c203bd14407 ] + +amdgpu_dm_hpd_init() may see connectors without a valid dc_link. + +The code already checks dc_link for the polling decision, but later +unconditionally dereferences it when setting up HPD interrupts. + +Assign dc_link early and skip connectors where it is NULL. + +Fixes the below: +drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_irq.c:940 amdgpu_dm_hpd_init() +error: we previously assumed 'dc_link' could be null (see line 931) + +drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_irq.c + 923 /* + 924 * Analog connectors may be hot-plugged unlike other connector + 925 * types that don't support HPD. Only poll analog connectors. + 926 */ + 927 use_polling |= + 928 amdgpu_dm_connector->dc_link && + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The patch adds this NULL check but hopefully it can be removed + + 929 dc_connector_supports_analog(amdgpu_dm_connector->dc_link->link_id.id); + 930 + 931 dc_link = amdgpu_dm_connector->dc_link; + +dc_link assigned here. + + 932 + 933 /* + 934 * Get a base driver irq reference for hpd ints for the lifetime + 935 * of dm. Note that only hpd interrupt types are registered with + 936 * base driver; hpd_rx types aren't. IOW, amdgpu_irq_get/put on + 937 * hpd_rx isn't available. DM currently controls hpd_rx + 938 * explicitly with dc_interrupt_set() + 939 */ +--> 940 if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) { + ^^^^^^^^^^^^^^^^^^^^^^^ If it's NULL then we are trouble because we dereference it here. + + 941 irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1; + 942 /* + 943 * TODO: There's a mismatch between mode_info.num_hpd + 944 * and what bios reports as the # of connectors with hpd + +Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)") +Cc: Timur Kristóf +Cc: Harry Wentland +Cc: Mario Limonciello +Cc: Alex Hung +Cc: Aurabindo Pillai +Cc: ChiaHsuan Chung +Cc: Roman Li +Reported-by: Dan Carpenter +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Timur Kristóf +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +index e7b0928bd3db7..5948e2a6219e3 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +@@ -919,16 +919,15 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) + continue; + + amdgpu_dm_connector = to_amdgpu_dm_connector(connector); ++ dc_link = amdgpu_dm_connector->dc_link; ++ if (!dc_link) ++ continue; + + /* + * Analog connectors may be hot-plugged unlike other connector + * types that don't support HPD. Only poll analog connectors. + */ +- use_polling |= +- amdgpu_dm_connector->dc_link && +- dc_connector_supports_analog(amdgpu_dm_connector->dc_link->link_id.id); +- +- dc_link = amdgpu_dm_connector->dc_link; ++ use_polling |= dc_connector_supports_analog(dc_link->link_id.id); + + /* + * Get a base driver irq reference for hpd ints for the lifetime +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch b/queue-6.19/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch new file mode 100644 index 0000000000..0667677c47 --- /dev/null +++ b/queue-6.19/drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch @@ -0,0 +1,216 @@ +From fcfb9e6cce9b892a7bdfcdb84d465914f0e2806c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 20:49:23 +0530 +Subject: drm/amd/display: Fix out-of-bounds stream encoder index v3 + +From: Srinivasan Shanmugam + +[ Upstream commit abde491143e4e12eecc41337910aace4e8d59603 ] + +eng_id can be negative and that stream_enc_regs[] +can be indexed out of bounds. + +eng_id is used directly as an index into stream_enc_regs[], which has +only 5 entries. When eng_id is 5 (ENGINE_ID_DIGF) or negative, this can +access memory past the end of the array. + +Add a bounds check using ARRAY_SIZE() before using eng_id as an index. +The unsigned cast also rejects negative values. + +This avoids out-of-bounds access. + +Fixes the below smatch error: +dcn*_resource.c: stream_encoder_create() may index +stream_enc_regs[eng_id] out of bounds (size 5). + +drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c + 1246 static struct stream_encoder *dcn35_stream_encoder_create( + 1247 enum engine_id eng_id, + 1248 struct dc_context *ctx) + 1249 { + + ... + + 1255 + 1256 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ + 1257 if (eng_id <= ENGINE_ID_DIGF) { + +ENGINE_ID_DIGF is 5. should <= be dc_bios, + 1283 eng_id, vpg, afmt, +--> 1284 &stream_enc_regs[eng_id], + ^^^^^^^^^^^^^^^^^^^^^^^ This stream_enc_regs[] array has 5 elements so we are one element beyond the end of the array. + + ... + + 1287 return &enc1->base; + 1288 } + +v2: use explicit bounds check as suggested by Roman/Dan; avoid unsigned int cast + +v3: The compiler already knows how to compare the two values, so the + cast (int) is not needed. (Roman) + +Fixes: 2728e9c7c842 ("drm/amd/display: add DC changes for DCN351") +Reported-by: Dan Carpenter +Cc: Harry Wentland +Cc: Mario Limonciello +Cc: Alex Hung +Cc: Aurabindo Pillai +Cc: ChiaHsuan Chung +Cc: Roman Li +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Roman Li +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn316/dcn316_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn321/dcn321_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 8 ++++---- + .../drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 8 ++++---- + 6 files changed, 24 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +index 4e962f522f1be..228ae665c7893 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +@@ -1230,12 +1230,12 @@ static struct stream_encoder *dcn315_stream_encoder_create( + /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/ + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +index 5a95dd54cb429..45abf3b2eb2c4 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +@@ -1223,12 +1223,12 @@ static struct stream_encoder *dcn316_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +index b276fec3e479a..d39a0f9c78c92 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +@@ -1211,12 +1211,12 @@ static struct stream_encoder *dcn32_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn32_vpg_create(ctx, vpg_inst); + afmt = dcn32_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +index 3466ca34c93fe..c72c6dbc0cb4d 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +@@ -1192,12 +1192,12 @@ static struct stream_encoder *dcn321_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn321_vpg_create(ctx, vpg_inst); + afmt = dcn321_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +index d056e5fd54587..9edabd8ceca9b 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +@@ -1274,12 +1274,12 @@ static struct stream_encoder *dcn35_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +index 9fab3169069c4..43ece2bbcd64f 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +@@ -1254,12 +1254,12 @@ static struct stream_encoder *dcn35_stream_encoder_create( + int afmt_inst; + + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ +- if (eng_id <= ENGINE_ID_DIGF) { +- vpg_inst = eng_id; +- afmt_inst = eng_id; +- } else ++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) + return NULL; + ++ vpg_inst = eng_id; ++ afmt_inst = eng_id; ++ + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg = dcn31_vpg_create(ctx, vpg_inst); + afmt = dcn31_afmt_create(ctx, afmt_inst); +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-initialize-dac-in-dce-link-encoder-u.patch b/queue-6.19/drm-amd-display-initialize-dac-in-dce-link-encoder-u.patch new file mode 100644 index 0000000000..bd0b146328 --- /dev/null +++ b/queue-6.19/drm-amd-display-initialize-dac-in-dce-link-encoder-u.patch @@ -0,0 +1,74 @@ +From 51c075fbf45e86de859b24e2c965538b41fd00ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 12:25:05 +0100 +Subject: drm/amd/display: Initialize DAC in DCE link encoder using VBIOS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit e2a024345bce78a8e1ed7d9e84c859b05979e41e ] + +The VBIOS DAC1EncoderControl() function can initialize the DAC, +by writing board-specific values to certain registers. +Call this at link encoder hardware initialization time similarly +to how the equivalent UNIPHYTransmitterControl initialization +is done. + +This fixes DAC output on the Radeon HD 7790. + +Also remove the ENCODER_CONTROL_SETUP enum from the +dac_encoder_control_prepare_params function which is actually +not a supported operation for DAC encoders. + +Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") +Signed-off-by: Timur Kristóf +Tested-by: Mauro Rossi +Suggested-by: Alex Deucher +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/bios/command_table.c | 3 +-- + drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 10 ++++++++++ + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c +index 76a3559f0ddc1..b692fa37402d9 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c +@@ -1874,8 +1874,7 @@ static void dac_encoder_control_prepare_params( + uint8_t dac_standard) + { + params->ucDacStandard = dac_standard; +- if (action == ENCODER_CONTROL_SETUP || +- action == ENCODER_CONTROL_INIT) ++ if (action == ENCODER_CONTROL_INIT) + params->ucAction = ATOM_ENCODER_INIT; + else if (action == ENCODER_CONTROL_ENABLE) + params->ucAction = ATOM_ENABLE; +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +index 2e742950a62c7..48a1b3b492e7f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +@@ -1033,6 +1033,16 @@ void dce110_link_encoder_hw_init( + cntl.coherent = false; + cntl.hpd_sel = enc110->base.hpd_source; + ++ if (enc110->base.analog_engine != ENGINE_ID_UNKNOWN) { ++ result = link_dac_encoder_control(enc110, ENCODER_CONTROL_INIT, 0); ++ if (result != BP_RESULT_OK) { ++ DC_LOG_ERROR("%s: Failed to execute VBIOS command table for DAC!\n", ++ __func__); ++ BREAK_TO_DEBUGGER(); ++ return; ++ } ++ } ++ + /* The code below is only applicable to encoders with a digital transmitter. */ + if (enc110->base.transmitter == TRANSMITTER_UNKNOWN) + return; +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-only-use-analog-link-encoder-with-an.patch b/queue-6.19/drm-amd-display-only-use-analog-link-encoder-with-an.patch new file mode 100644 index 0000000000..864a289157 --- /dev/null +++ b/queue-6.19/drm-amd-display-only-use-analog-link-encoder-with-an.patch @@ -0,0 +1,72 @@ +From 238db58c8b29ecd7721f16050f26ab1d64e2aaf3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Jan 2026 22:08:25 +0100 +Subject: drm/amd/display: Only use analog link encoder with analog engine +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit f402898bd101af3166bde236b7f6a43d926e17a0 ] + +Some GPUs have analog connectors that work with a DP bridge chip +and don't actually have an internal DAC: Those should not use +the analog link encoder code path. + +Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") +Signed-off-by: Timur Kristóf +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c | 3 ++- + drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 3 ++- + drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c | 3 ++- + 3 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +index d40d91ec2035f..a916872db7bd4 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +@@ -638,7 +638,8 @@ static struct link_encoder *dce100_link_encoder_create( + if (!enc110) + return NULL; + +- if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { ++ if (enc_init_data->connector.id == CONNECTOR_ID_VGA && ++ enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { + dce110_link_encoder_construct(enc110, + enc_init_data, + &link_enc_feature, +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +index 068fb1df8d889..90d826237cf00 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +@@ -733,7 +733,8 @@ static struct link_encoder *dce60_link_encoder_create( + if (!enc110) + return NULL; + +- if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { ++ if (enc_init_data->connector.id == CONNECTOR_ID_VGA && ++ enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { + dce60_link_encoder_construct(enc110, + enc_init_data, + &link_enc_feature, +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +index 8687104cabb72..cde2c2cba1dd6 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +@@ -740,7 +740,8 @@ static struct link_encoder *dce80_link_encoder_create( + if (!enc110) + return NULL; + +- if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { ++ if (enc_init_data->connector.id == CONNECTOR_ID_VGA && ++ enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { + dce110_link_encoder_construct(enc110, + enc_init_data, + &link_enc_feature, +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-only-use-analog-stream-encoder-with-.patch b/queue-6.19/drm-amd-display-only-use-analog-stream-encoder-with-.patch new file mode 100644 index 0000000000..37a5b19368 --- /dev/null +++ b/queue-6.19/drm-amd-display-only-use-analog-stream-encoder-with-.patch @@ -0,0 +1,44 @@ +From 585a9e80f40b4c39f72af546774287ae7a753529 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Jan 2026 22:08:26 +0100 +Subject: drm/amd/display: Only use analog stream encoder with analog engine +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit 17ff034f805e032ed1358624a71381f9d6e29e9e ] + +Some GPUs have analog connectors that work with a DP bridge chip +and don't actually have an internal DAC: Those should not use +the analog stream encoders. + +Fixes: 5834c33fd3f6 ("drm/amd/display: Add concept of analog encoders (v2)") +Signed-off-by: Timur Kristóf +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +index a916872db7bd4..83b9abb64bfcb 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +@@ -979,7 +979,10 @@ struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link( + struct dc_link *link = stream->link; + enum engine_id preferred_engine = link->link_enc->preferred_engine; + +- if (dc_is_rgb_signal(stream->signal)) ++ /* Prefer analog engine if the link encoder has one. ++ * Otherwise, it's an external encoder. ++ */ ++ if (dc_is_rgb_signal(stream->signal) && link->link_enc->analog_engine != ENGINE_ID_UNKNOWN) + preferred_engine = link->link_enc->analog_engine; + + for (i = 0; i < pool->stream_enc_count; i++) { +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch b/queue-6.19/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch new file mode 100644 index 0000000000..474c7e0322 --- /dev/null +++ b/queue-6.19/drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch @@ -0,0 +1,69 @@ +From 1f4b6cffa3be92f0814c5a49096654daf981e516 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 18 Jan 2026 15:57:41 +0100 +Subject: drm/amd/display: Reject cursor plane on DCE when scaled differently + than primary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit 41af6215cdbcecd12920f211239479027904abf3 ] + +Currently DCE doesn't support the overlay cursor, so the +dm_crtc_get_cursor_mode() function returns DM_CURSOR_NATIVE_MODE +unconditionally. The outcome is that it doesn't check for the +conditions that would necessitate the overlay cursor, meaning +that it doesn't reject cases where the native cursor mode isn't +supported on DCE. + +Remove the early return from dm_crtc_get_cursor_mode() for +DCE and instead let it perform the necessary checks and +return DM_CURSOR_OVERLAY_MODE. Add a later check that rejects +when DM_CURSOR_OVERLAY_MODE would be used with DCE. + +Fixes: 1b04dcca4fb1 ("drm/amd/display: Introduce overlay cursor mode") +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4600 +Suggested-by: Leo Li +Signed-off-by: Timur Kristóf +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index b31bd6fa70181..62622aa622066 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -12275,10 +12275,9 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, + + /* Overlay cursor not supported on HW before DCN + * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions +- * as previous DCN generations, so enable native mode on DCN401 in addition to DCE ++ * as previous DCN generations, so enable native mode on DCN401 + */ +- if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 || +- amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { ++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { + *cursor_mode = DM_CURSOR_NATIVE_MODE; + return 0; + } +@@ -12598,6 +12597,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, + * need to be added for DC to not disable a plane by mistake + */ + if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) { ++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) { ++ drm_dbg(dev, "Overlay cursor not supported on DCE\n"); ++ ret = -EINVAL; ++ goto fail; ++ } ++ + ret = drm_atomic_add_affected_planes(state, crtc); + if (ret) + goto fail; +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-set-crtc-source-for-dac-using-regist.patch b/queue-6.19/drm-amd-display-set-crtc-source-for-dac-using-regist.patch new file mode 100644 index 0000000000..572bb6d185 --- /dev/null +++ b/queue-6.19/drm-amd-display-set-crtc-source-for-dac-using-regist.patch @@ -0,0 +1,276 @@ +From 3c41d946a418f482679daa80023a9dbb45bb7f75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 12:25:06 +0100 +Subject: drm/amd/display: Set CRTC source for DAC using registers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit cbced93894d145239c83881d7fd953b7392c23a8 ] + +Apparently the VBIOS SelectCRTC_Source function overwrites +a few registers (such as FMT_*) which DC writes in a different +place, which can cause problems. + +Instead of using the SelectCRTC_Source function from the +VBIOS, use the DAC_SOURCE_SELECT register directly, similarly +to how it is done for digital link encoders. + +Fixes: 3be26d81b150 ("drm/amd/display: Support DAC in dce110_hwseq") +Signed-off-by: Timur Kristóf +Tested-by: Mauro Rossi +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../amd/display/dc/dce/dce_stream_encoder.c | 23 +++++++++++++--- + .../amd/display/dc/dce/dce_stream_encoder.h | 12 +++++++-- + .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 26 +------------------ + .../dc/resource/dce100/dce100_resource.c | 6 +++-- + .../dc/resource/dce60/dce60_resource.c | 7 +++-- + .../dc/resource/dce80/dce80_resource.c | 6 +++-- + 6 files changed, 43 insertions(+), 37 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +index 574618d5d4a4e..87c19f17c799f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +@@ -1498,7 +1498,10 @@ static void dig_connect_to_otg( + { + struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); + +- REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst); ++ if (enc->id == ENGINE_ID_DACA || enc->id == ENGINE_ID_DACB) ++ REG_UPDATE(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, tg_inst); ++ else ++ REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst); + } + + static unsigned int dig_source_otg( +@@ -1507,7 +1510,10 @@ static unsigned int dig_source_otg( + uint32_t tg_inst = 0; + struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); + +- REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst); ++ if (enc->id == ENGINE_ID_DACA || enc->id == ENGINE_ID_DACB) ++ REG_GET(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, &tg_inst); ++ else ++ REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst); + + return tg_inst; + } +@@ -1568,16 +1574,25 @@ void dce110_stream_encoder_construct( + enc110->se_mask = se_mask; + } + +-static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {}; ++static const struct stream_encoder_funcs dce110_an_str_enc_funcs = { ++ .dig_connect_to_otg = dig_connect_to_otg, ++ .dig_source_otg = dig_source_otg, ++}; + + void dce110_analog_stream_encoder_construct( + struct dce110_stream_encoder *enc110, + struct dc_context *ctx, + struct dc_bios *bp, +- enum engine_id eng_id) ++ enum engine_id eng_id, ++ const struct dce110_stream_enc_registers *regs, ++ const struct dce_stream_encoder_shift *se_shift, ++ const struct dce_stream_encoder_mask *se_mask) + { + enc110->base.funcs = &dce110_an_str_enc_funcs; + enc110->base.ctx = ctx; + enc110->base.id = eng_id; + enc110->base.bp = bp; ++ enc110->regs = regs; ++ enc110->se_shift = se_shift; ++ enc110->se_mask = se_mask; + } +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h +index 068de1392121e..342c0afe6a949 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h +@@ -65,6 +65,7 @@ + SRI(AFMT_60958_1, DIG, id), \ + SRI(AFMT_60958_2, DIG, id), \ + SRI(DIG_FE_CNTL, DIG, id), \ ++ SR(DAC_SOURCE_SELECT), \ + SRI(HDMI_CONTROL, DIG, id), \ + SRI(HDMI_GC, DIG, id), \ + SRI(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \ +@@ -290,7 +291,8 @@ + #define SE_COMMON_MASK_SH_LIST_DCE80_100(mask_sh)\ + SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\ + SE_SF(TMDS_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\ +- SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh) ++ SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh),\ ++ SE_SF(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, mask_sh) + + #define SE_COMMON_MASK_SH_LIST_DCE110(mask_sh)\ + SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\ +@@ -494,6 +496,7 @@ struct dce_stream_encoder_shift { + uint8_t DP_VID_N_MUL; + uint8_t DP_VID_M_DOUBLE_VALUE_EN; + uint8_t DIG_SOURCE_SELECT; ++ uint8_t DAC_SOURCE_SELECT; + }; + + struct dce_stream_encoder_mask { +@@ -626,6 +629,7 @@ struct dce_stream_encoder_mask { + uint32_t DP_VID_N_MUL; + uint32_t DP_VID_M_DOUBLE_VALUE_EN; + uint32_t DIG_SOURCE_SELECT; ++ uint32_t DAC_SOURCE_SELECT; + }; + + struct dce110_stream_enc_registers { +@@ -653,6 +657,7 @@ struct dce110_stream_enc_registers { + uint32_t AFMT_60958_1; + uint32_t AFMT_60958_2; + uint32_t DIG_FE_CNTL; ++ uint32_t DAC_SOURCE_SELECT; + uint32_t DP_MSE_RATE_CNTL; + uint32_t DP_MSE_RATE_UPDATE; + uint32_t DP_PIXEL_FORMAT; +@@ -712,7 +717,10 @@ void dce110_analog_stream_encoder_construct( + struct dce110_stream_encoder *enc110, + struct dc_context *ctx, + struct dc_bios *bp, +- enum engine_id eng_id); ++ enum engine_id eng_id, ++ const struct dce110_stream_enc_registers *regs, ++ const struct dce_stream_encoder_shift *se_shift, ++ const struct dce_stream_encoder_mask *se_mask); + + void dce110_se_audio_mute_control( + struct stream_encoder *enc, bool mute); +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +index fd41e52e4d2f1..c472303276672 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +@@ -1600,25 +1600,6 @@ static enum dc_status dce110_enable_stream_timing( + return DC_OK; + } + +-static void +-dce110_select_crtc_source(struct pipe_ctx *pipe_ctx) +-{ +- struct dc_link *link = pipe_ctx->stream->link; +- struct dc_bios *bios = link->ctx->dc_bios; +- struct bp_crtc_source_select crtc_source_select = {0}; +- enum engine_id engine_id = link->link_enc->preferred_engine; +- +- if (dc_is_rgb_signal(pipe_ctx->stream->signal)) +- engine_id = link->link_enc->analog_engine; +- +- crtc_source_select.controller_id = CONTROLLER_ID_D0 + pipe_ctx->stream_res.tg->inst; +- crtc_source_select.color_depth = pipe_ctx->stream->timing.display_color_depth; +- crtc_source_select.engine_id = engine_id; +- crtc_source_select.sink_signal = pipe_ctx->stream->signal; +- +- bios->funcs->select_crtc_source(bios, &crtc_source_select); +-} +- + enum dc_status dce110_apply_single_controller_ctx_to_hw( + struct pipe_ctx *pipe_ctx, + struct dc_state *context, +@@ -1638,10 +1619,6 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw( + hws->funcs.disable_stream_gating(dc, pipe_ctx); + } + +- if (pipe_ctx->stream->signal == SIGNAL_TYPE_RGB) { +- dce110_select_crtc_source(pipe_ctx); +- } +- + if (pipe_ctx->stream_res.audio != NULL) { + struct audio_output audio_output = {0}; + +@@ -1721,8 +1698,7 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw( + pipe_ctx->stream_res.tg->funcs->set_static_screen_control( + pipe_ctx->stream_res.tg, event_triggers, 2); + +- if (!dc_is_virtual_signal(pipe_ctx->stream->signal) && +- !dc_is_rgb_signal(pipe_ctx->stream->signal)) ++ if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) + pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( + pipe_ctx->stream_res.stream_enc, + pipe_ctx->stream_res.tg->inst); +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +index 83b9abb64bfcb..b78bb595d69ed 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +@@ -242,7 +242,8 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { + stream_enc_regs(3), + stream_enc_regs(4), + stream_enc_regs(5), +- stream_enc_regs(6) ++ stream_enc_regs(6), ++ {SR(DAC_SOURCE_SELECT),} /* DACA */ + }; + + static const struct dce_stream_encoder_shift se_shift = { +@@ -491,7 +492,8 @@ static struct stream_encoder *dce100_stream_encoder_create( + return NULL; + + if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { +- dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); ++ dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, ++ &stream_enc_regs[eng_id], &se_shift, &se_mask); + return &enc110->base; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +index 90d826237cf00..6cf2faffc961b 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +@@ -258,7 +258,9 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { + stream_enc_regs(2), + stream_enc_regs(3), + stream_enc_regs(4), +- stream_enc_regs(5) ++ stream_enc_regs(5), ++ {0}, ++ {SR(DAC_SOURCE_SELECT),} /* DACA */ + }; + + static const struct dce_stream_encoder_shift se_shift = { +@@ -607,7 +609,8 @@ static struct stream_encoder *dce60_stream_encoder_create( + return NULL; + + if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { +- dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); ++ dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, ++ &stream_enc_regs[eng_id], &se_shift, &se_mask); + return &enc110->base; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +index cde2c2cba1dd6..066dbf8125a87 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +@@ -258,7 +258,8 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { + stream_enc_regs(3), + stream_enc_regs(4), + stream_enc_regs(5), +- stream_enc_regs(6) ++ stream_enc_regs(6), ++ {SR(DAC_SOURCE_SELECT),} /* DACA */ + }; + + static const struct dce_stream_encoder_shift se_shift = { +@@ -614,7 +615,8 @@ static struct stream_encoder *dce80_stream_encoder_create( + return NULL; + + if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { +- dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); ++ dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, ++ &stream_enc_regs[eng_id], &se_shift, &se_mask); + return &enc110->base; + } + +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-turn-off-dac-in-dce-link-encoder-usi.patch b/queue-6.19/drm-amd-display-turn-off-dac-in-dce-link-encoder-usi.patch new file mode 100644 index 0000000000..d3d74547fb --- /dev/null +++ b/queue-6.19/drm-amd-display-turn-off-dac-in-dce-link-encoder-usi.patch @@ -0,0 +1,97 @@ +From e3a82348739ce91450f0a3e8e7883766b5c467d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 12:25:04 +0100 +Subject: drm/amd/display: Turn off DAC in DCE link encoder using VBIOS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit e021ee995056ee7e58114edd92bcd4578d8b4bb5 ] + +Apparently, the VBIOS DAC1EncoderControl function is much more +graceful about turning off the DAC. It writes various DAC +registers in a specific sequence. Use that instead of just +clearing the DAC_ENABLE register. + +Do this in just the dce110_link_encoder_disable_output +function and remove it from the HWSS. + +Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") +Signed-off-by: Timur Kristóf +Tested-by: Mauro Rossi +Suggested-by: Alex Deucher +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/display/dc/dce/dce_link_encoder.c | 30 +++++++++++-------- + .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 3 -- + 2 files changed, 17 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +index 5c1a10f77733a..2e742950a62c7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +@@ -131,6 +131,21 @@ static enum bp_result link_transmitter_control( + return result; + } + ++static enum bp_result link_dac_encoder_control( ++ struct dce110_link_encoder *link_enc, ++ enum bp_encoder_control_action action, ++ uint32_t pix_clk_100hz) ++{ ++ struct dc_bios *bios = link_enc->base.ctx->dc_bios; ++ struct bp_encoder_control encoder_control = {0}; ++ ++ encoder_control.action = action; ++ encoder_control.engine_id = link_enc->base.analog_engine; ++ encoder_control.pixel_clock = pix_clk_100hz / 10; ++ ++ return bios->funcs->encoder_control(bios, &encoder_control); ++} ++ + static void enable_phy_bypass_mode( + struct dce110_link_encoder *enc110, + bool enable) +@@ -1337,19 +1352,8 @@ void dce110_link_encoder_disable_output( + struct bp_transmitter_control cntl = { 0 }; + enum bp_result result; + +- switch (enc->analog_engine) { +- case ENGINE_ID_DACA: +- REG_UPDATE(DAC_ENABLE, DAC_ENABLE, 0); +- break; +- case ENGINE_ID_DACB: +- /* DACB doesn't seem to be present on DCE6+, +- * although there are references to it in the register file. +- */ +- DC_LOG_ERROR("%s DACB is unsupported\n", __func__); +- break; +- default: +- break; +- } ++ if (enc->analog_engine != ENGINE_ID_UNKNOWN) ++ link_dac_encoder_control(enc110, ENCODER_CONTROL_DISABLE, 0); + + /* The code below only applies to connectors that support digital signals. */ + if (enc->transmitter == TRANSMITTER_UNKNOWN) +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +index ebd74b43e935e..fd41e52e4d2f1 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +@@ -1218,9 +1218,6 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) + dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, + link_enc->transmitter - TRANSMITTER_UNIPHY_A); + } +- +- if (dc_is_rgb_signal(pipe_ctx->stream->signal)) +- dce110_dac_encoder_control(pipe_ctx, false); + } + + void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-use-dce-6-link-encoder-for-dce-6-ana.patch b/queue-6.19/drm-amd-display-use-dce-6-link-encoder-for-dce-6-ana.patch new file mode 100644 index 0000000000..bfd3c5d721 --- /dev/null +++ b/queue-6.19/drm-amd-display-use-dce-6-link-encoder-for-dce-6-ana.patch @@ -0,0 +1,40 @@ +From 674df3f14a80ca6d211ff258bc5b4542c2b6389e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Jan 2026 22:08:24 +0100 +Subject: drm/amd/display: Use DCE 6 link encoder for DCE 6 analog connectors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Timur Kristóf + +[ Upstream commit 2de34fbcab2063cd3d52e5872a801b9a5fc755d0 ] + +DCE 6 should use the DCE 6 specific link encoder. +This was a copy paste mistake. + +Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)") +Signed-off-by: Timur Kristóf +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +index f0152933bee2c..068fb1df8d889 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +@@ -734,7 +734,7 @@ static struct link_encoder *dce60_link_encoder_create( + return NULL; + + if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { +- dce110_link_encoder_construct(enc110, ++ dce60_link_encoder_construct(enc110, + enc_init_data, + &link_enc_feature, + &link_enc_regs[ENGINE_ID_DACA], +-- +2.51.0 + diff --git a/queue-6.19/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch b/queue-6.19/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch new file mode 100644 index 0000000000..3a31535015 --- /dev/null +++ b/queue-6.19/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch @@ -0,0 +1,78 @@ +From 210ff702204f6c81f911cc2cfe363c8bcd96bad9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 23:38:28 +0100 +Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp + formats + +From: Mario Kleiner + +[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ] + +The plane scaling hw seems to have the same min/max plane scaling limits +for all 16 bpc / 64 bpp interleaved pixel color formats. + +Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for +all the 16 bpc fixed-point / unorm formats to use the same .fp16 +up/downscaling factor limits as used by the fp16 floating point formats. + +So far, 16 bpc unorm formats were not handled, and the default: path +returned max/min factors for 32 bpp argb8888 formats, which were wrong +and bigger than what many DCE / DCN hw generations could handle. + +The result sometimes was misscaling of framebuffers with +DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616, +DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested +on Polaris11 / DCE-11.2. + +So far this went unnoticed, because only few userspace clients used such +16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they +did not experience this issue. + +With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL +and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland +compositor allowing for direct scanout of these formats, the scaling +hw will be used on these formats if possible for HiDPI display scaling, +so it is important to use the correct hw scaling limits to avoid wrong +display. + +Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50 +on HiDPI displays with scaling enabled. The mutter Wayland compositor now +correctly falls back to scaling via desktop compositing instead of direct +scanout, thereby avoiding wrong image display. For unscaled mode, it +correctly uses direct scanout. + +Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.") +Signed-off-by: Mario Kleiner +Tested-by: Mario Kleiner +Cc: Alex Deucher +Cc: Harry Wentland +Cc: Leo Li +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +index 7c4496fb4b9d4..f0946e67aef97 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +@@ -1060,10 +1060,15 @@ static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev, + *min_downscale = plane_cap->max_downscale_factor.nv12; + break; + ++ /* All 64 bpp formats have the same fp16 scaling limits */ + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: ++ case DRM_FORMAT_XRGB16161616: ++ case DRM_FORMAT_ARGB16161616: ++ case DRM_FORMAT_XBGR16161616: ++ case DRM_FORMAT_ABGR16161616: + *max_upscale = plane_cap->max_upscale_factor.fp16; + *min_downscale = plane_cap->max_downscale_factor.fp16; + break; +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-clean-up-the-amdgpu_cs_parser_bos.patch b/queue-6.19/drm-amdgpu-clean-up-the-amdgpu_cs_parser_bos.patch new file mode 100644 index 0000000000..195a0c2b31 --- /dev/null +++ b/queue-6.19/drm-amdgpu-clean-up-the-amdgpu_cs_parser_bos.patch @@ -0,0 +1,50 @@ +From 59d10ec5f2006f6c062f3b25ae60a512dadbc22d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 12:09:05 +0530 +Subject: drm/amdgpu: clean up the amdgpu_cs_parser_bos +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Sunil Khatri + +[ Upstream commit f025a2b8d93358467b8e8f4b3a617e88c5f02fab ] + +In low memory conditions, kmalloc can fail. In such conditions +unlock the mutex for a clean exit. + +We do not need to amdgpu_bo_list_put as it's been handled in the +amdgpu_cs_parser_fini. + +Fixes: 737da5363cc0 ("drm/amdgpu: update the functions to use amdgpu version of hmm") +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/202602030017.7E0xShmH-lkp@intel.com/ +Signed-off-by: Sunil Khatri +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +index ecdfe6cb36ccd..dac0b15823f2a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -892,8 +892,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, + struct amdgpu_bo *bo = e->bo; + + e->range = amdgpu_hmm_range_alloc(NULL); +- if (unlikely(!e->range)) +- return -ENOMEM; ++ if (unlikely(!e->range)) { ++ r = -ENOMEM; ++ goto out_free_user_pages; ++ } + + r = amdgpu_ttm_tt_get_user_pages(bo, e->range); + if (r) +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch b/queue-6.19/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch new file mode 100644 index 0000000000..24d51ec0c9 --- /dev/null +++ b/queue-6.19/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch @@ -0,0 +1,46 @@ +From 06a0ff33b8d3b779d4586497780f255aa7ef527e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 09:25:32 +0000 +Subject: drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc() + +From: Zilin Guan + +[ Upstream commit c9be63d565789b56ca7b0197e2cb78a3671f95a8 ] + +In amdgpu_acpi_enumerate_xcc(), if amdgpu_acpi_dev_init() returns -ENOMEM, +the function returns directly without releasing the allocated xcc_info, +resulting in a memory leak. + +Fix this by ensuring that xcc_info is properly freed in the error paths. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects") +Reviewed-by: Lijo Lazar +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +index d31460a9e9582..7c9d8a6d0bfdb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -1135,8 +1135,10 @@ static int amdgpu_acpi_enumerate_xcc(void) + if (!dev_info) + ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf); + +- if (ret == -ENOMEM) ++ if (ret == -ENOMEM) { ++ kfree(xcc_info); + return ret; ++ } + + if (!dev_info) { + kfree(xcc_info); +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch b/queue-6.19/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch new file mode 100644 index 0000000000..fcf97e54e4 --- /dev/null +++ b/queue-6.19/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch @@ -0,0 +1,44 @@ +From 81ef3e5b87c4fa8efb0644016a6927fef11c5909 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 08:35:15 +0000 +Subject: drm/amdgpu: Fix memory leak in amdgpu_ras_init() + +From: Zilin Guan + +[ Upstream commit ee41e5b63c8210525c936ee637a2c8d185ce873c ] + +When amdgpu_nbio_ras_sw_init() fails in amdgpu_ras_init(), the function +returns directly without freeing the allocated con structure, leading +to a memory leak. + +Fix this by jumping to the release_con label to properly clean up the +allocated memory before returning the error code. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: fdc94d3a8c88 ("drm/amdgpu: Rework pcie_bif ras sw_init") +Reviewed-by: Tao Zhou +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index 2a6cf7963dde2..8de9f68f7bea6 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -4343,7 +4343,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev) + * to handle fatal error */ + r = amdgpu_nbio_ras_sw_init(adev); + if (r) +- return r; ++ goto release_con; + + if (adev->nbio.ras && + adev->nbio.ras->init_ras_controller_interrupt) { +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-fix-missing-unwind-in-amdgpu_ib_schedule-.patch b/queue-6.19/drm-amdgpu-fix-missing-unwind-in-amdgpu_ib_schedule-.patch new file mode 100644 index 0000000000..fd39de740b --- /dev/null +++ b/queue-6.19/drm-amdgpu-fix-missing-unwind-in-amdgpu_ib_schedule-.patch @@ -0,0 +1,86 @@ +From 76ea02802259f38f7748d1555c392230891ebdbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 19:53:05 +0530 +Subject: drm/amdgpu: Fix missing unwind in amdgpu_ib_schedule() error path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Srinivasan Shanmugam + +[ Upstream commit ba038065655c45728be346d0b174a6da08d8a5c5 ] + +amdgpu_ib_schedule() returns early after calling amdgpu_ring_undo(). +This skips the common free_fence cleanup path. Other error paths were +already changed to use goto free_fence, but this one was missed. + +Change the early return to goto free_fence so all error paths clean up +the same way. + +Fixes the below: +drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c:232 amdgpu_ib_schedule() +warn: missing unwind goto? + +drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c + 124 int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, + 125 struct amdgpu_ib *ibs, struct amdgpu_job *job, + 126 struct dma_fence **f) + 127 { + + ... + + 224 + 225 if (ring->funcs->insert_start) + 226 ring->funcs->insert_start(ring); + 227 + 228 if (job) { + 229 r = amdgpu_vm_flush(ring, job, need_pipe_sync); + 230 if (r) { + 231 amdgpu_ring_undo(ring); +--> 232 return r; + + The patch changed the other error paths to goto free_fence but + this one was accidentally skipped. + + 233 } + 234 } + 235 + 236 amdgpu_ring_ib_begin(ring); + + ... + + 338 + 339 free_fence: + 340 if (!job) + 341 kfree(af); + 342 return r; + 343 } + +Fixes: f903b85ed0f1 ("drm/amdgpu: fix possible fence leaks from job structure") +Reported-by: Dan Carpenter +Cc: Alex Deucher +Cc: Christian König +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +index 44f230d67da24..bfa64cd7a62d4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +@@ -229,7 +229,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, + r = amdgpu_vm_flush(ring, job, need_pipe_sync); + if (r) { + amdgpu_ring_undo(ring); +- return r; ++ goto free_fence; + } + } + +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch b/queue-6.19/drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch new file mode 100644 index 0000000000..4cb1d09278 --- /dev/null +++ b/queue-6.19/drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch @@ -0,0 +1,49 @@ +From 79cbd5b6ee2616770f7f555fbad86067c5c7ef49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 11:51:45 -0500 +Subject: drm/amdgpu/sdma5: enable queue resets unconditionally + +From: Alex Deucher + +[ Upstream commit 46a2cb7d24f21132e970cab52359210c3f5ea3c6 ] + +There is no firmware version dependency. + +Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask") +Cc: Jesse Zhang +Reviewed-by: Jesse.Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 15 +++------------ + 1 file changed, 3 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +index 8ddc4df06a1fd..45e2933214a80 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +@@ -1424,18 +1424,9 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block) + + adev->sdma.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); +- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { +- case IP_VERSION(5, 0, 0): +- case IP_VERSION(5, 0, 2): +- case IP_VERSION(5, 0, 5): +- if ((adev->sdma.instance[0].fw_version >= 35) && +- !amdgpu_sriov_vf(adev) && +- !adev->debug_disable_gpu_ring_reset) +- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; +- break; +- default: +- break; +- } ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) ++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + + /* Allocate memory for SDMA IP Dump buffer */ + ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL); +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch b/queue-6.19/drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch new file mode 100644 index 0000000000..8db141db46 --- /dev/null +++ b/queue-6.19/drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch @@ -0,0 +1,58 @@ +From ae71f9207da511fc585e4fb123ae57bb5f873148 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 11:52:46 -0500 +Subject: drm/amdgpu/sdma5.2: enable queue resets unconditionally + +From: Alex Deucher + +[ Upstream commit 314d30ad50622fc0d70da71509f9dff21545be14 ] + +There is no firmware version dependency. This also +enables sdma queue resets on all SDMA 5.2.x based +chips. + +Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask") +Cc: Jesse Zhang +Reviewed-by: Jesse.Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 22 +++------------------- + 1 file changed, 3 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +index 51101b0aa2fab..82b1d34a6533e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +@@ -1342,25 +1342,9 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block) + + adev->sdma.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); +- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { +- case IP_VERSION(5, 2, 0): +- case IP_VERSION(5, 2, 2): +- case IP_VERSION(5, 2, 3): +- case IP_VERSION(5, 2, 4): +- if ((adev->sdma.instance[0].fw_version >= 76) && +- !amdgpu_sriov_vf(adev) && +- !adev->debug_disable_gpu_ring_reset) +- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; +- break; +- case IP_VERSION(5, 2, 5): +- if ((adev->sdma.instance[0].fw_version >= 34) && +- !amdgpu_sriov_vf(adev) && +- !adev->debug_disable_gpu_ring_reset) +- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; +- break; +- default: +- break; +- } ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) ++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + + /* Allocate memory for SDMA IP Dump buffer */ + ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL); +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch b/queue-6.19/drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch new file mode 100644 index 0000000000..3c6083f652 --- /dev/null +++ b/queue-6.19/drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch @@ -0,0 +1,51 @@ +From 4665dfb40041a079b2a3a694013b5a9b11613770 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 11:53:51 -0500 +Subject: drm/amdgpu/sdma6: enable queue resets unconditionally + +From: Alex Deucher + +[ Upstream commit 56423871e9eef1dd069bddef895207fa5ce275fe ] + +There is no firmware version dependency. This also +enables sdma queue resets on all SDMA 6.x based +chips. + +Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask") +Cc: Jesse Zhang +Reviewed-by: Jesse.Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 15 +++------------ + 1 file changed, 3 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +index 2170400449872..6809c6d4be5b1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +@@ -1351,18 +1351,9 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block) + + adev->sdma.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); +- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { +- case IP_VERSION(6, 0, 0): +- case IP_VERSION(6, 0, 2): +- case IP_VERSION(6, 0, 3): +- if ((adev->sdma.instance[0].fw_version >= 21) && +- !amdgpu_sriov_vf(adev) && +- !adev->debug_disable_gpu_ring_reset) +- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; +- break; +- default: +- break; +- } ++ if (!amdgpu_sriov_vf(adev) && ++ !adev->debug_disable_gpu_ring_reset) ++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + + if (amdgpu_sdma_ras_sw_init(adev)) { + dev_err(adev->dev, "Failed to initialize sdma ras block!\n"); +-- +2.51.0 + diff --git a/queue-6.19/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch b/queue-6.19/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch new file mode 100644 index 0000000000..284a5850b7 --- /dev/null +++ b/queue-6.19/drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch @@ -0,0 +1,44 @@ +From 91bce3d993cb5cdfe84dfdbc8565c0da954bd74b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 09:05:42 +0000 +Subject: drm/amdgpu: Use kvfree instead of kfree in + amdgpu_gmc_get_nps_memranges() + +From: Zilin Guan + +[ Upstream commit 0c44d61945c4a80775292d96460aa2f22e62f86c ] + +amdgpu_discovery_get_nps_info() internally allocates memory for ranges +using kvcalloc(), which may use vmalloc() for large allocation. Using +kfree() to release vmalloc memory will lead to a memory corruption. + +Use kvfree() to safely handle both kmalloc and vmalloc allocations. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: b194d21b9bcc ("drm/amdgpu: Use NPS ranges from discovery table") +Reviewed-by: Lijo Lazar +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +index d9c7ad297293b..2b37398337afc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +@@ -1387,7 +1387,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev, + if (!*exp_ranges) + *exp_ranges = range_cnt; + err: +- kfree(ranges); ++ kvfree(ranges); + + return ret; + } +-- +2.51.0 + diff --git a/queue-6.19/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch b/queue-6.19/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch new file mode 100644 index 0000000000..af961ad848 --- /dev/null +++ b/queue-6.19/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch @@ -0,0 +1,138 @@ +From 3d79a11f6f79740d2241dc2e5e122ec070426e47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 21:18:11 +0530 +Subject: drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Srinivasan Shanmugam + +[ Upstream commit 5a19302cab5cec7ae7f1a60c619951e6c17d8742 ] + +The address watch clear code receives watch_id as an unsigned value +(u32), but some helper functions were using a signed int and checked +bits by shifting with watch_id. + +If a very large watch_id is passed from userspace, it can be converted +to a negative value. This can cause invalid shifts and may access +memory outside the watch_points array. + +drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 + +Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before +using it. Also use BIT(watch_id) to test and clear bits safely. + +This keeps the behavior unchanged for valid watch IDs and avoids +undefined behavior for invalid ones. + +Fixes the below: +drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448 +kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow +'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped + +drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c + 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, + 434 uint32_t watch_id) + 435 { + 436 int r; + 437 + 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) + +kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if +watch_id is larger than INT_MAX it leads to a buffer overflow. +(Negative shifts are undefined). + + 439 return -EINVAL; + 440 + 441 if (!pdd->dev->kfd->shared_resources.enable_mes) { + 442 r = debug_lock_and_unmap(pdd->dev->dqm); + 443 if (r) + 444 return r; + 445 } + 446 + 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false); +--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch( + 449 pdd->dev->adev, + 450 watch_id); + +v2: (as per, Jonathan Kim) + - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to + match the clear path. + - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id(). + +Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation") +Reported-by: Dan Carpenter +Cc: Jonathan Kim +Cc: Felix Kuehling +Cc: Alex Deucher +Cc: Christian König +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Jonathan Kim +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +index ba99e0f258aee..986cb297de8f8 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +@@ -401,27 +401,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i + return -ENOMEM; + } + +-static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id) ++static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) + { + spin_lock(&pdd->dev->watch_points_lock); + + /* process owns device watch point so safe to clear */ +- if ((pdd->alloc_watch_ids >> watch_id) & 0x1) { +- pdd->alloc_watch_ids &= ~(0x1 << watch_id); +- pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id); ++ if (pdd->alloc_watch_ids & BIT(watch_id)) { ++ pdd->alloc_watch_ids &= ~BIT(watch_id); ++ pdd->dev->alloc_watch_ids &= ~BIT(watch_id); + } + + spin_unlock(&pdd->dev->watch_points_lock); + } + +-static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id) ++static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) + { + bool owns_watch_id = false; + + spin_lock(&pdd->dev->watch_points_lock); +- owns_watch_id = watch_id < MAX_WATCH_ADDRESSES && +- ((pdd->alloc_watch_ids >> watch_id) & 0x1); +- ++ owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id); + spin_unlock(&pdd->dev->watch_points_lock); + + return owns_watch_id; +@@ -432,6 +430,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, + { + int r; + ++ if (watch_id >= MAX_WATCH_ADDRESSES) ++ return -EINVAL; ++ + if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) + return -EINVAL; + +@@ -469,6 +470,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd, + if (r) + return r; + ++ if (*watch_id >= MAX_WATCH_ADDRESSES) ++ return -EINVAL; ++ + if (!pdd->dev->kfd->shared_resources.enable_mes) { + r = debug_lock_and_unmap(pdd->dev->dqm); + if (r) { +-- +2.51.0 + diff --git a/queue-6.19/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch b/queue-6.19/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch new file mode 100644 index 0000000000..787fd2fb7b --- /dev/null +++ b/queue-6.19/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch @@ -0,0 +1,40 @@ +From 96a1d5e9254814e0919926cffe7375dea2515ad5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jan 2026 08:55:49 +0530 +Subject: drm/i915/acpi: free _DSM package when no connectors + +From: Kaushlendra Kumar + +[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ] + +acpi_evaluate_dsm_typed() returns an ACPI package in pkg. +When pkg->package.count == 0, we returned without freeing pkg, +leaking memory. Free pkg before returning on the empty case. + +Signed-off-by: Kaushlendra Kumar +Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects") +Reviewed-by: Jani Nikula +Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c +index 68c01932f7b4f..e06f324027bec 100644 +--- a/drivers/gpu/drm/i915/display/intel_acpi.c ++++ b/drivers/gpu/drm/i915/display/intel_acpi.c +@@ -96,6 +96,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle) + + if (!pkg->package.count) { + DRM_DEBUG_DRIVER("no connection in _DSM\n"); ++ ACPI_FREE(pkg); + return; + } + +-- +2.51.0 + diff --git a/queue-6.19/drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch b/queue-6.19/drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch new file mode 100644 index 0000000000..5fb14ef178 --- /dev/null +++ b/queue-6.19/drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch @@ -0,0 +1,44 @@ +From b0157cec3d749b6f4a09a6fb4d230e93b579da15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 11:26:22 +0530 +Subject: drm/xe/bo: Redirect faults to dummy page for wedged device + +From: Raag Jadav + +[ Upstream commit 4e83a8d58e1c721a89b3ffe15f549007080272e2 ] + +As per uapi documentation[1], the prerequisite for wedged device is to +redirected page faults to a dummy page. Follow it. + +[1] Documentation/gpu/drm-uapi.rst + +v2: Add uapi reference and fixes tag (Matthew Brost) + +Fixes: 7bc00751f877 ("drm/xe: Use device wedged event") +Signed-off-by: Raag Jadav +Reviewed-by: Matthew Brost +Link: https://patch.msgid.link/20260212055622.2054991-1-raag.jadav@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit c020fff70d757612933711dd3cc3751d7d782d3c) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_bo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c +index 71acd45aa33b0..579e98dec7492 100644 +--- a/drivers/gpu/drm/xe/xe_bo.c ++++ b/drivers/gpu/drm/xe/xe_bo.c +@@ -1942,7 +1942,7 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf) + int err = 0; + int idx; + +- if (!drm_dev_enter(&xe->drm, &idx)) ++ if (xe_device_wedged(xe) || !drm_dev_enter(&xe->drm, &idx)) + return ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot); + + ret = xe_bo_cpu_fault_fastpath(vmf, xe, bo, needs_rpm); +-- +2.51.0 + diff --git a/queue-6.19/drm-xe-configfs-fix-parameter-name-omitted-errors.patch b/queue-6.19/drm-xe-configfs-fix-parameter-name-omitted-errors.patch new file mode 100644 index 0000000000..b6d6e56fdd --- /dev/null +++ b/queue-6.19/drm-xe-configfs-fix-parameter-name-omitted-errors.patch @@ -0,0 +1,69 @@ +From d8e1903a39aaef8b8a7b159046a238d3e9148627 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Feb 2026 20:37:45 +0100 +Subject: drm/xe/configfs: Fix 'parameter name omitted' errors + +From: Michal Wajdeczko + +[ Upstream commit 2a673fb4d787ce6672862cb693112378bff86abb ] + +On some configs and old compilers we can get following build errors: + + ../drivers/gpu/drm/xe/xe_configfs.h: In function 'xe_configfs_get_ctx_restore_mid_bb': + ../drivers/gpu/drm/xe/xe_configfs.h:40:76: error: parameter name omitted + static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class, + ^~~~~~~~~~~~~~~~~~~~ + ../drivers/gpu/drm/xe/xe_configfs.h: In function 'xe_configfs_get_ctx_restore_post_bb': + ../drivers/gpu/drm/xe/xe_configfs.h:42:77: error: parameter name omitted + static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class, + ^~~~~~~~~~~~~~~~~~~~ +when trying to define our configfs stub functions. Fix that. + +Fixes: 7a4756b2fd04 ("drm/xe/lrc: Allow to add user commands mid context switch") +Signed-off-by: Michal Wajdeczko +Cc: Rodrigo Vivi +Reviewed-by: Rodrigo Vivi +Reviewed-by: Shuicheng Lin +Link: https://patch.msgid.link/20260203193745.576-1-michal.wajdeczko@intel.com +(cherry picked from commit f59cde8a2452b392115d2af8f1143a94725f4827) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_configfs.h | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_configfs.h b/drivers/gpu/drm/xe/xe_configfs.h +index fed57be0b90e1..f3683bc7eb90c 100644 +--- a/drivers/gpu/drm/xe/xe_configfs.h ++++ b/drivers/gpu/drm/xe/xe_configfs.h +@@ -21,9 +21,11 @@ bool xe_configfs_primary_gt_allowed(struct pci_dev *pdev); + bool xe_configfs_media_gt_allowed(struct pci_dev *pdev); + u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev); + bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev); +-u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class, ++u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, ++ enum xe_engine_class class, + const u32 **cs); +-u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class, ++u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, ++ enum xe_engine_class class, + const u32 **cs); + #ifdef CONFIG_PCI_IOV + unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev); +@@ -37,9 +39,11 @@ static inline bool xe_configfs_primary_gt_allowed(struct pci_dev *pdev) { return + static inline bool xe_configfs_media_gt_allowed(struct pci_dev *pdev) { return true; } + static inline u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev) { return U64_MAX; } + static inline bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev) { return false; } +-static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class, ++static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, ++ enum xe_engine_class class, + const u32 **cs) { return 0; } +-static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class, ++static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, ++ enum xe_engine_class class, + const u32 **cs) { return 0; } + static inline unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev) { return UINT_MAX; } + #endif +-- +2.51.0 + diff --git a/queue-6.19/drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch b/queue-6.19/drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch new file mode 100644 index 0000000000..09e4037f93 --- /dev/null +++ b/queue-6.19/drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch @@ -0,0 +1,42 @@ +From 7c623e978d9fe0f2fa7c82bdfd14ab36bf373cca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 18:18:54 +0000 +Subject: drm/xe: Make xe_modparam.force_vram_bar_size signed + +From: Shuicheng Lin + +[ Upstream commit 1acec6ef0511b92e7974cc5a8768bfd3a659feaf ] + +vram_bar_size is registered as an int module parameter and is documented +to accept negative values to disable BAR resizing. +Store it as an int in xe_modparam as well, so negative values work as +intended and the module_param type matches. + +Fixes: 80742a1aa26e ("drm/xe: Allow to drop vram resizing") +Reviewed-by: Michal Wajdeczko +Signed-off-by: Shuicheng Lin +Link: https://patch.msgid.link/20260202181853.1095736-2-shuicheng.lin@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit 25c9aa4dcb5ef2ad9f354d19f8f1eeb690d1c161) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_module.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h +index 5a3bfea8b7b4c..b668495392701 100644 +--- a/drivers/gpu/drm/xe/xe_module.h ++++ b/drivers/gpu/drm/xe/xe_module.h +@@ -12,7 +12,7 @@ + struct xe_modparam { + bool force_execlist; + bool probe_display; +- u32 force_vram_bar_size; ++ int force_vram_bar_size; + int guc_log_level; + char *guc_firmware_path; + char *huc_firmware_path; +-- +2.51.0 + diff --git a/queue-6.19/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch b/queue-6.19/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch new file mode 100644 index 0000000000..2d2a4886cd --- /dev/null +++ b/queue-6.19/drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch @@ -0,0 +1,61 @@ +From 4749844f8e36ad04ad08d7c0feac5d2c72bac2ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 16:56:22 +0000 +Subject: drm/xe/mmio: Avoid double-adjust in 64-bit reads + +From: Shuicheng Lin + +[ Upstream commit 4a9b4e1fa52a6aaa1adbb7f759048df14afed54c ] + +xe_mmio_read64_2x32() was adjusting register addresses and then +calling xe_mmio_read32(), which applies the adjustment again. +This may shift accesses twice if adj_offset < adj_limit. There is +no issue currently, as for media gt, adj_offset > adj_limit, so +the 2nd adjust will be a no-op. But it may not work in future. + +To fix it, replace the adjusted-address comparison with a direct +sanity check that ensures the MMIO address adjustment cutoff never +falls within the 8-byte range of a 64-bit register. And let +xe_mmio_read32() handle address translation. + +v2: rewrite the sanity check in a more natural way. (Matt) +v3: Add Fixes tag. (Jani) + +Fixes: 07431945d8ae ("drm/xe: Avoid 64-bit register reads") +Reviewed-by: Matt Roper +Cc: Jani Nikula +Cc: Rodrigo Vivi +Signed-off-by: Shuicheng Lin +Link: https://patch.msgid.link/20260130165621.471408-2-shuicheng.lin@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit a30f999681126b128a43137793ac84b6a5b7443f) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_mmio.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c +index 350dca1f09259..3d59440ec44dd 100644 +--- a/drivers/gpu/drm/xe/xe_mmio.c ++++ b/drivers/gpu/drm/xe/xe_mmio.c +@@ -260,11 +260,11 @@ u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) + struct xe_reg reg_udw = { .addr = reg.addr + 0x4 }; + u32 ldw, udw, oldudw, retries; + +- reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr); +- reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr); +- +- /* we shouldn't adjust just one register address */ +- xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4); ++ /* ++ * The two dwords of a 64-bit register can never straddle the offset ++ * adjustment cutoff. ++ */ ++ xe_tile_assert(mmio->tile, !in_range(mmio->adj_limit, reg.addr + 1, 7)); + + oldudw = xe_mmio_read32(mmio, reg_udw); + for (retries = 5; retries; --retries) { +-- +2.51.0 + diff --git a/queue-6.19/drm-xe-pf-fix-sysfs-initialization.patch b/queue-6.19/drm-xe-pf-fix-sysfs-initialization.patch new file mode 100644 index 0000000000..539bd3a267 --- /dev/null +++ b/queue-6.19/drm-xe-pf-fix-sysfs-initialization.patch @@ -0,0 +1,158 @@ +From 9e56a23cd646ae886dae8e2157a6b745b738af74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 00:53:32 +0100 +Subject: drm/xe/pf: Fix sysfs initialization + +From: Michal Wajdeczko + +[ Upstream commit bf7172cd25ed182f30af2cbb9f80c730dc717d8e ] + +In case of devm_add_action_or_reset() failure the provided cleanup +action will be run immediately on the not yet initialized kobject. +This may lead to errors like: + + [ ] kobject: '(null)' (ff110001393608e0): is not initialized, yet kobject_put() is being called. + [ ] WARNING: lib/kobject.c:734 at kobject_put+0xd9/0x250, CPU#0: kworker/0:0/9 + [ ] RIP: 0010:kobject_put+0xdf/0x250 + [ ] Call Trace: + [ ] xe_sriov_pf_sysfs_init+0x21/0x100 [xe] + [ ] xe_sriov_pf_init_late+0x87/0x2b0 [xe] + [ ] xe_sriov_init_late+0x5f/0x2c0 [xe] + [ ] xe_device_probe+0x5f2/0xc20 [xe] + [ ] xe_pci_probe+0x396/0x610 [xe] + [ ] local_pci_probe+0x47/0xb0 + + [ ] refcount_t: underflow; use-after-free. + [ ] WARNING: lib/refcount.c:28 at refcount_warn_saturate+0x68/0xb0, CPU#0: kworker/0:0/9 + [ ] RIP: 0010:refcount_warn_saturate+0x68/0xb0 + [ ] Call Trace: + [ ] kobject_put+0x174/0x250 + [ ] xe_sriov_pf_sysfs_init+0x21/0x100 [xe] + [ ] xe_sriov_pf_init_late+0x87/0x2b0 [xe] + [ ] xe_sriov_init_late+0x5f/0x2c0 [xe] + [ ] xe_device_probe+0x5f2/0xc20 [xe] + [ ] xe_pci_probe+0x396/0x610 [xe] + [ ] local_pci_probe+0x47/0xb0 + +Fix that by calling kobject_init() and kobject_add() separately +and register cleanup action after the kobject is initialized. + +Also make this cleanup registration a part of the create helper to +fix another mistake, as in the loop we were wrongly passing parent +kobject while registering cleanup action, and this resulted in some +undetected leaks. + +Fixes: 5c170a4d9c53 ("drm/xe/pf: Prepare sysfs for SR-IOV admin attributes") +Signed-off-by: Michal Wajdeczko +Cc: Rodrigo Vivi +Reviewed-by: Shuicheng Lin +Link: https://patch.msgid.link/20260203235332.1350-1-michal.wajdeczko@intel.com +(cherry picked from commit 98b16727f07e26a5d4de84d88805ce7ffcfdd324) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c | 54 +++++++++++++------------- + 1 file changed, 26 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c +index c0b767ac735cf..d1c1f6c295664 100644 +--- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c ++++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c +@@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = { + + /* no user serviceable parts below */ + +-static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid) ++static void action_put_kobject(void *arg) ++{ ++ struct kobject *kobj = arg; ++ ++ kobject_put(kobj); ++} ++ ++static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid, ++ const struct kobj_type *ktype) + { + struct xe_sriov_kobj *vkobj; ++ int err; + + xe_sriov_pf_assert_vfid(xe, vfid); + + vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL); + if (!vkobj) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + vkobj->xe = xe; + vkobj->vfid = vfid; ++ kobject_init(&vkobj->base, ktype); ++ ++ err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base); ++ if (err) ++ return ERR_PTR(err); ++ + return &vkobj->base; + } + +@@ -471,28 +486,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what) + xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err)); + } + +-static void action_put_kobject(void *arg) +-{ +- struct kobject *kobj = arg; +- +- kobject_put(kobj); +-} +- + static int pf_setup_root(struct xe_device *xe) + { + struct kobject *parent = &xe->drm.dev->kobj; + struct kobject *root; + int err; + +- root = create_xe_sriov_kobj(xe, PFID); +- if (!root) +- return pf_sysfs_error(xe, -ENOMEM, "root obj"); +- +- err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); +- if (err) +- return pf_sysfs_error(xe, err, "root action"); ++ root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype); ++ if (IS_ERR(root)) ++ return pf_sysfs_error(xe, PTR_ERR(root), "root obj"); + +- err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin"); ++ err = kobject_add(root, parent, "sriov_admin"); + if (err) + return pf_sysfs_error(xe, err, "root init"); + +@@ -513,20 +517,14 @@ static int pf_setup_tree(struct xe_device *xe) + root = xe->sriov.pf.sysfs.root; + + for (n = 0; n <= totalvfs; n++) { +- kobj = create_xe_sriov_kobj(xe, VFID(n)); +- if (!kobj) +- return pf_sysfs_error(xe, -ENOMEM, "tree obj"); +- +- err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); +- if (err) +- return pf_sysfs_error(xe, err, "tree action"); ++ kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype); ++ if (IS_ERR(kobj)) ++ return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj"); + + if (n) +- err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, +- root, "vf%u", n); ++ err = kobject_add(kobj, root, "vf%u", n); + else +- err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, +- root, "pf"); ++ err = kobject_add(kobj, root, "pf"); + if (err) + return pf_sysfs_error(xe, err, "tree init"); + +-- +2.51.0 + diff --git a/queue-6.19/drm-xe-vf-avoid-reading-media-version-when-media-gt-.patch b/queue-6.19/drm-xe-vf-avoid-reading-media-version-when-media-gt-.patch new file mode 100644 index 0000000000..c1d6f7ab5e --- /dev/null +++ b/queue-6.19/drm-xe-vf-avoid-reading-media-version-when-media-gt-.patch @@ -0,0 +1,63 @@ +From e3b0257cc0786db6923a17f3da5d2f6f9ab14cb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 12:50:41 +0100 +Subject: drm/xe/vf: Avoid reading media version when media GT is disabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Piotr Piórkowski + +[ Upstream commit 5e905ec67214444362b81345ef8fde63e58425b6 ] + +When the media GT is not allowed, a VF must not attempt to read +the media version from the GuC. The GuC may not be loaded, and +any attempt to communicate with it would result in a timeout +and a VF probe failure: + +(...) +[ 1912.406046] xe 0000:01:00.1: [drm] *ERROR* Tile0: GT1: GuC mmio request 0x5507: no reply 0x5507 +[ 1912.407277] xe 0000:01:00.1: [drm] *ERROR* Tile0: GT1: [GUC COMMUNICATION] MMIO send failed (-ETIMEDOUT) +[ 1912.408689] xe 0000:01:00.1: [drm] *ERROR* VF: Tile0: GT1: Failed to reset GuC state (-ETIMEDOUT) +[ 1912.413986] xe 0000:01:00.1: probe with driver xe failed with error -110 + +Let's skip reading the media version for VFs when the media GT is not +allowed. + +v2: move the condition directly to the VF path + +Fixes: 7abd69278bb5 ("drm/xe/configfs: Add attribute to disable GT types") +Signed-off-by: Piotr Piórkowski +Cc: Matt Roper +Cc: Michal Wajdeczko +Cc: Shuicheng Lin +Reviewed-by: Shuicheng Lin +Link: https://patch.msgid.link/20260202115041.2863357-1-piotr.piorkowski@intel.com +Signed-off-by: Michał Winiarski +(cherry picked from commit 0bcacf56dc0b265f9c47056c6a4f0c1394a8a3f0) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_pci.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c +index 2aa883f5ef797..38ea9d7dad091 100644 +--- a/drivers/gpu/drm/xe/xe_pci.c ++++ b/drivers/gpu/drm/xe/xe_pci.c +@@ -533,6 +533,12 @@ static int read_gmdid(struct xe_device *xe, enum xe_gmdid_type type, u32 *ver, u + struct xe_gt *gt __free(kfree) = NULL; + int err; + ++ /* Don't try to read media ver if media GT is not allowed */ ++ if (type == GMDID_MEDIA && !xe_configfs_media_gt_allowed(to_pci_dev(xe->drm.dev))) { ++ *ver = *revid = 0; ++ return 0; ++ } ++ + gt = kzalloc(sizeof(*gt), GFP_KERNEL); + if (!gt) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.19/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch b/queue-6.19/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch new file mode 100644 index 0000000000..76df58dd01 --- /dev/null +++ b/queue-6.19/drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch @@ -0,0 +1,72 @@ +From b9df89a3b93ae981b193e0304d5c334791f55b14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 14:05:09 -0800 +Subject: drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138 + +From: Matt Roper + +[ Upstream commit bc6387a2e0c1562faa56ce2a98cef50cab809e08 ] + +The PSS_CHICKEN register has been part of the RCS engine's LRC since it +was first introduced in Xe_LP. That means that any workarounds that +adjust its value (such as Wa_14019988906 and Wa_14019877138) need to be +implemented in the lrc_was[] table so that they become part of the +default LRC from which all subsequent LRCs are copied. Although these +workarounds were implemented correctly on most platforms, they were +incorrectly placed on the engine_was[] table for Xe2_HPG. + +Move the workarounds to the proper lrc_was[] table and switch the +'xe_rtp_match_first_render_or_compute' rule to specifically match the +RCS since that's the engine whose LRC manages the register. + +Bspec: 65182 +Fixes: 7f3ee7d88058 ("drm/xe/xe2hpg: Add initial GT workarounds") +Reviewed-by: Shekhar Chauhan +Link: https://patch.msgid.link/20260205220508.51905-2-matthew.d.roper@intel.com +Signed-off-by: Matt Roper +(cherry picked from commit e04c609eedf4d6748ac0bcada4de1275b034fed6) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_wa.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c +index e32dd2fde6f1c..c7eab0c4af7a8 100644 +--- a/drivers/gpu/drm/xe/xe_wa.c ++++ b/drivers/gpu/drm/xe/xe_wa.c +@@ -567,16 +567,6 @@ static const struct xe_rtp_entry_sr engine_was[] = { + FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS)) + }, +- { XE_RTP_NAME("14019988906"), +- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), +- FUNC(xe_rtp_match_first_render_or_compute)), +- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) +- }, +- { XE_RTP_NAME("14019877138"), +- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), +- FUNC(xe_rtp_match_first_render_or_compute)), +- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) +- }, + { XE_RTP_NAME("14020338487"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), + FUNC(xe_rtp_match_first_render_or_compute)), +@@ -873,6 +863,14 @@ static const struct xe_rtp_entry_sr lrc_was[] = { + XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(WM_CHICKEN3, HIZ_PLANE_COMPRESSION_DIS)) + }, ++ { XE_RTP_NAME("14019988906"), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) ++ }, ++ { XE_RTP_NAME("14019877138"), ++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) ++ }, + { XE_RTP_NAME("14021490052"), + XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(FF_MODE, +-- +2.51.0 + diff --git a/queue-6.19/efi-fix-reservation-of-unaccepted-memory-table.patch b/queue-6.19/efi-fix-reservation-of-unaccepted-memory-table.patch new file mode 100644 index 0000000000..c90345fc6a --- /dev/null +++ b/queue-6.19/efi-fix-reservation-of-unaccepted-memory-table.patch @@ -0,0 +1,62 @@ +From 7e7cd481fb1fc6c6d66eb54d07b5f8044d87b09d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 10:49:56 +0000 +Subject: efi: Fix reservation of unaccepted memory table + +From: Kiryl Shutsemau (Meta) + +[ Upstream commit 0862438c90487e79822d5647f854977d50381505 ] + +The reserve_unaccepted() function incorrectly calculates the size of the +memblock reservation for the unaccepted memory table. It aligns the +size of the table, but fails to account for cases where the table's +starting physical address (efi.unaccepted) is not page-aligned. + +If the table starts at an offset within a page and its end crosses into +a subsequent page that the aligned size does not cover, the end of the +table will not be reserved. This can lead to the table being overwritten +or inaccessible, causing a kernel panic in accept_memory(). + +This issue was observed when starting Intel TDX VMs with specific memory +sizes (e.g., > 64GB). + +Fix this by calculating the end address first (including the unaligned +start) and then aligning it up, ensuring the entire range is covered +by the reservation. + +Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped") +Reported-by: Moritz Sanft +Signed-off-by: Kiryl Shutsemau (Meta) +Reviewed-by: Tom Lendacky +Acked-by: Mike Rapoport (Microsoft) +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/efi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index 17b5f3415465e..92e91c3eb4690 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -692,13 +692,13 @@ static __init int match_config_table(const efi_guid_t *guid, + + static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted) + { +- phys_addr_t start, size; ++ phys_addr_t start, end; + + start = PAGE_ALIGN_DOWN(efi.unaccepted); +- size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size); ++ end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size); + +- memblock_add(start, size); +- memblock_reserve(start, size); ++ memblock_add(start, end - start); ++ memblock_reserve(start, end - start); + } + + int __init efi_config_parse_tables(const efi_config_table_t *config_tables, +-- +2.51.0 + diff --git a/queue-6.19/eth-fbnic-add-validation-for-mtu-changes.patch b/queue-6.19/eth-fbnic-add-validation-for-mtu-changes.patch new file mode 100644 index 0000000000..3ca611fb6b --- /dev/null +++ b/queue-6.19/eth-fbnic-add-validation-for-mtu-changes.patch @@ -0,0 +1,68 @@ +From 68138ad93cf0231fa5031cbd07fbaf374ce692f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 09:19:49 -0800 +Subject: eth: fbnic: Add validation for MTU changes + +From: Dimitri Daskalakis + +[ Upstream commit ccd8e87748ad083047d6c8544c5809b7f96cc8df ] + +Increasing the MTU beyond the HDS threshold causes the hardware to +fragment packets across multiple buffers. If a single-buffer XDP program +is attached, the driver will drop all multi-frag frames. While we can't +prevent a remote sender from sending non-TCP packets larger than the MTU, +this will prevent users from inadvertently breaking new TCP streams. + +Traditionally, drivers supported XDP with MTU less than 4Kb +(packet per page). Fbnic currently prevents attaching XDP when MTU is too high. +But it does not prevent increasing MTU after XDP is attached. + +Fixes: 1b0a3950dbd4 ("eth: fbnic: Add XDP pass, drop, abort support") +Signed-off-by: Jakub Kicinski +Signed-off-by: Dimitri Daskalakis +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +index 81c9d5c9a4b2c..e3ca5fcfabef3 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +@@ -262,6 +262,23 @@ static int fbnic_set_mac(struct net_device *netdev, void *p) + return 0; + } + ++static int fbnic_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ struct fbnic_net *fbn = netdev_priv(dev); ++ ++ if (fbnic_check_split_frames(fbn->xdp_prog, new_mtu, fbn->hds_thresh)) { ++ dev_err(&dev->dev, ++ "MTU %d is larger than HDS threshold %d in XDP mode\n", ++ new_mtu, fbn->hds_thresh); ++ ++ return -EINVAL; ++ } ++ ++ WRITE_ONCE(dev->mtu, new_mtu); ++ ++ return 0; ++} ++ + void fbnic_clear_rx_mode(struct fbnic_dev *fbd) + { + struct net_device *netdev = fbd->netdev; +@@ -533,6 +550,7 @@ static const struct net_device_ops fbnic_netdev_ops = { + .ndo_start_xmit = fbnic_xmit_frame, + .ndo_features_check = fbnic_features_check, + .ndo_set_mac_address = fbnic_set_mac, ++ .ndo_change_mtu = fbnic_change_mtu, + .ndo_set_rx_mode = fbnic_set_rx_mode, + .ndo_get_stats64 = fbnic_get_stats64, + .ndo_bpf = fbnic_bpf, +-- +2.51.0 + diff --git a/queue-6.19/eth-fbnic-advertise-supported-xdp-features.patch b/queue-6.19/eth-fbnic-advertise-supported-xdp-features.patch new file mode 100644 index 0000000000..f4610db84b --- /dev/null +++ b/queue-6.19/eth-fbnic-advertise-supported-xdp-features.patch @@ -0,0 +1,57 @@ +From 31ccee2271d2b89e312df7ab123ac0da811f54b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 19:06:20 -0800 +Subject: eth: fbnic: Advertise supported XDP features. + +From: Dimitri Daskalakis + +[ Upstream commit e977fcb3a318b53b47f23b44ac237fceb1b731fe ] + +Drivers are supposed to advertise the XDP features they support. This was +missed while adding XDP support. + +Before: +$ ynl --family netdev --dump dev-get +... + {'ifindex': 3, + 'xdp-features': set(), + 'xdp-rx-metadata-features': set(), + 'xsk-features': set()}, +... + +After: +$ ynl --family netdev --dump dev-get +... + {'ifindex': 3, + 'xdp-features': {'basic', 'rx-sg'}, + 'xdp-rx-metadata-features': set(), + 'xsk-features': set()}, +... + +Fixes: 168deb7b31b2 ("eth: fbnic: Add support for XDP_TX action") +Signed-off-by: Jakub Kicinski +Signed-off-by: Dimitri Daskalakis +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260218030620.3329608-1-dimitri.daskalakis1@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +index e3ca5fcfabef3..b4b396ca9bce3 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +@@ -805,6 +805,8 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd) + netdev->hw_enc_features |= netdev->features; + netdev->features |= NETIF_F_NTUPLE; + ++ netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_RX_SG; ++ + netdev->min_mtu = IPV6_MIN_MTU; + netdev->max_mtu = FBNIC_MAX_JUMBO_FRAME_SIZE - ETH_HLEN; + +-- +2.51.0 + diff --git a/queue-6.19/eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch b/queue-6.19/eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch new file mode 100644 index 0000000000..a2117aac26 --- /dev/null +++ b/queue-6.19/eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch @@ -0,0 +1,43 @@ +From e47f478f2f54575f3b48e63f40333359c9cea1c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:00:42 -0800 +Subject: eth: fbnic: increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes + +From: Bobby Eshleman + +[ Upstream commit bd254115f38db3c046332bb62e8719e0dc7c2b53 ] + +Increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes. The previous minimum +was too small to guarantee that very long L2+L3+L4 headers always fit +within the header buffer. When EN_HDR_SPLIT is disabled and a packet +exceeds MAX_HEADER_BYTES, splitting occurs at that byte offset instead +of the header boundary, resulting in some of the header landing in the +payload page. The increased minimum ensures headers always fit with the +MAX_HEADER_BYTES cut off and land in the header page. + +Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration") +Signed-off-by: Bobby Eshleman +Acked-by: Mohsin Bashir +Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-2-55d050e6f606@meta.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +index 27776e844e29b..51a98f27d5d91 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +@@ -66,7 +66,7 @@ struct fbnic_net; + (4096 - FBNIC_RX_HROOM - FBNIC_RX_TROOM - FBNIC_RX_PAD) + #define FBNIC_HDS_THRESH_DEFAULT \ + (1536 - FBNIC_RX_PAD) +-#define FBNIC_HDR_BYTES_MIN 128 ++#define FBNIC_HDR_BYTES_MIN 256 + + struct fbnic_pkt_buff { + struct xdp_buff buff; +-- +2.51.0 + diff --git a/queue-6.19/eth-fbnic-set-dma_hint_l4-for-all-flows.patch b/queue-6.19/eth-fbnic-set-dma_hint_l4-for-all-flows.patch new file mode 100644 index 0000000000..4c02c06cf8 --- /dev/null +++ b/queue-6.19/eth-fbnic-set-dma_hint_l4-for-all-flows.patch @@ -0,0 +1,61 @@ +From 372d012fa178fb032fbaf62eb6342ff611a5e9ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:00:43 -0800 +Subject: eth: fbnic: set DMA_HINT_L4 for all flows + +From: Bobby Eshleman + +[ Upstream commit 0f30a31b55c4179fc55613a75ef41d496687d465 ] + +fbnic always advertises ETHTOOL_TCP_DATA_SPLIT_ENABLED via ethtool +.get_ringparam. To enable proper splitting for all flow types, even for +IP/Ethernet flows, this patch sets DMA_HINT_L4 unconditionally for all +RSS and NFC flow steering rules. According to the spec, L4 falls back to +L3 if no valid L4 is found, and L3 falls back to L2 if no L3 is found. +This makes sure that the correct header boundary is used regardless of +traffic type. This is important for zero-copy use cases where we must +ensure that all ZC packets are split correctly. + +Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration") +Signed-off-by: Bobby Eshleman +Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-3-55d050e6f606@meta.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c | 3 +++ + drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 5 ++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +index 693ebdf387055..5edc28ba29553 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +@@ -1142,6 +1142,9 @@ static int fbnic_set_cls_rule_ins(struct fbnic_net *fbn, + return -EINVAL; + } + ++ dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, ++ FBNIC_RCD_HDR_AL_DMA_HINT_L4); ++ + /* Write action table values */ + act_tcam->dest = dest; + act_tcam->rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, hash_idx); +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c +index 7f31e890031c0..42a186db43ea9 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c +@@ -338,9 +338,8 @@ void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn) + else if (tstamp_mask & (1u << flow_type)) + dest |= FBNIC_RPC_ACT_TBL0_TS_ENA; + +- if (act1_value[flow_type] & FBNIC_RPC_TCAM_ACT1_L4_VALID) +- dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, +- FBNIC_RCD_HDR_AL_DMA_HINT_L4); ++ dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, ++ FBNIC_RCD_HDR_AL_DMA_HINT_L4); + + rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, flow_type); + +-- +2.51.0 + diff --git a/queue-6.19/eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch b/queue-6.19/eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch new file mode 100644 index 0000000000..4554a0c018 --- /dev/null +++ b/queue-6.19/eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch @@ -0,0 +1,99 @@ +From 46b5e3c20823fbf13cbc72060553dd6bfe18a0de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:00:41 -0800 +Subject: eth: fbnic: set FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT on RDE_CTL0 + +From: Bobby Eshleman + +[ Upstream commit bbeb3bfbffe0279fa47c041658b037fb38a93965 ] + +Fix EN_HDR_SPLIT configuration by writing the field to RDE_CTL0 instead +of RDE_CTL1. + +Because drop mode configuration and header splitting enablement both use +RDE_CTL0, we consolidate these configurations into the single function +fbnic_config_drop_mode. + +Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration") +Signed-off-by: Bobby Eshleman +Acked-by: Mohsin Bashir +Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-1-55d050e6f606@meta.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 25 +++++++++++--------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +index 13d508ce637f1..e119526fce14c 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +@@ -2575,7 +2575,8 @@ static void fbnic_enable_bdq(struct fbnic_ring *hpq, struct fbnic_ring *ppq) + } + + static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv, +- struct fbnic_ring *rcq, bool tx_pause) ++ struct fbnic_ring *rcq, bool tx_pause, ++ bool hdr_split) + { + struct fbnic_net *fbn = netdev_priv(nv->napi.dev); + u32 drop_mode, rcq_ctl; +@@ -2588,22 +2589,26 @@ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv, + /* Specify packet layout */ + rcq_ctl = FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_DROP_MODE_MASK, drop_mode) | + FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_HROOM_MASK, FBNIC_RX_HROOM) | +- FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM); ++ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM) | ++ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT, hdr_split); + + fbnic_ring_wr32(rcq, FBNIC_QUEUE_RDE_CTL0, rcq_ctl); + } + +-void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause) ++void fbnic_config_drop_mode(struct fbnic_net *fbn, bool txp) + { ++ bool hds; + int i, t; + ++ hds = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN; ++ + for (i = 0; i < fbn->num_napi; i++) { + struct fbnic_napi_vector *nv = fbn->napi[i]; + + for (t = 0; t < nv->rxt_count; t++) { + struct fbnic_q_triad *qt = &nv->qt[nv->txt_count + t]; + +- fbnic_config_drop_mode_rcq(nv, &qt->cmpl, tx_pause); ++ fbnic_config_drop_mode_rcq(nv, &qt->cmpl, txp, hds); + } + } + } +@@ -2654,20 +2659,18 @@ static void fbnic_enable_rcq(struct fbnic_napi_vector *nv, + { + struct fbnic_net *fbn = netdev_priv(nv->napi.dev); + u32 log_size = fls(rcq->size_mask); +- u32 hds_thresh = fbn->hds_thresh; + u32 rcq_ctl = 0; +- +- fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause); ++ bool hdr_split; ++ u32 hds_thresh; + + /* Force lower bound on MAX_HEADER_BYTES. Below this, all frames should + * be split at L4. It would also result in the frames being split at + * L2/L3 depending on the frame size. + */ +- if (fbn->hds_thresh < FBNIC_HDR_BYTES_MIN) { +- rcq_ctl = FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT; +- hds_thresh = FBNIC_HDR_BYTES_MIN; +- } ++ hdr_split = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN; ++ fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause, hdr_split); + ++ hds_thresh = max(fbn->hds_thresh, FBNIC_HDR_BYTES_MIN); + rcq_ctl |= FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PADLEN_MASK, FBNIC_RX_PAD) | + FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_MAX_HDR_MASK, hds_thresh) | + FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PAYLD_OFF_MASK, +-- +2.51.0 + diff --git a/queue-6.19/fbnic-close-fw_log-race-between-users-and-teardown.patch b/queue-6.19/fbnic-close-fw_log-race-between-users-and-teardown.patch new file mode 100644 index 0000000000..221a4a9720 --- /dev/null +++ b/queue-6.19/fbnic-close-fw_log-race-between-users-and-teardown.patch @@ -0,0 +1,124 @@ +From 3ba2d343e2091336cb146a6930917b8fd4a66f97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 19:13:29 +0000 +Subject: fbnic: close fw_log race between users and teardown + +From: Chengfeng Ye + +[ Upstream commit ee5492fd88cfc079c19fbeac78e9e53b7f6c04f3 ] + +Fixes a theoretical race on fw_log between the teardown path and fw_log +write functions. + +fw_log is written inside fbnic_fw_log_write() and can be reached from +the mailbox handler fbnic_fw_msix_intr(), but fw_log is freed before +IRQ/MBX teardown during cleanup, resulting in a potential data race of +dereferencing a freed/null variable. + +Possible Interleaving Scenario: + CPU0: fbnic_fw_msix_intr() // Entry + fbnic_fw_log_write() + if (fbnic_fw_log_ready()) // true + ... preempt ... + CPU1: fbnic_remove() // Entry + fbnic_fw_log_free() + vfree(log->data_start); + log->data_start = NULL; + CPU0: continues, walks log->entries or writes to log->data_start + +The initialization also has an incorrect order problem, as the fw_log +is currently allocated after MBX setup during initialization. +Fix the problems by adjusting the synchronization order to put +initialization in place before the mailbox is enabled, and not cleared +until after the mailbox has been disabled. + +Fixes: ecc53b1b46c89 ("eth: fbnic: Enable firmware logging") +Signed-off-by: Chengfeng Ye +Link: https://patch.msgid.link/20260211191329.530886-1-dg573847474@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/meta/fbnic/fbnic_fw_log.c | 3 --- + drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 19 ++++++++++++------- + 2 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c +index 85a883dba385f..d8a9a7d7c2375 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c +@@ -51,8 +51,6 @@ int fbnic_fw_log_init(struct fbnic_dev *fbd) + log->data_start = data; + log->data_end = data + FBNIC_FW_LOG_SIZE; + +- fbnic_fw_log_enable(fbd, true); +- + return 0; + } + +@@ -63,7 +61,6 @@ void fbnic_fw_log_free(struct fbnic_dev *fbd) + if (!fbnic_fw_log_ready(fbd)) + return; + +- fbnic_fw_log_disable(fbd); + INIT_LIST_HEAD(&log->entries); + log->size = 0; + vfree(log->data_start); +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c +index 9240673c7533d..e92187bc1c0fa 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c +@@ -307,11 +307,17 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + goto free_irqs; + } + ++ err = fbnic_fw_log_init(fbd); ++ if (err) ++ dev_warn(fbd->dev, ++ "Unable to initialize firmware log buffer: %d\n", ++ err); ++ + err = fbnic_fw_request_mbx(fbd); + if (err) { + dev_err(&pdev->dev, + "Firmware mailbox initialization failure\n"); +- goto free_irqs; ++ goto free_fw_log; + } + + /* Send the request to enable the FW logging to host. Note if this +@@ -319,11 +325,7 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * possible the FW is just too old to support the logging and needs + * to be updated. + */ +- err = fbnic_fw_log_init(fbd); +- if (err) +- dev_warn(fbd->dev, +- "Unable to initialize firmware log buffer: %d\n", +- err); ++ fbnic_fw_log_enable(fbd, true); + + fbnic_devlink_register(fbd); + fbnic_devlink_otp_check(fbd, "error detected during probe"); +@@ -370,6 +372,8 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * firmware updates for fixes. + */ + return 0; ++free_fw_log: ++ fbnic_fw_log_free(fbd); + free_irqs: + fbnic_free_irqs(fbd); + err_destroy_health: +@@ -404,8 +408,9 @@ static void fbnic_remove(struct pci_dev *pdev) + fbnic_hwmon_unregister(fbd); + fbnic_dbg_fbd_exit(fbd); + fbnic_devlink_unregister(fbd); +- fbnic_fw_log_free(fbd); ++ fbnic_fw_log_disable(fbd); + fbnic_fw_free_mbx(fbd); ++ fbnic_fw_log_free(fbd); + fbnic_free_irqs(fbd); + + fbnic_devlink_health_destroy(fbd); +-- +2.51.0 + diff --git a/queue-6.19/fs-ntfs3-fix-deadlock-in-ni_read_folio_cmpr.patch b/queue-6.19/fs-ntfs3-fix-deadlock-in-ni_read_folio_cmpr.patch new file mode 100644 index 0000000000..ffdcff092f --- /dev/null +++ b/queue-6.19/fs-ntfs3-fix-deadlock-in-ni_read_folio_cmpr.patch @@ -0,0 +1,72 @@ +From 5a11392d8f69158feb13dd893406b7c72d29a525 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Dec 2025 16:10:10 +0100 +Subject: fs/ntfs3: fix deadlock in ni_read_folio_cmpr + +From: Szymon Wilczek + +[ Upstream commit e37a75bb866c29da954b51d0dd7670406246d9ee ] + +Syzbot reported a task hung in ni_readpage_cmpr (now ni_read_folio_cmpr). +This is caused by a lock inversion deadlock involving the inode mutex +(ni_lock) and page locks. + +Scenario: +1. Task A enters ntfs_read_folio() for page X. It acquires ni_lock. +2. Task A calls ni_read_folio_cmpr(), which attempts to lock all pages in + the compressed frame (including page Y). +3. Concurrently, Task B (e.g., via readahead) has locked page Y and + calls ntfs_read_folio(). +4. Task B waits for ni_lock (held by A). +5. Task A waits for page Y lock (held by B). + -> DEADLOCK. + +The fix is to restructure locking: do not take ni_lock in ntfs_read_folio(). +Instead, acquire ni_lock inside ni_read_folio_cmpr() ONLY AFTER all required +page locks for the frame have been successfully acquired. This restores the +correct lock ordering (Page Lock -> ni_lock) consistent with VFS. + +Reported-by: syzbot+5af33dd272b913b65880@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=5af33dd272b913b65880 +Fixes: f35590ee26f5 ("fs/ntfs3: remove ntfs_bio_pages and use page cache for compressed I/O") +Signed-off-by: Szymon Wilczek +[almaz.alexandrovich@paragon-software.com: ni_readpage_cmpr was renamed to ni_read_folio_cmpr] +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 2 ++ + fs/ntfs3/inode.c | 3 +-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 7e3d61de2f8fa..d5bbd47e1ee9d 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -2107,7 +2107,9 @@ int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio) + pages[i] = pg; + } + ++ ni_lock(ni); + err = ni_read_frame(ni, frame_vbo, pages, pages_per_frame, 0); ++ ni_unlock(ni); + + out1: + for (i = 0; i < pages_per_frame; i++) { +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 1319b99dfeb41..ec8e954f4426c 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -735,9 +735,8 @@ static int ntfs_read_folio(struct file *file, struct folio *folio) + } + + if (is_compressed(ni)) { +- ni_lock(ni); ++ /* ni_lock is taken inside ni_read_folio_cmpr after page locks */ + err = ni_read_folio_cmpr(ni, folio); +- ni_unlock(ni); + return err; + } + +-- +2.51.0 + diff --git a/queue-6.19/fs-ntfs3-fix-ntfs_mount_options-leak-in-ntfs_fill_su.patch b/queue-6.19/fs-ntfs3-fix-ntfs_mount_options-leak-in-ntfs_fill_su.patch new file mode 100644 index 0000000000..51ee1538f1 --- /dev/null +++ b/queue-6.19/fs-ntfs3-fix-ntfs_mount_options-leak-in-ntfs_fill_su.patch @@ -0,0 +1,86 @@ +From e0d10835ab57b076d0031e45de03493c5d2424b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Dec 2025 15:21:41 +0800 +Subject: fs/ntfs3: fix ntfs_mount_options leak in ntfs_fill_super() + +From: Baokun Li + +[ Upstream commit f7edab0cee03a1cbe0e55a7bcab8d2d8b6b74278 ] + +In ntfs_fill_super(), the fc->fs_private pointer is set to NULL without +first freeing the memory it points to. This causes the subsequent call to +ntfs_fs_free() to skip freeing the ntfs_mount_options structure. + +This results in a kmemleak report: + + unreferenced object 0xff1100015378b800 (size 32): + comm "mount", pid 582, jiffies 4294890685 + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00 00 00 00 00 00 00 00 ed ff ed ff 00 04 00 00 ................ + backtrace (crc ed541d8c): + __kmalloc_cache_noprof+0x424/0x5a0 + __ntfs_init_fs_context+0x47/0x590 + alloc_fs_context+0x5d8/0x960 + __x64_sys_fsopen+0xb1/0x190 + do_syscall_64+0x50/0x1f0 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +This issue can be reproduced using the following commands: + fallocate -l 100M test.file + mount test.file /tmp/test + +Since sbi->options is duplicated from fc->fs_private and does not +directly use the memory allocated for fs_private, it is unnecessary to +set fc->fs_private to NULL. + +Additionally, this patch simplifies the code by utilizing the helper +function put_mount_options() instead of open-coding the cleanup logic. + +Reported-by: syzbot+23aee7afc440fe803545@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=23aee7afc440fe803545 +Fixes: aee4d5a521e9 ("ntfs3: fix double free of sbi->options->nls and clarify ownership of fc->fs_private") +Signed-off-by: Baokun Li +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/super.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c +index 8b0cf0ed4f72c..0567a3b224ed3 100644 +--- a/fs/ntfs3/super.c ++++ b/fs/ntfs3/super.c +@@ -705,9 +705,7 @@ static void ntfs_put_super(struct super_block *sb) + ntfs_set_state(sbi, NTFS_DIRTY_CLEAR); + + if (sbi->options) { +- unload_nls(sbi->options->nls); +- kfree(sbi->options->nls_name); +- kfree(sbi->options); ++ put_mount_options(sbi->options); + sbi->options = NULL; + } + +@@ -1253,7 +1251,6 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc) + } + } + sbi->options = options; +- fc->fs_private = NULL; + sb->s_flags |= SB_NODIRATIME; + sb->s_magic = 0x7366746e; // "ntfs" + sb->s_op = &ntfs_sops; +@@ -1679,9 +1676,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc) + out: + /* sbi->options == options */ + if (options) { +- unload_nls(options->nls); +- kfree(options->nls_name); +- kfree(options); ++ put_mount_options(sbi->options); + sbi->options = NULL; + } + +-- +2.51.0 + diff --git a/queue-6.19/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch b/queue-6.19/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch new file mode 100644 index 0000000000..e4b534d7f3 --- /dev/null +++ b/queue-6.19/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch @@ -0,0 +1,51 @@ +From f8f77ec37c07da9b1d64c82337de2c761ea7dade Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jan 2026 16:50:24 +0000 +Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot + +From: Jiasheng Jiang + +[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ] + +In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the +entry size ('esize') is retrieved from the log record without adequate +bounds checking. + +Specifically, the code calculates the end of the entry ('e2') using: + e2 = Add2Ptr(e1, esize); + +It then calculates the size for memmove using 'PtrOffset(e2, ...)', +which subtracts the end pointer from the buffer limit. If 'esize' is +maliciously large, 'e2' exceeds the used buffer size. This results in +a negative offset which, when cast to size_t for memmove, interprets +as a massive unsigned integer, leading to a heap buffer overflow. + +This commit adds a check to ensure that the entry size ('esize') strictly +fits within the remaining used space of the index header before performing +memory operations. + +Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fslog.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c +index 38934e6978ece..28bd611f580d9 100644 +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3429,6 +3429,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, + + e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off)); + esize = le16_to_cpu(e1->size); ++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize) ++ goto dirty_vol; ++ + e2 = Add2Ptr(e1, esize); + + memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used))); +-- +2.51.0 + diff --git a/queue-6.19/fs-ntfs3-initialize-new-folios-before-use.patch b/queue-6.19/fs-ntfs3-initialize-new-folios-before-use.patch new file mode 100644 index 0000000000..a818c6b34d --- /dev/null +++ b/queue-6.19/fs-ntfs3-initialize-new-folios-before-use.patch @@ -0,0 +1,43 @@ +From 814af6655a618a54c7567f9de7e1263a58c5de66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 23:02:51 +0100 +Subject: fs/ntfs3: Initialize new folios before use + +From: Bartlomiej Kubik + +[ Upstream commit f223ebffa185cc8da934333c5a31ff2d4f992dc9 ] + +KMSAN reports an uninitialized value in longest_match_std(), invoked +from ntfs_compress_write(). When new folios are allocated without being +marked uptodate and ni_read_frame() is skipped because the caller expects +the frame to be completely overwritten, some reserved folios may remain +only partially filled, leaving the rest memory uninitialized. + +Fixes: 584f60ba22f7 ("ntfs3: Convert ntfs_get_frame_pages() to use a folio") +Tested-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com +Reported-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=08d8956768c96a2c52cf + +Signed-off-by: Bartlomiej Kubik +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index 2e7b2e566ebe1..732260087066d 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -995,7 +995,7 @@ static int ntfs_get_frame_pages(struct address_space *mapping, pgoff_t index, + + folio = __filemap_get_folio(mapping, index, + FGP_LOCK | FGP_ACCESSED | FGP_CREAT, +- gfp_mask); ++ gfp_mask | __GFP_ZERO); + if (IS_ERR(folio)) { + while (npages--) { + folio = page_folio(pages[npages]); +-- +2.51.0 + diff --git a/queue-6.19/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch b/queue-6.19/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch new file mode 100644 index 0000000000..41ff8099fd --- /dev/null +++ b/queue-6.19/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch @@ -0,0 +1,58 @@ +From 7f8958188bcccef6bc46ad6fb34a2c5ab3dc2aae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Dec 2025 11:53:25 +0800 +Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the + same + +From: Edward Adam Davis + +[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ] + +When processing valid within the range [valid : pos), if valid cannot +be retrieved correctly, for example, if the retrieved valid value is +always the same, this can trigger a potential infinite loop, similar +to the hung problem reported by syzbot [1]. + +Adding a check for the valid value within the loop body, and terminating +the loop and returning -EINVAL if the value is the same as the current +value, can prevent this. + +[1] +INFO: task syz.4.21:6056 blocked for more than 143 seconds. +Call Trace: + rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244 + inode_lock include/linux/fs.h:1027 [inline] + ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1 +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index 732260087066d..5120bd7851694 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -1077,8 +1077,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) + goto out; + + if (lcn == SPARSE_LCN) { +- ni->i_valid = valid = +- frame_vbo + ((u64)clen << sbi->cluster_bits); ++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits); ++ if (ni->i_valid == valid) { ++ err = -EINVAL; ++ goto out; ++ } ++ ni->i_valid = valid; + continue; + } + +-- +2.51.0 + diff --git a/queue-6.19/fs-ntfs3-rename-ni_readpage_cmpr-into-ni_read_folio_.patch b/queue-6.19/fs-ntfs3-rename-ni_readpage_cmpr-into-ni_read_folio_.patch new file mode 100644 index 0000000000..9760be6bcd --- /dev/null +++ b/queue-6.19/fs-ntfs3-rename-ni_readpage_cmpr-into-ni_read_folio_.patch @@ -0,0 +1,80 @@ +From 407f842cf9f5c24fe054bc010e3957a21276ac27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Dec 2025 22:57:46 +0300 +Subject: fs/ntfs3: rename ni_readpage_cmpr into ni_read_folio_cmpr + +From: Konstantin Komarov + +[ Upstream commit 4248f563f0b76f3fb74b2a28ee068bf66fcbbedf ] + +The old "readpage" naming is still used in ni_readpage_cmpr(), even though +the vfs has transitioned to the folio-based read_folio() API. + +This patch performs a straightforward renaming of the helper: +ni_readpage_cmpr() -> ni_read_folio_cmpr(). + +Signed-off-by: Konstantin Komarov +Stable-dep-of: e37a75bb866c ("fs/ntfs3: fix deadlock in ni_read_folio_cmpr") +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 8 ++++---- + fs/ntfs3/inode.c | 2 +- + fs/ntfs3/ntfs_fs.h | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 641ddaf8d4a07..7e3d61de2f8fa 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -2046,18 +2046,18 @@ static struct page *ntfs_lock_new_page(struct address_space *mapping, + } + + /* +- * ni_readpage_cmpr ++ * ni_read_folio_cmpr + * + * When decompressing, we typically obtain more than one page per reference. + * We inject the additional pages into the page cache. + */ +-int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio) ++int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio) + { + int err; + struct ntfs_sb_info *sbi = ni->mi.sbi; + struct address_space *mapping = folio->mapping; +- pgoff_t index = folio->index; +- u64 frame_vbo, vbo = (u64)index << PAGE_SHIFT; ++ pgoff_t index; ++ u64 frame_vbo, vbo = folio_pos(folio); + struct page **pages = NULL; /* Array of at most 16 pages. stack? */ + u8 frame_bits; + CLST frame; +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 0a9ac5efeb67c..1319b99dfeb41 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -736,7 +736,7 @@ static int ntfs_read_folio(struct file *file, struct folio *folio) + + if (is_compressed(ni)) { + ni_lock(ni); +- err = ni_readpage_cmpr(ni, folio); ++ err = ni_read_folio_cmpr(ni, folio); + ni_unlock(ni); + return err; + } +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index a4559c9f64e68..7b619bb151ce9 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -568,7 +568,7 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint); + #define _ni_write_inode(i, w) ni_write_inode(i, w, __func__) + int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + __u64 vbo, __u64 len); +-int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio); ++int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio); + int ni_decompress_file(struct ntfs_inode *ni); + int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages, + u32 pages_per_frame, int copy); +-- +2.51.0 + diff --git a/queue-6.19/gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch b/queue-6.19/gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch new file mode 100644 index 0000000000..08d5f69642 --- /dev/null +++ b/queue-6.19/gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch @@ -0,0 +1,58 @@ +From 94e7c37b7cd3c1886f06c4df96147b48645ee0de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 14:11:49 -0800 +Subject: gpio: amd-fch: ionly return allowed values from amd_fch_gpio_get() + +From: Dmitry Torokhov + +[ Upstream commit fbd03587ba732c612b8a569d1cf5bed72bd3a27c ] + +As of 86ef402d805d ("gpiolib: sanitize the return value of +gpio_chip::get()") gpiolib requires drivers implementing GPIOs to only +return 0, 1 or negative error for the get() callbacks. Ensure that +amd-fch complies with this requirement. + +Fixes: 86ef402d805d ("gpiolib: sanitize the return value of gpio_chip::get()") +Reported-and-tested-by: Tj +Signed-off-by: Dmitry Torokhov +Link: https://patch.msgid.link/aZTlwnvHt2Gho4yN@google.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-amd-fch.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpio/gpio-amd-fch.c b/drivers/gpio/gpio-amd-fch.c +index e6c6c3ec7656e..9f329938202bf 100644 +--- a/drivers/gpio/gpio-amd-fch.c ++++ b/drivers/gpio/gpio-amd-fch.c +@@ -8,6 +8,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -120,15 +121,15 @@ static int amd_fch_gpio_get(struct gpio_chip *gc, + unsigned int offset) + { + unsigned long flags; +- int ret; ++ u32 val; + struct amd_fch_gpio_priv *priv = gpiochip_get_data(gc); + void __iomem *ptr = amd_fch_gpio_addr(priv, offset); + + spin_lock_irqsave(&priv->lock, flags); +- ret = (readl_relaxed(ptr) & AMD_FCH_GPIO_FLAG_READ); ++ val = readl_relaxed(ptr); + spin_unlock_irqrestore(&priv->lock, flags); + +- return ret; ++ return FIELD_GET(AMD_FCH_GPIO_FLAG_READ, val); + } + + static int amd_fch_gpio_request(struct gpio_chip *chip, +-- +2.51.0 + diff --git a/queue-6.19/gpio-cdev-avoid-null-dereference-in-linehandle_creat.patch b/queue-6.19/gpio-cdev-avoid-null-dereference-in-linehandle_creat.patch new file mode 100644 index 0000000000..2f50773cca --- /dev/null +++ b/queue-6.19/gpio-cdev-avoid-null-dereference-in-linehandle_creat.patch @@ -0,0 +1,42 @@ +From 08ef006907255e2a072c0fc2ab28ac6fdf9ee911 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Feb 2026 12:05:55 -0800 +Subject: gpio: cdev: Avoid NULL dereference in linehandle_create() + +From: Douglas Anderson + +[ Upstream commit 6af6be278e3ba2ffb6af5b796c89dfb3f5d9063e ] + +In linehandle_create(), there is a statement like this: + retain_and_null_ptr(lh); + +Soon after, there is a debug printout that dereferences "lh", which +will crash things. + +Avoid the crash by using handlereq.lines, which is the same value. + +Fixes: da7e394bf58f ("gpio: convert linehandle_create() to FD_PREPARE()") +Signed-off-by: Douglas Anderson +Link: https://patch.msgid.link/20260215120555.v2.1.I77c3eb563271c21870379eefd16ebbc4e09635bb@changeid +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib-cdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c +index 2adc3c0709082..189127721e383 100644 +--- a/drivers/gpio/gpiolib-cdev.c ++++ b/drivers/gpio/gpiolib-cdev.c +@@ -388,7 +388,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) + fd_publish(fdf); + + dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", +- lh->num_descs); ++ handlereq.lines); + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.19/icmp-prevent-possible-overflow-in-icmp_global_allow.patch b/queue-6.19/icmp-prevent-possible-overflow-in-icmp_global_allow.patch new file mode 100644 index 0000000000..a13aa2a5af --- /dev/null +++ b/queue-6.19/icmp-prevent-possible-overflow-in-icmp_global_allow.patch @@ -0,0 +1,41 @@ +From 801b4d9ad5761d229cbccf162639b5294705458b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:28 +0000 +Subject: icmp: prevent possible overflow in icmp_global_allow() + +From: Eric Dumazet + +[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ] + +Following expression can overflow +if sysctl_icmp_msgs_per_sec is big enough. + +sysctl_icmp_msgs_per_sec * delta / HZ; + +Fixes: 4cdf507d5452 ("icmp: add a global rate limitation") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/icmp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index a2cff16668d72..471dd862f6639 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -248,7 +248,8 @@ bool icmp_global_allow(struct net *net) + if (delta < HZ / 50) + return false; + +- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; ++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec); ++ incr = div_u64((u64)incr * delta, HZ); + if (!incr) + return false; + +-- +2.51.0 + diff --git a/queue-6.19/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch b/queue-6.19/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch new file mode 100644 index 0000000000..128a23a511 --- /dev/null +++ b/queue-6.19/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch @@ -0,0 +1,57 @@ +From 48835273717464aed4e66f52d263c9b3d5d3fc21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:29 +0000 +Subject: inet: move icmp_global_{credit,stamp} to a separate cache line + +From: Eric Dumazet + +[ Upstream commit 87b08913a9ae82082e276d237ece08fc8ee24380 ] + +icmp_global_credit was meant to be changed ~1000 times per second, +but if an admin sets net.ipv4.icmp_msgs_per_sec to a very high value, +icmp_global_credit changes can inflict false sharing to surrounding +fields that are read mostly. + +Move icmp_global_credit and icmp_global_stamp to a separate +cacheline aligned group. + +Fixes: b056b4cd9178 ("icmp: move icmp_global.credit and icmp_global.stamp to per netns storage") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/netns/ipv4.h | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 2dbd46fc4734b..8e971c7bf1646 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -88,6 +88,12 @@ struct netns_ipv4 { + int sysctl_tcp_rcvbuf_low_rtt; + __cacheline_group_end(netns_ipv4_read_rx); + ++ /* ICMP rate limiter hot cache line. */ ++ __cacheline_group_begin_aligned(icmp); ++ atomic_t icmp_global_credit; ++ u32 icmp_global_stamp; ++ __cacheline_group_end_aligned(icmp); ++ + struct inet_timewait_death_row tcp_death_row; + struct udp_table *udp_table; + +@@ -141,8 +147,7 @@ struct netns_ipv4 { + int sysctl_icmp_ratemask; + int sysctl_icmp_msgs_per_sec; + int sysctl_icmp_msgs_burst; +- atomic_t icmp_global_credit; +- u32 icmp_global_stamp; ++ + u32 ip_rt_min_pmtu; + int ip_rt_mtu_expires; + int ip_rt_min_advmss; +-- +2.51.0 + diff --git a/queue-6.19/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch b/queue-6.19/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch new file mode 100644 index 0000000000..cfab75743d --- /dev/null +++ b/queue-6.19/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch @@ -0,0 +1,53 @@ +From ae6029d2a55a080518b8392d5f74117e2039e7fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:22:02 +0000 +Subject: ipv6: fix a race in ip6_sock_set_v6only() + +From: Eric Dumazet + +[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ] + +It is unlikely that this function will be ever called +with isk->inet_num being not zero. + +Perform the check on isk->inet_num inside the locked section +for complete safety. + +Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Fernando Fernandez Mancera +Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/ipv6.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 74fbf1ad8065a..6a933690e0ff5 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -1280,12 +1280,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, + + static inline int ip6_sock_set_v6only(struct sock *sk) + { +- if (inet_sk(sk)->inet_num) +- return -EINVAL; ++ int ret = 0; ++ + lock_sock(sk); +- sk->sk_ipv6only = true; ++ if (inet_sk(sk)->inet_num) ++ ret = -EINVAL; ++ else ++ sk->sk_ipv6only = true; + release_sock(sk); +- return 0; ++ return ret; + } + + static inline void ip6_sock_set_recverr(struct sock *sk) +-- +2.51.0 + diff --git a/queue-6.19/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch b/queue-6.19/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch new file mode 100644 index 0000000000..dd58af4af6 --- /dev/null +++ b/queue-6.19/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch @@ -0,0 +1,125 @@ +From 02042b9abe3538355cbceb89e0000ec10214a476 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:50:21 +0000 +Subject: ipv6: Fix out-of-bound access in fib6_add_rt2node(). + +From: Kuniyuki Iwashima + +[ Upstream commit 8244f959e2c125c849e569f5b23ed49804cce695 ] + +syzbot reported out-of-bound read in fib6_add_rt2node(). [0] + +When IPv6 route is created with RTA_NH_ID, struct fib6_info +does not have the trailing struct fib6_nh. + +The cited commit started to check !iter->fib6_nh->fib_nh_gw_family +to ensure that rt6_qualify_for_ecmp() will return false for iter. + +If iter->nh is not NULL, rt6_qualify_for_ecmp() returns false anyway. + +Let's check iter->nh before reading iter->fib6_nh and avoid OOB read. + +[0]: +BUG: KASAN: slab-out-of-bounds in fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142 +Read of size 1 at addr ffff8880384ba6de by task syz.0.18/5500 + +CPU: 0 UID: 0 PID: 5500 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full) +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +Call Trace: + + dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:378 [inline] + print_report+0xba/0x230 mm/kasan/report.c:482 + kasan_report+0x117/0x150 mm/kasan/report.c:595 + fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142 + fib6_add_rt2node_nh net/ipv6/ip6_fib.c:1363 [inline] + fib6_add+0x910/0x18c0 net/ipv6/ip6_fib.c:1531 + __ip6_ins_rt net/ipv6/route.c:1351 [inline] + ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3957 + inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660 + rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f9316b9aeb9 +Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007ffd8809b678 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00007f9316e15fa0 RCX: 00007f9316b9aeb9 +RDX: 0000000000000000 RSI: 0000200000004380 RDI: 0000000000000003 +RBP: 00007f9316c08c1f R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007f9316e15fac R14: 00007f9316e15fa0 R15: 00007f9316e15fa0 + + +Allocated by task 5499: + kasan_save_stack mm/kasan/common.c:57 [inline] + kasan_save_track+0x3e/0x80 mm/kasan/common.c:78 + poison_kmalloc_redzone mm/kasan/common.c:398 [inline] + __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415 + kasan_kmalloc include/linux/kasan.h:263 [inline] + __do_kmalloc_node mm/slub.c:5657 [inline] + __kmalloc_noprof+0x40c/0x7e0 mm/slub.c:5669 + kmalloc_noprof include/linux/slab.h:961 [inline] + kzalloc_noprof include/linux/slab.h:1094 [inline] + fib6_info_alloc+0x30/0xf0 net/ipv6/ip6_fib.c:155 + ip6_route_info_create+0x142/0x860 net/ipv6/route.c:3820 + ip6_route_add+0x49/0x1b0 net/ipv6/route.c:3949 + inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660 + rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Fixes: bbf4a17ad9ff ("ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF") +Reported-by: syzbot+707d6a5da1ab9e0c6f9d@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/698cbfba.050a0220.2eeac1.009d.GAE@google.com/ +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Fernando Fernandez Mancera +Reviewed-by: Shigeru Yoshida +Link: https://patch.msgid.link/20260211175133.3657034-1-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index c6439e30e892a..cc149227b49f4 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1139,7 +1139,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_add_gc_list(iter); + } + if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) && +- !iter->fib6_nh->fib_nh_gw_family) { ++ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) { + iter->fib6_flags &= ~RTF_ADDRCONF; + iter->fib6_flags &= ~RTF_PREFIX_RT; + } +-- +2.51.0 + diff --git a/queue-6.19/ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch b/queue-6.19/ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch new file mode 100644 index 0000000000..ebfcdcbbaf --- /dev/null +++ b/queue-6.19/ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch @@ -0,0 +1,95 @@ +From 3fb24ec4dccf88d6253ef67c610551ddd992c6b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:30 +0000 +Subject: ipv6: icmp: remove obsolete code in icmpv6_xrlim_allow() + +From: Eric Dumazet + +[ Upstream commit 0201eedb69b24a6be9b7c1716287a89c4dde2320 ] + +Following part was needed before the blamed commit, because +inet_getpeer_v6() second argument was the prefix. + + /* Give more bandwidth to wider prefixes. */ + if (rt->rt6i_dst.plen < 128) + tmo >>= ((128 - rt->rt6i_dst.plen)>>5); + +Now inet_getpeer_v6() retrieves hosts, we need to remove +@tmo adjustement or wider prefixes likes /24 allow 8x +more ICMP to be sent for a given ratelimit. + +As we had this issue for a while, this patch changes net.ipv6.icmp.ratelimit +default value from 1000ms to 100ms to avoid potential regressions. + +Also add a READ_ONCE() when reading net->ipv6.sysctl.icmpv6_time. + +Fixes: fd0273d7939f ("ipv6: Remove external dependency on rt6i_dst and rt6i_src") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Cc: Martin KaFai Lau +Link: https://patch.msgid.link/20260216142832.3834174-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + Documentation/networking/ip-sysctl.rst | 7 ++++--- + net/ipv6/af_inet6.c | 2 +- + net/ipv6/icmp.c | 7 +------ + 3 files changed, 6 insertions(+), 10 deletions(-) + +diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst +index bc9a01606daf5..2c65d57103fb1 100644 +--- a/Documentation/networking/ip-sysctl.rst ++++ b/Documentation/networking/ip-sysctl.rst +@@ -3232,12 +3232,13 @@ enhanced_dad - BOOLEAN + =========== + + ratelimit - INTEGER +- Limit the maximal rates for sending ICMPv6 messages. ++ Limit the maximal rates for sending ICMPv6 messages to a particular ++ peer. + + 0 to disable any limiting, +- otherwise the minimal space between responses in milliseconds. ++ otherwise the space between responses in milliseconds. + +- Default: 1000 ++ Default: 100 + + ratemask - list of comma separated ranges + For ICMPv6 message types matching the ranges in the ratemask, limit +diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c +index b705751eb73c6..d3534bdb805da 100644 +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -955,7 +955,7 @@ static int __net_init inet6_net_init(struct net *net) + int err = 0; + + net->ipv6.sysctl.bindv6only = 0; +- net->ipv6.sysctl.icmpv6_time = 1*HZ; ++ net->ipv6.sysctl.icmpv6_time = HZ / 10; + net->ipv6.sysctl.icmpv6_echo_ignore_all = 0; + net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0; + net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0; +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index a77f3113ef23b..55b1aa75ab802 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -217,14 +217,9 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type, + } else if (dev && (dev->flags & IFF_LOOPBACK)) { + res = true; + } else { +- struct rt6_info *rt = dst_rt6_info(dst); +- int tmo = net->ipv6.sysctl.icmpv6_time; ++ int tmo = READ_ONCE(net->ipv6.sysctl.icmpv6_time); + struct inet_peer *peer; + +- /* Give more bandwidth to wider prefixes. */ +- if (rt->rt6i_dst.plen < 128) +- tmo >>= ((128 - rt->rt6i_dst.plen)>>5); +- + peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr); + res = inet_peer_xrlim_allow(peer, tmo); + } +-- +2.51.0 + diff --git a/queue-6.19/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch b/queue-6.19/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch new file mode 100644 index 0000000000..42dcf17495 --- /dev/null +++ b/queue-6.19/ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch @@ -0,0 +1,129 @@ +From 9e6303b7a931eb6f039347083b09de673b256d9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 16:58:50 +0200 +Subject: ipvs: do not keep dest_dst if dev is going down + +From: Julian Anastasov + +[ Upstream commit 8fde939b0206afc1d5846217a01a16b9bc8c7896 ] + +There is race between the netdev notifier ip_vs_dst_event() +and the code that caches dst with dev that is going down. +As the FIB can be notified for the closed device after our +handler finishes, it is possible valid route to be returned +and cached resuling in a leaked dev reference until the dest +is not removed. + +To prevent new dest_dst to be attached to dest just after the +handler dropped the old one, add a netif_running() check +to make sure the notifier handler is not currently running +for device that is closing. + +Fixes: 7a4f0761fce3 ("IPVS: init and cleanup restructuring") +Signed-off-by: Julian Anastasov +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_xmit.c | 46 ++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 10 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c +index 64c697212578a..124f779424b0f 100644 +--- a/net/netfilter/ipvs/ip_vs_xmit.c ++++ b/net/netfilter/ipvs/ip_vs_xmit.c +@@ -294,6 +294,12 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs, + return true; + } + ++/* rt has device that is down */ ++static bool rt_dev_is_down(const struct net_device *dev) ++{ ++ return dev && !netif_running(dev); ++} ++ + /* Get route to destination or remote server */ + static int + __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, +@@ -309,9 +315,11 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + + if (dest) { + dest_dst = __ip_vs_dst_check(dest); +- if (likely(dest_dst)) ++ if (likely(dest_dst)) { + rt = dst_rtable(dest_dst->dst_cache); +- else { ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.ip; ++ } else { + dest_dst = ip_vs_dest_dst_alloc(); + spin_lock_bh(&dest->dst_lock); + if (!dest_dst) { +@@ -327,14 +335,22 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + ip_vs_dest_dst_free(dest_dst); + goto err_unreach; + } +- __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0); ++ /* It is forbidden to attach dest->dest_dst if ++ * device is going down. ++ */ ++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst))) ++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0); ++ else ++ noref = 0; + spin_unlock_bh(&dest->dst_lock); + IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d\n", + &dest->addr.ip, &dest_dst->dst_saddr.ip, + rcuref_read(&rt->dst.__rcuref)); ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.ip; ++ if (!noref) ++ ip_vs_dest_dst_free(dest_dst); + } +- if (ret_saddr) +- *ret_saddr = dest_dst->dst_saddr.ip; + } else { + noref = 0; + +@@ -471,9 +487,11 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + + if (dest) { + dest_dst = __ip_vs_dst_check(dest); +- if (likely(dest_dst)) ++ if (likely(dest_dst)) { + rt = dst_rt6_info(dest_dst->dst_cache); +- else { ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.in6; ++ } else { + u32 cookie; + + dest_dst = ip_vs_dest_dst_alloc(); +@@ -494,14 +512,22 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, + } + rt = dst_rt6_info(dst); + cookie = rt6_get_cookie(rt); +- __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie); ++ /* It is forbidden to attach dest->dest_dst if ++ * device is going down. ++ */ ++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst))) ++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie); ++ else ++ noref = 0; + spin_unlock_bh(&dest->dst_lock); + IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n", + &dest->addr.in6, &dest_dst->dst_saddr.in6, + rcuref_read(&rt->dst.__rcuref)); ++ if (ret_saddr) ++ *ret_saddr = dest_dst->dst_saddr.in6; ++ if (!noref) ++ ip_vs_dest_dst_free(dest_dst); + } +- if (ret_saddr) +- *ret_saddr = dest_dst->dst_saddr.in6; + } else { + noref = 0; + dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm, +-- +2.51.0 + diff --git a/queue-6.19/ipvs-skip-ipv6-extension-headers-for-csum-checks.patch b/queue-6.19/ipvs-skip-ipv6-extension-headers-for-csum-checks.patch new file mode 100644 index 0000000000..b9ce65a69c --- /dev/null +++ b/queue-6.19/ipvs-skip-ipv6-extension-headers-for-csum-checks.patch @@ -0,0 +1,203 @@ +From 9a2373589647bda5b67d7e6f554c35be23b29490 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Feb 2026 16:58:49 +0200 +Subject: ipvs: skip ipv6 extension headers for csum checks + +From: Julian Anastasov + +[ Upstream commit 05cfe9863ef049d98141dc2969eefde72fb07625 ] + +Protocol checksum validation fails for IPv6 if there are extension +headers before the protocol header. iph->len already contains its +offset, so use it to fix the problem. + +Fixes: 2906f66a5682 ("ipvs: SCTP Trasport Loadbalancing Support") +Fixes: 0bbdd42b7efa ("IPVS: Extend protocol DNAT/SNAT and state handlers") +Signed-off-by: Julian Anastasov +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_proto_sctp.c | 18 ++++++------------ + net/netfilter/ipvs/ip_vs_proto_tcp.c | 21 +++++++-------------- + net/netfilter/ipvs/ip_vs_proto_udp.c | 20 +++++++------------- + 3 files changed, 20 insertions(+), 39 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c +index 83e452916403d..63c78a1f3918a 100644 +--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c ++++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c +@@ -10,7 +10,8 @@ + #include + + static int +-sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); ++sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int sctphoff); + + static int + sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, +@@ -108,7 +109,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + int ret; + + /* Some checks before mangling */ +- if (!sctp_csum_check(cp->af, skb, pp)) ++ if (!sctp_csum_check(cp->af, skb, pp, sctphoff)) + return 0; + + /* Call application helper if needed */ +@@ -156,7 +157,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + int ret; + + /* Some checks before mangling */ +- if (!sctp_csum_check(cp->af, skb, pp)) ++ if (!sctp_csum_check(cp->af, skb, pp, sctphoff)) + return 0; + + /* Call application helper if needed */ +@@ -185,19 +186,12 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + } + + static int +-sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) ++sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int sctphoff) + { +- unsigned int sctphoff; + struct sctphdr *sh; + __le32 cmp, val; + +-#ifdef CONFIG_IP_VS_IPV6 +- if (af == AF_INET6) +- sctphoff = sizeof(struct ipv6hdr); +- else +-#endif +- sctphoff = ip_hdrlen(skb); +- + sh = (struct sctphdr *)(skb->data + sctphoff); + cmp = sh->checksum; + val = sctp_compute_cksum(skb, sctphoff); +diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c +index f68a1533ee455..8cc0a8ce62411 100644 +--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c ++++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c +@@ -28,7 +28,8 @@ + #include + + static int +-tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); ++tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int tcphoff); + + static int + tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, +@@ -165,7 +166,7 @@ tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + int ret; + + /* Some checks before mangling */ +- if (!tcp_csum_check(cp->af, skb, pp)) ++ if (!tcp_csum_check(cp->af, skb, pp, tcphoff)) + return 0; + + /* Call application helper if needed */ +@@ -243,7 +244,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + int ret; + + /* Some checks before mangling */ +- if (!tcp_csum_check(cp->af, skb, pp)) ++ if (!tcp_csum_check(cp->af, skb, pp, tcphoff)) + return 0; + + /* +@@ -300,17 +301,9 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + + + static int +-tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) ++tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int tcphoff) + { +- unsigned int tcphoff; +- +-#ifdef CONFIG_IP_VS_IPV6 +- if (af == AF_INET6) +- tcphoff = sizeof(struct ipv6hdr); +- else +-#endif +- tcphoff = ip_hdrlen(skb); +- + switch (skb->ip_summed) { + case CHECKSUM_NONE: + skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0); +@@ -321,7 +314,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) + if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + skb->len - tcphoff, +- ipv6_hdr(skb)->nexthdr, ++ IPPROTO_TCP, + skb->csum)) { + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, + "Failed checksum for"); +diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c +index 0f0107c80dd23..f9de632e38cdd 100644 +--- a/net/netfilter/ipvs/ip_vs_proto_udp.c ++++ b/net/netfilter/ipvs/ip_vs_proto_udp.c +@@ -24,7 +24,8 @@ + #include + + static int +-udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); ++udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int udphoff); + + static int + udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, +@@ -154,7 +155,7 @@ udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + int ret; + + /* Some checks before mangling */ +- if (!udp_csum_check(cp->af, skb, pp)) ++ if (!udp_csum_check(cp->af, skb, pp, udphoff)) + return 0; + + /* +@@ -237,7 +238,7 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + int ret; + + /* Some checks before mangling */ +- if (!udp_csum_check(cp->af, skb, pp)) ++ if (!udp_csum_check(cp->af, skb, pp, udphoff)) + return 0; + + /* +@@ -296,17 +297,10 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + + + static int +-udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) ++udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int udphoff) + { + struct udphdr _udph, *uh; +- unsigned int udphoff; +- +-#ifdef CONFIG_IP_VS_IPV6 +- if (af == AF_INET6) +- udphoff = sizeof(struct ipv6hdr); +- else +-#endif +- udphoff = ip_hdrlen(skb); + + uh = skb_header_pointer(skb, udphoff, sizeof(_udph), &_udph); + if (uh == NULL) +@@ -324,7 +318,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) + if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + skb->len - udphoff, +- ipv6_hdr(skb)->nexthdr, ++ IPPROTO_UDP, + skb->csum)) { + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, + "Failed checksum for"); +-- +2.51.0 + diff --git a/queue-6.19/kbuild-add-objtool-to-top-level-clean-target.patch b/queue-6.19/kbuild-add-objtool-to-top-level-clean-target.patch new file mode 100644 index 0000000000..e4816fc9c8 --- /dev/null +++ b/queue-6.19/kbuild-add-objtool-to-top-level-clean-target.patch @@ -0,0 +1,71 @@ +From 4c975cb278a0922e6bcf4e2f3c26d1c11748769b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 13:45:22 -0800 +Subject: kbuild: Add objtool to top-level clean target + +From: Josh Poimboeuf + +[ Upstream commit 68b4fe32d73789dea23e356f468de67c8367ef8f ] + +Objtool is an integral part of the build, make sure it gets cleaned by +"make clean" and "make mrproper". + +Fixes: 442f04c34a1a ("objtool: Add tool to perform compile-time stack metadata validation") +Reported-by: Jens Remus +Closes: https://lore.kernel.org/15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com +Signed-off-by: Josh Poimboeuf +Tested-by: Jens Remus +Link: https://patch.msgid.link/968faf2ed30fa8b3519f79f01a1ecfe7929553e5.1770759919.git.jpoimboe@kernel.org +[nathan: use Closes: instead of Link: per checkpatch.pl] +Signed-off-by: Nathan Chancellor +Signed-off-by: Sasha Levin +--- + Makefile | 11 ++++++++++- + tools/objtool/Makefile | 2 ++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 21df635071198..7e34042743d9e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1474,6 +1474,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),) + $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean + endif + ++PHONY += objtool_clean ++ ++objtool_O = $(abspath $(objtree))/tools/objtool ++ ++objtool_clean: ++ifneq ($(wildcard $(objtool_O)),) ++ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean ++endif ++ + tools/: FORCE + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ +@@ -1637,7 +1646,7 @@ vmlinuxclean: + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean + $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean) + +-clean: archclean vmlinuxclean resolve_btfids_clean ++clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean + + # mrproper - Delete all generated files, including .config + # +diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile +index a40f302329291..6964175abdfdf 100644 +--- a/tools/objtool/Makefile ++++ b/tools/objtool/Makefile +@@ -29,6 +29,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR))) + srctree := $(patsubst %/,%,$(dir $(srctree))) + endif + ++RM ?= rm -f ++ + LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ + ifneq ($(OUTPUT),) + LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd +-- +2.51.0 + diff --git a/queue-6.19/libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch b/queue-6.19/libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch new file mode 100644 index 0000000000..2b58684639 --- /dev/null +++ b/queue-6.19/libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch @@ -0,0 +1,43 @@ +From e0c698a0a0d0f75696e5624610f9dfc7ad5b589a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 15:01:34 -0800 +Subject: libbpf: Fix invalid write loop logic in bpf_linker__add_buf() + +From: Amery Hung + +[ Upstream commit 04999b99e81eaa7b6223ec1c03af3bcb4ac57aaa ] + +Fix bpf_linker__add_buf()'s logic of copying data from memory buffer into +memfd. In the event of short write not writing entire buf_sz bytes into memfd +file, we'll append bytes from the beginning of buf *again* (corrupting ELF +file contents) instead of correctly appending the rest of not-yet-read buf +contents. + +Closes: https://github.com/libbpf/libbpf/issues/945 +Fixes: 6d5e5e5d7ce1 ("libbpf: Extend linker API to support in-memory ELF files") +Signed-off-by: Amery Hung +Signed-off-by: Andrii Nakryiko +Acked-by: Jiri Olsa +Link: https://lore.kernel.org/bpf/20260209230134.3530521-1-ameryhung@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/linker.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c +index f4403e3cf9946..78f92c39290af 100644 +--- a/tools/lib/bpf/linker.c ++++ b/tools/lib/bpf/linker.c +@@ -581,7 +581,7 @@ int bpf_linker__add_buf(struct bpf_linker *linker, void *buf, size_t buf_sz, + + written = 0; + while (written < buf_sz) { +- ret = write(fd, buf, buf_sz); ++ ret = write(fd, buf + written, buf_sz - written); + if (ret < 0) { + ret = -errno; + pr_warn("failed to write '%s': %s\n", filename, errstr(ret)); +-- +2.51.0 + diff --git a/queue-6.19/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch b/queue-6.19/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch new file mode 100644 index 0000000000..4e368b1bb8 --- /dev/null +++ b/queue-6.19/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch @@ -0,0 +1,116 @@ +From 849581d7f5a79a15193cdcdfde73e029b850d59a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:25:57 +0000 +Subject: macvlan: observe an RCU grace period in macvlan_common_newlink() + error path + +From: Eric Dumazet + +[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ] + +valis reported that a race condition still happens after my prior patch. + +macvlan_common_newlink() might have made @dev visible before +detecting an error, and its caller will directly call free_netdev(dev). + +We must respect an RCU period, either in macvlan or the core networking +stack. + +After adding a temporary mdelay(1000) in macvlan_forward_source_one() +to open the race window, valis repro was: + +ip link add p1 type veth peer p2 +ip link set address 00:00:00:00:00:20 dev p1 +ip link set up dev p1 +ip link set up dev p2 +ip link add mv0 link p2 type macvlan mode source + +(ip link add invalid% link p2 type macvlan mode source macaddr add +00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4 +PING 1.2.3.4 (1.2.3.4): 56 data bytes +RTNETLINK answers: Invalid argument + +BUG: KASAN: slab-use-after-free in macvlan_forward_source +(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +Read of size 8 at addr ffff888016bb89c0 by task e/175 + +CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +Call Trace: + +dump_stack_lvl (lib/dump_stack.c:123) +print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +kasan_report (mm/kasan/report.c:597) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +? tasklet_init (kernel/softirq.c:983) +macvlan_handle_frame (drivers/net/macvlan.c:501) + +Allocated by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +__kasan_kmalloc (mm/kasan/common.c:419) +__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657 +mm/slub.c:7140) +alloc_netdev_mqs (net/core/dev.c:12012) +rtnl_create_link (net/core/rtnetlink.c:3648) +rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Freed by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +kasan_save_free_info (mm/kasan/generic.c:587) +__kasan_slab_free (mm/kasan/common.c:287) +kfree (mm/slub.c:6674 mm/slub.c:6882) +rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()") +Signed-off-by: Eric Dumazet +Reported-by: valis +Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index c509228be84d1..4433b8e95b6ac 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1572,6 +1572,11 @@ int macvlan_common_newlink(struct net_device *dev, + if (create) + macvlan_port_destroy(port->dev); + } ++ /* @dev might have been made visible before an error was detected. ++ * Make sure to observe an RCU grace period before our caller ++ * (rtnl_newlink()) frees it. ++ */ ++ synchronize_net(); + return err; + } + EXPORT_SYMBOL_GPL(macvlan_common_newlink); +-- +2.51.0 + diff --git a/queue-6.19/mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch b/queue-6.19/mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch new file mode 100644 index 0000000000..a948706abd --- /dev/null +++ b/queue-6.19/mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch @@ -0,0 +1,51 @@ +From e67c5598626666e384fd9de6346bb29b80bc0452 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Feb 2026 04:40:10 -0500 +Subject: mshv: fix SRCU protection in irqfd resampler ack handler + +From: Li RongQing + +[ Upstream commit 2e7577cd5ddc1f86d1b6c48caf3cfa87dbb14e34 ] + +Replace hlist_for_each_entry_rcu() with hlist_for_each_entry_srcu() +in mshv_irqfd_resampler_ack() to correctly handle SRCU-protected +linked list traversal. + +The function uses SRCU (sleepable RCU) synchronization via +partition->pt_irq_srcu, but was incorrectly using the RCU variant +for list iteration. This could lead to race conditions when the +list is modified concurrently. + +Also add srcu_read_lock_held() assertion as required by +hlist_for_each_entry_srcu() to ensure we're in the proper +read-side critical section. + +Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs") +Signed-off-by: Li RongQing +Reviewed-by: Anirudh Rayabharam (Microsoft) +Acked-by: Stanislav Kinsburskii +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + drivers/hv/mshv_eventfd.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/hv/mshv_eventfd.c b/drivers/hv/mshv_eventfd.c +index 0b75ff1edb735..6d176ed8ae516 100644 +--- a/drivers/hv/mshv_eventfd.c ++++ b/drivers/hv/mshv_eventfd.c +@@ -87,8 +87,9 @@ static void mshv_irqfd_resampler_ack(struct mshv_irq_ack_notifier *mian) + + idx = srcu_read_lock(&partition->pt_irq_srcu); + +- hlist_for_each_entry_rcu(irqfd, &resampler->rsmplr_irqfd_list, +- irqfd_resampler_hnode) { ++ hlist_for_each_entry_srcu(irqfd, &resampler->rsmplr_irqfd_list, ++ irqfd_resampler_hnode, ++ srcu_read_lock_held(&partition->pt_irq_srcu)) { + if (hv_should_clear_interrupt(irqfd->irqfd_lapic_irq.lapic_control.interrupt_type)) + hv_call_clear_virtual_interrupt(partition->pt_id); + +-- +2.51.0 + diff --git a/queue-6.19/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch b/queue-6.19/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch new file mode 100644 index 0000000000..14321a038f --- /dev/null +++ b/queue-6.19/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch @@ -0,0 +1,192 @@ +From 5527061049067225b66f380a271b68e6c1a38d05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 09:00:30 +0200 +Subject: net: bridge: mcast: always update mdb_n_entries for vlan contexts + +From: Nikolay Aleksandrov + +[ Upstream commit 8b769e311a86bb9d15c5658ad283b86fc8f080a2 ] + +syzbot triggered a warning[1] about the number of mdb entries in a context. +It turned out that there are multiple ways to trigger that warning today +(some got added during the years), the root cause of the problem is that +the increase is done conditionally, and over the years these different +conditions increased so there were new ways to trigger the warning, that is +to do a decrease which wasn't paired with a previous increase. + +For example one way to trigger it is with flush: + $ ip l add br0 up type bridge vlan_filtering 1 mcast_snooping 1 + $ ip l add dumdum up master br0 type dummy + $ bridge mdb add dev br0 port dumdum grp 239.0.0.1 permanent vid 1 + $ ip link set dev br0 down + $ ip link set dev br0 type bridge mcast_vlan_snooping 1 + ^^^^ this will enable snooping, but will not update mdb_n_entries + because in __br_multicast_enable_port_ctx() we check !netif_running + $ bridge mdb flush dev br0 + ^^^ this will trigger the warning because it will delete the pg which + we added above, which will try to decrease mdb_n_entries + +Fix the problem by removing the conditional increase and always keep the +count up-to-date while the vlan exists. In order to do that we have to +first initialize it on port-vlan context creation, and then always increase +or decrease the value regardless of mcast options. To keep the current +behaviour we have to enforce the mdb limit only if the context is port's or +if the port-vlan's mcast snooping is enabled. + +[1] + ------------[ cut here ]------------ + n == 0 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline], CPU#0: syz.4.4607/22043 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline], CPU#0: syz.4.4607/22043 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825, CPU#0: syz.4.4607/22043 + Modules linked in: + CPU: 0 UID: 0 PID: 22043 Comm: syz.4.4607 Not tainted syzkaller #0 PREEMPT(full) + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026 + RIP: 0010:br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline] + RIP: 0010:br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline] + RIP: 0010:br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825 + Code: 41 5f 5d e9 04 7a 48 f7 e8 3f 73 5c f7 90 0f 0b 90 e9 cf fd ff ff e8 31 73 5c f7 90 0f 0b 90 e9 16 fd ff ff e8 23 73 5c f7 90 <0f> 0b 90 e9 60 fd ff ff e8 15 73 5c f7 eb 05 e8 0e 73 5c f7 48 8b + RSP: 0018:ffffc9000c207220 EFLAGS: 00010293 + RAX: ffffffff8a68042d RBX: ffff88807c6f1800 RCX: ffff888066e90000 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: 0000000000000000 R08: ffff888066e90000 R09: 000000000000000c + R10: 000000000000000c R11: 0000000000000000 R12: ffff8880303ef800 + R13: dffffc0000000000 R14: ffff888050eb11c4 R15: 1ffff1100a1d6238 + FS: 00007fa45921b6c0(0000) GS:ffff8881256f5000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007fa4591f9ff8 CR3: 0000000081df2000 CR4: 00000000003526f0 + Call Trace: + + br_mdb_flush_pgs net/bridge/br_mdb.c:1525 [inline] + br_mdb_flush net/bridge/br_mdb.c:1544 [inline] + br_mdb_del_bulk+0x5e2/0xb20 net/bridge/br_mdb.c:1561 + rtnl_mdb_del+0x48a/0x640 net/core/rtnetlink.c:-1 + rtnetlink_rcv_msg+0x77e/0xbe0 net/core/rtnetlink.c:6967 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + RIP: 0033:0x7fa45839aeb9 + Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48 + RSP: 002b:00007fa45921b028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e + RAX: ffffffffffffffda RBX: 00007fa458615fa0 RCX: 00007fa45839aeb9 + RDX: 0000000000000000 RSI: 00002000000000c0 RDI: 0000000000000004 + RBP: 00007fa458408c1f R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 + R13: 00007fa458616038 R14: 00007fa458615fa0 R15: 00007fff0b59fae8 + + +Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port") +Reported-by: syzbot+d5d1b7343531d17bd3c5@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/aYrWbRp83MQR1ife@debil/T/#t +Reviewed-by: Ido Schimmel +Signed-off-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20260213070031.1400003-2-nikolay@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/bridge/br_multicast.c | 45 ++++++++++++++++----------------------- + 1 file changed, 18 insertions(+), 27 deletions(-) + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index d55a4ab87837f..e9a7e65304017 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -244,14 +244,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid) + + lockdep_assert_held_once(&port->br->multicast_lock); + +- if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) +- return NULL; +- + /* Take RCU to access the vlan. */ + rcu_read_lock(); + + vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid); +- if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx)) ++ if (vlan) + pmctx = &vlan->port_mcast_ctx; + + rcu_read_unlock(); +@@ -701,7 +698,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx, + u32 max = READ_ONCE(pmctx->mdb_max_entries); + u32 n = READ_ONCE(pmctx->mdb_n_entries); + +- if (max && n >= max) { ++ /* enforce the max limit when it's a port pmctx or a port-vlan pmctx ++ * with snooping enabled ++ */ ++ if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) { + NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u", + what, n, max); + return -E2BIG; +@@ -736,9 +736,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port, + return err; + } + +- /* Only count on the VLAN context if VID is given, and if snooping on +- * that VLAN is enabled. +- */ ++ /* Only count on the VLAN context if VID is given */ + if (!group->vid) + return 0; + +@@ -2011,6 +2009,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port, + timer_setup(&pmctx->ip6_own_query.timer, + br_ip6_multicast_port_query_expired, 0); + #endif ++ /* initialize mdb_n_entries if a new port vlan is being created */ ++ if (vlan) { ++ struct net_bridge_port_group *pg; ++ u32 n = 0; ++ ++ spin_lock_bh(&port->br->multicast_lock); ++ hlist_for_each_entry(pg, &port->mglist, mglist) ++ if (pg->key.addr.vid == vlan->vid) ++ n++; ++ WRITE_ONCE(pmctx->mdb_n_entries, n); ++ spin_unlock_bh(&port->br->multicast_lock); ++ } + } + + void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx) +@@ -2094,25 +2104,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) + br_ip4_multicast_add_router(brmctx, pmctx); + br_ip6_multicast_add_router(brmctx, pmctx); + } +- +- if (br_multicast_port_ctx_is_vlan(pmctx)) { +- struct net_bridge_port_group *pg; +- u32 n = 0; +- +- /* The mcast_n_groups counter might be wrong. First, +- * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries +- * are flushed, thus mcast_n_groups after the toggle does not +- * reflect the true values. And second, permanent entries added +- * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected +- * either. Thus we have to refresh the counter. +- */ +- +- hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) { +- if (pg->key.addr.vid == pmctx->vlan->vid) +- n++; +- } +- WRITE_ONCE(pmctx->mdb_n_entries, n); +- } + } + + static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) +-- +2.51.0 + diff --git a/queue-6.19/net-do-not-delay-zero-copy-skbs-in-skb_attempt_defer.patch b/queue-6.19/net-do-not-delay-zero-copy-skbs-in-skb_attempt_defer.patch new file mode 100644 index 0000000000..8e62d2a448 --- /dev/null +++ b/queue-6.19/net-do-not-delay-zero-copy-skbs-in-skb_attempt_defer.patch @@ -0,0 +1,48 @@ +From 4296ed5d4fd5c80db2211f5e665c9cf912ef91d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 19:36:53 +0000 +Subject: net: do not delay zero-copy skbs in skb_attempt_defer_free() + +From: Eric Dumazet + +[ Upstream commit 0943404b1f3b178e1e54386dadcbf4f2729c7762 ] + +After the blamed commit, TCP tx zero copy notifications could be +arbitrarily delayed and cause regressions in applications waiting +for them. + +Signed-off-by: Eric Dumazet +Fixes: e20dfbad8aab ("net: fix napi_consume_skb() with alien skbs") +Reviewed-by: Jason Xing +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20260216193653.627617-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/skbuff.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 61746c2b95f63..fa6209f45de9c 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -7231,10 +7231,15 @@ void skb_attempt_defer_free(struct sk_buff *skb) + { + struct skb_defer_node *sdn; + unsigned long defer_count; +- int cpu = skb->alloc_cpu; + unsigned int defer_max; + bool kick; ++ int cpu; + ++ /* zero copy notifications should not be delayed. */ ++ if (skb_zcopy(skb)) ++ goto nodefer; ++ ++ cpu = skb->alloc_cpu; + if (cpu == raw_smp_processor_id() || + WARN_ON_ONCE(cpu >= nr_cpu_ids) || + !cpu_online(cpu)) { +-- +2.51.0 + diff --git a/queue-6.19/net-mctp-ensure-our-nlmsg-responses-are-initialised.patch b/queue-6.19/net-mctp-ensure-our-nlmsg-responses-are-initialised.patch new file mode 100644 index 0000000000..af28f3ac4d --- /dev/null +++ b/queue-6.19/net-mctp-ensure-our-nlmsg-responses-are-initialised.patch @@ -0,0 +1,70 @@ +From a9c7fddbd583759f2f27a96d651c9a814a8130ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 15:27:33 +0800 +Subject: net: mctp: ensure our nlmsg responses are initialised + +From: Jeremy Kerr + +[ Upstream commit a6a9bc544b675d8b5180f2718ec985ad267b5cbf ] + +Syed Faraz Abrar (@farazsth98) from Zellic, and Pumpkin (@u1f383) from +DEVCORE Research Team working with Trend Micro Zero Day Initiative +report that a RTM_GETNEIGH will return uninitalised data in the pad +bytes of the ndmsg data. + +Ensure we're initialising the netlink data to zero, in the link, addr +and neigh response messages. + +Fixes: 831119f88781 ("mctp: Add neighbour netlink interface") +Fixes: 06d2f4c583a7 ("mctp: Add netlink route management") +Fixes: 583be982d934 ("mctp: Add device handling and netlink interface") +Signed-off-by: Jeremy Kerr +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260209-dev-mctp-nlmsg-v1-1-f1e30c346a43@codeconstruct.com.au +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/mctp/device.c | 1 + + net/mctp/neigh.c | 1 + + net/mctp/route.c | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/net/mctp/device.c b/net/mctp/device.c +index 4d404edd7446e..04c5570bacff6 100644 +--- a/net/mctp/device.c ++++ b/net/mctp/device.c +@@ -70,6 +70,7 @@ static int mctp_fill_addrinfo(struct sk_buff *skb, + return -EMSGSIZE; + + hdr = nlmsg_data(nlh); ++ memset(hdr, 0, sizeof(*hdr)); + hdr->ifa_family = AF_MCTP; + hdr->ifa_prefixlen = 0; + hdr->ifa_flags = 0; +diff --git a/net/mctp/neigh.c b/net/mctp/neigh.c +index 05b899f22d902..fc85f0e693014 100644 +--- a/net/mctp/neigh.c ++++ b/net/mctp/neigh.c +@@ -218,6 +218,7 @@ static int mctp_fill_neigh(struct sk_buff *skb, u32 portid, u32 seq, int event, + return -EMSGSIZE; + + hdr = nlmsg_data(nlh); ++ memset(hdr, 0, sizeof(*hdr)); + hdr->ndm_family = AF_MCTP; + hdr->ndm_ifindex = dev->ifindex; + hdr->ndm_state = 0; // TODO other state bits? +diff --git a/net/mctp/route.c b/net/mctp/route.c +index 2ac4011a953ff..ecbbe4beb2133 100644 +--- a/net/mctp/route.c ++++ b/net/mctp/route.c +@@ -1643,6 +1643,7 @@ static int mctp_fill_rtinfo(struct sk_buff *skb, struct mctp_route *rt, + return -EMSGSIZE; + + hdr = nlmsg_data(nlh); ++ memset(hdr, 0, sizeof(*hdr)); + hdr->rtm_family = AF_MCTP; + + /* we use the _len fields as a number of EIDs, rather than +-- +2.51.0 + diff --git a/queue-6.19/net-mlx5-fix-misidentification-of-write-combining-cq.patch b/queue-6.19/net-mlx5-fix-misidentification-of-write-combining-cq.patch new file mode 100644 index 0000000000..1d18f9ed2c --- /dev/null +++ b/queue-6.19/net-mlx5-fix-misidentification-of-write-combining-cq.patch @@ -0,0 +1,87 @@ +From e8685a828e6c57390ca724f150464acb6e069137 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:01 +0200 +Subject: net/mlx5: Fix misidentification of write combining CQE during poll + loop + +From: Gal Pressman + +[ Upstream commit d451994ebc7d4392610bd4b2ab339b255deb4143 ] + +The write combining completion poll loop uses usleep_range() which can +sleep much longer than requested due to scheduler latency. Under load, +we witnessed a 20ms+ delay until the process was rescheduled, causing +the jiffies based timeout to expire while the thread is sleeping. + +The original do-while loop structure (poll, sleep, check timeout) would +exit without a final poll when waking after timeout, missing a CQE that +arrived during sleep. + +Instead of the open-coded while loop, use the kernel's poll_timeout_us() +which always performs an additional check after the sleep expiration, +and is less error-prone. + +Note: poll_timeout_us() doesn't accept a sleep range, by passing 10 +sleep_us the sleep range effectively changes from 2-10 to 3-10 usecs. + +Fixes: d98995b4bf98 ("net/mlx5: Reimplement write combining test") +Signed-off-by: Gal Pressman +Reviewed-by: Jianbo Liu +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-4-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/wc.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wc.c b/drivers/net/ethernet/mellanox/mlx5/core/wc.c +index 815a7c97d6b09..04d03be1bb775 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/wc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/wc.c +@@ -2,6 +2,7 @@ + // Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + #include ++#include + #include + #include "lib/clock.h" + #include "mlx5_core.h" +@@ -15,7 +16,7 @@ + #define TEST_WC_NUM_WQES 255 + #define TEST_WC_LOG_CQ_SZ (order_base_2(TEST_WC_NUM_WQES)) + #define TEST_WC_SQ_LOG_WQ_SZ TEST_WC_LOG_CQ_SZ +-#define TEST_WC_POLLING_MAX_TIME_JIFFIES msecs_to_jiffies(100) ++#define TEST_WC_POLLING_MAX_TIME_USEC (100 * USEC_PER_MSEC) + + struct mlx5_wc_cq { + /* data path - accessed per cqe */ +@@ -359,7 +360,6 @@ static int mlx5_wc_poll_cq(struct mlx5_wc_sq *sq) + static void mlx5_core_test_wc(struct mlx5_core_dev *mdev) + { + unsigned int offset = 0; +- unsigned long expires; + struct mlx5_wc_sq *sq; + int i, err; + +@@ -389,13 +389,9 @@ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev) + + mlx5_wc_post_nop(sq, &offset, true); + +- expires = jiffies + TEST_WC_POLLING_MAX_TIME_JIFFIES; +- do { +- err = mlx5_wc_poll_cq(sq); +- if (err) +- usleep_range(2, 10); +- } while (mdev->wc_state == MLX5_WC_STATE_UNINITIALIZED && +- time_is_after_jiffies(expires)); ++ poll_timeout_us(mlx5_wc_poll_cq(sq), ++ mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED, 10, ++ TEST_WC_POLLING_MAX_TIME_USEC, false); + + mlx5_wc_destroy_sq(sq); + +-- +2.51.0 + diff --git a/queue-6.19/net-mlx5-fix-multiport-device-check-over-light-sfs.patch b/queue-6.19/net-mlx5-fix-multiport-device-check-over-light-sfs.patch new file mode 100644 index 0000000000..bb1c72e287 --- /dev/null +++ b/queue-6.19/net-mlx5-fix-multiport-device-check-over-light-sfs.patch @@ -0,0 +1,55 @@ +From 05ee32f7a14d6875e6a2405475f635d22c0d3196 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:28:59 +0200 +Subject: net/mlx5: Fix multiport device check over light SFs + +From: Shay Drory + +[ Upstream commit 47bf2e813817159f4d195be83a9b5a640ee6baec ] + +Driver is using num_vhca_ports capability to distinguish between +multiport master device and multiport slave device. num_vhca_ports is a +capability the driver sets according to the MAX num_vhca_ports +capability reported by FW. On the other hand, light SFs doesn't set the +above capbility. + +This leads to wrong results whenever light SFs is checking whether he is +a multiport master or slave. + +Therefore, use the MAX capability to distinguish between master and +slave devices. + +Fixes: e71383fb9cd1 ("net/mlx5: Light probe local SFs") +Signed-off-by: Shay Drory +Reviewed-by: Moshe Shemesh +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-2-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/linux/mlx5/driver.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index 1c54aa6f74fbc..1967d1c79139b 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -1281,12 +1281,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev) + static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev) + { + return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) && +- MLX5_CAP_GEN(dev, num_vhca_ports) <= 1; ++ MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1; + } + + static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev) + { +- return MLX5_CAP_GEN(dev, num_vhca_ports) > 1; ++ return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1; + } + + static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev) +-- +2.51.0 + diff --git a/queue-6.19/net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch b/queue-6.19/net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch new file mode 100644 index 0000000000..7cc2ee5b28 --- /dev/null +++ b/queue-6.19/net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch @@ -0,0 +1,318 @@ +From 3b8b6144afddccbf04a0eb8529b5c41bc6472f77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:03 +0200 +Subject: net/mlx5e: Fix deadlocks between devlink and netdev instance locks + +From: Cosmin Ratiu + +[ Upstream commit 83ac0304a2d77519dae1e54c9713cbe1aedf19c9 ] + +In the mentioned "Fixes" commit, various work tasks triggering devlink +health reporter recovery were switched to use netdev_trylock to protect +against concurrent tear down of the channels being recovered. But this +had the side effect of introducing potential deadlocks because of +incorrect lock ordering. + +The correct lock order is described by the init flow: +probe_one -> mlx5_init_one (acquires devlink lock) +-> mlx5_init_one_devl_locked -> mlx5_register_device +-> mlx5_rescan_drivers_locked -...-> mlx5e_probe -> _mlx5e_probe +-> register_netdev (acquires rtnl lock) +-> register_netdevice (acquires netdev lock) +=> devlink lock -> rtnl lock -> netdev lock. + +But in the current recovery flow, the order is wrong: +mlx5e_tx_err_cqe_work (acquires netdev lock) +-> mlx5e_reporter_tx_err_cqe -> mlx5e_health_report +-> devlink_health_report (acquires devlink lock => boom!) +-> devlink_health_reporter_recover +-> mlx5e_tx_reporter_recover -> mlx5e_tx_reporter_recover_from_ctx +-> mlx5e_tx_reporter_err_cqe_recover + +The same pattern exists in: +mlx5e_reporter_rx_timeout +mlx5e_reporter_tx_ptpsq_unhealthy +mlx5e_reporter_tx_timeout + +Fix these by moving the netdev_trylock calls from the work handlers +lower in the call stack, in the respective recovery functions, where +they are actually necessary. + +Fixes: 8f7b00307bf1 ("net/mlx5e: Convert mlx5 netdevs to instance locking") +Signed-off-by: Cosmin Ratiu +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-6-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 14 ----- + .../mellanox/mlx5/core/en/reporter_rx.c | 13 +++++ + .../mellanox/mlx5/core/en/reporter_tx.c | 52 +++++++++++++++++-- + .../net/ethernet/mellanox/mlx5/core/en_main.c | 40 -------------- + 4 files changed, 61 insertions(+), 58 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +index 424f8a2728a3e..74660e7fe6748 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +@@ -457,22 +457,8 @@ static void mlx5e_ptpsq_unhealthy_work(struct work_struct *work) + { + struct mlx5e_ptpsq *ptpsq = + container_of(work, struct mlx5e_ptpsq, report_unhealthy_work); +- struct mlx5e_txqsq *sq = &ptpsq->txqsq; +- +- /* Recovering the PTP SQ means re-enabling NAPI, which requires the +- * netdev instance lock. However, SQ closing has to wait for this work +- * task to finish while also holding the same lock. So either get the +- * lock or find that the SQ is no longer enabled and thus this work is +- * not relevant anymore. +- */ +- while (!netdev_trylock(sq->netdev)) { +- if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) +- return; +- msleep(20); +- } + + mlx5e_reporter_tx_ptpsq_unhealthy(ptpsq); +- netdev_unlock(sq->netdev); + } + + static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +index 0686fbdd5a059..6efb626b55062 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +@@ -1,6 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 + // Copyright (c) 2019 Mellanox Technologies. + ++#include ++ + #include "health.h" + #include "params.h" + #include "txrx.h" +@@ -177,6 +179,16 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx) + rq = ctx; + priv = rq->priv; + ++ /* Acquire netdev instance lock to synchronize with channel close and ++ * reopen flows. Either successfully obtain the lock, or detect that ++ * channels are closing for another reason, making this work no longer ++ * necessary. ++ */ ++ while (!netdev_trylock(rq->netdev)) { ++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state)) ++ return 0; ++ msleep(20); ++ } + mutex_lock(&priv->state_lock); + + eq = rq->cq.mcq.eq; +@@ -186,6 +198,7 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx) + clear_bit(MLX5E_SQ_STATE_ENABLED, &rq->icosq->state); + + mutex_unlock(&priv->state_lock); ++ netdev_unlock(rq->netdev); + + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +index 9e2cf191ed308..9f6454102cf79 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +@@ -1,6 +1,8 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + /* Copyright (c) 2019 Mellanox Technologies. */ + ++#include ++ + #include "health.h" + #include "en/ptp.h" + #include "en/devlink.h" +@@ -78,6 +80,18 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx) + if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) + return 0; + ++ /* Recovering queues means re-enabling NAPI, which requires the netdev ++ * instance lock. However, SQ closing flows have to wait for work tasks ++ * to finish while also holding the netdev instance lock. So either get ++ * the lock or find that the SQ is no longer enabled and thus this work ++ * is not relevant anymore. ++ */ ++ while (!netdev_trylock(dev)) { ++ if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) ++ return 0; ++ msleep(20); ++ } ++ + err = mlx5_core_query_sq_state(mdev, sq->sqn, &state); + if (err) { + netdev_err(dev, "Failed to query SQ 0x%x state. err = %d\n", +@@ -113,9 +127,11 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx) + else + mlx5e_trigger_napi_sched(sq->cq.napi); + ++ netdev_unlock(dev); + return 0; + out: + clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state); ++ netdev_unlock(dev); + return err; + } + +@@ -136,10 +152,24 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) + sq = to_ctx->sq; + eq = sq->cq.mcq.eq; + priv = sq->priv; ++ ++ /* Recovering the TX queues implies re-enabling NAPI, which requires ++ * the netdev instance lock. ++ * However, channel closing flows have to wait for this work to finish ++ * while holding the same lock. So either get the lock or find that ++ * channels are being closed for other reason and this work is not ++ * relevant anymore. ++ */ ++ while (!netdev_trylock(sq->netdev)) { ++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)) ++ return 0; ++ msleep(20); ++ } ++ + err = mlx5e_health_channel_eq_recover(sq->netdev, eq, sq->cq.ch_stats); + if (!err) { + to_ctx->status = 0; /* this sq recovered */ +- return err; ++ goto out; + } + + mutex_lock(&priv->state_lock); +@@ -147,7 +177,7 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) + mutex_unlock(&priv->state_lock); + if (!err) { + to_ctx->status = 1; /* all channels recovered */ +- return err; ++ goto out; + } + + to_ctx->status = err; +@@ -155,7 +185,8 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) + netdev_err(priv->netdev, + "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n", + err); +- ++out: ++ netdev_unlock(sq->netdev); + return err; + } + +@@ -172,10 +203,22 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) + return 0; + + priv = ptpsq->txqsq.priv; ++ netdev = priv->netdev; ++ ++ /* Recovering the PTP SQ means re-enabling NAPI, which requires the ++ * netdev instance lock. However, SQ closing has to wait for this work ++ * task to finish while also holding the same lock. So either get the ++ * lock or find that the SQ is no longer enabled and thus this work is ++ * not relevant anymore. ++ */ ++ while (!netdev_trylock(netdev)) { ++ if (!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state)) ++ return 0; ++ msleep(20); ++ } + + mutex_lock(&priv->state_lock); + chs = &priv->channels; +- netdev = priv->netdev; + + carrier_ok = netif_carrier_ok(netdev); + netif_carrier_off(netdev); +@@ -192,6 +235,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) + netif_carrier_on(netdev); + + mutex_unlock(&priv->state_lock); ++ netdev_unlock(netdev); + + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 4b2963bbe7ff4..e15e6fb4cd8ea 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -688,19 +688,7 @@ static void mlx5e_rq_timeout_work(struct work_struct *timeout_work) + struct mlx5e_rq, + rx_timeout_work); + +- /* Acquire netdev instance lock to synchronize with channel close and +- * reopen flows. Either successfully obtain the lock, or detect that +- * channels are closing for another reason, making this work no longer +- * necessary. +- */ +- while (!netdev_trylock(rq->netdev)) { +- if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state)) +- return; +- msleep(20); +- } +- + mlx5e_reporter_rx_timeout(rq); +- netdev_unlock(rq->netdev); + } + + static int mlx5e_alloc_mpwqe_rq_drop_page(struct mlx5e_rq *rq) +@@ -1997,20 +1985,7 @@ void mlx5e_tx_err_cqe_work(struct work_struct *recover_work) + struct mlx5e_txqsq *sq = container_of(recover_work, struct mlx5e_txqsq, + recover_work); + +- /* Recovering queues means re-enabling NAPI, which requires the netdev +- * instance lock. However, SQ closing flows have to wait for work tasks +- * to finish while also holding the netdev instance lock. So either get +- * the lock or find that the SQ is no longer enabled and thus this work +- * is not relevant anymore. +- */ +- while (!netdev_trylock(sq->netdev)) { +- if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) +- return; +- msleep(20); +- } +- + mlx5e_reporter_tx_err_cqe(sq); +- netdev_unlock(sq->netdev); + } + + static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode) +@@ -5121,19 +5096,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) + struct net_device *netdev = priv->netdev; + int i; + +- /* Recovering the TX queues implies re-enabling NAPI, which requires +- * the netdev instance lock. +- * However, channel closing flows have to wait for this work to finish +- * while holding the same lock. So either get the lock or find that +- * channels are being closed for other reason and this work is not +- * relevant anymore. +- */ +- while (!netdev_trylock(netdev)) { +- if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)) +- return; +- msleep(20); +- } +- + for (i = 0; i < netdev->real_num_tx_queues; i++) { + struct netdev_queue *dev_queue = + netdev_get_tx_queue(netdev, i); +@@ -5146,8 +5108,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) + /* break if tried to reopened channels */ + break; + } +- +- netdev_unlock(netdev); + } + + static void mlx5e_tx_timeout(struct net_device *dev, unsigned int txqueue) +-- +2.51.0 + diff --git a/queue-6.19/net-mlx5e-fix-misidentification-of-aso-cqe-during-po.patch b/queue-6.19/net-mlx5e-fix-misidentification-of-aso-cqe-during-po.patch new file mode 100644 index 0000000000..9788c58425 --- /dev/null +++ b/queue-6.19/net-mlx5e-fix-misidentification-of-aso-cqe-during-po.patch @@ -0,0 +1,112 @@ +From dd3f3086446e0cb06519b89e342bd30f68cd85c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:00 +0200 +Subject: net/mlx5e: Fix misidentification of ASO CQE during poll loop + +From: Gal Pressman + +[ Upstream commit ae3cb71e6c4dbda0c0b7c10475b744377813c7bd ] + +The ASO completion poll loop uses usleep_range() which can sleep much +longer than requested due to scheduler latency. Under load, we witnessed +a 20ms+ delay until the process was rescheduled, causing the jiffies +based timeout to expire while the thread is sleeping. + +The original do-while loop structure (poll, sleep, check timeout) would +exit without a final poll when waking after timeout, missing a CQE that +arrived during sleep. + +Instead of the open-coded while loop, use the kernel's +read_poll_timeout() which always performs an additional check after the +sleep expiration, and is less error-prone. + +Note: read_poll_timeout() doesn't accept a sleep range, by passing 10 +sleep_us the sleep range effectively changes from 2-10 to 3-10 usecs. + +Fixes: 739cfa34518e ("net/mlx5: Make ASO poll CQ usable in atomic context") +Fixes: 7e3fce82d945 ("net/mlx5e: Overcome slow response for first macsec ASO WQE") +Signed-off-by: Gal Pressman +Reviewed-by: Jianbo Liu +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-3-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c | 10 +++------- + .../net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 10 +++------- + 2 files changed, 6 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c +index 7819fb2972802..d5d9146efca67 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB + // Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + ++#include + #include + #include "lib/aso.h" + #include "en/tc/post_act.h" +@@ -115,7 +116,6 @@ mlx5e_tc_meter_modify(struct mlx5_core_dev *mdev, + struct mlx5e_flow_meters *flow_meters; + u8 cir_man, cir_exp, cbs_man, cbs_exp; + struct mlx5_aso_wqe *aso_wqe; +- unsigned long expires; + struct mlx5_aso *aso; + u64 rate, burst; + u8 ds_cnt; +@@ -187,12 +187,8 @@ mlx5e_tc_meter_modify(struct mlx5_core_dev *mdev, + mlx5_aso_post_wqe(aso, true, &aso_wqe->ctrl); + + /* With newer FW, the wait for the first ASO WQE is more than 2us, put the wait 10ms. */ +- expires = jiffies + msecs_to_jiffies(10); +- do { +- err = mlx5_aso_poll_cq(aso, true); +- if (err) +- usleep_range(2, 10); +- } while (err && time_is_after_jiffies(expires)); ++ read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC, ++ false, aso, true); + mutex_unlock(&flow_meters->aso_lock); + + return err; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +index 528b04d4de416..641cd3a2cdfab 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + + #include "en.h" + #include "lib/aso.h" +@@ -1397,7 +1398,6 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac + struct mlx5e_macsec_aso *aso; + struct mlx5_aso_wqe *aso_wqe; + struct mlx5_aso *maso; +- unsigned long expires; + int err; + + aso = &macsec->aso; +@@ -1411,12 +1411,8 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac + macsec_aso_build_wqe_ctrl_seg(aso, &aso_wqe->aso_ctrl, NULL); + + mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl); +- expires = jiffies + msecs_to_jiffies(10); +- do { +- err = mlx5_aso_poll_cq(maso, false); +- if (err) +- usleep_range(2, 10); +- } while (err && time_is_after_jiffies(expires)); ++ read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC, ++ false, maso, false); + + if (err) + goto err_out; +-- +2.51.0 + diff --git a/queue-6.19/net-mlx5e-macsec-add-aso-poll-loop-in-macsec_aso_set.patch b/queue-6.19/net-mlx5e-macsec-add-aso-poll-loop-in-macsec_aso_set.patch new file mode 100644 index 0000000000..ca382aded5 --- /dev/null +++ b/queue-6.19/net-mlx5e-macsec-add-aso-poll-loop-in-macsec_aso_set.patch @@ -0,0 +1,45 @@ +From d4ac37e80b0a0934dfd2d885807614043823c252 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:02 +0200 +Subject: net/mlx5e: MACsec, add ASO poll loop in macsec_aso_set_arm_event + +From: Gal Pressman + +[ Upstream commit 9854b243ce4225328d0b32fdc998d35b6952d3f7 ] + +The macsec_aso_set_arm_event function calls mlx5_aso_poll_cq once +without a retry loop. If the CQE is not immediately available after +posting the WQE, the function fails unnecessarily. + +Use read_poll_timeout() to poll 3-10 usecs for CQE, consistent with +other ASO polling code paths in the driver. + +Fixes: 739cfa34518e ("net/mlx5: Make ASO poll CQ usable in atomic context") +Signed-off-by: Gal Pressman +Reviewed-by: Jianbo Liu +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-5-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +index 641cd3a2cdfab..90b3bc5f9166f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +@@ -1386,7 +1386,8 @@ static int macsec_aso_set_arm_event(struct mlx5_core_dev *mdev, struct mlx5e_mac + MLX5_ACCESS_ASO_OPC_MOD_MACSEC); + macsec_aso_build_ctrl(aso, &aso_wqe->aso_ctrl, in); + mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl); +- err = mlx5_aso_poll_cq(maso, false); ++ read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC, ++ false, maso, false); + mutex_unlock(&aso->aso_lock); + + return err; +-- +2.51.0 + diff --git a/queue-6.19/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch b/queue-6.19/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch new file mode 100644 index 0000000000..c80cd28571 --- /dev/null +++ b/queue-6.19/net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch @@ -0,0 +1,48 @@ +From 05e007304b5ffceaac011c53126b6e3019f5ee7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:29:04 +0200 +Subject: net/mlx5e: Use unsigned for mlx5e_get_max_num_channels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cosmin Ratiu + +[ Upstream commit 57a94d4b22b0c6cc5d601e6b6238d78fb923d991 ] + +The max number of channels is always an unsigned int, use the correct +type to fix compilation errors done with strict type checking, e.g.: + +error: call to ‘__compiletime_assert_1110’ declared with attribute + error: min(mlx5e_get_devlink_param_num_doorbells(mdev), + mlx5e_get_max_num_channels(mdev)) signedness error + +Fixes: 74a8dadac17e ("net/mlx5e: Preparations for supporting larger number of channels") +Signed-off-by: Cosmin Ratiu +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-7-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index ff4ab4691baf0..a06d08576fd4b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -179,7 +179,8 @@ static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size) + } + + /* Use this function to get max num channels (rxqs/txqs) only to create netdev */ +-static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) ++static inline unsigned int ++mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) + { + return is_kdump_kernel() ? + MLX5E_MIN_NUM_CHANNELS : +-- +2.51.0 + diff --git a/queue-6.19/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch b/queue-6.19/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch new file mode 100644 index 0000000000..ac56293d26 --- /dev/null +++ b/queue-6.19/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch @@ -0,0 +1,62 @@ +From 0b51c451393255c0595ecdca84e6fa322cd8ccb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:02 +0000 +Subject: net: mscc: ocelot: add missing lock protection in + ocelot_port_xmit_inj() + +From: Ziyi Guo + +[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ] + +ocelot_port_xmit_inj() calls ocelot_can_inject() and +ocelot_port_inject_frame() without holding the injection group lock. +Both functions contain lockdep_assert_held() for the injection lock, +and the correct caller felix_port_deferred_xmit() properly acquires +the lock using ocelot_lock_inj_grp() before calling these functions. + +Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register +injection path to fix the missing lock protection. The FDMA path is not +affected as it uses its own locking mechanism. + +Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups") +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index a7966c174b2e2..1b82693204640 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, + int port = priv->port.index; + u32 rew_op = 0; + +- if (!ocelot_can_inject(ocelot, 0)) ++ ocelot_lock_inj_grp(ocelot, 0); ++ ++ if (!ocelot_can_inject(ocelot, 0)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_BUSY; ++ } + +- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_OK; ++ } + + ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ++ ocelot_unlock_inj_grp(ocelot, 0); ++ + consume_skb(skb); + + return NETDEV_TX_OK; +-- +2.51.0 + diff --git a/queue-6.19/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch b/queue-6.19/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch new file mode 100644 index 0000000000..ed12b99002 --- /dev/null +++ b/queue-6.19/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch @@ -0,0 +1,93 @@ +From 9d464bc3152c8b046754165245286e9dae3b7a7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:00 +0000 +Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper + +From: Ziyi Guo + +[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ] + +Extract the PTP timestamp handling logic from ocelot_port_xmit() into a +separate ocelot_xmit_timestamp() helper function. This is a pure +refactor with no behavioral change. + +The helper returns false if the skb was consumed (freed) due to a +timestamp request failure, and true if the caller should continue with +frame injection. The rew_op value is returned via pointer. + +This prepares for splitting ocelot_port_xmit() into separate FDMA and +register injection paths in a subsequent patch. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++---------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 469784d3a1a67..ef4a6c768de9b 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -551,33 +551,41 @@ static int ocelot_port_stop(struct net_device *dev) + return 0; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, ++ struct sk_buff *skb, u32 *rew_op) + { +- struct ocelot_port_private *priv = netdev_priv(dev); +- struct ocelot_port *ocelot_port = &priv->port; +- struct ocelot *ocelot = ocelot_port->ocelot; +- int port = priv->port.index; +- u32 rew_op = 0; +- +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) +- return NETDEV_TX_BUSY; +- +- /* Check if timestamping is needed */ + if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + struct sk_buff *clone = NULL; + + if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) { + kfree_skb(skb); +- return NETDEV_TX_OK; ++ return false; + } + + if (clone) + OCELOT_SKB_CB(skb)->clone = clone; + +- rew_op = ocelot_ptp_rew_op(skb); ++ *rew_op = ocelot_ptp_rew_op(skb); + } + ++ return true; ++} ++ ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!static_branch_unlikely(&ocelot_fdma_enabled) && ++ !ocelot_can_inject(ocelot, 0)) ++ return NETDEV_TX_BUSY; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ + if (static_branch_unlikely(&ocelot_fdma_enabled)) { + ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); + } else { +-- +2.51.0 + diff --git a/queue-6.19/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch b/queue-6.19/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch new file mode 100644 index 0000000000..24e04d9784 --- /dev/null +++ b/queue-6.19/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch @@ -0,0 +1,100 @@ +From e6dc59b2a009d278e19f3b158045ad6daebc6cb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:01 +0000 +Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths + +From: Ziyi Guo + +[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ] + +Split ocelot_port_xmit() into two separate functions: +- ocelot_port_xmit_fdma(): handles the FDMA injection path +- ocelot_port_xmit_inj(): handles the register-based injection path + +The top-level ocelot_port_xmit() now dispatches to the appropriate +function based on the ocelot_fdma_enabled static key. + +This is a pure refactor with no behavioral change. Separating the two +code paths makes each one simpler and prepares for adding proper locking +to the register injection path without affecting the FDMA path. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index ef4a6c768de9b..a7966c174b2e2 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -571,7 +571,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, + return true; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ ++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); ++ ++ return NETDEV_TX_OK; ++} ++ ++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, ++ struct net_device *dev) + { + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; +@@ -579,24 +597,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) + int port = priv->port.index; + u32 rew_op = 0; + +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) ++ if (!ocelot_can_inject(ocelot, 0)) + return NETDEV_TX_BUSY; + + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + return NETDEV_TX_OK; + +- if (static_branch_unlikely(&ocelot_fdma_enabled)) { +- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); +- } else { +- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); ++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + +- consume_skb(skb); +- } ++ consume_skb(skb); + + return NETDEV_TX_OK; + } + ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ if (static_branch_unlikely(&ocelot_fdma_enabled)) ++ return ocelot_port_xmit_fdma(skb, dev); ++ ++ return ocelot_port_xmit_inj(skb, dev); ++} ++ + enum ocelot_action_type { + OCELOT_MACT_LEARN, + OCELOT_MACT_FORGET, +-- +2.51.0 + diff --git a/queue-6.19/net-psp-select-config_skb_extensions.patch b/queue-6.19/net-psp-select-config_skb_extensions.patch new file mode 100644 index 0000000000..988c70555d --- /dev/null +++ b/queue-6.19/net-psp-select-config_skb_extensions.patch @@ -0,0 +1,59 @@ +From abfd67c2ef742cc495495ba746b4ebac16be6b43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 11:54:54 +0100 +Subject: net: psp: select CONFIG_SKB_EXTENSIONS + +From: Arnd Bergmann + +[ Upstream commit 6e980df452169f82674f2e650079c1fe0aee343d ] + +psp now uses skb extensions, failing to build when that is disabled: + +In file included from include/net/psp.h:7, + from net/psp/psp_sock.c:9: +include/net/psp/functions.h: In function '__psp_skb_coalesce_diff': +include/net/psp/functions.h:60:13: error: implicit declaration of function 'skb_ext_find'; did you mean 'skb_ext_copy'? [-Wimplicit-function-declaration] + 60 | a = skb_ext_find(one, SKB_EXT_PSP); + | ^~~~~~~~~~~~ + | skb_ext_copy +include/net/psp/functions.h:60:31: error: 'SKB_EXT_PSP' undeclared (first use in this function) + 60 | a = skb_ext_find(one, SKB_EXT_PSP); + | ^~~~~~~~~~~ +include/net/psp/functions.h:60:31: note: each undeclared identifier is reported only once for each function it appears in +include/net/psp/functions.h: In function '__psp_sk_rx_policy_check': +include/net/psp/functions.h:94:53: error: 'SKB_EXT_PSP' undeclared (first use in this function) + 94 | struct psp_skb_ext *pse = skb_ext_find(skb, SKB_EXT_PSP); + | ^~~~~~~~~~~ +net/psp/psp_sock.c: In function 'psp_sock_recv_queue_check': +net/psp/psp_sock.c:164:41: error: 'SKB_EXT_PSP' undeclared (first use in this function) + 164 | pse = skb_ext_find(skb, SKB_EXT_PSP); + | ^~~~~~~~~~~ + +Select the Kconfig symbol as we do from its other users. + +Fixes: 6b46ca260e22 ("net: psp: add socket security association code") +Signed-off-by: Arnd Bergmann +Reviewed-by: Simon Horman +Reviewed-by: Daniel Zahka +Link: https://patch.msgid.link/20260216105500.2382181-1-arnd@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/psp/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/psp/Kconfig b/net/psp/Kconfig +index 371e8771f3bd3..84d6b0f254606 100644 +--- a/net/psp/Kconfig ++++ b/net/psp/Kconfig +@@ -6,6 +6,7 @@ config INET_PSP + bool "PSP Security Protocol support" + depends on INET + select SKB_DECRYPTED ++ select SKB_EXTENSIONS + select SOCK_VALIDATE_XMIT + help + Enable kernel support for the PSP Security Protocol (PSP). +-- +2.51.0 + diff --git a/queue-6.19/net-rds-rds_sendmsg-should-not-discard-payload_len.patch b/queue-6.19/net-rds-rds_sendmsg-should-not-discard-payload_len.patch new file mode 100644 index 0000000000..1b1d5e4ecd --- /dev/null +++ b/queue-6.19/net-rds-rds_sendmsg-should-not-discard-payload_len.patch @@ -0,0 +1,50 @@ +From 34a93041e44c9a70c80dbd9587e7ba466a428be5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:54:09 -0700 +Subject: net/rds: rds_sendmsg should not discard payload_len + +From: Allison Henderson + +[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ] + +Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with +connection teardown") modifies rds_sendmsg to avoid enqueueing work +while a tear down is in progress. However, it also changed the return +value of rds_sendmsg to that of rds_send_xmit instead of the +payload_len. This means the user may incorrectly receive errno values +when it should have simply received a payload of 0 while the peer +attempts a reconnections. So this patch corrects the teardown handling +code to only use the out error path in that case, thus restoring the +original payload_len return value. + +Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown") +Reviewed-by: Simon Horman +Signed-off-by: Allison Henderson +Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/rds/send.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/rds/send.c b/net/rds/send.c +index 0b3d0ef2f008b..071c5dca969a2 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1382,9 +1382,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) + else + queue_delayed_work(rds_wq, &cpath->cp_send_w, 1); + rcu_read_unlock(); ++ ++ if (ret) ++ goto out; + } +- if (ret) +- goto out; ++ + rds_message_put(rm); + + for (ind = 0; ind < vct.indx; ind++) +-- +2.51.0 + diff --git a/queue-6.19/net-remove-warn_on_once-when-accessing-forward-path-.patch b/queue-6.19/net-remove-warn_on_once-when-accessing-forward-path-.patch new file mode 100644 index 0000000000..a94c0d8fac --- /dev/null +++ b/queue-6.19/net-remove-warn_on_once-when-accessing-forward-path-.patch @@ -0,0 +1,39 @@ +From db79210d3cfdfb429354edceabb45545cbdf8129 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 12:56:39 +0100 +Subject: net: remove WARN_ON_ONCE when accessing forward path array + +From: Pablo Neira Ayuso + +[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ] + +Although unlikely, recent support for IPIP tunnels increases chances of +reaching this WARN_ON_ONCE if userspace manages to build a sufficiently +long forward path. + +Remove it. + +Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index ccef685023c29..f5e4040e08399 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -738,7 +738,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) + { + int k = stack->num_paths++; + +- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) ++ if (k >= NET_DEVICE_PATH_STACK_MAX) + return NULL; + + return &stack->path[k]; +-- +2.51.0 + diff --git a/queue-6.19/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch b/queue-6.19/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch new file mode 100644 index 0000000000..946c3267b4 --- /dev/null +++ b/queue-6.19/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch @@ -0,0 +1,48 @@ +From 2d22b4b6af80acb6c3f2f1c15b5ed6c317c75da2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 14:44:01 +0100 +Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register + width + +From: Daniel Machon + +[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ] + +DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth +across traffic classes based on per-queue cost values, where lower cost +means higher bandwidth share. + +The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware +register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only +5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to +compute cost values that silently overflow via FIELD_PREP, resulting +in incorrect scheduling weights. + +Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width. + +Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc") +Signed-off-by: Daniel Machon +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +index 1231a80335d7b..04f76f1e23f60 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +@@ -35,7 +35,7 @@ + #define SPX5_SE_BURST_UNIT 4096 + + /* Dwrr */ +-#define SPX5_DWRR_COST_MAX 63 ++#define SPX5_DWRR_COST_MAX 31 + + struct sparx5_shaper { + u32 mode; +-- +2.51.0 + diff --git a/queue-6.19/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch b/queue-6.19/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch new file mode 100644 index 0000000000..374dda56c0 --- /dev/null +++ b/queue-6.19/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch @@ -0,0 +1,53 @@ +From e02fc728c93e6dc41565ede185068699483d916b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 12:02:30 +0100 +Subject: net: sparx5/lan969x: fix PTP clock max_adj value + +From: Daniel Machon + +[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ] + +The max_adj field in ptp_clock_info tells userspace how much the PHC +clock frequency can be adjusted. ptp4l reads this and will never request +a correction larger than max_adj. + +On both sparx5 and lan969x the clock offset may never converge because +the servo needs a frequency correction larger than the current max_adj +of 200000 (200 ppm) allows. The servo rails at the max and the offset +stays in the tens of microseconds. + +The hardware has no inherent max adjustment limit; frequency correction +is done by writing a 64-bit clock period increment to CLK_PER_CFG, and +the register has plenty of range. The 200000 value was just an overly +conservative software limit. The max_adj is shared between sparx5 and +lan969x, and the increased value is safe for both. + +Fix this by increasing max_adj to 10000000 (10000 ppm), giving the +servo sufficient headroom. + +Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks") +Signed-off-by: Daniel Machon +Reviewed-by: Maxime Chevallier +Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +index 2f168700f63c1..8b2e07821a950 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +@@ -576,7 +576,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) + static struct ptp_clock_info sparx5_ptp_clock_info = { + .owner = THIS_MODULE, + .name = "sparx5 ptp", +- .max_adj = 200000, ++ .max_adj = 10000000, + .gettime64 = sparx5_ptp_gettime64, + .settime64 = sparx5_ptp_settime64, + .adjtime = sparx5_ptp_adjtime, +-- +2.51.0 + diff --git a/queue-6.19/net-stmmac-fix-oops-when-split-header-is-enabled.patch b/queue-6.19/net-stmmac-fix-oops-when-split-header-is-enabled.patch new file mode 100644 index 0000000000..f20c2f4da2 --- /dev/null +++ b/queue-6.19/net-stmmac-fix-oops-when-split-header-is-enabled.patch @@ -0,0 +1,79 @@ +From 69cf32f63b80b5e74681799a05e7ed0e00d274bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 17:50:32 -0500 +Subject: net: stmmac: fix oops when split header is enabled + +From: Jie Zhang + +[ Upstream commit babab1b42ed68877ef669a08384becf281ad2582 ] + +For GMAC4, when split header is enabled, in some rare cases, the +hardware does not fill buf2 of the first descriptor with payload. +Thus we cannot assume buf2 is always fully filled if it is not +the last descriptor. Otherwise, the length of buf2 of the second +descriptor will be calculated wrong and cause an oops: + +Unable to handle kernel paging request at virtual address ffff00019246bfc0 +... +x2 : 0000000000000040 x1 : ffff00019246bfc0 x0 : ffff00009246c000 +Call trace: + dcache_inval_poc+0x28/0x58 (P) + dma_direct_sync_single_for_cpu+0x38/0x6c + __dma_sync_single_for_cpu+0x34/0x6c + stmmac_napi_poll_rx+0x8f0/0xb60 + __napi_poll.constprop.0+0x30/0x144 + net_rx_action+0x160/0x274 + handle_softirqs+0x1b8/0x1fc +... + +To fix this, the PL bit-field in RDES3 register is used for all +descriptors, whether it is the last descriptor or not. + +Fixes: ec222003bd94 ("net: stmmac: Prepare to add Split Header support") +Reviewed-by: Jacob Keller +Signed-off-by: Jie Zhang +Link: https://patch.msgid.link/20260209225037.589130-1-jie.zhang@analog.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index a379221b96a34..f98fd254315f6 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5023,13 +5023,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv, + if (!priv->sph_active) + return 0; + +- /* Not last descriptor */ +- if (status & rx_not_ls) ++ /* For GMAC4, when split header is enabled, in some rare cases, the ++ * hardware does not fill buf2 of the first descriptor with payload. ++ * Thus we cannot assume buf2 is always fully filled if it is not ++ * the last descriptor. Otherwise, the length of buf2 of the second ++ * descriptor will be calculated wrong and cause an oops. ++ * ++ * If this is the last descriptor, 'plen' is the length of the ++ * received packet that was transferred to system memory. ++ * Otherwise, it is the accumulated number of bytes that have been ++ * transferred for the current packet. ++ * ++ * Thus 'plen - len' always gives the correct length of buf2. ++ */ ++ ++ /* Not GMAC4 and not last descriptor */ ++ if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls)) + return priv->dma_conf.dma_buf_sz; + ++ /* GMAC4 or last descriptor */ + plen = stmmac_get_rx_frame_len(priv, p, coe); + +- /* Last descriptor */ + return plen - len; + } + +-- +2.51.0 + diff --git a/queue-6.19/net-usb-catc-enable-basic-endpoint-checking.patch b/queue-6.19/net-usb-catc-enable-basic-endpoint-checking.patch new file mode 100644 index 0000000000..d8685bb7c6 --- /dev/null +++ b/queue-6.19/net-usb-catc-enable-basic-endpoint-checking.patch @@ -0,0 +1,111 @@ +From 17faa6040df2fbe5ed71092774225b2360bd153f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 21:41:54 +0000 +Subject: net: usb: catc: enable basic endpoint checking + +From: Ziyi Guo + +[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ] + +catc_probe() fills three URBs with hardcoded endpoint pipes without +verifying the endpoint descriptors: + + - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX + - usb_rcvintpipe(usbdev, 2) for interrupt status + +A malformed USB device can present these endpoints with transfer types +that differ from what the driver assumes. + +Add a catc_usb_ep enum for endpoint numbers, replacing magic constants +throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints() +calls after usb_set_interface() to verify endpoint types before use, +rejecting devices with mismatched descriptors at probe time. + +Similar to +- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking") +which fixed the issue in rtl8150. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Suggested-by: Simon Horman +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c +index 6759388692f8e..3c824340ffb06 100644 +--- a/drivers/net/usb/catc.c ++++ b/drivers/net/usb/catc.c +@@ -64,6 +64,16 @@ static const char driver_name[] = "catc"; + #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ + #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ + ++/* ++ * USB endpoints. ++ */ ++ ++enum catc_usb_ep { ++ CATC_USB_EP_CONTROL = 0, ++ CATC_USB_EP_BULK = 1, ++ CATC_USB_EP_INT_IN = 2, ++}; ++ + /* + * Control requests. + */ +@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + u8 broadcast[ETH_ALEN]; + u8 *macbuf; + int pktsz, ret = -ENOMEM; ++ static const u8 bulk_ep_addr[] = { ++ CATC_USB_EP_BULK | USB_DIR_OUT, ++ CATC_USB_EP_BULK | USB_DIR_IN, ++ 0}; ++ static const u8 int_ep_addr[] = { ++ CATC_USB_EP_INT_IN | USB_DIR_IN, ++ 0}; + + macbuf = kmalloc(ETH_ALEN, GFP_KERNEL); + if (!macbuf) +@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + goto fail_mem; + } + ++ /* Verify that all required endpoints are present */ ++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || ++ !usb_check_int_endpoints(intf, int_ep_addr)) { ++ dev_err(dev, "Missing or invalid endpoints\n"); ++ ret = -ENODEV; ++ goto fail_mem; ++ } ++ + netdev = alloc_etherdev(sizeof(struct catc)); + if (!netdev) + goto fail_mem; +@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), + NULL, NULL, 0, catc_ctrl_done, catc); + +- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), +- NULL, 0, catc_tx_done, catc); ++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK), ++ NULL, 0, catc_tx_done, catc); + +- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), +- catc->rx_buf, pktsz, catc_rx_done, catc); ++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK), ++ catc->rx_buf, pktsz, catc_rx_done, catc); + +- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), +- catc->irq_buf, 2, catc_irq_done, catc, 1); ++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN), ++ catc->irq_buf, 2, catc_irq_done, catc, 1); + + if (!catc->is_f5u011) { + u32 *buf; +-- +2.51.0 + diff --git a/queue-6.19/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch b/queue-6.19/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch new file mode 100644 index 0000000000..db4eac3506 --- /dev/null +++ b/queue-6.19/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch @@ -0,0 +1,58 @@ +From b5666a149bd8f8b8e83c2393102a0bf312b752a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 12:53:09 +0100 +Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value + +From: Florian Westphal + +[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ] + +Mihail Milev reports: Error: UNINIT (CWE-457): + net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl: + Declaring variable "tuple" without initializer. + net/netfilter/nf_conntrack_h323_main.c:1197:2: + uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find". + net/netfilter/nf_conntrack_expect.c:142:2: + read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash". + + 1195| tuple.dst.protonum = IPPROTO_TCP; + 1196| + 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + 1198| if (exp && exp->master == ct) + 1199| return exp; + +Switch this to a C99 initialiser and set the l3num value. + +Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port") +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_h323_main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c +index 14f73872f6477..e35814d68ce30 100644 +--- a/net/netfilter/nf_conntrack_h323_main.c ++++ b/net/netfilter/nf_conntrack_h323_main.c +@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, + { + struct net *net = nf_ct_net(ct); + struct nf_conntrack_expect *exp; +- struct nf_conntrack_tuple tuple; ++ struct nf_conntrack_tuple tuple = { ++ .src.l3num = nf_ct_l3num(ct), ++ .dst.protonum = IPPROTO_TCP, ++ .dst.u.tcp.port = port, ++ }; + +- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); +- tuple.src.u.tcp.port = 0; + memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); +- tuple.dst.u.tcp.port = port; +- tuple.dst.protonum = IPPROTO_TCP; + + exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + if (exp && exp->master == ct) +-- +2.51.0 + diff --git a/queue-6.19/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch b/queue-6.19/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch new file mode 100644 index 0000000000..4134ca3d53 --- /dev/null +++ b/queue-6.19/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch @@ -0,0 +1,54 @@ +From dc2035a560ba3eab1ba1a2c9e9e9b5d7777e2062 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 21:14:40 +0900 +Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain() + +From: Inseo An + +[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ] + +nf_tables_addchain() publishes the chain to table->chains via +list_add_tail_rcu() (in nft_chain_add()) before registering hooks. +If nf_tables_register_hook() then fails, the error path calls +nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy() +with no RCU grace period in between. + +This creates two use-after-free conditions: + + 1) Control-plane: nf_tables_dump_chains() traverses table->chains + under rcu_read_lock(). A concurrent dump can still be walking + the chain when the error path frees it. + + 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly + installs the IPv4 hook before IPv6 registration fails. Packets + entering nft_do_chain() via the transient IPv4 hook can still be + dereferencing chain->blob_gen_X when the error path frees the + chain. + +Add synchronize_rcu() between nft_chain_del() and the chain destroy +so that all RCU readers -- both dump threads and in-flight packet +evaluation -- have finished before the chain is freed. + +Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain") +Signed-off-by: Inseo An +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index f807183235e79..8dae197c7fafb 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2822,6 +2822,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 policy, + + err_register_hook: + nft_chain_del(chain); ++ synchronize_rcu(); + err_chain_add: + nft_trans_destroy(trans); + err_trans: +-- +2.51.0 + diff --git a/queue-6.19/netfilter-nf_tables-revert-commit_mutex-usage-in-res.patch b/queue-6.19/netfilter-nf_tables-revert-commit_mutex-usage-in-res.patch new file mode 100644 index 0000000000..5fbc1401fd --- /dev/null +++ b/queue-6.19/netfilter-nf_tables-revert-commit_mutex-usage-in-res.patch @@ -0,0 +1,424 @@ +From 22620c07e4055d9be237d5edb1cf6d1413a0edc7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 14:26:36 -0600 +Subject: netfilter: nf_tables: revert commit_mutex usage in reset path + +From: Brian Witte + +[ Upstream commit 7f261bb906bf527c4a6e2a646e2d5f3679f2a8bc ] + +It causes circular lock dependency between commit_mutex, nfnl_subsys_ipset +and nlk_cb_mutex when nft reset, ipset list, and iptables-nft with '-m set' +rule run at the same time. + +Previous patches made it safe to run individual reset handlers concurrently +so commit_mutex is no longer required to prevent this. + +Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests") +Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests") +Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests") +Link: https://lore.kernel.org/all/aUh_3mVRV8OrGsVo@strlen.de/ +Reported-by: +Closes: https://syzkaller.appspot.com/bug?extid=ff16b505ec9152e5f448 +Signed-off-by: Brian Witte +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 248 ++++++---------------------------- + 1 file changed, 42 insertions(+), 206 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index daef07ee09427..f807183235e79 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3900,23 +3900,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb, + return skb->len; + } + +-static int nf_tables_dumpreset_rules(struct sk_buff *skb, +- struct netlink_callback *cb) +-{ +- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk)); +- int ret; +- +- /* Mutex is held is to prevent that two concurrent dump-and-reset calls +- * do not underrun counters and quotas. The commit_mutex is used for +- * the lack a better lock, this is not transaction path. +- */ +- mutex_lock(&nft_net->commit_mutex); +- ret = nf_tables_dump_rules(skb, cb); +- mutex_unlock(&nft_net->commit_mutex); +- +- return ret; +-} +- + static int nf_tables_dump_rules_start(struct netlink_callback *cb) + { + struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; +@@ -3936,16 +3919,10 @@ static int nf_tables_dump_rules_start(struct netlink_callback *cb) + return -ENOMEM; + } + } +- return 0; +-} +- +-static int nf_tables_dumpreset_rules_start(struct netlink_callback *cb) +-{ +- struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; +- +- ctx->reset = true; ++ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET) ++ ctx->reset = true; + +- return nf_tables_dump_rules_start(cb); ++ return 0; + } + + static int nf_tables_dump_rules_done(struct netlink_callback *cb) +@@ -4011,6 +3988,8 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, + u32 portid = NETLINK_CB(skb).portid; + struct net *net = info->net; + struct sk_buff *skb2; ++ bool reset = false; ++ char *buf; + + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { + struct netlink_dump_control c = { +@@ -4024,47 +4003,16 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); + } + +- skb2 = nf_tables_getrule_single(portid, info, nla, false); +- if (IS_ERR(skb2)) +- return PTR_ERR(skb2); +- +- return nfnetlink_unicast(skb2, net, portid); +-} +- +-static int nf_tables_getrule_reset(struct sk_buff *skb, +- const struct nfnl_info *info, +- const struct nlattr * const nla[]) +-{ +- struct nftables_pernet *nft_net = nft_pernet(info->net); +- u32 portid = NETLINK_CB(skb).portid; +- struct net *net = info->net; +- struct sk_buff *skb2; +- char *buf; +- +- if (info->nlh->nlmsg_flags & NLM_F_DUMP) { +- struct netlink_dump_control c = { +- .start= nf_tables_dumpreset_rules_start, +- .dump = nf_tables_dumpreset_rules, +- .done = nf_tables_dump_rules_done, +- .module = THIS_MODULE, +- .data = (void *)nla, +- }; +- +- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); +- } +- +- if (!try_module_get(THIS_MODULE)) +- return -EINVAL; +- rcu_read_unlock(); +- mutex_lock(&nft_net->commit_mutex); +- skb2 = nf_tables_getrule_single(portid, info, nla, true); +- mutex_unlock(&nft_net->commit_mutex); +- rcu_read_lock(); +- module_put(THIS_MODULE); ++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET) ++ reset = true; + ++ skb2 = nf_tables_getrule_single(portid, info, nla, reset); + if (IS_ERR(skb2)) + return PTR_ERR(skb2); + ++ if (!reset) ++ return nfnetlink_unicast(skb2, net, portid); ++ + buf = kasprintf(GFP_ATOMIC, "%.*s:%u", + nla_len(nla[NFTA_RULE_TABLE]), + (char *)nla_data(nla[NFTA_RULE_TABLE]), +@@ -6323,6 +6271,10 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) + nla_nest_end(skb, nest); + nlmsg_end(skb, nlh); + ++ if (dump_ctx->reset && args.iter.count > args.iter.skip) ++ audit_log_nft_set_reset(table, cb->seq, ++ args.iter.count - args.iter.skip); ++ + rcu_read_unlock(); + + if (args.iter.err && args.iter.err != -EMSGSIZE) +@@ -6338,26 +6290,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) + return -ENOSPC; + } + +-static int nf_tables_dumpreset_set(struct sk_buff *skb, +- struct netlink_callback *cb) +-{ +- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk)); +- struct nft_set_dump_ctx *dump_ctx = cb->data; +- int ret, skip = cb->args[0]; +- +- mutex_lock(&nft_net->commit_mutex); +- +- ret = nf_tables_dump_set(skb, cb); +- +- if (cb->args[0] > skip) +- audit_log_nft_set_reset(dump_ctx->ctx.table, cb->seq, +- cb->args[0] - skip); +- +- mutex_unlock(&nft_net->commit_mutex); +- +- return ret; +-} +- + static int nf_tables_dump_set_start(struct netlink_callback *cb) + { + struct nft_set_dump_ctx *dump_ctx = cb->data; +@@ -6601,8 +6533,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb, + { + struct netlink_ext_ack *extack = info->extack; + struct nft_set_dump_ctx dump_ctx; ++ int rem, err = 0, nelems = 0; ++ struct net *net = info->net; + struct nlattr *attr; +- int rem, err = 0; ++ bool reset = false; ++ ++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETSETELEM_RESET) ++ reset = true; + + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { + struct netlink_dump_control c = { +@@ -6612,7 +6549,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb, + .module = THIS_MODULE, + }; + +- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false); ++ err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset); + if (err) + return err; + +@@ -6623,75 +6560,21 @@ static int nf_tables_getsetelem(struct sk_buff *skb, + if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS]) + return -EINVAL; + +- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false); ++ err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset); + if (err) + return err; + + nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { +- err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, false); +- if (err < 0) { +- NL_SET_BAD_ATTR(extack, attr); +- break; +- } +- } +- +- return err; +-} +- +-static int nf_tables_getsetelem_reset(struct sk_buff *skb, +- const struct nfnl_info *info, +- const struct nlattr * const nla[]) +-{ +- struct nftables_pernet *nft_net = nft_pernet(info->net); +- struct netlink_ext_ack *extack = info->extack; +- struct nft_set_dump_ctx dump_ctx; +- int rem, err = 0, nelems = 0; +- struct nlattr *attr; +- +- if (info->nlh->nlmsg_flags & NLM_F_DUMP) { +- struct netlink_dump_control c = { +- .start = nf_tables_dump_set_start, +- .dump = nf_tables_dumpreset_set, +- .done = nf_tables_dump_set_done, +- .module = THIS_MODULE, +- }; +- +- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true); +- if (err) +- return err; +- +- c.data = &dump_ctx; +- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); +- } +- +- if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS]) +- return -EINVAL; +- +- if (!try_module_get(THIS_MODULE)) +- return -EINVAL; +- rcu_read_unlock(); +- mutex_lock(&nft_net->commit_mutex); +- rcu_read_lock(); +- +- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true); +- if (err) +- goto out_unlock; +- +- nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { +- err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, true); ++ err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, reset); + if (err < 0) { + NL_SET_BAD_ATTR(extack, attr); + break; + } + nelems++; + } +- audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(info->net), nelems); +- +-out_unlock: +- rcu_read_unlock(); +- mutex_unlock(&nft_net->commit_mutex); +- rcu_read_lock(); +- module_put(THIS_MODULE); ++ if (reset) ++ audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(net), ++ nelems); + + return err; + } +@@ -8562,19 +8445,6 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) + return skb->len; + } + +-static int nf_tables_dumpreset_obj(struct sk_buff *skb, +- struct netlink_callback *cb) +-{ +- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk)); +- int ret; +- +- mutex_lock(&nft_net->commit_mutex); +- ret = nf_tables_dump_obj(skb, cb); +- mutex_unlock(&nft_net->commit_mutex); +- +- return ret; +-} +- + static int nf_tables_dump_obj_start(struct netlink_callback *cb) + { + struct nft_obj_dump_ctx *ctx = (void *)cb->ctx; +@@ -8591,16 +8461,10 @@ static int nf_tables_dump_obj_start(struct netlink_callback *cb) + if (nla[NFTA_OBJ_TYPE]) + ctx->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE])); + +- return 0; +-} +- +-static int nf_tables_dumpreset_obj_start(struct netlink_callback *cb) +-{ +- struct nft_obj_dump_ctx *ctx = (void *)cb->ctx; +- +- ctx->reset = true; ++ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET) ++ ctx->reset = true; + +- return nf_tables_dump_obj_start(cb); ++ return 0; + } + + static int nf_tables_dump_obj_done(struct netlink_callback *cb) +@@ -8662,42 +8526,16 @@ nf_tables_getobj_single(u32 portid, const struct nfnl_info *info, + static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info, + const struct nlattr * const nla[]) + { +- u32 portid = NETLINK_CB(skb).portid; +- struct sk_buff *skb2; +- +- if (info->nlh->nlmsg_flags & NLM_F_DUMP) { +- struct netlink_dump_control c = { +- .start = nf_tables_dump_obj_start, +- .dump = nf_tables_dump_obj, +- .done = nf_tables_dump_obj_done, +- .module = THIS_MODULE, +- .data = (void *)nla, +- }; +- +- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); +- } +- +- skb2 = nf_tables_getobj_single(portid, info, nla, false); +- if (IS_ERR(skb2)) +- return PTR_ERR(skb2); +- +- return nfnetlink_unicast(skb2, info->net, portid); +-} +- +-static int nf_tables_getobj_reset(struct sk_buff *skb, +- const struct nfnl_info *info, +- const struct nlattr * const nla[]) +-{ +- struct nftables_pernet *nft_net = nft_pernet(info->net); + u32 portid = NETLINK_CB(skb).portid; + struct net *net = info->net; + struct sk_buff *skb2; ++ bool reset = false; + char *buf; + + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { + struct netlink_dump_control c = { +- .start = nf_tables_dumpreset_obj_start, +- .dump = nf_tables_dumpreset_obj, ++ .start = nf_tables_dump_obj_start, ++ .dump = nf_tables_dump_obj, + .done = nf_tables_dump_obj_done, + .module = THIS_MODULE, + .data = (void *)nla, +@@ -8706,18 +8544,16 @@ static int nf_tables_getobj_reset(struct sk_buff *skb, + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); + } + +- if (!try_module_get(THIS_MODULE)) +- return -EINVAL; +- rcu_read_unlock(); +- mutex_lock(&nft_net->commit_mutex); +- skb2 = nf_tables_getobj_single(portid, info, nla, true); +- mutex_unlock(&nft_net->commit_mutex); +- rcu_read_lock(); +- module_put(THIS_MODULE); ++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET) ++ reset = true; + ++ skb2 = nf_tables_getobj_single(portid, info, nla, reset); + if (IS_ERR(skb2)) + return PTR_ERR(skb2); + ++ if (!reset) ++ return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid); ++ + buf = kasprintf(GFP_ATOMIC, "%.*s:%u", + nla_len(nla[NFTA_OBJ_TABLE]), + (char *)nla_data(nla[NFTA_OBJ_TABLE]), +@@ -10035,7 +9871,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { + .policy = nft_rule_policy, + }, + [NFT_MSG_GETRULE_RESET] = { +- .call = nf_tables_getrule_reset, ++ .call = nf_tables_getrule, + .type = NFNL_CB_RCU, + .attr_count = NFTA_RULE_MAX, + .policy = nft_rule_policy, +@@ -10089,7 +9925,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { + .policy = nft_set_elem_list_policy, + }, + [NFT_MSG_GETSETELEM_RESET] = { +- .call = nf_tables_getsetelem_reset, ++ .call = nf_tables_getsetelem, + .type = NFNL_CB_RCU, + .attr_count = NFTA_SET_ELEM_LIST_MAX, + .policy = nft_set_elem_list_policy, +@@ -10135,7 +9971,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { + .policy = nft_obj_policy, + }, + [NFT_MSG_GETOBJ_RESET] = { +- .call = nf_tables_getobj_reset, ++ .call = nf_tables_getobj, + .type = NFNL_CB_RCU, + .attr_count = NFTA_OBJ_MAX, + .policy = nft_obj_policy, +-- +2.51.0 + diff --git a/queue-6.19/netfilter-nft_counter-serialize-reset-with-spinlock.patch b/queue-6.19/netfilter-nft_counter-serialize-reset-with-spinlock.patch new file mode 100644 index 0000000000..511f73d7d5 --- /dev/null +++ b/queue-6.19/netfilter-nft_counter-serialize-reset-with-spinlock.patch @@ -0,0 +1,86 @@ +From 5839cc0233f39ee4170ec88e5062dbf952ddbee4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 14:26:37 -0600 +Subject: netfilter: nft_counter: serialize reset with spinlock + +From: Brian Witte + +[ Upstream commit 779c60a5190c42689534172f4b49e927c9959e4e ] + +Add a global static spinlock to serialize counter fetch+reset +operations, preventing concurrent dump-and-reset from underrunning +values. + +The lock is taken before fetching the total so that two parallel +resets cannot both read the same counter values and then both +subtract them. + +A global lock is used for simplicity since resets are infrequent. +If this becomes a bottleneck, it can be replaced with a per-net +lock later. + +Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests") +Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests") +Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests") +Suggested-by: Florian Westphal +Signed-off-by: Brian Witte +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_counter.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c +index 0d70325280cc5..169ae93688bcc 100644 +--- a/net/netfilter/nft_counter.c ++++ b/net/netfilter/nft_counter.c +@@ -32,6 +32,9 @@ struct nft_counter_percpu_priv { + + static DEFINE_PER_CPU(struct u64_stats_sync, nft_counter_sync); + ++/* control plane only: sync fetch+reset */ ++static DEFINE_SPINLOCK(nft_counter_lock); ++ + static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +@@ -148,13 +151,25 @@ static void nft_counter_fetch(struct nft_counter_percpu_priv *priv, + } + } + ++static void nft_counter_fetch_and_reset(struct nft_counter_percpu_priv *priv, ++ struct nft_counter_tot *total) ++{ ++ spin_lock(&nft_counter_lock); ++ nft_counter_fetch(priv, total); ++ nft_counter_reset(priv, total); ++ spin_unlock(&nft_counter_lock); ++} ++ + static int nft_counter_do_dump(struct sk_buff *skb, + struct nft_counter_percpu_priv *priv, + bool reset) + { + struct nft_counter_tot total; + +- nft_counter_fetch(priv, &total); ++ if (unlikely(reset)) ++ nft_counter_fetch_and_reset(priv, &total); ++ else ++ nft_counter_fetch(priv, &total); + + if (nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes), + NFTA_COUNTER_PAD) || +@@ -162,9 +177,6 @@ static int nft_counter_do_dump(struct sk_buff *skb, + NFTA_COUNTER_PAD)) + goto nla_put_failure; + +- if (reset) +- nft_counter_reset(priv, &total); +- + return 0; + + nla_put_failure: +-- +2.51.0 + diff --git a/queue-6.19/netfilter-nft_quota-use-atomic64_xchg-for-reset.patch b/queue-6.19/netfilter-nft_quota-use-atomic64_xchg-for-reset.patch new file mode 100644 index 0000000000..8ecbffc841 --- /dev/null +++ b/queue-6.19/netfilter-nft_quota-use-atomic64_xchg-for-reset.patch @@ -0,0 +1,61 @@ +From 9489b2a10db3829805c9344dace56873d914a00d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 14:26:38 -0600 +Subject: netfilter: nft_quota: use atomic64_xchg for reset + +From: Brian Witte + +[ Upstream commit 30c4d7fb59ac4c8d7fa7937df11eed10b368fa11 ] + +Use atomic64_xchg() to atomically read and zero the consumed value +on reset, which is simpler than the previous read+sub pattern and +doesn't require lock serialization. + +Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests") +Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests") +Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests") +Suggested-by: Pablo Neira Ayuso +Signed-off-by: Brian Witte +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_quota.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c +index df0798da2329b..cb6c0e04ff675 100644 +--- a/net/netfilter/nft_quota.c ++++ b/net/netfilter/nft_quota.c +@@ -140,11 +140,16 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, + u64 consumed, consumed_cap, quota; + u32 flags = priv->flags; + +- /* Since we inconditionally increment consumed quota for each packet ++ /* Since we unconditionally increment consumed quota for each packet + * that we see, don't go over the quota boundary in what we send to + * userspace. + */ +- consumed = atomic64_read(priv->consumed); ++ if (reset) { ++ consumed = atomic64_xchg(priv->consumed, 0); ++ clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags); ++ } else { ++ consumed = atomic64_read(priv->consumed); ++ } + quota = atomic64_read(&priv->quota); + if (consumed >= quota) { + consumed_cap = quota; +@@ -160,10 +165,6 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, + nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags))) + goto nla_put_failure; + +- if (reset) { +- atomic64_sub(consumed, priv->consumed); +- clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags); +- } + return 0; + + nla_put_failure: +-- +2.51.0 + diff --git a/queue-6.19/objpool-fix-the-overestimation-of-object-pooling-met.patch b/queue-6.19/objpool-fix-the-overestimation-of-object-pooling-met.patch new file mode 100644 index 0000000000..cbf836f908 --- /dev/null +++ b/queue-6.19/objpool-fix-the-overestimation-of-object-pooling-met.patch @@ -0,0 +1,47 @@ +From d261cc46e7d42d4a85a45f56a8b0b09a1509769d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 21:28:46 +0800 +Subject: objpool: fix the overestimation of object pooling metadata size + +From: zhouwenhao + +[ Upstream commit 5ed4b6b37c647d168ae31035b3f61b705997e043 ] + +objpool uses struct objpool_head to store metadata information, and its +cpu_slots member points to an array of pointers that store the addresses +of the percpu ring arrays. However, the memory size allocated during the +initialization of cpu_slots is nr_cpu_ids * sizeof(struct objpool_slot). +On a 64-bit machine, the size of struct objpool_slot is 16 bytes, which is +twice the size of the actual pointer required, and the extra memory is +never be used, resulting in a waste of memory. Therefore, the memory size +required for cpu_slots needs to be corrected. + +Link: https://lkml.kernel.org/r/20260202132846.68257-1-zhouwenhao7600@gmail.com +Fixes: b4edb8d2d464 ("lib: objpool added: ring-array based lockless MPMC") +Signed-off-by: zhouwenhao +Reviewed-by: Andrew Morton +Cc: "Masami Hiramatsu (Google)" +Cc: Matt Wu +Cc: wuqiang.matt +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + lib/objpool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/objpool.c b/lib/objpool.c +index b998b720c7329..d98fadf1de169 100644 +--- a/lib/objpool.c ++++ b/lib/objpool.c +@@ -142,7 +142,7 @@ int objpool_init(struct objpool_head *pool, int nr_objs, int object_size, + pool->gfp = gfp & ~__GFP_ZERO; + pool->context = context; + pool->release = release; +- slot_size = nr_cpu_ids * sizeof(struct objpool_slot); ++ slot_size = nr_cpu_ids * sizeof(struct objpool_slot *); + pool->cpu_slots = kzalloc(slot_size, pool->gfp); + if (!pool->cpu_slots) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.19/octeontx2-af-fix-default-entries-mcam-entry-action.patch b/queue-6.19/octeontx2-af-fix-default-entries-mcam-entry-action.patch new file mode 100644 index 0000000000..b77ca39302 --- /dev/null +++ b/queue-6.19/octeontx2-af-fix-default-entries-mcam-entry-action.patch @@ -0,0 +1,85 @@ +From ecf24242b1500171589822cfce1a5ee8248f2f60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:33:38 +0530 +Subject: octeontx2-af: Fix default entries mcam entry action + +From: Hariprasad Kelam + +[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ] + +As per design, AF should update the default MCAM action only when +mcam_index is -1. A bug in the previous patch caused default entries +to be changed even when the request was not for them. + +Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index") +Signed-off-by: Hariprasad Kelam +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++--------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index c7c70429eb6c1..8658cb2143dfc 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -1042,32 +1042,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, + rvu_write64(rvu, blkaddr, + NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action); + +- /* update the VF flow rule action with the VF default entry action */ +- if (mcam_index < 0) +- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, +- *(u64 *)&action); +- + /* update the action change in default rule */ + pfvf = rvu_get_pfvf(rvu, pcifunc); + if (pfvf->def_ucast_rule) + pfvf->def_ucast_rule->rx_action = action; + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_PROMISC_ENTRY); ++ if (mcam_index < 0) { ++ /* update the VF flow rule action with the VF default ++ * entry action ++ */ ++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, ++ *(u64 *)&action); + +- /* If PF's promiscuous entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_PROMISC_ENTRY); + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_ALLMULTI_ENTRY); +- /* If PF's allmulti entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ /* If PF's promiscuous entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_ALLMULTI_ENTRY); ++ /* If PF's allmulti entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ } + } + + void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, +-- +2.51.0 + diff --git a/queue-6.19/ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch b/queue-6.19/ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch new file mode 100644 index 0000000000..35ddf74181 --- /dev/null +++ b/queue-6.19/ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch @@ -0,0 +1,113 @@ +From b6473ab1f0324021e57ca7140a52fa59c7d323db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 18:32:49 +0100 +Subject: ovpn: fix possible use-after-free in ovpn_net_xmit + +From: Ralf Lici + +[ Upstream commit a5ec7baa44ea3a1d6aa0ca31c0ad82edf9affe41 ] + +When building the skb_list in ovpn_net_xmit, skb_share_check will free +the original skb if it is shared. The current implementation continues +to use the stale skb pointer for subsequent operations: +- peer lookup, +- skb_dst_drop (even though all segments produced by skb_gso_segment + will have a dst attached), +- ovpn_peer_stats_increment_tx. + +Fix this by moving the peer lookup and skb_dst_drop before segmentation +so that the original skb is still valid when used. Return early if all +segments fail skb_share_check and the list ends up empty. +Also switch ovpn_peer_stats_increment_tx to use skb_list.next; the next +patch fixes the stats logic. + +Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") +Signed-off-by: Ralf Lici +Reviewed-by: Sabrina Dubroca +Signed-off-by: Antonio Quartulli +Signed-off-by: Sasha Levin +--- + drivers/net/ovpn/io.c | 52 ++++++++++++++++++++++++++----------------- + 1 file changed, 31 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c +index 3e9e7f8444b34..f70c58b10599b 100644 +--- a/drivers/net/ovpn/io.c ++++ b/drivers/net/ovpn/io.c +@@ -365,7 +365,27 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + /* verify IP header size in network packet */ + proto = ovpn_ip_check_protocol(skb); + if (unlikely(!proto || skb->protocol != proto)) +- goto drop; ++ goto drop_no_peer; ++ ++ /* retrieve peer serving the destination IP of this packet */ ++ peer = ovpn_peer_get_by_dst(ovpn, skb); ++ if (unlikely(!peer)) { ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): ++ net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n", ++ netdev_name(ovpn->dev), ++ &ip_hdr(skb)->daddr); ++ break; ++ case htons(ETH_P_IPV6): ++ net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n", ++ netdev_name(ovpn->dev), ++ &ipv6_hdr(skb)->daddr); ++ break; ++ } ++ goto drop_no_peer; ++ } ++ /* dst was needed for peer selection - it can now be dropped */ ++ skb_dst_drop(skb); + + if (skb_is_gso(skb)) { + segments = skb_gso_segment(skb, 0); +@@ -396,34 +416,24 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + + __skb_queue_tail(&skb_list, curr); + } +- skb_list.prev->next = NULL; + +- /* retrieve peer serving the destination IP of this packet */ +- peer = ovpn_peer_get_by_dst(ovpn, skb); +- if (unlikely(!peer)) { +- switch (skb->protocol) { +- case htons(ETH_P_IP): +- net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n", +- netdev_name(ovpn->dev), +- &ip_hdr(skb)->daddr); +- break; +- case htons(ETH_P_IPV6): +- net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n", +- netdev_name(ovpn->dev), +- &ipv6_hdr(skb)->daddr); +- break; +- } +- goto drop; ++ /* no segments survived: don't jump to 'drop' because we already ++ * incremented the counter for each failure in the loop ++ */ ++ if (unlikely(skb_queue_empty(&skb_list))) { ++ ovpn_peer_put(peer); ++ return NETDEV_TX_OK; + } +- /* dst was needed for peer selection - it can now be dropped */ +- skb_dst_drop(skb); ++ skb_list.prev->next = NULL; + +- ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb->len); ++ ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb_list.next->len); + ovpn_send(ovpn, skb_list.next, peer); + + return NETDEV_TX_OK; + + drop: ++ ovpn_peer_put(peer); ++drop_no_peer: + dev_dstats_tx_dropped(ovpn->dev); + skb_tx_error(skb); + kfree_skb_list(skb); +-- +2.51.0 + diff --git a/queue-6.19/ovpn-fix-vpn-tx-bytes-counting.patch b/queue-6.19/ovpn-fix-vpn-tx-bytes-counting.patch new file mode 100644 index 0000000000..7babb6da1b --- /dev/null +++ b/queue-6.19/ovpn-fix-vpn-tx-bytes-counting.patch @@ -0,0 +1,60 @@ +From 400e71dc537e42d3e88e1f13111818754c694ca8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 18:32:50 +0100 +Subject: ovpn: fix VPN TX bytes counting + +From: Ralf Lici + +[ Upstream commit b660b13d4c6379ca6360f24aaef8c5807fefd237 ] + +In ovpn_net_xmit, after GSO segmentation and segment processing, the +first segment on the list is used to increment VPN TX statistics, which +fails to account for any subsequent segments in the chain. + +Fix this by accumulating the length of every segment that successfully +passes skb_share_check into a tx_bytes variable. This ensures the peer +statistics accurately reflect the total data volume sent, regardless of +whether the original packet was segmented. + +Fixes: 04ca14955f9a ("ovpn: store tunnel and transport statistics") +Signed-off-by: Ralf Lici +Reviewed-by: Sabrina Dubroca +Signed-off-by: Antonio Quartulli +Signed-off-by: Sasha Levin +--- + drivers/net/ovpn/io.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c +index f70c58b10599b..955c9a37e1f8d 100644 +--- a/drivers/net/ovpn/io.c ++++ b/drivers/net/ovpn/io.c +@@ -355,6 +355,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + struct ovpn_priv *ovpn = netdev_priv(dev); + struct sk_buff *segments, *curr, *next; + struct sk_buff_head skb_list; ++ unsigned int tx_bytes = 0; + struct ovpn_peer *peer; + __be16 proto; + int ret; +@@ -414,6 +415,8 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + continue; + } + ++ /* only count what we actually send */ ++ tx_bytes += curr->len; + __skb_queue_tail(&skb_list, curr); + } + +@@ -426,7 +429,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) + } + skb_list.prev->next = NULL; + +- ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb_list.next->len); ++ ovpn_peer_stats_increment_tx(&peer->vpn_stats, tx_bytes); + ovpn_send(ovpn, skb_list.next, peer); + + return NETDEV_TX_OK; +-- +2.51.0 + diff --git a/queue-6.19/ovpn-set-sk_user_data-before-overriding-callbacks.patch b/queue-6.19/ovpn-set-sk_user_data-before-overriding-callbacks.patch new file mode 100644 index 0000000000..af56e7f67f --- /dev/null +++ b/queue-6.19/ovpn-set-sk_user_data-before-overriding-callbacks.patch @@ -0,0 +1,155 @@ +From f864c078dd8e643075ec2421b5dbb18b7ab0df85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jan 2026 18:32:48 +0100 +Subject: ovpn: set sk_user_data before overriding callbacks + +From: Ralf Lici + +[ Upstream commit 93686c472eb7b09a51b97a096449e7092fefcd1f ] + +During initialization, we override socket callbacks and set sk_user_data +to an ovpn_socket instance. Currently, these two operations are +decoupled: callbacks are overridden before sk_user_data is set. While +existing callbacks perform safety checks for NULL or non-ovpn +sk_user_data, this condition causes a "half-formed" state where valid +packets arriving during attachment trigger error logs (e.g., "invoked on +non ovpn socket"). + +Set sk_user_data before overriding the callbacks so that it can be +accessed safely from them. Since we already check that the socket has no +sk_user_data before setting it, this remains safe even if an interrupt +accesses the socket after sk_user_data is set but before the callbacks +are overridden. + +This also requires initializing all protocol-specific fields (such as +tcp_tx_work and peer links) before calling ovpn_socket_attach, ensuring +the ovpn_socket is fully formed before it becomes visible to any +callback. + +Fixes: f6226ae7a0cd ("ovpn: introduce the ovpn_socket object") +Signed-off-by: Ralf Lici +Reviewed-by: Sabrina Dubroca +Signed-off-by: Antonio Quartulli +Signed-off-by: Sasha Levin +--- + drivers/net/ovpn/socket.c | 39 +++++++++++++++++++++------------------ + drivers/net/ovpn/tcp.c | 9 +++++++-- + drivers/net/ovpn/udp.c | 1 + + 3 files changed, 29 insertions(+), 20 deletions(-) + +diff --git a/drivers/net/ovpn/socket.c b/drivers/net/ovpn/socket.c +index 9750871ab65ce..448cee3b3f9fa 100644 +--- a/drivers/net/ovpn/socket.c ++++ b/drivers/net/ovpn/socket.c +@@ -200,6 +200,22 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) + ovpn_sock->sk = sk; + kref_init(&ovpn_sock->refcount); + ++ /* TCP sockets are per-peer, therefore they are linked to their unique ++ * peer ++ */ ++ if (sk->sk_protocol == IPPROTO_TCP) { ++ INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work); ++ ovpn_sock->peer = peer; ++ ovpn_peer_hold(peer); ++ } else if (sk->sk_protocol == IPPROTO_UDP) { ++ /* in UDP we only link the ovpn instance since the socket is ++ * shared among multiple peers ++ */ ++ ovpn_sock->ovpn = peer->ovpn; ++ netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker, ++ GFP_KERNEL); ++ } ++ + /* the newly created ovpn_socket is holding reference to sk, + * therefore we increase its refcounter. + * +@@ -212,29 +228,16 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) + + ret = ovpn_socket_attach(ovpn_sock, sock, peer); + if (ret < 0) { ++ if (sk->sk_protocol == IPPROTO_TCP) ++ ovpn_peer_put(peer); ++ else if (sk->sk_protocol == IPPROTO_UDP) ++ netdev_put(peer->ovpn->dev, &ovpn_sock->dev_tracker); ++ + sock_put(sk); + kfree(ovpn_sock); + ovpn_sock = ERR_PTR(ret); +- goto sock_release; +- } +- +- /* TCP sockets are per-peer, therefore they are linked to their unique +- * peer +- */ +- if (sk->sk_protocol == IPPROTO_TCP) { +- INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work); +- ovpn_sock->peer = peer; +- ovpn_peer_hold(peer); +- } else if (sk->sk_protocol == IPPROTO_UDP) { +- /* in UDP we only link the ovpn instance since the socket is +- * shared among multiple peers +- */ +- ovpn_sock->ovpn = peer->ovpn; +- netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker, +- GFP_KERNEL); + } + +- rcu_assign_sk_user_data(sk, ovpn_sock); + sock_release: + release_sock(sk); + return ovpn_sock; +diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c +index 0d7f30360d874..f0b4e07ba9245 100644 +--- a/drivers/net/ovpn/tcp.c ++++ b/drivers/net/ovpn/tcp.c +@@ -487,6 +487,7 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, + /* make sure no pre-existing encapsulation handler exists */ + if (ovpn_sock->sk->sk_user_data) + return -EBUSY; ++ rcu_assign_sk_user_data(ovpn_sock->sk, ovpn_sock); + + /* only a fully connected socket is expected. Connection should be + * handled in userspace +@@ -495,13 +496,14 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, + net_err_ratelimited("%s: provided TCP socket is not in ESTABLISHED state: %d\n", + netdev_name(peer->ovpn->dev), + ovpn_sock->sk->sk_state); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err; + } + + ret = strp_init(&peer->tcp.strp, ovpn_sock->sk, &cb); + if (ret < 0) { + DEBUG_NET_WARN_ON_ONCE(1); +- return ret; ++ goto err; + } + + INIT_WORK(&peer->tcp.defer_del_work, ovpn_tcp_peer_del_work); +@@ -536,6 +538,9 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, + strp_check_rcv(&peer->tcp.strp); + + return 0; ++err: ++ rcu_assign_sk_user_data(ovpn_sock->sk, NULL); ++ return ret; + } + + static void ovpn_tcp_close(struct sock *sk, long timeout) +diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c +index d6a0f7a0b75d7..272b535ecaad4 100644 +--- a/drivers/net/ovpn/udp.c ++++ b/drivers/net/ovpn/udp.c +@@ -386,6 +386,7 @@ int ovpn_udp_socket_attach(struct ovpn_socket *ovpn_sock, struct socket *sock, + struct ovpn_priv *ovpn) + { + struct udp_tunnel_sock_cfg cfg = { ++ .sk_user_data = ovpn_sock, + .encap_type = UDP_ENCAP_OVPNINUDP, + .encap_rcv = ovpn_udp_encap_recv, + .encap_destroy = ovpn_udp_encap_destroy, +-- +2.51.0 + diff --git a/queue-6.19/ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch b/queue-6.19/ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch new file mode 100644 index 0000000000..effc391556 --- /dev/null +++ b/queue-6.19/ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch @@ -0,0 +1,78 @@ +From f5f52610fc9ce71e30c47e50794616215653ea29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:31:19 +0100 +Subject: ovpn: tcp - don't deref NULL sk_socket member after tcp_close() + +From: Antonio Quartulli + +[ Upstream commit 94560267d6c41b1ff3fafbab726e3f8a55a6af34 ] + +When deleting a peer in case of keepalive expiration, the peer is +removed from the OpenVPN hashtable and is temporary inserted in a +"release list" for further processing. + +This happens in: +ovpn_peer_keepalive_work() + unlock_ovpn(release_list) + +This processing includes detaching from the socket being used to +talk to this peer, by restoring its original proto and socket +ops/callbacks. + +In case of TCP it may happen that, while the peer is sitting in +the release list, userspace decides to close the socket. +This will result in a concurrent execution of: + +tcp_close(sk) + __tcp_close(sk) + sock_orphan(sk) + sk_set_socket(sk, NULL) + +The last function call will set sk->sk_socket to NULL. + +When the releasing routine is resumed, ovpn_tcp_socket_detach() +will attempt to dereference sk->sk_socket to restore its original +ops member. This operation will crash due to sk->sk_socket being NULL. + +Fix this race condition by testing-and-accessing +sk->sk_socket atomically under sk->sk_callback_lock. + +Link: https://lore.kernel.org/netdev/176996279620.3109699.15382994681575380467@eldamar.lan/ +Link: https://github.com/OpenVPN/ovpn-net-next/issues/29 +Signed-off-by: Antonio Quartulli +Fixes: 11851cbd60ea ("ovpn: implement TCP transport") +Link: https://patch.msgid.link/20260212213130.11497-1-antonio@openvpn.net +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ovpn/tcp.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c +index f0b4e07ba9245..ec2bbc28c1966 100644 +--- a/drivers/net/ovpn/tcp.c ++++ b/drivers/net/ovpn/tcp.c +@@ -199,7 +199,19 @@ void ovpn_tcp_socket_detach(struct ovpn_socket *ovpn_sock) + sk->sk_data_ready = peer->tcp.sk_cb.sk_data_ready; + sk->sk_write_space = peer->tcp.sk_cb.sk_write_space; + sk->sk_prot = peer->tcp.sk_cb.prot; +- sk->sk_socket->ops = peer->tcp.sk_cb.ops; ++ ++ /* tcp_close() may race this function and could set ++ * sk->sk_socket to NULL. It does so by invoking ++ * sock_orphan(), which holds sk_callback_lock before ++ * doing the assignment. ++ * ++ * For this reason we acquire the same lock to avoid ++ * sk_socket to disappear under our feet ++ */ ++ write_lock_bh(&sk->sk_callback_lock); ++ if (sk->sk_socket) ++ sk->sk_socket->ops = peer->tcp.sk_cb.ops; ++ write_unlock_bh(&sk->sk_callback_lock); + + rcu_assign_sk_user_data(sk, NULL); + } +-- +2.51.0 + diff --git a/queue-6.19/pci-dwc-ep-always-clear-ib-maps-on-bar-update.patch b/queue-6.19/pci-dwc-ep-always-clear-ib-maps-on-bar-update.patch new file mode 100644 index 0000000000..55851a1f41 --- /dev/null +++ b/queue-6.19/pci-dwc-ep-always-clear-ib-maps-on-bar-update.patch @@ -0,0 +1,82 @@ +From 113694fb3a282b06e5ea7b58c61535612e45228f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 23:54:07 +0900 +Subject: PCI: dwc: ep: Always clear IB maps on BAR update + +From: Koichiro Den + +[ Upstream commit 8c746e22096579897d1f8f74dbb6b17a6862fb6d ] + +dw_pcie_ep_set_bar() currently tears down existing inbound mappings only +when either the previous or the new struct pci_epf_bar uses submaps +(num_submap != 0). If both the old and new mappings are BAR Match Mode, +reprogramming the same ATU index is sufficient, so no explicit teardown +was needed. + +However, some callers may reuse the same struct pci_epf_bar instance and +update it in place before calling set_bar() again. In that case +ep_func->epf_bar[bar] and the passed-in epf_bar can point to the same +object, so we cannot reliably distinguish BAR Match Mode -> BAR Match Mode +from Address Match Mode -> BAR Match Mode. As a result, the conditional +teardown based on num_submap becomes unreliable and existing inbound maps +may be left active. + +Call dw_pcie_ep_clear_ib_maps() unconditionally before reprogramming the +BAR so that in-place updates are handled correctly. + +This introduces a behavioral change in a corner case: if a BAR +reprogramming attempt fails (especially for the long-standing BAR Match +Mode -> BAR Match Mode update case), the previously programmed inbound +mapping will already have been torn down. This should be acceptable, since +the caller observes the error and should not use the BAR for any real +transactions in that case. + +While at it, document that the existing update parameter check is +best-effort for in-place updates. + +Fixes: cc839bef7727 ("PCI: dwc: ep: Support BAR subrange inbound mapping via Address Match Mode iATU") +Signed-off-by: Koichiro Den +Signed-off-by: Bjorn Helgaas +Reviewed-by: Niklas Cassel +Link: https://patch.msgid.link/20260202145407.503348-3-den@valinux.co.jp +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware-ep.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c +index 6d3c35dd280f3..59fd6ebf01489 100644 +--- a/drivers/pci/controller/dwc/pcie-designware-ep.c ++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c +@@ -518,6 +518,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, + /* + * We can only dynamically change a BAR if the new BAR size and + * BAR flags do not differ from the existing configuration. ++ * ++ * Note: this safety check only works when the caller uses ++ * a new struct pci_epf_bar in the second set_bar() call. ++ * If the same instance is updated in place and passed in, ++ * we cannot reliably detect invalid barno/size/flags ++ * changes here. + */ + if (ep_func->epf_bar[bar]->barno != bar || + ep_func->epf_bar[bar]->size != size || +@@ -526,10 +532,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, + + /* + * When dynamically changing a BAR, tear down any existing +- * mappings before re-programming. ++ * mappings before re-programming. This is redundant when ++ * both the old and new mappings are BAR Match Mode, but ++ * required to handle in-place updates and match-mode ++ * changes reliably. + */ +- if (ep_func->epf_bar[bar]->num_submap || epf_bar->num_submap) +- dw_pcie_ep_clear_ib_maps(ep, func_no, bar); ++ dw_pcie_ep_clear_ib_maps(ep, func_no, bar); + + /* + * When dynamically changing a BAR, skip writing the BAR reg, as +-- +2.51.0 + diff --git a/queue-6.19/pci-validate-window-resource-type-in-pbus_select_win.patch b/queue-6.19/pci-validate-window-resource-type-in-pbus_select_win.patch new file mode 100644 index 0000000000..433f2fb8c9 --- /dev/null +++ b/queue-6.19/pci-validate-window-resource-type-in-pbus_select_win.patch @@ -0,0 +1,70 @@ +From 766b9730aa9fcb41bc00a0b1ad18799ab728a7bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 22:20:57 +0800 +Subject: PCI: Validate window resource type in pbus_select_window_for_type() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kai-Heng Feng + +[ Upstream commit e5f72cb9cea599dc9f5a9b80a33560a1d06f01cc ] + +After ebe091ad81e1 ("PCI: Use pbus_select_window_for_type() during IO +window sizing") and ae88d0b9c57f ("PCI: Use pbus_select_window_for_type() +during mem window sizing"), many bridge windows can't get resources +assigned: + + pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: can't assign; no space + pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: failed to assign + +Those commits replace find_bus_resource_of_type() with +pbus_select_window_for_type(), and the latter lacks resource type +validation. + +Add the resource type validation back to pbus_select_window_for_type() to +match the original behavior. + +Fixes: 74afce3dfcba ("PCI: Add bridge window selection functions") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=221072 +Signed-off-by: Kai-Heng Feng +Signed-off-by: Bjorn Helgaas +Reviewed-by: Ilpo Järvinen +Link: https://patch.msgid.link/20260210142058.82701-1-kaihengf@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/pci/setup-bus.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c +index 902fdae73c232..09a28cfcd5b88 100644 +--- a/drivers/pci/setup-bus.c ++++ b/drivers/pci/setup-bus.c +@@ -225,14 +225,21 @@ static struct resource *pbus_select_window_for_type(struct pci_bus *bus, + + switch (iores_type) { + case IORESOURCE_IO: +- return pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); ++ win = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); ++ if (win && (win->flags & IORESOURCE_IO)) ++ return win; ++ return NULL; + + case IORESOURCE_MEM: + mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW); + mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW); + +- if (!(type & IORESOURCE_PREFETCH) || +- !(mmio_pref->flags & IORESOURCE_MEM)) ++ if (mmio && !(mmio->flags & IORESOURCE_MEM)) ++ mmio = NULL; ++ if (mmio_pref && !(mmio_pref->flags & IORESOURCE_MEM)) ++ mmio_pref = NULL; ++ ++ if (!(type & IORESOURCE_PREFETCH) || !mmio_pref) + return mmio; + + if ((type & IORESOURCE_MEM_64) || +-- +2.51.0 + diff --git a/queue-6.19/ping-annotate-data-races-in-ping_lookup.patch b/queue-6.19/ping-annotate-data-races-in-ping_lookup.patch new file mode 100644 index 0000000000..47d629a6c4 --- /dev/null +++ b/queue-6.19/ping-annotate-data-races-in-ping_lookup.patch @@ -0,0 +1,118 @@ +From 60075b54f79c6aca4b5816f6aeffc2ab3a8851c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:01:49 +0000 +Subject: ping: annotate data-races in ping_lookup() + +From: Eric Dumazet + +[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ] + +isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if +are read locklessly in ping_lookup(). + +Add READ_ONCE()/WRITE_ONCE() annotations. + +The race on isk->inet_rcv_saddr is probably coming from IPv6 support, +but does not deserve a specific backport. + +Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/ping.c | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index cfbd563498e85..0fec4e5645667 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -148,7 +148,7 @@ void ping_unhash(struct sock *sk) + pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); + spin_lock(&ping_table.lock); + if (sk_del_node_init_rcu(sk)) { +- isk->inet_num = 0; ++ WRITE_ONCE(isk->inet_num, 0); + isk->inet_sport = 0; + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + } +@@ -181,31 +181,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + } + + sk_for_each_rcu(sk, hslot) { ++ int bound_dev_if; ++ + if (!net_eq(sock_net(sk), net)) + continue; + isk = inet_sk(sk); + + pr_debug("iterate\n"); +- if (isk->inet_num != ident) ++ if (READ_ONCE(isk->inet_num) != ident) + continue; + ++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); + if (skb->protocol == htons(ETH_P_IP) && + sk->sk_family == AF_INET) { ++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr); ++ + pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk, +- (int) isk->inet_num, &isk->inet_rcv_saddr, +- sk->sk_bound_dev_if); ++ ident, &rcv_saddr, ++ bound_dev_if); + +- if (isk->inet_rcv_saddr && +- isk->inet_rcv_saddr != ip_hdr(skb)->daddr) ++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr) + continue; + #if IS_ENABLED(CONFIG_IPV6) + } else if (skb->protocol == htons(ETH_P_IPV6) && + sk->sk_family == AF_INET6) { + + pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk, +- (int) isk->inet_num, ++ ident, + &sk->sk_v6_rcv_saddr, +- sk->sk_bound_dev_if); ++ bound_dev_if); + + if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && + !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, +@@ -216,8 +220,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + continue; + } + +- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && +- sk->sk_bound_dev_if != sdif) ++ if (bound_dev_if && bound_dev_if != dif && ++ bound_dev_if != sdif) + continue; + + goto exit; +@@ -392,7 +396,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr_unsized *saddr) + if (saddr->sa_family == AF_INET) { + struct inet_sock *isk = inet_sk(sk); + struct sockaddr_in *addr = (struct sockaddr_in *) saddr; +- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr; ++ ++ isk->inet_saddr = addr->sin_addr.s_addr; ++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr); + #if IS_ENABLED(CONFIG_IPV6) + } else if (saddr->sa_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr; +@@ -849,7 +855,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, + struct sk_buff *skb; + int copied, err; + +- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); ++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, ++ READ_ONCE(isk->inet_num)); + + err = -EOPNOTSUPP; + if (flags & MSG_OOB) +-- +2.51.0 + diff --git a/queue-6.19/powercap-intel_rapl-remove-incorrect-cpu-check-in-pm.patch b/queue-6.19/powercap-intel_rapl-remove-incorrect-cpu-check-in-pm.patch new file mode 100644 index 0000000000..6bf106007b --- /dev/null +++ b/queue-6.19/powercap-intel_rapl-remove-incorrect-cpu-check-in-pm.patch @@ -0,0 +1,119 @@ +From a35cd3f77ee236f3e22335638dbab151f1a69461 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 15:43:09 -0800 +Subject: powercap: intel_rapl: Remove incorrect CPU check in PMU context + +From: Kuppuswamy Sathyanarayanan + +[ Upstream commit 7537bae8b6eb635583e0e6260f61d13ddbd52087 ] + +The RAPL MSR read path incorrectly validates CPU context when called +from the PMU subsystem: + + if (atomic) { + if (unlikely(smp_processor_id() != cpu)) + return -EIO; + rdmsrq(ra->reg.msr, ra->value); + } + +This check fails for package-scoped MSRs like RAPL energy counters, +which are readable from any CPU within the package. + +The perf tool avoids hitting this check by validating against +/sys/bus/event_source/devices/power/cpumask before opening events. +However, turbostat does not perform this validation and may attempt +reads from non-lead CPUs, causing the check to fail and return zero +power values. + +Since package-scoped MSRs are architecturally accessible from any CPU +in the package, remove the CPU matching check. + +Also rename 'atomic' to 'pmu_ctx' to clarify this indicates PMU context +where rdmsrq() can be used directly instead of rdmsrl_safe_on_cpu(). + +Fixes: 748d6ba43afd ("powercap: intel_rapl: Enable MSR-based RAPL PMU support") +Signed-off-by: Kuppuswamy Sathyanarayanan +Tested-by: Furquim Ulisses +Reviewed-by: Srinivas Pandruvada +Link: https://patch.msgid.link/20260209234310.1440722-2-sathyanarayanan.kuppuswamy@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/intel_rapl_common.c | 6 +++--- + drivers/powercap/intel_rapl_msr.c | 12 +++++------- + include/linux/intel_rapl.h | 2 +- + 3 files changed, 9 insertions(+), 11 deletions(-) + +diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c +index 3ff6da3bf4e63..3705d0608a0fb 100644 +--- a/drivers/powercap/intel_rapl_common.c ++++ b/drivers/powercap/intel_rapl_common.c +@@ -254,7 +254,7 @@ static void rapl_init_domains(struct rapl_package *rp); + static int rapl_read_data_raw(struct rapl_domain *rd, + enum rapl_primitives prim, + bool xlate, u64 *data, +- bool atomic); ++ bool pmu_ctx); + static int rapl_write_data_raw(struct rapl_domain *rd, + enum rapl_primitives prim, + unsigned long long value); +@@ -832,7 +832,7 @@ prim_fixups(struct rapl_domain *rd, enum rapl_primitives prim) + */ + static int rapl_read_data_raw(struct rapl_domain *rd, + enum rapl_primitives prim, bool xlate, u64 *data, +- bool atomic) ++ bool pmu_ctx) + { + u64 value; + enum rapl_primitives prim_fixed = prim_fixups(rd, prim); +@@ -854,7 +854,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd, + + ra.mask = rpi->mask; + +- if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, atomic)) { ++ if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, pmu_ctx)) { + pr_debug("failed to read reg 0x%llx for %s:%s\n", ra.reg.val, rd->rp->name, rd->name); + return -EIO; + } +diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c +index 9a7e150b3536b..152893dca5653 100644 +--- a/drivers/powercap/intel_rapl_msr.c ++++ b/drivers/powercap/intel_rapl_msr.c +@@ -110,16 +110,14 @@ static int rapl_cpu_down_prep(unsigned int cpu) + return 0; + } + +-static int rapl_msr_read_raw(int cpu, struct reg_action *ra, bool atomic) ++static int rapl_msr_read_raw(int cpu, struct reg_action *ra, bool pmu_ctx) + { + /* +- * When called from atomic-context (eg PMU event handler) +- * perform MSR read directly using rdmsrq(). ++ * When called from PMU context, perform MSR read directly using ++ * rdmsrq() without IPI overhead. Package-scoped MSRs are readable ++ * from any CPU in the package. + */ +- if (atomic) { +- if (unlikely(smp_processor_id() != cpu)) +- return -EIO; +- ++ if (pmu_ctx) { + rdmsrq(ra->reg.msr, ra->value); + goto out; + } +diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h +index f479ef5b3341c..fa1f328d67120 100644 +--- a/include/linux/intel_rapl.h ++++ b/include/linux/intel_rapl.h +@@ -152,7 +152,7 @@ struct rapl_if_priv { + union rapl_reg reg_unit; + union rapl_reg regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; + int limits[RAPL_DOMAIN_MAX]; +- int (*read_raw)(int id, struct reg_action *ra, bool atomic); ++ int (*read_raw)(int id, struct reg_action *ra, bool pmu_ctx); + int (*write_raw)(int id, struct reg_action *ra); + void *defaults; + void *rpi; +-- +2.51.0 + diff --git a/queue-6.19/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch b/queue-6.19/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch new file mode 100644 index 0000000000..8d98f12116 --- /dev/null +++ b/queue-6.19/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch @@ -0,0 +1,49 @@ +From e7545381464ebd49da70e9d12c4c97cd09becdad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 14:34:01 -0800 +Subject: powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check + +From: Kuppuswamy Sathyanarayanan + +[ Upstream commit c7d54dafa042cf379859dba265fe5afef6fa8770 ] + +On partitioned systems, multiple TPMI instances may exist per package, +but RAPL registers are only valid on one instance since RAPL has +package-scope control. Other instances return invalid versions during +domain parsing, which is expected behavior on such systems. + +Currently this generates a firmware bug warning: + + intel_rapl_tpmi: [Firmware Bug]: Invalid version + +Remove the FW_BUG tag, downgrade to pr_debug(), and update the message +to clarify that invalid versions are expected on partitioned systems +where only one instance can be valid. + +Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver") +Reported-by: Zhang Rui +Signed-off-by: Kuppuswamy Sathyanarayanan +Reviewed-by: Srinivas Pandruvada +Link: https://patch.msgid.link/20260211223401.1575776-1-sathyanarayanan.kuppuswamy@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/intel_rapl_tpmi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c +index 0a0b85f4528b1..0f8abdc592bc1 100644 +--- a/drivers/powercap/intel_rapl_tpmi.c ++++ b/drivers/powercap/intel_rapl_tpmi.c +@@ -157,7 +157,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) + tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; + + if (tpmi_domain_version == TPMI_VERSION_INVALID) { +- pr_warn(FW_BUG "Invalid version\n"); ++ pr_debug("Invalid version, other instances may be valid\n"); + return -ENODEV; + } + +-- +2.51.0 + diff --git a/queue-6.19/regulator-mt6363-fix-interrmittent-timeout.patch b/queue-6.19/regulator-mt6363-fix-interrmittent-timeout.patch new file mode 100644 index 0000000000..6ce063c765 --- /dev/null +++ b/queue-6.19/regulator-mt6363-fix-interrmittent-timeout.patch @@ -0,0 +1,52 @@ +From b626cebd592eda9eb476a4b82eef4c3590ff8693 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 23:37:04 -0600 +Subject: regulator: mt6363: Fix interrmittent timeout + +From: Adam Ford + +[ Upstream commit 1a4b0c999101b2532723f9bd9818b70ffa7580f4 ] + +Sometimes, the mt6363 regulator would fail to initialize and return with +a TIMEOUT error, so add an extra instruction to wake up the bus before +issuing the commands. + +Fixes: 3c36965df808 ("regulator: Add support for MediaTek MT6363 SPMI PMIC Regulators") +Signed-off-by: Adam Ford +Link: https://patch.msgid.link/20260210053708.17239-4-aford173@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/mt6363-regulator.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/regulator/mt6363-regulator.c b/drivers/regulator/mt6363-regulator.c +index e0fbf92e76851..03af5fa536007 100644 +--- a/drivers/regulator/mt6363-regulator.c ++++ b/drivers/regulator/mt6363-regulator.c +@@ -861,7 +861,7 @@ static int mt6363_regulator_probe(struct platform_device *pdev) + struct irq_domain *domain; + struct irq_fwspec fwspec; + struct spmi_device *sdev; +- int i, ret; ++ int i, ret, val; + + config.regmap = mt6363_spmi_register_regmap(dev); + if (IS_ERR(config.regmap)) +@@ -870,6 +870,13 @@ static int mt6363_regulator_probe(struct platform_device *pdev) + config.dev = dev; + sdev = to_spmi_device(dev->parent); + ++ /* ++ * The first read may fail if the bootloader sets sleep mode: wake up ++ * this PMIC with W/R on the SPMI bus and ignore the first result. ++ * This matches the MT6373 driver behavior. ++ */ ++ regmap_read(config.regmap, MT6363_TOP_TRAP, &val); ++ + interrupt_parent = of_irq_find_parent(dev->of_node); + if (!interrupt_parent) + return dev_err_probe(dev, -EINVAL, "Cannot find IRQ parent\n"); +-- +2.51.0 + diff --git a/queue-6.19/s390-kexec-make-kexec_sig-available-when-config_modu.patch b/queue-6.19/s390-kexec-make-kexec_sig-available-when-config_modu.patch new file mode 100644 index 0000000000..9c2e96641d --- /dev/null +++ b/queue-6.19/s390-kexec-make-kexec_sig-available-when-config_modu.patch @@ -0,0 +1,61 @@ +From 335e23a0b9d1e1ba17548158f50e566448859464 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 07:29:16 +0100 +Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n + +From: Alexander Egorenkov + +[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ] + +The commit c8424e776b09 ("MODSIGN: Export module signature definitions") +replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the +dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390 +kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT. + +Furthermore, the signature verification in s390 kexec does not require +MODULE_SIG_FORMAT because it requires only the struct module_signature and, +therefore, does not depend on code in kernel/module_signature.c. + +But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is +also incorrect because it makes KEXEC_SIG available on s390 only if some +other arbitrary option (for instance a file system or device driver) +selects it directly or indirectly. + +To properly make KEXEC_SIG available for s390 kernels built with MODULES=y +as well as MODULES=n _and_ also not depend on arbitrary options selecting +SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select +SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y. + +Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions") +Suggested-by: Heiko Carstens +Signed-off-by: Alexander Egorenkov +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index 0e5fad5f06ca1..783be50f38f2b 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -275,6 +275,7 @@ config S390 + select SPARSE_IRQ + select SWIOTLB + select SYSCTL_EXCEPTION_TRACE ++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG + select THREAD_INFO_IN_TASK + select TRACE_IRQFLAGS_SUPPORT + select TTY +@@ -301,7 +302,7 @@ config ARCH_SUPPORTS_KEXEC_FILE + def_bool y + + config ARCH_SUPPORTS_KEXEC_SIG +- def_bool MODULE_SIG_FORMAT ++ def_bool y + + config ARCH_SUPPORTS_KEXEC_PURGATORY + def_bool y +-- +2.51.0 + diff --git a/queue-6.19/selftests-forwarding-fix-pedit-tests-failure-with-br.patch b/queue-6.19/selftests-forwarding-fix-pedit-tests-failure-with-br.patch new file mode 100644 index 0000000000..5fa338c75b --- /dev/null +++ b/queue-6.19/selftests-forwarding-fix-pedit-tests-failure-with-br.patch @@ -0,0 +1,86 @@ +From e4d85c9e23570a6255e1d75aa2ab8285c3fd61e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:07 +0000 +Subject: selftests: forwarding: fix pedit tests failure with br_netfilter + enabled + +From: Aleksei Oladko + +[ Upstream commit a8c198d16c64cdf57f481a4cd3e769502802369e ] + +The tests use the tc pedit action to modify the IPv4 source address +("pedit ex munge ip src set"), but the IP header checksum is not +recalculated after the modification. As a result, the modified packet +fails sanity checks in br_netfilter after bridging and is dropped, +which causes the test to fail. + +Fix this by ensuring net.bridge.bridge-nf-call-iptables is set to 0 +during the test execution. This prevents the bridge from passing +L2 traffic to netfilter, bypassing the checksum validation that +causes the test failure. + +Fixes: 92ad3828944e ("selftests: forwarding: Add a test for pedit munge SIP and DIP") +Fixes: 226657ba2389 ("selftests: forwarding: Add a forwarding test for pedit munge dsfield") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-4-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/pedit_dsfield.sh | 8 ++++++++ + tools/testing/selftests/net/forwarding/pedit_ip.sh | 8 ++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/tools/testing/selftests/net/forwarding/pedit_dsfield.sh b/tools/testing/selftests/net/forwarding/pedit_dsfield.sh +index af008fbf2725e..eb2d8034de9c7 100755 +--- a/tools/testing/selftests/net/forwarding/pedit_dsfield.sh ++++ b/tools/testing/selftests/net/forwarding/pedit_dsfield.sh +@@ -98,12 +98,20 @@ setup_prepare() + h1_create + h2_create + switch_create ++ ++ if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then ++ sysctl_set net.bridge.bridge-nf-call-iptables 0 ++ fi + } + + cleanup() + { + pre_cleanup + ++ if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then ++ sysctl_restore net.bridge.bridge-nf-call-iptables ++ fi ++ + switch_destroy + h2_destroy + h1_destroy +diff --git a/tools/testing/selftests/net/forwarding/pedit_ip.sh b/tools/testing/selftests/net/forwarding/pedit_ip.sh +index d14efb2d23b2e..9235674627abd 100755 +--- a/tools/testing/selftests/net/forwarding/pedit_ip.sh ++++ b/tools/testing/selftests/net/forwarding/pedit_ip.sh +@@ -91,12 +91,20 @@ setup_prepare() + h1_create + h2_create + switch_create ++ ++ if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then ++ sysctl_set net.bridge.bridge-nf-call-iptables 0 ++ fi + } + + cleanup() + { + pre_cleanup + ++ if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then ++ sysctl_restore net.bridge.bridge-nf-call-iptables ++ fi ++ + switch_destroy + h2_destroy + h1_destroy +-- +2.51.0 + diff --git a/queue-6.19/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch b/queue-6.19/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch new file mode 100644 index 0000000000..6e866bc278 --- /dev/null +++ b/queue-6.19/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch @@ -0,0 +1,78 @@ +From eb4e8f11e531c95486cae258b4d9c476ab37c9ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:05 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with + br_netfilter enabled + +From: Aleksei Oladko + +[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv4 packet contains a zero IP header checksum. After VXLAN +decapsulation, such packets do not pass sanity checks in br_netfilter +and are dropped, which causes the test to fail. + +Fix this by calculating and setting a valid IPv4 header checksum for the +encapsulated packet generated by mausezahn, so that the packet is accepted +by br_netfilter. Fixed by using the payload_template_calc_checksum() / +payload_template_expand_checksum() helpers that are only available +in v6.3 and newer kernels. + +Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index b43816dd998ca..457f41d5e584b 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -567,6 +567,21 @@ vxlan_encapped_ping_do() + local inner_tos=$1; shift + local outer_tos=$1; shift + ++ local ipv4hdr=$(: ++ )"45:"$( : IP version + IHL ++ )"$inner_tos:"$( : IP TOS ++ )"00:54:"$( : IP total length ++ )"99:83:"$( : IP identification ++ )"40:00:"$( : IP flags + frag off ++ )"40:"$( : IP TTL ++ )"01:"$( : IP proto ++ )"CHECKSUM:"$( : IP header csum ++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 ++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1 ++ ) ++ local checksum=$(payload_template_calc_checksum "$ipv4hdr") ++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum) ++ + $MZ $dev -c $count -d 100msec -q \ + -b $next_hop_mac -B $dest_ip \ + -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(: +@@ -577,16 +592,7 @@ vxlan_encapped_ping_do() + )"$dest_mac:"$( : ETH daddr + )"$(mac_get w2):"$( : ETH saddr + )"08:00:"$( : ETH type +- )"45:"$( : IP version + IHL +- )"$inner_tos:"$( : IP TOS +- )"00:54:"$( : IP total length +- )"99:83:"$( : IP identification +- )"40:00:"$( : IP flags + frag off +- )"40:"$( : IP TTL +- )"01:"$( : IP proto +- )"00:00:"$( : IP header csum +- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 +- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 ++ )"$ipv4hdr:"$( : IPv4 header + )"08:"$( : ICMP type + )"00:"$( : ICMP code + )"8b:f2:"$( : ICMP csum +-- +2.51.0 + diff --git a/queue-6.19/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch b/queue-6.19/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch new file mode 100644 index 0000000000..b12bad0fc0 --- /dev/null +++ b/queue-6.19/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch @@ -0,0 +1,69 @@ +From 50b5b2278c7f8f3f7c16af7a857a086f299a71d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:06 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with + br_netfilter enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Aleksei Oladko + +[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv6 packet has an incorrect payload length set in the IPv6 header. +After VXLAN decapsulation, such packets do not pass sanity checks in +br_netfilter and are dropped, which causes the test to fail. + +Fix this by setting the correct IPv6 payload length for the encapsulated +packet generated by mausezahn, so that the packet is accepted +by br_netfilter. + +tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +lines 698-706 + + )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + )"80:"$( : ICMPv6.type + )"00:"$( : ICMPv6.code + )"00:"$( : ICMPv6.checksum + ) + +Data after IPv6 header: +• 80: — 1 byte (ICMPv6 type) +• 00: — 1 byte (ICMPv6 code) +• 00: — 1 byte (ICMPv6 checksum, truncated) + +Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match +the actual payload size. + +Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +index a603f7b0a08f0..e642feeada0e7 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +@@ -695,7 +695,7 @@ vxlan_encapped_ping_do() + )"6"$( : IP version + )"$inner_tos"$( : Traffic class + )"0:00:00:"$( : Flow label +- )"00:08:"$( : Payload length ++ )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr +-- +2.51.0 + diff --git a/queue-6.19/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch b/queue-6.19/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch new file mode 100644 index 0000000000..1f37fe604d --- /dev/null +++ b/queue-6.19/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch @@ -0,0 +1,241 @@ +From 37cf61e710eeb0369586c7c0e23e068d504dbab5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 09:38:05 -0500 +Subject: selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT + +From: Aristeu Rozanski + +[ Upstream commit b24335521de92fd2ee22460072b75367ca8860b0 ] + +selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT + +In order to synchronize new processes to test inheritance of memfd_noexec +sysctl, memfd_test sets up the sysctl with a value before creating the new +process. The new process then sends itself a SIGSTOP in order to wait for +the parent to flip the sysctl value and send a SIGCONT signal. + +This would work as intended if it wasn't the fact that the new process is +being created with CLONE_NEWPID, which creates a new PID namespace and the +new process has PID 1 in this namespace. There're restrictions on sending +signals to PID 1 and, although it's relaxed for other than root PID +namespace, it's biting us here. In this specific case the SIGSTOP sent by +the new process is ignored (no error to kill() is returned) and it never +stops its execution. This is usually not noticiable as the parent usually +manages to set the new sysctl value before the child has a chance to run +and the test succeeds. But if you run the test in a loop, it eventually +reproduces: + + while [ 1 ]; do ./memfd_test >log 2>&1 || break; done; cat log + +So this patch replaces the SIGSTOP/SIGCONT synchronization with IPC +semaphore. + +Link: https://lkml.kernel.org/r/a7776389-b3d6-4b18-b438-0b0e3ed1fd3b@work +Fixes: 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests") +Signed-off-by: Aristeu Rozanski +Cc: Aleksa Sarai +Cc: Shuah Khan +Cc: liuye +Cc: Lorenzo Stoakes +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/memfd/memfd_test.c | 113 +++++++++++++++++++-- + 1 file changed, 105 insertions(+), 8 deletions(-) + +diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c +index 5b993924cc3f5..2ca07ea7202a5 100644 +--- a/tools/testing/selftests/memfd/memfd_test.c ++++ b/tools/testing/selftests/memfd/memfd_test.c +@@ -18,6 +18,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + +@@ -39,6 +42,20 @@ + F_SEAL_EXEC) + + #define MFD_NOEXEC_SEAL 0x0008U ++union semun { ++ int val; ++ struct semid_ds *buf; ++ unsigned short int *array; ++ struct seminfo *__buf; ++}; ++ ++/* ++ * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the ++ * child will be PID 1 and can't send SIGSTOP to themselves due special ++ * treatment of the init task, so the SIGSTOP/SIGCONT synchronization ++ * approach can't be used here. ++ */ ++#define SEM_KEY 0xdeadbeef + + /* + * Default is not to test hugetlbfs +@@ -1333,8 +1350,22 @@ static int sysctl_nested(void *arg) + + static int sysctl_nested_wait(void *arg) + { +- /* Wait for a SIGCONT. */ +- kill(getpid(), SIGSTOP); ++ int sem = semget(SEM_KEY, 1, 0600); ++ struct sembuf sembuf; ++ ++ if (sem < 0) { ++ perror("semget:"); ++ abort(); ++ } ++ sembuf.sem_num = 0; ++ sembuf.sem_flg = 0; ++ sembuf.sem_op = 0; ++ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ abort(); ++ } ++ + return sysctl_nested(arg); + } + +@@ -1355,7 +1386,9 @@ static void test_sysctl_sysctl2_failset(void) + + static int sysctl_nested_child(void *arg) + { +- int pid; ++ int pid, sem; ++ union semun semun; ++ struct sembuf sembuf; + + printf("%s nested sysctl 0\n", memfd_str); + sysctl_assert_write("0"); +@@ -1389,23 +1422,53 @@ static int sysctl_nested_child(void *arg) + test_sysctl_sysctl2_failset); + join_thread(pid); + ++ sem = semget(SEM_KEY, 1, IPC_CREAT | 0600); ++ if (sem < 0) { ++ perror("semget:"); ++ return 1; ++ } ++ semun.val = 1; ++ sembuf.sem_op = -1; ++ sembuf.sem_flg = 0; ++ sembuf.sem_num = 0; ++ + /* Verify that the rules are actually inherited after fork. */ + printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str); + sysctl_assert_write("0"); + ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl1_failset); + sysctl_assert_write("1"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str); + sysctl_assert_write("0"); + ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2_failset); + sysctl_assert_write("2"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + /* +@@ -1415,28 +1478,62 @@ static int sysctl_nested_child(void *arg) + */ + printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str); + sysctl_assert_write("2"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2); + sysctl_assert_write("1"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str); + sysctl_assert_write("2"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2); + sysctl_assert_write("0"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str); + sysctl_assert_write("1"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl1); + sysctl_assert_write("0"); +- kill(pid, SIGCONT); ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + ++ semctl(sem, 0, IPC_RMID); ++ + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.19/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch b/queue-6.19/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch new file mode 100644 index 0000000000..86a72c99c4 --- /dev/null +++ b/queue-6.19/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch @@ -0,0 +1,57 @@ +From 3c6f9d11c952846f78b7127f119a561e49297623 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 14:53:53 +0100 +Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2 + +From: Ido Schimmel + +[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ] + +As explained in [1], iproute2 started rejecting tc-police burst sizes +that result in an overflow. This can happen when the burst size is high +enough and the rate is low enough. + +A couple of test cases specify such configurations, resulting in +iproute2 errors and test failure. + +Fix by reducing the burst size so that the test will pass with both new +and old iproute2 versions. + +[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/ + +Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions") +Signed-off-by: Ido Schimmel +Signed-off-by: Petr Machata +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +index 0441a18f098b1..aac8ef490feb8 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +@@ -317,7 +317,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 0.5kbit burst 1m conform-exceed drop/ok ++ action police rate 0.5kbit burst 2k conform-exceed drop/ok + check_fail $? "Incorrect success to add police action with too low rate" + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ +@@ -327,7 +327,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 1.5kbit burst 1m conform-exceed drop/ok ++ action police rate 1.5kbit burst 2k conform-exceed drop/ok + check_err $? "Failed to add police action with low rate" + + tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower +-- +2.51.0 + diff --git a/queue-6.19/selftests-net-lib-fix-jq-parsing-error.patch b/queue-6.19/selftests-net-lib-fix-jq-parsing-error.patch new file mode 100644 index 0000000000..bd709a7553 --- /dev/null +++ b/queue-6.19/selftests-net-lib-fix-jq-parsing-error.patch @@ -0,0 +1,56 @@ +From b166222df84adc71c41438f934a0348cc2a2e93b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 10:21:46 +0800 +Subject: selftests: net: lib: Fix jq parsing error + +From: Yue Haibing + +[ Upstream commit 10ec0fc0ccc525abc807b0ca8ad5a26a0bd56361 ] + +The testcase failed as below: +$./vlan_bridge_binding.sh +... ++ adf_ip_link_set_up d1 ++ local name=d1 ++ shift ++ ip_link_is_up d1 ++ ip_link_has_flag d1 UP ++ local name=d1 ++ shift ++ local flag=UP ++ shift +++ ip -j link show d1 +++ jq --arg flag UP 'any(.[].flags.[]; . == $flag)' +jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START + (Unix shell quoting issues?) at , line 1: +any(.[].flags.[]; . == $flag) +jq: 1 compile error + +Remove the extra dot (.) after flags array to fix this. + +Fixes: 4baa1d3a5080 ("selftests: net: lib: Add ip_link_has_flag()") +Signed-off-by: Yue Haibing +Reviewed-by: Petr Machata +Link: https://patch.msgid.link/20260211022146.190948-1-yuehaibing@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/lib.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh +index 0ec131b339bc4..b40694573f4c7 100644 +--- a/tools/testing/selftests/net/lib.sh ++++ b/tools/testing/selftests/net/lib.sh +@@ -577,7 +577,7 @@ ip_link_has_flag() + local flag=$1; shift + + local state=$(ip -j link show "$name" | +- jq --arg flag "$flag" 'any(.[].flags.[]; . == $flag)') ++ jq --arg flag "$flag" 'any(.[].flags[]; . == $flag)') + [[ $state == true ]] + } + +-- +2.51.0 + diff --git a/queue-6.19/selftests-netconsole-increase-port-listening-timeout.patch b/queue-6.19/selftests-netconsole-increase-port-listening-timeout.patch new file mode 100644 index 0000000000..1a3631adb9 --- /dev/null +++ b/queue-6.19/selftests-netconsole-increase-port-listening-timeout.patch @@ -0,0 +1,44 @@ +From dacaaa52341b932faa1ee8fcb28cb64cbba4f711 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 16:59:36 -0800 +Subject: selftests: netconsole: Increase port listening timeout + +From: Pin-yen Lin + +[ Upstream commit a68a9bd086c2822d0c629443bd16ad1317afe501 ] + +wait_for_port() can wait up to 2 seconds with the sleep and the polling +in wait_local_port_listen() combined. So, in netcons_basic.sh, the socat +process could die before the test writes to the netconsole. + +Increase the timeout to 3 seconds to make netcons_basic.sh pass +consistently. + +Fixes: 3dc6c76391cb ("selftests: net: Add IPv6 support to netconsole basic tests") +Signed-off-by: Pin-yen Lin +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260210005939.3230550-1-treapking@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +index ae8abff4be409..64d3941576d5d 100644 +--- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh ++++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +@@ -247,8 +247,8 @@ function listen_port_and_save_to() { + SOCAT_MODE="UDP6-LISTEN" + fi + +- # Just wait for 2 seconds +- timeout 2 ip netns exec "${NAMESPACE}" \ ++ # Just wait for 3 seconds ++ timeout 3 ip netns exec "${NAMESPACE}" \ + socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}" 2> /dev/null + } + +-- +2.51.0 + diff --git a/queue-6.19/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch b/queue-6.19/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch new file mode 100644 index 0000000000..29dbdb1334 --- /dev/null +++ b/queue-6.19/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch @@ -0,0 +1,57 @@ +From 137d243f07b7208c07597994004462380dd0d0cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:51:59 -0800 +Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout + +From: Jakub Kicinski + +[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ] + +Since we started running selftests in NIPA we have been seeing +tc_actions.sh generate a soft lockup warning on ~20% of the runs. +On the pre-netdev foundation setup it was actually a missed irq +splat from the console. Now it's either that or a lockup. + +I initially suspected a socket locking issue since the test +is exercising local loopback with act_mirred. +After hours of staring at this I noticed in strace that ncat +when -o $file is specified _both_ saves the output to the file +and still prints it to stdout. Because the file being sent +is constructed with: + + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred + ^^^^^^^^^ + +the data printed is all \0. Most terminals don't display nul +characters (and neither does vng output capture save them). +But QEMU's serial console still has to poke them thru which +is very slow and causes the lockup (if the file is >600kB). + +Replace the '-o $file' with '> $file'. This speeds the test up +from 2m20s to 18s on debug kernels, and prevents the warnings. + +Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index ea89e558672db..86edbc7e2489b 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -223,7 +223,7 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & ++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 & + local rpid=$! + ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid +-- +2.51.0 + diff --git a/queue-6.19/series b/queue-6.19/series index 0d4d0dc905..ade4856985 100644 --- a/queue-6.19/series +++ b/queue-6.19/series @@ -614,3 +614,142 @@ drbd-always-set-blk_feat_stable_writes.patch block-allow-ioc_pr_read_-ioctls-with-blk_open_read.patch io_uring-delay-sqarray-static-branch-disablement.patch io_uring-cancel-de-unionize-file-and-user_data-in-st.patch +fs-ntfs3-initialize-new-folios-before-use.patch +fs-ntfs3-fix-ntfs_mount_options-leak-in-ntfs_fill_su.patch +fs-ntfs3-rename-ni_readpage_cmpr-into-ni_read_folio_.patch +fs-ntfs3-fix-deadlock-in-ni_read_folio_cmpr.patch +fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch +fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch +tools-power-turbostat-amd-msr-offset-0x611-read-fail.patch +tools-power-turbostat-harden-against-unexpected-valu.patch +powercap-intel_rapl-remove-incorrect-cpu-check-in-pm.patch +acpi-button-adjust-event-notification-routines.patch +acpi-button-convert-the-driver-to-a-platform-one.patch +acpi-button-call-device_init_wakeup-earlier-during-p.patch +acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch +powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch +kbuild-add-objtool-to-top-level-clean-target.patch +smb-client-fix-regression-with-mount-options-parsing.patch +selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch +objpool-fix-the-overestimation-of-object-pooling-met.patch +acpi-pm-add-unused-power-resource-quirk-for-thundero.patch +cpuidle-skip-governor-when-only-one-idle-state-is-av.patch +ovpn-set-sk_user_data-before-overriding-callbacks.patch +ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch +ovpn-fix-vpn-tx-bytes-counting.patch +net-mctp-ensure-our-nlmsg-responses-are-initialised.patch +selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch +selftests-net-lib-fix-jq-parsing-error.patch +net-stmmac-fix-oops-when-split-header-is-enabled.patch +net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch +net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch +net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch +net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch +selftests-netconsole-increase-port-listening-timeout.patch +ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch +net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch +fbnic-close-fw_log-race-between-users-and-teardown.patch +libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch +bpf-fix-a-potential-use-after-free-of-btf-object.patch +bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch +eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch +eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch +eth-fbnic-set-dma_hint_l4-for-all-flows.patch +ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch +net-usb-catc-enable-basic-endpoint-checking.patch +xen-netback-reject-zero-queue-configuration-from-gue.patch +net-rds-rds_sendmsg-should-not-discard-payload_len.patch +net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch +selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch +selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch +selftests-forwarding-fix-pedit-tests-failure-with-br.patch +netfilter-nft_counter-serialize-reset-with-spinlock.patch +netfilter-nft_quota-use-atomic64_xchg-for-reset.patch +netfilter-nf_tables-revert-commit_mutex-usage-in-res.patch +netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch +ipvs-skip-ipv6-extension-headers-for-csum-checks.patch +ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch +net-remove-warn_on_once-when-accessing-forward-path-.patch +netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch +ipv6-fix-a-race-in-ip6_sock_set_v6only.patch +bpftool-fix-truncated-netlink-dumps.patch +net-psp-select-config_skb_extensions.patch +net-do-not-delay-zero-copy-skbs-in-skb_attempt_defer.patch +dpll-zl3073x-fix-ref-frequency-setting.patch +ping-annotate-data-races-in-ping_lookup.patch +selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch +macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch +eth-fbnic-add-validation-for-mtu-changes.patch +icmp-prevent-possible-overflow-in-icmp_global_allow.patch +inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch +ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch +octeontx2-af-fix-default-entries-mcam-entry-action.patch +eth-fbnic-advertise-supported-xdp-features.patch +bnge-fix-reserving-resources-from-fw.patch +bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch +net-mlx5-fix-multiport-device-check-over-light-sfs.patch +net-mlx5e-fix-misidentification-of-aso-cqe-during-po.patch +net-mlx5-fix-misidentification-of-write-combining-cq.patch +net-mlx5e-macsec-add-aso-poll-loop-in-macsec_aso_set.patch +net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch +net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch +apparmor-fix-null-pointer-dereference-in-__unix_need.patch +apparmor-fix-null-sock-in-aa_sock_file_perm.patch +apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch +apparmor-fix-optimize-table-creation-from-possibly-u.patch +apparmor-return-enomem-in-unpack_perms_table-upon-al.patch +apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch +apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch +apparmor-account-for-in_atomic-removal-in-common_fil.patch +apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch +apparmor-fix-rlimit-for-posix-cpu-timers.patch +apparmor-remove-apply_modes_to_perms-from-label_matc.patch +apparmor-make-label_match-return-a-consistent-value.patch +apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch +apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch +apparmor-fix-aa_label-to-return-state-from-compount-.patch +drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch +drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch +drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch +drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch +drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch +drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch +drm-amdgpu-clean-up-the-amdgpu_cs_parser_bos.patch +mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch +regulator-mt6363-fix-interrmittent-timeout.patch +asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch +drm-i915-acpi-free-_dsm-package-when-no-connectors.patch +asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch +pci-validate-window-resource-type-in-pbus_select_win.patch +drm-amd-display-fix-dc_link-null-handling-in-hpd-ini.patch +drm-amdgpu-fix-missing-unwind-in-amdgpu_ib_schedule-.patch +drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch +drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch +drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch +spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch +gpio-cdev-avoid-null-dereference-in-linehandle_creat.patch +s390-kexec-make-kexec_sig-available-when-config_modu.patch +drm-xe-pf-fix-sysfs-initialization.patch +drm-xe-configfs-fix-parameter-name-omitted-errors.patch +drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch +drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch +drm-xe-vf-avoid-reading-media-version-when-media-gt-.patch +drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch +drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch +gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch +efi-fix-reservation-of-unaccepted-memory-table.patch +btrfs-reset-block-group-size-class-when-it-becomes-e.patch +btrfs-use-the-correct-type-to-initialize-block-reser.patch +btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch +drm-amd-display-use-dce-6-link-encoder-for-dce-6-ana.patch +drm-amd-display-only-use-analog-link-encoder-with-an.patch +drm-amd-display-only-use-analog-stream-encoder-with-.patch +x86-hyperv-fix-error-pointer-dereference.patch +asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch +drm-amd-display-use-same-max-plane-scaling-limits-fo.patch +drm-amd-display-don-t-call-find_analog_engine-twice.patch +drm-amd-display-turn-off-dac-in-dce-link-encoder-usi.patch +drm-amd-display-initialize-dac-in-dce-link-encoder-u.patch +drm-amd-display-set-crtc-source-for-dac-using-regist.patch +drm-amd-display-enable-dac-in-dce-link-encoder.patch +pci-dwc-ep-always-clear-ib-maps-on-bar-update.patch diff --git a/queue-6.19/smb-client-fix-regression-with-mount-options-parsing.patch b/queue-6.19/smb-client-fix-regression-with-mount-options-parsing.patch new file mode 100644 index 0000000000..1d31717acf --- /dev/null +++ b/queue-6.19/smb-client-fix-regression-with-mount-options-parsing.patch @@ -0,0 +1,56 @@ +From 5a81cb90d9490b67febd9f7017010edd0dacd112 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 01:10:07 -0300 +Subject: smb: client: fix regression with mount options parsing + +From: Paulo Alcantara + +[ Upstream commit 72f4d48034864b93700d1d23fc418d90fa28d7ae ] + +After commit 1ef15fbe6771 ("cifs: client: enforce consistent handling +of multichannel and max_channels"), invalid mount options started to +be ignored, allowing cifs.ko to proceed with the mount instead of +baling out. + +The problem was related to smb3_handle_conflicting_options() being +called even when an invalid parameter had been parsed, overwriting the +return value of vfs_parse_fs_string() in +smb3_fs_context_parse_monolithic(). + +Fix this by calling smb3_handle_conflicting_options() only when a +valid mount option has been passed. + +Reproducer: + +$ mount.cifs //srv/share /mnt -o ${opts} +$ mount -o remount,foo,${opts} /mnt # must fail + +Fixes: 1ef15fbe6771 ("cifs: client: enforce consistent handling of multichannel and max_channels") +Reported-by: Xiaoli Feng +Signed-off-by: Paulo Alcantara (Red Hat) +Cc: David Howells +Cc: linux-cifs@vger.kernel.org +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/fs_context.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c +index d4291d3a9a485..2527d2d29f190 100644 +--- a/fs/smb/client/fs_context.c ++++ b/fs/smb/client/fs_context.c +@@ -826,9 +826,7 @@ static int smb3_fs_context_parse_monolithic(struct fs_context *fc, + if (ret < 0) + break; + } +- ret = smb3_handle_conflicting_options(fc); +- +- return ret; ++ return ret ?: smb3_handle_conflicting_options(fc); + } + + /* +-- +2.51.0 + diff --git a/queue-6.19/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch b/queue-6.19/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch new file mode 100644 index 0000000000..b7606ad47d --- /dev/null +++ b/queue-6.19/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch @@ -0,0 +1,49 @@ +From 13116967c2bef46ab490f332fd6b29e036ac6b07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:41:40 +0800 +Subject: spi: wpcm-fiu: Fix potential NULL pointer dereference in + wpcm_fiu_probe() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felix Gu + +[ Upstream commit 888a0a802c467bbe34a42167bdf9d7331333440a ] + +platform_get_resource_byname() can return NULL, which would cause a crash +when passed the pointer to resource_size(). + +Move the fiu->memory_size assignment after the error check for +devm_ioremap_resource() to prevent the potential NULL pointer dereference. + +Fixes: 9838c182471e ("spi: wpcm-fiu: Add direct map support") +Signed-off-by: Felix Gu +Reviewed-by: J. Neuschäfer +Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-wpcm-fiu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c +index a9aee2a6c7dcb..c47b56f0933f1 100644 +--- a/drivers/spi/spi-wpcm-fiu.c ++++ b/drivers/spi/spi-wpcm-fiu.c +@@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); + fiu->memory = devm_ioremap_resource(dev, res); +- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + if (IS_ERR(fiu->memory)) + return dev_err_probe(dev, PTR_ERR(fiu->memory), + "Failed to map flash memory window\n"); + ++ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm"); + + wpcm_fiu_hw_init(fiu); +-- +2.51.0 + diff --git a/queue-6.19/tools-power-turbostat-amd-msr-offset-0x611-read-fail.patch b/queue-6.19/tools-power-turbostat-amd-msr-offset-0x611-read-fail.patch new file mode 100644 index 0000000000..247155c8c1 --- /dev/null +++ b/queue-6.19/tools-power-turbostat-amd-msr-offset-0x611-read-fail.patch @@ -0,0 +1,42 @@ +From d566a9b82361571b0f47556cc4851ef8b8faa474 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 14:41:53 -0600 +Subject: tools/power turbostat: AMD: msr offset 0x611 read failed: + Input/output error + +From: Len Brown + +[ Upstream commit 16cc8f249c702b7cbb4c2c2be7cd8f4fdd5d1d0c ] + +Turbostat exits during RAPL probe with: + +turbostat: cpu0: msr offset 0x611 read failed: Input/output error + +A binary with this bug can be used successfully with +the option "--no-msr" + +Fix this regression by trusting the static AMD RAPL MSR offset. + +Fixes: 19476a592bf2 ("tools/power turbostat: Validate RAPL MSRs for AWS Nitro Hypervisor") +Signed-off-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 5ad45c2ac5bd8..c4c8b6315fd26 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -2135,7 +2135,7 @@ off_t idx_to_offset(int idx) + + switch (idx) { + case IDX_PKG_ENERGY: +- if (valid_rapl_msrs & RAPL_AMD_F17H) ++ if (platform->plat_rapl_msrs & RAPL_AMD_F17H) + offset = MSR_PKG_ENERGY_STAT; + else + offset = MSR_PKG_ENERGY_STATUS; +-- +2.51.0 + diff --git a/queue-6.19/tools-power-turbostat-harden-against-unexpected-valu.patch b/queue-6.19/tools-power-turbostat-harden-against-unexpected-valu.patch new file mode 100644 index 0000000000..ef457455d0 --- /dev/null +++ b/queue-6.19/tools-power-turbostat-harden-against-unexpected-valu.patch @@ -0,0 +1,275 @@ +From 018510cb4c7a95a41294cc538ac54937c493c4f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Dec 2025 10:01:04 -0500 +Subject: tools/power turbostat: Harden against unexpected values + +From: Len Brown + +[ Upstream commit d0f7093ad5e4aa37405da2669bca1a62d22b7025 ] + +Divide-by-zero resulted if LLC references == 0 + +Pull the percentage division into pct() to centralize sanity checks there. + +Fixes: 8808292799b0 ("tools/power turbostat: Print "nan" for out of range percentages") + +Signed-off-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 94 +++++++++++++++------------ + 1 file changed, 51 insertions(+), 43 deletions(-) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index c4c8b6315fd26..1b26d94c373fb 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -3001,22 +3001,30 @@ void print_header(char *delim) + } + + /* +- * pct() ++ * pct(numerator, denominator) + * +- * If absolute value is < 1.1, return percentage +- * otherwise, return nan ++ * Return sanity checked percentage (100.0 * numerator/denominotor) + * +- * return value is appropriate for printing percentages with %f +- * while flagging some obvious erroneous values. ++ * n < 0: nan ++ * d <= 0: nan ++ * n/d > 1.1: nan + */ +-double pct(double d) ++double pct(double numerator, double denominator) + { ++ double retval; + +- double abs = fabs(d); ++ if (numerator < 0) ++ return nan(""); + +- if (abs < 1.10) +- return (100.0 * d); +- return nan(""); ++ if (denominator <= 0) ++ return nan(""); ++ ++ retval = 100.0 * numerator / denominator; ++ ++ if (retval > 110.0) ++ return nan(""); ++ ++ return retval; + } + + int dump_counters(PER_THREAD_PARAMS) +@@ -3046,7 +3054,7 @@ int dump_counters(PER_THREAD_PARAMS) + + outp += sprintf(outp, "LLC refs: %lld", t->llc.references); + outp += sprintf(outp, "LLC miss: %lld", t->llc.misses); +- outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses) / t->llc.references)); ++ outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses), t->llc.references)); + + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { + outp += sprintf(outp, "tADDED [%d] %8s msr0x%x: %08llX %s\n", i, mp->name, mp->msr_num, t->counter[i], mp->sp->path); +@@ -3261,7 +3269,7 @@ int format_counters(PER_THREAD_PARAMS) + outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 / units * t->aperf / interval_float); + + if (DO_BIC(BIC_Busy)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf, tsc)); + + if (DO_BIC(BIC_Bzy_MHz)) { + if (has_base_hz) +@@ -3302,7 +3310,7 @@ int format_counters(PER_THREAD_PARAMS) + outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), t->llc.references / interval_float / 1000); + + if (DO_BIC(BIC_LLC_HIT)) +- outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses) / t->llc.references)); ++ outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses), t->llc.references)); + } + + /* Added Thread Counters */ +@@ -3315,7 +3323,7 @@ int format_counters(PER_THREAD_PARAMS) + if (mp->type == COUNTER_USEC) + outp += print_float_value(&printed, delim, t->counter[i] / interval_float / 10000); + else +- outp += print_float_value(&printed, delim, pct(t->counter[i] / tsc)); ++ outp += print_float_value(&printed, delim, pct(t->counter[i], tsc)); + } + } + +@@ -3329,7 +3337,7 @@ int format_counters(PER_THREAD_PARAMS) + if (pp->type == COUNTER_USEC) + outp += print_float_value(&printed, delim, t->perf_counter[i] / interval_float / 10000); + else +- outp += print_float_value(&printed, delim, pct(t->perf_counter[i] / tsc)); ++ outp += print_float_value(&printed, delim, pct(t->perf_counter[i], tsc)); + } + } + +@@ -3343,34 +3351,34 @@ int format_counters(PER_THREAD_PARAMS) + break; + + case PMT_TYPE_XTAL_TIME: +- value_converted = pct(value_raw / crystal_hz / interval_float); ++ value_converted = pct(value_raw / crystal_hz, interval_float); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); + break; + + case PMT_TYPE_TCORE_CLOCK: +- value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); ++ value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); + } + } + + /* C1 */ + if (DO_BIC(BIC_CPU_c1)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1, tsc)); + + /* print per-core data only for 1st thread in core */ + if (!is_cpu_first_thread_in_core(t, c)) + goto done; + + if (DO_BIC(BIC_CPU_c3)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3, tsc)); + if (DO_BIC(BIC_CPU_c6)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6, tsc)); + if (DO_BIC(BIC_CPU_c7)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7, tsc)); + + /* Mod%c6 */ + if (DO_BIC(BIC_Mod_c6)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us, tsc)); + + if (DO_BIC(BIC_CoreTmp)) + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c); +@@ -3386,7 +3394,7 @@ int format_counters(PER_THREAD_PARAMS) + else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) + outp += print_decimal_value(mp->width, &printed, delim, c->counter[i]); + else if (mp->format == FORMAT_PERCENT) +- outp += print_float_value(&printed, delim, pct(c->counter[i] / tsc)); ++ outp += print_float_value(&printed, delim, pct(c->counter[i], tsc)); + } + + /* Added perf Core counters */ +@@ -3396,7 +3404,7 @@ int format_counters(PER_THREAD_PARAMS) + else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) + outp += print_decimal_value(pp->width, &printed, delim, c->perf_counter[i]); + else if (pp->format == FORMAT_PERCENT) +- outp += print_float_value(&printed, delim, pct(c->perf_counter[i] / tsc)); ++ outp += print_float_value(&printed, delim, pct(c->perf_counter[i], tsc)); + } + + /* Added PMT Core counters */ +@@ -3409,12 +3417,12 @@ int format_counters(PER_THREAD_PARAMS) + break; + + case PMT_TYPE_XTAL_TIME: +- value_converted = pct(value_raw / crystal_hz / interval_float); ++ value_converted = pct(value_raw / crystal_hz, interval_float); + outp += print_float_value(&printed, delim, value_converted); + break; + + case PMT_TYPE_TCORE_CLOCK: +- value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); ++ value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); + outp += print_float_value(&printed, delim, value_converted); + } + } +@@ -3470,39 +3478,39 @@ int format_counters(PER_THREAD_PARAMS) + if (DO_BIC(BIC_Totl_c0)) + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100 * p->pkg_wtd_core_c0 / tsc); /* can exceed 100% */ + if (DO_BIC(BIC_Any_c0)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0, tsc)); + if (DO_BIC(BIC_GFX_c0)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0, tsc)); + if (DO_BIC(BIC_CPUGFX)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0, tsc)); + + if (DO_BIC(BIC_Pkgpc2)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2, tsc)); + if (DO_BIC(BIC_Pkgpc3)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3, tsc)); + if (DO_BIC(BIC_Pkgpc6)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6, tsc)); + if (DO_BIC(BIC_Pkgpc7)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7, tsc)); + if (DO_BIC(BIC_Pkgpc8)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8, tsc)); + if (DO_BIC(BIC_Pkgpc9)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9, tsc)); + if (DO_BIC(BIC_Pkgpc10)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10 / tsc)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10, tsc)); + + if (DO_BIC(BIC_Diec6)) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz / interval_float)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz, interval_float)); + + if (DO_BIC(BIC_CPU_LPI)) { + if (p->cpu_lpi >= 0) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0 / interval_float)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0, interval_float)); + else + outp += sprintf(outp, "%s(neg)", (printed++ ? delim : "")); + } + if (DO_BIC(BIC_SYS_LPI)) { + if (p->sys_lpi >= 0) +- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0 / interval_float)); ++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0, interval_float)); + else + outp += sprintf(outp, "%s(neg)", (printed++ ? delim : "")); + } +@@ -3542,7 +3550,7 @@ int format_counters(PER_THREAD_PARAMS) + else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) + outp += print_decimal_value(mp->width, &printed, delim, p->counter[i]); + else if (mp->format == FORMAT_PERCENT) +- outp += print_float_value(&printed, delim, pct(p->counter[i] / tsc)); ++ outp += print_float_value(&printed, delim, pct(p->counter[i], tsc)); + } + + /* Added perf Package Counters */ +@@ -3554,7 +3562,7 @@ int format_counters(PER_THREAD_PARAMS) + else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) + outp += print_decimal_value(pp->width, &printed, delim, p->perf_counter[i]); + else if (pp->format == FORMAT_PERCENT) +- outp += print_float_value(&printed, delim, pct(p->perf_counter[i] / tsc)); ++ outp += print_float_value(&printed, delim, pct(p->perf_counter[i], tsc)); + } + + /* Added PMT Package Counters */ +@@ -3567,12 +3575,12 @@ int format_counters(PER_THREAD_PARAMS) + break; + + case PMT_TYPE_XTAL_TIME: +- value_converted = pct(value_raw / crystal_hz / interval_float); ++ value_converted = pct(value_raw / crystal_hz, interval_float); + outp += print_float_value(&printed, delim, value_converted); + break; + + case PMT_TYPE_TCORE_CLOCK: +- value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); ++ value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); + outp += print_float_value(&printed, delim, value_converted); + } + } +-- +2.51.0 + diff --git a/queue-6.19/x86-hyperv-fix-error-pointer-dereference.patch b/queue-6.19/x86-hyperv-fix-error-pointer-dereference.patch new file mode 100644 index 0000000000..c076ef7b0d --- /dev/null +++ b/queue-6.19/x86-hyperv-fix-error-pointer-dereference.patch @@ -0,0 +1,54 @@ +From 69474501fded49350ca3b03ee04bbb481926ea15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 13:09:03 -0600 +Subject: x86/hyperv: Fix error pointer dereference + +From: Ethan Tidmore + +[ Upstream commit 705d01c8d78121ee1634bfc602ac4b0ad1438fab ] + +The function idle_thread_get() can return an error pointer and is not +checked for it. Add check for error pointer. + +Detected by Smatch: +arch/x86/hyperv/hv_vtl.c:126 hv_vtl_bringup_vcpu() error: +'idle' dereferencing possible ERR_PTR() + +Fixes: 2b4b90e053a29 ("x86/hyperv: Use per cpu initial stack for vtl context") +Signed-off-by: Ethan Tidmore +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + arch/x86/hyperv/hv_vtl.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c +index c0edaed0efb30..9b6a9bc4ab760 100644 +--- a/arch/x86/hyperv/hv_vtl.c ++++ b/arch/x86/hyperv/hv_vtl.c +@@ -110,7 +110,7 @@ static void hv_vtl_ap_entry(void) + + static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) + { +- u64 status; ++ u64 status, rsp, rip; + int ret = 0; + struct hv_enable_vp_vtl *input; + unsigned long irq_flags; +@@ -123,9 +123,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) + struct desc_struct *gdt; + + struct task_struct *idle = idle_thread_get(cpu); +- u64 rsp = (unsigned long)idle->thread.sp; ++ if (IS_ERR(idle)) ++ return PTR_ERR(idle); + +- u64 rip = (u64)&hv_vtl_ap_entry; ++ rsp = (unsigned long)idle->thread.sp; ++ rip = (u64)&hv_vtl_ap_entry; + + native_store_gdt(&gdt_ptr); + store_idt(&idt_ptr); +-- +2.51.0 + diff --git a/queue-6.19/xen-netback-reject-zero-queue-configuration-from-gue.patch b/queue-6.19/xen-netback-reject-zero-queue-configuration-from-gue.patch new file mode 100644 index 0000000000..ef66a94bc3 --- /dev/null +++ b/queue-6.19/xen-netback-reject-zero-queue-configuration-from-gue.patch @@ -0,0 +1,57 @@ +From 622160f4a69e3b04099d0b7d7052d037897026a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:40:40 +0000 +Subject: xen-netback: reject zero-queue configuration from guest + +From: Ziyi Guo + +[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ] + +A malicious or buggy Xen guest can write "0" to the xenbus key +"multi-queue-num-queues". The connect() function in the backend only +validates the upper bound (requested_num_queues > xenvif_max_queues) +but not zero, allowing requested_num_queues=0 to reach +vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers +WARN_ON_ONCE(!size) in __vmalloc_node_range(). + +On systems with panic_on_warn=1, this allows a guest-to-host denial +of service. + +The Xen network interface specification requires +the queue count to be "greater than zero". + +Add a zero check to match the validation already present +in xen-blkback, which has included this +guard since its multi-queue support was added. + +Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues") +Signed-off-by: Ziyi Guo +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/xen-netback/xenbus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index a78a25b872409..61b547aab286a 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -735,10 +735,11 @@ static void connect(struct backend_info *be) + */ + requested_num_queues = xenbus_read_unsigned(dev->otherend, + "multi-queue-num-queues", 1); +- if (requested_num_queues > xenvif_max_queues) { ++ if (requested_num_queues > xenvif_max_queues || ++ requested_num_queues == 0) { + /* buggy or malicious guest */ + xenbus_dev_fatal(dev, -EINVAL, +- "guest requested %u queues, exceeding the maximum of %u.", ++ "guest requested %u queues, but valid range is 1 - %u.", + requested_num_queues, xenvif_max_queues); + return; + } +-- +2.51.0 + diff --git a/queue-6.6/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch b/queue-6.6/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch new file mode 100644 index 0000000000..6288d01662 --- /dev/null +++ b/queue-6.6/acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch @@ -0,0 +1,55 @@ +From 9fa64217bad4ee164ebcbc2ee5a79285aa0f1910 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 21:22:54 +0000 +Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs + +From: Sean V Kelley + +[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ] + +per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online +CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> +acpi_cppc_processor_probe(). + +However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all +possible CPUs. In acpi_get_psd_map(), encountering an offline CPU +returns -EFAULT, causing cppc_cpufreq initialization to fail. + +This breaks systems booted with "nosmt" or "nosmt=force". + +Fix by using for_each_online_cpu() in both functions. + +Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests") +Signed-off-by: Sean V Kelley +Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index 16ac219ae6fe5..0bf3861cf79b1 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -347,7 +347,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) + end: + if (cmd == CMD_WRITE) { + if (unlikely(ret)) { +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i); + + if (!desc) +@@ -509,7 +509,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data) + else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) + cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; + +- for_each_possible_cpu(i) { ++ for_each_online_cpu(i) { + if (i == cpu) + continue; + +-- +2.51.0 + diff --git a/queue-6.6/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch b/queue-6.6/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch new file mode 100644 index 0000000000..3b651c5a9c --- /dev/null +++ b/queue-6.6/acpi-pm-add-unused-power-resource-quirk-for-thundero.patch @@ -0,0 +1,67 @@ +From 8896cecee33e47f81c0e59e2edfd2dbb2d72c1f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Feb 2026 00:14:52 +0800 +Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO + +From: Zhai Can + +[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ] + +On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete +NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table +bug (lack of reference), PXP will be shut dow as an "unused" power resource +during initialization, making the NVMe slot #2 + NVIDIA both inaccessible. + +This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check +states of power resources during initialization"). Here are test +results on the three consecutive commits: + +(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization +(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state +(bad) 519d81956ee2 Linux 5.15-rc6 + +On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in +unknown state") this was not an issue because the power resource state +left UNKNOWN thus being ignored. + +See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power +resources on the Toshiba Click Mini") which is another almost identical +case to this one. + +Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization") +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087 +Signed-off-by: Zhai Can +Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/power.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c +index c2c70139c4f1d..ff5fcd541e50f 100644 +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -1035,6 +1035,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"), + }, + }, ++ { ++ /* ++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power ++ * resource 'PXP' will be shut down on initialization, making ++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're ++ * both controlled by 'PXP'). ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"), ++ } ++ ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.6/apparmor-fix-aa_label-to-return-state-from-compount-.patch b/queue-6.6/apparmor-fix-aa_label-to-return-state-from-compount-.patch new file mode 100644 index 0000000000..5b8a2f57a5 --- /dev/null +++ b/queue-6.6/apparmor-fix-aa_label-to-return-state-from-compount-.patch @@ -0,0 +1,74 @@ +From 643db385c6725bc167f935c7a34ea25a73fe69e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 04:12:02 -0800 +Subject: apparmor: fix aa_label to return state from compount and component + match + +From: John Johansen + +[ Upstream commit 9058798652c8bc0584ed1fb0766a1015046c06e8 ] + +aa-label_match is not correctly returning the state in all cases. +The only reason this didn't cause a error is that all callers currently +ignore the return value. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202602020631.wXgZosyU-lkp@intel.com/ +Fixes: a4c9efa4dbad6 ("apparmor: make label_match return a consistent value") +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 7289712df2414..d64c838f5d84e 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1344,7 +1344,7 @@ static int label_compound_match(struct aa_profile *profile, + * @request: permissions to request + * @perms: an initialized perms struct to add accumulation to + * +- * Returns: 0 on success else ERROR ++ * Returns: the state the match finished in, may be the none matching state + * + * For the label A//&B//&C this does the perm match for each of A and B and C + * @perms should be preinitialized with allperms OR a previous permission +@@ -1372,7 +1372,7 @@ static int label_components_match(struct aa_profile *profile, + } + + /* no subcomponents visible - no change in perms */ +- return 0; ++ return state; + + next: + tmp = *aa_lookup_perms(rules->policy, state); +@@ -1388,13 +1388,13 @@ static int label_components_match(struct aa_profile *profile, + } + + if ((perms->allow & request) != request) +- return -EACCES; ++ return DFA_NOMATCH; + +- return 0; ++ return state; + + fail: + *perms = nullperms; +- return -EACCES; ++ return DFA_NOMATCH; + } + + /** +@@ -1416,7 +1416,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, + aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, + request, perms); + if ((perms->allow & request) == request) +- return 0; ++ return tmp; + + /* failed compound_match try component matches */ + *perms = allperms; +-- +2.51.0 + diff --git a/queue-6.6/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch b/queue-6.6/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch new file mode 100644 index 0000000000..2b32748375 --- /dev/null +++ b/queue-6.6/apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch @@ -0,0 +1,85 @@ +From 99b9e2ab549a5b1d68637949be3c5b9c1c51c0a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 15:58:45 -0300 +Subject: apparmor: fix invalid deref of rawdata when export_binary is unset + +From: Georgia Garcia + +[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ] + +If the export_binary parameter is disabled on runtime, profiles that +were loaded before that will still have their rawdata stored in +apparmorfs, with a symbolic link to the rawdata on the policy +directory. When one of those profiles are replaced, the rawdata is set +to NULL, but when trying to resolve the symbolic links to rawdata for +that profile, it will try to dereference profile->rawdata->name when +profile->rawdata is now NULL causing an oops. Fix it by checking if +rawdata is set. + +[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088 +[ 168.657420] #PF: supervisor read access in kernel mode +[ 168.660619] #PF: error_code(0x0000) - not-present page +[ 168.663613] PGD 0 P4D 0 +[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI +[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary) +[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330 +[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8 +[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282 +[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158 +[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80 +[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000 +[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80 +[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0 +[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000 +[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0 +[ 168.701696] Call Trace: +[ 168.702325] +[ 168.702995] rawdata_get_link_data+0x1c/0x30 +[ 168.704145] vfs_readlink+0xd4/0x160 +[ 168.705152] do_readlinkat+0x114/0x180 +[ 168.706214] __x64_sys_readlink+0x1e/0x30 +[ 168.708653] x64_sys_call+0x1d77/0x26b0 +[ 168.709525] do_syscall_64+0x81/0x500 +[ 168.710348] ? do_statx+0x72/0xb0 +[ 168.711109] ? putname+0x3e/0x80 +[ 168.711845] ? __x64_sys_statx+0xb7/0x100 +[ 168.712711] ? x64_sys_call+0x10fc/0x26b0 +[ 168.713577] ? do_syscall_64+0xbf/0x500 +[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0 +[ 168.715404] ? irqentry_exit+0xb2/0x740 +[ 168.716359] ? exc_page_fault+0x90/0x1b0 +[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement") +Signed-off-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index c2a09056c7014..6885ecd4afddc 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -1637,6 +1637,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry, + + label = aa_get_label_rcu(&proxy->label); + profile = labels_profile(label); ++ ++ /* rawdata can be null when aa_g_export_binary is unset during ++ * runtime and a profile is replaced ++ */ ++ if (!profile->rawdata) { ++ aa_put_label(label); ++ return ERR_PTR(-ENOENT); ++ } ++ + depth = profile_depth(profile); + target = gen_symlink_name(depth, profile->rawdata->name, name); + aa_put_label(label); +-- +2.51.0 + diff --git a/queue-6.6/apparmor-fix-null-sock-in-aa_sock_file_perm.patch b/queue-6.6/apparmor-fix-null-sock-in-aa_sock_file_perm.patch new file mode 100644 index 0000000000..0937d4a25e --- /dev/null +++ b/queue-6.6/apparmor-fix-null-sock-in-aa_sock_file_perm.patch @@ -0,0 +1,44 @@ +From 0698ba1162cd3c5d337887992f51b36f7f07edb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:07:42 -0800 +Subject: apparmor: fix NULL sock in aa_sock_file_perm + +From: John Johansen + +[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ] + +Deal with the potential that sock and sock-sk can be NULL during +socket setup or teardown. This could lead to an oops. The fix for NULL +pointer dereference in __unix_needs_revalidation shows this is at +least possible for af_unix sockets. While the fix for af_unix sockets +applies for newer mediation this is still the fall back path for older +af_unix mediation and other sockets, so ensure it is covered. + +Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/net.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 704c171232ab4..814e8319d43e0 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -190,8 +190,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, + const char *op, u32 request, struct socket *sock) + { + AA_BUG(!label); +- AA_BUG(!sock); +- AA_BUG(!sock->sk); ++ ++ /* sock && sock->sk can be NULL for sockets being set up or torn down */ ++ if (!sock || !sock->sk) ++ return 0; + + return aa_label_sk_perm(subj_cred, label, op, request, sock->sk); + } +-- +2.51.0 + diff --git a/queue-6.6/apparmor-fix-rlimit-for-posix-cpu-timers.patch b/queue-6.6/apparmor-fix-rlimit-for-posix-cpu-timers.patch new file mode 100644 index 0000000000..7ce702dfb0 --- /dev/null +++ b/queue-6.6/apparmor-fix-rlimit-for-posix-cpu-timers.patch @@ -0,0 +1,40 @@ +From 3258003c56b414c36cf171bcff15ce1f1597cf59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:16:54 -0800 +Subject: apparmor: fix rlimit for posix cpu timers + +From: John Johansen + +[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ] + +Posix cpu timers requires an additional step beyond setting the rlimit. +Refactor the code so its clear when what code is setting the +limit and conditionally update the posix cpu timers when appropriate. + +Fixes: baa73d9e478ff ("posix-timers: Make them configurable") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/resource.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index dcc94c3153d51..a7eee815f1215 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -201,6 +201,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l) + rules->rlimits.limits[j].rlim_max); + /* soft limit should not exceed hard limit */ + rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); ++ if (j == RLIMIT_CPU && ++ rlim->rlim_cur != RLIM_INFINITY && ++ IS_ENABLED(CONFIG_POSIX_TIMERS)) ++ (void) update_rlimit_cpu(current->group_leader, ++ rlim->rlim_cur); + } + } + } +-- +2.51.0 + diff --git a/queue-6.6/apparmor-make-label_match-return-a-consistent-value.patch b/queue-6.6/apparmor-make-label_match-return-a-consistent-value.patch new file mode 100644 index 0000000000..5b1d4f7505 --- /dev/null +++ b/queue-6.6/apparmor-make-label_match-return-a-consistent-value.patch @@ -0,0 +1,80 @@ +From 089edea40e0661221ad1fb6787d985e522d4636c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 23:59:38 -0800 +Subject: apparmor: make label_match return a consistent value + +From: John Johansen + +[ Upstream commit a4c9efa4dbad6dacad6e8b274e30e814c8353097 ] + +compound match is inconsistent in returning a state or an integer error +this is problemati if the error is ever used as a state in the state +machine + +Fixes: f1bd904175e81 ("apparmor: add the base fns() for domain labels") +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 217bd6709023f..7289712df2414 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1288,7 +1288,7 @@ static inline aa_state_t match_component(struct aa_profile *profile, + * @request: permissions to request + * @perms: perms struct to set + * +- * Returns: 0 on success else ERROR ++ * Returns: state match stopped at or DFA_NOMATCH if aborted early + * + * For the label A//&B//&C this does the perm match for A//&B//&C + * @perms should be preinitialized with allperms OR a previous permission +@@ -1315,7 +1315,7 @@ static int label_compound_match(struct aa_profile *profile, + + /* no component visible */ + *perms = allperms; +- return 0; ++ return state; + + next: + label_for_each_cont(i, label, tp) { +@@ -1327,14 +1327,11 @@ static int label_compound_match(struct aa_profile *profile, + goto fail; + } + *perms = *aa_lookup_perms(rules->policy, state); +- if ((perms->allow & request) != request) +- return -EACCES; +- +- return 0; ++ return state; + + fail: + *perms = nullperms; +- return state; ++ return DFA_NOMATCH; + } + + /** +@@ -1416,11 +1413,12 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, + struct aa_label *label, aa_state_t state, bool subns, + u32 request, struct aa_perms *perms) + { +- int error = label_compound_match(profile, rules, label, state, subns, +- request, perms); +- if (!error) +- return error; ++ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, ++ request, perms); ++ if ((perms->allow & request) == request) ++ return 0; + ++ /* failed compound_match try component matches */ + *perms = allperms; + return label_components_match(profile, rules, label, state, subns, + request, perms); +-- +2.51.0 + diff --git a/queue-6.6/apparmor-provide-separate-audit-messages-for-file-an.patch b/queue-6.6/apparmor-provide-separate-audit-messages-for-file-an.patch new file mode 100644 index 0000000000..9fe9eb9a2e --- /dev/null +++ b/queue-6.6/apparmor-provide-separate-audit-messages-for-file-an.patch @@ -0,0 +1,51 @@ +From bc18bf3c0d991a851a98a34f930955a4522cffb5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Apr 2023 03:27:36 -0700 +Subject: apparmor: provide separate audit messages for file and policy checks + +From: John Johansen + +[ Upstream commit 75c77e9e0713fddbe99a21a036aa6482402f9e34 ] + +Improve policy load failure messages by identifying which dfa the +verification check failed in. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value") +Signed-off-by: Sasha Levin +--- + security/apparmor/policy_unpack.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index a1de48c2d826b..cefda5e5b6ed0 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -1249,12 +1249,18 @@ static int verify_profile(struct aa_profile *profile) + if (!rules) + return 0; + +- if ((rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa, +- rules->file.size)) || +- (rules->policy.dfa && +- !verify_dfa_accept_index(rules->policy.dfa, rules->policy.size))) { ++ if (rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa, ++ rules->file.size)) { + audit_iface(profile, NULL, NULL, +- "Unpack: Invalid named transition", NULL, -EPROTO); ++ "Unpack: file Invalid named transition", NULL, ++ -EPROTO); ++ return -EPROTO; ++ } ++ if (rules->policy.dfa && ++ !verify_dfa_accept_index(rules->policy.dfa, rules->policy.size)) { ++ audit_iface(profile, NULL, NULL, ++ "Unpack: policy Invalid named transition", NULL, ++ -EPROTO); + return -EPROTO; + } + +-- +2.51.0 + diff --git a/queue-6.6/apparmor-refcount-the-pdb.patch b/queue-6.6/apparmor-refcount-the-pdb.patch new file mode 100644 index 0000000000..8c1a3782d6 --- /dev/null +++ b/queue-6.6/apparmor-refcount-the-pdb.patch @@ -0,0 +1,1075 @@ +From b90954646faa93d31283dca73b609d1ea4b282c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Apr 2023 05:32:52 -0700 +Subject: apparmor: refcount the pdb + +From: John Johansen + +[ Upstream commit 98b824ff8984fd523fc264fbb13208098ab09da3 ] + +With the move to permission tables the dfa is no longer a stand +alone entity when used, needing a minimum of a permission table. +However it still could be shared among different pdbs each using +a different permission table. + +Instead of duping the permission table when sharing a pdb, add a +refcount to the pdb so it can be easily shared. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value") +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 18 ++--- + security/apparmor/domain.c | 60 ++++++++-------- + security/apparmor/file.c | 12 ++-- + security/apparmor/include/lib.h | 2 + + security/apparmor/include/match.h | 6 -- + security/apparmor/include/policy.h | 49 +++++++++---- + security/apparmor/ipc.c | 4 +- + security/apparmor/label.c | 18 ++--- + security/apparmor/lib.c | 4 +- + security/apparmor/lsm.c | 63 +++++++++++++++++ + security/apparmor/match.c | 44 ------------ + security/apparmor/mount.c | 20 +++--- + security/apparmor/net.c | 4 +- + security/apparmor/policy.c | 58 +++++++++++----- + security/apparmor/policy_unpack.c | 108 +++++++++++++---------------- + 15 files changed, 260 insertions(+), 210 deletions(-) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index 23b2853ce3c42..c2a09056c7014 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -619,23 +619,23 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms, + + if (profile_unconfined(profile)) + return; +- if (rules->file.dfa && *match_str == AA_CLASS_FILE) { +- state = aa_dfa_match_len(rules->file.dfa, +- rules->file.start[AA_CLASS_FILE], ++ if (rules->file->dfa && *match_str == AA_CLASS_FILE) { ++ state = aa_dfa_match_len(rules->file->dfa, ++ rules->file->start[AA_CLASS_FILE], + match_str + 1, match_len - 1); + if (state) { + struct path_cond cond = { }; + +- tmp = *(aa_lookup_fperms(&(rules->file), state, &cond)); ++ tmp = *(aa_lookup_fperms(rules->file, state, &cond)); + } +- } else if (rules->policy.dfa) { ++ } else if (rules->policy->dfa) { + if (!RULE_MEDIATES(rules, *match_str)) + return; /* no change to current perms */ +- state = aa_dfa_match_len(rules->policy.dfa, +- rules->policy.start[0], ++ state = aa_dfa_match_len(rules->policy->dfa, ++ rules->policy->start[0], + match_str, match_len); + if (state) +- tmp = *aa_lookup_perms(&rules->policy, state); ++ tmp = *aa_lookup_perms(rules->policy, state); + } + aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum_raw(perms, &tmp); +@@ -1096,7 +1096,7 @@ static int seq_profile_attach_show(struct seq_file *seq, void *v) + struct aa_profile *profile = labels_profile(label); + if (profile->attach.xmatch_str) + seq_printf(seq, "%s\n", profile->attach.xmatch_str); +- else if (profile->attach.xmatch.dfa) ++ else if (profile->attach.xmatch->dfa) + seq_puts(seq, "\n"); + else + seq_printf(seq, "%s\n", profile->base.name); +diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c +index 543105cf7e334..d6500ec4f6b63 100644 +--- a/security/apparmor/domain.c ++++ b/security/apparmor/domain.c +@@ -77,7 +77,7 @@ static int may_change_ptraced_domain(const struct cred *to_cred, + /**** TODO: dedup to aa_label_match - needs perm and dfa, merging + * specifically this is an exact copy of aa_label_match except + * aa_compute_perms is replaced with aa_compute_fperms +- * and policy.dfa with file.dfa ++ * and policy->dfa with file->dfa + ****/ + /* match a profile and its associated ns component if needed + * Assumes visibility test has already been done. +@@ -93,16 +93,16 @@ static inline aa_state_t match_component(struct aa_profile *profile, + const char *ns_name; + + if (stack) +- state = aa_dfa_match(rules->file.dfa, state, "&"); ++ state = aa_dfa_match(rules->file->dfa, state, "&"); + if (profile->ns == tp->ns) +- return aa_dfa_match(rules->file.dfa, state, tp->base.hname); ++ return aa_dfa_match(rules->file->dfa, state, tp->base.hname); + + /* try matching with namespace name and then profile */ + ns_name = aa_ns_name(profile->ns, tp->ns, true); +- state = aa_dfa_match_len(rules->file.dfa, state, ":", 1); +- state = aa_dfa_match(rules->file.dfa, state, ns_name); +- state = aa_dfa_match_len(rules->file.dfa, state, ":", 1); +- return aa_dfa_match(rules->file.dfa, state, tp->base.hname); ++ state = aa_dfa_match_len(rules->file->dfa, state, ":", 1); ++ state = aa_dfa_match(rules->file->dfa, state, ns_name); ++ state = aa_dfa_match_len(rules->file->dfa, state, ":", 1); ++ return aa_dfa_match(rules->file->dfa, state, tp->base.hname); + } + + /** +@@ -150,12 +150,12 @@ static int label_compound_match(struct aa_profile *profile, + label_for_each_cont(i, label, tp) { + if (!aa_ns_visible(profile->ns, tp->ns, subns)) + continue; +- state = aa_dfa_match(rules->file.dfa, state, "//&"); ++ state = aa_dfa_match(rules->file->dfa, state, "//&"); + state = match_component(profile, tp, false, state); + if (!state) + goto fail; + } +- *perms = *(aa_lookup_fperms(&(rules->file), state, &cond)); ++ *perms = *(aa_lookup_fperms(rules->file, state, &cond)); + aa_apply_modes_to_perms(profile, perms); + if ((perms->allow & request) != request) + return -EACCES; +@@ -210,7 +210,7 @@ static int label_components_match(struct aa_profile *profile, + return 0; + + next: +- tmp = *(aa_lookup_fperms(&(rules->file), state, &cond)); ++ tmp = *(aa_lookup_fperms(rules->file, state, &cond)); + aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + label_for_each_cont(i, label, tp) { +@@ -219,7 +219,7 @@ static int label_components_match(struct aa_profile *profile, + state = match_component(profile, tp, stack, start); + if (!state) + goto fail; +- tmp = *(aa_lookup_fperms(&(rules->file), state, &cond)); ++ tmp = *(aa_lookup_fperms(rules->file, state, &cond)); + aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + } +@@ -316,7 +316,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm, + might_sleep(); + + /* transition from exec match to xattr set */ +- state = aa_dfa_outofband_transition(attach->xmatch.dfa, state); ++ state = aa_dfa_outofband_transition(attach->xmatch->dfa, state); + d = bprm->file->f_path.dentry; + + for (i = 0; i < attach->xattr_count; i++) { +@@ -330,20 +330,20 @@ static int aa_xattrs_match(const struct linux_binprm *bprm, + * that not present xattr can be distinguished from a 0 + * length value or rule that matches any value + */ +- state = aa_dfa_null_transition(attach->xmatch.dfa, ++ state = aa_dfa_null_transition(attach->xmatch->dfa, + state); + /* Check xattr value */ +- state = aa_dfa_match_len(attach->xmatch.dfa, state, ++ state = aa_dfa_match_len(attach->xmatch->dfa, state, + value, size); +- index = ACCEPT_TABLE(attach->xmatch.dfa)[state]; +- perm = attach->xmatch.perms[index].allow; ++ index = ACCEPT_TABLE(attach->xmatch->dfa)[state]; ++ perm = attach->xmatch->perms[index].allow; + if (!(perm & MAY_EXEC)) { + ret = -EINVAL; + goto out; + } + } + /* transition to next element */ +- state = aa_dfa_outofband_transition(attach->xmatch.dfa, state); ++ state = aa_dfa_outofband_transition(attach->xmatch->dfa, state); + if (size < 0) { + /* + * No xattr match, so verify if transition to +@@ -412,16 +412,16 @@ static struct aa_label *find_attach(const struct linux_binprm *bprm, + * as another profile, signal a conflict and refuse to + * match. + */ +- if (attach->xmatch.dfa) { ++ if (attach->xmatch->dfa) { + unsigned int count; + aa_state_t state; + u32 index, perm; + +- state = aa_dfa_leftmatch(attach->xmatch.dfa, +- attach->xmatch.start[AA_CLASS_XMATCH], ++ state = aa_dfa_leftmatch(attach->xmatch->dfa, ++ attach->xmatch->start[AA_CLASS_XMATCH], + name, &count); +- index = ACCEPT_TABLE(attach->xmatch.dfa)[state]; +- perm = attach->xmatch.perms[index].allow; ++ index = ACCEPT_TABLE(attach->xmatch->dfa)[state]; ++ perm = attach->xmatch->perms[index].allow; + /* any accepting state means a valid match. */ + if (perm & MAY_EXEC) { + int ret = 0; +@@ -524,7 +524,7 @@ struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, + /* TODO: move lookup parsing to unpack time so this is a straight + * index into the resultant label + */ +- for (*name = rules->file.trans.table[index]; !label && *name; ++ for (*name = rules->file->trans.table[index]; !label && *name; + *name = next_name(xtype, *name)) { + if (xindex & AA_X_CHILD) { + struct aa_profile *new_profile; +@@ -577,7 +577,7 @@ static struct aa_label *x_to_label(struct aa_profile *profile, + break; + case AA_X_TABLE: + /* TODO: fix when perm mapping done at unload */ +- stack = rules->file.trans.table[xindex & AA_X_INDEX_MASK]; ++ stack = rules->file->trans.table[xindex & AA_X_INDEX_MASK]; + if (*stack != '&') { + /* released by caller */ + new = x_table_lookup(profile, xindex, lookupname); +@@ -636,7 +636,7 @@ static struct aa_label *profile_transition(const struct cred *subj_cred, + typeof(*rules), list); + struct aa_label *new = NULL; + const char *info = NULL, *name = NULL, *target = NULL; +- aa_state_t state = rules->file.start[AA_CLASS_FILE]; ++ aa_state_t state = rules->file->start[AA_CLASS_FILE]; + struct aa_perms perms = {}; + bool nonewprivs = false; + int error = 0; +@@ -670,7 +670,7 @@ static struct aa_label *profile_transition(const struct cred *subj_cred, + } + + /* find exec permissions for name */ +- state = aa_str_perms(&(rules->file), state, name, cond, &perms); ++ state = aa_str_perms(rules->file, state, name, cond, &perms); + if (perms.allow & MAY_EXEC) { + /* exec permission determine how to transition */ + new = x_to_label(profile, bprm, name, perms.xindex, &target, +@@ -736,7 +736,7 @@ static int profile_onexec(const struct cred *subj_cred, + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, + typeof(*rules), list); +- aa_state_t state = rules->file.start[AA_CLASS_FILE]; ++ aa_state_t state = rules->file->start[AA_CLASS_FILE]; + struct aa_perms perms = {}; + const char *xname = NULL, *info = "change_profile onexec"; + int error = -EACCES; +@@ -769,7 +769,7 @@ static int profile_onexec(const struct cred *subj_cred, + } + + /* find exec permissions for name */ +- state = aa_str_perms(&(rules->file), state, xname, cond, &perms); ++ state = aa_str_perms(rules->file, state, xname, cond, &perms); + if (!(perms.allow & AA_MAY_ONEXEC)) { + info = "no change_onexec valid for executable"; + goto audit; +@@ -778,7 +778,7 @@ static int profile_onexec(const struct cred *subj_cred, + * onexec permission is linked to exec with a standard pairing + * exec\0change_profile + */ +- state = aa_dfa_null_transition(rules->file.dfa, state); ++ state = aa_dfa_null_transition(rules->file->dfa, state); + error = change_profile_perms(profile, onexec, stack, AA_MAY_ONEXEC, + state, &perms); + if (error) { +@@ -1298,7 +1298,7 @@ static int change_profile_perms_wrapper(const char *op, const char *name, + + if (!error) + error = change_profile_perms(profile, target, stack, request, +- rules->file.start[AA_CLASS_FILE], ++ rules->file->start[AA_CLASS_FILE], + perms); + if (error) + error = aa_audit_file(subj_cred, profile, perms, op, request, +diff --git a/security/apparmor/file.c b/security/apparmor/file.c +index a51b83cf69689..e9e71d7bdcb6e 100644 +--- a/security/apparmor/file.c ++++ b/security/apparmor/file.c +@@ -236,7 +236,7 @@ static int __aa_path_perm(const char *op, const struct cred *subj_cred, + + if (profile_unconfined(profile)) + return 0; +- aa_str_perms(&(rules->file), rules->file.start[AA_CLASS_FILE], ++ aa_str_perms(rules->file, rules->file->start[AA_CLASS_FILE], + name, cond, perms); + if (request & ~perms->allow) + e = -EACCES; +@@ -353,16 +353,16 @@ static int profile_path_link(const struct cred *subj_cred, + + error = -EACCES; + /* aa_str_perms - handles the case of the dfa being NULL */ +- state = aa_str_perms(&(rules->file), +- rules->file.start[AA_CLASS_FILE], lname, ++ state = aa_str_perms(rules->file, ++ rules->file->start[AA_CLASS_FILE], lname, + cond, &lperms); + + if (!(lperms.allow & AA_MAY_LINK)) + goto audit; + + /* test to see if target can be paired with link */ +- state = aa_dfa_null_transition(rules->file.dfa, state); +- aa_str_perms(&(rules->file), state, tname, cond, &perms); ++ state = aa_dfa_null_transition(rules->file->dfa, state); ++ aa_str_perms(rules->file, state, tname, cond, &perms); + + /* force audit/quiet masks for link are stored in the second entry + * in the link pair. +@@ -384,7 +384,7 @@ static int profile_path_link(const struct cred *subj_cred, + /* Do link perm subset test requiring allowed permission on link are + * a subset of the allowed permissions on target. + */ +- aa_str_perms(&(rules->file), rules->file.start[AA_CLASS_FILE], ++ aa_str_perms(rules->file, rules->file->start[AA_CLASS_FILE], + tname, cond, &perms); + + /* AA_MAY_LINK is not considered in the subset test */ +diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h +index 6e88e99da80f6..1ec00113a056f 100644 +--- a/security/apparmor/include/lib.h ++++ b/security/apparmor/include/lib.h +@@ -16,6 +16,8 @@ + + #include "match.h" + ++extern struct aa_dfa *stacksplitdfa; ++ + /* + * DEBUG remains global (no per profile flag) since it is mostly used in sysctl + * which is not related to profile accesses. +diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h +index e59305abb85a3..ae31a8a631fc6 100644 +--- a/security/apparmor/include/match.h ++++ b/security/apparmor/include/match.h +@@ -102,9 +102,6 @@ struct aa_dfa { + struct table_header *tables[YYTD_ID_TSIZE]; + }; + +-extern struct aa_dfa *nulldfa; +-extern struct aa_dfa *stacksplitdfa; +- + #define byte_to_byte(X) (X) + + #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \ +@@ -122,9 +119,6 @@ static inline size_t table_size(size_t len, size_t el_size) + return ALIGN(sizeof(struct table_header) + len * el_size, 8); + } + +-int aa_setup_dfa_engine(void); +-void aa_teardown_dfa_engine(void); +- + #define aa_state_t unsigned int + + struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags); +diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h +index fa15a5c7febb8..bb682d5134129 100644 +--- a/security/apparmor/include/policy.h ++++ b/security/apparmor/include/policy.h +@@ -74,12 +74,14 @@ enum profile_mode { + + + /* struct aa_policydb - match engine for a policy ++ * count: refcount for the pdb + * dfa: dfa pattern match + * perms: table of permissions + * strs: table of strings, index by x + * start: set of start states for the different classes of data + */ + struct aa_policydb { ++ struct kref count; + struct aa_dfa *dfa; + struct { + struct aa_perms *perms; +@@ -89,13 +91,36 @@ struct aa_policydb { + aa_state_t start[AA_CLASS_LAST + 1]; + }; + +-static inline void aa_destroy_policydb(struct aa_policydb *policy) ++extern struct aa_policydb *nullpdb; ++ ++struct aa_policydb *aa_alloc_pdb(gfp_t gfp); ++void aa_pdb_free_kref(struct kref *kref); ++ ++/** ++ * aa_get_pdb - increment refcount on @pdb ++ * @pdb: policydb (MAYBE NULL) ++ * ++ * Returns: pointer to @pdb if @pdb is NULL will return NULL ++ * Requires: @pdb must be held with valid refcount when called ++ */ ++static inline struct aa_policydb *aa_get_pdb(struct aa_policydb *pdb) + { +- aa_put_dfa(policy->dfa); +- if (policy->perms) +- kvfree(policy->perms); +- aa_free_str_table(&policy->trans); ++ if (pdb) ++ kref_get(&(pdb->count)); + ++ return pdb; ++} ++ ++/** ++ * aa_put_pdb - put a pdb refcount ++ * @pdb: pdb to put refcount (MAYBE NULL) ++ * ++ * Requires: if @pdb != NULL that a valid refcount be held ++ */ ++static inline void aa_put_pdb(struct aa_policydb *pdb) ++{ ++ if (pdb) ++ kref_put(&pdb->count, aa_pdb_free_kref); + } + + static inline struct aa_perms *aa_lookup_perms(struct aa_policydb *policy, +@@ -139,8 +164,8 @@ struct aa_ruleset { + int size; + + /* TODO: merge policy and file */ +- struct aa_policydb policy; +- struct aa_policydb file; ++ struct aa_policydb *policy; ++ struct aa_policydb *file; + struct aa_caps caps; + + struct aa_rlimit rlimits; +@@ -159,7 +184,7 @@ struct aa_ruleset { + */ + struct aa_attachment { + const char *xmatch_str; +- struct aa_policydb xmatch; ++ struct aa_policydb *xmatch; + unsigned int xmatch_len; + int xattr_count; + char **xattrs; +@@ -276,10 +301,10 @@ static inline aa_state_t RULE_MEDIATES(struct aa_ruleset *rules, + unsigned char class) + { + if (class <= AA_CLASS_LAST) +- return rules->policy.start[class]; ++ return rules->policy->start[class]; + else +- return aa_dfa_match_len(rules->policy.dfa, +- rules->policy.start[0], &class, 1); ++ return aa_dfa_match_len(rules->policy->dfa, ++ rules->policy->start[0], &class, 1); + } + + static inline aa_state_t RULE_MEDIATES_AF(struct aa_ruleset *rules, u16 AF) +@@ -289,7 +314,7 @@ static inline aa_state_t RULE_MEDIATES_AF(struct aa_ruleset *rules, u16 AF) + + if (!state) + return DFA_NOMATCH; +- return aa_dfa_match_len(rules->policy.dfa, state, (char *) &be_af, 2); ++ return aa_dfa_match_len(rules->policy->dfa, state, (char *) &be_af, 2); + } + + static inline aa_state_t ANY_RULE_MEDIATES(struct list_head *head, +diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c +index c0d0dbd7b4c4b..0cdf4340b02d5 100644 +--- a/security/apparmor/ipc.c ++++ b/security/apparmor/ipc.c +@@ -92,8 +92,8 @@ static int profile_signal_perm(const struct cred *cred, + ad->subj_cred = cred; + ad->peer = peer; + /* TODO: secondary cache check */ +- state = aa_dfa_next(rules->policy.dfa, +- rules->policy.start[AA_CLASS_SIGNAL], ++ state = aa_dfa_next(rules->policy->dfa, ++ rules->policy->start[AA_CLASS_SIGNAL], + ad->signal); + aa_label_match(profile, rules, peer, state, false, request, &perms); + aa_apply_modes_to_perms(profile, &perms); +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 8a2af96f4da57..178eca800ddaf 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1269,14 +1269,14 @@ static inline aa_state_t match_component(struct aa_profile *profile, + const char *ns_name; + + if (profile->ns == tp->ns) +- return aa_dfa_match(rules->policy.dfa, state, tp->base.hname); ++ return aa_dfa_match(rules->policy->dfa, state, tp->base.hname); + + /* try matching with namespace name and then profile */ + ns_name = aa_ns_name(profile->ns, tp->ns, true); +- state = aa_dfa_match_len(rules->policy.dfa, state, ":", 1); +- state = aa_dfa_match(rules->policy.dfa, state, ns_name); +- state = aa_dfa_match_len(rules->policy.dfa, state, ":", 1); +- return aa_dfa_match(rules->policy.dfa, state, tp->base.hname); ++ state = aa_dfa_match_len(rules->policy->dfa, state, ":", 1); ++ state = aa_dfa_match(rules->policy->dfa, state, ns_name); ++ state = aa_dfa_match_len(rules->policy->dfa, state, ":", 1); ++ return aa_dfa_match(rules->policy->dfa, state, tp->base.hname); + } + + /** +@@ -1321,12 +1321,12 @@ static int label_compound_match(struct aa_profile *profile, + label_for_each_cont(i, label, tp) { + if (!aa_ns_visible(profile->ns, tp->ns, subns)) + continue; +- state = aa_dfa_match(rules->policy.dfa, state, "//&"); ++ state = aa_dfa_match(rules->policy->dfa, state, "//&"); + state = match_component(profile, rules, tp, state); + if (!state) + goto fail; + } +- *perms = *aa_lookup_perms(&rules->policy, state); ++ *perms = *aa_lookup_perms(rules->policy, state); + aa_apply_modes_to_perms(profile, perms); + if ((perms->allow & request) != request) + return -EACCES; +@@ -1379,7 +1379,7 @@ static int label_components_match(struct aa_profile *profile, + return 0; + + next: +- tmp = *aa_lookup_perms(&rules->policy, state); ++ tmp = *aa_lookup_perms(rules->policy, state); + aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + label_for_each_cont(i, label, tp) { +@@ -1388,7 +1388,7 @@ static int label_components_match(struct aa_profile *profile, + state = match_component(profile, rules, tp, start); + if (!state) + goto fail; +- tmp = *aa_lookup_perms(&rules->policy, state); ++ tmp = *aa_lookup_perms(rules->policy, state); + aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + } +diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c +index 7182a8b821fbd..cd569fbbfe36d 100644 +--- a/security/apparmor/lib.c ++++ b/security/apparmor/lib.c +@@ -342,8 +342,8 @@ void aa_profile_match_label(struct aa_profile *profile, + /* TODO: doesn't yet handle extended types */ + aa_state_t state; + +- state = aa_dfa_next(rules->policy.dfa, +- rules->policy.start[AA_CLASS_LABEL], ++ state = aa_dfa_next(rules->policy->dfa, ++ rules->policy->start[AA_CLASS_LABEL], + type); + aa_label_match(profile, rules, label, state, false, request, perms); + } +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 5303a51eff9c1..641f6510d7cb0 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -1909,6 +1909,69 @@ static int __init apparmor_nf_ip_init(void) + __initcall(apparmor_nf_ip_init); + #endif + ++static char nulldfa_src[] = { ++ #include "nulldfa.in" ++}; ++struct aa_dfa *nulldfa; ++ ++static char stacksplitdfa_src[] = { ++ #include "stacksplitdfa.in" ++}; ++struct aa_dfa *stacksplitdfa; ++struct aa_policydb *nullpdb; ++ ++static int __init aa_setup_dfa_engine(void) ++{ ++ int error = -ENOMEM; ++ ++ nullpdb = aa_alloc_pdb(GFP_KERNEL); ++ if (!nullpdb) ++ return -ENOMEM; ++ ++ nulldfa = aa_dfa_unpack(nulldfa_src, sizeof(nulldfa_src), ++ TO_ACCEPT1_FLAG(YYTD_DATA32) | ++ TO_ACCEPT2_FLAG(YYTD_DATA32)); ++ if (IS_ERR(nulldfa)) { ++ error = PTR_ERR(nulldfa); ++ goto fail; ++ } ++ nullpdb->dfa = aa_get_dfa(nulldfa); ++ nullpdb->perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL); ++ if (!nullpdb->perms) ++ goto fail; ++ nullpdb->size = 2; ++ ++ stacksplitdfa = aa_dfa_unpack(stacksplitdfa_src, ++ sizeof(stacksplitdfa_src), ++ TO_ACCEPT1_FLAG(YYTD_DATA32) | ++ TO_ACCEPT2_FLAG(YYTD_DATA32)); ++ if (IS_ERR(stacksplitdfa)) { ++ error = PTR_ERR(stacksplitdfa); ++ goto fail; ++ } ++ ++ return 0; ++ ++fail: ++ aa_put_pdb(nullpdb); ++ aa_put_dfa(nulldfa); ++ nullpdb = NULL; ++ nulldfa = NULL; ++ stacksplitdfa = NULL; ++ ++ return error; ++} ++ ++static void __init aa_teardown_dfa_engine(void) ++{ ++ aa_put_dfa(stacksplitdfa); ++ aa_put_dfa(nulldfa); ++ aa_put_pdb(nullpdb); ++ nullpdb = NULL; ++ stacksplitdfa = NULL; ++ nulldfa = NULL; ++} ++ + static int __init apparmor_init(void) + { + int error; +diff --git a/security/apparmor/match.c b/security/apparmor/match.c +index 3667b79e9366b..6f6cdb86f32b5 100644 +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -21,50 +21,6 @@ + + #define base_idx(X) ((X) & 0xffffff) + +-static char nulldfa_src[] = { +- #include "nulldfa.in" +-}; +-struct aa_dfa *nulldfa; +- +-static char stacksplitdfa_src[] = { +- #include "stacksplitdfa.in" +-}; +-struct aa_dfa *stacksplitdfa; +- +-int __init aa_setup_dfa_engine(void) +-{ +- int error; +- +- nulldfa = aa_dfa_unpack(nulldfa_src, sizeof(nulldfa_src), +- TO_ACCEPT1_FLAG(YYTD_DATA32) | +- TO_ACCEPT2_FLAG(YYTD_DATA32)); +- if (IS_ERR(nulldfa)) { +- error = PTR_ERR(nulldfa); +- nulldfa = NULL; +- return error; +- } +- +- stacksplitdfa = aa_dfa_unpack(stacksplitdfa_src, +- sizeof(stacksplitdfa_src), +- TO_ACCEPT1_FLAG(YYTD_DATA32) | +- TO_ACCEPT2_FLAG(YYTD_DATA32)); +- if (IS_ERR(stacksplitdfa)) { +- aa_put_dfa(nulldfa); +- nulldfa = NULL; +- error = PTR_ERR(stacksplitdfa); +- stacksplitdfa = NULL; +- return error; +- } +- +- return 0; +-} +- +-void __init aa_teardown_dfa_engine(void) +-{ +- aa_put_dfa(stacksplitdfa); +- aa_put_dfa(nulldfa); +-} +- + /** + * unpack_table - unpack a dfa table (one of accept, default, base, next check) + * @blob: data to unpack (NOT NULL) +diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c +index cb0fdbdb82d94..49fe8da6fea45 100644 +--- a/security/apparmor/mount.c ++++ b/security/apparmor/mount.c +@@ -332,8 +332,8 @@ static int match_mnt_path_str(const struct cred *subj_cred, + } + + error = -EACCES; +- pos = do_match_mnt(&rules->policy, +- rules->policy.start[AA_CLASS_MOUNT], ++ pos = do_match_mnt(rules->policy, ++ rules->policy->start[AA_CLASS_MOUNT], + mntpnt, devname, type, flags, data, binary, &perms); + if (pos) { + info = mnt_info_table[pos]; +@@ -620,10 +620,10 @@ static int profile_umount(const struct cred *subj_cred, + if (error) + goto audit; + +- state = aa_dfa_match(rules->policy.dfa, +- rules->policy.start[AA_CLASS_MOUNT], ++ state = aa_dfa_match(rules->policy->dfa, ++ rules->policy->start[AA_CLASS_MOUNT], + name); +- perms = *aa_lookup_perms(&rules->policy, state); ++ perms = *aa_lookup_perms(rules->policy, state); + if (AA_MAY_UMOUNT & ~perms.allow) + error = -EACCES; + +@@ -694,12 +694,12 @@ static struct aa_label *build_pivotroot(const struct cred *subj_cred, + goto audit; + + error = -EACCES; +- state = aa_dfa_match(rules->policy.dfa, +- rules->policy.start[AA_CLASS_MOUNT], ++ state = aa_dfa_match(rules->policy->dfa, ++ rules->policy->start[AA_CLASS_MOUNT], + new_name); +- state = aa_dfa_null_transition(rules->policy.dfa, state); +- state = aa_dfa_match(rules->policy.dfa, state, old_name); +- perms = *aa_lookup_perms(&rules->policy, state); ++ state = aa_dfa_null_transition(rules->policy->dfa, state); ++ state = aa_dfa_match(rules->policy->dfa, state, old_name); ++ perms = *aa_lookup_perms(rules->policy, state); + + if (AA_MAY_PIVOTROOT & perms.allow) + error = 0; +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 814e8319d43e0..3e632700d06fb 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -127,9 +127,9 @@ int aa_profile_af_perm(struct aa_profile *profile, + + buffer[0] = cpu_to_be16(family); + buffer[1] = cpu_to_be16((u16) type); +- state = aa_dfa_match_len(rules->policy.dfa, state, (char *) &buffer, ++ state = aa_dfa_match_len(rules->policy->dfa, state, (char *) &buffer, + 4); +- perms = *aa_lookup_perms(&rules->policy, state); ++ perms = *aa_lookup_perms(rules->policy, state); + aa_apply_modes_to_perms(profile, &perms); + + return aa_check_perms(profile, &perms, request, ad, audit_net_cb); +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index adf38e592bd4b..009fa7cfb6688 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -98,6 +98,41 @@ const char *const aa_profile_mode_names[] = { + }; + + ++static void aa_free_pdb(struct aa_policydb *policy) ++{ ++ if (policy) { ++ aa_put_dfa(policy->dfa); ++ if (policy->perms) ++ kvfree(policy->perms); ++ aa_free_str_table(&policy->trans); ++ } ++} ++ ++/** ++ * aa_pdb_free_kref - free aa_policydb by kref (called by aa_put_pdb) ++ * @kr: kref callback for freeing of a dfa (NOT NULL) ++ */ ++void aa_pdb_free_kref(struct kref *kref) ++{ ++ struct aa_policydb *pdb = container_of(kref, struct aa_policydb, count); ++ ++ aa_free_pdb(pdb); ++} ++ ++ ++struct aa_policydb *aa_alloc_pdb(gfp_t gfp) ++{ ++ struct aa_policydb *pdb = kzalloc(sizeof(struct aa_policydb), gfp); ++ ++ if (!pdb) ++ return NULL; ++ ++ kref_init(&pdb->count); ++ ++ return pdb; ++} ++ ++ + /** + * __add_profile - add a profiles to list and label tree + * @list: list to add it to (NOT NULL) +@@ -200,15 +235,15 @@ static void free_attachment(struct aa_attachment *attach) + for (i = 0; i < attach->xattr_count; i++) + kfree_sensitive(attach->xattrs[i]); + kfree_sensitive(attach->xattrs); +- aa_destroy_policydb(&attach->xmatch); ++ aa_put_pdb(attach->xmatch); + } + + static void free_ruleset(struct aa_ruleset *rules) + { + int i; + +- aa_destroy_policydb(&rules->file); +- aa_destroy_policydb(&rules->policy); ++ aa_put_pdb(rules->file); ++ aa_put_pdb(rules->policy); + aa_free_cap_rules(&rules->caps); + aa_free_rlimit_rules(&rules->rlimits); + +@@ -590,16 +625,8 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name, + /* TODO: ideally we should inherit abi from parent */ + profile->label.flags |= FLAG_NULL; + rules = list_first_entry(&profile->rules, typeof(*rules), list); +- rules->file.dfa = aa_get_dfa(nulldfa); +- rules->file.perms = kcalloc(2, sizeof(struct aa_perms), gfp); +- if (!rules->file.perms) +- goto fail; +- rules->file.size = 2; +- rules->policy.dfa = aa_get_dfa(nulldfa); +- rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), gfp); +- if (!rules->policy.perms) +- goto fail; +- rules->policy.size = 2; ++ rules->file = aa_get_pdb(nullpdb); ++ rules->policy = aa_get_pdb(nullpdb); + + if (parent) { + profile->path_flags = parent->path_flags; +@@ -610,11 +637,6 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name, + } + + return profile; +- +-fail: +- aa_free_profile(profile); +- +- return NULL; + } + + /** +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index cefda5e5b6ed0..9b25624285e67 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -707,24 +707,29 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms) + return -EPROTO; + } + +-static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy, ++static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy, + bool required_dfa, bool required_trans, + const char **info) + { ++ struct aa_policydb *pdb; + void *pos = e->pos; + int i, flags, error = -EPROTO; + ssize_t size; + +- size = unpack_perms_table(e, &policy->perms); ++ pdb = aa_alloc_pdb(GFP_KERNEL); ++ if (!pdb) ++ return -ENOMEM; ++ ++ size = unpack_perms_table(e, &pdb->perms); + if (size < 0) { + error = size; +- policy->perms = NULL; ++ pdb->perms = NULL; + *info = "failed to unpack - perms"; + goto fail; + } +- policy->size = size; ++ pdb->size = size; + +- if (policy->perms) { ++ if (pdb->perms) { + /* perms table present accept is index */ + flags = TO_ACCEPT1_FLAG(YYTD_DATA32); + } else { +@@ -733,13 +738,13 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy, + TO_ACCEPT2_FLAG(YYTD_DATA32); + } + +- policy->dfa = unpack_dfa(e, flags); +- if (IS_ERR(policy->dfa)) { +- error = PTR_ERR(policy->dfa); +- policy->dfa = NULL; ++ pdb->dfa = unpack_dfa(e, flags); ++ if (IS_ERR(pdb->dfa)) { ++ error = PTR_ERR(pdb->dfa); ++ pdb->dfa = NULL; + *info = "failed to unpack - dfa"; + goto fail; +- } else if (!policy->dfa) { ++ } else if (!pdb->dfa) { + if (required_dfa) { + *info = "missing required dfa"; + goto fail; +@@ -753,18 +758,18 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy, + * sadly start was given different names for file and policydb + * but since it is optional we can try both + */ +- if (!aa_unpack_u32(e, &policy->start[0], "start")) ++ if (!aa_unpack_u32(e, &pdb->start[0], "start")) + /* default start state */ +- policy->start[0] = DFA_START; +- if (!aa_unpack_u32(e, &policy->start[AA_CLASS_FILE], "dfa_start")) { ++ pdb->start[0] = DFA_START; ++ if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], "dfa_start")) { + /* default start state for xmatch and file dfa */ +- policy->start[AA_CLASS_FILE] = DFA_START; ++ pdb->start[AA_CLASS_FILE] = DFA_START; + } /* setup class index */ + for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) { +- policy->start[i] = aa_dfa_next(policy->dfa, policy->start[0], ++ pdb->start[i] = aa_dfa_next(pdb->dfa, pdb->start[0], + i); + } +- if (!unpack_trans_table(e, &policy->trans) && required_trans) { ++ if (!unpack_trans_table(e, &pdb->trans) && required_trans) { + *info = "failed to unpack profile transition table"; + goto fail; + } +@@ -772,9 +777,11 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy, + /* TODO: move compat mapping here, requires dfa merging first */ + /* TODO: move verify here, it has to be done after compat mappings */ + out: ++ *policy = pdb; + return 0; + + fail: ++ aa_put_pdb(pdb); + e->pos = pos; + return error; + } +@@ -862,15 +869,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) + } + + /* neither xmatch_len not xmatch_perms are optional if xmatch is set */ +- if (profile->attach.xmatch.dfa) { ++ if (profile->attach.xmatch->dfa) { + if (!aa_unpack_u32(e, &tmp, NULL)) { + info = "missing xmatch len"; + goto fail; + } + profile->attach.xmatch_len = tmp; +- profile->attach.xmatch.start[AA_CLASS_XMATCH] = DFA_START; +- if (!profile->attach.xmatch.perms) { +- error = aa_compat_map_xmatch(&profile->attach.xmatch); ++ profile->attach.xmatch->start[AA_CLASS_XMATCH] = DFA_START; ++ if (!profile->attach.xmatch->perms) { ++ error = aa_compat_map_xmatch(profile->attach.xmatch); + if (error) { + info = "failed to convert xmatch permission table"; + goto fail; +@@ -987,16 +994,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) + if (error) + goto fail; + /* Fixup: drop when we get rid of start array */ +- if (aa_dfa_next(rules->policy.dfa, rules->policy.start[0], ++ if (aa_dfa_next(rules->policy->dfa, rules->policy->start[0], + AA_CLASS_FILE)) +- rules->policy.start[AA_CLASS_FILE] = +- aa_dfa_next(rules->policy.dfa, +- rules->policy.start[0], ++ rules->policy->start[AA_CLASS_FILE] = ++ aa_dfa_next(rules->policy->dfa, ++ rules->policy->start[0], + AA_CLASS_FILE); + if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) + goto fail; +- if (!rules->policy.perms) { +- error = aa_compat_map_policy(&rules->policy, ++ if (!rules->policy->perms) { ++ error = aa_compat_map_policy(rules->policy, + e->version); + if (error) { + info = "failed to remap policydb permission table"; +@@ -1004,44 +1011,25 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) + } + } + } else { +- rules->policy.dfa = aa_get_dfa(nulldfa); +- rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), +- GFP_KERNEL); +- if (!rules->policy.perms) +- goto fail; +- rules->policy.size = 2; ++ rules->policy = aa_get_pdb(nullpdb); + } + /* get file rules */ + error = unpack_pdb(e, &rules->file, false, true, &info); + if (error) { + goto fail; +- } else if (rules->file.dfa) { +- if (!rules->file.perms) { +- error = aa_compat_map_file(&rules->file); ++ } else if (rules->file->dfa) { ++ if (!rules->file->perms) { ++ error = aa_compat_map_file(rules->file); + if (error) { + info = "failed to remap file permission table"; + goto fail; + } + } +- } else if (rules->policy.dfa && +- rules->policy.start[AA_CLASS_FILE]) { +- rules->file.dfa = aa_get_dfa(rules->policy.dfa); +- rules->file.start[AA_CLASS_FILE] = rules->policy.start[AA_CLASS_FILE]; +- rules->file.perms = kcalloc(rules->policy.size, +- sizeof(struct aa_perms), +- GFP_KERNEL); +- if (!rules->file.perms) +- goto fail; +- memcpy(rules->file.perms, rules->policy.perms, +- rules->policy.size * sizeof(struct aa_perms)); +- rules->file.size = rules->policy.size; ++ } else if (rules->policy->dfa && ++ rules->policy->start[AA_CLASS_FILE]) { ++ rules->file = aa_get_pdb(rules->policy); + } else { +- rules->file.dfa = aa_get_dfa(nulldfa); +- rules->file.perms = kcalloc(2, sizeof(struct aa_perms), +- GFP_KERNEL); +- if (!rules->file.perms) +- goto fail; +- rules->file.size = 2; ++ rules->file = aa_get_pdb(nullpdb); + } + error = -EPROTO; + if (aa_unpack_nameX(e, AA_STRUCT, "data")) { +@@ -1249,32 +1237,32 @@ static int verify_profile(struct aa_profile *profile) + if (!rules) + return 0; + +- if (rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa, +- rules->file.size)) { ++ if (rules->file->dfa && !verify_dfa_accept_index(rules->file->dfa, ++ rules->file->size)) { + audit_iface(profile, NULL, NULL, + "Unpack: file Invalid named transition", NULL, + -EPROTO); + return -EPROTO; + } +- if (rules->policy.dfa && +- !verify_dfa_accept_index(rules->policy.dfa, rules->policy.size)) { ++ if (rules->policy->dfa && ++ !verify_dfa_accept_index(rules->policy->dfa, rules->policy->size)) { + audit_iface(profile, NULL, NULL, + "Unpack: policy Invalid named transition", NULL, + -EPROTO); + return -EPROTO; + } + +- if (!verify_perms(&rules->file)) { ++ if (!verify_perms(rules->file)) { + audit_iface(profile, NULL, NULL, + "Unpack: Invalid perm index", NULL, -EPROTO); + return -EPROTO; + } +- if (!verify_perms(&rules->policy)) { ++ if (!verify_perms(rules->policy)) { + audit_iface(profile, NULL, NULL, + "Unpack: Invalid perm index", NULL, -EPROTO); + return -EPROTO; + } +- if (!verify_perms(&profile->attach.xmatch)) { ++ if (!verify_perms(profile->attach.xmatch)) { + audit_iface(profile, NULL, NULL, + "Unpack: Invalid perm index", NULL, -EPROTO); + return -EPROTO; +-- +2.51.0 + diff --git a/queue-6.6/apparmor-remove-apply_modes_to_perms-from-label_matc.patch b/queue-6.6/apparmor-remove-apply_modes_to_perms-from-label_matc.patch new file mode 100644 index 0000000000..233660bc12 --- /dev/null +++ b/queue-6.6/apparmor-remove-apply_modes_to_perms-from-label_matc.patch @@ -0,0 +1,53 @@ +From e5e786ec71fa9e7ef2e76340eba31e06f66dbaf1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 00:14:36 -0800 +Subject: apparmor: remove apply_modes_to_perms from label_match + +From: John Johansen + +[ Upstream commit b2e27be2948f2f8c38421cd554b5fc9383215648 ] + +The modes shouldn't be applied at the point of label match, it just +results in them being applied multiple times. Instead they should be +applied after which is already being done by all callers so it can +just be dropped from label_match. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value") +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 178eca800ddaf..217bd6709023f 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -1327,7 +1327,6 @@ static int label_compound_match(struct aa_profile *profile, + goto fail; + } + *perms = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, perms); + if ((perms->allow & request) != request) + return -EACCES; + +@@ -1380,7 +1379,6 @@ static int label_components_match(struct aa_profile *profile, + + next: + tmp = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + label_for_each_cont(i, label, tp) { + if (!aa_ns_visible(profile->ns, tp->ns, subns)) +@@ -1389,7 +1387,6 @@ static int label_components_match(struct aa_profile *profile, + if (!state) + goto fail; + tmp = *aa_lookup_perms(rules->policy, state); +- aa_apply_modes_to_perms(profile, &tmp); + aa_perms_accum(perms, &tmp); + } + +-- +2.51.0 + diff --git a/queue-6.6/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch b/queue-6.6/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch new file mode 100644 index 0000000000..f4f729a9d6 --- /dev/null +++ b/queue-6.6/apparmor-return-enomem-in-unpack_perms_table-upon-al.patch @@ -0,0 +1,44 @@ +From 6fab80771ba41f414c7aa0f4ebaaf0a024cab4fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Jan 2026 09:35:57 -0800 +Subject: apparmor: return -ENOMEM in unpack_perms_table upon alloc failure + +From: Ryan Lee + +[ Upstream commit 74b7105e53e80a4072bd3e1a50be7aa15e3f0a01 ] + +In policy_unpack.c:unpack_perms_table, the perms struct is allocated via +kcalloc, with the position being reset if the allocation fails. However, +the error path results in -EPROTO being retured instead of -ENOMEM. Fix +this to return the correct error code. + +Reported-by: Zygmunt Krynicki +Fixes: fd1b2b95a2117 ("apparmor: add the ability for policy to specify a permission table") +Reviewed-by: Tyler Hicks +Signed-off-by: Ryan Lee +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/policy_unpack.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index d752bfa9b3f37..a1de48c2d826b 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -683,8 +683,10 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms) + if (!aa_unpack_array(e, NULL, &size)) + goto fail_reset; + *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL); +- if (!*perms) +- goto fail_reset; ++ if (!*perms) { ++ e->pos = pos; ++ return -ENOMEM; ++ } + for (i = 0; i < size; i++) { + if (!unpack_perm(e, version, &(*perms)[i])) + goto fail; +-- +2.51.0 + diff --git a/queue-6.6/apparmor-use-passed-in-gfp-flags-in-aa_alloc_null.patch b/queue-6.6/apparmor-use-passed-in-gfp-flags-in-aa_alloc_null.patch new file mode 100644 index 0000000000..7db1a0f4c3 --- /dev/null +++ b/queue-6.6/apparmor-use-passed-in-gfp-flags-in-aa_alloc_null.patch @@ -0,0 +1,44 @@ +From 68d2bfabc7dd14f889d5868067f64d2de93523ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Jun 2023 16:02:04 +0300 +Subject: apparmor: use passed in gfp flags in aa_alloc_null() + +From: Dan Carpenter + +[ Upstream commit afad53575a938ceb557227ecfeb0dda59d668d4e ] + +These allocations should use the gfp flags from the caller instead of +GFP_KERNEL. But from what I can see, all the callers pass in GFP_KERNEL +so this does not affect runtime. + +Fixes: e31dd6e412f7 ("apparmor: fix: kzalloc perms tables for shared dfas") +Signed-off-by: Dan Carpenter +Signed-off-by: John Johansen +Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value") +Signed-off-by: Sasha Levin +--- + security/apparmor/policy.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index d9d3b3d776e11..adf38e592bd4b 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -591,12 +591,12 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name, + profile->label.flags |= FLAG_NULL; + rules = list_first_entry(&profile->rules, typeof(*rules), list); + rules->file.dfa = aa_get_dfa(nulldfa); +- rules->file.perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL); ++ rules->file.perms = kcalloc(2, sizeof(struct aa_perms), gfp); + if (!rules->file.perms) + goto fail; + rules->file.size = 2; + rules->policy.dfa = aa_get_dfa(nulldfa); +- rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL); ++ rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), gfp); + if (!rules->policy.perms) + goto fail; + rules->policy.size = 2; +-- +2.51.0 + diff --git a/queue-6.6/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch b/queue-6.6/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch new file mode 100644 index 0000000000..0a19fdb17a --- /dev/null +++ b/queue-6.6/asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch @@ -0,0 +1,49 @@ +From a7671d73ab3201f7f0ea4bd3559afd488d25a22b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 11:27:32 +0100 +Subject: ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init + +From: Alexandre Ferrieux + +[ Upstream commit b82fa9b0c26eeb2fde6017f7de2c3c544484efef ] + +The aw88261_dev_reg_update() function sets the Awinic registers in a +rather nonuniform way: + - most registers get directly overwritten from the firmware blob + - but a handful of them need more delicate logic to preserve + some bits from their current value, according to a register- + specific mask +For the latter, the logic is basically + NEW = (OLD & MASK) | (VAL & ~MASK) +However, the ~MASK value is hand-computed, and in the specific case +of the SYSCTRL register, in a buggy way. +This patch restores the proper ~MASK value. + +Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver") +Signed-off-by: Alexandre Ferrieux +Link: https://patch.msgid.link/20260211-aw88261-fwname-v1-1-e24e833a019d@fairphone.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/aw88261.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c +index a697b5006b45b..f2a9c33ff4a64 100644 +--- a/sound/soc/codecs/aw88261.c ++++ b/sound/soc/codecs/aw88261.c +@@ -424,9 +424,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261, + if (ret) + break; + ++ /* keep all three bits from current hw status */ + read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) | + (~AW88261_HMUTE_MASK); +- reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK); ++ reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK); + reg_val |= read_val; + + /* enable uls hmute */ +-- +2.51.0 + diff --git a/queue-6.6/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch b/queue-6.6/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch new file mode 100644 index 0000000000..180a38ddb8 --- /dev/null +++ b/queue-6.6/asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch @@ -0,0 +1,52 @@ +From 1e0c54e25553a31008eeb53d713ee0de3f811860 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 18:57:14 +0000 +Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put() + +From: Ziyi Guo + +[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ] + +This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()"). + +The original patch attempted to acquire the card->controls_rwsem lock in +fsl_xcvr_mode_put(). However, this function is called from the upper ALSA +core function snd_ctl_elem_write(), which already holds the write lock on +controls_rwsem for the whole put operation. So there is no need to simply +hold the lock for fsl_xcvr_activate_ctl() again. + +Acquiring the read lock while holding the write lock in the same thread +results in a deadlock and a hung task, as reported by Alexander Stein. + +Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()") +Reported-by: Alexander Stein +Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/ +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 3a5ab8b536728..90a0a24c05d84 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -206,13 +206,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, + + xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); + +- down_read(&card->snd_card->controls_rwsem); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_ARC)); + fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, + (xcvr->mode == FSL_XCVR_MODE_EARC)); +- up_read(&card->snd_card->controls_rwsem); +- + /* Allow playback for SPDIF only */ + rtd = snd_soc_get_pcm_runtime(card, card->dai_link); + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = +-- +2.51.0 + diff --git a/queue-6.6/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch b/queue-6.6/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch new file mode 100644 index 0000000000..654efa8b59 --- /dev/null +++ b/queue-6.6/asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch @@ -0,0 +1,55 @@ +From 05e357a33eeb1ecc759cf817138a98ad50e777ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 15:18:34 -0500 +Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk + +From: Detlev Casanova + +[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ] + +Drivers will not always call set_sysclk() for all clocks, especially when +default mclk-fs can be used. +When that is the case, use the clock rate set in the params multiplied by the +default mclk-fs. + +Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback") +Signed-off-by: Detlev Casanova +Reported-by: Luca Ceresoli +Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c +index 7ae93cbaea9a7..15ef6b6bec2bb 100644 +--- a/sound/soc/rockchip/rockchip_i2s_tdm.c ++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c +@@ -24,6 +24,7 @@ + + #define DRV_NAME "rockchip-i2s-tdm" + ++#define DEFAULT_MCLK_FS 256 + #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ + #define MULTIPLEX_CH_MAX 10 + +@@ -695,6 +696,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, + mclk_rate = i2s_tdm->mclk_rx_freq; + } + ++ /* ++ * When the dai/component driver doesn't need to set mclk-fs for a specific ++ * clock, it can skip the call to set_sysclk() for that clock. ++ * In that case, simply use the clock rate from the params and multiply it by ++ * the default mclk-fs value. ++ */ ++ if (!mclk_rate) ++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params); ++ + err = clk_set_rate(mclk, mclk_rate); + if (err) + return err; +-- +2.51.0 + diff --git a/queue-6.6/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch b/queue-6.6/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch new file mode 100644 index 0000000000..eb20caea0f --- /dev/null +++ b/queue-6.6/bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch @@ -0,0 +1,108 @@ +From f94e9c79f37cc6c86dfdb5863c9369721c19eebb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 06:09:19 +0000 +Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down + +From: Hangbin Liu + +[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ] + +The ALB RX path may access rx_hashtbl concurrently with bond +teardown. During rapid bond up/down cycles, rlb_deinitialize() +frees rx_hashtbl while RX handlers are still running, leading +to a null pointer dereference detected by KASAN. + +However, the root cause is that rlb_arp_recv() can still be accessed +after setting recv_probe to NULL, which is actually a use-after-free +(UAF) issue. That is the reason for using the referenced commit in the +Fixes tag. + +[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI +[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef] +[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary) +[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022 +[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding] +[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6 + 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00 +[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206 +[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e +[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8 +[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8 +[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119 +[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810 +[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000 +[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0 +[ 214.310347] Call Trace: +[ 214.313070] +[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding] +[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding] +[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding] +[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710 +[ 214.339199] ? __pfx_arp_process+0x10/0x10 +[ 214.343775] ? sched_balance_find_src_group+0x98/0x630 +[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10 +[ 214.356513] ? arp_rcv+0x307/0x690 +[ 214.360311] ? __pfx_arp_rcv+0x10/0x10 +[ 214.364499] ? __lock_acquire+0x58c/0xbd0 +[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0 +[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10 +[ 214.380743] ? lock_acquire+0x10b/0x140 +[ 214.385026] process_backlog+0x3f1/0x13a0 +[ 214.389502] ? process_backlog+0x3aa/0x13a0 +[ 214.394174] __napi_poll.constprop.0+0x9f/0x370 +[ 214.399233] net_rx_action+0x8c1/0xe60 +[ 214.403423] ? __pfx_net_rx_action+0x10/0x10 +[ 214.408193] ? lock_acquire.part.0+0xbd/0x260 +[ 214.413058] ? sched_clock_cpu+0x6c/0x540 +[ 214.417540] ? mark_held_locks+0x40/0x70 +[ 214.421920] handle_softirqs+0x1fd/0x860 +[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10 +[ 214.431264] ? __neigh_event_send+0x2d6/0xf50 +[ 214.436131] do_softirq+0xb1/0xf0 +[ 214.439830] + +The issue is reproducible by repeatedly running +ip link set bond0 up/down while receiving ARP messages, where +rlb_arp_recv() can race with rlb_deinitialize() and dereference +a freed rx_hashtbl entry. + +Fix this by setting recv_probe to NULL and then calling +synchronize_net() to wait for any concurrent RX processing to finish. +This ensures that no RX handler can access rx_hashtbl after it is freed +in bond_alb_deinitialize(). + +Reported-by: Liang Li +Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()") +Reviewed-by: Nikolay Aleksandrov +Acked-by: Jay Vosburgh +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 4f8a59b4ba985..836d7fcac71a1 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4401,9 +4401,13 @@ static int bond_close(struct net_device *bond_dev) + + bond_work_cancel_all(bond); + bond->send_peer_notif = 0; ++ WRITE_ONCE(bond->recv_probe, NULL); ++ ++ /* Wait for any in-flight RX handlers */ ++ synchronize_net(); ++ + if (bond_is_lb(bond)) + bond_alb_deinitialize(bond); +- bond->recv_probe = NULL; + + if (bond_uses_primary(bond)) { + rcu_read_lock(); +-- +2.51.0 + diff --git a/queue-6.6/bpftool-fix-truncated-netlink-dumps.patch b/queue-6.6/bpftool-fix-truncated-netlink-dumps.patch new file mode 100644 index 0000000000..3e5ec1a799 --- /dev/null +++ b/queue-6.6/bpftool-fix-truncated-netlink-dumps.patch @@ -0,0 +1,73 @@ +From 239922eabf1763cf5c95985a2a87008f035dac3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 11:41:50 -0800 +Subject: bpftool: Fix truncated netlink dumps + +From: Jakub Kicinski + +[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ] + +Netlink requires that the recv buffer used during dumps is at least +min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will +get truncated. Make sure bpftool follows this requirement, avoid +missing information on systems with large pages. + +Acked-by: Quentin Monnet +Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool") +Signed-off-by: Jakub Kicinski +Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/net.c | 5 ++++- + tools/lib/bpf/netlink.c | 4 +++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c +index c2ca82fc21e21..225d3678b4ed1 100644 +--- a/tools/bpf/bpftool/net.c ++++ b/tools/bpf/bpftool/net.c +@@ -150,7 +150,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + bool multipart = true; + struct nlmsgerr *err; + struct nlmsghdr *nh; +- char buf[4096]; ++ char buf[8192]; + int len, ret; + + while (multipart) { +@@ -195,6 +195,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, + return ret; + } + } ++ ++ if (len) ++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len); + } + ret = 0; + done: +diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c +index 68a2def171751..6f16c4f7b3a43 100644 +--- a/tools/lib/bpf/netlink.c ++++ b/tools/lib/bpf/netlink.c +@@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + struct nlmsghdr *nh; + int len, ret; + +- ret = alloc_iov(&iov, 4096); ++ ret = alloc_iov(&iov, 8192); + if (ret) + goto done; + +@@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, + } + } + } ++ if (len) ++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len); + } + ret = 0; + done: +-- +2.51.0 + diff --git a/queue-6.6/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch b/queue-6.6/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch new file mode 100644 index 0000000000..a9c2ae85ad --- /dev/null +++ b/queue-6.6/btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch @@ -0,0 +1,52 @@ +From 67764adc21f2039c89a49ada675c7fddc0bb254e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Feb 2026 17:15:53 +0000 +Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not + found + +From: Filipe Manana + +[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ] + +If btrfs_search_slot_for_read() returns 1, it means we did not find any +key greater than or equals to the key we asked for, meaning we have +reached the end of the tree and therefore the path is not valid. If +this happens we need to break out of the loop and stop, instead of +continuing and accessing an invalid path. + +Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/qgroup.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index d27b9e0fa229a..622febdb61e23 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1129,11 +1129,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) + } + if (ret > 0) { + /* +- * Shouldn't happen, but in case it does we +- * don't need to do the btrfs_next_item, just +- * continue. ++ * Shouldn't happen because the key should still ++ * be there (return 0), but in case it does it ++ * means we have reached the end of the tree - ++ * there are no more leaves with items that have ++ * a key greater than or equals to @found_key, ++ * so just stop the search loop. + */ +- continue; ++ break; + } + } + ret = btrfs_next_item(tree_root, path); +-- +2.51.0 + diff --git a/queue-6.6/cache-add-__cacheline_group_-begin-end-_aligned-coup.patch b/queue-6.6/cache-add-__cacheline_group_-begin-end-_aligned-coup.patch new file mode 100644 index 0000000000..74efce80d3 --- /dev/null +++ b/queue-6.6/cache-add-__cacheline_group_-begin-end-_aligned-coup.patch @@ -0,0 +1,131 @@ +From a0b244ec9e689e1d33dcd1baaccae5c6870b4446 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jun 2024 15:53:34 +0200 +Subject: cache: add __cacheline_group_{begin, end}_aligned() (+ couple more) + +From: Alexander Lobakin + +[ Upstream commit 2cb13dec8c5e5e104fd2f71c2dee761d6ed9a333 ] + +__cacheline_group_begin(), unfortunately, doesn't align the group +anyhow. If it is wanted, then you need to do something like + +__cacheline_group_begin(grp) __aligned(ALIGN) + +which isn't really convenient nor compact. +Add the _aligned() counterparts to align the groups automatically to +either the specified alignment (optional) or ``SMP_CACHE_BYTES``. +Note that the actual struct layout will then be (on x64 with 64-byte CL): + +struct x { + u32 y; // offset 0, size 4, padding 56 + __cacheline_group_begin__grp; // offset 64, size 0 + u32 z; // offset 64, size 4, padding 4 + __cacheline_group_end__grp; // offset 72, size 0 + __cacheline_group_pad__grp; // offset 72, size 0, padding 56 + u32 w; // offset 128 +}; + +The end marker is aligned to long, so that you can assert the struct +size more strictly, but the offset of the next field in the structure +will be aligned to the group alignment, so that the next field won't +fall into the group it's not intended to. + +Add __LARGEST_ALIGN definition and LARGEST_ALIGN() macro. +__LARGEST_ALIGN is the value to which the compilers align fields when +__aligned_largest is specified. Sometimes, it might be needed to get +this value outside of variable definitions. LARGEST_ALIGN() is macro +which just aligns a value to __LARGEST_ALIGN. +Also add SMP_CACHE_ALIGN(), similar to L1_CACHE_ALIGN(), but using +``SMP_CACHE_BYTES`` instead of ``L1_CACHE_BYTES`` as the former +also accounts L2, needed in some cases. + +Signed-off-by: Alexander Lobakin +Reviewed-by: Przemek Kitszel +Signed-off-by: Tony Nguyen +Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line") +Signed-off-by: Sasha Levin +--- + include/linux/cache.h | 59 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/include/linux/cache.h b/include/linux/cache.h +index 0ecb17bb68837..ca2a05682a54b 100644 +--- a/include/linux/cache.h ++++ b/include/linux/cache.h +@@ -13,6 +13,32 @@ + #define SMP_CACHE_BYTES L1_CACHE_BYTES + #endif + ++/** ++ * SMP_CACHE_ALIGN - align a value to the L2 cacheline size ++ * @x: value to align ++ * ++ * On some architectures, L2 ("SMP") CL size is bigger than L1, and sometimes, ++ * this needs to be accounted. ++ * ++ * Return: aligned value. ++ */ ++#ifndef SMP_CACHE_ALIGN ++#define SMP_CACHE_ALIGN(x) ALIGN(x, SMP_CACHE_BYTES) ++#endif ++ ++/* ++ * ``__aligned_largest`` aligns a field to the value most optimal for the ++ * target architecture to perform memory operations. Get the actual value ++ * to be able to use it anywhere else. ++ */ ++#ifndef __LARGEST_ALIGN ++#define __LARGEST_ALIGN sizeof(struct { long x; } __aligned_largest) ++#endif ++ ++#ifndef LARGEST_ALIGN ++#define LARGEST_ALIGN(x) ALIGN(x, __LARGEST_ALIGN) ++#endif ++ + /* + * __read_mostly is used to keep rarely changing variables out of frequently + * updated cachelines. Its use should be reserved for data that is used +@@ -95,6 +121,39 @@ + __u8 __cacheline_group_end__##GROUP[0] + #endif + ++/** ++ * __cacheline_group_begin_aligned - declare an aligned group start ++ * @GROUP: name of the group ++ * @...: optional group alignment ++ * ++ * The following block inside a struct: ++ * ++ * __cacheline_group_begin_aligned(grp); ++ * field a; ++ * field b; ++ * __cacheline_group_end_aligned(grp); ++ * ++ * will always be aligned to either the specified alignment or ++ * ``SMP_CACHE_BYTES``. ++ */ ++#define __cacheline_group_begin_aligned(GROUP, ...) \ ++ __cacheline_group_begin(GROUP) \ ++ __aligned((__VA_ARGS__ + 0) ? : SMP_CACHE_BYTES) ++ ++/** ++ * __cacheline_group_end_aligned - declare an aligned group end ++ * @GROUP: name of the group ++ * @...: optional alignment (same as was in __cacheline_group_begin_aligned()) ++ * ++ * Note that the end marker is aligned to sizeof(long) to allow more precise ++ * size assertion. It also declares a padding at the end to avoid next field ++ * falling into this cacheline. ++ */ ++#define __cacheline_group_end_aligned(GROUP, ...) \ ++ __cacheline_group_end(GROUP) __aligned(sizeof(long)); \ ++ struct { } __cacheline_group_pad__##GROUP \ ++ __aligned((__VA_ARGS__ + 0) ? : SMP_CACHE_BYTES) ++ + #ifndef CACHELINE_ASSERT_GROUP_MEMBER + #define CACHELINE_ASSERT_GROUP_MEMBER(TYPE, GROUP, MEMBER) \ + BUILD_BUG_ON(!(offsetof(TYPE, MEMBER) >= \ +-- +2.51.0 + diff --git a/queue-6.6/cache-enforce-cache-groups.patch b/queue-6.6/cache-enforce-cache-groups.patch new file mode 100644 index 0000000000..1be9969f20 --- /dev/null +++ b/queue-6.6/cache-enforce-cache-groups.patch @@ -0,0 +1,89 @@ +From 1a8c3053129f7bcb5b034121808177347f473094 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 07:27:53 +0000 +Subject: cache: enforce cache groups + +From: Coco Li + +[ Upstream commit aeb9ce058d7c6193dc41e06b3a5b29d22c446b14 ] + +Set up build time warnings to safeguard against future header changes of +organized structs. + +Warning includes: + +1) whether all variables are still in the same cache group +2) whether all the cache groups have the sum of the members size (in the + maximum condition, including all members defined in configs) + +The __cache_group* variables are ignored in kernel-doc check in the +various header files they appear in to enforce the cache groups. + +Suggested-by: Daniel Borkmann +Acked-by: Daniel Borkmann +Signed-off-by: Coco Li +Reviewed-by: Eric Dumazet +Reviewed-by: Shakeel Butt +Signed-off-by: David S. Miller +Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line") +Signed-off-by: Sasha Levin +--- + include/linux/cache.h | 25 +++++++++++++++++++++++++ + scripts/kernel-doc | 5 +++++ + 2 files changed, 30 insertions(+) + +diff --git a/include/linux/cache.h b/include/linux/cache.h +index 9900d20b76c28..0ecb17bb68837 100644 +--- a/include/linux/cache.h ++++ b/include/linux/cache.h +@@ -85,6 +85,31 @@ + #define cache_line_size() L1_CACHE_BYTES + #endif + ++#ifndef __cacheline_group_begin ++#define __cacheline_group_begin(GROUP) \ ++ __u8 __cacheline_group_begin__##GROUP[0] ++#endif ++ ++#ifndef __cacheline_group_end ++#define __cacheline_group_end(GROUP) \ ++ __u8 __cacheline_group_end__##GROUP[0] ++#endif ++ ++#ifndef CACHELINE_ASSERT_GROUP_MEMBER ++#define CACHELINE_ASSERT_GROUP_MEMBER(TYPE, GROUP, MEMBER) \ ++ BUILD_BUG_ON(!(offsetof(TYPE, MEMBER) >= \ ++ offsetofend(TYPE, __cacheline_group_begin__##GROUP) && \ ++ offsetofend(TYPE, MEMBER) <= \ ++ offsetof(TYPE, __cacheline_group_end__##GROUP))) ++#endif ++ ++#ifndef CACHELINE_ASSERT_GROUP_SIZE ++#define CACHELINE_ASSERT_GROUP_SIZE(TYPE, GROUP, SIZE) \ ++ BUILD_BUG_ON(offsetof(TYPE, __cacheline_group_end__##GROUP) - \ ++ offsetofend(TYPE, __cacheline_group_begin__##GROUP) > \ ++ SIZE) ++#endif ++ + /* + * Helper to add padding within a struct to ensure data fall into separate + * cachelines. +diff --git a/scripts/kernel-doc b/scripts/kernel-doc +index 6e199a745ccb2..d963fdf40e900 100755 +--- a/scripts/kernel-doc ++++ b/scripts/kernel-doc +@@ -1592,6 +1592,11 @@ sub push_parameter($$$$$) { + $parameterdescs{$param} = "anonymous\n"; + $anon_struct_union = 1; + } ++ elsif ($param =~ "__cacheline_group" ) ++ # handle cache group enforcing variables: they do not need be described in header files ++ { ++ return; # ignore __cacheline_group_begin and __cacheline_group_end ++ } + + # warn if parameter has no description + # (but ignore ones starting with # as these are not parameters +-- +2.51.0 + diff --git a/queue-6.6/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch b/queue-6.6/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch new file mode 100644 index 0000000000..e22358d5bf --- /dev/null +++ b/queue-6.6/cpuidle-skip-governor-when-only-one-idle-state-is-av.patch @@ -0,0 +1,59 @@ +From 439d35481a7b6d1c6abab4a29a4a1b0c0fe7f2b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 00:20:02 +0530 +Subject: cpuidle: Skip governor when only one idle state is available + +From: Aboorva Devarajan + +[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ] + +On certain platforms (PowerNV systems without a power-mgt DT node), +cpuidle may register only a single idle state. In cases where that +single state is a polling state (state 0), the ladder governor may +incorrectly treat state 1 as the first usable state and pass an +out-of-bounds index. This can lead to a NULL enter callback being +invoked, ultimately resulting in a system crash. + +[ 13.342636] cpuidle-powernv : Only Snooze is available +[ 13.351854] Faulting instruction address: 0x00000000 +[ 13.376489] NIP [0000000000000000] 0x0 +[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668 + +Fix this by adding a bail-out in cpuidle_select() that returns state 0 +directly when state_count <= 1, bypassing the governor and keeping the +tick running. + +Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") +Signed-off-by: Aboorva Devarajan +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/cpuidle.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index 6704d610573ad..aa117f2967fdf 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -356,6 +356,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev, + int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, + bool *stop_tick) + { ++ /* ++ * If there is only a single idle state (or none), there is nothing ++ * meaningful for the governor to choose. Skip the governor and ++ * always use state 0 with the tick running. ++ */ ++ if (drv->state_count <= 1) { ++ *stop_tick = false; ++ return 0; ++ } ++ + return cpuidle_curr_governor->select(drv, dev, stop_tick); + } + +-- +2.51.0 + diff --git a/queue-6.6/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch b/queue-6.6/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch new file mode 100644 index 0000000000..e82dcfcd26 --- /dev/null +++ b/queue-6.6/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch @@ -0,0 +1,78 @@ +From d2a84e160c92f39531581976e249940d9d5a69f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 23:38:28 +0100 +Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp + formats + +From: Mario Kleiner + +[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ] + +The plane scaling hw seems to have the same min/max plane scaling limits +for all 16 bpc / 64 bpp interleaved pixel color formats. + +Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for +all the 16 bpc fixed-point / unorm formats to use the same .fp16 +up/downscaling factor limits as used by the fp16 floating point formats. + +So far, 16 bpc unorm formats were not handled, and the default: path +returned max/min factors for 32 bpp argb8888 formats, which were wrong +and bigger than what many DCE / DCN hw generations could handle. + +The result sometimes was misscaling of framebuffers with +DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616, +DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested +on Polaris11 / DCE-11.2. + +So far this went unnoticed, because only few userspace clients used such +16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they +did not experience this issue. + +With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL +and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland +compositor allowing for direct scanout of these formats, the scaling +hw will be used on these formats if possible for HiDPI display scaling, +so it is important to use the correct hw scaling limits to avoid wrong +display. + +Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50 +on HiDPI displays with scaling enabled. The mutter Wayland compositor now +correctly falls back to scaling via desktop compositing instead of direct +scanout, thereby avoiding wrong image display. For unscaled mode, it +correctly uses direct scanout. + +Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.") +Signed-off-by: Mario Kleiner +Tested-by: Mario Kleiner +Cc: Alex Deucher +Cc: Harry Wentland +Cc: Leo Li +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +index d1329f20b7bd4..746df72405eb4 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +@@ -970,10 +970,15 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev, + *min_downscale = plane_cap->max_downscale_factor.nv12; + break; + ++ /* All 64 bpp formats have the same fp16 scaling limits */ + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: ++ case DRM_FORMAT_XRGB16161616: ++ case DRM_FORMAT_ARGB16161616: ++ case DRM_FORMAT_XBGR16161616: ++ case DRM_FORMAT_ABGR16161616: + *max_upscale = plane_cap->max_upscale_factor.fp16; + *min_downscale = plane_cap->max_downscale_factor.fp16; + break; +-- +2.51.0 + diff --git a/queue-6.6/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch b/queue-6.6/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch new file mode 100644 index 0000000000..bbaa453443 --- /dev/null +++ b/queue-6.6/drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch @@ -0,0 +1,46 @@ +From e7222b03f59ee9d5737c85e10e12d7c3e6fe2e65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 09:25:32 +0000 +Subject: drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc() + +From: Zilin Guan + +[ Upstream commit c9be63d565789b56ca7b0197e2cb78a3671f95a8 ] + +In amdgpu_acpi_enumerate_xcc(), if amdgpu_acpi_dev_init() returns -ENOMEM, +the function returns directly without releasing the allocated xcc_info, +resulting in a memory leak. + +Fix this by ensuring that xcc_info is properly freed in the error paths. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects") +Reviewed-by: Lijo Lazar +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +index 8b2f2b921d9de..7730e56444934 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -1128,8 +1128,10 @@ static int amdgpu_acpi_enumerate_xcc(void) + if (!dev_info) + ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, bdf); + +- if (ret == -ENOMEM) ++ if (ret == -ENOMEM) { ++ kfree(xcc_info); + return ret; ++ } + + if (!dev_info) { + kfree(xcc_info); +-- +2.51.0 + diff --git a/queue-6.6/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch b/queue-6.6/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch new file mode 100644 index 0000000000..2367b63703 --- /dev/null +++ b/queue-6.6/drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch @@ -0,0 +1,44 @@ +From 2bb72b5c7a0c73fdfb12f14eb1f11983057422e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jan 2026 08:35:15 +0000 +Subject: drm/amdgpu: Fix memory leak in amdgpu_ras_init() + +From: Zilin Guan + +[ Upstream commit ee41e5b63c8210525c936ee637a2c8d185ce873c ] + +When amdgpu_nbio_ras_sw_init() fails in amdgpu_ras_init(), the function +returns directly without freeing the allocated con structure, leading +to a memory leak. + +Fix this by jumping to the release_con label to properly clean up the +allocated memory before returning the error code. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: fdc94d3a8c88 ("drm/amdgpu: Rework pcie_bif ras sw_init") +Reviewed-by: Tao Zhou +Signed-off-by: Zilin Guan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index 7cba98f8bbdca..4214bbd7a1a23 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -2673,7 +2673,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev) + * to handle fatal error */ + r = amdgpu_nbio_ras_sw_init(adev); + if (r) +- return r; ++ goto release_con; + + if (adev->nbio.ras && + adev->nbio.ras->init_ras_controller_interrupt) { +-- +2.51.0 + diff --git a/queue-6.6/drm-amdkfd-fix-debug-watchpoints-for-logical-devices.patch b/queue-6.6/drm-amdkfd-fix-debug-watchpoints-for-logical-devices.patch new file mode 100644 index 0000000000..3be1261134 --- /dev/null +++ b/queue-6.6/drm-amdkfd-fix-debug-watchpoints-for-logical-devices.patch @@ -0,0 +1,135 @@ +From 90df9e4c96690846dd167572976b7e618b2cabf5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Jul 2024 13:26:08 -0400 +Subject: drm/amdkfd: fix debug watchpoints for logical devices + +From: Jonathan Kim + +[ Upstream commit b41a382932263b2951bc9e83a22168d579a94865 ] + +The number of watchpoints should be set and constrained per logical +partition device, not by the socket device. + +Signed-off-by: Jonathan Kim +Reviewed-by: Harish Kasiviswanathan +Signed-off-by: Alex Deucher +Stable-dep-of: 5a19302cab5c ("drm/amdkfd: Fix watch_id bounds checking in debug address watch v2") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++---------- + drivers/gpu/drm/amd/amdkfd/kfd_device.c | 5 +++-- + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 8 ++++---- + 3 files changed, 17 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +index 9c32c64c407fa..eb973f16848d3 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +@@ -381,47 +381,47 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i + + *watch_id = KFD_DEBUGGER_INVALID_WATCH_POINT_ID; + +- spin_lock(&pdd->dev->kfd->watch_points_lock); ++ spin_lock(&pdd->dev->watch_points_lock); + + for (i = 0; i < MAX_WATCH_ADDRESSES; i++) { + /* device watchpoint in use so skip */ +- if ((pdd->dev->kfd->alloc_watch_ids >> i) & 0x1) ++ if ((pdd->dev->alloc_watch_ids >> i) & 0x1) + continue; + + pdd->alloc_watch_ids |= 0x1 << i; +- pdd->dev->kfd->alloc_watch_ids |= 0x1 << i; ++ pdd->dev->alloc_watch_ids |= 0x1 << i; + *watch_id = i; +- spin_unlock(&pdd->dev->kfd->watch_points_lock); ++ spin_unlock(&pdd->dev->watch_points_lock); + return 0; + } + +- spin_unlock(&pdd->dev->kfd->watch_points_lock); ++ spin_unlock(&pdd->dev->watch_points_lock); + + return -ENOMEM; + } + + static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id) + { +- spin_lock(&pdd->dev->kfd->watch_points_lock); ++ spin_lock(&pdd->dev->watch_points_lock); + + /* process owns device watch point so safe to clear */ + if ((pdd->alloc_watch_ids >> watch_id) & 0x1) { + pdd->alloc_watch_ids &= ~(0x1 << watch_id); +- pdd->dev->kfd->alloc_watch_ids &= ~(0x1 << watch_id); ++ pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id); + } + +- spin_unlock(&pdd->dev->kfd->watch_points_lock); ++ spin_unlock(&pdd->dev->watch_points_lock); + } + + static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id) + { + bool owns_watch_id = false; + +- spin_lock(&pdd->dev->kfd->watch_points_lock); ++ spin_lock(&pdd->dev->watch_points_lock); + owns_watch_id = watch_id < MAX_WATCH_ADDRESSES && + ((pdd->alloc_watch_ids >> watch_id) & 0x1); + +- spin_unlock(&pdd->dev->kfd->watch_points_lock); ++ spin_unlock(&pdd->dev->watch_points_lock); + + return owns_watch_id; + } +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c +index 6af65db4de947..af50aa9638cab 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c +@@ -815,13 +815,14 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, + dev_err(kfd_device, "Error initializing KFD node\n"); + goto node_init_error; + } ++ ++ spin_lock_init(&node->watch_points_lock); ++ + kfd->nodes[i] = node; + } + + svm_range_set_max_pages(kfd->adev); + +- spin_lock_init(&kfd->watch_points_lock); +- + kfd->init_complete = true; + dev_info(kfd_device, "added device %x:%x\n", kfd->adev->pdev->vendor, + kfd->adev->pdev->device); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +index b475c2ab9768a..0b69ff5375c52 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +@@ -316,6 +316,10 @@ struct kfd_node { + struct kfd_local_mem_info local_mem_info; + + struct kfd_dev *kfd; ++ ++ /* Track per device allocated watch points */ ++ uint32_t alloc_watch_ids; ++ spinlock_t watch_points_lock; + }; + + struct kfd_dev { +@@ -368,10 +372,6 @@ struct kfd_dev { + struct kfd_node *nodes[MAX_KFD_NODES]; + unsigned int num_nodes; + +- /* Track per device allocated watch points */ +- uint32_t alloc_watch_ids; +- spinlock_t watch_points_lock; +- + /* Kernel doorbells for KFD device */ + struct amdgpu_bo *doorbells; + +-- +2.51.0 + diff --git a/queue-6.6/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch b/queue-6.6/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch new file mode 100644 index 0000000000..4fe50abfd4 --- /dev/null +++ b/queue-6.6/drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch @@ -0,0 +1,138 @@ +From cf5c14e45eff2dd348758645311e929eb0af05ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Feb 2026 21:18:11 +0530 +Subject: drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Srinivasan Shanmugam + +[ Upstream commit 5a19302cab5cec7ae7f1a60c619951e6c17d8742 ] + +The address watch clear code receives watch_id as an unsigned value +(u32), but some helper functions were using a signed int and checked +bits by shifting with watch_id. + +If a very large watch_id is passed from userspace, it can be converted +to a negative value. This can cause invalid shifts and may access +memory outside the watch_points array. + +drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 + +Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before +using it. Also use BIT(watch_id) to test and clear bits safely. + +This keeps the behavior unchanged for valid watch IDs and avoids +undefined behavior for invalid ones. + +Fixes the below: +drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448 +kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow +'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped + +drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c + 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, + 434 uint32_t watch_id) + 435 { + 436 int r; + 437 + 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) + +kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if +watch_id is larger than INT_MAX it leads to a buffer overflow. +(Negative shifts are undefined). + + 439 return -EINVAL; + 440 + 441 if (!pdd->dev->kfd->shared_resources.enable_mes) { + 442 r = debug_lock_and_unmap(pdd->dev->dqm); + 443 if (r) + 444 return r; + 445 } + 446 + 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false); +--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch( + 449 pdd->dev->adev, + 450 watch_id); + +v2: (as per, Jonathan Kim) + - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to + match the clear path. + - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id(). + +Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation") +Reported-by: Dan Carpenter +Cc: Jonathan Kim +Cc: Felix Kuehling +Cc: Alex Deucher +Cc: Christian König +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Jonathan Kim +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +index eb973f16848d3..267650dcced9d 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +@@ -400,27 +400,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i + return -ENOMEM; + } + +-static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id) ++static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) + { + spin_lock(&pdd->dev->watch_points_lock); + + /* process owns device watch point so safe to clear */ +- if ((pdd->alloc_watch_ids >> watch_id) & 0x1) { +- pdd->alloc_watch_ids &= ~(0x1 << watch_id); +- pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id); ++ if (pdd->alloc_watch_ids & BIT(watch_id)) { ++ pdd->alloc_watch_ids &= ~BIT(watch_id); ++ pdd->dev->alloc_watch_ids &= ~BIT(watch_id); + } + + spin_unlock(&pdd->dev->watch_points_lock); + } + +-static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id) ++static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) + { + bool owns_watch_id = false; + + spin_lock(&pdd->dev->watch_points_lock); +- owns_watch_id = watch_id < MAX_WATCH_ADDRESSES && +- ((pdd->alloc_watch_ids >> watch_id) & 0x1); +- ++ owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id); + spin_unlock(&pdd->dev->watch_points_lock); + + return owns_watch_id; +@@ -431,6 +429,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, + { + int r; + ++ if (watch_id >= MAX_WATCH_ADDRESSES) ++ return -EINVAL; ++ + if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) + return -EINVAL; + +@@ -468,6 +469,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd, + if (r) + return r; + ++ if (*watch_id >= MAX_WATCH_ADDRESSES) ++ return -EINVAL; ++ + if (!pdd->dev->kfd->shared_resources.enable_mes) { + r = debug_lock_and_unmap(pdd->dev->dqm); + if (r) { +-- +2.51.0 + diff --git a/queue-6.6/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch b/queue-6.6/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch new file mode 100644 index 0000000000..6eb55a2844 --- /dev/null +++ b/queue-6.6/drm-i915-acpi-free-_dsm-package-when-no-connectors.patch @@ -0,0 +1,40 @@ +From 987612ba0b9e300b8a0cefc63923204c93797a06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jan 2026 08:55:49 +0530 +Subject: drm/i915/acpi: free _DSM package when no connectors + +From: Kaushlendra Kumar + +[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ] + +acpi_evaluate_dsm_typed() returns an ACPI package in pkg. +When pkg->package.count == 0, we returned without freeing pkg, +leaking memory. Free pkg before returning on the empty case. + +Signed-off-by: Kaushlendra Kumar +Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects") +Reviewed-by: Jani Nikula +Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c +index 9df78e7caa2bd..231b341d968ad 100644 +--- a/drivers/gpu/drm/i915/display/intel_acpi.c ++++ b/drivers/gpu/drm/i915/display/intel_acpi.c +@@ -93,6 +93,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle) + + if (!pkg->package.count) { + DRM_DEBUG_DRIVER("no connection in _DSM\n"); ++ ACPI_FREE(pkg); + return; + } + +-- +2.51.0 + diff --git a/queue-6.6/efi-fix-reservation-of-unaccepted-memory-table.patch b/queue-6.6/efi-fix-reservation-of-unaccepted-memory-table.patch new file mode 100644 index 0000000000..cc1a0e5446 --- /dev/null +++ b/queue-6.6/efi-fix-reservation-of-unaccepted-memory-table.patch @@ -0,0 +1,62 @@ +From 5a62ebb47b8662c5ed10f31a6988f70f4320b343 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 10:49:56 +0000 +Subject: efi: Fix reservation of unaccepted memory table + +From: Kiryl Shutsemau (Meta) + +[ Upstream commit 0862438c90487e79822d5647f854977d50381505 ] + +The reserve_unaccepted() function incorrectly calculates the size of the +memblock reservation for the unaccepted memory table. It aligns the +size of the table, but fails to account for cases where the table's +starting physical address (efi.unaccepted) is not page-aligned. + +If the table starts at an offset within a page and its end crosses into +a subsequent page that the aligned size does not cover, the end of the +table will not be reserved. This can lead to the table being overwritten +or inaccessible, causing a kernel panic in accept_memory(). + +This issue was observed when starting Intel TDX VMs with specific memory +sizes (e.g., > 64GB). + +Fix this by calculating the end address first (including the unaligned +start) and then aligning it up, ensuring the entire range is covered +by the reservation. + +Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped") +Reported-by: Moritz Sanft +Signed-off-by: Kiryl Shutsemau (Meta) +Reviewed-by: Tom Lendacky +Acked-by: Mike Rapoport (Microsoft) +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/efi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index 1ab161e00c867..ef55e3851b362 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -648,13 +648,13 @@ static __init int match_config_table(const efi_guid_t *guid, + + static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted) + { +- phys_addr_t start, size; ++ phys_addr_t start, end; + + start = PAGE_ALIGN_DOWN(efi.unaccepted); +- size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size); ++ end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size); + +- memblock_add(start, size); +- memblock_reserve(start, size); ++ memblock_add(start, end - start); ++ memblock_reserve(start, end - start); + } + + int __init efi_config_parse_tables(const efi_config_table_t *config_tables, +-- +2.51.0 + diff --git a/queue-6.6/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch b/queue-6.6/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch new file mode 100644 index 0000000000..93760c7c36 --- /dev/null +++ b/queue-6.6/fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch @@ -0,0 +1,51 @@ +From 69fae95502073775d0eea5e1b00f07411eca9b82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jan 2026 16:50:24 +0000 +Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot + +From: Jiasheng Jiang + +[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ] + +In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the +entry size ('esize') is retrieved from the log record without adequate +bounds checking. + +Specifically, the code calculates the end of the entry ('e2') using: + e2 = Add2Ptr(e1, esize); + +It then calculates the size for memmove using 'PtrOffset(e2, ...)', +which subtracts the end pointer from the buffer limit. If 'esize' is +maliciously large, 'e2' exceeds the used buffer size. This results in +a negative offset which, when cast to size_t for memmove, interprets +as a massive unsigned integer, leading to a heap buffer overflow. + +This commit adds a check to ensure that the entry size ('esize') strictly +fits within the remaining used space of the index header before performing +memory operations. + +Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fslog.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c +index 2a1aeab53ea4b..598b7f42b5e7e 100644 +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3431,6 +3431,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, + + e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off)); + esize = le16_to_cpu(e1->size); ++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize) ++ goto dirty_vol; ++ + e2 = Add2Ptr(e1, esize); + + memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used))); +-- +2.51.0 + diff --git a/queue-6.6/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch b/queue-6.6/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch new file mode 100644 index 0000000000..c34e6e16d6 --- /dev/null +++ b/queue-6.6/fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch @@ -0,0 +1,58 @@ +From 91ed73d355c883c97cd587a02cb94319e03cecc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Dec 2025 11:53:25 +0800 +Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the + same + +From: Edward Adam Davis + +[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ] + +When processing valid within the range [valid : pos), if valid cannot +be retrieved correctly, for example, if the retrieved valid value is +always the same, this can trigger a potential infinite loop, similar +to the hung problem reported by syzbot [1]. + +Adding a check for the valid value within the loop body, and terminating +the loop and returning -EINVAL if the value is the same as the current +value, can prevent this. + +[1] +INFO: task syz.4.21:6056 blocked for more than 143 seconds. +Call Trace: + rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244 + inode_lock include/linux/fs.h:1027 [inline] + ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1 +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index a7fe2e02c32ee..212737a816d7a 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -901,8 +901,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) + goto out; + + if (lcn == SPARSE_LCN) { +- ni->i_valid = valid = +- frame_vbo + ((u64)clen << sbi->cluster_bits); ++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits); ++ if (ni->i_valid == valid) { ++ err = -EINVAL; ++ goto out; ++ } ++ ni->i_valid = valid; + continue; + } + +-- +2.51.0 + diff --git a/queue-6.6/icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch b/queue-6.6/icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch new file mode 100644 index 0000000000..8fd622ee06 --- /dev/null +++ b/queue-6.6/icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch @@ -0,0 +1,145 @@ +From 39e84b15836fc6e5d38a48f5ad536261559902b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 14:46:41 +0000 +Subject: icmp: icmp_msgs_per_sec and icmp_msgs_burst sysctls become per netns + +From: Eric Dumazet + +[ Upstream commit f17bf505ff89595df5147755e51441632a5dc563 ] + +Previous patch made ICMP rate limits per netns, it makes sense +to allow each netns to change the associated sysctl. + +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20240829144641.3880376-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 034bbd806298 ("icmp: prevent possible overflow in icmp_global_allow()") +Signed-off-by: Sasha Levin +--- + include/net/ip.h | 3 --- + include/net/netns/ipv4.h | 2 ++ + net/ipv4/icmp.c | 9 ++++----- + net/ipv4/sysctl_net_ipv4.c | 32 ++++++++++++++++---------------- + 4 files changed, 22 insertions(+), 24 deletions(-) + +diff --git a/include/net/ip.h b/include/net/ip.h +index a8e70ba54da45..bacdb4fecc89b 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -793,9 +793,6 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) + bool icmp_global_allow(struct net *net); + void icmp_global_consume(struct net *net); + +-extern int sysctl_icmp_msgs_per_sec; +-extern int sysctl_icmp_msgs_burst; +- + #ifdef CONFIG_PROC_FS + int ip_misc_proc_init(void); + #endif +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 8d32df274910c..40a3a7e2e6070 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -84,6 +84,8 @@ struct netns_ipv4 { + u8 sysctl_icmp_errors_use_inbound_ifaddr; + int sysctl_icmp_ratelimit; + int sysctl_icmp_ratemask; ++ int sysctl_icmp_msgs_per_sec; ++ int sysctl_icmp_msgs_burst; + atomic_t icmp_global_credit; + u32 icmp_global_stamp; + u32 ip_rt_min_pmtu; +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 0a67e1f0c3ba6..8a8c1fa3bb073 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -221,9 +221,6 @@ static inline void icmp_xmit_unlock(struct sock *sk) + spin_unlock(&sk->sk_lock.slock); + } + +-int sysctl_icmp_msgs_per_sec __read_mostly = 1000; +-int sysctl_icmp_msgs_burst __read_mostly = 50; +- + /** + * icmp_global_allow - Are we allowed to send one more ICMP message ? + * @net: network namespace +@@ -250,14 +247,14 @@ bool icmp_global_allow(struct net *net) + if (delta < HZ / 50) + return false; + +- incr = READ_ONCE(sysctl_icmp_msgs_per_sec) * delta / HZ; ++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; + if (!incr) + return false; + + if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) { + old = atomic_read(&net->ipv4.icmp_global_credit); + do { +- new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst)); ++ new = min(old + incr, READ_ONCE(net->ipv4.sysctl_icmp_msgs_burst)); + } while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new)); + } + return true; +@@ -1516,6 +1513,8 @@ static int __net_init icmp_sk_init(struct net *net) + net->ipv4.sysctl_icmp_ratelimit = 1 * HZ; + net->ipv4.sysctl_icmp_ratemask = 0x1818; + net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0; ++ net->ipv4.sysctl_icmp_msgs_per_sec = 1000; ++ net->ipv4.sysctl_icmp_msgs_burst = 50; + + return 0; + } +diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c +index 6ac890b4073f4..7a1164ea3d3af 100644 +--- a/net/ipv4/sysctl_net_ipv4.c ++++ b/net/ipv4/sysctl_net_ipv4.c +@@ -547,22 +547,6 @@ static struct ctl_table ipv4_table[] = { + .mode = 0444, + .proc_handler = proc_tcp_available_ulp, + }, +- { +- .procname = "icmp_msgs_per_sec", +- .data = &sysctl_icmp_msgs_per_sec, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, +- }, +- { +- .procname = "icmp_msgs_burst", +- .data = &sysctl_icmp_msgs_burst, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, +- }, + { + .procname = "udp_mem", + .data = &sysctl_udp_mem, +@@ -649,6 +633,22 @@ static struct ctl_table ipv4_net_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec + }, ++ { ++ .procname = "icmp_msgs_per_sec", ++ .data = &init_net.ipv4.sysctl_icmp_msgs_per_sec, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ }, ++ { ++ .procname = "icmp_msgs_burst", ++ .data = &init_net.ipv4.sysctl_icmp_msgs_burst, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ }, + { + .procname = "ping_group_range", + .data = &init_net.ipv4.ping_group_range.range, +-- +2.51.0 + diff --git a/queue-6.6/icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch b/queue-6.6/icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch new file mode 100644 index 0000000000..8a7246f971 --- /dev/null +++ b/queue-6.6/icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch @@ -0,0 +1,168 @@ +From 34091d5eff8468b4dac191ea7af281a65d6f921c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 14:46:40 +0000 +Subject: icmp: move icmp_global.credit and icmp_global.stamp to per netns + storage + +From: Eric Dumazet + +[ Upstream commit b056b4cd9178f7a1d5d57f7b48b073c29729ddaa ] + +Host wide ICMP ratelimiter should be per netns, to provide better isolation. + +Following patch in this series makes the sysctl per netns. + +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20240829144641.3880376-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 034bbd806298 ("icmp: prevent possible overflow in icmp_global_allow()") +Signed-off-by: Sasha Levin +--- + include/net/ip.h | 4 ++-- + include/net/netns/ipv4.h | 3 ++- + net/ipv4/icmp.c | 26 +++++++++++--------------- + net/ipv6/icmp.c | 4 ++-- + 4 files changed, 17 insertions(+), 20 deletions(-) + +diff --git a/include/net/ip.h b/include/net/ip.h +index d8bf1f0a6919c..a8e70ba54da45 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -790,8 +790,8 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) + ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0); + } + +-bool icmp_global_allow(void); +-void icmp_global_consume(void); ++bool icmp_global_allow(struct net *net); ++void icmp_global_consume(struct net *net); + + extern int sysctl_icmp_msgs_per_sec; + extern int sysctl_icmp_msgs_burst; +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 7a41c47915367..8d32df274910c 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -84,7 +84,8 @@ struct netns_ipv4 { + u8 sysctl_icmp_errors_use_inbound_ifaddr; + int sysctl_icmp_ratelimit; + int sysctl_icmp_ratemask; +- ++ atomic_t icmp_global_credit; ++ u32 icmp_global_stamp; + u32 ip_rt_min_pmtu; + int ip_rt_mtu_expires; + int ip_rt_min_advmss; +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 9653ef1281a46..0a67e1f0c3ba6 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -224,19 +224,15 @@ static inline void icmp_xmit_unlock(struct sock *sk) + int sysctl_icmp_msgs_per_sec __read_mostly = 1000; + int sysctl_icmp_msgs_burst __read_mostly = 50; + +-static struct { +- atomic_t credit; +- u32 stamp; +-} icmp_global; +- + /** + * icmp_global_allow - Are we allowed to send one more ICMP message ? ++ * @net: network namespace + * + * Uses a token bucket to limit our ICMP messages to ~sysctl_icmp_msgs_per_sec. + * Returns false if we reached the limit and can not send another packet. + * Works in tandem with icmp_global_consume(). + */ +-bool icmp_global_allow(void) ++bool icmp_global_allow(struct net *net) + { + u32 delta, now, oldstamp; + int incr, new, old; +@@ -245,11 +241,11 @@ bool icmp_global_allow(void) + * Then later icmp_global_consume() could consume more credits, + * this is an acceptable race. + */ +- if (atomic_read(&icmp_global.credit) > 0) ++ if (atomic_read(&net->ipv4.icmp_global_credit) > 0) + return true; + + now = jiffies; +- oldstamp = READ_ONCE(icmp_global.stamp); ++ oldstamp = READ_ONCE(net->ipv4.icmp_global_stamp); + delta = min_t(u32, now - oldstamp, HZ); + if (delta < HZ / 50) + return false; +@@ -258,23 +254,23 @@ bool icmp_global_allow(void) + if (!incr) + return false; + +- if (cmpxchg(&icmp_global.stamp, oldstamp, now) == oldstamp) { +- old = atomic_read(&icmp_global.credit); ++ if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) { ++ old = atomic_read(&net->ipv4.icmp_global_credit); + do { + new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst)); +- } while (!atomic_try_cmpxchg(&icmp_global.credit, &old, new)); ++ } while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new)); + } + return true; + } + EXPORT_SYMBOL(icmp_global_allow); + +-void icmp_global_consume(void) ++void icmp_global_consume(struct net *net) + { + int credits = get_random_u32_below(3); + + /* Note: this might make icmp_global.credit negative. */ + if (credits) +- atomic_sub(credits, &icmp_global.credit); ++ atomic_sub(credits, &net->ipv4.icmp_global_credit); + } + EXPORT_SYMBOL(icmp_global_consume); + +@@ -300,7 +296,7 @@ static bool icmpv4_global_allow(struct net *net, int type, int code, + if (icmpv4_mask_allow(net, type, code)) + return true; + +- if (icmp_global_allow()) { ++ if (icmp_global_allow(net)) { + *apply_ratelimit = true; + return true; + } +@@ -337,7 +333,7 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, + if (!rc) + __ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST); + else +- icmp_global_consume(); ++ icmp_global_consume(net); + return rc; + } + +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index e9e457b7d4eac..1d1c56e0e2460 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -181,7 +181,7 @@ static bool icmpv6_global_allow(struct net *net, int type, + if (icmpv6_mask_allow(net, type)) + return true; + +- if (icmp_global_allow()) { ++ if (icmp_global_allow(net)) { + *apply_ratelimit = true; + return true; + } +@@ -231,7 +231,7 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type, + __ICMP6_INC_STATS(net, ip6_dst_idev(dst), + ICMP6_MIB_RATELIMITHOST); + else +- icmp_global_consume(); ++ icmp_global_consume(net); + dst_release(dst); + return res; + } +-- +2.51.0 + diff --git a/queue-6.6/icmp-prevent-possible-overflow-in-icmp_global_allow.patch b/queue-6.6/icmp-prevent-possible-overflow-in-icmp_global_allow.patch new file mode 100644 index 0000000000..3441d6fea0 --- /dev/null +++ b/queue-6.6/icmp-prevent-possible-overflow-in-icmp_global_allow.patch @@ -0,0 +1,41 @@ +From 29b5644bc67288e1aa069bfe3e8fba45e7f5a93e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:28 +0000 +Subject: icmp: prevent possible overflow in icmp_global_allow() + +From: Eric Dumazet + +[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ] + +Following expression can overflow +if sysctl_icmp_msgs_per_sec is big enough. + +sysctl_icmp_msgs_per_sec * delta / HZ; + +Fixes: 4cdf507d5452 ("icmp: add a global rate limitation") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/icmp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 8a8c1fa3bb073..784591ed5bb7c 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -247,7 +247,8 @@ bool icmp_global_allow(struct net *net) + if (delta < HZ / 50) + return false; + +- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; ++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec); ++ incr = div_u64((u64)incr * delta, HZ); + if (!incr) + return false; + +-- +2.51.0 + diff --git a/queue-6.6/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch b/queue-6.6/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch new file mode 100644 index 0000000000..090cd47f7d --- /dev/null +++ b/queue-6.6/inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch @@ -0,0 +1,57 @@ +From b1a67ef30071ff00e67198a4a2a524dd9a2c29d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:28:29 +0000 +Subject: inet: move icmp_global_{credit,stamp} to a separate cache line + +From: Eric Dumazet + +[ Upstream commit 87b08913a9ae82082e276d237ece08fc8ee24380 ] + +icmp_global_credit was meant to be changed ~1000 times per second, +but if an admin sets net.ipv4.icmp_msgs_per_sec to a very high value, +icmp_global_credit changes can inflict false sharing to surrounding +fields that are read mostly. + +Move icmp_global_credit and icmp_global_stamp to a separate +cacheline aligned group. + +Fixes: b056b4cd9178 ("icmp: move icmp_global.credit and icmp_global.stamp to per netns storage") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216142832.3834174-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/netns/ipv4.h | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 3d7e03847b5be..521529e61ae1c 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -74,6 +74,12 @@ struct netns_ipv4 { + int sysctl_tcp_rmem[3]; + __cacheline_group_end(netns_ipv4_read_rx); + ++ /* ICMP rate limiter hot cache line. */ ++ __cacheline_group_begin_aligned(icmp); ++ atomic_t icmp_global_credit; ++ u32 icmp_global_stamp; ++ __cacheline_group_end_aligned(icmp); ++ + struct inet_timewait_death_row tcp_death_row; + struct udp_table *udp_table; + +@@ -118,8 +124,7 @@ struct netns_ipv4 { + int sysctl_icmp_ratemask; + int sysctl_icmp_msgs_per_sec; + int sysctl_icmp_msgs_burst; +- atomic_t icmp_global_credit; +- u32 icmp_global_stamp; ++ + u32 ip_rt_min_pmtu; + int ip_rt_mtu_expires; + int ip_rt_min_advmss; +-- +2.51.0 + diff --git a/queue-6.6/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch b/queue-6.6/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch new file mode 100644 index 0000000000..9aea0ec817 --- /dev/null +++ b/queue-6.6/ipv6-fix-a-race-in-ip6_sock_set_v6only.patch @@ -0,0 +1,53 @@ +From 4b10e2f405fcb891206dc863aa483b49d58de6e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:22:02 +0000 +Subject: ipv6: fix a race in ip6_sock_set_v6only() + +From: Eric Dumazet + +[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ] + +It is unlikely that this function will be ever called +with isk->inet_num being not zero. + +Perform the check on isk->inet_num inside the locked section +for complete safety. + +Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Fernando Fernandez Mancera +Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/ipv6.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index c6932d1a3fa80..9e5e44c6da0a6 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -1293,12 +1293,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, + + static inline int ip6_sock_set_v6only(struct sock *sk) + { +- if (inet_sk(sk)->inet_num) +- return -EINVAL; ++ int ret = 0; ++ + lock_sock(sk); +- sk->sk_ipv6only = true; ++ if (inet_sk(sk)->inet_num) ++ ret = -EINVAL; ++ else ++ sk->sk_ipv6only = true; + release_sock(sk); +- return 0; ++ return ret; + } + + static inline void ip6_sock_set_recverr(struct sock *sk) +-- +2.51.0 + diff --git a/queue-6.6/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch b/queue-6.6/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch new file mode 100644 index 0000000000..ef5af26d27 --- /dev/null +++ b/queue-6.6/ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch @@ -0,0 +1,125 @@ +From caa04607ff0203bf1250fd859959e2c88b16e7f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 17:50:21 +0000 +Subject: ipv6: Fix out-of-bound access in fib6_add_rt2node(). + +From: Kuniyuki Iwashima + +[ Upstream commit 8244f959e2c125c849e569f5b23ed49804cce695 ] + +syzbot reported out-of-bound read in fib6_add_rt2node(). [0] + +When IPv6 route is created with RTA_NH_ID, struct fib6_info +does not have the trailing struct fib6_nh. + +The cited commit started to check !iter->fib6_nh->fib_nh_gw_family +to ensure that rt6_qualify_for_ecmp() will return false for iter. + +If iter->nh is not NULL, rt6_qualify_for_ecmp() returns false anyway. + +Let's check iter->nh before reading iter->fib6_nh and avoid OOB read. + +[0]: +BUG: KASAN: slab-out-of-bounds in fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142 +Read of size 1 at addr ffff8880384ba6de by task syz.0.18/5500 + +CPU: 0 UID: 0 PID: 5500 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full) +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +Call Trace: + + dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:378 [inline] + print_report+0xba/0x230 mm/kasan/report.c:482 + kasan_report+0x117/0x150 mm/kasan/report.c:595 + fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142 + fib6_add_rt2node_nh net/ipv6/ip6_fib.c:1363 [inline] + fib6_add+0x910/0x18c0 net/ipv6/ip6_fib.c:1531 + __ip6_ins_rt net/ipv6/route.c:1351 [inline] + ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3957 + inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660 + rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f9316b9aeb9 +Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007ffd8809b678 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00007f9316e15fa0 RCX: 00007f9316b9aeb9 +RDX: 0000000000000000 RSI: 0000200000004380 RDI: 0000000000000003 +RBP: 00007f9316c08c1f R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007f9316e15fac R14: 00007f9316e15fa0 R15: 00007f9316e15fa0 + + +Allocated by task 5499: + kasan_save_stack mm/kasan/common.c:57 [inline] + kasan_save_track+0x3e/0x80 mm/kasan/common.c:78 + poison_kmalloc_redzone mm/kasan/common.c:398 [inline] + __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415 + kasan_kmalloc include/linux/kasan.h:263 [inline] + __do_kmalloc_node mm/slub.c:5657 [inline] + __kmalloc_noprof+0x40c/0x7e0 mm/slub.c:5669 + kmalloc_noprof include/linux/slab.h:961 [inline] + kzalloc_noprof include/linux/slab.h:1094 [inline] + fib6_info_alloc+0x30/0xf0 net/ipv6/ip6_fib.c:155 + ip6_route_info_create+0x142/0x860 net/ipv6/route.c:3820 + ip6_route_add+0x49/0x1b0 net/ipv6/route.c:3949 + inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660 + rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Fixes: bbf4a17ad9ff ("ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF") +Reported-by: syzbot+707d6a5da1ab9e0c6f9d@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/698cbfba.050a0220.2eeac1.009d.GAE@google.com/ +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Fernando Fernandez Mancera +Reviewed-by: Shigeru Yoshida +Link: https://patch.msgid.link/20260211175133.3657034-1-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index fe57884ca7238..6fe867579118b 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1137,7 +1137,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_add_gc_list(iter); + } + if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) && +- !iter->fib6_nh->fib_nh_gw_family) { ++ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) { + iter->fib6_flags &= ~RTF_ADDRCONF; + iter->fib6_flags &= ~RTF_PREFIX_RT; + } +-- +2.51.0 + diff --git a/queue-6.6/kbuild-add-objtool-to-top-level-clean-target.patch b/queue-6.6/kbuild-add-objtool-to-top-level-clean-target.patch new file mode 100644 index 0000000000..f869a17728 --- /dev/null +++ b/queue-6.6/kbuild-add-objtool-to-top-level-clean-target.patch @@ -0,0 +1,71 @@ +From 65e16191624c6d2fad2df78573992651dc2f321c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 13:45:22 -0800 +Subject: kbuild: Add objtool to top-level clean target + +From: Josh Poimboeuf + +[ Upstream commit 68b4fe32d73789dea23e356f468de67c8367ef8f ] + +Objtool is an integral part of the build, make sure it gets cleaned by +"make clean" and "make mrproper". + +Fixes: 442f04c34a1a ("objtool: Add tool to perform compile-time stack metadata validation") +Reported-by: Jens Remus +Closes: https://lore.kernel.org/15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com +Signed-off-by: Josh Poimboeuf +Tested-by: Jens Remus +Link: https://patch.msgid.link/968faf2ed30fa8b3519f79f01a1ecfe7929553e5.1770759919.git.jpoimboe@kernel.org +[nathan: use Closes: instead of Link: per checkpatch.pl] +Signed-off-by: Nathan Chancellor +Signed-off-by: Sasha Levin +--- + Makefile | 11 ++++++++++- + tools/objtool/Makefile | 2 ++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index b9c04d8271b94..1c7555ea8b06a 100644 +--- a/Makefile ++++ b/Makefile +@@ -1356,6 +1356,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),) + $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean + endif + ++PHONY += objtool_clean ++ ++objtool_O = $(abspath $(objtree))/tools/objtool ++ ++objtool_clean: ++ifneq ($(wildcard $(objtool_O)),) ++ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean ++endif ++ + tools/: FORCE + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ +@@ -1509,7 +1518,7 @@ vmlinuxclean: + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean + $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean) + +-clean: archclean vmlinuxclean resolve_btfids_clean ++clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean + + # mrproper - Delete all generated files, including .config + # +diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile +index 83b100c1e7f68..e9a0f89e9c39a 100644 +--- a/tools/objtool/Makefile ++++ b/tools/objtool/Makefile +@@ -7,6 +7,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR))) + srctree := $(patsubst %/,%,$(dir $(srctree))) + endif + ++RM ?= rm -f ++ + LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ + ifneq ($(OUTPUT),) + LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd +-- +2.51.0 + diff --git a/queue-6.6/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch b/queue-6.6/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch new file mode 100644 index 0000000000..711e0e2637 --- /dev/null +++ b/queue-6.6/macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch @@ -0,0 +1,116 @@ +From 226f456233b3f23e9c7d88ac6b6cbdd7d4d000b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:25:57 +0000 +Subject: macvlan: observe an RCU grace period in macvlan_common_newlink() + error path + +From: Eric Dumazet + +[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ] + +valis reported that a race condition still happens after my prior patch. + +macvlan_common_newlink() might have made @dev visible before +detecting an error, and its caller will directly call free_netdev(dev). + +We must respect an RCU period, either in macvlan or the core networking +stack. + +After adding a temporary mdelay(1000) in macvlan_forward_source_one() +to open the race window, valis repro was: + +ip link add p1 type veth peer p2 +ip link set address 00:00:00:00:00:20 dev p1 +ip link set up dev p1 +ip link set up dev p2 +ip link add mv0 link p2 type macvlan mode source + +(ip link add invalid% link p2 type macvlan mode source macaddr add +00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4 +PING 1.2.3.4 (1.2.3.4): 56 data bytes +RTNETLINK answers: Invalid argument + +BUG: KASAN: slab-use-after-free in macvlan_forward_source +(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +Read of size 8 at addr ffff888016bb89c0 by task e/175 + +CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +Call Trace: + +dump_stack_lvl (lib/dump_stack.c:123) +print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +kasan_report (mm/kasan/report.c:597) +? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444) +? tasklet_init (kernel/softirq.c:983) +macvlan_handle_frame (drivers/net/macvlan.c:501) + +Allocated by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +__kasan_kmalloc (mm/kasan/common.c:419) +__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657 +mm/slub.c:7140) +alloc_netdev_mqs (net/core/dev.c:12012) +rtnl_create_link (net/core/rtnetlink.c:3648) +rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Freed by task 169: +kasan_save_stack (mm/kasan/common.c:58) +kasan_save_track (./arch/x86/include/asm/current.h:25 +mm/kasan/common.c:70 mm/kasan/common.c:79) +kasan_save_free_info (mm/kasan/generic.c:587) +__kasan_slab_free (mm/kasan/common.c:287) +kfree (mm/slub.c:6674 mm/slub.c:6882) +rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957 +net/core/rtnetlink.c:4072) +rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) +netlink_rcv_skb (net/netlink/af_netlink.c:2550) +netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) +netlink_sendmsg (net/netlink/af_netlink.c:1894) +__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206) +__x64_sys_sendto (net/socket.c:2209) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) + +Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()") +Signed-off-by: Eric Dumazet +Reported-by: valis +Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index fea7352e2a470..4e28fcbf13c74 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1577,6 +1577,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, + if (create) + macvlan_port_destroy(port->dev); + } ++ /* @dev might have been made visible before an error was detected. ++ * Make sure to observe an RCU grace period before our caller ++ * (rtnl_newlink()) frees it. ++ */ ++ synchronize_net(); + return err; + } + EXPORT_SYMBOL_GPL(macvlan_common_newlink); +-- +2.51.0 + diff --git a/queue-6.6/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch b/queue-6.6/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch new file mode 100644 index 0000000000..3930ac79aa --- /dev/null +++ b/queue-6.6/net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch @@ -0,0 +1,192 @@ +From f291b1916d80fe1cf9762322ba5f240958b42c2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 09:00:30 +0200 +Subject: net: bridge: mcast: always update mdb_n_entries for vlan contexts + +From: Nikolay Aleksandrov + +[ Upstream commit 8b769e311a86bb9d15c5658ad283b86fc8f080a2 ] + +syzbot triggered a warning[1] about the number of mdb entries in a context. +It turned out that there are multiple ways to trigger that warning today +(some got added during the years), the root cause of the problem is that +the increase is done conditionally, and over the years these different +conditions increased so there were new ways to trigger the warning, that is +to do a decrease which wasn't paired with a previous increase. + +For example one way to trigger it is with flush: + $ ip l add br0 up type bridge vlan_filtering 1 mcast_snooping 1 + $ ip l add dumdum up master br0 type dummy + $ bridge mdb add dev br0 port dumdum grp 239.0.0.1 permanent vid 1 + $ ip link set dev br0 down + $ ip link set dev br0 type bridge mcast_vlan_snooping 1 + ^^^^ this will enable snooping, but will not update mdb_n_entries + because in __br_multicast_enable_port_ctx() we check !netif_running + $ bridge mdb flush dev br0 + ^^^ this will trigger the warning because it will delete the pg which + we added above, which will try to decrease mdb_n_entries + +Fix the problem by removing the conditional increase and always keep the +count up-to-date while the vlan exists. In order to do that we have to +first initialize it on port-vlan context creation, and then always increase +or decrease the value regardless of mcast options. To keep the current +behaviour we have to enforce the mdb limit only if the context is port's or +if the port-vlan's mcast snooping is enabled. + +[1] + ------------[ cut here ]------------ + n == 0 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline], CPU#0: syz.4.4607/22043 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline], CPU#0: syz.4.4607/22043 + WARNING: net/bridge/br_multicast.c:718 at br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825, CPU#0: syz.4.4607/22043 + Modules linked in: + CPU: 0 UID: 0 PID: 22043 Comm: syz.4.4607 Not tainted syzkaller #0 PREEMPT(full) + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026 + RIP: 0010:br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline] + RIP: 0010:br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline] + RIP: 0010:br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825 + Code: 41 5f 5d e9 04 7a 48 f7 e8 3f 73 5c f7 90 0f 0b 90 e9 cf fd ff ff e8 31 73 5c f7 90 0f 0b 90 e9 16 fd ff ff e8 23 73 5c f7 90 <0f> 0b 90 e9 60 fd ff ff e8 15 73 5c f7 eb 05 e8 0e 73 5c f7 48 8b + RSP: 0018:ffffc9000c207220 EFLAGS: 00010293 + RAX: ffffffff8a68042d RBX: ffff88807c6f1800 RCX: ffff888066e90000 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: 0000000000000000 R08: ffff888066e90000 R09: 000000000000000c + R10: 000000000000000c R11: 0000000000000000 R12: ffff8880303ef800 + R13: dffffc0000000000 R14: ffff888050eb11c4 R15: 1ffff1100a1d6238 + FS: 00007fa45921b6c0(0000) GS:ffff8881256f5000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007fa4591f9ff8 CR3: 0000000081df2000 CR4: 00000000003526f0 + Call Trace: + + br_mdb_flush_pgs net/bridge/br_mdb.c:1525 [inline] + br_mdb_flush net/bridge/br_mdb.c:1544 [inline] + br_mdb_del_bulk+0x5e2/0xb20 net/bridge/br_mdb.c:1561 + rtnl_mdb_del+0x48a/0x640 net/core/rtnetlink.c:-1 + rtnetlink_rcv_msg+0x77e/0xbe0 net/core/rtnetlink.c:6967 + netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550 + netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] + netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344 + netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg net/socket.c:742 [inline] + ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592 + ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646 + __sys_sendmsg net/socket.c:2678 [inline] + __do_sys_sendmsg net/socket.c:2683 [inline] + __se_sys_sendmsg net/socket.c:2681 [inline] + __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + RIP: 0033:0x7fa45839aeb9 + Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48 + RSP: 002b:00007fa45921b028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e + RAX: ffffffffffffffda RBX: 00007fa458615fa0 RCX: 00007fa45839aeb9 + RDX: 0000000000000000 RSI: 00002000000000c0 RDI: 0000000000000004 + RBP: 00007fa458408c1f R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 + R13: 00007fa458616038 R14: 00007fa458615fa0 R15: 00007fff0b59fae8 + + +Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port") +Reported-by: syzbot+d5d1b7343531d17bd3c5@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/aYrWbRp83MQR1ife@debil/T/#t +Reviewed-by: Ido Schimmel +Signed-off-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20260213070031.1400003-2-nikolay@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/bridge/br_multicast.c | 45 ++++++++++++++++----------------------- + 1 file changed, 18 insertions(+), 27 deletions(-) + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 4a2d94e8717e6..4e75ec75c7021 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -243,14 +243,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid) + + lockdep_assert_held_once(&port->br->multicast_lock); + +- if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) +- return NULL; +- + /* Take RCU to access the vlan. */ + rcu_read_lock(); + + vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid); +- if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx)) ++ if (vlan) + pmctx = &vlan->port_mcast_ctx; + + rcu_read_unlock(); +@@ -700,7 +697,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx, + u32 max = READ_ONCE(pmctx->mdb_max_entries); + u32 n = READ_ONCE(pmctx->mdb_n_entries); + +- if (max && n >= max) { ++ /* enforce the max limit when it's a port pmctx or a port-vlan pmctx ++ * with snooping enabled ++ */ ++ if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) { + NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u", + what, n, max); + return -E2BIG; +@@ -735,9 +735,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port, + return err; + } + +- /* Only count on the VLAN context if VID is given, and if snooping on +- * that VLAN is enabled. +- */ ++ /* Only count on the VLAN context if VID is given */ + if (!group->vid) + return 0; + +@@ -2009,6 +2007,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port, + timer_setup(&pmctx->ip6_own_query.timer, + br_ip6_multicast_port_query_expired, 0); + #endif ++ /* initialize mdb_n_entries if a new port vlan is being created */ ++ if (vlan) { ++ struct net_bridge_port_group *pg; ++ u32 n = 0; ++ ++ spin_lock_bh(&port->br->multicast_lock); ++ hlist_for_each_entry(pg, &port->mglist, mglist) ++ if (pg->key.addr.vid == vlan->vid) ++ n++; ++ WRITE_ONCE(pmctx->mdb_n_entries, n); ++ spin_unlock_bh(&port->br->multicast_lock); ++ } + } + + void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx) +@@ -2092,25 +2102,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) + br_ip4_multicast_add_router(brmctx, pmctx); + br_ip6_multicast_add_router(brmctx, pmctx); + } +- +- if (br_multicast_port_ctx_is_vlan(pmctx)) { +- struct net_bridge_port_group *pg; +- u32 n = 0; +- +- /* The mcast_n_groups counter might be wrong. First, +- * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries +- * are flushed, thus mcast_n_groups after the toggle does not +- * reflect the true values. And second, permanent entries added +- * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected +- * either. Thus we have to refresh the counter. +- */ +- +- hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) { +- if (pg->key.addr.vid == pmctx->vlan->vid) +- n++; +- } +- WRITE_ONCE(pmctx->mdb_n_entries, n); +- } + } + + static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) +-- +2.51.0 + diff --git a/queue-6.6/net-mlx5-fix-multiport-device-check-over-light-sfs.patch b/queue-6.6/net-mlx5-fix-multiport-device-check-over-light-sfs.patch new file mode 100644 index 0000000000..c8d68c51fa --- /dev/null +++ b/queue-6.6/net-mlx5-fix-multiport-device-check-over-light-sfs.patch @@ -0,0 +1,55 @@ +From b0a464b55e013fe646a7150cc767ecf2c3233e76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 09:28:59 +0200 +Subject: net/mlx5: Fix multiport device check over light SFs + +From: Shay Drory + +[ Upstream commit 47bf2e813817159f4d195be83a9b5a640ee6baec ] + +Driver is using num_vhca_ports capability to distinguish between +multiport master device and multiport slave device. num_vhca_ports is a +capability the driver sets according to the MAX num_vhca_ports +capability reported by FW. On the other hand, light SFs doesn't set the +above capbility. + +This leads to wrong results whenever light SFs is checking whether he is +a multiport master or slave. + +Therefore, use the MAX capability to distinguish between master and +slave devices. + +Fixes: e71383fb9cd1 ("net/mlx5: Light probe local SFs") +Signed-off-by: Shay Drory +Reviewed-by: Moshe Shemesh +Signed-off-by: Tariq Toukan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260218072904.1764634-2-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/linux/mlx5/driver.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index c0e0468b25a18..c29ecbfbf3da2 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -1288,12 +1288,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev) + static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev) + { + return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) && +- MLX5_CAP_GEN(dev, num_vhca_ports) <= 1; ++ MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1; + } + + static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev) + { +- return MLX5_CAP_GEN(dev, num_vhca_ports) > 1; ++ return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1; + } + + static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev) +-- +2.51.0 + diff --git a/queue-6.6/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch b/queue-6.6/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch new file mode 100644 index 0000000000..ba9e2fa094 --- /dev/null +++ b/queue-6.6/net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch @@ -0,0 +1,62 @@ +From d6267ee421be7d2d0767a6a694f99500c02080e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:02 +0000 +Subject: net: mscc: ocelot: add missing lock protection in + ocelot_port_xmit_inj() + +From: Ziyi Guo + +[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ] + +ocelot_port_xmit_inj() calls ocelot_can_inject() and +ocelot_port_inject_frame() without holding the injection group lock. +Both functions contain lockdep_assert_held() for the injection lock, +and the correct caller felix_port_deferred_xmit() properly acquires +the lock using ocelot_lock_inj_grp() before calling these functions. + +Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register +injection path to fix the missing lock protection. The FDMA path is not +affected as it uses its own locking mechanism. + +Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups") +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 84b3dcf1d2f5a..b516b4e1ed974 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, + int port = priv->port.index; + u32 rew_op = 0; + +- if (!ocelot_can_inject(ocelot, 0)) ++ ocelot_lock_inj_grp(ocelot, 0); ++ ++ if (!ocelot_can_inject(ocelot, 0)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_BUSY; ++ } + +- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { ++ ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_OK; ++ } + + ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + ++ ocelot_unlock_inj_grp(ocelot, 0); ++ + consume_skb(skb); + + return NETDEV_TX_OK; +-- +2.51.0 + diff --git a/queue-6.6/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch b/queue-6.6/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch new file mode 100644 index 0000000000..8de67938e4 --- /dev/null +++ b/queue-6.6/net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch @@ -0,0 +1,93 @@ +From e11b62207d110c0df277e1f6f254a7ff28bec62e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:00 +0000 +Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper + +From: Ziyi Guo + +[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ] + +Extract the PTP timestamp handling logic from ocelot_port_xmit() into a +separate ocelot_xmit_timestamp() helper function. This is a pure +refactor with no behavioral change. + +The helper returns false if the skb was consumed (freed) due to a +timestamp request failure, and true if the caller should continue with +frame injection. The rew_op value is returned via pointer. + +This prepares for splitting ocelot_port_xmit() into separate FDMA and +register injection paths in a subsequent patch. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++---------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index 21a87a3fc5562..e2b475bf58e6c 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -551,33 +551,41 @@ static int ocelot_port_stop(struct net_device *dev) + return 0; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, ++ struct sk_buff *skb, u32 *rew_op) + { +- struct ocelot_port_private *priv = netdev_priv(dev); +- struct ocelot_port *ocelot_port = &priv->port; +- struct ocelot *ocelot = ocelot_port->ocelot; +- int port = priv->port.index; +- u32 rew_op = 0; +- +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) +- return NETDEV_TX_BUSY; +- +- /* Check if timestamping is needed */ + if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + struct sk_buff *clone = NULL; + + if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) { + kfree_skb(skb); +- return NETDEV_TX_OK; ++ return false; + } + + if (clone) + OCELOT_SKB_CB(skb)->clone = clone; + +- rew_op = ocelot_ptp_rew_op(skb); ++ *rew_op = ocelot_ptp_rew_op(skb); + } + ++ return true; ++} ++ ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!static_branch_unlikely(&ocelot_fdma_enabled) && ++ !ocelot_can_inject(ocelot, 0)) ++ return NETDEV_TX_BUSY; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ + if (static_branch_unlikely(&ocelot_fdma_enabled)) { + ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); + } else { +-- +2.51.0 + diff --git a/queue-6.6/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch b/queue-6.6/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch new file mode 100644 index 0000000000..bdb23e6da6 --- /dev/null +++ b/queue-6.6/net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch @@ -0,0 +1,100 @@ +From 5b287416a10c6f89b20d4921df20abd4ad6757a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Feb 2026 22:56:01 +0000 +Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths + +From: Ziyi Guo + +[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ] + +Split ocelot_port_xmit() into two separate functions: +- ocelot_port_xmit_fdma(): handles the FDMA injection path +- ocelot_port_xmit_inj(): handles the register-based injection path + +The top-level ocelot_port_xmit() now dispatches to the appropriate +function based on the ocelot_fdma_enabled static key. + +This is a pure refactor with no behavioral change. Separating the two +code paths makes each one simpler and prepares for adding proper locking +to the register injection path without affecting the FDMA path. + +Signed-off-by: Ziyi Guo +Reviewed-by: Vladimir Oltean +Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu +Signed-off-by: Jakub Kicinski +Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c +index e2b475bf58e6c..84b3dcf1d2f5a 100644 +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -571,7 +571,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, + return true; + } + +-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct ocelot_port_private *priv = netdev_priv(dev); ++ struct ocelot_port *ocelot_port = &priv->port; ++ struct ocelot *ocelot = ocelot_port->ocelot; ++ int port = priv->port.index; ++ u32 rew_op = 0; ++ ++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) ++ return NETDEV_TX_OK; ++ ++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); ++ ++ return NETDEV_TX_OK; ++} ++ ++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, ++ struct net_device *dev) + { + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; +@@ -579,24 +597,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) + int port = priv->port.index; + u32 rew_op = 0; + +- if (!static_branch_unlikely(&ocelot_fdma_enabled) && +- !ocelot_can_inject(ocelot, 0)) ++ if (!ocelot_can_inject(ocelot, 0)) + return NETDEV_TX_BUSY; + + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + return NETDEV_TX_OK; + +- if (static_branch_unlikely(&ocelot_fdma_enabled)) { +- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); +- } else { +- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); ++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + +- consume_skb(skb); +- } ++ consume_skb(skb); + + return NETDEV_TX_OK; + } + ++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ if (static_branch_unlikely(&ocelot_fdma_enabled)) ++ return ocelot_port_xmit_fdma(skb, dev); ++ ++ return ocelot_port_xmit_inj(skb, dev); ++} ++ + enum ocelot_action_type { + OCELOT_MACT_LEARN, + OCELOT_MACT_FORGET, +-- +2.51.0 + diff --git a/queue-6.6/net-rds-rds_sendmsg-should-not-discard-payload_len.patch b/queue-6.6/net-rds-rds_sendmsg-should-not-discard-payload_len.patch new file mode 100644 index 0000000000..2e25050d04 --- /dev/null +++ b/queue-6.6/net-rds-rds_sendmsg-should-not-discard-payload_len.patch @@ -0,0 +1,50 @@ +From 8f36cae60e5f2726fa2c88a82592dd5da2481bdc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:54:09 -0700 +Subject: net/rds: rds_sendmsg should not discard payload_len + +From: Allison Henderson + +[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ] + +Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with +connection teardown") modifies rds_sendmsg to avoid enqueueing work +while a tear down is in progress. However, it also changed the return +value of rds_sendmsg to that of rds_send_xmit instead of the +payload_len. This means the user may incorrectly receive errno values +when it should have simply received a payload of 0 while the peer +attempts a reconnections. So this patch corrects the teardown handling +code to only use the out error path in that case, thus restoring the +original payload_len return value. + +Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown") +Reviewed-by: Simon Horman +Signed-off-by: Allison Henderson +Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/rds/send.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/rds/send.c b/net/rds/send.c +index 09a2801106549..4a24ee9c22d7c 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1382,9 +1382,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) + else + queue_delayed_work(rds_wq, &cpath->cp_send_w, 1); + rcu_read_unlock(); ++ ++ if (ret) ++ goto out; + } +- if (ret) +- goto out; ++ + rds_message_put(rm); + + for (ind = 0; ind < vct.indx; ind++) +-- +2.51.0 + diff --git a/queue-6.6/net-remove-warn_on_once-when-accessing-forward-path-.patch b/queue-6.6/net-remove-warn_on_once-when-accessing-forward-path-.patch new file mode 100644 index 0000000000..56a0fd9ccf --- /dev/null +++ b/queue-6.6/net-remove-warn_on_once-when-accessing-forward-path-.patch @@ -0,0 +1,39 @@ +From 0f44f28a225813d1f376868efa4a67255d484a13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 12:56:39 +0100 +Subject: net: remove WARN_ON_ONCE when accessing forward path array + +From: Pablo Neira Ayuso + +[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ] + +Although unlikely, recent support for IPIP tunnels increases chances of +reaching this WARN_ON_ONCE if userspace manages to build a sufficiently +long forward path. + +Remove it. + +Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 206194bb8fcad..890535fa52be6 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -701,7 +701,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) + { + int k = stack->num_paths++; + +- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) ++ if (k >= NET_DEVICE_PATH_STACK_MAX) + return NULL; + + return &stack->path[k]; +-- +2.51.0 + diff --git a/queue-6.6/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch b/queue-6.6/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch new file mode 100644 index 0000000000..548aa63583 --- /dev/null +++ b/queue-6.6/net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch @@ -0,0 +1,48 @@ +From 14f2bf9c482b625cdf0a5af3b76cfddd5477914b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 14:44:01 +0100 +Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register + width + +From: Daniel Machon + +[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ] + +DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth +across traffic classes based on per-queue cost values, where lower cost +means higher bandwidth share. + +The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware +register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only +5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to +compute cost values that silently overflow via FIELD_PREP, resulting +in incorrect scheduling weights. + +Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width. + +Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc") +Signed-off-by: Daniel Machon +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +index ced35033a6c5d..b1c6c5c6f16ca 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +@@ -35,7 +35,7 @@ + #define SPX5_SE_BURST_UNIT 4096 + + /* Dwrr */ +-#define SPX5_DWRR_COST_MAX 63 ++#define SPX5_DWRR_COST_MAX 31 + + struct sparx5_shaper { + u32 mode; +-- +2.51.0 + diff --git a/queue-6.6/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch b/queue-6.6/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch new file mode 100644 index 0000000000..f986a8f315 --- /dev/null +++ b/queue-6.6/net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch @@ -0,0 +1,53 @@ +From c122d1a99a2704af85feb7ed661b0d08728b92e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 12:02:30 +0100 +Subject: net: sparx5/lan969x: fix PTP clock max_adj value + +From: Daniel Machon + +[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ] + +The max_adj field in ptp_clock_info tells userspace how much the PHC +clock frequency can be adjusted. ptp4l reads this and will never request +a correction larger than max_adj. + +On both sparx5 and lan969x the clock offset may never converge because +the servo needs a frequency correction larger than the current max_adj +of 200000 (200 ppm) allows. The servo rails at the max and the offset +stays in the tens of microseconds. + +The hardware has no inherent max adjustment limit; frequency correction +is done by writing a 64-bit clock period increment to CLK_PER_CFG, and +the register has plenty of range. The 200000 value was just an overly +conservative software limit. The max_adj is shared between sparx5 and +lan969x, and the increased value is safe for both. + +Fix this by increasing max_adj to 10000000 (10000 ppm), giving the +servo sufficient headroom. + +Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks") +Signed-off-by: Daniel Machon +Reviewed-by: Maxime Chevallier +Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +index 5a932460db581..6b2dbfbeef377 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +@@ -562,7 +562,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) + static struct ptp_clock_info sparx5_ptp_clock_info = { + .owner = THIS_MODULE, + .name = "sparx5 ptp", +- .max_adj = 200000, ++ .max_adj = 10000000, + .gettime64 = sparx5_ptp_gettime64, + .settime64 = sparx5_ptp_settime64, + .adjtime = sparx5_ptp_adjtime, +-- +2.51.0 + diff --git a/queue-6.6/net-usb-catc-enable-basic-endpoint-checking.patch b/queue-6.6/net-usb-catc-enable-basic-endpoint-checking.patch new file mode 100644 index 0000000000..61a198d823 --- /dev/null +++ b/queue-6.6/net-usb-catc-enable-basic-endpoint-checking.patch @@ -0,0 +1,111 @@ +From b608072b660771a4b5cc3bc3b724ff1492a352de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 21:41:54 +0000 +Subject: net: usb: catc: enable basic endpoint checking + +From: Ziyi Guo + +[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ] + +catc_probe() fills three URBs with hardcoded endpoint pipes without +verifying the endpoint descriptors: + + - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX + - usb_rcvintpipe(usbdev, 2) for interrupt status + +A malformed USB device can present these endpoints with transfer types +that differ from what the driver assumes. + +Add a catc_usb_ep enum for endpoint numbers, replacing magic constants +throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints() +calls after usb_set_interface() to verify endpoint types before use, +rejecting devices with mismatched descriptors at probe time. + +Similar to +- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking") +which fixed the issue in rtl8150. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Suggested-by: Simon Horman +Signed-off-by: Ziyi Guo +Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c +index ff439ef535ac9..98346cb4ece01 100644 +--- a/drivers/net/usb/catc.c ++++ b/drivers/net/usb/catc.c +@@ -64,6 +64,16 @@ static const char driver_name[] = "catc"; + #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ + #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ + ++/* ++ * USB endpoints. ++ */ ++ ++enum catc_usb_ep { ++ CATC_USB_EP_CONTROL = 0, ++ CATC_USB_EP_BULK = 1, ++ CATC_USB_EP_INT_IN = 2, ++}; ++ + /* + * Control requests. + */ +@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + u8 broadcast[ETH_ALEN]; + u8 *macbuf; + int pktsz, ret = -ENOMEM; ++ static const u8 bulk_ep_addr[] = { ++ CATC_USB_EP_BULK | USB_DIR_OUT, ++ CATC_USB_EP_BULK | USB_DIR_IN, ++ 0}; ++ static const u8 int_ep_addr[] = { ++ CATC_USB_EP_INT_IN | USB_DIR_IN, ++ 0}; + + macbuf = kmalloc(ETH_ALEN, GFP_KERNEL); + if (!macbuf) +@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + goto fail_mem; + } + ++ /* Verify that all required endpoints are present */ ++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || ++ !usb_check_int_endpoints(intf, int_ep_addr)) { ++ dev_err(dev, "Missing or invalid endpoints\n"); ++ ret = -ENODEV; ++ goto fail_mem; ++ } ++ + netdev = alloc_etherdev(sizeof(struct catc)); + if (!netdev) + goto fail_mem; +@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), + NULL, NULL, 0, catc_ctrl_done, catc); + +- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), +- NULL, 0, catc_tx_done, catc); ++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK), ++ NULL, 0, catc_tx_done, catc); + +- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), +- catc->rx_buf, pktsz, catc_rx_done, catc); ++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK), ++ catc->rx_buf, pktsz, catc_rx_done, catc); + +- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), +- catc->irq_buf, 2, catc_irq_done, catc, 1); ++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN), ++ catc->irq_buf, 2, catc_irq_done, catc, 1); + + if (!catc->is_f5u011) { + u32 *buf; +-- +2.51.0 + diff --git a/queue-6.6/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch b/queue-6.6/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch new file mode 100644 index 0000000000..d63dddab16 --- /dev/null +++ b/queue-6.6/netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch @@ -0,0 +1,58 @@ +From 6c772a947a03e0f3326d3adee40149c08c2a4086 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 12:53:09 +0100 +Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value + +From: Florian Westphal + +[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ] + +Mihail Milev reports: Error: UNINIT (CWE-457): + net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl: + Declaring variable "tuple" without initializer. + net/netfilter/nf_conntrack_h323_main.c:1197:2: + uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find". + net/netfilter/nf_conntrack_expect.c:142:2: + read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash". + + 1195| tuple.dst.protonum = IPPROTO_TCP; + 1196| + 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + 1198| if (exp && exp->master == ct) + 1199| return exp; + +Switch this to a C99 initialiser and set the l3num value. + +Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port") +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_h323_main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c +index 5a9bce24f3c3d..ed983421e2eb2 100644 +--- a/net/netfilter/nf_conntrack_h323_main.c ++++ b/net/netfilter/nf_conntrack_h323_main.c +@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, + { + struct net *net = nf_ct_net(ct); + struct nf_conntrack_expect *exp; +- struct nf_conntrack_tuple tuple; ++ struct nf_conntrack_tuple tuple = { ++ .src.l3num = nf_ct_l3num(ct), ++ .dst.protonum = IPPROTO_TCP, ++ .dst.u.tcp.port = port, ++ }; + +- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); +- tuple.src.u.tcp.port = 0; + memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); +- tuple.dst.u.tcp.port = port; +- tuple.dst.protonum = IPPROTO_TCP; + + exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); + if (exp && exp->master == ct) +-- +2.51.0 + diff --git a/queue-6.6/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch b/queue-6.6/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch new file mode 100644 index 0000000000..98f2008c04 --- /dev/null +++ b/queue-6.6/netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch @@ -0,0 +1,54 @@ +From abb4ebcf2d4cc0f9f4391bef9fad65cd60b12b20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Feb 2026 21:14:40 +0900 +Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain() + +From: Inseo An + +[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ] + +nf_tables_addchain() publishes the chain to table->chains via +list_add_tail_rcu() (in nft_chain_add()) before registering hooks. +If nf_tables_register_hook() then fails, the error path calls +nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy() +with no RCU grace period in between. + +This creates two use-after-free conditions: + + 1) Control-plane: nf_tables_dump_chains() traverses table->chains + under rcu_read_lock(). A concurrent dump can still be walking + the chain when the error path frees it. + + 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly + installs the IPv4 hook before IPv6 registration fails. Packets + entering nft_do_chain() via the transient IPv4 hook can still be + dereferencing chain->blob_gen_X when the error path frees the + chain. + +Add synchronize_rcu() between nft_chain_del() and the chain destroy +so that all RCU readers -- both dump threads and in-flight packet +evaluation -- have finished before the chain is freed. + +Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain") +Signed-off-by: Inseo An +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 8532d832aad6a..41614e897ec8f 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2581,6 +2581,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, + + err_register_hook: + nft_chain_del(chain); ++ synchronize_rcu(); + err_chain_add: + nft_trans_destroy(trans); + err_trans: +-- +2.51.0 + diff --git a/queue-6.6/netns-ipv4-reorganize-netns_ipv4-fast-path-variables.patch b/queue-6.6/netns-ipv4-reorganize-netns_ipv4-fast-path-variables.patch new file mode 100644 index 0000000000..9216498eb4 --- /dev/null +++ b/queue-6.6/netns-ipv4-reorganize-netns_ipv4-fast-path-variables.patch @@ -0,0 +1,205 @@ +From f36532ad882997aa1d24af45beeccdeaf51dce13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 07:27:54 +0000 +Subject: netns-ipv4: reorganize netns_ipv4 fast path variables + +From: Coco Li + +[ Upstream commit 18fd64d2542292713b0322e6815be059bdee440c ] + +Reorganize fast path variables on tx-txrx-rx order. +Fastpath cacheline ends after sysctl_tcp_rmem. +There are only read-only variables here. (write is on the control path +and not considered in this case) + +Below data generated with pahole on x86 architecture. +Fast path variables span cache lines before change: 4 +Fast path variables span cache lines after change: 2 + +Suggested-by: Eric Dumazet +Reviewed-by: Wei Wang +Reviewed-by: David Ahern +Signed-off-by: Coco Li +Reviewed-by: Eric Dumazet +Reviewed-by: Shakeel Butt +Signed-off-by: David S. Miller +Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line") +Signed-off-by: Sasha Levin +--- + include/net/netns/ipv4.h | 47 +++++++++++++++++++++++++++------------- + net/core/net_namespace.c | 45 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 77 insertions(+), 15 deletions(-) + +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index fb7842dfd185a..3d7e03847b5be 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -42,6 +42,38 @@ struct inet_timewait_death_row { + struct tcp_fastopen_context; + + struct netns_ipv4 { ++ /* Cacheline organization can be found documented in ++ * Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst. ++ * Please update the document when adding new fields. ++ */ ++ ++ /* TX readonly hotpath cache lines */ ++ __cacheline_group_begin(netns_ipv4_read_tx); ++ u8 sysctl_tcp_early_retrans; ++ u8 sysctl_tcp_tso_win_divisor; ++ u8 sysctl_tcp_tso_rtt_log; ++ u8 sysctl_tcp_autocorking; ++ int sysctl_tcp_min_snd_mss; ++ unsigned int sysctl_tcp_notsent_lowat; ++ int sysctl_tcp_limit_output_bytes; ++ int sysctl_tcp_min_rtt_wlen; ++ int sysctl_tcp_wmem[3]; ++ u8 sysctl_ip_fwd_use_pmtu; ++ __cacheline_group_end(netns_ipv4_read_tx); ++ ++ /* TXRX readonly hotpath cache lines */ ++ __cacheline_group_begin(netns_ipv4_read_txrx); ++ u8 sysctl_tcp_moderate_rcvbuf; ++ __cacheline_group_end(netns_ipv4_read_txrx); ++ ++ /* RX readonly hotpath cache line */ ++ __cacheline_group_begin(netns_ipv4_read_rx); ++ u8 sysctl_ip_early_demux; ++ u8 sysctl_tcp_early_demux; ++ int sysctl_tcp_reordering; ++ int sysctl_tcp_rmem[3]; ++ __cacheline_group_end(netns_ipv4_read_rx); ++ + struct inet_timewait_death_row tcp_death_row; + struct udp_table *udp_table; + +@@ -99,17 +131,14 @@ struct netns_ipv4 { + + u8 sysctl_ip_default_ttl; + u8 sysctl_ip_no_pmtu_disc; +- u8 sysctl_ip_fwd_use_pmtu; + u8 sysctl_ip_fwd_update_priority; + u8 sysctl_ip_nonlocal_bind; + u8 sysctl_ip_autobind_reuse; + /* Shall we try to damage output packets if routing dev changes? */ + u8 sysctl_ip_dynaddr; +- u8 sysctl_ip_early_demux; + #ifdef CONFIG_NET_L3_MASTER_DEV + u8 sysctl_raw_l3mdev_accept; + #endif +- u8 sysctl_tcp_early_demux; + u8 sysctl_udp_early_demux; + + u8 sysctl_nexthop_compat_mode; +@@ -122,7 +151,6 @@ struct netns_ipv4 { + u8 sysctl_tcp_mtu_probing; + int sysctl_tcp_mtu_probe_floor; + int sysctl_tcp_base_mss; +- int sysctl_tcp_min_snd_mss; + int sysctl_tcp_probe_threshold; + u32 sysctl_tcp_probe_interval; + +@@ -138,17 +166,14 @@ struct netns_ipv4 { + u8 sysctl_tcp_backlog_ack_defer; + u8 sysctl_tcp_pingpong_thresh; + +- int sysctl_tcp_reordering; + u8 sysctl_tcp_retries1; + u8 sysctl_tcp_retries2; + u8 sysctl_tcp_orphan_retries; + u8 sysctl_tcp_tw_reuse; + int sysctl_tcp_fin_timeout; +- unsigned int sysctl_tcp_notsent_lowat; + u8 sysctl_tcp_sack; + u8 sysctl_tcp_window_scaling; + u8 sysctl_tcp_timestamps; +- u8 sysctl_tcp_early_retrans; + u8 sysctl_tcp_recovery; + u8 sysctl_tcp_thin_linear_timeouts; + u8 sysctl_tcp_slow_start_after_idle; +@@ -164,21 +189,13 @@ struct netns_ipv4 { + u8 sysctl_tcp_frto; + u8 sysctl_tcp_nometrics_save; + u8 sysctl_tcp_no_ssthresh_metrics_save; +- u8 sysctl_tcp_moderate_rcvbuf; +- u8 sysctl_tcp_tso_win_divisor; + u8 sysctl_tcp_workaround_signed_windows; +- int sysctl_tcp_limit_output_bytes; + int sysctl_tcp_challenge_ack_limit; +- int sysctl_tcp_min_rtt_wlen; + u8 sysctl_tcp_min_tso_segs; +- u8 sysctl_tcp_tso_rtt_log; +- u8 sysctl_tcp_autocorking; + u8 sysctl_tcp_reflect_tos; + int sysctl_tcp_invalid_ratelimit; + int sysctl_tcp_pacing_ss_ratio; + int sysctl_tcp_pacing_ca_ratio; +- int sysctl_tcp_wmem[3]; +- int sysctl_tcp_rmem[3]; + unsigned int sysctl_tcp_child_ehash_entries; + unsigned long sysctl_tcp_comp_sack_delay_ns; + unsigned long sysctl_tcp_comp_sack_slack_ns; +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index 20829e0c36cdb..b99fdca441f31 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -1144,11 +1144,56 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid, + rtnl_set_sk_err(net, RTNLGRP_NSID, err); + } + ++#ifdef CONFIG_NET_NS ++static void __init netns_ipv4_struct_check(void) ++{ ++ /* TX readonly hotpath cache lines */ ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_early_retrans); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_tso_win_divisor); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_tso_rtt_log); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_autocorking); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_min_snd_mss); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_notsent_lowat); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_limit_output_bytes); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_min_rtt_wlen); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_tcp_wmem); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx, ++ sysctl_ip_fwd_use_pmtu); ++ CACHELINE_ASSERT_GROUP_SIZE(struct netns_ipv4, netns_ipv4_read_tx, 33); ++ ++ /* TXRX readonly hotpath cache lines */ ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_txrx, ++ sysctl_tcp_moderate_rcvbuf); ++ CACHELINE_ASSERT_GROUP_SIZE(struct netns_ipv4, netns_ipv4_read_txrx, 1); ++ ++ /* RX readonly hotpath cache line */ ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_rx, ++ sysctl_ip_early_demux); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_rx, ++ sysctl_tcp_early_demux); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_rx, ++ sysctl_tcp_reordering); ++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_rx, ++ sysctl_tcp_rmem); ++ CACHELINE_ASSERT_GROUP_SIZE(struct netns_ipv4, netns_ipv4_read_rx, 18); ++} ++#endif ++ + void __init net_ns_init(void) + { + struct net_generic *ng; + + #ifdef CONFIG_NET_NS ++ netns_ipv4_struct_check(); + net_cachep = kmem_cache_create("net_namespace", sizeof(struct net), + SMP_CACHE_BYTES, + SLAB_PANIC|SLAB_ACCOUNT, NULL); +-- +2.51.0 + diff --git a/queue-6.6/octeontx2-af-fix-default-entries-mcam-entry-action.patch b/queue-6.6/octeontx2-af-fix-default-entries-mcam-entry-action.patch new file mode 100644 index 0000000000..322e3d4db8 --- /dev/null +++ b/queue-6.6/octeontx2-af-fix-default-entries-mcam-entry-action.patch @@ -0,0 +1,85 @@ +From 7134bcf62a73fcdb18c15641ad4a919255a23180 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 14:33:38 +0530 +Subject: octeontx2-af: Fix default entries mcam entry action + +From: Hariprasad Kelam + +[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ] + +As per design, AF should update the default MCAM action only when +mcam_index is -1. A bug in the previous patch caused default entries +to be changed even when the request was not for them. + +Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index") +Signed-off-by: Hariprasad Kelam +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++--------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 00ef6d201b973..9b8a6046e6dff 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -1070,32 +1070,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, + rvu_write64(rvu, blkaddr, + NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action); + +- /* update the VF flow rule action with the VF default entry action */ +- if (mcam_index < 0) +- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, +- *(u64 *)&action); +- + /* update the action change in default rule */ + pfvf = rvu_get_pfvf(rvu, pcifunc); + if (pfvf->def_ucast_rule) + pfvf->def_ucast_rule->rx_action = action; + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_PROMISC_ENTRY); ++ if (mcam_index < 0) { ++ /* update the VF flow rule action with the VF default ++ * entry action ++ */ ++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, ++ *(u64 *)&action); + +- /* If PF's promiscuous entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_PROMISC_ENTRY); + +- index = npc_get_nixlf_mcam_index(mcam, pcifunc, +- nixlf, NIXLF_ALLMULTI_ENTRY); +- /* If PF's allmulti entry is enabled, +- * Set RSS action for that entry as well +- */ +- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, +- alg_idx); ++ /* If PF's promiscuous entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ ++ index = npc_get_nixlf_mcam_index(mcam, pcifunc, ++ nixlf, NIXLF_ALLMULTI_ENTRY); ++ /* If PF's allmulti entry is enabled, ++ * Set RSS action for that entry as well ++ */ ++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, ++ blkaddr, alg_idx); ++ } + } + + void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, +-- +2.51.0 + diff --git a/queue-6.6/ping-annotate-data-races-in-ping_lookup.patch b/queue-6.6/ping-annotate-data-races-in-ping_lookup.patch new file mode 100644 index 0000000000..b4b8eb82bd --- /dev/null +++ b/queue-6.6/ping-annotate-data-races-in-ping_lookup.patch @@ -0,0 +1,118 @@ +From a9b6fccd7c9ea9010fc126e90d7de6107c4aa41f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 10:01:49 +0000 +Subject: ping: annotate data-races in ping_lookup() + +From: Eric Dumazet + +[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ] + +isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if +are read locklessly in ping_lookup(). + +Add READ_ONCE()/WRITE_ONCE() annotations. + +The race on isk->inet_rcv_saddr is probably coming from IPv6 support, +but does not deserve a specific backport. + +Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/ping.c | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index 47f2e7dd554ad..fa13cfa2fa00f 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -159,7 +159,7 @@ void ping_unhash(struct sock *sk) + pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); + spin_lock(&ping_table.lock); + if (sk_del_node_init_rcu(sk)) { +- isk->inet_num = 0; ++ WRITE_ONCE(isk->inet_num, 0); + isk->inet_sport = 0; + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + } +@@ -192,31 +192,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + } + + sk_for_each_rcu(sk, hslot) { ++ int bound_dev_if; ++ + if (!net_eq(sock_net(sk), net)) + continue; + isk = inet_sk(sk); + + pr_debug("iterate\n"); +- if (isk->inet_num != ident) ++ if (READ_ONCE(isk->inet_num) != ident) + continue; + ++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); + if (skb->protocol == htons(ETH_P_IP) && + sk->sk_family == AF_INET) { ++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr); ++ + pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk, +- (int) isk->inet_num, &isk->inet_rcv_saddr, +- sk->sk_bound_dev_if); ++ ident, &rcv_saddr, ++ bound_dev_if); + +- if (isk->inet_rcv_saddr && +- isk->inet_rcv_saddr != ip_hdr(skb)->daddr) ++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr) + continue; + #if IS_ENABLED(CONFIG_IPV6) + } else if (skb->protocol == htons(ETH_P_IPV6) && + sk->sk_family == AF_INET6) { + + pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk, +- (int) isk->inet_num, ++ ident, + &sk->sk_v6_rcv_saddr, +- sk->sk_bound_dev_if); ++ bound_dev_if); + + if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && + !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, +@@ -227,8 +231,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + continue; + } + +- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && +- sk->sk_bound_dev_if != sdif) ++ if (bound_dev_if && bound_dev_if != dif && ++ bound_dev_if != sdif) + continue; + + goto exit; +@@ -403,7 +407,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr) + if (saddr->sa_family == AF_INET) { + struct inet_sock *isk = inet_sk(sk); + struct sockaddr_in *addr = (struct sockaddr_in *) saddr; +- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr; ++ ++ isk->inet_saddr = addr->sin_addr.s_addr; ++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr); + #if IS_ENABLED(CONFIG_IPV6) + } else if (saddr->sa_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr; +@@ -860,7 +866,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, + struct sk_buff *skb; + int copied, err; + +- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); ++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, ++ READ_ONCE(isk->inet_num)); + + err = -EOPNOTSUPP; + if (flags & MSG_OOB) +-- +2.51.0 + diff --git a/queue-6.6/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch b/queue-6.6/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch new file mode 100644 index 0000000000..f08cbb6127 --- /dev/null +++ b/queue-6.6/powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch @@ -0,0 +1,49 @@ +From c8dc4af0ceee074f372db6536c633432d217505b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Feb 2026 14:34:01 -0800 +Subject: powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check + +From: Kuppuswamy Sathyanarayanan + +[ Upstream commit c7d54dafa042cf379859dba265fe5afef6fa8770 ] + +On partitioned systems, multiple TPMI instances may exist per package, +but RAPL registers are only valid on one instance since RAPL has +package-scope control. Other instances return invalid versions during +domain parsing, which is expected behavior on such systems. + +Currently this generates a firmware bug warning: + + intel_rapl_tpmi: [Firmware Bug]: Invalid version + +Remove the FW_BUG tag, downgrade to pr_debug(), and update the message +to clarify that invalid versions are expected on partitioned systems +where only one instance can be valid. + +Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver") +Reported-by: Zhang Rui +Signed-off-by: Kuppuswamy Sathyanarayanan +Reviewed-by: Srinivas Pandruvada +Link: https://patch.msgid.link/20260211223401.1575776-1-sathyanarayanan.kuppuswamy@linux.intel.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/intel_rapl_tpmi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c +index 1c48dba0ba96a..6958c2f0b7660 100644 +--- a/drivers/powercap/intel_rapl_tpmi.c ++++ b/drivers/powercap/intel_rapl_tpmi.c +@@ -156,7 +156,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) + tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; + + if (tpmi_domain_version == TPMI_VERSION_INVALID) { +- pr_warn(FW_BUG "Invalid version\n"); ++ pr_debug("Invalid version, other instances may be valid\n"); + return -ENODEV; + } + +-- +2.51.0 + diff --git a/queue-6.6/s390-kexec-make-kexec_sig-available-when-config_modu.patch b/queue-6.6/s390-kexec-make-kexec_sig-available-when-config_modu.patch new file mode 100644 index 0000000000..3e0d0d02a2 --- /dev/null +++ b/queue-6.6/s390-kexec-make-kexec_sig-available-when-config_modu.patch @@ -0,0 +1,61 @@ +From 603e00de5edc37885a89d5b99de1eeac030f17ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Feb 2026 07:29:16 +0100 +Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n + +From: Alexander Egorenkov + +[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ] + +The commit c8424e776b09 ("MODSIGN: Export module signature definitions") +replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the +dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390 +kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT. + +Furthermore, the signature verification in s390 kexec does not require +MODULE_SIG_FORMAT because it requires only the struct module_signature and, +therefore, does not depend on code in kernel/module_signature.c. + +But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is +also incorrect because it makes KEXEC_SIG available on s390 only if some +other arbitrary option (for instance a file system or device driver) +selects it directly or indirectly. + +To properly make KEXEC_SIG available for s390 kernels built with MODULES=y +as well as MODULES=n _and_ also not depend on arbitrary options selecting +SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select +SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y. + +Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions") +Suggested-by: Heiko Carstens +Signed-off-by: Alexander Egorenkov +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index e99dae26500d2..3b2625eb34c5a 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -231,6 +231,7 @@ config S390 + select SPARSE_IRQ + select SWIOTLB + select SYSCTL_EXCEPTION_TRACE ++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG + select THREAD_INFO_IN_TASK + select TRACE_IRQFLAGS_SUPPORT + select TTY +@@ -254,7 +255,7 @@ config ARCH_SUPPORTS_KEXEC_FILE + def_bool y + + config ARCH_SUPPORTS_KEXEC_SIG +- def_bool MODULE_SIG_FORMAT ++ def_bool y + + config ARCH_SUPPORTS_KEXEC_PURGATORY + def_bool y +-- +2.51.0 + diff --git a/queue-6.6/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch b/queue-6.6/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch new file mode 100644 index 0000000000..b075b94d1a --- /dev/null +++ b/queue-6.6/selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch @@ -0,0 +1,78 @@ +From 0acdf013c231b607dea8003875686ae602501a59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:05 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with + br_netfilter enabled + +From: Aleksei Oladko + +[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv4 packet contains a zero IP header checksum. After VXLAN +decapsulation, such packets do not pass sanity checks in br_netfilter +and are dropped, which causes the test to fail. + +Fix this by calculating and setting a valid IPv4 header checksum for the +encapsulated packet generated by mausezahn, so that the packet is accepted +by br_netfilter. Fixed by using the payload_template_calc_checksum() / +payload_template_expand_checksum() helpers that are only available +in v6.3 and newer kernels. + +Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index eb307ca37bfa6..002551451a728 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -559,6 +559,21 @@ vxlan_encapped_ping_do() + local inner_tos=$1; shift + local outer_tos=$1; shift + ++ local ipv4hdr=$(: ++ )"45:"$( : IP version + IHL ++ )"$inner_tos:"$( : IP TOS ++ )"00:54:"$( : IP total length ++ )"99:83:"$( : IP identification ++ )"40:00:"$( : IP flags + frag off ++ )"40:"$( : IP TTL ++ )"01:"$( : IP proto ++ )"CHECKSUM:"$( : IP header csum ++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 ++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1 ++ ) ++ local checksum=$(payload_template_calc_checksum "$ipv4hdr") ++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum) ++ + $MZ $dev -c $count -d 100msec -q \ + -b $next_hop_mac -B $dest_ip \ + -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(: +@@ -569,16 +584,7 @@ vxlan_encapped_ping_do() + )"$dest_mac:"$( : ETH daddr + )"$(mac_get w2):"$( : ETH saddr + )"08:00:"$( : ETH type +- )"45:"$( : IP version + IHL +- )"$inner_tos:"$( : IP TOS +- )"00:54:"$( : IP total length +- )"99:83:"$( : IP identification +- )"40:00:"$( : IP flags + frag off +- )"40:"$( : IP TTL +- )"01:"$( : IP proto +- )"00:00:"$( : IP header csum +- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 +- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 ++ )"$ipv4hdr:"$( : IPv4 header + )"08:"$( : ICMP type + )"00:"$( : ICMP code + )"8b:f2:"$( : ICMP csum +-- +2.51.0 + diff --git a/queue-6.6/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch b/queue-6.6/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch new file mode 100644 index 0000000000..13521f278f --- /dev/null +++ b/queue-6.6/selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch @@ -0,0 +1,69 @@ +From bbda4bb7775df718f20e2bf07f64e06a50b37c28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 13:19:06 +0000 +Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with + br_netfilter enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Aleksei Oladko + +[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ] + +The test generates VXLAN traffic using mausezahn, where the encapsulated +inner IPv6 packet has an incorrect payload length set in the IPv6 header. +After VXLAN decapsulation, such packets do not pass sanity checks in +br_netfilter and are dropped, which causes the test to fail. + +Fix this by setting the correct IPv6 payload length for the encapsulated +packet generated by mausezahn, so that the packet is accepted +by br_netfilter. + +tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +lines 698-706 + + )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + )"80:"$( : ICMPv6.type + )"00:"$( : ICMPv6.code + )"00:"$( : ICMPv6.checksum + ) + +Data after IPv6 header: +• 80: — 1 byte (ICMPv6 type) +• 00: — 1 byte (ICMPv6 code) +• 00: — 1 byte (ICMPv6 checksum, truncated) + +Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match +the actual payload size. + +Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6") +Signed-off-by: Aleksei Oladko +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +index bd3f7d492af2b..28284a5aa07a9 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +@@ -695,7 +695,7 @@ vxlan_encapped_ping_do() + )"6"$( : IP version + )"$inner_tos"$( : Traffic class + )"0:00:00:"$( : Flow label +- )"00:08:"$( : Payload length ++ )"00:03:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr +-- +2.51.0 + diff --git a/queue-6.6/selftests-memfd-delete-unused-declarations.patch b/queue-6.6/selftests-memfd-delete-unused-declarations.patch new file mode 100644 index 0000000000..7f6644e531 --- /dev/null +++ b/queue-6.6/selftests-memfd-delete-unused-declarations.patch @@ -0,0 +1,101 @@ +From dd6119c39c549edc4e63147b745a151ab94309b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jan 2024 01:50:57 -0800 +Subject: selftests/memfd: delete unused declarations + +From: Greg Thelen + +[ Upstream commit a9117b4d7f178ea36e8d256f8ab3752839e245b2 ] + +Commit 32d118ad50a5 ("selftests/memfd: add tests for F_SEAL_EXEC"): +- added several unused 'nbytes' local variables + +Commit 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests"): +- orphaned 'newpid_thread_fn2()' forward declaration +- orphaned 'join_newpid_thread()' forward declaration +- added unused 'pid' local in sysctl_simple_child() +- orphaned 'fd' local in sysctl_simple_child() +- added unused 'fd' in sysctl_nested_child() + +Delete the unused locals and forward declarations. + +Link: https://lkml.kernel.org/r/20240118095057.677544-1-gthelen@google.com +Signed-off-by: Greg Thelen +Cc: Aleksa Sarai +Cc: Daniel Verkamp +Cc: Jeff Xu +Cc: Kees Cook +Cc: Shuah Khan +Signed-off-by: Andrew Morton +Stable-dep-of: b24335521de9 ("selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/memfd/memfd_test.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c +index 9c9c82fd18a7e..da88dbe37dda9 100644 +--- a/tools/testing/selftests/memfd/memfd_test.c ++++ b/tools/testing/selftests/memfd/memfd_test.c +@@ -45,8 +45,6 @@ + */ + static size_t mfd_def_size = MFD_DEF_SIZE; + static const char *memfd_str = MEMFD_STR; +-static int newpid_thread_fn2(void *arg); +-static void join_newpid_thread(pid_t pid); + + static ssize_t fd2name(int fd, char *buf, size_t bufsize) + { +@@ -195,7 +193,6 @@ static unsigned int mfd_assert_get_seals(int fd) + static void mfd_assert_has_seals(int fd, unsigned int seals) + { + char buf[PATH_MAX]; +- int nbytes; + unsigned int s; + fd2name(fd, buf, PATH_MAX); + +@@ -715,7 +712,6 @@ static void mfd_assert_mode(int fd, int mode) + { + struct stat st; + char buf[PATH_MAX]; +- int nbytes; + + fd2name(fd, buf, PATH_MAX); + +@@ -734,7 +730,6 @@ static void mfd_assert_mode(int fd, int mode) + static void mfd_assert_chmod(int fd, int mode) + { + char buf[PATH_MAX]; +- int nbytes; + + fd2name(fd, buf, PATH_MAX); + +@@ -750,7 +745,6 @@ static void mfd_fail_chmod(int fd, int mode) + { + struct stat st; + char buf[PATH_MAX]; +- int nbytes; + + fd2name(fd, buf, PATH_MAX); + +@@ -1297,9 +1291,6 @@ static void test_sysctl_set_sysctl2(void) + + static int sysctl_simple_child(void *arg) + { +- int fd; +- int pid; +- + printf("%s sysctl 0\n", memfd_str); + test_sysctl_set_sysctl0(); + +@@ -1364,7 +1355,6 @@ static void test_sysctl_sysctl2_failset(void) + + static int sysctl_nested_child(void *arg) + { +- int fd; + int pid; + + printf("%s nested sysctl 0\n", memfd_str); +-- +2.51.0 + diff --git a/queue-6.6/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch b/queue-6.6/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch new file mode 100644 index 0000000000..1de0e7f4f0 --- /dev/null +++ b/queue-6.6/selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch @@ -0,0 +1,241 @@ +From a8cf7fdd71fa4049c416339cae2f312f6059d4e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Feb 2026 09:38:05 -0500 +Subject: selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT + +From: Aristeu Rozanski + +[ Upstream commit b24335521de92fd2ee22460072b75367ca8860b0 ] + +selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT + +In order to synchronize new processes to test inheritance of memfd_noexec +sysctl, memfd_test sets up the sysctl with a value before creating the new +process. The new process then sends itself a SIGSTOP in order to wait for +the parent to flip the sysctl value and send a SIGCONT signal. + +This would work as intended if it wasn't the fact that the new process is +being created with CLONE_NEWPID, which creates a new PID namespace and the +new process has PID 1 in this namespace. There're restrictions on sending +signals to PID 1 and, although it's relaxed for other than root PID +namespace, it's biting us here. In this specific case the SIGSTOP sent by +the new process is ignored (no error to kill() is returned) and it never +stops its execution. This is usually not noticiable as the parent usually +manages to set the new sysctl value before the child has a chance to run +and the test succeeds. But if you run the test in a loop, it eventually +reproduces: + + while [ 1 ]; do ./memfd_test >log 2>&1 || break; done; cat log + +So this patch replaces the SIGSTOP/SIGCONT synchronization with IPC +semaphore. + +Link: https://lkml.kernel.org/r/a7776389-b3d6-4b18-b438-0b0e3ed1fd3b@work +Fixes: 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests") +Signed-off-by: Aristeu Rozanski +Cc: Aleksa Sarai +Cc: Shuah Khan +Cc: liuye +Cc: Lorenzo Stoakes +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/memfd/memfd_test.c | 113 +++++++++++++++++++-- + 1 file changed, 105 insertions(+), 8 deletions(-) + +diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c +index da88dbe37dda9..f2042de4bab8e 100644 +--- a/tools/testing/selftests/memfd/memfd_test.c ++++ b/tools/testing/selftests/memfd/memfd_test.c +@@ -18,6 +18,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + +@@ -39,6 +42,20 @@ + F_SEAL_EXEC) + + #define MFD_NOEXEC_SEAL 0x0008U ++union semun { ++ int val; ++ struct semid_ds *buf; ++ unsigned short int *array; ++ struct seminfo *__buf; ++}; ++ ++/* ++ * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the ++ * child will be PID 1 and can't send SIGSTOP to themselves due special ++ * treatment of the init task, so the SIGSTOP/SIGCONT synchronization ++ * approach can't be used here. ++ */ ++#define SEM_KEY 0xdeadbeef + + /* + * Default is not to test hugetlbfs +@@ -1333,8 +1350,22 @@ static int sysctl_nested(void *arg) + + static int sysctl_nested_wait(void *arg) + { +- /* Wait for a SIGCONT. */ +- kill(getpid(), SIGSTOP); ++ int sem = semget(SEM_KEY, 1, 0600); ++ struct sembuf sembuf; ++ ++ if (sem < 0) { ++ perror("semget:"); ++ abort(); ++ } ++ sembuf.sem_num = 0; ++ sembuf.sem_flg = 0; ++ sembuf.sem_op = 0; ++ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ abort(); ++ } ++ + return sysctl_nested(arg); + } + +@@ -1355,7 +1386,9 @@ static void test_sysctl_sysctl2_failset(void) + + static int sysctl_nested_child(void *arg) + { +- int pid; ++ int pid, sem; ++ union semun semun; ++ struct sembuf sembuf; + + printf("%s nested sysctl 0\n", memfd_str); + sysctl_assert_write("0"); +@@ -1389,23 +1422,53 @@ static int sysctl_nested_child(void *arg) + test_sysctl_sysctl2_failset); + join_thread(pid); + ++ sem = semget(SEM_KEY, 1, IPC_CREAT | 0600); ++ if (sem < 0) { ++ perror("semget:"); ++ return 1; ++ } ++ semun.val = 1; ++ sembuf.sem_op = -1; ++ sembuf.sem_flg = 0; ++ sembuf.sem_num = 0; ++ + /* Verify that the rules are actually inherited after fork. */ + printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str); + sysctl_assert_write("0"); + ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl1_failset); + sysctl_assert_write("1"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str); + sysctl_assert_write("0"); + ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2_failset); + sysctl_assert_write("2"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + /* +@@ -1415,28 +1478,62 @@ static int sysctl_nested_child(void *arg) + */ + printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str); + sysctl_assert_write("2"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2); + sysctl_assert_write("1"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str); + sysctl_assert_write("2"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl2); + sysctl_assert_write("0"); +- kill(pid, SIGCONT); ++ ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + + printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str); + sysctl_assert_write("1"); ++ ++ if (semctl(sem, 0, SETVAL, semun) < 0) { ++ perror("semctl:"); ++ return 1; ++ } ++ + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, + test_sysctl_sysctl1); + sysctl_assert_write("0"); +- kill(pid, SIGCONT); ++ /* Allow child to continue */ ++ if (semop(sem, &sembuf, 1) < 0) { ++ perror("semop:"); ++ return 1; ++ } + join_thread(pid); + ++ semctl(sem, 0, IPC_RMID); ++ + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.6/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch b/queue-6.6/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch new file mode 100644 index 0000000000..55a2a45f53 --- /dev/null +++ b/queue-6.6/selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch @@ -0,0 +1,57 @@ +From 15b2d8e785967b15bc7af018a6f5dbf72ca40412 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Feb 2026 14:53:53 +0100 +Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2 + +From: Ido Schimmel + +[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ] + +As explained in [1], iproute2 started rejecting tc-police burst sizes +that result in an overflow. This can happen when the burst size is high +enough and the rate is low enough. + +A couple of test cases specify such configurations, resulting in +iproute2 errors and test failure. + +Fix by reducing the burst size so that the test will pass with both new +and old iproute2 versions. + +[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/ + +Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions") +Signed-off-by: Ido Schimmel +Signed-off-by: Petr Machata +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +index 0441a18f098b1..aac8ef490feb8 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +@@ -317,7 +317,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 0.5kbit burst 1m conform-exceed drop/ok ++ action police rate 0.5kbit burst 2k conform-exceed drop/ok + check_fail $? "Incorrect success to add police action with too low rate" + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ +@@ -327,7 +327,7 @@ police_limits_test() + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + flower skip_sw \ +- action police rate 1.5kbit burst 1m conform-exceed drop/ok ++ action police rate 1.5kbit burst 2k conform-exceed drop/ok + check_err $? "Failed to add police action with low rate" + + tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower +-- +2.51.0 + diff --git a/queue-6.6/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch b/queue-6.6/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch new file mode 100644 index 0000000000..ec66c15da6 --- /dev/null +++ b/queue-6.6/selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch @@ -0,0 +1,57 @@ +From cff71c2fa13849512f84b7f7f9a04167eff28026 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:51:59 -0800 +Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout + +From: Jakub Kicinski + +[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ] + +Since we started running selftests in NIPA we have been seeing +tc_actions.sh generate a soft lockup warning on ~20% of the runs. +On the pre-netdev foundation setup it was actually a missed irq +splat from the console. Now it's either that or a lockup. + +I initially suspected a socket locking issue since the test +is exercising local loopback with act_mirred. +After hours of staring at this I noticed in strace that ncat +when -o $file is specified _both_ saves the output to the file +and still prints it to stdout. Because the file being sent +is constructed with: + + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred + ^^^^^^^^^ + +the data printed is all \0. Most terminals don't display nul +characters (and neither does vng output capture save them). +But QEMU's serial console still has to poke them thru which +is very slow and causes the lockup (if the file is >600kB). + +Replace the '-o $file' with '> $file'. This speeds the test up +from 2m20s to 18s on debug kernels, and prevents the warnings. + +Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh +index 5896296365022..b2f9aae401e09 100755 +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -222,7 +222,7 @@ mirred_egress_to_ingress_tcp_test() + ip_proto icmp \ + action drop + +- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & ++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 & + local rpid=$! + ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 + wait -n $rpid +-- +2.51.0 + diff --git a/queue-6.6/series b/queue-6.6/series index a6cec19a65..14e3f320f7 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -253,3 +253,72 @@ backlight-qcom-wled-change-pm8950-wled-configuration.patch dmaengine-fsl-edma-main-convert-to-platform-remove-c.patch dmaengine-fsl-edma-don-t-explicitly-disable-clocks-i.patch io_uring-cancel-de-unionize-file-and-user_data-in-st.patch +fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch +fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch +acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch +powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch +kbuild-add-objtool-to-top-level-clean-target.patch +selftests-memfd-delete-unused-declarations.patch +selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch +acpi-pm-add-unused-power-resource-quirk-for-thundero.patch +cpuidle-skip-governor-when-only-one-idle-state-is-av.patch +selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch +net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch +net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch +net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch +net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch +ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch +net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch +net-usb-catc-enable-basic-endpoint-checking.patch +xen-netback-reject-zero-queue-configuration-from-gue.patch +net-rds-rds_sendmsg-should-not-discard-payload_len.patch +net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch +selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch +selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch +netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch +net-remove-warn_on_once-when-accessing-forward-path-.patch +netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch +ipv6-fix-a-race-in-ip6_sock_set_v6only.patch +bpftool-fix-truncated-netlink-dumps.patch +ping-annotate-data-races-in-ping_lookup.patch +selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch +macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch +icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch +icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch +icmp-prevent-possible-overflow-in-icmp_global_allow.patch +tcp-defer-regular-ack-while-processing-socket-backlo.patch +tcp-set-pingpong-threshold-via-sysctl.patch +cache-enforce-cache-groups.patch +netns-ipv4-reorganize-netns_ipv4-fast-path-variables.patch +cache-add-__cacheline_group_-begin-end-_aligned-coup.patch +inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch +octeontx2-af-fix-default-entries-mcam-entry-action.patch +bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch +net-mlx5-fix-multiport-device-check-over-light-sfs.patch +apparmor-fix-null-sock-in-aa_sock_file_perm.patch +apparmor-return-enomem-in-unpack_perms_table-upon-al.patch +apparmor-fix-rlimit-for-posix-cpu-timers.patch +apparmor-use-passed-in-gfp-flags-in-aa_alloc_null.patch +apparmor-provide-separate-audit-messages-for-file-an.patch +apparmor-refcount-the-pdb.patch +apparmor-remove-apply_modes_to_perms-from-label_matc.patch +apparmor-make-label_match-return-a-consistent-value.patch +apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch +apparmor-fix-aa_label-to-return-state-from-compount-.patch +drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch +drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch +asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch +drm-i915-acpi-free-_dsm-package-when-no-connectors.patch +asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch +drm-amdkfd-fix-debug-watchpoints-for-logical-devices.patch +drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch +spi-wpcm-fiu-use-devm_platform_ioremap_resource_byna.patch +spi-wpcm-fiu-fix-uninitialized-res.patch +spi-wpcm-fiu-simplify-with-dev_err_probe.patch +spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch +s390-kexec-make-kexec_sig-available-when-config_modu.patch +efi-fix-reservation-of-unaccepted-memory-table.patch +btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch +x86-hyperv-fix-error-pointer-dereference.patch +asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch +drm-amd-display-use-same-max-plane-scaling-limits-fo.patch diff --git a/queue-6.6/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch b/queue-6.6/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch new file mode 100644 index 0000000000..63c76c477e --- /dev/null +++ b/queue-6.6/spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch @@ -0,0 +1,49 @@ +From b79b4c97cde12d07c706dfbd75f3f9b73505b83d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 20:41:40 +0800 +Subject: spi: wpcm-fiu: Fix potential NULL pointer dereference in + wpcm_fiu_probe() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felix Gu + +[ Upstream commit 888a0a802c467bbe34a42167bdf9d7331333440a ] + +platform_get_resource_byname() can return NULL, which would cause a crash +when passed the pointer to resource_size(). + +Move the fiu->memory_size assignment after the error check for +devm_ioremap_resource() to prevent the potential NULL pointer dereference. + +Fixes: 9838c182471e ("spi: wpcm-fiu: Add direct map support") +Signed-off-by: Felix Gu +Reviewed-by: J. Neuschäfer +Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-wpcm-fiu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c +index a67432a4bea21..c006889b37ebb 100644 +--- a/drivers/spi/spi-wpcm-fiu.c ++++ b/drivers/spi/spi-wpcm-fiu.c +@@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); + fiu->memory = devm_ioremap_resource(dev, res); +- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + if (IS_ERR(fiu->memory)) + return dev_err_probe(dev, PTR_ERR(fiu->memory), + "Failed to map flash memory window\n"); + ++ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm"); + + wpcm_fiu_hw_init(fiu); +-- +2.51.0 + diff --git a/queue-6.6/spi-wpcm-fiu-fix-uninitialized-res.patch b/queue-6.6/spi-wpcm-fiu-fix-uninitialized-res.patch new file mode 100644 index 0000000000..ded691e4d1 --- /dev/null +++ b/queue-6.6/spi-wpcm-fiu-fix-uninitialized-res.patch @@ -0,0 +1,40 @@ +From 2b86a28b1fb3f5852f01ea056d0495ed3084d6f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 21:25:43 +0800 +Subject: spi: wpcm-fiu: Fix uninitialized res + +From: Jinjie Ruan + +[ Upstream commit 0f2cf3bc4727fd07e3a1c8acb9f83e462b455986 ] + +The second platform_get_resource_byname() can not be replaced with +devm_platform_ioremap_resource_byname(), because the intermediate "res" +is used by resource_size() later. + +Fixes: 3bf2a5359b0b ("spi: wpcm-fiu: Use devm_platform_ioremap_resource_byname()") +Signed-off-by: Jinjie Ruan +Link: https://patch.msgid.link/20240826132544.3463616-2-ruanjinjie@huawei.com +Signed-off-by: Mark Brown +Stable-dep-of: 888a0a802c46 ("spi: wpcm-fiu: Fix potential NULL pointer dereference in wpcm_fiu_probe()") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-wpcm-fiu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c +index 5d16340524007..d07a06f492044 100644 +--- a/drivers/spi/spi-wpcm-fiu.c ++++ b/drivers/spi/spi-wpcm-fiu.c +@@ -458,7 +458,8 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + if (IS_ERR(fiu->clk)) + return PTR_ERR(fiu->clk); + +- fiu->memory = devm_platform_ioremap_resource_byname(pdev, "memory"); ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); ++ fiu->memory = devm_ioremap_resource(dev, res); + fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + if (IS_ERR(fiu->memory)) { + dev_err(dev, "Failed to map flash memory window\n"); +-- +2.51.0 + diff --git a/queue-6.6/spi-wpcm-fiu-simplify-with-dev_err_probe.patch b/queue-6.6/spi-wpcm-fiu-simplify-with-dev_err_probe.patch new file mode 100644 index 0000000000..200ec02aaa --- /dev/null +++ b/queue-6.6/spi-wpcm-fiu-simplify-with-dev_err_probe.patch @@ -0,0 +1,57 @@ +From d6ace5a2111b0981cf76af646863e14cf1c8585e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 21:25:44 +0800 +Subject: spi: wpcm-fiu: Simplify with dev_err_probe() + +From: Jinjie Ruan + +[ Upstream commit 196d34e2c8cfec7b94e44e75d0b1bc9176acf6f8 ] + +Use the dev_err_probe() helper to simplify error handling during probe. +This also handle scenario, when EDEFER is returned and useless error +is printed. + +Signed-off-by: Jinjie Ruan +Link: https://patch.msgid.link/20240826132544.3463616-3-ruanjinjie@huawei.com +Signed-off-by: Mark Brown +Stable-dep-of: 888a0a802c46 ("spi: wpcm-fiu: Fix potential NULL pointer dereference in wpcm_fiu_probe()") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-wpcm-fiu.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c +index d07a06f492044..a67432a4bea21 100644 +--- a/drivers/spi/spi-wpcm-fiu.c ++++ b/drivers/spi/spi-wpcm-fiu.c +@@ -449,10 +449,9 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + fiu->dev = dev; + + fiu->regs = devm_platform_ioremap_resource_byname(pdev, "control"); +- if (IS_ERR(fiu->regs)) { +- dev_err(dev, "Failed to map registers\n"); +- return PTR_ERR(fiu->regs); +- } ++ if (IS_ERR(fiu->regs)) ++ return dev_err_probe(dev, PTR_ERR(fiu->regs), ++ "Failed to map registers\n"); + + fiu->clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(fiu->clk)) +@@ -461,10 +460,9 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); + fiu->memory = devm_ioremap_resource(dev, res); + fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); +- if (IS_ERR(fiu->memory)) { +- dev_err(dev, "Failed to map flash memory window\n"); +- return PTR_ERR(fiu->memory); +- } ++ if (IS_ERR(fiu->memory)) ++ return dev_err_probe(dev, PTR_ERR(fiu->memory), ++ "Failed to map flash memory window\n"); + + fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm"); + +-- +2.51.0 + diff --git a/queue-6.6/spi-wpcm-fiu-use-devm_platform_ioremap_resource_byna.patch b/queue-6.6/spi-wpcm-fiu-use-devm_platform_ioremap_resource_byna.patch new file mode 100644 index 0000000000..b247da02a3 --- /dev/null +++ b/queue-6.6/spi-wpcm-fiu-use-devm_platform_ioremap_resource_byna.patch @@ -0,0 +1,49 @@ +From b088bc8bb0d2053f387352ac91d1a84d15cf79cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Aug 2024 20:35:18 +0800 +Subject: spi: wpcm-fiu: Use devm_platform_ioremap_resource_byname() + +From: Jinjie Ruan + +[ Upstream commit 3bf2a5359b0bde22418705ec862ac5077312e4c2 ] + +Use the devm_platform_ioremap_resource_byname() helper instead of +calling platform_get_resource_byname() and devm_ioremap_resource() +separately. + +Signed-off-by: Jinjie Ruan +Link: https://patch.msgid.link/20240820123518.1788294-1-ruanjinjie@huawei.com +Signed-off-by: Mark Brown +Stable-dep-of: 888a0a802c46 ("spi: wpcm-fiu: Fix potential NULL pointer dereference in wpcm_fiu_probe()") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-wpcm-fiu.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c +index 852ffe013d326..5d16340524007 100644 +--- a/drivers/spi/spi-wpcm-fiu.c ++++ b/drivers/spi/spi-wpcm-fiu.c +@@ -448,8 +448,7 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + fiu = spi_controller_get_devdata(ctrl); + fiu->dev = dev; + +- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control"); +- fiu->regs = devm_ioremap_resource(dev, res); ++ fiu->regs = devm_platform_ioremap_resource_byname(pdev, "control"); + if (IS_ERR(fiu->regs)) { + dev_err(dev, "Failed to map registers\n"); + return PTR_ERR(fiu->regs); +@@ -459,8 +458,7 @@ static int wpcm_fiu_probe(struct platform_device *pdev) + if (IS_ERR(fiu->clk)) + return PTR_ERR(fiu->clk); + +- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); +- fiu->memory = devm_ioremap_resource(dev, res); ++ fiu->memory = devm_platform_ioremap_resource_byname(pdev, "memory"); + fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + if (IS_ERR(fiu->memory)) { + dev_err(dev, "Failed to map flash memory window\n"); +-- +2.51.0 + diff --git a/queue-6.6/tcp-defer-regular-ack-while-processing-socket-backlo.patch b/queue-6.6/tcp-defer-regular-ack-while-processing-socket-backlo.patch new file mode 100644 index 0000000000..60a40f6668 --- /dev/null +++ b/queue-6.6/tcp-defer-regular-ack-while-processing-socket-backlo.patch @@ -0,0 +1,206 @@ +From a17c938b428aae174884775fb234ded4c40748bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 17:05:31 +0000 +Subject: tcp: defer regular ACK while processing socket backlog + +From: Eric Dumazet + +[ Upstream commit 133c4c0d37175f510a10fa9bed51e223936073fc ] + +This idea came after a particular workload requested +the quickack attribute set on routes, and a performance +drop was noticed for large bulk transfers. + +For high throughput flows, it is best to use one cpu +running the user thread issuing socket system calls, +and a separate cpu to process incoming packets from BH context. +(With TSO/GRO, bottleneck is usually the 'user' cpu) + +Problem is the user thread can spend a lot of time while holding +the socket lock, forcing BH handler to queue most of incoming +packets in the socket backlog. + +Whenever the user thread releases the socket lock, it must first +process all accumulated packets in the backlog, potentially +adding latency spikes. Due to flood mitigation, having too many +packets in the backlog increases chance of unexpected drops. + +Backlog processing unfortunately shifts a fair amount of cpu cycles +from the BH cpu to the 'user' cpu, thus reducing max throughput. + +This patch takes advantage of the backlog processing, +and the fact that ACK are mostly cumulative. + +The idea is to detect we are in the backlog processing +and defer all eligible ACK into a single one, +sent from tcp_release_cb(). + +This saves cpu cycles on both sides, and network resources. + +Performance of a single TCP flow on a 200Gbit NIC: + +- Throughput is increased by 20% (100Gbit -> 120Gbit). +- Number of generated ACK per second shrinks from 240,000 to 40,000. +- Number of backlog drops per second shrinks from 230 to 0. + +Benchmark context: + - Regular netperf TCP_STREAM (no zerocopy) + - Intel(R) Xeon(R) Platinum 8481C (Saphire Rapids) + - MAX_SKB_FRAGS = 17 (~60KB per GRO packet) + +This feature is guarded by a new sysctl, and enabled by default: + /proc/sys/net/ipv4/tcp_backlog_ack_defer + +Signed-off-by: Eric Dumazet +Acked-by: Yuchung Cheng +Acked-by: Neal Cardwell +Acked-by: Soheil Hassas Yeganeh +Acked-by: Dave Taht +Signed-off-by: Paolo Abeni +Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line") +Signed-off-by: Sasha Levin +--- + Documentation/networking/ip-sysctl.rst | 7 +++++++ + include/linux/tcp.h | 14 ++++++++------ + include/net/netns/ipv4.h | 1 + + net/ipv4/sysctl_net_ipv4.c | 9 +++++++++ + net/ipv4/tcp_input.c | 8 ++++++++ + net/ipv4/tcp_ipv4.c | 1 + + net/ipv4/tcp_output.c | 5 ++++- + 7 files changed, 38 insertions(+), 7 deletions(-) + +diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst +index a66054d0763a6..5bfa1837968ce 100644 +--- a/Documentation/networking/ip-sysctl.rst ++++ b/Documentation/networking/ip-sysctl.rst +@@ -745,6 +745,13 @@ tcp_comp_sack_nr - INTEGER + + Default : 44 + ++tcp_backlog_ack_defer - BOOLEAN ++ If set, user thread processing socket backlog tries sending ++ one ACK for the whole queue. This helps to avoid potential ++ long latencies at end of a TCP socket syscall. ++ ++ Default : true ++ + tcp_slow_start_after_idle - BOOLEAN + If set, provide RFC2861 behavior and time out the congestion + window after an idle period. An idle period is defined at +diff --git a/include/linux/tcp.h b/include/linux/tcp.h +index 9b371aa7c7962..e15452df9804f 100644 +--- a/include/linux/tcp.h ++++ b/include/linux/tcp.h +@@ -471,15 +471,17 @@ enum tsq_enum { + TCP_MTU_REDUCED_DEFERRED, /* tcp_v{4|6}_err() could not call + * tcp_v{4|6}_mtu_reduced() + */ ++ TCP_ACK_DEFERRED, /* TX pure ack is deferred */ + }; + + enum tsq_flags { +- TSQF_THROTTLED = (1UL << TSQ_THROTTLED), +- TSQF_QUEUED = (1UL << TSQ_QUEUED), +- TCPF_TSQ_DEFERRED = (1UL << TCP_TSQ_DEFERRED), +- TCPF_WRITE_TIMER_DEFERRED = (1UL << TCP_WRITE_TIMER_DEFERRED), +- TCPF_DELACK_TIMER_DEFERRED = (1UL << TCP_DELACK_TIMER_DEFERRED), +- TCPF_MTU_REDUCED_DEFERRED = (1UL << TCP_MTU_REDUCED_DEFERRED), ++ TSQF_THROTTLED = BIT(TSQ_THROTTLED), ++ TSQF_QUEUED = BIT(TSQ_QUEUED), ++ TCPF_TSQ_DEFERRED = BIT(TCP_TSQ_DEFERRED), ++ TCPF_WRITE_TIMER_DEFERRED = BIT(TCP_WRITE_TIMER_DEFERRED), ++ TCPF_DELACK_TIMER_DEFERRED = BIT(TCP_DELACK_TIMER_DEFERRED), ++ TCPF_MTU_REDUCED_DEFERRED = BIT(TCP_MTU_REDUCED_DEFERRED), ++ TCPF_ACK_DEFERRED = BIT(TCP_ACK_DEFERRED), + }; + + #define tcp_sk(ptr) container_of_const(ptr, struct tcp_sock, inet_conn.icsk_inet.sk) +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 40a3a7e2e6070..3193e362b8a55 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -135,6 +135,7 @@ struct netns_ipv4 { + u8 sysctl_tcp_syncookies; + u8 sysctl_tcp_migrate_req; + u8 sysctl_tcp_comp_sack_nr; ++ u8 sysctl_tcp_backlog_ack_defer; + int sysctl_tcp_reordering; + u8 sysctl_tcp_retries1; + u8 sysctl_tcp_retries2; +diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c +index 7a1164ea3d3af..18bcbcfee824a 100644 +--- a/net/ipv4/sysctl_net_ipv4.c ++++ b/net/ipv4/sysctl_net_ipv4.c +@@ -1366,6 +1366,15 @@ static struct ctl_table ipv4_net_table[] = { + .proc_handler = proc_dou8vec_minmax, + .extra1 = SYSCTL_ZERO, + }, ++ { ++ .procname = "tcp_backlog_ack_defer", ++ .data = &init_net.ipv4.sysctl_tcp_backlog_ack_defer, ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = proc_dou8vec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE, ++ }, + { + .procname = "tcp_reflect_tos", + .data = &init_net.ipv4.sysctl_tcp_reflect_tos, +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 8834cd41b3840..f67967c757714 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5678,6 +5678,14 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible) + tcp_in_quickack_mode(sk) || + /* Protocol state mandates a one-time immediate ACK */ + inet_csk(sk)->icsk_ack.pending & ICSK_ACK_NOW) { ++ /* If we are running from __release_sock() in user context, ++ * Defer the ack until tcp_release_cb(). ++ */ ++ if (sock_owned_by_user_nocheck(sk) && ++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_backlog_ack_defer)) { ++ set_bit(TCP_ACK_DEFERRED, &sk->sk_tsq_flags); ++ return; ++ } + send_now: + tcp_send_ack(sk); + return; +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 2f49a504c9d3e..6cc4cf3ca9f45 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -3279,6 +3279,7 @@ static int __net_init tcp_sk_init(struct net *net) + net->ipv4.sysctl_tcp_comp_sack_delay_ns = NSEC_PER_MSEC; + net->ipv4.sysctl_tcp_comp_sack_slack_ns = 100 * NSEC_PER_USEC; + net->ipv4.sysctl_tcp_comp_sack_nr = 44; ++ net->ipv4.sysctl_tcp_backlog_ack_defer = 1; + net->ipv4.sysctl_tcp_fastopen = TFO_CLIENT_ENABLE; + net->ipv4.sysctl_tcp_fastopen_blackhole_timeout = 0; + atomic_set(&net->ipv4.tfo_active_disable_times, 0); +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 88551db62ca29..b82d1c146d3a4 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1083,7 +1083,8 @@ static void tcp_tasklet_func(struct tasklet_struct *t) + #define TCP_DEFERRED_ALL (TCPF_TSQ_DEFERRED | \ + TCPF_WRITE_TIMER_DEFERRED | \ + TCPF_DELACK_TIMER_DEFERRED | \ +- TCPF_MTU_REDUCED_DEFERRED) ++ TCPF_MTU_REDUCED_DEFERRED | \ ++ TCPF_ACK_DEFERRED) + /** + * tcp_release_cb - tcp release_sock() callback + * @sk: socket +@@ -1130,6 +1131,8 @@ void tcp_release_cb(struct sock *sk) + inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); + __sock_put(sk); + } ++ if ((flags & TCPF_ACK_DEFERRED) && inet_csk_ack_scheduled(sk)) ++ tcp_send_ack(sk); + } + EXPORT_SYMBOL(tcp_release_cb); + +-- +2.51.0 + diff --git a/queue-6.6/tcp-set-pingpong-threshold-via-sysctl.patch b/queue-6.6/tcp-set-pingpong-threshold-via-sysctl.patch new file mode 100644 index 0000000000..940625d2a3 --- /dev/null +++ b/queue-6.6/tcp-set-pingpong-threshold-via-sysctl.patch @@ -0,0 +1,166 @@ +From e52602fe536a06925d7ec1acaae0ea3fd0df344d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 13:30:44 -0700 +Subject: tcp: Set pingpong threshold via sysctl + +From: Haiyang Zhang + +[ Upstream commit 562b1fdf061bff9394ccd884456ed1173c224fdc ] + +TCP pingpong threshold is 1 by default. But some applications, like SQL DB +may prefer a higher pingpong threshold to activate delayed acks in quick +ack mode for better performance. + +The pingpong threshold and related code were changed to 3 in the year +2019 in: + commit 4a41f453bedf ("tcp: change pingpong threshold to 3") +And reverted to 1 in the year 2022 in: + commit 4d8f24eeedc5 ("Revert "tcp: change pingpong threshold to 3"") + +There is no single value that fits all applications. +Add net.ipv4.tcp_pingpong_thresh sysctl tunable, so it can be tuned for +optimal performance based on the application needs. + +Signed-off-by: Haiyang Zhang +Reviewed-by: Simon Horman +Reviewed-by: Eric Dumazet +Acked-by: Neal Cardwell +Reviewed-by: Kuniyuki Iwashima +Link: https://lore.kernel.org/r/1697056244-21888-1-git-send-email-haiyangz@microsoft.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line") +Signed-off-by: Sasha Levin +--- + Documentation/networking/ip-sysctl.rst | 13 +++++++++++++ + include/net/inet_connection_sock.h | 16 ++++++++++++---- + include/net/netns/ipv4.h | 2 ++ + net/ipv4/sysctl_net_ipv4.c | 8 ++++++++ + net/ipv4/tcp_ipv4.c | 2 ++ + net/ipv4/tcp_output.c | 4 ++-- + 6 files changed, 39 insertions(+), 6 deletions(-) + +diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst +index 5bfa1837968ce..531a070df2a6b 100644 +--- a/Documentation/networking/ip-sysctl.rst ++++ b/Documentation/networking/ip-sysctl.rst +@@ -1183,6 +1183,19 @@ tcp_plb_cong_thresh - INTEGER + + Default: 128 + ++tcp_pingpong_thresh - INTEGER ++ The number of estimated data replies sent for estimated incoming data ++ requests that must happen before TCP considers that a connection is a ++ "ping-pong" (request-response) connection for which delayed ++ acknowledgments can provide benefits. ++ ++ This threshold is 1 by default, but some applications may need a higher ++ threshold for optimal performance. ++ ++ Possible Values: 1 - 255 ++ ++ Default: 1 ++ + UDP variables + ============= + +diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h +index e85834722b8f2..3eb715f66cbf6 100644 +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -326,11 +326,10 @@ void inet_csk_update_fastreuse(struct inet_bind_bucket *tb, + + struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu); + +-#define TCP_PINGPONG_THRESH 1 +- + static inline void inet_csk_enter_pingpong_mode(struct sock *sk) + { +- inet_csk(sk)->icsk_ack.pingpong = TCP_PINGPONG_THRESH; ++ inet_csk(sk)->icsk_ack.pingpong = ++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_pingpong_thresh); + } + + static inline void inet_csk_exit_pingpong_mode(struct sock *sk) +@@ -340,7 +339,16 @@ static inline void inet_csk_exit_pingpong_mode(struct sock *sk) + + static inline bool inet_csk_in_pingpong_mode(struct sock *sk) + { +- return inet_csk(sk)->icsk_ack.pingpong >= TCP_PINGPONG_THRESH; ++ return inet_csk(sk)->icsk_ack.pingpong >= ++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_pingpong_thresh); ++} ++ ++static inline void inet_csk_inc_pingpong_cnt(struct sock *sk) ++{ ++ struct inet_connection_sock *icsk = inet_csk(sk); ++ ++ if (icsk->icsk_ack.pingpong < U8_MAX) ++ icsk->icsk_ack.pingpong++; + } + + static inline bool inet_csk_has_ulp(const struct sock *sk) +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index 3193e362b8a55..fb7842dfd185a 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -136,6 +136,8 @@ struct netns_ipv4 { + u8 sysctl_tcp_migrate_req; + u8 sysctl_tcp_comp_sack_nr; + u8 sysctl_tcp_backlog_ack_defer; ++ u8 sysctl_tcp_pingpong_thresh; ++ + int sysctl_tcp_reordering; + u8 sysctl_tcp_retries1; + u8 sysctl_tcp_retries2; +diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c +index 18bcbcfee824a..96f1b8d39fac1 100644 +--- a/net/ipv4/sysctl_net_ipv4.c ++++ b/net/ipv4/sysctl_net_ipv4.c +@@ -1498,6 +1498,14 @@ static struct ctl_table ipv4_net_table[] = { + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, ++ { ++ .procname = "tcp_pingpong_thresh", ++ .data = &init_net.ipv4.sysctl_tcp_pingpong_thresh, ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = proc_dou8vec_minmax, ++ .extra1 = SYSCTL_ONE, ++ }, + { } + }; + +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 6cc4cf3ca9f45..ab4be34e58bb2 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -3303,6 +3303,8 @@ static int __net_init tcp_sk_init(struct net *net) + net->ipv4.sysctl_tcp_syn_linear_timeouts = 4; + net->ipv4.sysctl_tcp_shrink_window = 0; + ++ net->ipv4.sysctl_tcp_pingpong_thresh = 1; ++ + return 0; + } + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index b82d1c146d3a4..db8f2830c67bf 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -170,10 +170,10 @@ static void tcp_event_data_sent(struct tcp_sock *tp, + tp->lsndtime = now; + + /* If it is a reply for ato after last received +- * packet, enter pingpong mode. ++ * packet, increase pingpong count. + */ + if ((u32)(now - icsk->icsk_ack.lrcvtime) < icsk->icsk_ack.ato) +- inet_csk_enter_pingpong_mode(sk); ++ inet_csk_inc_pingpong_cnt(sk); + } + + /* Account for an ACK we sent. */ +-- +2.51.0 + diff --git a/queue-6.6/x86-hyperv-fix-error-pointer-dereference.patch b/queue-6.6/x86-hyperv-fix-error-pointer-dereference.patch new file mode 100644 index 0000000000..08dac36444 --- /dev/null +++ b/queue-6.6/x86-hyperv-fix-error-pointer-dereference.patch @@ -0,0 +1,54 @@ +From acea335c8b2171cd93e02bc4d4e287e7ebfb85a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Feb 2026 13:09:03 -0600 +Subject: x86/hyperv: Fix error pointer dereference + +From: Ethan Tidmore + +[ Upstream commit 705d01c8d78121ee1634bfc602ac4b0ad1438fab ] + +The function idle_thread_get() can return an error pointer and is not +checked for it. Add check for error pointer. + +Detected by Smatch: +arch/x86/hyperv/hv_vtl.c:126 hv_vtl_bringup_vcpu() error: +'idle' dereferencing possible ERR_PTR() + +Fixes: 2b4b90e053a29 ("x86/hyperv: Use per cpu initial stack for vtl context") +Signed-off-by: Ethan Tidmore +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + arch/x86/hyperv/hv_vtl.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c +index b12bef0ff7bb6..4b91b41df5207 100644 +--- a/arch/x86/hyperv/hv_vtl.c ++++ b/arch/x86/hyperv/hv_vtl.c +@@ -68,7 +68,7 @@ static void hv_vtl_ap_entry(void) + + static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) + { +- u64 status; ++ u64 status, rsp, rip; + int ret = 0; + struct hv_enable_vp_vtl *input; + unsigned long irq_flags; +@@ -81,9 +81,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) + struct desc_struct *gdt; + + struct task_struct *idle = idle_thread_get(cpu); +- u64 rsp = (unsigned long)idle->thread.sp; ++ if (IS_ERR(idle)) ++ return PTR_ERR(idle); + +- u64 rip = (u64)&hv_vtl_ap_entry; ++ rsp = (unsigned long)idle->thread.sp; ++ rip = (u64)&hv_vtl_ap_entry; + + native_store_gdt(&gdt_ptr); + store_idt(&idt_ptr); +-- +2.51.0 + diff --git a/queue-6.6/xen-netback-reject-zero-queue-configuration-from-gue.patch b/queue-6.6/xen-netback-reject-zero-queue-configuration-from-gue.patch new file mode 100644 index 0000000000..7b5ed6d3cb --- /dev/null +++ b/queue-6.6/xen-netback-reject-zero-queue-configuration-from-gue.patch @@ -0,0 +1,57 @@ +From 9b38d2c92d3786a0e568b43b6b9933e02e25be51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Feb 2026 22:40:40 +0000 +Subject: xen-netback: reject zero-queue configuration from guest + +From: Ziyi Guo + +[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ] + +A malicious or buggy Xen guest can write "0" to the xenbus key +"multi-queue-num-queues". The connect() function in the backend only +validates the upper bound (requested_num_queues > xenvif_max_queues) +but not zero, allowing requested_num_queues=0 to reach +vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers +WARN_ON_ONCE(!size) in __vmalloc_node_range(). + +On systems with panic_on_warn=1, this allows a guest-to-host denial +of service. + +The Xen network interface specification requires +the queue count to be "greater than zero". + +Add a zero check to match the validation already present +in xen-blkback, which has included this +guard since its multi-queue support was added. + +Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues") +Signed-off-by: Ziyi Guo +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/xen-netback/xenbus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index a78a25b872409..61b547aab286a 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -735,10 +735,11 @@ static void connect(struct backend_info *be) + */ + requested_num_queues = xenbus_read_unsigned(dev->otherend, + "multi-queue-num-queues", 1); +- if (requested_num_queues > xenvif_max_queues) { ++ if (requested_num_queues > xenvif_max_queues || ++ requested_num_queues == 0) { + /* buggy or malicious guest */ + xenbus_dev_fatal(dev, -EINVAL, +- "guest requested %u queues, exceeding the maximum of %u.", ++ "guest requested %u queues, but valid range is 1 - %u.", + requested_num_queues, xenvif_max_queues); + return; + } +-- +2.51.0 + -- 2.47.3