From 81aad6490ddfdcbc3e1b144363275a1db31aabe5 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 15 Jun 2024 22:01:16 -0400 Subject: [PATCH] Fixes for 6.1 Signed-off-by: Sasha Levin --- ...-data-races-around-sk-sk_state-for-w.patch | 88 ++ ...-data-race-of-net-unx.sysctl_max_dgr.patch | 38 + ...-data-race-of-sk-sk_shutdown-in-sk_d.patch | 37 + ...-data-race-of-sk-sk_state-in-unix_in.patch | 50 ++ ...-data-race-of-sk-sk_state-in-unix_st.patch | 60 ++ ...-race-of-sk-sk_state-in-unix_st.patch-1419 | 39 + ...-data-races-around-sk-sk_state-in-se.patch | 72 ++ ...-data-races-around-sk-sk_state-in-un.patch | 128 +++ ...races-around-sk-sk_state-in-un.patch-22249 | 71 ++ ...otate-lockless-accesses-to-sk-sk_err.patch | 66 ++ ...k_state-under-unix_state_lock-for-tr.patch | 90 ++ ...queue_empty_lockless-in-unix_release.patch | 44 + ...queue_len_lockless-in-sk_diag_show_r.patch | 41 + ..._recvq_full_lockless-in-unix_stream_.patch | 72 ++ ...a8155p-adp-fix-sdhc2-cd-pin-configur.patch | 101 +++ ...m8150-align-tlmm-pin-configuration-w.patch | 771 ++++++++++++++++++ ...unt-imbalance-on-inbound-connections.patch | 93 +++ ...ee-in-ax25_dev_free-with-ax25_dev_pu.patch | 39 + ...qca-fix-invalid-device-address-check.patch | 123 +++ ...-context-for-rawtp-test_run-callback.patch | 52 ++ ...f-qgroup-extent-records-after-transa.patch | 65 ++ ...block_start-calculation-for-btrfs_dr.patch | 94 +++ ...rfs_destroy_delayed_refs-return-void.patch | 66 ++ ...ecessary-prototype-declarations-at-d.patch | 45 + ...drop-unnecessary-null-checks-in-debu.patch | 235 ++++++ ...y-fix-incorrect-dsc-instance-for-mst.patch | 166 ++++ ...m-disable-clocks-if-qcom_scm_bw_enab.patch | 98 +++ ...hid-i2c-hid-elan-add-ili9882t-timing.patch | 140 ++++ ...an-fix-reset-suspend-current-leakage.patch | 164 ++++ ...pi-unbind-mux-adapters-before-delete.patch | 158 ++++ queue-6.1/i2c-add-fwnode-apis.patch | 290 +++++++ ...ion-of-tlvs-in-preserved-fields-area.patch | 124 +++ ...uce-new-parameters-in-ice_sched_node.patch | 289 +++++++ .../ice-remove-af_xdp_zc_qps-bitmap.patch | 170 ++++ ...-null-checks-before-devm_kfree-calls.patch | 249 ++++++ ...5-allow-module-autoloading-via-of-co.patch | 51 ++ ...c4005-reset-chip-on-probe-and-resume.patch | 157 ++++ ...ssible-race-in-__fib6_drop_pcpu_from.patch | 130 +++ ...ipv6-ioam-block-bh-from-ioam6_output.patch | 65 ++ ...-in-seg6_output_core-and-seg6_input_.patch | 95 +++ ...e-alloc-extern-to-allow-empty-rust-f.patch | 72 ++ ...misc-pvpanic-deduplicate-common-code.patch | 328 ++++++++ ...i-register-attributes-via-pci_driver.patch | 48 ++ ...-high-order-__gfp_nofail-allocations.patch | 114 +++ ...malloc-which-may-return-null-if-call.patch | 115 +++ ...t-strip-remove-function-when-driver-.patch | 59 ++ ...stop-health-timer-during-driver-remo.patch | 105 +++ ...nted-pointer-delete-is-case-of-flow-.patch | 51 ++ ...unction_setup-to-enable-and-open-fun.patch | 172 ++++ ...iting-for-pci-if-pci-channel-is-offl.patch | 86 ++ ...iting-for-pci-up-if-teardown-was-tri.patch | 45 + ...e-multi-thread-manner-of-ncsi-driver.patch | 220 +++++ ...si-simplify-kconfig-dts-control-flow.patch | 152 ++++ ...ltiq-fix-possible-oob-write-in-multi.patch | 38 + ...-always-validate-tca_taprio_attr_pri.patch | 63 ++ ...erwriting-when-adjusting-sock-bufsiz.patch | 68 ++ ...x-tainted-pointer-delete-is-case-of-.patch | 44 + ..._empty_dir-misjudgment-and-long-loop.patch | 51 ++ ...e-mapped-address-from-nilfs_get_page.patch | 146 ++++ ...ays-allocate-pf-entries-from-low-pri.patch | 87 ++ ...r-message-on-failed-pin-verification.patch | 42 + ...paction_test-fix-bogus-test-success-.patch | 109 +++ ...paction_test-fix-incorrect-write-of-.patch | 43 + ...mm-conform-test-to-tap-format-output.patch | 229 ++++++ ...-a-consistent-test-name-for-check_co.patch | 124 +++ ...-fix-bug-in-sc16is7xx_set_baud-when-.patch | 96 +++ ...-replace-hardcoded-divisor-value-wit.patch | 39 + queue-6.1/series | 86 ++ ...e-wait-sockets-for-tcp_mib_currestab.patch | 71 ++ ...fix-race-between-aio_cancel-and-aio-.patch | 95 +++ ...f_fs-use-io_data-status-consistently.patch | 65 ++ ...sion-when-dropping-packets-due-to-in.patch | 65 ++ ...10k-fix-qcom_rproc_common-dependency.patch | 45 + ...wifi-ath10k-fix-qcom_smem-dependency.patch | 47 ++ ...e-wlan-firmware-version-in-smem-imag.patch | 123 +++ ...lly-move-wiphy-work-to-unbound-workq.patch | 62 ++ ...1-lock-wiphy-in-cfg80211_get_station.patch | 103 +++ ...msr-use-correct-nla_get_ux-functions.patch | 85 ++ ..._ini-move-iwl_dbg_tlv_free-outside-o.patch | 41 + ...-check-n_ssids-before-accessing-the-.patch | 49 ++ ...-don-t-read-past-the-mfuart-notifcat.patch | 55 ++ ...mvm-revert-gen2-tx-a-mpdu-size-to-64.patch | 49 ++ ...rrectly-parse-spatial-reuse-paramete.patch | 65 ++ ...x-deadlock-in-ieee80211_sta_ps_deliv.patch | 109 +++ ...sh-fix-leak-of-mesh_preq_queue-objec.patch | 100 +++ ...-fix-make_pc_from_ra-second-argument.patch | 126 +++ ...e-include-asm-ftrace.h-for-prototype.patch | 40 + 87 files changed, 9153 insertions(+) create mode 100644 queue-6.1/af_unix-annodate-data-races-around-sk-sk_state-for-w.patch create mode 100644 queue-6.1/af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch create mode 100644 queue-6.1/af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch create mode 100644 queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch create mode 100644 queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch create mode 100644 queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch-1419 create mode 100644 queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-se.patch create mode 100644 queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch create mode 100644 queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-22249 create mode 100644 queue-6.1/af_unix-annotate-lockless-accesses-to-sk-sk_err.patch create mode 100644 queue-6.1/af_unix-set-sk-sk_state-under-unix_state_lock-for-tr.patch create mode 100644 queue-6.1/af_unix-use-skb_queue_empty_lockless-in-unix_release.patch create mode 100644 queue-6.1/af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch create mode 100644 queue-6.1/af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch create mode 100644 queue-6.1/arm64-dts-qcom-sa8155p-adp-fix-sdhc2-cd-pin-configur.patch create mode 100644 queue-6.1/arm64-dts-qcom-sm8150-align-tlmm-pin-configuration-w.patch create mode 100644 queue-6.1/ax25-fix-refcount-imbalance-on-inbound-connections.patch create mode 100644 queue-6.1/ax25-replace-kfree-in-ax25_dev_free-with-ax25_dev_pu.patch create mode 100644 queue-6.1/bluetooth-qca-fix-invalid-device-address-check.patch create mode 100644 queue-6.1/bpf-set-run-context-for-rawtp-test_run-callback.patch create mode 100644 queue-6.1/btrfs-fix-leak-of-qgroup-extent-records-after-transa.patch create mode 100644 queue-6.1/btrfs-fix-wrong-block_start-calculation-for-btrfs_dr.patch create mode 100644 queue-6.1/btrfs-make-btrfs_destroy_delayed_refs-return-void.patch create mode 100644 queue-6.1/btrfs-remove-unnecessary-prototype-declarations-at-d.patch create mode 100644 queue-6.1/drm-amd-display-drop-unnecessary-null-checks-in-debu.patch create mode 100644 queue-6.1/drm-amd-display-fix-incorrect-dsc-instance-for-mst.patch create mode 100644 queue-6.1/firmware-qcom_scm-disable-clocks-if-qcom_scm_bw_enab.patch create mode 100644 queue-6.1/hid-i2c-hid-elan-add-ili9882t-timing.patch create mode 100644 queue-6.1/hid-i2c-hid-elan-fix-reset-suspend-current-leakage.patch create mode 100644 queue-6.1/i2c-acpi-unbind-mux-adapters-before-delete.patch create mode 100644 queue-6.1/i2c-add-fwnode-apis.patch create mode 100644 queue-6.1/ice-fix-iteration-of-tlvs-in-preserved-fields-area.patch create mode 100644 queue-6.1/ice-introduce-new-parameters-in-ice_sched_node.patch create mode 100644 queue-6.1/ice-remove-af_xdp_zc_qps-bitmap.patch create mode 100644 queue-6.1/ice-remove-null-checks-before-devm_kfree-calls.patch create mode 100644 queue-6.1/iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch create mode 100644 queue-6.1/iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch create mode 100644 queue-6.1/ipv6-fix-possible-race-in-__fib6_drop_pcpu_from.patch create mode 100644 queue-6.1/ipv6-ioam-block-bh-from-ioam6_output.patch create mode 100644 queue-6.1/ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch create mode 100644 queue-6.1/kbuild-rust-force-alloc-extern-to-allow-empty-rust-f.patch create mode 100644 queue-6.1/misc-pvpanic-deduplicate-common-code.patch create mode 100644 queue-6.1/misc-pvpanic-pci-register-attributes-via-pci_driver.patch create mode 100644 queue-6.1/mm-vmalloc-fix-high-order-__gfp_nofail-allocations.patch create mode 100644 queue-6.1/mm-vmalloc-fix-vmalloc-which-may-return-null-if-call.patch create mode 100644 queue-6.1/mmc-davinci-don-t-strip-remove-function-when-driver-.patch create mode 100644 queue-6.1/net-mlx5-always-stop-health-timer-during-driver-remo.patch create mode 100644 queue-6.1/net-mlx5-fix-tainted-pointer-delete-is-case-of-flow-.patch create mode 100644 queue-6.1/net-mlx5-split-function_setup-to-enable-and-open-fun.patch create mode 100644 queue-6.1/net-mlx5-stop-waiting-for-pci-if-pci-channel-is-offl.patch create mode 100644 queue-6.1/net-mlx5-stop-waiting-for-pci-up-if-teardown-was-tri.patch create mode 100644 queue-6.1/net-ncsi-fix-the-multi-thread-manner-of-ncsi-driver.patch create mode 100644 queue-6.1/net-ncsi-simplify-kconfig-dts-control-flow.patch create mode 100644 queue-6.1/net-sched-sch_multiq-fix-possible-oob-write-in-multi.patch create mode 100644 queue-6.1/net-sched-taprio-always-validate-tca_taprio_attr_pri.patch create mode 100644 queue-6.1/net-smc-avoid-overwriting-when-adjusting-sock-bufsiz.patch create mode 100644 queue-6.1/net-wwan-iosm-fix-tainted-pointer-delete-is-case-of-.patch create mode 100644 queue-6.1/nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch create mode 100644 queue-6.1/nilfs2-return-the-mapped-address-from-nilfs_get_page.patch create mode 100644 queue-6.1/octeontx2-af-always-allocate-pf-entries-from-low-pri.patch create mode 100644 queue-6.1/ptp-fix-error-message-on-failed-pin-verification.patch create mode 100644 queue-6.1/selftests-mm-compaction_test-fix-bogus-test-success-.patch create mode 100644 queue-6.1/selftests-mm-compaction_test-fix-incorrect-write-of-.patch create mode 100644 queue-6.1/selftests-mm-conform-test-to-tap-format-output.patch create mode 100644 queue-6.1/selftests-mm-log-a-consistent-test-name-for-check_co.patch create mode 100644 queue-6.1/serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch create mode 100644 queue-6.1/serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch create mode 100644 queue-6.1/tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch create mode 100644 queue-6.1/usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch create mode 100644 queue-6.1/usb-gadget-f_fs-use-io_data-status-consistently.patch create mode 100644 queue-6.1/vxlan-fix-regression-when-dropping-packets-due-to-in.patch create mode 100644 queue-6.1/wifi-ath10k-fix-qcom_rproc_common-dependency.patch create mode 100644 queue-6.1/wifi-ath10k-fix-qcom_smem-dependency.patch create mode 100644 queue-6.1/wifi-ath10k-store-wlan-firmware-version-in-smem-imag.patch create mode 100644 queue-6.1/wifi-cfg80211-fully-move-wiphy-work-to-unbound-workq.patch create mode 100644 queue-6.1/wifi-cfg80211-lock-wiphy-in-cfg80211_get_station.patch create mode 100644 queue-6.1/wifi-cfg80211-pmsr-use-correct-nla_get_ux-functions.patch create mode 100644 queue-6.1/wifi-iwlwifi-dbg_ini-move-iwl_dbg_tlv_free-outside-o.patch create mode 100644 queue-6.1/wifi-iwlwifi-mvm-check-n_ssids-before-accessing-the-.patch create mode 100644 queue-6.1/wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch create mode 100644 queue-6.1/wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch create mode 100644 queue-6.1/wifi-mac80211-correctly-parse-spatial-reuse-paramete.patch create mode 100644 queue-6.1/wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch create mode 100644 queue-6.1/wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch create mode 100644 queue-6.1/xtensa-fix-make_pc_from_ra-second-argument.patch create mode 100644 queue-6.1/xtensa-stacktrace-include-asm-ftrace.h-for-prototype.patch diff --git a/queue-6.1/af_unix-annodate-data-races-around-sk-sk_state-for-w.patch b/queue-6.1/af_unix-annodate-data-races-around-sk-sk_state-for-w.patch new file mode 100644 index 00000000000..9842e17b439 --- /dev/null +++ b/queue-6.1/af_unix-annodate-data-races-around-sk-sk_state-for-w.patch @@ -0,0 +1,88 @@ +From 060662c04319ff771cc664278a0175fb40f5faa0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:28 -0700 +Subject: af_unix: Annodate data-races around sk->sk_state for writers. + +From: Kuniyuki Iwashima + +[ Upstream commit 942238f9735a4a4ebf8274b218d9a910158941d1 ] + +sk->sk_state is changed under unix_state_lock(), but it's read locklessly +in many places. + +This patch adds WRITE_ONCE() on the writer side. + +We will add READ_ONCE() to the lockless readers in the following patches. + +Fixes: 83301b5367a9 ("af_unix: Set TCP_ESTABLISHED for datagram sockets too") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 5d6203b6e25c3..358e80956cb7b 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -604,7 +604,7 @@ static void unix_release_sock(struct sock *sk, int embrion) + u->path.dentry = NULL; + u->path.mnt = NULL; + state = sk->sk_state; +- sk->sk_state = TCP_CLOSE; ++ WRITE_ONCE(sk->sk_state, TCP_CLOSE); + + skpair = unix_peer(sk); + unix_peer(sk) = NULL; +@@ -726,7 +726,8 @@ static int unix_listen(struct socket *sock, int backlog) + if (backlog > sk->sk_max_ack_backlog) + wake_up_interruptible_all(&u->peer_wait); + sk->sk_max_ack_backlog = backlog; +- sk->sk_state = TCP_LISTEN; ++ WRITE_ONCE(sk->sk_state, TCP_LISTEN); ++ + /* set credentials so connect can copy them */ + init_peercred(sk); + err = 0; +@@ -1389,7 +1390,8 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, + if (err) + goto out_unlock; + +- sk->sk_state = other->sk_state = TCP_ESTABLISHED; ++ WRITE_ONCE(sk->sk_state, TCP_ESTABLISHED); ++ WRITE_ONCE(other->sk_state, TCP_ESTABLISHED); + } else { + /* + * 1003.1g breaking connected state with AF_UNSPEC +@@ -1406,7 +1408,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, + + unix_peer(sk) = other; + if (!other) +- sk->sk_state = TCP_CLOSE; ++ WRITE_ONCE(sk->sk_state, TCP_CLOSE); + unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer); + + unix_state_double_unlock(sk, other); +@@ -1620,7 +1622,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + copy_peercred(sk, other); + + sock->state = SS_CONNECTED; +- sk->sk_state = TCP_ESTABLISHED; ++ WRITE_ONCE(sk->sk_state, TCP_ESTABLISHED); + sock_hold(newsk); + + smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */ +@@ -2015,7 +2017,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, + unix_peer(sk) = NULL; + unix_dgram_peer_wake_disconnect_wakeup(sk, other); + +- sk->sk_state = TCP_CLOSE; ++ WRITE_ONCE(sk->sk_state, TCP_CLOSE); + unix_state_unlock(sk); + + unix_dgram_disconnected(sk, other); +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch b/queue-6.1/af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch new file mode 100644 index 00000000000..1f729b9efc4 --- /dev/null +++ b/queue-6.1/af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch @@ -0,0 +1,38 @@ +From ed9d0a458021ee76c0c7c458b0c19ff4ffe8a512 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:37 -0700 +Subject: af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen. + +From: Kuniyuki Iwashima + +[ Upstream commit bd9f2d05731f6a112d0c7391a0d537bfc588dbe6 ] + +net->unx.sysctl_max_dgram_qlen is exposed as a sysctl knob and can be +changed concurrently. + +Let's use READ_ONCE() in unix_create1(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index f6ba015fffd2f..5cffbd0661406 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -966,7 +966,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, + sk->sk_hash = unix_unbound_hash(sk); + sk->sk_allocation = GFP_KERNEL_ACCOUNT; + sk->sk_write_space = unix_write_space; +- sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen; ++ sk->sk_max_ack_backlog = READ_ONCE(net->unx.sysctl_max_dgram_qlen); + sk->sk_destruct = unix_sock_destructor; + u = unix_sk(sk); + u->inflight = 0; +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch b/queue-6.1/af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch new file mode 100644 index 00000000000..db81eabb126 --- /dev/null +++ b/queue-6.1/af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch @@ -0,0 +1,37 @@ +From 73f968a407b4e6f4944af31b0955109b4753d8a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:41 -0700 +Subject: af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill(). + +From: Kuniyuki Iwashima + +[ Upstream commit efaf24e30ec39ebbea9112227485805a48b0ceb1 ] + +While dumping sockets via UNIX_DIAG, we do not hold unix_state_lock(). + +Let's use READ_ONCE() to read sk->sk_shutdown. + +Fixes: e4e541a84863 ("sock-diag: Report shutdown for inet and unix sockets (v2)") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/diag.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/diag.c b/net/unix/diag.c +index fc56244214c30..1de7500b41b61 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -165,7 +165,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r + sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) + goto out_nlmsg_trim; + +- if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown)) ++ if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, READ_ONCE(sk->sk_shutdown))) + goto out_nlmsg_trim; + + if ((req->udiag_show & UDIAG_SHOW_UID) && +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch b/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch new file mode 100644 index 00000000000..cb8b4c9502f --- /dev/null +++ b/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch @@ -0,0 +1,50 @@ +From 801ff1c2d0f8c5f885add406686115095573f853 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:29 -0700 +Subject: af_unix: Annotate data-race of sk->sk_state in unix_inq_len(). + +From: Kuniyuki Iwashima + +[ Upstream commit 3a0f38eb285c8c2eead4b3230c7ac2983707599d ] + +ioctl(SIOCINQ) calls unix_inq_len() that checks sk->sk_state first +and returns -EINVAL if it's TCP_LISTEN. + +Then, for SOCK_STREAM sockets, unix_inq_len() returns the number of +bytes in recvq. + +However, unix_inq_len() does not hold unix_state_lock(), and the +concurrent listen() might change the state after checking sk->sk_state. + +If the race occurs, 0 is returned for the listener, instead of -EINVAL, +because the length of skb with embryo is 0. + +We could hold unix_state_lock() in unix_inq_len(), but it's overkill +given the result is true for pre-listen() TCP_CLOSE state. + +So, let's use READ_ONCE() for sk->sk_state in unix_inq_len(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 358e80956cb7b..6d7e1cd97c52e 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -3068,7 +3068,7 @@ long unix_inq_len(struct sock *sk) + struct sk_buff *skb; + long amount = 0; + +- if (sk->sk_state == TCP_LISTEN) ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) + return -EINVAL; + + spin_lock(&sk->sk_receive_queue.lock); +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch b/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch new file mode 100644 index 00000000000..61697d31a7d --- /dev/null +++ b/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch @@ -0,0 +1,60 @@ +From bc188fff197443c2f9a1b396429ffb4fc5ebd012 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:31 -0700 +Subject: af_unix: Annotate data-race of sk->sk_state in unix_stream_connect(). + +From: Kuniyuki Iwashima + +[ Upstream commit a9bf9c7dc6a5899c01cb8f6e773a66315a5cd4b7 ] + +As small optimisation, unix_stream_connect() prefetches the client's +sk->sk_state without unix_state_lock() and checks if it's TCP_CLOSE. + +Later, sk->sk_state is checked again under unix_state_lock(). + +Let's use READ_ONCE() for the first check and TCP_CLOSE directly for +the second check. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 67a2a0e842e4f..6e03b364bb727 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1469,7 +1469,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + struct sk_buff *skb = NULL; + long timeo; + int err; +- int st; + + err = unix_validate_addr(sunaddr, addr_len); + if (err) +@@ -1553,9 +1552,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + + Well, and we have to recheck the state after socket locked. + */ +- st = sk->sk_state; +- +- switch (st) { ++ switch (READ_ONCE(sk->sk_state)) { + case TCP_CLOSE: + /* This is ok... continue with connect */ + break; +@@ -1570,7 +1567,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + + unix_state_lock_nested(sk, U_LOCK_SECOND); + +- if (sk->sk_state != st) { ++ if (sk->sk_state != TCP_CLOSE) { + unix_state_unlock(sk); + unix_state_unlock(other); + sock_put(other); +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch-1419 b/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch-1419 new file mode 100644 index 00000000000..d469bb55ab3 --- /dev/null +++ b/queue-6.1/af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch-1419 @@ -0,0 +1,39 @@ +From ca70dbf1c59f7db483e9b753cbcabe7249651816 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:34 -0700 +Subject: af_unix: Annotate data-race of sk->sk_state in + unix_stream_read_skb(). + +From: Kuniyuki Iwashima + +[ Upstream commit af4c733b6b1aded4dc808fafece7dfe6e9d2ebb3 ] + +unix_stream_read_skb() is called from sk->sk_data_ready() context +where unix_state_lock() is not held. + +Let's use READ_ONCE() there. + +Fixes: 77462de14a43 ("af_unix: Add read_sock for stream socket types") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 2e25d9eaa82ea..f6ba015fffd2f 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2716,7 +2716,7 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk, + + static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + { +- if (unlikely(sk->sk_state != TCP_ESTABLISHED)) ++ if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)) + return -ENOTCONN; + + return unix_read_skb(sk, recv_actor); +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-se.patch b/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-se.patch new file mode 100644 index 00000000000..7b48cafefe9 --- /dev/null +++ b/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-se.patch @@ -0,0 +1,72 @@ +From 68c83cf234ebc253af04f52764906d646e64f90a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:33 -0700 +Subject: af_unix: Annotate data-races around sk->sk_state in sendmsg() and + recvmsg(). + +From: Kuniyuki Iwashima + +[ Upstream commit 8a34d4e8d9742a24f74998f45a6a98edd923319b ] + +The following functions read sk->sk_state locklessly and proceed only if +the state is TCP_ESTABLISHED. + + * unix_stream_sendmsg + * unix_stream_read_generic + * unix_seqpacket_sendmsg + * unix_seqpacket_recvmsg + +Let's use READ_ONCE() there. + +Fixes: a05d2ad1c1f3 ("af_unix: Only allow recv on connected seqpacket sockets.") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 6e03b364bb727..2e25d9eaa82ea 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2190,7 +2190,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, + } + + if (msg->msg_namelen) { +- err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; ++ err = READ_ONCE(sk->sk_state) == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; + goto out_err; + } else { + err = -ENOTCONN; +@@ -2402,7 +2402,7 @@ static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg, + if (err) + return err; + +- if (sk->sk_state != TCP_ESTABLISHED) ++ if (READ_ONCE(sk->sk_state) != TCP_ESTABLISHED) + return -ENOTCONN; + + if (msg->msg_namelen) +@@ -2416,7 +2416,7 @@ static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg, + { + struct sock *sk = sock->sk; + +- if (sk->sk_state != TCP_ESTABLISHED) ++ if (READ_ONCE(sk->sk_state) != TCP_ESTABLISHED) + return -ENOTCONN; + + return unix_dgram_recvmsg(sock, msg, size, flags); +@@ -2740,7 +2740,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, + size_t size = state->size; + unsigned int last_len; + +- if (unlikely(sk->sk_state != TCP_ESTABLISHED)) { ++ if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)) { + err = -EINVAL; + goto out; + } +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch b/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch new file mode 100644 index 00000000000..821052dd0af --- /dev/null +++ b/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch @@ -0,0 +1,128 @@ +From 39faefc77944835fa6fa27faf8216a53f51bd2de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:30 -0700 +Subject: af_unix: Annotate data-races around sk->sk_state in + unix_write_space() and poll(). + +From: Kuniyuki Iwashima + +[ Upstream commit eb0718fb3e97ad0d6f4529b810103451c90adf94 ] + +unix_poll() and unix_dgram_poll() read sk->sk_state locklessly and +calls unix_writable() which also reads sk->sk_state without holding +unix_state_lock(). + +Let's use READ_ONCE() in unix_poll() and unix_dgram_poll() and pass +it to unix_writable(). + +While at it, we remove TCP_SYN_SENT check in unix_dgram_poll() as +that state does not exist for AF_UNIX socket since the code was added. + +Fixes: 1586a5877db9 ("af_unix: do not report POLLOUT on listeners") +Fixes: 3c73419c09a5 ("af_unix: fix 'poll for write'/ connected DGRAM sockets") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 6d7e1cd97c52e..67a2a0e842e4f 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -518,9 +518,9 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) + return 0; + } + +-static int unix_writable(const struct sock *sk) ++static int unix_writable(const struct sock *sk, unsigned char state) + { +- return sk->sk_state != TCP_LISTEN && ++ return state != TCP_LISTEN && + (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf; + } + +@@ -529,7 +529,7 @@ static void unix_write_space(struct sock *sk) + struct socket_wq *wq; + + rcu_read_lock(); +- if (unix_writable(sk)) { ++ if (unix_writable(sk, READ_ONCE(sk->sk_state))) { + wq = rcu_dereference(sk->sk_wq); + if (skwq_has_sleeper(wq)) + wake_up_interruptible_sync_poll(&wq->wait, +@@ -3180,12 +3180,14 @@ static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon + static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait) + { + struct sock *sk = sock->sk; ++ unsigned char state; + __poll_t mask; + u8 shutdown; + + sock_poll_wait(file, sock, wait); + mask = 0; + shutdown = READ_ONCE(sk->sk_shutdown); ++ state = READ_ONCE(sk->sk_state); + + /* exceptional events? */ + if (sk->sk_err) +@@ -3207,14 +3209,14 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa + + /* Connection-based need to check for termination and startup */ + if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && +- sk->sk_state == TCP_CLOSE) ++ state == TCP_CLOSE) + mask |= EPOLLHUP; + + /* + * we set writable also when the other side has shut down the + * connection. This prevents stuck sockets. + */ +- if (unix_writable(sk)) ++ if (unix_writable(sk, state)) + mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND; + + return mask; +@@ -3225,12 +3227,14 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, + { + struct sock *sk = sock->sk, *other; + unsigned int writable; ++ unsigned char state; + __poll_t mask; + u8 shutdown; + + sock_poll_wait(file, sock, wait); + mask = 0; + shutdown = READ_ONCE(sk->sk_shutdown); ++ state = READ_ONCE(sk->sk_state); + + /* exceptional events? */ + if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) +@@ -3249,19 +3253,14 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, + mask |= EPOLLIN | EPOLLRDNORM; + + /* Connection-based need to check for termination and startup */ +- if (sk->sk_type == SOCK_SEQPACKET) { +- if (sk->sk_state == TCP_CLOSE) +- mask |= EPOLLHUP; +- /* connection hasn't started yet? */ +- if (sk->sk_state == TCP_SYN_SENT) +- return mask; +- } ++ if (sk->sk_type == SOCK_SEQPACKET && state == TCP_CLOSE) ++ mask |= EPOLLHUP; + + /* No write status requested, avoid expensive OUT tests. */ + if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT))) + return mask; + +- writable = unix_writable(sk); ++ writable = unix_writable(sk, state); + if (writable) { + unix_state_lock(sk); + +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-22249 b/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-22249 new file mode 100644 index 00000000000..d671b8e196f --- /dev/null +++ b/queue-6.1/af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-22249 @@ -0,0 +1,71 @@ +From 96d5317af7a90d51f2164ac4e658df786f5bdf5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:35 -0700 +Subject: af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG. + +From: Kuniyuki Iwashima + +[ Upstream commit 0aa3be7b3e1f8f997312cc4705f8165e02806f8f ] + +While dumping AF_UNIX sockets via UNIX_DIAG, sk->sk_state is read +locklessly. + +Let's use READ_ONCE() there. + +Note that the result could be inconsistent if the socket is dumped +during the state change. This is common for other SOCK_DIAG and +similar interfaces. + +Fixes: c9da99e6475f ("unix_diag: Fixup RQLEN extension report") +Fixes: 2aac7a2cb0d9 ("unix_diag: Pending connections IDs NLA") +Fixes: 45a96b9be6ec ("unix_diag: Dumping all sockets core") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/diag.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/unix/diag.c b/net/unix/diag.c +index 3438b7af09af5..9151c72e742fc 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -65,7 +65,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) + u32 *buf; + int i; + +- if (sk->sk_state == TCP_LISTEN) { ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) { + spin_lock(&sk->sk_receive_queue.lock); + + attr = nla_reserve(nlskb, UNIX_DIAG_ICONS, +@@ -103,7 +103,7 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) + { + struct unix_diag_rqlen rql; + +- if (sk->sk_state == TCP_LISTEN) { ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) { + rql.udiag_rqueue = sk->sk_receive_queue.qlen; + rql.udiag_wqueue = sk->sk_max_ack_backlog; + } else { +@@ -136,7 +136,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r + rep = nlmsg_data(nlh); + rep->udiag_family = AF_UNIX; + rep->udiag_type = sk->sk_type; +- rep->udiag_state = sk->sk_state; ++ rep->udiag_state = READ_ONCE(sk->sk_state); + rep->pad = 0; + rep->udiag_ino = sk_ino; + sock_diag_save_cookie(sk, rep->udiag_cookie); +@@ -215,7 +215,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) + sk_for_each(sk, &net->unx.table.buckets[slot]) { + if (num < s_num) + goto next; +- if (!(req->udiag_states & (1 << sk->sk_state))) ++ if (!(req->udiag_states & (1 << READ_ONCE(sk->sk_state)))) + goto next; + if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk), + NETLINK_CB(cb->skb).portid, +-- +2.43.0 + diff --git a/queue-6.1/af_unix-annotate-lockless-accesses-to-sk-sk_err.patch b/queue-6.1/af_unix-annotate-lockless-accesses-to-sk-sk_err.patch new file mode 100644 index 00000000000..43eb63166b4 --- /dev/null +++ b/queue-6.1/af_unix-annotate-lockless-accesses-to-sk-sk_err.patch @@ -0,0 +1,66 @@ +From 4b11817b7f171800e61a15e88b0043243229b830 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Mar 2023 20:57:46 +0000 +Subject: af_unix: annotate lockless accesses to sk->sk_err + +From: Eric Dumazet + +[ Upstream commit cc04410af7de348234ac36a5f50c4ce416efdb4b ] + +unix_poll() and unix_dgram_poll() read sk->sk_err +without any lock held. + +Add relevant READ_ONCE()/WRITE_ONCE() annotations. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Stable-dep-of: 83690b82d228 ("af_unix: Use skb_queue_empty_lockless() in unix_release_sock().") +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 359d4f604ebda..02d8612385bd9 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -548,7 +548,7 @@ static void unix_dgram_disconnected(struct sock *sk, struct sock *other) + * when peer was not connected to us. + */ + if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) { +- other->sk_err = ECONNRESET; ++ WRITE_ONCE(other->sk_err, ECONNRESET); + sk_error_report(other); + } + } +@@ -620,7 +620,7 @@ static void unix_release_sock(struct sock *sk, int embrion) + /* No more writes */ + WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK); + if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) +- skpair->sk_err = ECONNRESET; ++ WRITE_ONCE(skpair->sk_err, ECONNRESET); + unix_state_unlock(skpair); + skpair->sk_state_change(skpair); + sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); +@@ -3181,7 +3181,7 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa + state = READ_ONCE(sk->sk_state); + + /* exceptional events? */ +- if (sk->sk_err) ++ if (READ_ONCE(sk->sk_err)) + mask |= EPOLLERR; + if (shutdown == SHUTDOWN_MASK) + mask |= EPOLLHUP; +@@ -3228,7 +3228,8 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, + state = READ_ONCE(sk->sk_state); + + /* exceptional events? */ +- if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) ++ if (READ_ONCE(sk->sk_err) || ++ !skb_queue_empty_lockless(&sk->sk_error_queue)) + mask |= EPOLLERR | + (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0); + +-- +2.43.0 + diff --git a/queue-6.1/af_unix-set-sk-sk_state-under-unix_state_lock-for-tr.patch b/queue-6.1/af_unix-set-sk-sk_state-under-unix_state_lock-for-tr.patch new file mode 100644 index 00000000000..4b2212d0f6b --- /dev/null +++ b/queue-6.1/af_unix-set-sk-sk_state-under-unix_state_lock-for-tr.patch @@ -0,0 +1,90 @@ +From d109d393bf5857587363f8e8fd95c8010582b6eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:27 -0700 +Subject: af_unix: Set sk->sk_state under unix_state_lock() for truly + disconencted peer. + +From: Kuniyuki Iwashima + +[ Upstream commit 26bfb8b57063f52b867f9b6c8d1742fcb5bd656c ] + +When a SOCK_DGRAM socket connect()s to another socket, the both sockets' +sk->sk_state are changed to TCP_ESTABLISHED so that we can register them +to BPF SOCKMAP. + +When the socket disconnects from the peer by connect(AF_UNSPEC), the state +is set back to TCP_CLOSE. + +Then, the peer's state is also set to TCP_CLOSE, but the update is done +locklessly and unconditionally. + +Let's say socket A connect()ed to B, B connect()ed to C, and A disconnects +from B. + +After the first two connect()s, all three sockets' sk->sk_state are +TCP_ESTABLISHED: + + $ ss -xa + Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess + u_dgr ESTAB 0 0 @A 641 * 642 + u_dgr ESTAB 0 0 @B 642 * 643 + u_dgr ESTAB 0 0 @C 643 * 0 + +And after the disconnect, B's state is TCP_CLOSE even though it's still +connected to C and C's state is TCP_ESTABLISHED. + + $ ss -xa + Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess + u_dgr UNCONN 0 0 @A 641 * 0 + u_dgr UNCONN 0 0 @B 642 * 643 + u_dgr ESTAB 0 0 @C 643 * 0 + +In this case, we cannot register B to SOCKMAP. + +So, when a socket disconnects from the peer, we should not set TCP_CLOSE to +the peer if the peer is connected to yet another socket, and this must be +done under unix_state_lock(). + +Note that we use WRITE_ONCE() for sk->sk_state as there are many lockless +readers. These data-races will be fixed in the following patches. + +Fixes: 83301b5367a9 ("af_unix: Set TCP_ESTABLISHED for datagram sockets too") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 7d2a3b42b456a..5d6203b6e25c3 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -558,7 +558,6 @@ static void unix_dgram_disconnected(struct sock *sk, struct sock *other) + sk_error_report(other); + } + } +- other->sk_state = TCP_CLOSE; + } + + static void unix_sock_destructor(struct sock *sk) +@@ -1412,8 +1411,15 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, + + unix_state_double_unlock(sk, other); + +- if (other != old_peer) ++ if (other != old_peer) { + unix_dgram_disconnected(sk, old_peer); ++ ++ unix_state_lock(old_peer); ++ if (!unix_peer(old_peer)) ++ WRITE_ONCE(old_peer->sk_state, TCP_CLOSE); ++ unix_state_unlock(old_peer); ++ } ++ + sock_put(old_peer); + } else { + unix_peer(sk) = other; +-- +2.43.0 + diff --git a/queue-6.1/af_unix-use-skb_queue_empty_lockless-in-unix_release.patch b/queue-6.1/af_unix-use-skb_queue_empty_lockless-in-unix_release.patch new file mode 100644 index 00000000000..1095c92b1b0 --- /dev/null +++ b/queue-6.1/af_unix-use-skb_queue_empty_lockless-in-unix_release.patch @@ -0,0 +1,44 @@ +From b72f28a16dbb598c00f7c5b23b42352a153b3b21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:39 -0700 +Subject: af_unix: Use skb_queue_empty_lockless() in unix_release_sock(). + +From: Kuniyuki Iwashima + +[ Upstream commit 83690b82d228b3570565ebd0b41873933238b97f ] + +If the socket type is SOCK_STREAM or SOCK_SEQPACKET, unix_release_sock() +checks the length of the peer socket's recvq under unix_state_lock(). + +However, unix_stream_read_generic() calls skb_unlink() after releasing +the lock. Also, for SOCK_SEQPACKET, __skb_try_recv_datagram() unlinks +skb without unix_state_lock(). + +Thues, unix_state_lock() does not protect qlen. + +Let's use skb_queue_empty_lockless() in unix_release_sock(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 02d8612385bd9..bb94a67229aa3 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -619,7 +619,7 @@ static void unix_release_sock(struct sock *sk, int embrion) + unix_state_lock(skpair); + /* No more writes */ + WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK); +- if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) ++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || embrion) + WRITE_ONCE(skpair->sk_err, ECONNRESET); + unix_state_unlock(skpair); + skpair->sk_state_change(skpair); +-- +2.43.0 + diff --git a/queue-6.1/af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch b/queue-6.1/af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch new file mode 100644 index 00000000000..144223b736d --- /dev/null +++ b/queue-6.1/af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch @@ -0,0 +1,41 @@ +From 67bef1f9eda0e8ec1d4413dab9b6272ad47e1217 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:40 -0700 +Subject: af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen(). + +From: Kuniyuki Iwashima + +[ Upstream commit 5d915e584d8408211d4567c22685aae8820bfc55 ] + +We can dump the socket queue length via UNIX_DIAG by specifying +UDIAG_SHOW_RQLEN. + +If sk->sk_state is TCP_LISTEN, we return the recv queue length, +but here we do not hold recvq lock. + +Let's use skb_queue_len_lockless() in sk_diag_show_rqlen(). + +Fixes: c9da99e6475f ("unix_diag: Fixup RQLEN extension report") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/diag.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/unix/diag.c b/net/unix/diag.c +index 9151c72e742fc..fc56244214c30 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -104,7 +104,7 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) + struct unix_diag_rqlen rql; + + if (READ_ONCE(sk->sk_state) == TCP_LISTEN) { +- rql.udiag_rqueue = sk->sk_receive_queue.qlen; ++ rql.udiag_rqueue = skb_queue_len_lockless(&sk->sk_receive_queue); + rql.udiag_wqueue = sk->sk_max_ack_backlog; + } else { + rql.udiag_rqueue = (u32) unix_inq_len(sk); +-- +2.43.0 + diff --git a/queue-6.1/af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch b/queue-6.1/af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch new file mode 100644 index 00000000000..e457d21c564 --- /dev/null +++ b/queue-6.1/af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch @@ -0,0 +1,72 @@ +From d0e67939a2ddbd16a140b6184f011942150fa4a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 09:52:38 -0700 +Subject: af_unix: Use unix_recvq_full_lockless() in unix_stream_connect(). + +From: Kuniyuki Iwashima + +[ Upstream commit 45d872f0e65593176d880ec148f41ad7c02e40a7 ] + +Once sk->sk_state is changed to TCP_LISTEN, it never changes. + +unix_accept() takes advantage of this characteristics; it does not +hold the listener's unix_state_lock() and only acquires recvq lock +to pop one skb. + +It means unix_state_lock() does not prevent the queue length from +changing in unix_stream_connect(). + +Thus, we need to use unix_recvq_full_lockless() to avoid data-race. + +Now we remove unix_recvq_full() as no one uses it. + +Note that we can remove READ_ONCE() for sk->sk_max_ack_backlog in +unix_recvq_full_lockless() because of the following reasons: + + (1) For SOCK_DGRAM, it is a written-once field in unix_create1() + + (2) For SOCK_STREAM and SOCK_SEQPACKET, it is changed under the + listener's unix_state_lock() in unix_listen(), and we hold + the lock in unix_stream_connect() + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 5cffbd0661406..359d4f604ebda 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -221,15 +221,9 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk) + return unix_peer(osk) == NULL || unix_our_peer(sk, osk); + } + +-static inline int unix_recvq_full(const struct sock *sk) +-{ +- return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog; +-} +- + static inline int unix_recvq_full_lockless(const struct sock *sk) + { +- return skb_queue_len_lockless(&sk->sk_receive_queue) > +- READ_ONCE(sk->sk_max_ack_backlog); ++ return skb_queue_len_lockless(&sk->sk_receive_queue) > sk->sk_max_ack_backlog; + } + + struct sock *unix_peer_get(struct sock *s) +@@ -1527,7 +1521,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + if (other->sk_shutdown & RCV_SHUTDOWN) + goto out_unlock; + +- if (unix_recvq_full(other)) { ++ if (unix_recvq_full_lockless(other)) { + err = -EAGAIN; + if (!timeo) + goto out_unlock; +-- +2.43.0 + diff --git a/queue-6.1/arm64-dts-qcom-sa8155p-adp-fix-sdhc2-cd-pin-configur.patch b/queue-6.1/arm64-dts-qcom-sa8155p-adp-fix-sdhc2-cd-pin-configur.patch new file mode 100644 index 00000000000..226d4f4fb8d --- /dev/null +++ b/queue-6.1/arm64-dts-qcom-sa8155p-adp-fix-sdhc2-cd-pin-configur.patch @@ -0,0 +1,101 @@ +From 549c86f9733521510cf94ad525d0c9b8494ce403 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Apr 2024 19:03:25 +0000 +Subject: arm64: dts: qcom: sa8155p-adp: fix SDHC2 CD pin configuration + +From: Volodymyr Babchuk + +[ Upstream commit 819fe8c96a5172dfd960e5945e8f00f8fed32953 ] + +There are two issues with SDHC2 configuration for SA8155P-ADP, +which prevent use of SDHC2 and causes issues with ethernet: + +- Card Detect pin for SHDC2 on SA8155P-ADP is connected to gpio4 of + PMM8155AU_1, not to SoC itself. SoC's gpio4 is used for DWMAC + TX. If sdhc driver probes after dwmac driver, it reconfigures + gpio4 and this breaks Ethernet MAC. + +- pinctrl configuration mentions gpio96 as CD pin. It seems it was + copied from some SM8150 example, because as mentioned above, + correct CD pin is gpio4 on PMM8155AU_1. + +This patch fixes both mentioned issues by providing correct pin handle +and pinctrl configuration. + +Fixes: 0deb2624e2d0 ("arm64: dts: qcom: sa8155p-adp: Add support for uSD card") +Cc: stable@vger.kernel.org +Signed-off-by: Volodymyr Babchuk +Reviewed-by: Stephan Gerhold +Link: https://lore.kernel.org/r/20240412190310.1647893-1-volodymyr_babchuk@epam.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sa8155p-adp.dts | 30 ++++++++++-------------- + 1 file changed, 13 insertions(+), 17 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts +index 01ac460d910ec..cbec4c9f31025 100644 +--- a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts ++++ b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts +@@ -372,6 +372,16 @@ rgmii_phy: phy@7 { + }; + }; + ++&pmm8155au_1_gpios { ++ pmm8155au_1_sdc2_cd: sdc2-cd-default-state { ++ pins = "gpio4"; ++ function = "normal"; ++ input-enable; ++ bias-pull-up; ++ power-source = <0>; ++ }; ++}; ++ + &qupv3_id_1 { + status = "okay"; + }; +@@ -389,10 +399,10 @@ &remoteproc_cdsp { + &sdhc_2 { + status = "okay"; + +- cd-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; ++ cd-gpios = <&pmm8155au_1_gpios 4 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&sdc2_on>; +- pinctrl-1 = <&sdc2_off>; ++ pinctrl-0 = <&sdc2_on &pmm8155au_1_sdc2_cd>; ++ pinctrl-1 = <&sdc2_off &pmm8155au_1_sdc2_cd>; + vqmmc-supply = <&vreg_l13c_2p96>; /* IO line power */ + vmmc-supply = <&vreg_l17a_2p96>; /* Card power line */ + bus-width = <4>; +@@ -506,13 +516,6 @@ data-pins { + bias-pull-up; /* pull up */ + drive-strength = <16>; /* 16 MA */ + }; +- +- sd-cd-pins { +- pins = "gpio96"; +- function = "gpio"; +- bias-pull-up; /* pull up */ +- drive-strength = <2>; /* 2 MA */ +- }; + }; + + sdc2_off: sdc2-off-state { +@@ -533,13 +536,6 @@ data-pins { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; +- +- sd-cd-pins { +- pins = "gpio96"; +- function = "gpio"; +- bias-pull-up; /* pull up */ +- drive-strength = <2>; /* 2 MA */ +- }; + }; + + usb2phy_ac_en1_default: usb2phy-ac-en1-default-state { +-- +2.43.0 + diff --git a/queue-6.1/arm64-dts-qcom-sm8150-align-tlmm-pin-configuration-w.patch b/queue-6.1/arm64-dts-qcom-sm8150-align-tlmm-pin-configuration-w.patch new file mode 100644 index 00000000000..cba9d3cb0d3 --- /dev/null +++ b/queue-6.1/arm64-dts-qcom-sm8150-align-tlmm-pin-configuration-w.patch @@ -0,0 +1,771 @@ +From 87d1fec4dfe2a602224b065ebb73e5669698e19e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Oct 2022 16:45:17 +0200 +Subject: arm64: dts: qcom: sm8150: align TLMM pin configuration with DT schema + +From: Krzysztof Kozlowski + +[ Upstream commit 028fe09cda0a0d568e6a7d65b0336d32600b480c ] + +DT schema expects TLMM pin configuration nodes to be named with +'-state' suffix and their optional children with '-pins' suffix. + +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Bjorn Andersson +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221006144518.256956-1-krzysztof.kozlowski@linaro.org +Stable-dep-of: 819fe8c96a51 ("arm64: dts: qcom: sa8155p-adp: fix SDHC2 CD pin configuration") +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sa8155p-adp.dts | 60 ++- + .../dts/qcom/sm8150-microsoft-surface-duo.dts | 2 +- + arch/arm64/boot/dts/qcom/sm8150.dtsi | 376 ++++++------------ + 3 files changed, 157 insertions(+), 281 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts +index 4dee790f1049d..01ac460d910ec 100644 +--- a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts ++++ b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts +@@ -488,26 +488,26 @@ &pcie1_phy { + &tlmm { + gpio-reserved-ranges = <0 4>; + +- sdc2_on: sdc2_on { +- clk { ++ sdc2_on: sdc2-on-state { ++ clk-pins { + pins = "sdc2_clk"; + bias-disable; /* No pull */ + drive-strength = <16>; /* 16 MA */ + }; + +- cmd { ++ cmd-pins { + pins = "sdc2_cmd"; + bias-pull-up; /* pull up */ + drive-strength = <16>; /* 16 MA */ + }; + +- data { ++ data-pins { + pins = "sdc2_data"; + bias-pull-up; /* pull up */ + drive-strength = <16>; /* 16 MA */ + }; + +- sd-cd { ++ sd-cd-pins { + pins = "gpio96"; + function = "gpio"; + bias-pull-up; /* pull up */ +@@ -515,26 +515,26 @@ sd-cd { + }; + }; + +- sdc2_off: sdc2_off { +- clk { ++ sdc2_off: sdc2-off-state { ++ clk-pins { + pins = "sdc2_clk"; + bias-disable; /* No pull */ + drive-strength = <2>; /* 2 MA */ + }; + +- cmd { ++ cmd-pins { + pins = "sdc2_cmd"; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + +- data { ++ data-pins { + pins = "sdc2_data"; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + +- sd-cd { ++ sd-cd-pins { + pins = "gpio96"; + function = "gpio"; + bias-pull-up; /* pull up */ +@@ -542,66 +542,62 @@ sd-cd { + }; + }; + +- usb2phy_ac_en1_default: usb2phy_ac_en1_default { +- mux { +- pins = "gpio113"; +- function = "usb2phy_ac"; +- bias-disable; +- drive-strength = <2>; +- }; ++ usb2phy_ac_en1_default: usb2phy-ac-en1-default-state { ++ pins = "gpio113"; ++ function = "usb2phy_ac"; ++ bias-disable; ++ drive-strength = <2>; + }; + +- usb2phy_ac_en2_default: usb2phy_ac_en2_default { +- mux { +- pins = "gpio123"; +- function = "usb2phy_ac"; +- bias-disable; +- drive-strength = <2>; +- }; ++ usb2phy_ac_en2_default: usb2phy-ac-en2-default-state { ++ pins = "gpio123"; ++ function = "usb2phy_ac"; ++ bias-disable; ++ drive-strength = <2>; + }; + +- ethernet_defaults: ethernet-defaults { +- mdc { ++ ethernet_defaults: ethernet-defaults-state { ++ mdc-pins { + pins = "gpio7"; + function = "rgmii"; + bias-pull-up; + }; + +- mdio { ++ mdio-pins { + pins = "gpio59"; + function = "rgmii"; + bias-pull-up; + }; + +- rgmii-rx { ++ rgmii-rx-pins { + pins = "gpio117", "gpio118", "gpio119", "gpio120", "gpio115", "gpio116"; + function = "rgmii"; + bias-disable; + drive-strength = <2>; + }; + +- rgmii-tx { ++ rgmii-tx-pins { + pins = "gpio122", "gpio4", "gpio5", "gpio6", "gpio114", "gpio121"; + function = "rgmii"; + bias-pull-up; + drive-strength = <16>; + }; + +- phy-intr { ++ phy-intr-pins { + pins = "gpio124"; + function = "emac_phy"; + bias-disable; + drive-strength = <8>; + }; + +- pps { ++ pps-pins { + pins = "gpio81"; + function = "emac_pps"; + bias-disable; + drive-strength = <8>; + }; + +- phy-reset { ++ phy-reset-pins { + pins = "gpio79"; + function = "gpio"; + bias-pull-up; +diff --git a/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts b/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts +index bb278ecac3faf..5397fba9417bb 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts ++++ b/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts +@@ -475,7 +475,7 @@ &pon_resin { + &tlmm { + gpio-reserved-ranges = <126 4>; + +- da7280_intr_default: da7280-intr-default { ++ da7280_intr_default: da7280-intr-default-state { + pins = "gpio42"; + function = "gpio"; + bias-pull-up; +diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi +index 9dccecd9fcaef..bbd322fc56460 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi +@@ -2284,422 +2284,302 @@ tlmm: pinctrl@3100000 { + #interrupt-cells = <2>; + wakeup-parent = <&pdc>; + +- qup_i2c0_default: qup-i2c0-default { +- mux { +- pins = "gpio0", "gpio1"; +- function = "qup0"; +- }; +- +- config { +- pins = "gpio0", "gpio1"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c0_default: qup-i2c0-default-state { ++ pins = "gpio0", "gpio1"; ++ function = "qup0"; ++ drive-strength = <0x02>; ++ bias-disable; + }; + +- qup_spi0_default: qup-spi0-default { ++ qup_spi0_default: qup-spi0-default-state { + pins = "gpio0", "gpio1", "gpio2", "gpio3"; + function = "qup0"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c1_default: qup-i2c1-default { +- mux { +- pins = "gpio114", "gpio115"; +- function = "qup1"; +- }; +- +- config { +- pins = "gpio114", "gpio115"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c1_default: qup-i2c1-default-state { ++ pins = "gpio114", "gpio115"; ++ function = "qup1"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi1_default: qup-spi1-default { ++ qup_spi1_default: qup-spi1-default-state { + pins = "gpio114", "gpio115", "gpio116", "gpio117"; + function = "qup1"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c2_default: qup-i2c2-default { +- mux { +- pins = "gpio126", "gpio127"; +- function = "qup2"; +- }; +- +- config { +- pins = "gpio126", "gpio127"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c2_default: qup-i2c2-default-state { ++ pins = "gpio126", "gpio127"; ++ function = "qup2"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi2_default: qup-spi2-default { ++ qup_spi2_default: qup-spi2-default-state { + pins = "gpio126", "gpio127", "gpio128", "gpio129"; + function = "qup2"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c3_default: qup-i2c3-default { +- mux { +- pins = "gpio144", "gpio145"; +- function = "qup3"; +- }; +- +- config { +- pins = "gpio144", "gpio145"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c3_default: qup-i2c3-default-state { ++ pins = "gpio144", "gpio145"; ++ function = "qup3"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi3_default: qup-spi3-default { ++ qup_spi3_default: qup-spi3-default-state { + pins = "gpio144", "gpio145", "gpio146", "gpio147"; + function = "qup3"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c4_default: qup-i2c4-default { +- mux { +- pins = "gpio51", "gpio52"; +- function = "qup4"; +- }; +- +- config { +- pins = "gpio51", "gpio52"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c4_default: qup-i2c4-default-state { ++ pins = "gpio51", "gpio52"; ++ function = "qup4"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi4_default: qup-spi4-default { ++ qup_spi4_default: qup-spi4-default-state { + pins = "gpio51", "gpio52", "gpio53", "gpio54"; + function = "qup4"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c5_default: qup-i2c5-default { +- mux { +- pins = "gpio121", "gpio122"; +- function = "qup5"; +- }; +- +- config { +- pins = "gpio121", "gpio122"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c5_default: qup-i2c5-default-state { ++ pins = "gpio121", "gpio122"; ++ function = "qup5"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi5_default: qup-spi5-default { ++ qup_spi5_default: qup-spi5-default-state { + pins = "gpio119", "gpio120", "gpio121", "gpio122"; + function = "qup5"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c6_default: qup-i2c6-default { +- mux { +- pins = "gpio6", "gpio7"; +- function = "qup6"; +- }; +- +- config { +- pins = "gpio6", "gpio7"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c6_default: qup-i2c6-default-state { ++ pins = "gpio6", "gpio7"; ++ function = "qup6"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi6_default: qup-spi6_default { ++ qup_spi6_default: qup-spi6_default-state { + pins = "gpio4", "gpio5", "gpio6", "gpio7"; + function = "qup6"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c7_default: qup-i2c7-default { +- mux { +- pins = "gpio98", "gpio99"; +- function = "qup7"; +- }; +- +- config { +- pins = "gpio98", "gpio99"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c7_default: qup-i2c7-default-state { ++ pins = "gpio98", "gpio99"; ++ function = "qup7"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi7_default: qup-spi7_default { ++ qup_spi7_default: qup-spi7_default-state { + pins = "gpio98", "gpio99", "gpio100", "gpio101"; + function = "qup7"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c8_default: qup-i2c8-default { +- mux { +- pins = "gpio88", "gpio89"; +- function = "qup8"; +- }; +- +- config { +- pins = "gpio88", "gpio89"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c8_default: qup-i2c8-default-state { ++ pins = "gpio88", "gpio89"; ++ function = "qup8"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi8_default: qup-spi8-default { ++ qup_spi8_default: qup-spi8-default-state { + pins = "gpio88", "gpio89", "gpio90", "gpio91"; + function = "qup8"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c9_default: qup-i2c9-default { +- mux { +- pins = "gpio39", "gpio40"; +- function = "qup9"; +- }; +- +- config { +- pins = "gpio39", "gpio40"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c9_default: qup-i2c9-default-state { ++ pins = "gpio39", "gpio40"; ++ function = "qup9"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi9_default: qup-spi9-default { ++ qup_spi9_default: qup-spi9-default-state { + pins = "gpio39", "gpio40", "gpio41", "gpio42"; + function = "qup9"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c10_default: qup-i2c10-default { +- mux { +- pins = "gpio9", "gpio10"; +- function = "qup10"; +- }; +- +- config { +- pins = "gpio9", "gpio10"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c10_default: qup-i2c10-default-state { ++ pins = "gpio9", "gpio10"; ++ function = "qup10"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi10_default: qup-spi10-default { ++ qup_spi10_default: qup-spi10-default-state { + pins = "gpio9", "gpio10", "gpio11", "gpio12"; + function = "qup10"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c11_default: qup-i2c11-default { +- mux { +- pins = "gpio94", "gpio95"; +- function = "qup11"; +- }; +- +- config { +- pins = "gpio94", "gpio95"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c11_default: qup-i2c11-default-state { ++ pins = "gpio94", "gpio95"; ++ function = "qup11"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi11_default: qup-spi11-default { ++ qup_spi11_default: qup-spi11-default-state { + pins = "gpio92", "gpio93", "gpio94", "gpio95"; + function = "qup11"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c12_default: qup-i2c12-default { +- mux { +- pins = "gpio83", "gpio84"; +- function = "qup12"; +- }; +- +- config { +- pins = "gpio83", "gpio84"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c12_default: qup-i2c12-default-state { ++ pins = "gpio83", "gpio84"; ++ function = "qup12"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi12_default: qup-spi12-default { ++ qup_spi12_default: qup-spi12-default-state { + pins = "gpio83", "gpio84", "gpio85", "gpio86"; + function = "qup12"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c13_default: qup-i2c13-default { +- mux { +- pins = "gpio43", "gpio44"; +- function = "qup13"; +- }; +- +- config { +- pins = "gpio43", "gpio44"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c13_default: qup-i2c13-default-state { ++ pins = "gpio43", "gpio44"; ++ function = "qup13"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi13_default: qup-spi13-default { ++ qup_spi13_default: qup-spi13-default-state { + pins = "gpio43", "gpio44", "gpio45", "gpio46"; + function = "qup13"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c14_default: qup-i2c14-default { +- mux { +- pins = "gpio47", "gpio48"; +- function = "qup14"; +- }; +- +- config { +- pins = "gpio47", "gpio48"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c14_default: qup-i2c14-default-state { ++ pins = "gpio47", "gpio48"; ++ function = "qup14"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi14_default: qup-spi14-default { ++ qup_spi14_default: qup-spi14-default-state { + pins = "gpio47", "gpio48", "gpio49", "gpio50"; + function = "qup14"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c15_default: qup-i2c15-default { +- mux { +- pins = "gpio27", "gpio28"; +- function = "qup15"; +- }; +- +- config { +- pins = "gpio27", "gpio28"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c15_default: qup-i2c15-default-state { ++ pins = "gpio27", "gpio28"; ++ function = "qup15"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi15_default: qup-spi15-default { ++ qup_spi15_default: qup-spi15-default-state { + pins = "gpio27", "gpio28", "gpio29", "gpio30"; + function = "qup15"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c16_default: qup-i2c16-default { +- mux { +- pins = "gpio86", "gpio85"; +- function = "qup16"; +- }; +- +- config { +- pins = "gpio86", "gpio85"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c16_default: qup-i2c16-default-state { ++ pins = "gpio86", "gpio85"; ++ function = "qup16"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi16_default: qup-spi16-default { ++ qup_spi16_default: qup-spi16-default-state { + pins = "gpio83", "gpio84", "gpio85", "gpio86"; + function = "qup16"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c17_default: qup-i2c17-default { +- mux { +- pins = "gpio55", "gpio56"; +- function = "qup17"; +- }; +- +- config { +- pins = "gpio55", "gpio56"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c17_default: qup-i2c17-default-state { ++ pins = "gpio55", "gpio56"; ++ function = "qup17"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi17_default: qup-spi17-default { ++ qup_spi17_default: qup-spi17-default-state { + pins = "gpio55", "gpio56", "gpio57", "gpio58"; + function = "qup17"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c18_default: qup-i2c18-default { +- mux { +- pins = "gpio23", "gpio24"; +- function = "qup18"; +- }; +- +- config { +- pins = "gpio23", "gpio24"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c18_default: qup-i2c18-default-state { ++ pins = "gpio23", "gpio24"; ++ function = "qup18"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi18_default: qup-spi18-default { ++ qup_spi18_default: qup-spi18-default-state { + pins = "gpio23", "gpio24", "gpio25", "gpio26"; + function = "qup18"; + drive-strength = <6>; + bias-disable; + }; + +- qup_i2c19_default: qup-i2c19-default { +- mux { +- pins = "gpio57", "gpio58"; +- function = "qup19"; +- }; +- +- config { +- pins = "gpio57", "gpio58"; +- drive-strength = <0x02>; +- bias-disable; +- }; ++ qup_i2c19_default: qup-i2c19-default-state { ++ pins = "gpio57", "gpio58"; ++ function = "qup19"; ++ drive-strength = <2>; ++ bias-disable; + }; + +- qup_spi19_default: qup-spi19-default { ++ qup_spi19_default: qup-spi19-default-state { + pins = "gpio55", "gpio56", "gpio57", "gpio58"; + function = "qup19"; + drive-strength = <6>; + bias-disable; + }; + +- pcie0_default_state: pcie0-default { +- perst { ++ pcie0_default_state: pcie0-default-state { ++ perst-pins { + pins = "gpio35"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + +- clkreq { ++ clkreq-pins { + pins = "gpio36"; + function = "pci_e0"; + drive-strength = <2>; + bias-pull-up; + }; + +- wake { ++ wake-pins { + pins = "gpio37"; + function = "gpio"; + drive-strength = <2>; +@@ -2707,22 +2587,22 @@ wake { + }; + }; + +- pcie1_default_state: pcie1-default { +- perst { ++ pcie1_default_state: pcie1-default-state { ++ perst-pins { + pins = "gpio102"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + +- clkreq { ++ clkreq-pins { + pins = "gpio103"; + function = "pci_e1"; + drive-strength = <2>; + bias-pull-up; + }; + +- wake { ++ wake-pins { + pins = "gpio104"; + function = "gpio"; + drive-strength = <2>; +-- +2.43.0 + diff --git a/queue-6.1/ax25-fix-refcount-imbalance-on-inbound-connections.patch b/queue-6.1/ax25-fix-refcount-imbalance-on-inbound-connections.patch new file mode 100644 index 00000000000..85bb9761ec0 --- /dev/null +++ b/queue-6.1/ax25-fix-refcount-imbalance-on-inbound-connections.patch @@ -0,0 +1,93 @@ +From aff52dbc50ee3a612d46480e8c2612a2031d7e10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 17:02:43 -0400 +Subject: ax25: Fix refcount imbalance on inbound connections + +From: Lars Kellogg-Stedman + +[ Upstream commit 3c34fb0bd4a4237592c5ecb5b2e2531900c55774 ] + +When releasing a socket in ax25_release(), we call netdev_put() to +decrease the refcount on the associated ax.25 device. However, the +execution path for accepting an incoming connection never calls +netdev_hold(). This imbalance leads to refcount errors, and ultimately +to kernel crashes. + +A typical call trace for the above situation will start with one of the +following errors: + + refcount_t: decrement hit 0; leaking memory. + refcount_t: underflow; use-after-free. + +And will then have a trace like: + + Call Trace: + + ? show_regs+0x64/0x70 + ? __warn+0x83/0x120 + ? refcount_warn_saturate+0xb2/0x100 + ? report_bug+0x158/0x190 + ? prb_read_valid+0x20/0x30 + ? handle_bug+0x3e/0x70 + ? exc_invalid_op+0x1c/0x70 + ? asm_exc_invalid_op+0x1f/0x30 + ? refcount_warn_saturate+0xb2/0x100 + ? refcount_warn_saturate+0xb2/0x100 + ax25_release+0x2ad/0x360 + __sock_release+0x35/0xa0 + sock_close+0x19/0x20 + [...] + +On reboot (or any attempt to remove the interface), the kernel gets +stuck in an infinite loop: + + unregister_netdevice: waiting for ax0 to become free. Usage count = 0 + +This patch corrects these issues by ensuring that we call netdev_hold() +and ax25_dev_hold() for new connections in ax25_accept(). This makes the +logic leading to ax25_accept() match the logic for ax25_bind(): in both +cases we increment the refcount, which is ultimately decremented in +ax25_release(). + +Fixes: 9fd75b66b8f6 ("ax25: Fix refcount leaks caused by ax25_cb_del()") +Signed-off-by: Lars Kellogg-Stedman +Tested-by: Duoming Zhou +Tested-by: Dan Cross +Tested-by: Chris Maness +Reviewed-by: Dan Carpenter +Link: https://lore.kernel.org/r/20240529210242.3346844-2-lars@oddbit.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ax25/af_ax25.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c +index 0bffac238b615..a1e0be8716870 100644 +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -1378,8 +1378,10 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags, + { + struct sk_buff *skb; + struct sock *newsk; ++ ax25_dev *ax25_dev; + DEFINE_WAIT(wait); + struct sock *sk; ++ ax25_cb *ax25; + int err = 0; + + if (sock->state != SS_UNCONNECTED) +@@ -1434,6 +1436,10 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags, + kfree_skb(skb); + sk_acceptq_removed(sk); + newsock->state = SS_CONNECTED; ++ ax25 = sk_to_ax25(newsk); ++ ax25_dev = ax25->ax25_dev; ++ netdev_hold(ax25_dev->dev, &ax25->dev_tracker, GFP_ATOMIC); ++ ax25_dev_hold(ax25_dev); + + out: + release_sock(sk); +-- +2.43.0 + diff --git a/queue-6.1/ax25-replace-kfree-in-ax25_dev_free-with-ax25_dev_pu.patch b/queue-6.1/ax25-replace-kfree-in-ax25_dev_free-with-ax25_dev_pu.patch new file mode 100644 index 00000000000..0df69b84ced --- /dev/null +++ b/queue-6.1/ax25-replace-kfree-in-ax25_dev_free-with-ax25_dev_pu.patch @@ -0,0 +1,39 @@ +From 6c159eb0d74e4c83143ff18406925630193da6ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 May 2024 13:17:33 +0800 +Subject: ax25: Replace kfree() in ax25_dev_free() with ax25_dev_put() + +From: Duoming Zhou + +[ Upstream commit 166fcf86cd34e15c7f383eda4642d7a212393008 ] + +The object "ax25_dev" is managed by reference counting. Thus it should +not be directly released by kfree(), replace with ax25_dev_put(). + +Fixes: d01ffb9eee4a ("ax25: add refcount in ax25_dev to avoid UAF bugs") +Suggested-by: Dan Carpenter +Signed-off-by: Duoming Zhou +Reviewed-by: Dan Carpenter +Link: https://lore.kernel.org/r/20240530051733.11416-1-duoming@zju.edu.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ax25/ax25_dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c +index fcc64645bbf5e..e165fe108bb00 100644 +--- a/net/ax25/ax25_dev.c ++++ b/net/ax25/ax25_dev.c +@@ -193,7 +193,7 @@ void __exit ax25_dev_free(void) + list_for_each_entry_safe(s, n, &ax25_dev_list, list) { + netdev_put(s->dev, &s->dev_tracker); + list_del(&s->list); +- kfree(s); ++ ax25_dev_put(s); + } + spin_unlock_bh(&ax25_dev_lock); + } +-- +2.43.0 + diff --git a/queue-6.1/bluetooth-qca-fix-invalid-device-address-check.patch b/queue-6.1/bluetooth-qca-fix-invalid-device-address-check.patch new file mode 100644 index 00000000000..87c3269dd0d --- /dev/null +++ b/queue-6.1/bluetooth-qca-fix-invalid-device-address-check.patch @@ -0,0 +1,123 @@ +From a0a0d71831c568e121bd217082f28d1e3848522e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 11:15:09 +0200 +Subject: Bluetooth: qca: fix invalid device address check + +From: Johan Hovold + +[ Upstream commit 32868e126c78876a8a5ddfcb6ac8cb2fffcf4d27 ] + +Qualcomm Bluetooth controllers may not have been provisioned with a +valid device address and instead end up using the default address +00:00:00:00:5a:ad. + +This was previously believed to be due to lack of persistent storage for +the address but it may also be due to integrators opting to not use the +on-chip OTP memory and instead store the address elsewhere (e.g. in +storage managed by secure world firmware). + +According to Qualcomm, at least WCN6750, WCN6855 and WCN7850 have +on-chip OTP storage for the address. + +As the device type alone cannot be used to determine when the address is +valid, instead read back the address during setup() and only set the +HCI_QUIRK_USE_BDADDR_PROPERTY flag when needed. + +This specifically makes sure that controllers that have been provisioned +with an address do not start as unconfigured. + +Reported-by: Janaki Ramaiah Thota +Link: https://lore.kernel.org/r/124a7d54-5a18-4be7-9a76-a12017f6cce5@quicinc.com/ +Fixes: 5971752de44c ("Bluetooth: hci_qca: Set HCI_QUIRK_USE_BDADDR_PROPERTY for wcn3990") +Fixes: e668eb1e1578 ("Bluetooth: hci_core: Don't stop BT if the BD address missing in dts") +Fixes: 6945795bc81a ("Bluetooth: fix use-bdaddr-property quirk") +Cc: stable@vger.kernel.org # 6.5 +Cc: Matthias Kaehlcke +Signed-off-by: Johan Hovold +Reported-by: Janaki Ramaiah Thota +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btqca.c | 38 +++++++++++++++++++++++++++++++++++++ + drivers/bluetooth/hci_qca.c | 2 -- + 2 files changed, 38 insertions(+), 2 deletions(-) + +diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c +index 2dda94a0875a6..8df2e53dcd63c 100644 +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -15,6 +15,8 @@ + + #define VERSION "0.1" + ++#define QCA_BDADDR_DEFAULT (&(bdaddr_t) {{ 0xad, 0x5a, 0x00, 0x00, 0x00, 0x00 }}) ++ + int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver, + enum qca_btsoc_type soc_type) + { +@@ -682,6 +684,38 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) + } + EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); + ++static int qca_check_bdaddr(struct hci_dev *hdev) ++{ ++ struct hci_rp_read_bd_addr *bda; ++ struct sk_buff *skb; ++ int err; ++ ++ if (bacmp(&hdev->public_addr, BDADDR_ANY)) ++ return 0; ++ ++ skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL, ++ HCI_INIT_TIMEOUT); ++ if (IS_ERR(skb)) { ++ err = PTR_ERR(skb); ++ bt_dev_err(hdev, "Failed to read device address (%d)", err); ++ return err; ++ } ++ ++ if (skb->len != sizeof(*bda)) { ++ bt_dev_err(hdev, "Device address length mismatch"); ++ kfree_skb(skb); ++ return -EIO; ++ } ++ ++ bda = (struct hci_rp_read_bd_addr *)skb->data; ++ if (!bacmp(&bda->bdaddr, QCA_BDADDR_DEFAULT)) ++ set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); ++ ++ kfree_skb(skb); ++ ++ return 0; ++} ++ + static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size, + struct qca_btsoc_version ver, u8 rom_ver, u16 bid) + { +@@ -888,6 +922,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + break; + } + ++ err = qca_check_bdaddr(hdev); ++ if (err) ++ return err; ++ + bt_dev_info(hdev, "QCA setup on UART is completed"); + + return 0; +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index a0e2b5d992695..070014d0fc994 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -1853,8 +1853,6 @@ static int qca_setup(struct hci_uart *hu) + case QCA_WCN6750: + case QCA_WCN6855: + case QCA_WCN7850: +- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); +- + qcadev = serdev_device_get_drvdata(hu->serdev); + if (qcadev->bdaddr_property_broken) + set_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks); +-- +2.43.0 + diff --git a/queue-6.1/bpf-set-run-context-for-rawtp-test_run-callback.patch b/queue-6.1/bpf-set-run-context-for-rawtp-test_run-callback.patch new file mode 100644 index 00000000000..cae931a3c7f --- /dev/null +++ b/queue-6.1/bpf-set-run-context-for-rawtp-test_run-callback.patch @@ -0,0 +1,52 @@ +From 2e56d2a025b73ab10822204bfad600091fbd7cb4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 17:00:24 +0200 +Subject: bpf: Set run context for rawtp test_run callback + +From: Jiri Olsa + +[ Upstream commit d0d1df8ba18abc57f28fb3bc053b2bf319367f2c ] + +syzbot reported crash when rawtp program executed through the +test_run interface calls bpf_get_attach_cookie helper or any +other helper that touches task->bpf_ctx pointer. + +Setting the run context (task->bpf_ctx pointer) for test_run +callback. + +Fixes: 7adfc6c9b315 ("bpf: Add bpf_get_attach_cookie() BPF helper to access bpf_cookie value") +Reported-by: syzbot+3ab78ff125b7979e45f9@syzkaller.appspotmail.com +Signed-off-by: Jiri Olsa +Signed-off-by: Andrii Nakryiko +Signed-off-by: Daniel Borkmann +Closes: https://syzkaller.appspot.com/bug?extid=3ab78ff125b7979e45f9 +Link: https://lore.kernel.org/bpf/20240604150024.359247-1-jolsa@kernel.org +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 6094ef7cffcd2..64be562f0fe32 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -841,10 +841,16 @@ static void + __bpf_prog_test_run_raw_tp(void *data) + { + struct bpf_raw_tp_test_run_info *info = data; ++ struct bpf_trace_run_ctx run_ctx = {}; ++ struct bpf_run_ctx *old_run_ctx; ++ ++ old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); + + rcu_read_lock(); + info->retval = bpf_prog_run(info->prog, info->ctx); + rcu_read_unlock(); ++ ++ bpf_reset_run_ctx(old_run_ctx); + } + + int bpf_prog_test_run_raw_tp(struct bpf_prog *prog, +-- +2.43.0 + diff --git a/queue-6.1/btrfs-fix-leak-of-qgroup-extent-records-after-transa.patch b/queue-6.1/btrfs-fix-leak-of-qgroup-extent-records-after-transa.patch new file mode 100644 index 00000000000..4f12b1cae0a --- /dev/null +++ b/queue-6.1/btrfs-fix-leak-of-qgroup-extent-records-after-transa.patch @@ -0,0 +1,65 @@ +From fdcc77ec3b5213d09a7ece35147c7f1f41302540 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 12:49:08 +0100 +Subject: btrfs: fix leak of qgroup extent records after transaction abort + +From: Filipe Manana + +[ Upstream commit fb33eb2ef0d88e75564983ef057b44c5b7e4fded ] + +Qgroup extent records are created when delayed ref heads are created and +then released after accounting extents at btrfs_qgroup_account_extents(), +called during the transaction commit path. + +If a transaction is aborted we free the qgroup records by calling +btrfs_qgroup_destroy_extent_records() at btrfs_destroy_delayed_refs(), +unless we don't have delayed references. We are incorrectly assuming +that no delayed references means we don't have qgroup extents records. + +We can currently have no delayed references because we ran them all +during a transaction commit and the transaction was aborted after that +due to some error in the commit path. + +So fix this by ensuring we btrfs_qgroup_destroy_extent_records() at +btrfs_destroy_delayed_refs() even if we don't have any delayed references. + +Reported-by: syzbot+0fecc032fa134afd49df@syzkaller.appspotmail.com +Link: https://lore.kernel.org/linux-btrfs/0000000000004e7f980619f91835@google.com/ +Fixes: 81f7eb00ff5b ("btrfs: destroy qgroup extent records on transaction abort") +CC: stable@vger.kernel.org # 6.1+ +Reviewed-by: Josef Bacik +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/disk-io.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 5eac900f5d168..c17232659942d 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4943,18 +4943,10 @@ static void btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, + struct btrfs_fs_info *fs_info) + { + struct rb_node *node; +- struct btrfs_delayed_ref_root *delayed_refs; ++ struct btrfs_delayed_ref_root *delayed_refs = &trans->delayed_refs; + struct btrfs_delayed_ref_node *ref; + +- delayed_refs = &trans->delayed_refs; +- + spin_lock(&delayed_refs->lock); +- if (atomic_read(&delayed_refs->num_entries) == 0) { +- spin_unlock(&delayed_refs->lock); +- btrfs_debug(fs_info, "delayed_refs has NO entry"); +- return; +- } +- + while ((node = rb_first_cached(&delayed_refs->href_root)) != NULL) { + struct btrfs_delayed_ref_head *head; + struct rb_node *n; +-- +2.43.0 + diff --git a/queue-6.1/btrfs-fix-wrong-block_start-calculation-for-btrfs_dr.patch b/queue-6.1/btrfs-fix-wrong-block_start-calculation-for-btrfs_dr.patch new file mode 100644 index 00000000000..8691a2459f7 --- /dev/null +++ b/queue-6.1/btrfs-fix-wrong-block_start-calculation-for-btrfs_dr.patch @@ -0,0 +1,94 @@ +From 8f394f9f4fc10a17e405d4998dae170b3d07cd6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Apr 2024 20:32:34 +0930 +Subject: btrfs: fix wrong block_start calculation for + btrfs_drop_extent_map_range() + +From: Qu Wenruo + +[ Upstream commit fe1c6c7acce10baf9521d6dccc17268d91ee2305 ] + +[BUG] +During my extent_map cleanup/refactor, with extra sanity checks, +extent-map-tests::test_case_7() would not pass the checks. + +The problem is, after btrfs_drop_extent_map_range(), the resulted +extent_map has a @block_start way too large. +Meanwhile my btrfs_file_extent_item based members are returning a +correct @disk_bytenr/@offset combination. + +The extent map layout looks like this: + + 0 16K 32K 48K + | PINNED | | Regular | + +The regular em at [32K, 48K) also has 32K @block_start. + +Then drop range [0, 36K), which should shrink the regular one to be +[36K, 48K). +However the @block_start is incorrect, we expect 32K + 4K, but got 52K. + +[CAUSE] +Inside btrfs_drop_extent_map_range() function, if we hit an extent_map +that covers the target range but is still beyond it, we need to split +that extent map into half: + + |<-- drop range -->| + |<----- existing extent_map --->| + +And if the extent map is not compressed, we need to forward +extent_map::block_start by the difference between the end of drop range +and the extent map start. + +However in that particular case, the difference is calculated using +(start + len - em->start). + +The problem is @start can be modified if the drop range covers any +pinned extent. + +This leads to wrong calculation, and would be caught by my later +extent_map sanity checks, which checks the em::block_start against +btrfs_file_extent_item::disk_bytenr + btrfs_file_extent_item::offset. + +This is a regression caused by commit c962098ca4af ("btrfs: fix +incorrect splitting in btrfs_drop_extent_map_range"), which removed the +@len update for pinned extents. + +[FIX] +Fix it by avoiding using @start completely, and use @end - em->start +instead, which @end is exclusive bytenr number. + +And update the test case to verify the @block_start to prevent such +problem from happening. + +Thankfully this is not going to lead to any data corruption, as IO path +does not utilize btrfs_drop_extent_map_range() with @skip_pinned set. + +So this fix is only here for the sake of consistency/correctness. + +CC: stable@vger.kernel.org # 6.5+ +Fixes: c962098ca4af ("btrfs: fix incorrect splitting in btrfs_drop_extent_map_range") +Reviewed-by: Filipe Manana +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/extent_map.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c +index 56d7580fdc3c4..3518e638374ea 100644 +--- a/fs/btrfs/extent_map.c ++++ b/fs/btrfs/extent_map.c +@@ -867,7 +867,7 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, + split->block_len = em->block_len; + split->orig_start = em->orig_start; + } else { +- const u64 diff = start + len - em->start; ++ const u64 diff = end - em->start; + + split->block_len = split->len; + split->block_start += diff; +-- +2.43.0 + diff --git a/queue-6.1/btrfs-make-btrfs_destroy_delayed_refs-return-void.patch b/queue-6.1/btrfs-make-btrfs_destroy_delayed_refs-return-void.patch new file mode 100644 index 00000000000..95e05c815e3 --- /dev/null +++ b/queue-6.1/btrfs-make-btrfs_destroy_delayed_refs-return-void.patch @@ -0,0 +1,66 @@ +From e80bf27a450dbbd39b2f673bb9d42016de169916 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Jun 2023 12:19:42 +0100 +Subject: btrfs: make btrfs_destroy_delayed_refs() return void + +From: Filipe Manana + +[ Upstream commit 99f09ce309b8307ce8dca209f936e99a7c332214 ] + +btrfs_destroy_delayed_refs() always returns 0 and its single caller does +not check its return value, as it also returns void, and so does the +callers' caller and so on. This is because we are in the transaction abort +path, where we have no way to deal with errors (we are in a critical +situation) and all cleanup of resources works in a best effort fashion. +So make btrfs_destroy_delayed_refs() return void. + +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Stable-dep-of: fb33eb2ef0d8 ("btrfs: fix leak of qgroup extent records after transaction abort") +Signed-off-by: Sasha Levin +--- + fs/btrfs/disk-io.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 0111eda33aa9c..5eac900f5d168 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4939,13 +4939,12 @@ static void btrfs_destroy_all_ordered_extents(struct btrfs_fs_info *fs_info) + btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1); + } + +-static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, +- struct btrfs_fs_info *fs_info) ++static void btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, ++ struct btrfs_fs_info *fs_info) + { + struct rb_node *node; + struct btrfs_delayed_ref_root *delayed_refs; + struct btrfs_delayed_ref_node *ref; +- int ret = 0; + + delayed_refs = &trans->delayed_refs; + +@@ -4953,7 +4952,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, + if (atomic_read(&delayed_refs->num_entries) == 0) { + spin_unlock(&delayed_refs->lock); + btrfs_debug(fs_info, "delayed_refs has NO entry"); +- return ret; ++ return; + } + + while ((node = rb_first_cached(&delayed_refs->href_root)) != NULL) { +@@ -5015,8 +5014,6 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, + btrfs_qgroup_destroy_extent_records(trans); + + spin_unlock(&delayed_refs->lock); +- +- return ret; + } + + static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) +-- +2.43.0 + diff --git a/queue-6.1/btrfs-remove-unnecessary-prototype-declarations-at-d.patch b/queue-6.1/btrfs-remove-unnecessary-prototype-declarations-at-d.patch new file mode 100644 index 00000000000..af817953da8 --- /dev/null +++ b/queue-6.1/btrfs-remove-unnecessary-prototype-declarations-at-d.patch @@ -0,0 +1,45 @@ +From c0f4762e74c4c28ef53ca386cf8ff51b3dcf4602 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 May 2023 16:17:06 +0100 +Subject: btrfs: remove unnecessary prototype declarations at disk-io.c + +From: Filipe Manana + +[ Upstream commit 184533e3618f4d0b382c1ef3de0ce34e849005d7 ] + +We have a few static functions at disk-io.c for which we have a forward +declaration of their prototype, but it's not needed because all those +functions are defined before they are called, so remove them. + +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: fb33eb2ef0d8 ("btrfs: fix leak of qgroup extent records after transaction abort") +Signed-off-by: Sasha Levin +--- + fs/btrfs/disk-io.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 5756edb37c61e..0111eda33aa9c 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -51,15 +51,6 @@ + BTRFS_SUPER_FLAG_METADUMP |\ + BTRFS_SUPER_FLAG_METADUMP_V2) + +-static void btrfs_destroy_ordered_extents(struct btrfs_root *root); +-static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, +- struct btrfs_fs_info *fs_info); +-static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root); +-static int btrfs_destroy_marked_extents(struct btrfs_fs_info *fs_info, +- struct extent_io_tree *dirty_pages, +- int mark); +-static int btrfs_destroy_pinned_extent(struct btrfs_fs_info *fs_info, +- struct extent_io_tree *pinned_extents); + static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info); + static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info); + +-- +2.43.0 + diff --git a/queue-6.1/drm-amd-display-drop-unnecessary-null-checks-in-debu.patch b/queue-6.1/drm-amd-display-drop-unnecessary-null-checks-in-debu.patch new file mode 100644 index 00000000000..a160823af7b --- /dev/null +++ b/queue-6.1/drm-amd-display-drop-unnecessary-null-checks-in-debu.patch @@ -0,0 +1,235 @@ +From 9209ec986d0ce4d4b257a9b133e00a29422c2d29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Dec 2022 20:04:15 +0300 +Subject: drm/amd/display: drop unnecessary NULL checks in debugfs + +From: Alexey Kodanev + +[ Upstream commit f8e12e770e8049917f82387033b3cf44bc43b915 ] + +pipe_ctx pointer cannot be NULL when getting the address of +an element of the pipe_ctx array. Moreover, the MAX_PIPES is +defined as 6, so pipe_ctx is not NULL after the loop either. + +Detected using the static analysis tool - Svace. + +Signed-off-by: Alexey Kodanev +Signed-off-by: Hamza Mahfooz +Signed-off-by: Alex Deucher +Stable-dep-of: 892b41b16f61 ("drm/amd/display: Fix incorrect DSC instance for MST") +Signed-off-by: Sasha Levin +--- + .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 72 +++++-------------- + 1 file changed, 16 insertions(+), 56 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +index ff7dd17ad0763..35ea58fbc1d9d 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +@@ -1369,16 +1369,11 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; +- } +- + dsc = pipe_ctx->stream_res.dsc; + if (dsc) + dsc->funcs->dsc_read_state(dsc, &dsc_state); +@@ -1475,12 +1470,12 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx || !pipe_ctx->stream) ++ if (!pipe_ctx->stream) + goto done; + + // Get CRTC state +@@ -1560,16 +1555,11 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; +- } +- + dsc = pipe_ctx->stream_res.dsc; + if (dsc) + dsc->funcs->dsc_read_state(dsc, &dsc_state); +@@ -1664,12 +1654,12 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx || !pipe_ctx->stream) ++ if (!pipe_ctx->stream) + goto done; + + // Safely get CRTC state +@@ -1749,16 +1739,11 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; +- } +- + dsc = pipe_ctx->stream_res.dsc; + if (dsc) + dsc->funcs->dsc_read_state(dsc, &dsc_state); +@@ -1853,12 +1838,12 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx || !pipe_ctx->stream) ++ if (!pipe_ctx->stream) + goto done; + + // Get CRTC state +@@ -1934,16 +1919,11 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; +- } +- + dsc = pipe_ctx->stream_res.dsc; + if (dsc) + dsc->funcs->dsc_read_state(dsc, &dsc_state); +@@ -2035,12 +2015,12 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx || !pipe_ctx->stream) ++ if (!pipe_ctx->stream) + goto done; + + // Get CRTC state +@@ -2114,16 +2094,11 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; +- } +- + dsc = pipe_ctx->stream_res.dsc; + if (dsc) + dsc->funcs->dsc_read_state(dsc, &dsc_state); +@@ -2175,16 +2150,11 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; +- } +- + dsc = pipe_ctx->stream_res.dsc; + if (dsc) + dsc->funcs->dsc_read_state(dsc, &dsc_state); +@@ -2251,16 +2221,11 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; +- } +- + dsc = pipe_ctx->stream_res.dsc; + if (dsc) + dsc->funcs->dsc_read_state(dsc, &dsc_state); +@@ -2327,16 +2292,11 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && ++ if (pipe_ctx->stream && + pipe_ctx->stream->link == aconnector->dc_link) + break; + } + +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; +- } +- + dsc = pipe_ctx->stream_res.dsc; + if (dsc) + dsc->funcs->dsc_read_state(dsc, &dsc_state); +-- +2.43.0 + diff --git a/queue-6.1/drm-amd-display-fix-incorrect-dsc-instance-for-mst.patch b/queue-6.1/drm-amd-display-fix-incorrect-dsc-instance-for-mst.patch new file mode 100644 index 00000000000..78e1fe9d5b6 --- /dev/null +++ b/queue-6.1/drm-amd-display-fix-incorrect-dsc-instance-for-mst.patch @@ -0,0 +1,166 @@ +From bbe4713d34b8b67d3642caf24c0abb718c18b26c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 14:26:06 -0500 +Subject: drm/amd/display: Fix incorrect DSC instance for MST + +From: Hersen Wu + +[ Upstream commit 892b41b16f6163e6556545835abba668fcab4eea ] + +[Why] DSC debugfs, such as dp_dsc_clock_en_read, +use aconnector->dc_link to find pipe_ctx for display. +Displays connected to MST hub share the same dc_link. +DSC instance is from pipe_ctx. This causes incorrect +DSC instance for display connected to MST hub. + +[How] Add aconnector->sink check to find pipe_ctx. + +CC: stable@vger.kernel.org +Reviewed-by: Aurabindo Pillai +Signed-off-by: Hersen Wu +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 48 ++++++++++++++----- + 1 file changed, 36 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +index 35ea58fbc1d9d..dd34dfcd5af76 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +@@ -1370,7 +1370,9 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -1471,7 +1473,9 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -1556,7 +1560,9 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -1655,7 +1661,9 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -1740,7 +1748,9 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -1839,7 +1849,9 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -1920,7 +1932,9 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -2016,7 +2030,9 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -2095,7 +2111,9 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -2151,7 +2169,9 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -2222,7 +2242,9 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +@@ -2293,7 +2315,9 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf, + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) + break; + } + +-- +2.43.0 + diff --git a/queue-6.1/firmware-qcom_scm-disable-clocks-if-qcom_scm_bw_enab.patch b/queue-6.1/firmware-qcom_scm-disable-clocks-if-qcom_scm_bw_enab.patch new file mode 100644 index 00000000000..b08f3e68cc6 --- /dev/null +++ b/queue-6.1/firmware-qcom_scm-disable-clocks-if-qcom_scm_bw_enab.patch @@ -0,0 +1,98 @@ +From caad6c69cf15bce01232c574ecb10eb38ad45e9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Mar 2024 14:14:53 +0100 +Subject: firmware: qcom_scm: disable clocks if qcom_scm_bw_enable() fails + +From: Gabor Juhos + +[ Upstream commit 0c50b7fcf2773b4853e83fc15aba1a196ba95966 ] + +There are several functions which are calling qcom_scm_bw_enable() +then returns immediately if the call fails and leaves the clocks +enabled. + +Change the code of these functions to disable clocks when the +qcom_scm_bw_enable() call fails. This also fixes a possible dma +buffer leak in the qcom_scm_pas_init_image() function. + +Compile tested only due to lack of hardware with interconnect +support. + +Cc: stable@vger.kernel.org +Fixes: 65b7ebda5028 ("firmware: qcom_scm: Add bw voting support to the SCM interface") +Signed-off-by: Gabor Juhos +Reviewed-by: Mukesh Ojha +Link: https://lore.kernel.org/r/20240304-qcom-scm-disable-clk-v1-1-b36e51577ca1@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/firmware/qcom_scm.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c +index 58f1a86065dc9..619cd6548cf64 100644 +--- a/drivers/firmware/qcom_scm.c ++++ b/drivers/firmware/qcom_scm.c +@@ -495,13 +495,14 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size, + + ret = qcom_scm_bw_enable(); + if (ret) +- return ret; ++ goto disable_clk; + + desc.args[1] = mdata_phys; + + ret = qcom_scm_call(__scm->dev, &desc, &res); +- + qcom_scm_bw_disable(); ++ ++disable_clk: + qcom_scm_clk_disable(); + + out: +@@ -563,10 +564,12 @@ int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size) + + ret = qcom_scm_bw_enable(); + if (ret) +- return ret; ++ goto disable_clk; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + qcom_scm_bw_disable(); ++ ++disable_clk: + qcom_scm_clk_disable(); + + return ret ? : res.result[0]; +@@ -598,10 +601,12 @@ int qcom_scm_pas_auth_and_reset(u32 peripheral) + + ret = qcom_scm_bw_enable(); + if (ret) +- return ret; ++ goto disable_clk; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + qcom_scm_bw_disable(); ++ ++disable_clk: + qcom_scm_clk_disable(); + + return ret ? : res.result[0]; +@@ -632,11 +637,12 @@ int qcom_scm_pas_shutdown(u32 peripheral) + + ret = qcom_scm_bw_enable(); + if (ret) +- return ret; ++ goto disable_clk; + + ret = qcom_scm_call(__scm->dev, &desc, &res); +- + qcom_scm_bw_disable(); ++ ++disable_clk: + qcom_scm_clk_disable(); + + return ret ? : res.result[0]; +-- +2.43.0 + diff --git a/queue-6.1/hid-i2c-hid-elan-add-ili9882t-timing.patch b/queue-6.1/hid-i2c-hid-elan-add-ili9882t-timing.patch new file mode 100644 index 00000000000..bb4a5a3e257 --- /dev/null +++ b/queue-6.1/hid-i2c-hid-elan-add-ili9882t-timing.patch @@ -0,0 +1,140 @@ +From 50f464b906db35c76ab42edd566f179ff35d679e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Aug 2023 15:19:47 +0800 +Subject: HID: i2c-hid: elan: Add ili9882t timing + +From: Cong Yang + +[ Upstream commit f2f43bf15d7aa3286eced18d5199ee579e2c2614 ] + +The ili9882t is a TDDI IC (Touch with Display Driver). The +datasheet specifies there should be 60ms between touch SDA +sleep and panel RESX. Doug's series[1] allows panels and +touchscreens to power on/off together, so we can add the 65 ms +delay in i2c_hid_core_suspend before panel_unprepare. + +Because ili9882t touchscrgeen is a panel follower, and +needs to use vccio-supply instead of vcc33-supply, so set +it NULL to ili9882t_chip_data, then not use vcc33 regulator. + +[1]: https://lore.kernel.org/all/20230727171750.633410-1-dianders@chromium.org + +Reviewed-by: Douglas Anderson +Signed-off-by: Cong Yang +Acked-by: Benjamin Tissoires +Link: https://lore.kernel.org/r/20230802071947.1683318-3-yangcong5@huaqin.corp-partner.google.com +Signed-off-by: Benjamin Tissoires +Stable-dep-of: 0eafc58f2194 ("HID: i2c-hid: elan: fix reset suspend current leakage") +Signed-off-by: Sasha Levin +--- + drivers/hid/i2c-hid/i2c-hid-of-elan.c | 50 ++++++++++++++++++++------- + 1 file changed, 38 insertions(+), 12 deletions(-) + +diff --git a/drivers/hid/i2c-hid/i2c-hid-of-elan.c b/drivers/hid/i2c-hid/i2c-hid-of-elan.c +index 2d991325e734c..35986e8297095 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-of-elan.c ++++ b/drivers/hid/i2c-hid/i2c-hid-of-elan.c +@@ -18,9 +18,11 @@ + #include "i2c-hid.h" + + struct elan_i2c_hid_chip_data { +- unsigned int post_gpio_reset_delay_ms; ++ unsigned int post_gpio_reset_on_delay_ms; ++ unsigned int post_gpio_reset_off_delay_ms; + unsigned int post_power_delay_ms; + u16 hid_descriptor_address; ++ const char *main_supply_name; + }; + + struct i2c_hid_of_elan { +@@ -38,9 +40,11 @@ static int elan_i2c_hid_power_up(struct i2chid_ops *ops) + container_of(ops, struct i2c_hid_of_elan, ops); + int ret; + +- ret = regulator_enable(ihid_elan->vcc33); +- if (ret) +- return ret; ++ if (ihid_elan->vcc33) { ++ ret = regulator_enable(ihid_elan->vcc33); ++ if (ret) ++ return ret; ++ } + + ret = regulator_enable(ihid_elan->vccio); + if (ret) { +@@ -52,8 +56,8 @@ static int elan_i2c_hid_power_up(struct i2chid_ops *ops) + msleep(ihid_elan->chip_data->post_power_delay_ms); + + gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0); +- if (ihid_elan->chip_data->post_gpio_reset_delay_ms) +- msleep(ihid_elan->chip_data->post_gpio_reset_delay_ms); ++ if (ihid_elan->chip_data->post_gpio_reset_on_delay_ms) ++ msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms); + + return 0; + } +@@ -64,8 +68,12 @@ static void elan_i2c_hid_power_down(struct i2chid_ops *ops) + container_of(ops, struct i2c_hid_of_elan, ops); + + gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); ++ if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms) ++ msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms); ++ + regulator_disable(ihid_elan->vccio); +- regulator_disable(ihid_elan->vcc33); ++ if (ihid_elan->vcc33) ++ regulator_disable(ihid_elan->vcc33); + } + + static int i2c_hid_of_elan_probe(struct i2c_client *client, +@@ -90,24 +98,42 @@ static int i2c_hid_of_elan_probe(struct i2c_client *client, + if (IS_ERR(ihid_elan->vccio)) + return PTR_ERR(ihid_elan->vccio); + +- ihid_elan->vcc33 = devm_regulator_get(&client->dev, "vcc33"); +- if (IS_ERR(ihid_elan->vcc33)) +- return PTR_ERR(ihid_elan->vcc33); +- + ihid_elan->chip_data = device_get_match_data(&client->dev); + ++ if (ihid_elan->chip_data->main_supply_name) { ++ ihid_elan->vcc33 = devm_regulator_get(&client->dev, ++ ihid_elan->chip_data->main_supply_name); ++ if (IS_ERR(ihid_elan->vcc33)) ++ return PTR_ERR(ihid_elan->vcc33); ++ } ++ + return i2c_hid_core_probe(client, &ihid_elan->ops, + ihid_elan->chip_data->hid_descriptor_address, 0); + } + + static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = { + .post_power_delay_ms = 1, +- .post_gpio_reset_delay_ms = 300, ++ .post_gpio_reset_on_delay_ms = 300, ++ .hid_descriptor_address = 0x0001, ++ .main_supply_name = "vcc33", ++}; ++ ++static const struct elan_i2c_hid_chip_data ilitek_ili9882t_chip_data = { ++ .post_power_delay_ms = 1, ++ .post_gpio_reset_on_delay_ms = 200, ++ .post_gpio_reset_off_delay_ms = 65, + .hid_descriptor_address = 0x0001, ++ /* ++ * this touchscreen is tightly integrated with the panel and assumes ++ * that the relevant power rails (other than the IO rail) have already ++ * been turned on by the panel driver because we're a panel follower. ++ */ ++ .main_supply_name = NULL, + }; + + static const struct of_device_id elan_i2c_hid_of_match[] = { + { .compatible = "elan,ekth6915", .data = &elan_ekth6915_chip_data }, ++ { .compatible = "ilitek,ili9882t", .data = &ilitek_ili9882t_chip_data }, + { } + }; + MODULE_DEVICE_TABLE(of, elan_i2c_hid_of_match); +-- +2.43.0 + diff --git a/queue-6.1/hid-i2c-hid-elan-fix-reset-suspend-current-leakage.patch b/queue-6.1/hid-i2c-hid-elan-fix-reset-suspend-current-leakage.patch new file mode 100644 index 00000000000..54497a25681 --- /dev/null +++ b/queue-6.1/hid-i2c-hid-elan-fix-reset-suspend-current-leakage.patch @@ -0,0 +1,164 @@ +From 61687ed40104c35f09dcd449ec3fe359244b3a6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 May 2024 16:48:18 +0200 +Subject: HID: i2c-hid: elan: fix reset suspend current leakage + +From: Johan Hovold + +[ Upstream commit 0eafc58f2194dbd01d4be40f99a697681171995b ] + +The Elan eKTH5015M touch controller found on the Lenovo ThinkPad X13s +shares the VCC33 supply with other peripherals that may remain powered +during suspend (e.g. when enabled as wakeup sources). + +The reset line is also wired so that it can be left deasserted when the +supply is off. + +This is important as it avoids holding the controller in reset for +extended periods of time when it remains powered, which can lead to +increased power consumption, and also avoids leaking current through the +X13s reset circuitry during suspend (and after driver unbind). + +Use the new 'no-reset-on-power-off' devicetree property to determine +when reset needs to be asserted on power down. + +Notably this also avoids wasting power on machine variants without a +touchscreen for which the driver would otherwise exit probe with reset +asserted. + +Fixes: bd3cba00dcc6 ("HID: i2c-hid: elan: Add support for Elan eKTH6915 i2c-hid touchscreens") +Cc: # 6.0 +Cc: Douglas Anderson +Tested-by: Steev Klimaszewski +Signed-off-by: Johan Hovold +Reviewed-by: Douglas Anderson +Link: https://lore.kernel.org/r/20240507144821.12275-5-johan+linaro@kernel.org +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/i2c-hid/i2c-hid-of-elan.c | 59 +++++++++++++++++++++------ + 1 file changed, 47 insertions(+), 12 deletions(-) + +diff --git a/drivers/hid/i2c-hid/i2c-hid-of-elan.c b/drivers/hid/i2c-hid/i2c-hid-of-elan.c +index 35986e8297095..8d4deb2def97b 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-of-elan.c ++++ b/drivers/hid/i2c-hid/i2c-hid-of-elan.c +@@ -31,6 +31,7 @@ struct i2c_hid_of_elan { + struct regulator *vcc33; + struct regulator *vccio; + struct gpio_desc *reset_gpio; ++ bool no_reset_on_power_off; + const struct elan_i2c_hid_chip_data *chip_data; + }; + +@@ -40,17 +41,17 @@ static int elan_i2c_hid_power_up(struct i2chid_ops *ops) + container_of(ops, struct i2c_hid_of_elan, ops); + int ret; + ++ gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); ++ + if (ihid_elan->vcc33) { + ret = regulator_enable(ihid_elan->vcc33); + if (ret) +- return ret; ++ goto err_deassert_reset; + } + + ret = regulator_enable(ihid_elan->vccio); +- if (ret) { +- regulator_disable(ihid_elan->vcc33); +- return ret; +- } ++ if (ret) ++ goto err_disable_vcc33; + + if (ihid_elan->chip_data->post_power_delay_ms) + msleep(ihid_elan->chip_data->post_power_delay_ms); +@@ -60,6 +61,15 @@ static int elan_i2c_hid_power_up(struct i2chid_ops *ops) + msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms); + + return 0; ++ ++err_disable_vcc33: ++ if (ihid_elan->vcc33) ++ regulator_disable(ihid_elan->vcc33); ++err_deassert_reset: ++ if (ihid_elan->no_reset_on_power_off) ++ gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0); ++ ++ return ret; + } + + static void elan_i2c_hid_power_down(struct i2chid_ops *ops) +@@ -67,7 +77,14 @@ static void elan_i2c_hid_power_down(struct i2chid_ops *ops) + struct i2c_hid_of_elan *ihid_elan = + container_of(ops, struct i2c_hid_of_elan, ops); + +- gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); ++ /* ++ * Do not assert reset when the hardware allows for it to remain ++ * deasserted regardless of the state of the (shared) power supply to ++ * avoid wasting power when the supply is left on. ++ */ ++ if (!ihid_elan->no_reset_on_power_off) ++ gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); ++ + if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms) + msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms); + +@@ -80,6 +97,7 @@ static int i2c_hid_of_elan_probe(struct i2c_client *client, + const struct i2c_device_id *id) + { + struct i2c_hid_of_elan *ihid_elan; ++ int ret; + + ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL); + if (!ihid_elan) +@@ -94,21 +112,38 @@ static int i2c_hid_of_elan_probe(struct i2c_client *client, + if (IS_ERR(ihid_elan->reset_gpio)) + return PTR_ERR(ihid_elan->reset_gpio); + ++ ihid_elan->no_reset_on_power_off = of_property_read_bool(client->dev.of_node, ++ "no-reset-on-power-off"); ++ + ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio"); +- if (IS_ERR(ihid_elan->vccio)) +- return PTR_ERR(ihid_elan->vccio); ++ if (IS_ERR(ihid_elan->vccio)) { ++ ret = PTR_ERR(ihid_elan->vccio); ++ goto err_deassert_reset; ++ } + + ihid_elan->chip_data = device_get_match_data(&client->dev); + + if (ihid_elan->chip_data->main_supply_name) { + ihid_elan->vcc33 = devm_regulator_get(&client->dev, + ihid_elan->chip_data->main_supply_name); +- if (IS_ERR(ihid_elan->vcc33)) +- return PTR_ERR(ihid_elan->vcc33); ++ if (IS_ERR(ihid_elan->vcc33)) { ++ ret = PTR_ERR(ihid_elan->vcc33); ++ goto err_deassert_reset; ++ } + } + +- return i2c_hid_core_probe(client, &ihid_elan->ops, +- ihid_elan->chip_data->hid_descriptor_address, 0); ++ ret = i2c_hid_core_probe(client, &ihid_elan->ops, ++ ihid_elan->chip_data->hid_descriptor_address, 0); ++ if (ret) ++ goto err_deassert_reset; ++ ++ return 0; ++ ++err_deassert_reset: ++ if (ihid_elan->no_reset_on_power_off) ++ gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0); ++ ++ return ret; + } + + static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = { +-- +2.43.0 + diff --git a/queue-6.1/i2c-acpi-unbind-mux-adapters-before-delete.patch b/queue-6.1/i2c-acpi-unbind-mux-adapters-before-delete.patch new file mode 100644 index 00000000000..5764a138dd3 --- /dev/null +++ b/queue-6.1/i2c-acpi-unbind-mux-adapters-before-delete.patch @@ -0,0 +1,158 @@ +From 3cb90892db4b0a079d6513c3c689fe8ffe202c27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Mar 2024 11:16:32 +1300 +Subject: i2c: acpi: Unbind mux adapters before delete + +From: Hamish Martin + +[ Upstream commit 3f858bbf04dbac934ac279aaee05d49eb9910051 ] + +There is an issue with ACPI overlay table removal specifically related +to I2C multiplexers. + +Consider an ACPI SSDT Overlay that defines a PCA9548 I2C mux on an +existing I2C bus. When this table is loaded we see the creation of a +device for the overall PCA9548 chip and 8 further devices - one +i2c_adapter each for the mux channels. These are all bound to their +ACPI equivalents via an eventual invocation of acpi_bind_one(). + +When we unload the SSDT overlay we run into the problem. The ACPI +devices are deleted as normal via acpi_device_del_work_fn() and the +acpi_device_del_list. + +However, the following warning and stack trace is output as the +deletion does not go smoothly: +------------[ cut here ]------------ +kernfs: can not remove 'physical_node', no directory +WARNING: CPU: 1 PID: 11 at fs/kernfs/dir.c:1674 kernfs_remove_by_name_ns+0xb9/0xc0 +Modules linked in: +CPU: 1 PID: 11 Comm: kworker/u128:0 Not tainted 6.8.0-rc6+ #1 +Hardware name: congatec AG conga-B7E3/conga-B7E3, BIOS 5.13 05/16/2023 +Workqueue: kacpi_hotplug acpi_device_del_work_fn +RIP: 0010:kernfs_remove_by_name_ns+0xb9/0xc0 +Code: e4 00 48 89 ef e8 07 71 db ff 5b b8 fe ff ff ff 5d 41 5c 41 5d e9 a7 55 e4 00 0f 0b eb a6 48 c7 c7 f0 38 0d 9d e8 97 0a d5 ff <0f> 0b eb dc 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 +RSP: 0018:ffff9f864008fb28 EFLAGS: 00010286 +RAX: 0000000000000000 RBX: ffff8ef90a8d4940 RCX: 0000000000000000 +RDX: ffff8f000e267d10 RSI: ffff8f000e25c780 RDI: ffff8f000e25c780 +RBP: ffff8ef9186f9870 R08: 0000000000013ffb R09: 00000000ffffbfff +R10: 00000000ffffbfff R11: ffff8f000e0a0000 R12: ffff9f864008fb50 +R13: ffff8ef90c93dd60 R14: ffff8ef9010d0958 R15: ffff8ef9186f98c8 +FS: 0000000000000000(0000) GS:ffff8f000e240000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f48f5253a08 CR3: 00000003cb82e000 CR4: 00000000003506f0 +Call Trace: + + ? kernfs_remove_by_name_ns+0xb9/0xc0 + ? __warn+0x7c/0x130 + ? kernfs_remove_by_name_ns+0xb9/0xc0 + ? report_bug+0x171/0x1a0 + ? handle_bug+0x3c/0x70 + ? exc_invalid_op+0x17/0x70 + ? asm_exc_invalid_op+0x1a/0x20 + ? kernfs_remove_by_name_ns+0xb9/0xc0 + ? kernfs_remove_by_name_ns+0xb9/0xc0 + acpi_unbind_one+0x108/0x180 + device_del+0x18b/0x490 + ? srso_return_thunk+0x5/0x5f + ? srso_return_thunk+0x5/0x5f + device_unregister+0xd/0x30 + i2c_del_adapter.part.0+0x1bf/0x250 + i2c_mux_del_adapters+0xa1/0xe0 + i2c_device_remove+0x1e/0x80 + device_release_driver_internal+0x19a/0x200 + bus_remove_device+0xbf/0x100 + device_del+0x157/0x490 + ? __pfx_device_match_fwnode+0x10/0x10 + ? srso_return_thunk+0x5/0x5f + device_unregister+0xd/0x30 + i2c_acpi_notify+0x10f/0x140 + notifier_call_chain+0x58/0xd0 + blocking_notifier_call_chain+0x3a/0x60 + acpi_device_del_work_fn+0x85/0x1d0 + process_one_work+0x134/0x2f0 + worker_thread+0x2f0/0x410 + ? __pfx_worker_thread+0x10/0x10 + kthread+0xe3/0x110 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x2f/0x50 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + +---[ end trace 0000000000000000 ]--- +... +repeated 7 more times, 1 for each channel of the mux +... + +The issue is that the binding of the ACPI devices to their peer I2C +adapters is not correctly cleaned up. Digging deeper into the issue we +see that the deletion order is such that the ACPI devices matching the +mux channel i2c adapters are deleted first during the SSDT overlay +removal. For each of the channels we see a call to i2c_acpi_notify() +with ACPI_RECONFIG_DEVICE_REMOVE but, because these devices are not +actually i2c_clients, nothing is done for them. + +Later on, after each of the mux channels has been dealt with, we come +to delete the i2c_client representing the PCA9548 device. This is the +call stack we see above, whereby the kernel cleans up the i2c_client +including destruction of the mux and its channel adapters. At this +point we do attempt to unbind from the ACPI peers but those peers no +longer exist and so we hit the kernfs errors. + +The fix is to augment i2c_acpi_notify() to handle i2c_adapters. But, +given that the life cycle of the adapters is linked to the i2c_client, +instead of deleting the i2c_adapters during the i2c_acpi_notify(), we +just trigger unbinding of the ACPI device from the adapter device, and +allow the clean up of the adapter to continue in the way it always has. + +Signed-off-by: Hamish Martin +Reviewed-by: Mika Westerberg +Reviewed-by: Andi Shyti +Fixes: 525e6fabeae2 ("i2c / ACPI: add support for ACPI reconfigure notifications") +Cc: # v4.8+ +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/i2c-core-acpi.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index d6037a3286690..14ae0cfc325ef 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -445,6 +445,11 @@ static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) + return i2c_find_device_by_fwnode(acpi_fwnode_handle(adev)); + } + ++static struct i2c_adapter *i2c_acpi_find_adapter_by_adev(struct acpi_device *adev) ++{ ++ return i2c_find_adapter_by_fwnode(acpi_fwnode_handle(adev)); ++} ++ + static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, + void *arg) + { +@@ -471,11 +476,17 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, + break; + + client = i2c_acpi_find_client_by_adev(adev); +- if (!client) +- break; ++ if (client) { ++ i2c_unregister_device(client); ++ put_device(&client->dev); ++ } ++ ++ adapter = i2c_acpi_find_adapter_by_adev(adev); ++ if (adapter) { ++ acpi_unbind_one(&adapter->dev); ++ put_device(&adapter->dev); ++ } + +- i2c_unregister_device(client); +- put_device(&client->dev); + break; + } + +-- +2.43.0 + diff --git a/queue-6.1/i2c-add-fwnode-apis.patch b/queue-6.1/i2c-add-fwnode-apis.patch new file mode 100644 index 00000000000..72c6567a5cc --- /dev/null +++ b/queue-6.1/i2c-add-fwnode-apis.patch @@ -0,0 +1,290 @@ +From a51f8a7ef12d8c6d59f7992f4a7d04acc13177fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jan 2023 10:54:21 +0000 +Subject: i2c: add fwnode APIs + +From: Russell King (Oracle) + +[ Upstream commit 373c612d72461ddaea223592df31e62c934aae61 ] + +Add fwnode APIs for finding and getting I2C adapters, which will be +used by the SFP code. These are passed the fwnode corresponding to +the adapter, and return the I2C adapter. It is the responsibility of +the caller to find the appropriate fwnode. + +We keep the DT and ACPI interfaces, but where appropriate, recode them +to use the fwnode interfaces internally. + +Reviewed-by: Mika Westerberg +Signed-off-by: Russell King (Oracle) +Signed-off-by: Wolfram Sang +Stable-dep-of: 3f858bbf04db ("i2c: acpi: Unbind mux adapters before delete") +Signed-off-by: Sasha Levin +--- + drivers/i2c/i2c-core-acpi.c | 13 +---- + drivers/i2c/i2c-core-base.c | 98 +++++++++++++++++++++++++++++++++++++ + drivers/i2c/i2c-core-of.c | 66 ------------------------- + include/linux/i2c.h | 24 +++++++-- + 4 files changed, 120 insertions(+), 81 deletions(-) + +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index 4dd777cc0c89f..d6037a3286690 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -442,18 +442,7 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle); + + static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) + { +- struct device *dev; +- struct i2c_client *client; +- +- dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); +- if (!dev) +- return NULL; +- +- client = i2c_verify_client(dev); +- if (!client) +- put_device(dev); +- +- return client; ++ return i2c_find_device_by_fwnode(acpi_fwnode_handle(adev)); + } + + static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, +diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c +index 1ebc953799149..8af82f42af30b 100644 +--- a/drivers/i2c/i2c-core-base.c ++++ b/drivers/i2c/i2c-core-base.c +@@ -1017,6 +1017,35 @@ void i2c_unregister_device(struct i2c_client *client) + } + EXPORT_SYMBOL_GPL(i2c_unregister_device); + ++/** ++ * i2c_find_device_by_fwnode() - find an i2c_client for the fwnode ++ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_client ++ * ++ * Look up and return the &struct i2c_client corresponding to the @fwnode. ++ * If no client can be found, or @fwnode is NULL, this returns NULL. ++ * ++ * The user must call put_device(&client->dev) once done with the i2c client. ++ */ ++struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode) ++{ ++ struct i2c_client *client; ++ struct device *dev; ++ ++ if (!fwnode) ++ return NULL; ++ ++ dev = bus_find_device_by_fwnode(&i2c_bus_type, fwnode); ++ if (!dev) ++ return NULL; ++ ++ client = i2c_verify_client(dev); ++ if (!client) ++ put_device(dev); ++ ++ return client; ++} ++EXPORT_SYMBOL(i2c_find_device_by_fwnode); ++ + + static const struct i2c_device_id dummy_id[] = { + { "dummy", 0 }, +@@ -1767,6 +1796,75 @@ int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter) + } + EXPORT_SYMBOL_GPL(devm_i2c_add_adapter); + ++static int i2c_dev_or_parent_fwnode_match(struct device *dev, const void *data) ++{ ++ if (dev_fwnode(dev) == data) ++ return 1; ++ ++ if (dev->parent && dev_fwnode(dev->parent) == data) ++ return 1; ++ ++ return 0; ++} ++ ++/** ++ * i2c_find_adapter_by_fwnode() - find an i2c_adapter for the fwnode ++ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_adapter ++ * ++ * Look up and return the &struct i2c_adapter corresponding to the @fwnode. ++ * If no adapter can be found, or @fwnode is NULL, this returns NULL. ++ * ++ * The user must call put_device(&adapter->dev) once done with the i2c adapter. ++ */ ++struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode) ++{ ++ struct i2c_adapter *adapter; ++ struct device *dev; ++ ++ if (!fwnode) ++ return NULL; ++ ++ dev = bus_find_device(&i2c_bus_type, NULL, fwnode, ++ i2c_dev_or_parent_fwnode_match); ++ if (!dev) ++ return NULL; ++ ++ adapter = i2c_verify_adapter(dev); ++ if (!adapter) ++ put_device(dev); ++ ++ return adapter; ++} ++EXPORT_SYMBOL(i2c_find_adapter_by_fwnode); ++ ++/** ++ * i2c_get_adapter_by_fwnode() - find an i2c_adapter for the fwnode ++ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_adapter ++ * ++ * Look up and return the &struct i2c_adapter corresponding to the @fwnode, ++ * and increment the adapter module's use count. If no adapter can be found, ++ * or @fwnode is NULL, this returns NULL. ++ * ++ * The user must call i2c_put_adapter(adapter) once done with the i2c adapter. ++ * Note that this is different from i2c_find_adapter_by_node(). ++ */ ++struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode) ++{ ++ struct i2c_adapter *adapter; ++ ++ adapter = i2c_find_adapter_by_fwnode(fwnode); ++ if (!adapter) ++ return NULL; ++ ++ if (!try_module_get(adapter->owner)) { ++ put_device(&adapter->dev); ++ adapter = NULL; ++ } ++ ++ return adapter; ++} ++EXPORT_SYMBOL(i2c_get_adapter_by_fwnode); ++ + static void i2c_parse_timing(struct device *dev, char *prop_name, u32 *cur_val_p, + u32 def_val, bool use_def) + { +diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c +index 1073f82d5dd47..545436b7dd535 100644 +--- a/drivers/i2c/i2c-core-of.c ++++ b/drivers/i2c/i2c-core-of.c +@@ -113,72 +113,6 @@ void of_i2c_register_devices(struct i2c_adapter *adap) + of_node_put(bus); + } + +-static int of_dev_or_parent_node_match(struct device *dev, const void *data) +-{ +- if (dev->of_node == data) +- return 1; +- +- if (dev->parent) +- return dev->parent->of_node == data; +- +- return 0; +-} +- +-/* must call put_device() when done with returned i2c_client device */ +-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) +-{ +- struct device *dev; +- struct i2c_client *client; +- +- dev = bus_find_device_by_of_node(&i2c_bus_type, node); +- if (!dev) +- return NULL; +- +- client = i2c_verify_client(dev); +- if (!client) +- put_device(dev); +- +- return client; +-} +-EXPORT_SYMBOL(of_find_i2c_device_by_node); +- +-/* must call put_device() when done with returned i2c_adapter device */ +-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) +-{ +- struct device *dev; +- struct i2c_adapter *adapter; +- +- dev = bus_find_device(&i2c_bus_type, NULL, node, +- of_dev_or_parent_node_match); +- if (!dev) +- return NULL; +- +- adapter = i2c_verify_adapter(dev); +- if (!adapter) +- put_device(dev); +- +- return adapter; +-} +-EXPORT_SYMBOL(of_find_i2c_adapter_by_node); +- +-/* must call i2c_put_adapter() when done with returned i2c_adapter device */ +-struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node) +-{ +- struct i2c_adapter *adapter; +- +- adapter = of_find_i2c_adapter_by_node(node); +- if (!adapter) +- return NULL; +- +- if (!try_module_get(adapter->owner)) { +- put_device(&adapter->dev); +- adapter = NULL; +- } +- +- return adapter; +-} +-EXPORT_SYMBOL(of_get_i2c_adapter_by_node); +- + static const struct of_device_id* + i2c_of_match_device_sysfs(const struct of_device_id *matches, + struct i2c_client *client) +diff --git a/include/linux/i2c.h b/include/linux/i2c.h +index f7c49bbdb8a18..cfc59c3371cb2 100644 +--- a/include/linux/i2c.h ++++ b/include/linux/i2c.h +@@ -964,15 +964,33 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr); + + #endif /* I2C */ + ++/* must call put_device() when done with returned i2c_client device */ ++struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode); ++ ++/* must call put_device() when done with returned i2c_adapter device */ ++struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode); ++ ++/* must call i2c_put_adapter() when done with returned i2c_adapter device */ ++struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode); ++ + #if IS_ENABLED(CONFIG_OF) + /* must call put_device() when done with returned i2c_client device */ +-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); ++static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) ++{ ++ return i2c_find_device_by_fwnode(of_fwnode_handle(node)); ++} + + /* must call put_device() when done with returned i2c_adapter device */ +-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node); ++static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) ++{ ++ return i2c_find_adapter_by_fwnode(of_fwnode_handle(node)); ++} + + /* must call i2c_put_adapter() when done with returned i2c_adapter device */ +-struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node); ++static inline struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node) ++{ ++ return i2c_get_adapter_by_fwnode(of_fwnode_handle(node)); ++} + + const struct of_device_id + *i2c_of_match_device(const struct of_device_id *matches, +-- +2.43.0 + diff --git a/queue-6.1/ice-fix-iteration-of-tlvs-in-preserved-fields-area.patch b/queue-6.1/ice-fix-iteration-of-tlvs-in-preserved-fields-area.patch new file mode 100644 index 00000000000..09c02c7a21b --- /dev/null +++ b/queue-6.1/ice-fix-iteration-of-tlvs-in-preserved-fields-area.patch @@ -0,0 +1,124 @@ +From 7889cda3517cdfc43e011eda6b728b9ee82fb772 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 14:42:30 -0700 +Subject: ice: fix iteration of TLVs in Preserved Fields Area + +From: Jacob Keller + +[ Upstream commit 03e4a092be8ce3de7c1baa7ae14e68b64e3ea644 ] + +The ice_get_pfa_module_tlv() function iterates over the Type-Length-Value +structures in the Preserved Fields Area (PFA) of the NVM. This is used by +the driver to access data such as the Part Board Assembly identifier. + +The function uses simple logic to iterate over the PFA. First, the pointer +to the PFA in the NVM is read. Then the total length of the PFA is read +from the first word. + +A pointer to the first TLV is initialized, and a simple loop iterates over +each TLV. The pointer is moved forward through the NVM until it exceeds the +PFA area. + +The logic seems sound, but it is missing a key detail. The Preserved +Fields Area length includes one additional final word. This is documented +in the device data sheet as a dummy word which contains 0xFFFF. All NVMs +have this extra word. + +If the driver tries to scan for a TLV that is not in the PFA, it will read +past the size of the PFA. It reads and interprets the last dummy word of +the PFA as a TLV with type 0xFFFF. It then reads the word following the PFA +as a length. + +The PFA resides within the Shadow RAM portion of the NVM, which is +relatively small. All of its offsets are within a 16-bit size. The PFA +pointer and TLV pointer are stored by the driver as 16-bit values. + +In almost all cases, the word following the PFA will be such that +interpreting it as a length will result in 16-bit arithmetic overflow. Once +overflowed, the new next_tlv value is now below the maximum offset of the +PFA. Thus, the driver will continue to iterate the data as TLVs. In the +worst case, the driver hits on a sequence of reads which loop back to +reading the same offsets in an endless loop. + +To fix this, we need to correct the loop iteration check to account for +this extra word at the end of the PFA. This alone is sufficient to resolve +the known cases of this issue in the field. However, it is plausible that +an NVM could be misconfigured or have corrupt data which results in the +same kind of overflow. Protect against this by using check_add_overflow +when calculating both the maximum offset of the TLVs, and when calculating +the next_tlv offset at the end of each loop iteration. This ensures that +the driver will not get stuck in an infinite loop when scanning the PFA. + +Fixes: e961b679fb0b ("ice: add board identifier info to devlink .info_get") +Co-developed-by: Paul Greenwalt +Signed-off-by: Paul Greenwalt +Reviewed-by: Przemek Kitszel +Tested-by: Pucha Himasekhar Reddy +Signed-off-by: Jacob Keller +Link: https://lore.kernel.org/r/20240603-net-2024-05-30-intel-net-fixes-v2-1-e3563aa89b0c@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_nvm.c | 28 ++++++++++++++++++------ + 1 file changed, 21 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.c b/drivers/net/ethernet/intel/ice/ice_nvm.c +index c262dc886e6a6..07ef6b1f00884 100644 +--- a/drivers/net/ethernet/intel/ice/ice_nvm.c ++++ b/drivers/net/ethernet/intel/ice/ice_nvm.c +@@ -441,8 +441,7 @@ int + ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len, + u16 module_type) + { +- u16 pfa_len, pfa_ptr; +- u16 next_tlv; ++ u16 pfa_len, pfa_ptr, next_tlv, max_tlv; + int status; + + status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr); +@@ -455,11 +454,23 @@ ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len, + ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n"); + return status; + } ++ ++ /* The Preserved Fields Area contains a sequence of Type-Length-Value ++ * structures which define its contents. The PFA length includes all ++ * of the TLVs, plus the initial length word itself, *and* one final ++ * word at the end after all of the TLVs. ++ */ ++ if (check_add_overflow(pfa_ptr, pfa_len - 1, &max_tlv)) { ++ dev_warn(ice_hw_to_dev(hw), "PFA starts at offset %u. PFA length of %u caused 16-bit arithmetic overflow.\n", ++ pfa_ptr, pfa_len); ++ return -EINVAL; ++ } ++ + /* Starting with first TLV after PFA length, iterate through the list + * of TLVs to find the requested one. + */ + next_tlv = pfa_ptr + 1; +- while (next_tlv < pfa_ptr + pfa_len) { ++ while (next_tlv < max_tlv) { + u16 tlv_sub_module_type; + u16 tlv_len; + +@@ -483,10 +494,13 @@ ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len, + } + return -EINVAL; + } +- /* Check next TLV, i.e. current TLV pointer + length + 2 words +- * (for current TLV's type and length) +- */ +- next_tlv = next_tlv + tlv_len + 2; ++ ++ if (check_add_overflow(next_tlv, 2, &next_tlv) || ++ check_add_overflow(next_tlv, tlv_len, &next_tlv)) { ++ dev_warn(ice_hw_to_dev(hw), "TLV of type %u and length 0x%04x caused 16-bit arithmetic overflow. The PFA starts at 0x%04x and has length of 0x%04x\n", ++ tlv_sub_module_type, tlv_len, pfa_ptr, pfa_len); ++ return -EINVAL; ++ } + } + /* Module does not exist */ + return -ENOENT; +-- +2.43.0 + diff --git a/queue-6.1/ice-introduce-new-parameters-in-ice_sched_node.patch b/queue-6.1/ice-introduce-new-parameters-in-ice_sched_node.patch new file mode 100644 index 00000000000..ef581e00677 --- /dev/null +++ b/queue-6.1/ice-introduce-new-parameters-in-ice_sched_node.patch @@ -0,0 +1,289 @@ +From e0211da7bde028f379e2606877ced32c46073c26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 11:48:20 +0100 +Subject: ice: Introduce new parameters in ice_sched_node + +From: Michal Wilczynski + +[ Upstream commit 16dfa49406bc5e1f4cbb115027cbd719d7e6c930 ] + +To support new devlink-rate API ice_sched_node struct needs to store +a number of additional parameters. This includes tx_max, tx_share, +tx_weight, and tx_priority. + +Add new fields to ice_sched_node struct. Add new functions to configure +the hardware with new parameters. Introduce new xarray to identify +nodes uniquely. + +Signed-off-by: Michal Wilczynski +Signed-off-by: Jakub Kicinski +Stable-dep-of: adbf5a42341f ("ice: remove af_xdp_zc_qps bitmap") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/intel/ice/ice_adminq_cmd.h | 4 +- + drivers/net/ethernet/intel/ice/ice_common.c | 3 + + drivers/net/ethernet/intel/ice/ice_sched.c | 81 +++++++++++++++++-- + drivers/net/ethernet/intel/ice/ice_sched.h | 27 +++++++ + drivers/net/ethernet/intel/ice/ice_type.h | 8 ++ + 5 files changed, 116 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +index fe48164dce1e1..4d53c40a9de27 100644 +--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h ++++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +@@ -848,9 +848,9 @@ struct ice_aqc_txsched_elem { + u8 generic; + #define ICE_AQC_ELEM_GENERIC_MODE_M 0x1 + #define ICE_AQC_ELEM_GENERIC_PRIO_S 0x1 +-#define ICE_AQC_ELEM_GENERIC_PRIO_M (0x7 << ICE_AQC_ELEM_GENERIC_PRIO_S) ++#define ICE_AQC_ELEM_GENERIC_PRIO_M GENMASK(3, 1) + #define ICE_AQC_ELEM_GENERIC_SP_S 0x4 +-#define ICE_AQC_ELEM_GENERIC_SP_M (0x1 << ICE_AQC_ELEM_GENERIC_SP_S) ++#define ICE_AQC_ELEM_GENERIC_SP_M GENMASK(4, 4) + #define ICE_AQC_ELEM_GENERIC_ADJUST_VAL_S 0x5 + #define ICE_AQC_ELEM_GENERIC_ADJUST_VAL_M \ + (0x3 << ICE_AQC_ELEM_GENERIC_ADJUST_VAL_S) +diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c +index 039342a0ed15a..e2e661010176c 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.c ++++ b/drivers/net/ethernet/intel/ice/ice_common.c +@@ -1105,6 +1105,9 @@ int ice_init_hw(struct ice_hw *hw) + + hw->evb_veb = true; + ++ /* init xarray for identifying scheduling nodes uniquely */ ++ xa_init_flags(&hw->port_info->sched_node_ids, XA_FLAGS_ALLOC); ++ + /* Query the allocated resources for Tx scheduler */ + status = ice_sched_query_res_alloc(hw); + if (status) { +diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c +index 2c62c1763ee0d..88e74835d0274 100644 +--- a/drivers/net/ethernet/intel/ice/ice_sched.c ++++ b/drivers/net/ethernet/intel/ice/ice_sched.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright (c) 2018, Intel Corporation. */ + ++#include + #include "ice_sched.h" + + /** +@@ -355,6 +356,9 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node) + /* leaf nodes have no children */ + if (node->children) + devm_kfree(ice_hw_to_dev(hw), node->children); ++ ++ kfree(node->name); ++ xa_erase(&pi->sched_node_ids, node->id); + devm_kfree(ice_hw_to_dev(hw), node); + } + +@@ -875,7 +879,7 @@ void ice_sched_cleanup_all(struct ice_hw *hw) + * + * This function add nodes to HW as well as to SW DB for a given layer + */ +-static int ++int + ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node, + struct ice_sched_node *parent, u8 layer, u16 num_nodes, + u16 *num_nodes_added, u32 *first_node_teid) +@@ -940,6 +944,22 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node, + + new_node->sibling = NULL; + new_node->tc_num = tc_node->tc_num; ++ new_node->tx_weight = ICE_SCHED_DFLT_BW_WT; ++ new_node->tx_share = ICE_SCHED_DFLT_BW; ++ new_node->tx_max = ICE_SCHED_DFLT_BW; ++ new_node->name = kzalloc(SCHED_NODE_NAME_MAX_LEN, GFP_KERNEL); ++ if (!new_node->name) ++ return -ENOMEM; ++ ++ status = xa_alloc(&pi->sched_node_ids, &new_node->id, NULL, XA_LIMIT(0, UINT_MAX), ++ GFP_KERNEL); ++ if (status) { ++ ice_debug(hw, ICE_DBG_SCHED, "xa_alloc failed for sched node status =%d\n", ++ status); ++ break; ++ } ++ ++ snprintf(new_node->name, SCHED_NODE_NAME_MAX_LEN, "node_%u", new_node->id); + + /* add it to previous node sibling pointer */ + /* Note: siblings are not linked across branches */ +@@ -2154,7 +2174,7 @@ ice_sched_get_free_vsi_parent(struct ice_hw *hw, struct ice_sched_node *node, + * This function removes the child from the old parent and adds it to a new + * parent + */ +-static void ++void + ice_sched_update_parent(struct ice_sched_node *new_parent, + struct ice_sched_node *node) + { +@@ -2188,7 +2208,7 @@ ice_sched_update_parent(struct ice_sched_node *new_parent, + * + * This function move the child nodes to a given parent. + */ +-static int ++int + ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent, + u16 num_items, u32 *list) + { +@@ -3562,7 +3582,7 @@ ice_sched_set_eir_srl_excl(struct ice_port_info *pi, + * node's RL profile ID of type CIR, EIR, or SRL, and removes old profile + * ID from local database. The caller needs to hold scheduler lock. + */ +-static int ++int + ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node, + enum ice_rl_type rl_type, u32 bw, u8 layer_num) + { +@@ -3598,6 +3618,57 @@ ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node, + ICE_AQC_RL_PROFILE_TYPE_M, old_id); + } + ++/** ++ * ice_sched_set_node_priority - set node's priority ++ * @pi: port information structure ++ * @node: tree node ++ * @priority: number 0-7 representing priority among siblings ++ * ++ * This function sets priority of a node among it's siblings. ++ */ ++int ++ice_sched_set_node_priority(struct ice_port_info *pi, struct ice_sched_node *node, ++ u16 priority) ++{ ++ struct ice_aqc_txsched_elem_data buf; ++ struct ice_aqc_txsched_elem *data; ++ ++ buf = node->info; ++ data = &buf.data; ++ ++ data->valid_sections |= ICE_AQC_ELEM_VALID_GENERIC; ++ data->generic |= FIELD_PREP(ICE_AQC_ELEM_GENERIC_PRIO_M, priority); ++ ++ return ice_sched_update_elem(pi->hw, node, &buf); ++} ++ ++/** ++ * ice_sched_set_node_weight - set node's weight ++ * @pi: port information structure ++ * @node: tree node ++ * @weight: number 1-200 representing weight for WFQ ++ * ++ * This function sets weight of the node for WFQ algorithm. ++ */ ++int ++ice_sched_set_node_weight(struct ice_port_info *pi, struct ice_sched_node *node, u16 weight) ++{ ++ struct ice_aqc_txsched_elem_data buf; ++ struct ice_aqc_txsched_elem *data; ++ ++ buf = node->info; ++ data = &buf.data; ++ ++ data->valid_sections = ICE_AQC_ELEM_VALID_CIR | ICE_AQC_ELEM_VALID_EIR | ++ ICE_AQC_ELEM_VALID_GENERIC; ++ data->cir_bw.bw_alloc = cpu_to_le16(weight); ++ data->eir_bw.bw_alloc = cpu_to_le16(weight); ++ ++ data->generic |= FIELD_PREP(ICE_AQC_ELEM_GENERIC_SP_M, 0x0); ++ ++ return ice_sched_update_elem(pi->hw, node, &buf); ++} ++ + /** + * ice_sched_set_node_bw_lmt - set node's BW limit + * @pi: port information structure +@@ -3608,7 +3679,7 @@ ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node, + * It updates node's BW limit parameters like BW RL profile ID of type CIR, + * EIR, or SRL. The caller needs to hold scheduler lock. + */ +-static int ++int + ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node, + enum ice_rl_type rl_type, u32 bw) + { +diff --git a/drivers/net/ethernet/intel/ice/ice_sched.h b/drivers/net/ethernet/intel/ice/ice_sched.h +index 4f91577fed56b..920db43ed4fa6 100644 +--- a/drivers/net/ethernet/intel/ice/ice_sched.h ++++ b/drivers/net/ethernet/intel/ice/ice_sched.h +@@ -6,6 +6,8 @@ + + #include "ice_common.h" + ++#define SCHED_NODE_NAME_MAX_LEN 32 ++ + #define ICE_QGRP_LAYER_OFFSET 2 + #define ICE_VSI_LAYER_OFFSET 4 + #define ICE_AGG_LAYER_OFFSET 6 +@@ -69,6 +71,28 @@ int + ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req, + struct ice_aqc_txsched_elem_data *buf, u16 buf_size, + u16 *elems_ret, struct ice_sq_cd *cd); ++ ++int ++ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node, ++ enum ice_rl_type rl_type, u32 bw); ++ ++int ++ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node, ++ enum ice_rl_type rl_type, u32 bw, u8 layer_num); ++ ++int ++ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node, ++ struct ice_sched_node *parent, u8 layer, u16 num_nodes, ++ u16 *num_nodes_added, u32 *first_node_teid); ++ ++int ++ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent, ++ u16 num_items, u32 *list); ++ ++int ice_sched_set_node_priority(struct ice_port_info *pi, struct ice_sched_node *node, ++ u16 priority); ++int ice_sched_set_node_weight(struct ice_port_info *pi, struct ice_sched_node *node, u16 weight); ++ + int ice_sched_init_port(struct ice_port_info *pi); + int ice_sched_query_res_alloc(struct ice_hw *hw); + void ice_sched_get_psm_clk_freq(struct ice_hw *hw); +@@ -82,6 +106,9 @@ ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid); + int + ice_sched_add_node(struct ice_port_info *pi, u8 layer, + struct ice_aqc_txsched_elem_data *info); ++void ++ice_sched_update_parent(struct ice_sched_node *new_parent, ++ struct ice_sched_node *node); + void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node); + struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc); + struct ice_sched_node * +diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h +index e1abfcee96dcd..daf86cf561bc7 100644 +--- a/drivers/net/ethernet/intel/ice/ice_type.h ++++ b/drivers/net/ethernet/intel/ice/ice_type.h +@@ -524,7 +524,14 @@ struct ice_sched_node { + struct ice_sched_node *sibling; /* next sibling in the same layer */ + struct ice_sched_node **children; + struct ice_aqc_txsched_elem_data info; ++ char *name; ++ struct devlink_rate *rate_node; ++ u64 tx_max; ++ u64 tx_share; + u32 agg_id; /* aggregator group ID */ ++ u32 id; ++ u32 tx_priority; ++ u32 tx_weight; + u16 vsi_handle; + u8 in_use; /* suspended or in use */ + u8 tx_sched_layer; /* Logical Layer (1-9) */ +@@ -706,6 +713,7 @@ struct ice_port_info { + /* List contain profile ID(s) and other params per layer */ + struct list_head rl_prof_list[ICE_AQC_TOPO_MAX_LEVEL_NUM]; + struct ice_qos_cfg qos_cfg; ++ struct xarray sched_node_ids; + u8 is_vf:1; + }; + +-- +2.43.0 + diff --git a/queue-6.1/ice-remove-af_xdp_zc_qps-bitmap.patch b/queue-6.1/ice-remove-af_xdp_zc_qps-bitmap.patch new file mode 100644 index 00000000000..2afe1fe179c --- /dev/null +++ b/queue-6.1/ice-remove-af_xdp_zc_qps-bitmap.patch @@ -0,0 +1,170 @@ +From 5fca9a39918e7a263b68b17f9c258a8c90023f2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 14:42:32 -0700 +Subject: ice: remove af_xdp_zc_qps bitmap + +From: Larysa Zaremba + +[ Upstream commit adbf5a42341f6ea038d3626cd4437d9f0ad0b2dd ] + +Referenced commit has introduced a bitmap to distinguish between ZC and +copy-mode AF_XDP queues, because xsk_get_pool_from_qid() does not do this +for us. + +The bitmap would be especially useful when restoring previous state after +rebuild, if only it was not reallocated in the process. This leads to e.g. +xdpsock dying after changing number of queues. + +Instead of preserving the bitmap during the rebuild, remove it completely +and distinguish between ZC and copy-mode queues based on the presence of +a device associated with the pool. + +Fixes: e102db780e1c ("ice: track AF_XDP ZC enabled queues in bitmap") +Reviewed-by: Przemek Kitszel +Signed-off-by: Larysa Zaremba +Reviewed-by: Simon Horman +Tested-by: Chandan Kumar Rout +Signed-off-by: Jacob Keller +Link: https://lore.kernel.org/r/20240603-net-2024-05-30-intel-net-fixes-v2-3-e3563aa89b0c@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice.h | 32 ++++++++++++++++-------- + drivers/net/ethernet/intel/ice/ice_lib.c | 8 ------ + drivers/net/ethernet/intel/ice/ice_xsk.c | 13 +++++----- + 3 files changed, 27 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h +index f2be383d97df5..6d75e5638f665 100644 +--- a/drivers/net/ethernet/intel/ice/ice.h ++++ b/drivers/net/ethernet/intel/ice/ice.h +@@ -388,7 +388,6 @@ struct ice_vsi { + struct ice_tc_cfg tc_cfg; + struct bpf_prog *xdp_prog; + struct ice_tx_ring **xdp_rings; /* XDP ring array */ +- unsigned long *af_xdp_zc_qps; /* tracks AF_XDP ZC enabled qps */ + u16 num_xdp_txq; /* Used XDP queues */ + u8 xdp_mapping_mode; /* ICE_MAP_MODE_[CONTIG|SCATTER] */ + +@@ -688,6 +687,25 @@ static inline void ice_set_ring_xdp(struct ice_tx_ring *ring) + ring->flags |= ICE_TX_FLAGS_RING_XDP; + } + ++/** ++ * ice_get_xp_from_qid - get ZC XSK buffer pool bound to a queue ID ++ * @vsi: pointer to VSI ++ * @qid: index of a queue to look at XSK buff pool presence ++ * ++ * Return: A pointer to xsk_buff_pool structure if there is a buffer pool ++ * attached and configured as zero-copy, NULL otherwise. ++ */ ++static inline struct xsk_buff_pool *ice_get_xp_from_qid(struct ice_vsi *vsi, ++ u16 qid) ++{ ++ struct xsk_buff_pool *pool = xsk_get_pool_from_qid(vsi->netdev, qid); ++ ++ if (!ice_is_xdp_ena_vsi(vsi)) ++ return NULL; ++ ++ return (pool && pool->dev) ? pool : NULL; ++} ++ + /** + * ice_xsk_pool - get XSK buffer pool bound to a ring + * @ring: Rx ring to use +@@ -700,10 +718,7 @@ static inline struct xsk_buff_pool *ice_xsk_pool(struct ice_rx_ring *ring) + struct ice_vsi *vsi = ring->vsi; + u16 qid = ring->q_index; + +- if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps)) +- return NULL; +- +- return xsk_get_pool_from_qid(vsi->netdev, qid); ++ return ice_get_xp_from_qid(vsi, qid); + } + + /** +@@ -728,12 +743,7 @@ static inline void ice_tx_xsk_pool(struct ice_vsi *vsi, u16 qid) + if (!ring) + return; + +- if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps)) { +- ring->xsk_pool = NULL; +- return; +- } +- +- ring->xsk_pool = xsk_get_pool_from_qid(vsi->netdev, qid); ++ ring->xsk_pool = ice_get_xp_from_qid(vsi, qid); + } + + /** +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index cd161c03c5e39..7661e735d0992 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -117,14 +117,8 @@ static int ice_vsi_alloc_arrays(struct ice_vsi *vsi) + if (!vsi->q_vectors) + goto err_vectors; + +- vsi->af_xdp_zc_qps = bitmap_zalloc(max_t(int, vsi->alloc_txq, vsi->alloc_rxq), GFP_KERNEL); +- if (!vsi->af_xdp_zc_qps) +- goto err_zc_qps; +- + return 0; + +-err_zc_qps: +- devm_kfree(dev, vsi->q_vectors); + err_vectors: + devm_kfree(dev, vsi->rxq_map); + err_rxq_map: +@@ -320,8 +314,6 @@ static void ice_vsi_free_arrays(struct ice_vsi *vsi) + + dev = ice_pf_to_dev(pf); + +- bitmap_free(vsi->af_xdp_zc_qps); +- vsi->af_xdp_zc_qps = NULL; + /* free the ring and vector containers */ + devm_kfree(dev, vsi->q_vectors); + vsi->q_vectors = NULL; +diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c +index 48cf24709fe32..b917f271cdac1 100644 +--- a/drivers/net/ethernet/intel/ice/ice_xsk.c ++++ b/drivers/net/ethernet/intel/ice/ice_xsk.c +@@ -281,7 +281,6 @@ static int ice_xsk_pool_disable(struct ice_vsi *vsi, u16 qid) + if (!pool) + return -EINVAL; + +- clear_bit(qid, vsi->af_xdp_zc_qps); + xsk_pool_dma_unmap(pool, ICE_RX_DMA_ATTR); + + return 0; +@@ -312,8 +311,6 @@ ice_xsk_pool_enable(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid) + if (err) + return err; + +- set_bit(qid, vsi->af_xdp_zc_qps); +- + return 0; + } + +@@ -361,11 +358,13 @@ ice_realloc_rx_xdp_bufs(struct ice_rx_ring *rx_ring, bool pool_present) + int ice_realloc_zc_buf(struct ice_vsi *vsi, bool zc) + { + struct ice_rx_ring *rx_ring; +- unsigned long q; ++ uint i; ++ ++ ice_for_each_rxq(vsi, i) { ++ rx_ring = vsi->rx_rings[i]; ++ if (!rx_ring->xsk_pool) ++ continue; + +- for_each_set_bit(q, vsi->af_xdp_zc_qps, +- max_t(int, vsi->alloc_txq, vsi->alloc_rxq)) { +- rx_ring = vsi->rx_rings[q]; + if (ice_realloc_rx_xdp_bufs(rx_ring, zc)) + return -ENOMEM; + } +-- +2.43.0 + diff --git a/queue-6.1/ice-remove-null-checks-before-devm_kfree-calls.patch b/queue-6.1/ice-remove-null-checks-before-devm_kfree-calls.patch new file mode 100644 index 00000000000..39783e19254 --- /dev/null +++ b/queue-6.1/ice-remove-null-checks-before-devm_kfree-calls.patch @@ -0,0 +1,249 @@ +From c908676f50d4457e368abf6f34c9bd3aac6d1bef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 May 2023 14:38:40 +0200 +Subject: ice: remove null checks before devm_kfree() calls + +From: Przemek Kitszel + +[ Upstream commit ad667d626825383b626ad6ed38d6205618abb115 ] + +We all know they are redundant. + +Reviewed-by: Michal Swiatkowski +Reviewed-by: Michal Wilczynski +Reviewed-by: Simon Horman +Signed-off-by: Przemek Kitszel +Tested-by: Arpana Arland (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: adbf5a42341f ("ice: remove af_xdp_zc_qps bitmap") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_common.c | 6 +-- + drivers/net/ethernet/intel/ice/ice_controlq.c | 3 +- + drivers/net/ethernet/intel/ice/ice_flow.c | 23 ++-------- + drivers/net/ethernet/intel/ice/ice_lib.c | 42 +++++++------------ + drivers/net/ethernet/intel/ice/ice_sched.c | 11 ++--- + drivers/net/ethernet/intel/ice/ice_switch.c | 19 +++------ + 6 files changed, 29 insertions(+), 75 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c +index e2e661010176c..419052ebc3ae7 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.c ++++ b/drivers/net/ethernet/intel/ice/ice_common.c +@@ -789,8 +789,7 @@ static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw) + devm_kfree(ice_hw_to_dev(hw), lst_itr); + } + } +- if (recps[i].root_buf) +- devm_kfree(ice_hw_to_dev(hw), recps[i].root_buf); ++ devm_kfree(ice_hw_to_dev(hw), recps[i].root_buf); + } + ice_rm_all_sw_replay_rule_info(hw); + devm_kfree(ice_hw_to_dev(hw), sw->recp_list); +@@ -986,8 +985,7 @@ static int ice_cfg_fw_log(struct ice_hw *hw, bool enable) + } + + out: +- if (data) +- devm_kfree(ice_hw_to_dev(hw), data); ++ devm_kfree(ice_hw_to_dev(hw), data); + + return status; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c +index 6bcfee2959915..f68df8e05b18e 100644 +--- a/drivers/net/ethernet/intel/ice/ice_controlq.c ++++ b/drivers/net/ethernet/intel/ice/ice_controlq.c +@@ -339,8 +339,7 @@ do { \ + } \ + } \ + /* free the buffer info list */ \ +- if ((qi)->ring.cmd_buf) \ +- devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf); \ ++ devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf); \ + /* free DMA head */ \ + devm_kfree(ice_hw_to_dev(hw), (qi)->ring.dma_head); \ + } while (0) +diff --git a/drivers/net/ethernet/intel/ice/ice_flow.c b/drivers/net/ethernet/intel/ice/ice_flow.c +index ef103e47a8dc2..85cca572c22a5 100644 +--- a/drivers/net/ethernet/intel/ice/ice_flow.c ++++ b/drivers/net/ethernet/intel/ice/ice_flow.c +@@ -1303,23 +1303,6 @@ ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id) + return NULL; + } + +-/** +- * ice_dealloc_flow_entry - Deallocate flow entry memory +- * @hw: pointer to the HW struct +- * @entry: flow entry to be removed +- */ +-static void +-ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry) +-{ +- if (!entry) +- return; +- +- if (entry->entry) +- devm_kfree(ice_hw_to_dev(hw), entry->entry); +- +- devm_kfree(ice_hw_to_dev(hw), entry); +-} +- + /** + * ice_flow_rem_entry_sync - Remove a flow entry + * @hw: pointer to the HW struct +@@ -1335,7 +1318,8 @@ ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk, + + list_del(&entry->l_entry); + +- ice_dealloc_flow_entry(hw, entry); ++ devm_kfree(ice_hw_to_dev(hw), entry->entry); ++ devm_kfree(ice_hw_to_dev(hw), entry); + + return 0; + } +@@ -1662,8 +1646,7 @@ ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id, + + out: + if (status && e) { +- if (e->entry) +- devm_kfree(ice_hw_to_dev(hw), e->entry); ++ devm_kfree(ice_hw_to_dev(hw), e->entry); + devm_kfree(ice_hw_to_dev(hw), e); + } + +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index cc6c04a69b285..cd161c03c5e39 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -320,31 +320,19 @@ static void ice_vsi_free_arrays(struct ice_vsi *vsi) + + dev = ice_pf_to_dev(pf); + +- if (vsi->af_xdp_zc_qps) { +- bitmap_free(vsi->af_xdp_zc_qps); +- vsi->af_xdp_zc_qps = NULL; +- } ++ bitmap_free(vsi->af_xdp_zc_qps); ++ vsi->af_xdp_zc_qps = NULL; + /* free the ring and vector containers */ +- if (vsi->q_vectors) { +- devm_kfree(dev, vsi->q_vectors); +- vsi->q_vectors = NULL; +- } +- if (vsi->tx_rings) { +- devm_kfree(dev, vsi->tx_rings); +- vsi->tx_rings = NULL; +- } +- if (vsi->rx_rings) { +- devm_kfree(dev, vsi->rx_rings); +- vsi->rx_rings = NULL; +- } +- if (vsi->txq_map) { +- devm_kfree(dev, vsi->txq_map); +- vsi->txq_map = NULL; +- } +- if (vsi->rxq_map) { +- devm_kfree(dev, vsi->rxq_map); +- vsi->rxq_map = NULL; +- } ++ devm_kfree(dev, vsi->q_vectors); ++ vsi->q_vectors = NULL; ++ devm_kfree(dev, vsi->tx_rings); ++ vsi->tx_rings = NULL; ++ devm_kfree(dev, vsi->rx_rings); ++ vsi->rx_rings = NULL; ++ devm_kfree(dev, vsi->txq_map); ++ vsi->txq_map = NULL; ++ devm_kfree(dev, vsi->rxq_map); ++ vsi->rxq_map = NULL; + } + + /** +@@ -787,10 +775,8 @@ static void ice_rss_clean(struct ice_vsi *vsi) + + dev = ice_pf_to_dev(pf); + +- if (vsi->rss_hkey_user) +- devm_kfree(dev, vsi->rss_hkey_user); +- if (vsi->rss_lut_user) +- devm_kfree(dev, vsi->rss_lut_user); ++ devm_kfree(dev, vsi->rss_hkey_user); ++ devm_kfree(dev, vsi->rss_lut_user); + + ice_vsi_clean_rss_flow_fld(vsi); + /* remove RSS replay list */ +diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c +index 88e74835d0274..849b6c7f0506b 100644 +--- a/drivers/net/ethernet/intel/ice/ice_sched.c ++++ b/drivers/net/ethernet/intel/ice/ice_sched.c +@@ -353,10 +353,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node) + node->sibling; + } + +- /* leaf nodes have no children */ +- if (node->children) +- devm_kfree(ice_hw_to_dev(hw), node->children); +- ++ devm_kfree(ice_hw_to_dev(hw), node->children); + kfree(node->name); + xa_erase(&pi->sched_node_ids, node->id); + devm_kfree(ice_hw_to_dev(hw), node); +@@ -854,10 +851,8 @@ void ice_sched_cleanup_all(struct ice_hw *hw) + if (!hw) + return; + +- if (hw->layer_info) { +- devm_kfree(ice_hw_to_dev(hw), hw->layer_info); +- hw->layer_info = NULL; +- } ++ devm_kfree(ice_hw_to_dev(hw), hw->layer_info); ++ hw->layer_info = NULL; + + ice_sched_clear_port(hw->port_info); + +diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c +index 46b36851af460..5ea6365872571 100644 +--- a/drivers/net/ethernet/intel/ice/ice_switch.c ++++ b/drivers/net/ethernet/intel/ice/ice_switch.c +@@ -1636,21 +1636,16 @@ ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi) + */ + static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle) + { +- struct ice_vsi_ctx *vsi; ++ struct ice_vsi_ctx *vsi = ice_get_vsi_ctx(hw, vsi_handle); + u8 i; + +- vsi = ice_get_vsi_ctx(hw, vsi_handle); + if (!vsi) + return; + ice_for_each_traffic_class(i) { +- if (vsi->lan_q_ctx[i]) { +- devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]); +- vsi->lan_q_ctx[i] = NULL; +- } +- if (vsi->rdma_q_ctx[i]) { +- devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]); +- vsi->rdma_q_ctx[i] = NULL; +- } ++ devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]); ++ vsi->lan_q_ctx[i] = NULL; ++ devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]); ++ vsi->rdma_q_ctx[i] = NULL; + } + } + +@@ -5525,9 +5520,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, + devm_kfree(ice_hw_to_dev(hw), fvit); + } + +- if (rm->root_buf) +- devm_kfree(ice_hw_to_dev(hw), rm->root_buf); +- ++ devm_kfree(ice_hw_to_dev(hw), rm->root_buf); + kfree(rm); + + err_free_lkup_exts: +-- +2.43.0 + diff --git a/queue-6.1/iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch b/queue-6.1/iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch new file mode 100644 index 00000000000..d40a2b57b2e --- /dev/null +++ b/queue-6.1/iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch @@ -0,0 +1,51 @@ +From a32df7fb28bff910a9255de0aef7c789829d83f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 18:39:28 +0200 +Subject: iio: accel: mxc4005: allow module autoloading via OF compatible + +From: Luca Ceresoli + +[ Upstream commit 4d7c16d08d248952c116f2eb9b7b5abc43a19688 ] + +Add OF device table with compatible strings to allow automatic module +loading. + +Signed-off-by: Luca Ceresoli +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20231004-mxc4005-device-tree-support-v1-2-e7c0faea72e4@bootlin.com +Signed-off-by: Jonathan Cameron +Stable-dep-of: 6b8cffdc4a31 ("iio: accel: mxc4005: Reset chip on probe() and resume()") +Signed-off-by: Sasha Levin +--- + drivers/iio/accel/mxc4005.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c +index ffae30e5eb5be..b8dfdb571bf1f 100644 +--- a/drivers/iio/accel/mxc4005.c ++++ b/drivers/iio/accel/mxc4005.c +@@ -487,6 +487,13 @@ static const struct acpi_device_id mxc4005_acpi_match[] = { + }; + MODULE_DEVICE_TABLE(acpi, mxc4005_acpi_match); + ++static const struct of_device_id mxc4005_of_match[] = { ++ { .compatible = "memsic,mxc4005", }, ++ { .compatible = "memsic,mxc6655", }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, mxc4005_of_match); ++ + static const struct i2c_device_id mxc4005_id[] = { + {"mxc4005", 0}, + {"mxc6655", 0}, +@@ -498,6 +505,7 @@ static struct i2c_driver mxc4005_driver = { + .driver = { + .name = MXC4005_DRV_NAME, + .acpi_match_table = ACPI_PTR(mxc4005_acpi_match), ++ .of_match_table = mxc4005_of_match, + }, + .probe = mxc4005_probe, + .id_table = mxc4005_id, +-- +2.43.0 + diff --git a/queue-6.1/iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch b/queue-6.1/iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch new file mode 100644 index 00000000000..b7ffa9dfc9d --- /dev/null +++ b/queue-6.1/iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch @@ -0,0 +1,157 @@ +From 0706dce3ca1c323cc72123bf68302387cce7e0ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Mar 2024 12:37:00 +0100 +Subject: iio: accel: mxc4005: Reset chip on probe() and resume() + +From: Hans de Goede + +[ Upstream commit 6b8cffdc4a31e4a72f75ecd1bc13fbf0dafee390 ] + +On some designs the chip is not properly reset when powered up at boot or +after a suspend/resume cycle. + +Use the sw-reset feature to ensure that the chip is in a clean state +after probe() / resume() and in the case of resume() restore the settings +(scale, trigger-enabled). + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218578 +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20240326113700.56725-3-hdegoede@redhat.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/accel/mxc4005.c | 68 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 68 insertions(+) + +diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c +index b8dfdb571bf1f..0ae544aaff0cc 100644 +--- a/drivers/iio/accel/mxc4005.c ++++ b/drivers/iio/accel/mxc4005.c +@@ -5,6 +5,7 @@ + * Copyright (c) 2014, Intel Corporation. + */ + ++#include + #include + #include + #include +@@ -36,6 +37,7 @@ + + #define MXC4005_REG_INT_CLR1 0x01 + #define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01 ++#define MXC4005_REG_INT_CLR1_SW_RST 0x10 + + #define MXC4005_REG_CONTROL 0x0D + #define MXC4005_REG_CONTROL_MASK_FSR GENMASK(6, 5) +@@ -43,6 +45,9 @@ + + #define MXC4005_REG_DEVICE_ID 0x0E + ++/* Datasheet does not specify a reset time, this is a conservative guess */ ++#define MXC4005_RESET_TIME_US 2000 ++ + enum mxc4005_axis { + AXIS_X, + AXIS_Y, +@@ -66,6 +71,8 @@ struct mxc4005_data { + s64 timestamp __aligned(8); + } scan; + bool trigger_enabled; ++ unsigned int control; ++ unsigned int int_mask1; + }; + + /* +@@ -349,6 +356,7 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig, + return ret; + } + ++ data->int_mask1 = val; + data->trigger_enabled = state; + mutex_unlock(&data->mutex); + +@@ -384,6 +392,13 @@ static int mxc4005_chip_init(struct mxc4005_data *data) + + dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg); + ++ ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1, ++ MXC4005_REG_INT_CLR1_SW_RST); ++ if (ret < 0) ++ return dev_err_probe(data->dev, ret, "resetting chip\n"); ++ ++ fsleep(MXC4005_RESET_TIME_US); ++ + ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0); + if (ret < 0) + return dev_err_probe(data->dev, ret, "writing INT_MASK0\n"); +@@ -480,6 +495,58 @@ static int mxc4005_probe(struct i2c_client *client, + return devm_iio_device_register(&client->dev, indio_dev); + } + ++static int mxc4005_suspend(struct device *dev) ++{ ++ struct iio_dev *indio_dev = dev_get_drvdata(dev); ++ struct mxc4005_data *data = iio_priv(indio_dev); ++ int ret; ++ ++ /* Save control to restore it on resume */ ++ ret = regmap_read(data->regmap, MXC4005_REG_CONTROL, &data->control); ++ if (ret < 0) ++ dev_err(data->dev, "failed to read reg_control\n"); ++ ++ return ret; ++} ++ ++static int mxc4005_resume(struct device *dev) ++{ ++ struct iio_dev *indio_dev = dev_get_drvdata(dev); ++ struct mxc4005_data *data = iio_priv(indio_dev); ++ int ret; ++ ++ ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1, ++ MXC4005_REG_INT_CLR1_SW_RST); ++ if (ret) { ++ dev_err(data->dev, "failed to reset chip: %d\n", ret); ++ return ret; ++ } ++ ++ fsleep(MXC4005_RESET_TIME_US); ++ ++ ret = regmap_write(data->regmap, MXC4005_REG_CONTROL, data->control); ++ if (ret) { ++ dev_err(data->dev, "failed to restore control register\n"); ++ return ret; ++ } ++ ++ ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0); ++ if (ret) { ++ dev_err(data->dev, "failed to restore interrupt 0 mask\n"); ++ return ret; ++ } ++ ++ ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, data->int_mask1); ++ if (ret) { ++ dev_err(data->dev, "failed to restore interrupt 1 mask\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static DEFINE_SIMPLE_DEV_PM_OPS(mxc4005_pm_ops, mxc4005_suspend, mxc4005_resume); ++ + static const struct acpi_device_id mxc4005_acpi_match[] = { + {"MXC4005", 0}, + {"MXC6655", 0}, +@@ -506,6 +573,7 @@ static struct i2c_driver mxc4005_driver = { + .name = MXC4005_DRV_NAME, + .acpi_match_table = ACPI_PTR(mxc4005_acpi_match), + .of_match_table = mxc4005_of_match, ++ .pm = pm_sleep_ptr(&mxc4005_pm_ops), + }, + .probe = mxc4005_probe, + .id_table = mxc4005_id, +-- +2.43.0 + diff --git a/queue-6.1/ipv6-fix-possible-race-in-__fib6_drop_pcpu_from.patch b/queue-6.1/ipv6-fix-possible-race-in-__fib6_drop_pcpu_from.patch new file mode 100644 index 00000000000..eb7dc450cbf --- /dev/null +++ b/queue-6.1/ipv6-fix-possible-race-in-__fib6_drop_pcpu_from.patch @@ -0,0 +1,130 @@ +From 93ff2919f7c20c1e9ab04e08feb0e98c64f21e6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 19:35:49 +0000 +Subject: ipv6: fix possible race in __fib6_drop_pcpu_from() + +From: Eric Dumazet + +[ Upstream commit b01e1c030770ff3b4fe37fc7cc6bca03f594133f ] + +syzbot found a race in __fib6_drop_pcpu_from() [1] + +If compiler reads more than once (*ppcpu_rt), +second read could read NULL, if another cpu clears +the value in rt6_get_pcpu_route(). + +Add a READ_ONCE() to prevent this race. + +Also add rcu_read_lock()/rcu_read_unlock() because +we rely on RCU protection while dereferencing pcpu_rt. + +[1] + +Oops: general protection fault, probably for non-canonical address 0xdffffc0000000012: 0000 [#1] PREEMPT SMP KASAN PTI +KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097] +CPU: 0 PID: 7543 Comm: kworker/u8:17 Not tainted 6.10.0-rc1-syzkaller-00013-g2bfcfd584ff5 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024 +Workqueue: netns cleanup_net + RIP: 0010:__fib6_drop_pcpu_from.part.0+0x10a/0x370 net/ipv6/ip6_fib.c:984 +Code: f8 48 c1 e8 03 80 3c 28 00 0f 85 16 02 00 00 4d 8b 3f 4d 85 ff 74 31 e8 74 a7 fa f7 49 8d bf 90 00 00 00 48 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 1e 02 00 00 49 8b 87 90 00 00 00 48 8b 0c 24 48 +RSP: 0018:ffffc900040df070 EFLAGS: 00010206 +RAX: 0000000000000012 RBX: 0000000000000001 RCX: ffffffff89932e16 +RDX: ffff888049dd1e00 RSI: ffffffff89932d7c RDI: 0000000000000091 +RBP: dffffc0000000000 R08: 0000000000000005 R09: 0000000000000007 +R10: 0000000000000001 R11: 0000000000000006 R12: ffff88807fa080b8 +R13: fffffbfff1a9a07d R14: ffffed100ff41022 R15: 0000000000000001 +FS: 0000000000000000(0000) GS:ffff8880b9200000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000001b32c26000 CR3: 000000005d56e000 CR4: 00000000003526f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + __fib6_drop_pcpu_from net/ipv6/ip6_fib.c:966 [inline] + fib6_drop_pcpu_from net/ipv6/ip6_fib.c:1027 [inline] + fib6_purge_rt+0x7f2/0x9f0 net/ipv6/ip6_fib.c:1038 + fib6_del_route net/ipv6/ip6_fib.c:1998 [inline] + fib6_del+0xa70/0x17b0 net/ipv6/ip6_fib.c:2043 + fib6_clean_node+0x426/0x5b0 net/ipv6/ip6_fib.c:2205 + fib6_walk_continue+0x44f/0x8d0 net/ipv6/ip6_fib.c:2127 + fib6_walk+0x182/0x370 net/ipv6/ip6_fib.c:2175 + fib6_clean_tree+0xd7/0x120 net/ipv6/ip6_fib.c:2255 + __fib6_clean_all+0x100/0x2d0 net/ipv6/ip6_fib.c:2271 + rt6_sync_down_dev net/ipv6/route.c:4906 [inline] + rt6_disable_ip+0x7ed/0xa00 net/ipv6/route.c:4911 + addrconf_ifdown.isra.0+0x117/0x1b40 net/ipv6/addrconf.c:3855 + addrconf_notify+0x223/0x19e0 net/ipv6/addrconf.c:3778 + notifier_call_chain+0xb9/0x410 kernel/notifier.c:93 + call_netdevice_notifiers_info+0xbe/0x140 net/core/dev.c:1992 + call_netdevice_notifiers_extack net/core/dev.c:2030 [inline] + call_netdevice_notifiers net/core/dev.c:2044 [inline] + dev_close_many+0x333/0x6a0 net/core/dev.c:1585 + unregister_netdevice_many_notify+0x46d/0x19f0 net/core/dev.c:11193 + unregister_netdevice_many net/core/dev.c:11276 [inline] + default_device_exit_batch+0x85b/0xae0 net/core/dev.c:11759 + ops_exit_list+0x128/0x180 net/core/net_namespace.c:178 + cleanup_net+0x5b7/0xbf0 net/core/net_namespace.c:640 + process_one_work+0x9fb/0x1b60 kernel/workqueue.c:3231 + process_scheduled_works kernel/workqueue.c:3312 [inline] + worker_thread+0x6c8/0xf70 kernel/workqueue.c:3393 + kthread+0x2c1/0x3a0 kernel/kthread.c:389 + ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 + +Fixes: d52d3997f843 ("ipv6: Create percpu rt6_info") +Signed-off-by: Eric Dumazet +Cc: Martin KaFai Lau +Link: https://lore.kernel.org/r/20240604193549.981839-1-edumazet@google.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 6 +++++- + net/ipv6/route.c | 1 + + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 8213626434b91..1123594ad2be7 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -962,6 +962,7 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh, + if (!fib6_nh->rt6i_pcpu) + return; + ++ rcu_read_lock(); + /* release the reference to this fib entry from + * all of its cached pcpu routes + */ +@@ -970,7 +971,9 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh, + struct rt6_info *pcpu_rt; + + ppcpu_rt = per_cpu_ptr(fib6_nh->rt6i_pcpu, cpu); +- pcpu_rt = *ppcpu_rt; ++ ++ /* Paired with xchg() in rt6_get_pcpu_route() */ ++ pcpu_rt = READ_ONCE(*ppcpu_rt); + + /* only dropping the 'from' reference if the cached route + * is using 'match'. The cached pcpu_rt->from only changes +@@ -984,6 +987,7 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh, + fib6_info_release(from); + } + } ++ rcu_read_unlock(); + } + + struct fib6_nh_pcpu_arg { +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 258e87055836f..627431722f9d6 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1401,6 +1401,7 @@ static struct rt6_info *rt6_get_pcpu_route(const struct fib6_result *res) + struct rt6_info *prev, **p; + + p = this_cpu_ptr(res->nh->rt6i_pcpu); ++ /* Paired with READ_ONCE() in __fib6_drop_pcpu_from() */ + prev = xchg(p, NULL); + if (prev) { + dst_dev_put(&prev->dst); +-- +2.43.0 + diff --git a/queue-6.1/ipv6-ioam-block-bh-from-ioam6_output.patch b/queue-6.1/ipv6-ioam-block-bh-from-ioam6_output.patch new file mode 100644 index 00000000000..f841fbdf6a9 --- /dev/null +++ b/queue-6.1/ipv6-ioam-block-bh-from-ioam6_output.patch @@ -0,0 +1,65 @@ +From 5577ffe3207905a9140ab94c02314b5ff386543e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 May 2024 13:26:32 +0000 +Subject: ipv6: ioam: block BH from ioam6_output() + +From: Eric Dumazet + +[ Upstream commit 2fe40483ec257de2a0d819ef88e3e76c7e261319 ] + +As explained in commit 1378817486d6 ("tipc: block BH +before using dst_cache"), net/core/dst_cache.c +helpers need to be called with BH disabled. + +Disabling preemption in ioam6_output() is not good enough, +because ioam6_output() is called from process context, +lwtunnel_output() only uses rcu_read_lock(). + +We might be interrupted by a softirq, re-enter ioam6_output() +and corrupt dst_cache data structures. + +Fix the race by using local_bh_disable() instead of +preempt_disable(). + +Fixes: 8cb3bf8bff3c ("ipv6: ioam: Add support for the ip6ip6 encapsulation") +Signed-off-by: Eric Dumazet +Cc: Justin Iurman +Acked-by: Paolo Abeni +Link: https://lore.kernel.org/r/20240531132636.2637995-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ioam6_iptunnel.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/ipv6/ioam6_iptunnel.c b/net/ipv6/ioam6_iptunnel.c +index f6f5b83dd954d..a5cfc5b0b206b 100644 +--- a/net/ipv6/ioam6_iptunnel.c ++++ b/net/ipv6/ioam6_iptunnel.c +@@ -351,9 +351,9 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb) + goto drop; + + if (!ipv6_addr_equal(&orig_daddr, &ipv6_hdr(skb)->daddr)) { +- preempt_disable(); ++ local_bh_disable(); + dst = dst_cache_get(&ilwt->cache); +- preempt_enable(); ++ local_bh_enable(); + + if (unlikely(!dst)) { + struct ipv6hdr *hdr = ipv6_hdr(skb); +@@ -373,9 +373,9 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb) + goto drop; + } + +- preempt_disable(); ++ local_bh_disable(); + dst_cache_set_ip6(&ilwt->cache, dst, &fl6.saddr); +- preempt_enable(); ++ local_bh_enable(); + } + + skb_dst_drop(skb); +-- +2.43.0 + diff --git a/queue-6.1/ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch b/queue-6.1/ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch new file mode 100644 index 00000000000..2250983e94b --- /dev/null +++ b/queue-6.1/ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch @@ -0,0 +1,95 @@ +From 68cae30ac6a95129e009b289ad3cafcbe74278c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 May 2024 13:26:34 +0000 +Subject: ipv6: sr: block BH in seg6_output_core() and seg6_input_core() + +From: Eric Dumazet + +[ Upstream commit c0b98ac1cc104f48763cdb27b1e9ac25fd81fc90 ] + +As explained in commit 1378817486d6 ("tipc: block BH +before using dst_cache"), net/core/dst_cache.c +helpers need to be called with BH disabled. + +Disabling preemption in seg6_output_core() is not good enough, +because seg6_output_core() is called from process context, +lwtunnel_output() only uses rcu_read_lock(). + +We might be interrupted by a softirq, re-enter seg6_output_core() +and corrupt dst_cache data structures. + +Fix the race by using local_bh_disable() instead of +preempt_disable(). + +Apply a similar change in seg6_input_core(). + +Fixes: fa79581ea66c ("ipv6: sr: fix several BUGs when preemption is enabled") +Fixes: 6c8702c60b88 ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels") +Signed-off-by: Eric Dumazet +Cc: David Lebrun +Acked-by: Paolo Abeni +Link: https://lore.kernel.org/r/20240531132636.2637995-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/seg6_iptunnel.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c +index 5924407b87b07..ae5299c277bcf 100644 +--- a/net/ipv6/seg6_iptunnel.c ++++ b/net/ipv6/seg6_iptunnel.c +@@ -464,9 +464,8 @@ static int seg6_input_core(struct net *net, struct sock *sk, + + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + +- preempt_disable(); ++ local_bh_disable(); + dst = dst_cache_get(&slwt->cache); +- preempt_enable(); + + skb_dst_drop(skb); + +@@ -474,14 +473,13 @@ static int seg6_input_core(struct net *net, struct sock *sk, + ip6_route_input(skb); + dst = skb_dst(skb); + if (!dst->error) { +- preempt_disable(); + dst_cache_set_ip6(&slwt->cache, dst, + &ipv6_hdr(skb)->saddr); +- preempt_enable(); + } + } else { + skb_dst_set(skb, dst); + } ++ local_bh_enable(); + + err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); + if (unlikely(err)) +@@ -537,9 +535,9 @@ static int seg6_output_core(struct net *net, struct sock *sk, + + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + +- preempt_disable(); ++ local_bh_disable(); + dst = dst_cache_get(&slwt->cache); +- preempt_enable(); ++ local_bh_enable(); + + if (unlikely(!dst)) { + struct ipv6hdr *hdr = ipv6_hdr(skb); +@@ -559,9 +557,9 @@ static int seg6_output_core(struct net *net, struct sock *sk, + goto drop; + } + +- preempt_disable(); ++ local_bh_disable(); + dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); +- preempt_enable(); ++ local_bh_enable(); + } + + skb_dst_drop(skb); +-- +2.43.0 + diff --git a/queue-6.1/kbuild-rust-force-alloc-extern-to-allow-empty-rust-f.patch b/queue-6.1/kbuild-rust-force-alloc-extern-to-allow-empty-rust-f.patch new file mode 100644 index 00000000000..1d5bcc57750 --- /dev/null +++ b/queue-6.1/kbuild-rust-force-alloc-extern-to-allow-empty-rust-f.patch @@ -0,0 +1,72 @@ +From cb22155fdf04820451fcb5386eefe655f9f39941 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Apr 2024 11:06:44 +0200 +Subject: kbuild: rust: force `alloc` extern to allow "empty" Rust files + +From: Miguel Ojeda + +[ Upstream commit ded103c7eb23753f22597afa500a7c1ad34116ba ] + +If one attempts to build an essentially empty file somewhere in the +kernel tree, it leads to a build error because the compiler does not +recognize the `new_uninit` unstable feature: + + error[E0635]: unknown feature `new_uninit` + --> :1:9 + | + 1 | feature(new_uninit) + | ^^^^^^^^^^ + +The reason is that we pass `-Zcrate-attr='feature(new_uninit)'` (together +with `-Zallow-features=new_uninit`) to let non-`rust/` code use that +unstable feature. + +However, the compiler only recognizes the feature if the `alloc` crate +is resolved (the feature is an `alloc` one). `--extern alloc`, which we +pass, is not enough to resolve the crate. + +Introducing a reference like `use alloc;` or `extern crate alloc;` +solves the issue, thus this is not seen in normal files. For instance, +`use`ing the `kernel` prelude introduces such a reference, since `alloc` +is used inside. + +While normal use of the build system is not impacted by this, it can still +be fairly confusing for kernel developers [1], thus use the unstable +`force` option of `--extern` [2] (added in Rust 1.71 [3]) to force the +compiler to resolve `alloc`. + +This new unstable feature is only needed meanwhile we use the other +unstable feature, since then we will not need `-Zcrate-attr`. + +Cc: stable@vger.kernel.org # v6.6+ +Reported-by: Daniel Almeida +Reported-by: Julian Stecklina +Closes: https://rust-for-linux.zulipchat.com/#narrow/stream/288089-General/topic/x/near/424096982 [1] +Fixes: 2f7ab1267dc9 ("Kbuild: add Rust support") +Link: https://github.com/rust-lang/rust/issues/111302 [2] +Link: https://github.com/rust-lang/rust/pull/109421 [3] +Reviewed-by: Alice Ryhl +Reviewed-by: Gary Guo +Link: https://lore.kernel.org/r/20240422090644.525520-1-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Sasha Levin +--- + scripts/Makefile.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/Makefile.build b/scripts/Makefile.build +index 1827bc1db1e98..78f9cf73d96b2 100644 +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -285,7 +285,7 @@ rust_common_cmd = \ + -Zallow-features=$(rust_allowed_features) \ + -Zcrate-attr=no_std \ + -Zcrate-attr='feature($(rust_allowed_features))' \ +- --extern alloc --extern kernel \ ++ -Zunstable-options --extern force:alloc --extern kernel \ + --crate-type rlib -L $(objtree)/rust/ \ + --crate-name $(basename $(notdir $@)) \ + --out-dir $(dir $@) --emit=dep-info=$(depfile) +-- +2.43.0 + diff --git a/queue-6.1/misc-pvpanic-deduplicate-common-code.patch b/queue-6.1/misc-pvpanic-deduplicate-common-code.patch new file mode 100644 index 00000000000..e06a5d07981 --- /dev/null +++ b/queue-6.1/misc-pvpanic-deduplicate-common-code.patch @@ -0,0 +1,328 @@ +From aeec57b2ce6b0bd95572f3f36bb4509c7ee1c74a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 09:18:27 +0200 +Subject: misc/pvpanic: deduplicate common code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit c1426d392aebc51da4944d950d89e483e43f6f14 ] + +pvpanic-mmio.c and pvpanic-pci.c share a lot of code. +Refactor it into pvpanic.c where it doesn't have to be kept in sync +manually and where the core logic can be understood more easily. + +No functional change. + +Signed-off-by: Thomas Weißschuh +Link: https://lore.kernel.org/r/20231011-pvpanic-cleanup-v2-1-4b21d56f779f@weissschuh.net +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: ee59be35d7a8 ("misc/pvpanic-pci: register attributes via pci_driver") +Signed-off-by: Sasha Levin +--- + drivers/misc/pvpanic/pvpanic-mmio.c | 58 +--------------------- + drivers/misc/pvpanic/pvpanic-pci.c | 58 +--------------------- + drivers/misc/pvpanic/pvpanic.c | 76 ++++++++++++++++++++++++++++- + drivers/misc/pvpanic/pvpanic.h | 10 +--- + 4 files changed, 80 insertions(+), 122 deletions(-) + +diff --git a/drivers/misc/pvpanic/pvpanic-mmio.c b/drivers/misc/pvpanic/pvpanic-mmio.c +index eb97167c03fb4..9715798acce3d 100644 +--- a/drivers/misc/pvpanic/pvpanic-mmio.c ++++ b/drivers/misc/pvpanic/pvpanic-mmio.c +@@ -24,52 +24,9 @@ MODULE_AUTHOR("Hu Tao "); + MODULE_DESCRIPTION("pvpanic-mmio device driver"); + MODULE_LICENSE("GPL"); + +-static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%x\n", pi->capability); +-} +-static DEVICE_ATTR_RO(capability); +- +-static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%x\n", pi->events); +-} +- +-static ssize_t events_store(struct device *dev, struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- unsigned int tmp; +- int err; +- +- err = kstrtouint(buf, 16, &tmp); +- if (err) +- return err; +- +- if ((tmp & pi->capability) != tmp) +- return -EINVAL; +- +- pi->events = tmp; +- +- return count; +-} +-static DEVICE_ATTR_RW(events); +- +-static struct attribute *pvpanic_mmio_dev_attrs[] = { +- &dev_attr_capability.attr, +- &dev_attr_events.attr, +- NULL +-}; +-ATTRIBUTE_GROUPS(pvpanic_mmio_dev); +- + static int pvpanic_mmio_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- struct pvpanic_instance *pi; + struct resource *res; + void __iomem *base; + +@@ -92,18 +49,7 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) + return -EINVAL; + } + +- pi = devm_kmalloc(dev, sizeof(*pi), GFP_KERNEL); +- if (!pi) +- return -ENOMEM; +- +- pi->base = base; +- pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; +- +- /* initialize capability by RDPT */ +- pi->capability &= ioread8(base); +- pi->events = pi->capability; +- +- return devm_pvpanic_probe(dev, pi); ++ return devm_pvpanic_probe(dev, base); + } + + static const struct of_device_id pvpanic_mmio_match[] = { +@@ -123,7 +69,7 @@ static struct platform_driver pvpanic_mmio_driver = { + .name = "pvpanic-mmio", + .of_match_table = pvpanic_mmio_match, + .acpi_match_table = pvpanic_device_ids, +- .dev_groups = pvpanic_mmio_dev_groups, ++ .dev_groups = pvpanic_dev_groups, + }, + .probe = pvpanic_mmio_probe, + }; +diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c +index 07eddb5ea30fa..689af4c28c2a9 100644 +--- a/drivers/misc/pvpanic/pvpanic-pci.c ++++ b/drivers/misc/pvpanic/pvpanic-pci.c +@@ -22,51 +22,8 @@ MODULE_AUTHOR("Mihai Carabas "); + MODULE_DESCRIPTION("pvpanic device driver"); + MODULE_LICENSE("GPL"); + +-static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%x\n", pi->capability); +-} +-static DEVICE_ATTR_RO(capability); +- +-static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%x\n", pi->events); +-} +- +-static ssize_t events_store(struct device *dev, struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- unsigned int tmp; +- int err; +- +- err = kstrtouint(buf, 16, &tmp); +- if (err) +- return err; +- +- if ((tmp & pi->capability) != tmp) +- return -EINVAL; +- +- pi->events = tmp; +- +- return count; +-} +-static DEVICE_ATTR_RW(events); +- +-static struct attribute *pvpanic_pci_dev_attrs[] = { +- &dev_attr_capability.attr, +- &dev_attr_events.attr, +- NULL +-}; +-ATTRIBUTE_GROUPS(pvpanic_pci_dev); +- + static int pvpanic_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { +- struct pvpanic_instance *pi; + void __iomem *base; + int ret; + +@@ -78,18 +35,7 @@ static int pvpanic_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e + if (!base) + return -ENOMEM; + +- pi = devm_kmalloc(&pdev->dev, sizeof(*pi), GFP_KERNEL); +- if (!pi) +- return -ENOMEM; +- +- pi->base = base; +- pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; +- +- /* initlize capability by RDPT */ +- pi->capability &= ioread8(base); +- pi->events = pi->capability; +- +- return devm_pvpanic_probe(&pdev->dev, pi); ++ return devm_pvpanic_probe(&pdev->dev, base); + } + + static const struct pci_device_id pvpanic_pci_id_tbl[] = { +@@ -103,7 +49,7 @@ static struct pci_driver pvpanic_pci_driver = { + .id_table = pvpanic_pci_id_tbl, + .probe = pvpanic_pci_probe, + .driver = { +- .dev_groups = pvpanic_pci_dev_groups, ++ .dev_groups = pvpanic_dev_groups, + }, + }; + module_pci_driver(pvpanic_pci_driver); +diff --git a/drivers/misc/pvpanic/pvpanic.c b/drivers/misc/pvpanic/pvpanic.c +index 049a120063489..305b367e0ce34 100644 +--- a/drivers/misc/pvpanic/pvpanic.c ++++ b/drivers/misc/pvpanic/pvpanic.c +@@ -7,6 +7,7 @@ + * Copyright (C) 2021 Oracle. + */ + ++#include + #include + #include + #include +@@ -26,6 +27,13 @@ MODULE_AUTHOR("Mihai Carabas "); + MODULE_DESCRIPTION("pvpanic device driver"); + MODULE_LICENSE("GPL"); + ++struct pvpanic_instance { ++ void __iomem *base; ++ unsigned int capability; ++ unsigned int events; ++ struct list_head list; ++}; ++ + static struct list_head pvpanic_list; + static spinlock_t pvpanic_lock; + +@@ -81,11 +89,75 @@ static void pvpanic_remove(void *param) + spin_unlock(&pvpanic_lock); + } + +-int devm_pvpanic_probe(struct device *dev, struct pvpanic_instance *pi) ++static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct pvpanic_instance *pi = dev_get_drvdata(dev); ++ ++ return sysfs_emit(buf, "%x\n", pi->capability); ++} ++static DEVICE_ATTR_RO(capability); ++ ++static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct pvpanic_instance *pi = dev_get_drvdata(dev); ++ ++ return sysfs_emit(buf, "%x\n", pi->events); ++} ++ ++static ssize_t events_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct pvpanic_instance *pi = dev_get_drvdata(dev); ++ unsigned int tmp; ++ int err; ++ ++ err = kstrtouint(buf, 16, &tmp); ++ if (err) ++ return err; ++ ++ if ((tmp & pi->capability) != tmp) ++ return -EINVAL; ++ ++ pi->events = tmp; ++ ++ return count; ++} ++static DEVICE_ATTR_RW(events); ++ ++static struct attribute *pvpanic_dev_attrs[] = { ++ &dev_attr_capability.attr, ++ &dev_attr_events.attr, ++ NULL ++}; ++ ++static const struct attribute_group pvpanic_dev_group = { ++ .attrs = pvpanic_dev_attrs, ++}; ++ ++const struct attribute_group *pvpanic_dev_groups[] = { ++ &pvpanic_dev_group, ++ NULL ++}; ++EXPORT_SYMBOL_GPL(pvpanic_dev_groups); ++ ++int devm_pvpanic_probe(struct device *dev, void __iomem *base) + { +- if (!pi || !pi->base) ++ struct pvpanic_instance *pi; ++ ++ if (!base) + return -EINVAL; + ++ pi = devm_kmalloc(dev, sizeof(*pi), GFP_KERNEL); ++ if (!pi) ++ return -ENOMEM; ++ ++ pi->base = base; ++ pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; ++ ++ /* initlize capability by RDPT */ ++ pi->capability &= ioread8(base); ++ pi->events = pi->capability; ++ + spin_lock(&pvpanic_lock); + list_add(&pi->list, &pvpanic_list); + spin_unlock(&pvpanic_lock); +diff --git a/drivers/misc/pvpanic/pvpanic.h b/drivers/misc/pvpanic/pvpanic.h +index 4935459517548..46ffb10438adf 100644 +--- a/drivers/misc/pvpanic/pvpanic.h ++++ b/drivers/misc/pvpanic/pvpanic.h +@@ -8,13 +8,7 @@ + #ifndef PVPANIC_H_ + #define PVPANIC_H_ + +-struct pvpanic_instance { +- void __iomem *base; +- unsigned int capability; +- unsigned int events; +- struct list_head list; +-}; +- +-int devm_pvpanic_probe(struct device *dev, struct pvpanic_instance *pi); ++int devm_pvpanic_probe(struct device *dev, void __iomem *base); ++extern const struct attribute_group *pvpanic_dev_groups[]; + + #endif /* PVPANIC_H_ */ +-- +2.43.0 + diff --git a/queue-6.1/misc-pvpanic-pci-register-attributes-via-pci_driver.patch b/queue-6.1/misc-pvpanic-pci-register-attributes-via-pci_driver.patch new file mode 100644 index 00000000000..668409e66c2 --- /dev/null +++ b/queue-6.1/misc-pvpanic-pci-register-attributes-via-pci_driver.patch @@ -0,0 +1,48 @@ +From 36d8732894787a0678cd94e8d1356a496f0e9d16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 23:33:51 +0200 +Subject: misc/pvpanic-pci: register attributes via pci_driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit ee59be35d7a8be7fcaa2d61fb89734ab5c25e4ee ] + +In __pci_register_driver(), the pci core overwrites the dev_groups field of +the embedded struct device_driver with the dev_groups from the outer +struct pci_driver unconditionally. + +Set dev_groups in the pci_driver to make sure it is used. + +This was broken since the introduction of pvpanic-pci. + +Fixes: db3a4f0abefd ("misc/pvpanic: add PCI driver") +Cc: stable@vger.kernel.org +Signed-off-by: Thomas Weißschuh +Fixes: ded13b9cfd59 ("PCI: Add support for dev_groups to struct pci_driver") +Link: https://lore.kernel.org/r/20240411-pvpanic-pci-dev-groups-v1-1-db8cb69f1b09@weissschuh.net +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/misc/pvpanic/pvpanic-pci.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c +index 689af4c28c2a9..2494725dfacfa 100644 +--- a/drivers/misc/pvpanic/pvpanic-pci.c ++++ b/drivers/misc/pvpanic/pvpanic-pci.c +@@ -48,8 +48,6 @@ static struct pci_driver pvpanic_pci_driver = { + .name = "pvpanic-pci", + .id_table = pvpanic_pci_id_tbl, + .probe = pvpanic_pci_probe, +- .driver = { +- .dev_groups = pvpanic_dev_groups, +- }, ++ .dev_groups = pvpanic_dev_groups, + }; + module_pci_driver(pvpanic_pci_driver); +-- +2.43.0 + diff --git a/queue-6.1/mm-vmalloc-fix-high-order-__gfp_nofail-allocations.patch b/queue-6.1/mm-vmalloc-fix-high-order-__gfp_nofail-allocations.patch new file mode 100644 index 00000000000..d992f6dfd54 --- /dev/null +++ b/queue-6.1/mm-vmalloc-fix-high-order-__gfp_nofail-allocations.patch @@ -0,0 +1,114 @@ +From b5075f5154a6f790c7e1cb4cce4ba430e88def0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Mar 2023 09:15:17 +0100 +Subject: mm, vmalloc: fix high order __GFP_NOFAIL allocations + +From: Michal Hocko + +[ Upstream commit e9c3cda4d86e56bf7fe403729f38c4f0f65d3860 ] + +Gao Xiang has reported that the page allocator complains about high order +__GFP_NOFAIL request coming from the vmalloc core: + + __alloc_pages+0x1cb/0x5b0 mm/page_alloc.c:5549 + alloc_pages+0x1aa/0x270 mm/mempolicy.c:2286 + vm_area_alloc_pages mm/vmalloc.c:2989 [inline] + __vmalloc_area_node mm/vmalloc.c:3057 [inline] + __vmalloc_node_range+0x978/0x13c0 mm/vmalloc.c:3227 + kvmalloc_node+0x156/0x1a0 mm/util.c:606 + kvmalloc include/linux/slab.h:737 [inline] + kvmalloc_array include/linux/slab.h:755 [inline] + kvcalloc include/linux/slab.h:760 [inline] + +it seems that I have completely missed high order allocation backing +vmalloc areas case when implementing __GFP_NOFAIL support. This means +that [k]vmalloc at al. can allocate higher order allocations with +__GFP_NOFAIL which can trigger OOM killer for non-costly orders easily or +cause a lot of reclaim/compaction activity if those requests cannot be +satisfied. + +Fix the issue by falling back to zero order allocations for __GFP_NOFAIL +requests if the high order request fails. + +Link: https://lkml.kernel.org/r/ZAXynvdNqcI0f6Us@dhcp22.suse.cz +Fixes: 9376130c390a ("mm/vmalloc: add support for __GFP_NOFAIL") +Reported-by: Gao Xiang + Link: https://lkml.kernel.org/r/20230305053035.1911-1-hsiangkao@linux.alibaba.com +Signed-off-by: Michal Hocko +Reviewed-by: Uladzislau Rezki (Sony) +Acked-by: Vlastimil Babka +Cc: Baoquan He +Cc: Christoph Hellwig +Cc: Mel Gorman +Signed-off-by: Andrew Morton +Stable-dep-of: 8e0545c83d67 ("mm/vmalloc: fix vmalloc which may return null if called with __GFP_NOFAIL") +Signed-off-by: Sasha Levin +--- + mm/vmalloc.c | 28 +++++++++++++++++++++++----- + 1 file changed, 23 insertions(+), 5 deletions(-) + +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index 67a10a04df041..cab30d9497e6b 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -2923,6 +2923,8 @@ vm_area_alloc_pages(gfp_t gfp, int nid, + unsigned int order, unsigned int nr_pages, struct page **pages) + { + unsigned int nr_allocated = 0; ++ gfp_t alloc_gfp = gfp; ++ bool nofail = false; + struct page *page; + int i; + +@@ -2933,6 +2935,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid, + * more permissive. + */ + if (!order) { ++ /* bulk allocator doesn't support nofail req. officially */ + gfp_t bulk_gfp = gfp & ~__GFP_NOFAIL; + + while (nr_allocated < nr_pages) { +@@ -2971,20 +2974,35 @@ vm_area_alloc_pages(gfp_t gfp, int nid, + if (nr != nr_pages_request) + break; + } ++ } else if (gfp & __GFP_NOFAIL) { ++ /* ++ * Higher order nofail allocations are really expensive and ++ * potentially dangerous (pre-mature OOM, disruptive reclaim ++ * and compaction etc. ++ */ ++ alloc_gfp &= ~__GFP_NOFAIL; ++ nofail = true; + } + + /* High-order pages or fallback path if "bulk" fails. */ +- + while (nr_allocated < nr_pages) { + if (fatal_signal_pending(current)) + break; + + if (nid == NUMA_NO_NODE) +- page = alloc_pages(gfp, order); ++ page = alloc_pages(alloc_gfp, order); + else +- page = alloc_pages_node(nid, gfp, order); +- if (unlikely(!page)) +- break; ++ page = alloc_pages_node(nid, alloc_gfp, order); ++ if (unlikely(!page)) { ++ if (!nofail) ++ break; ++ ++ /* fall back to the zero order allocations */ ++ alloc_gfp |= __GFP_NOFAIL; ++ order = 0; ++ continue; ++ } ++ + /* + * Higher order allocations must be able to be treated as + * indepdenent small pages by callers (as they can with +-- +2.43.0 + diff --git a/queue-6.1/mm-vmalloc-fix-vmalloc-which-may-return-null-if-call.patch b/queue-6.1/mm-vmalloc-fix-vmalloc-which-may-return-null-if-call.patch new file mode 100644 index 00000000000..5af70802842 --- /dev/null +++ b/queue-6.1/mm-vmalloc-fix-vmalloc-which-may-return-null-if-call.patch @@ -0,0 +1,115 @@ +From ee807fe1db767f2d6b4336d0c3b41443de7e205f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 May 2024 18:01:31 +0800 +Subject: mm/vmalloc: fix vmalloc which may return null if called with + __GFP_NOFAIL + +From: Hailong.Liu + +[ Upstream commit 8e0545c83d672750632f46e3f9ad95c48c91a0fc ] + +commit a421ef303008 ("mm: allow !GFP_KERNEL allocations for kvmalloc") +includes support for __GFP_NOFAIL, but it presents a conflict with commit +dd544141b9eb ("vmalloc: back off when the current task is OOM-killed"). A +possible scenario is as follows: + +process-a +__vmalloc_node_range(GFP_KERNEL | __GFP_NOFAIL) + __vmalloc_area_node() + vm_area_alloc_pages() + --> oom-killer send SIGKILL to process-a + if (fatal_signal_pending(current)) break; +--> return NULL; + +To fix this, do not check fatal_signal_pending() in vm_area_alloc_pages() +if __GFP_NOFAIL set. + +This issue occurred during OPLUS KASAN TEST. Below is part of the log +-> oom-killer sends signal to process +[65731.222840] [ T1308] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/apps/uid_10198,task=gs.intelligence,pid=32454,uid=10198 + +[65731.259685] [T32454] Call trace: +[65731.259698] [T32454] dump_backtrace+0xf4/0x118 +[65731.259734] [T32454] show_stack+0x18/0x24 +[65731.259756] [T32454] dump_stack_lvl+0x60/0x7c +[65731.259781] [T32454] dump_stack+0x18/0x38 +[65731.259800] [T32454] mrdump_common_die+0x250/0x39c [mrdump] +[65731.259936] [T32454] ipanic_die+0x20/0x34 [mrdump] +[65731.260019] [T32454] atomic_notifier_call_chain+0xb4/0xfc +[65731.260047] [T32454] notify_die+0x114/0x198 +[65731.260073] [T32454] die+0xf4/0x5b4 +[65731.260098] [T32454] die_kernel_fault+0x80/0x98 +[65731.260124] [T32454] __do_kernel_fault+0x160/0x2a8 +[65731.260146] [T32454] do_bad_area+0x68/0x148 +[65731.260174] [T32454] do_mem_abort+0x151c/0x1b34 +[65731.260204] [T32454] el1_abort+0x3c/0x5c +[65731.260227] [T32454] el1h_64_sync_handler+0x54/0x90 +[65731.260248] [T32454] el1h_64_sync+0x68/0x6c + +[65731.260269] [T32454] z_erofs_decompress_queue+0x7f0/0x2258 +--> be->decompressed_pages = kvcalloc(be->nr_pages, sizeof(struct page *), GFP_KERNEL | __GFP_NOFAIL); + kernel panic by NULL pointer dereference. + erofs assume kvmalloc with __GFP_NOFAIL never return NULL. +[65731.260293] [T32454] z_erofs_runqueue+0xf30/0x104c +[65731.260314] [T32454] z_erofs_readahead+0x4f0/0x968 +[65731.260339] [T32454] read_pages+0x170/0xadc +[65731.260364] [T32454] page_cache_ra_unbounded+0x874/0xf30 +[65731.260388] [T32454] page_cache_ra_order+0x24c/0x714 +[65731.260411] [T32454] filemap_fault+0xbf0/0x1a74 +[65731.260437] [T32454] __do_fault+0xd0/0x33c +[65731.260462] [T32454] handle_mm_fault+0xf74/0x3fe0 +[65731.260486] [T32454] do_mem_abort+0x54c/0x1b34 +[65731.260509] [T32454] el0_da+0x44/0x94 +[65731.260531] [T32454] el0t_64_sync_handler+0x98/0xb4 +[65731.260553] [T32454] el0t_64_sync+0x198/0x19c + +Link: https://lkml.kernel.org/r/20240510100131.1865-1-hailong.liu@oppo.com +Fixes: 9376130c390a ("mm/vmalloc: add support for __GFP_NOFAIL") +Signed-off-by: Hailong.Liu +Acked-by: Michal Hocko +Suggested-by: Barry Song <21cnbao@gmail.com> +Reported-by: Oven +Reviewed-by: Barry Song +Reviewed-by: Uladzislau Rezki (Sony) +Cc: Chao Yu +Cc: Christoph Hellwig +Cc: Gao Xiang +Cc: Lorenzo Stoakes +Cc: Michal Hocko +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + mm/vmalloc.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index cab30d9497e6b..c5e30b52844c8 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -2924,7 +2924,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid, + { + unsigned int nr_allocated = 0; + gfp_t alloc_gfp = gfp; +- bool nofail = false; ++ bool nofail = gfp & __GFP_NOFAIL; + struct page *page; + int i; + +@@ -2981,12 +2981,11 @@ vm_area_alloc_pages(gfp_t gfp, int nid, + * and compaction etc. + */ + alloc_gfp &= ~__GFP_NOFAIL; +- nofail = true; + } + + /* High-order pages or fallback path if "bulk" fails. */ + while (nr_allocated < nr_pages) { +- if (fatal_signal_pending(current)) ++ if (!nofail && fatal_signal_pending(current)) + break; + + if (nid == NUMA_NO_NODE) +-- +2.43.0 + diff --git a/queue-6.1/mmc-davinci-don-t-strip-remove-function-when-driver-.patch b/queue-6.1/mmc-davinci-don-t-strip-remove-function-when-driver-.patch new file mode 100644 index 00000000000..f6bdba3effa --- /dev/null +++ b/queue-6.1/mmc-davinci-don-t-strip-remove-function-when-driver-.patch @@ -0,0 +1,59 @@ +From 9137ab8f1965176464c52c3817eca2fc252fca2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Mar 2024 12:40:17 +0100 +Subject: mmc: davinci: Don't strip remove function when driver is builtin +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 55c421b364482b61c4c45313a535e61ed5ae4ea3 ] + +Using __exit for the remove function results in the remove callback being +discarded with CONFIG_MMC_DAVINCI=y. When such a device gets unbound (e.g. +using sysfs or hotplug), the driver is just removed without the cleanup +being performed. This results in resource leaks. Fix it by compiling in the +remove callback unconditionally. + +This also fixes a W=1 modpost warning: + +WARNING: modpost: drivers/mmc/host/davinci_mmc: section mismatch in +reference: davinci_mmcsd_driver+0x10 (section: .data) -> +davinci_mmcsd_remove (section: .exit.text) + +Fixes: b4cff4549b7a ("DaVinci: MMC: MMC/SD controller driver for DaVinci family") +Signed-off-by: Uwe Kleine-König +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240324114017.231936-2-u.kleine-koenig@pengutronix.de +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/davinci_mmc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c +index 7138dfa065bfa..e89a97b415154 100644 +--- a/drivers/mmc/host/davinci_mmc.c ++++ b/drivers/mmc/host/davinci_mmc.c +@@ -1345,7 +1345,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev) + return ret; + } + +-static int __exit davinci_mmcsd_remove(struct platform_device *pdev) ++static int davinci_mmcsd_remove(struct platform_device *pdev) + { + struct mmc_davinci_host *host = platform_get_drvdata(pdev); + +@@ -1402,7 +1402,7 @@ static struct platform_driver davinci_mmcsd_driver = { + .of_match_table = davinci_mmc_dt_ids, + }, + .probe = davinci_mmcsd_probe, +- .remove = __exit_p(davinci_mmcsd_remove), ++ .remove = davinci_mmcsd_remove, + .id_table = davinci_mmc_devtype, + }; + +-- +2.43.0 + diff --git a/queue-6.1/net-mlx5-always-stop-health-timer-during-driver-remo.patch b/queue-6.1/net-mlx5-always-stop-health-timer-during-driver-remo.patch new file mode 100644 index 00000000000..1d2667c447a --- /dev/null +++ b/queue-6.1/net-mlx5-always-stop-health-timer-during-driver-remo.patch @@ -0,0 +1,105 @@ +From d613ac4cf994ade5bc294fc49b0a1050d62c97da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 00:04:43 +0300 +Subject: net/mlx5: Always stop health timer during driver removal + +From: Shay Drory + +[ Upstream commit c8b3f38d2dae0397944814d691a419c451f9906f ] + +Currently, if teardown_hca fails to execute during driver removal, mlx5 +does not stop the health timer. Afterwards, mlx5 continue with driver +teardown. This may lead to a UAF bug, which results in page fault +Oops[1], since the health timer invokes after resources were freed. + +Hence, stop the health monitor even if teardown_hca fails. + +[1] +mlx5_core 0000:18:00.0: E-Switch: Unload vfs: mode(LEGACY), nvfs(0), necvfs(0), active vports(0) +mlx5_core 0000:18:00.0: E-Switch: Disable: mode(LEGACY), nvfs(0), necvfs(0), active vports(0) +mlx5_core 0000:18:00.0: E-Switch: Disable: mode(LEGACY), nvfs(0), necvfs(0), active vports(0) +mlx5_core 0000:18:00.0: E-Switch: cleanup +mlx5_core 0000:18:00.0: wait_func:1155:(pid 1967079): TEARDOWN_HCA(0x103) timeout. Will cause a leak of a command resource +mlx5_core 0000:18:00.0: mlx5_function_close:1288:(pid 1967079): tear_down_hca failed, skip cleanup +BUG: unable to handle page fault for address: ffffa26487064230 +PGD 100c00067 P4D 100c00067 PUD 100e5a067 PMD 105ed7067 PTE 0 +Oops: 0000 [#1] PREEMPT SMP PTI +CPU: 0 PID: 0 Comm: swapper/0 Tainted: G OE ------- --- 6.7.0-68.fc38.x86_64 #1 +Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.02.01.0013.121520200651 12/15/2020 +RIP: 0010:ioread32be+0x34/0x60 +RSP: 0018:ffffa26480003e58 EFLAGS: 00010292 +RAX: ffffa26487064200 RBX: ffff9042d08161a0 RCX: ffff904c108222c0 +RDX: 000000010bbf1b80 RSI: ffffffffc055ddb0 RDI: ffffa26487064230 +RBP: ffff9042d08161a0 R08: 0000000000000022 R09: ffff904c108222e8 +R10: 0000000000000004 R11: 0000000000000441 R12: ffffffffc055ddb0 +R13: ffffa26487064200 R14: ffffa26480003f00 R15: ffff904c108222c0 +FS: 0000000000000000(0000) GS:ffff904c10800000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: ffffa26487064230 CR3: 00000002c4420006 CR4: 00000000007706f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +PKRU: 55555554 +Call Trace: + + ? __die+0x23/0x70 + ? page_fault_oops+0x171/0x4e0 + ? exc_page_fault+0x175/0x180 + ? asm_exc_page_fault+0x26/0x30 + ? __pfx_poll_health+0x10/0x10 [mlx5_core] + ? __pfx_poll_health+0x10/0x10 [mlx5_core] + ? ioread32be+0x34/0x60 + mlx5_health_check_fatal_sensors+0x20/0x100 [mlx5_core] + ? __pfx_poll_health+0x10/0x10 [mlx5_core] + poll_health+0x42/0x230 [mlx5_core] + ? __next_timer_interrupt+0xbc/0x110 + ? __pfx_poll_health+0x10/0x10 [mlx5_core] + call_timer_fn+0x21/0x130 + ? __pfx_poll_health+0x10/0x10 [mlx5_core] + __run_timers+0x222/0x2c0 + run_timer_softirq+0x1d/0x40 + __do_softirq+0xc9/0x2c8 + __irq_exit_rcu+0xa6/0xc0 + sysvec_apic_timer_interrupt+0x72/0x90 + + + asm_sysvec_apic_timer_interrupt+0x1a/0x20 +RIP: 0010:cpuidle_enter_state+0xcc/0x440 + ? cpuidle_enter_state+0xbd/0x440 + cpuidle_enter+0x2d/0x40 + do_idle+0x20d/0x270 + cpu_startup_entry+0x2a/0x30 + rest_init+0xd0/0xd0 + arch_call_rest_init+0xe/0x30 + start_kernel+0x709/0xa90 + x86_64_start_reservations+0x18/0x30 + x86_64_start_kernel+0x96/0xa0 + secondary_startup_64_no_verify+0x18f/0x19b +---[ end trace 0000000000000000 ]--- + +Fixes: 9b98d395b85d ("net/mlx5: Start health poll at earlier stage of driver load") +Signed-off-by: Shay Drory +Reviewed-by: Moshe Shemesh +Signed-off-by: Tariq Toukan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c +index fe0a78c29438b..67849b1c0bb71 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -1254,6 +1254,9 @@ static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot) + + if (!err) + mlx5_function_disable(dev, boot); ++ else ++ mlx5_stop_health_poll(dev, boot); ++ + return err; + } + +-- +2.43.0 + diff --git a/queue-6.1/net-mlx5-fix-tainted-pointer-delete-is-case-of-flow-.patch b/queue-6.1/net-mlx5-fix-tainted-pointer-delete-is-case-of-flow-.patch new file mode 100644 index 00000000000..143ace4b76a --- /dev/null +++ b/queue-6.1/net-mlx5-fix-tainted-pointer-delete-is-case-of-flow-.patch @@ -0,0 +1,51 @@ +From 4279db2da3a37c1c29055134c89bf7edea62fa2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 13:05:52 +0300 +Subject: net/mlx5: Fix tainted pointer delete is case of flow rules creation + fail + +From: Aleksandr Mishin + +[ Upstream commit 229bedbf62b13af5aba6525ad10b62ad38d9ccb5 ] + +In case of flow rule creation fail in mlx5_lag_create_port_sel_table(), +instead of previously created rules, the tainted pointer is deleted +deveral times. +Fix this bug by using correct flow rules pointers. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 352899f384d4 ("net/mlx5: Lag, use buckets in hash mode") +Signed-off-by: Aleksandr Mishin +Reviewed-by: Jacob Keller +Reviewed-by: Tariq Toukan +Link: https://lore.kernel.org/r/20240604100552.25201-1-amishin@t-argos.ru +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c +index 7d9bbb494d95b..005661248c7e9 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c +@@ -88,9 +88,13 @@ static int mlx5_lag_create_port_sel_table(struct mlx5_lag *ldev, + &dest, 1); + if (IS_ERR(lag_definer->rules[idx])) { + err = PTR_ERR(lag_definer->rules[idx]); +- while (i--) +- while (j--) ++ do { ++ while (j--) { ++ idx = i * ldev->buckets + j; + mlx5_del_flow_rules(lag_definer->rules[idx]); ++ } ++ j = ldev->buckets; ++ } while (i--); + goto destroy_fg; + } + } +-- +2.43.0 + diff --git a/queue-6.1/net-mlx5-split-function_setup-to-enable-and-open-fun.patch b/queue-6.1/net-mlx5-split-function_setup-to-enable-and-open-fun.patch new file mode 100644 index 00000000000..ab12ed3f070 --- /dev/null +++ b/queue-6.1/net-mlx5-split-function_setup-to-enable-and-open-fun.patch @@ -0,0 +1,172 @@ +From 331e48f2754450f818f21a4e80f13c1a23b771bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 May 2023 12:08:48 +0300 +Subject: net/mlx5: Split function_setup() to enable and open functions + +From: Shay Drory + +[ Upstream commit 2059cf51f318681a4cdd3eb1a01a2d62b6a9c442 ] + +mlx5_cmd_init_hca() is taking ~0.2 seconds. In case of a user who +desire to disable some of the SF aux devices, and with large scale-1K +SFs for example, this user will waste more than 3 minutes on +mlx5_cmd_init_hca() which isn't needed at this stage. + +Downstream patch will change SFs which are probe over the E-switch, +local SFs, to be probed without any aux dev. In order to support this, +split function_setup() to avoid executing mlx5_cmd_init_hca(). + +Signed-off-by: Shay Drory +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Stable-dep-of: c8b3f38d2dae ("net/mlx5: Always stop health timer during driver removal") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/main.c | 83 +++++++++++++------ + 1 file changed, 58 insertions(+), 25 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c +index 6ab0642e9de78..fe0a78c29438b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -1093,7 +1093,7 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev) + mlx5_devcom_unregister_device(dev->priv.devcom); + } + +-static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot, u64 timeout) ++static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeout) + { + int err; + +@@ -1158,28 +1158,56 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot, u64 timeout + goto reclaim_boot_pages; + } + ++ return 0; ++ ++reclaim_boot_pages: ++ mlx5_reclaim_startup_pages(dev); ++err_disable_hca: ++ mlx5_core_disable_hca(dev, 0); ++stop_health_poll: ++ mlx5_stop_health_poll(dev, boot); ++err_cmd_cleanup: ++ mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); ++ mlx5_cmd_cleanup(dev); ++ ++ return err; ++} ++ ++static void mlx5_function_disable(struct mlx5_core_dev *dev, bool boot) ++{ ++ mlx5_reclaim_startup_pages(dev); ++ mlx5_core_disable_hca(dev, 0); ++ mlx5_stop_health_poll(dev, boot); ++ mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); ++ mlx5_cmd_cleanup(dev); ++} ++ ++static int mlx5_function_open(struct mlx5_core_dev *dev) ++{ ++ int err; ++ + err = set_hca_ctrl(dev); + if (err) { + mlx5_core_err(dev, "set_hca_ctrl failed\n"); +- goto reclaim_boot_pages; ++ return err; + } + + err = set_hca_cap(dev); + if (err) { + mlx5_core_err(dev, "set_hca_cap failed\n"); +- goto reclaim_boot_pages; ++ return err; + } + + err = mlx5_satisfy_startup_pages(dev, 0); + if (err) { + mlx5_core_err(dev, "failed to allocate init pages\n"); +- goto reclaim_boot_pages; ++ return err; + } + + err = mlx5_cmd_init_hca(dev, sw_owner_id); + if (err) { + mlx5_core_err(dev, "init hca failed\n"); +- goto reclaim_boot_pages; ++ return err; + } + + mlx5_set_driver_version(dev); +@@ -1187,26 +1215,13 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot, u64 timeout + err = mlx5_query_hca_caps(dev); + if (err) { + mlx5_core_err(dev, "query hca failed\n"); +- goto reclaim_boot_pages; ++ return err; + } + mlx5_start_health_fw_log_up(dev); +- + return 0; +- +-reclaim_boot_pages: +- mlx5_reclaim_startup_pages(dev); +-err_disable_hca: +- mlx5_core_disable_hca(dev, 0); +-stop_health_poll: +- mlx5_stop_health_poll(dev, boot); +-err_cmd_cleanup: +- mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); +- mlx5_cmd_cleanup(dev); +- +- return err; + } + +-static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot) ++static int mlx5_function_close(struct mlx5_core_dev *dev) + { + int err; + +@@ -1215,15 +1230,33 @@ static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot) + mlx5_core_err(dev, "tear_down_hca failed, skip cleanup\n"); + return err; + } +- mlx5_reclaim_startup_pages(dev); +- mlx5_core_disable_hca(dev, 0); +- mlx5_stop_health_poll(dev, boot); +- mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); +- mlx5_cmd_cleanup(dev); + + return 0; + } + ++static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot, u64 timeout) ++{ ++ int err; ++ ++ err = mlx5_function_enable(dev, boot, timeout); ++ if (err) ++ return err; ++ ++ err = mlx5_function_open(dev); ++ if (err) ++ mlx5_function_disable(dev, boot); ++ return err; ++} ++ ++static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot) ++{ ++ int err = mlx5_function_close(dev); ++ ++ if (!err) ++ mlx5_function_disable(dev, boot); ++ return err; ++} ++ + static int mlx5_load(struct mlx5_core_dev *dev) + { + int err; +-- +2.43.0 + diff --git a/queue-6.1/net-mlx5-stop-waiting-for-pci-if-pci-channel-is-offl.patch b/queue-6.1/net-mlx5-stop-waiting-for-pci-if-pci-channel-is-offl.patch new file mode 100644 index 00000000000..eeac118c3d1 --- /dev/null +++ b/queue-6.1/net-mlx5-stop-waiting-for-pci-if-pci-channel-is-offl.patch @@ -0,0 +1,86 @@ +From 390ee295547fa2c793afa7e15979d8700b2e37f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 00:04:42 +0300 +Subject: net/mlx5: Stop waiting for PCI if pci channel is offline + +From: Moshe Shemesh + +[ Upstream commit 33afbfcc105a572159750f2ebee834a8a70fdd96 ] + +In case pci channel becomes offline the driver should not wait for PCI +reads during health dump and recovery flow. The driver has timeout for +each of these loops trying to read PCI, so it would fail anyway. +However, in case of recovery waiting till timeout may cause the pci +error_detected() callback fail to meet pci_dpc_recovered() wait timeout. + +Fixes: b3bd076f7501 ("net/mlx5: Report devlink health on FW fatal issues") +Signed-off-by: Moshe Shemesh +Reviewed-by: Shay Drori +Signed-off-by: Tariq Toukan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/fw.c | 4 ++++ + drivers/net/ethernet/mellanox/mlx5/core/health.c | 8 ++++++++ + drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c | 4 ++++ + 3 files changed, 16 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c +index f34e758a2f1f6..9e26dda93f8ee 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c +@@ -379,6 +379,10 @@ int mlx5_cmd_fast_teardown_hca(struct mlx5_core_dev *dev) + do { + if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED) + break; ++ if (pci_channel_offline(dev->pdev)) { ++ mlx5_core_err(dev, "PCI channel offline, stop waiting for NIC IFC\n"); ++ return -EACCES; ++ } + + cond_resched(); + } while (!time_after(jiffies, end)); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c +index e9462de771fd3..65483dab90573 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c +@@ -260,6 +260,10 @@ void mlx5_error_sw_reset(struct mlx5_core_dev *dev) + do { + if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED) + break; ++ if (pci_channel_offline(dev->pdev)) { ++ mlx5_core_err(dev, "PCI channel offline, stop waiting for NIC IFC\n"); ++ goto unlock; ++ } + + msleep(20); + } while (!time_after(jiffies, end)); +@@ -329,6 +333,10 @@ int mlx5_health_wait_pci_up(struct mlx5_core_dev *dev) + mlx5_core_warn(dev, "device is being removed, stop waiting for PCI\n"); + return -ENODEV; + } ++ if (pci_channel_offline(dev->pdev)) { ++ mlx5_core_err(dev, "PCI channel offline, stop waiting for PCI\n"); ++ return -EACCES; ++ } + msleep(100); + } + return 0; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c +index 6b774e0c27665..d0b595ba61101 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c +@@ -74,6 +74,10 @@ int mlx5_vsc_gw_lock(struct mlx5_core_dev *dev) + ret = -EBUSY; + goto pci_unlock; + } ++ if (pci_channel_offline(dev->pdev)) { ++ ret = -EACCES; ++ goto pci_unlock; ++ } + + /* Check if semaphore is already locked */ + ret = vsc_read(dev, VSC_SEMAPHORE_OFFSET, &lock_val); +-- +2.43.0 + diff --git a/queue-6.1/net-mlx5-stop-waiting-for-pci-up-if-teardown-was-tri.patch b/queue-6.1/net-mlx5-stop-waiting-for-pci-up-if-teardown-was-tri.patch new file mode 100644 index 00000000000..2e243a2668a --- /dev/null +++ b/queue-6.1/net-mlx5-stop-waiting-for-pci-up-if-teardown-was-tri.patch @@ -0,0 +1,45 @@ +From 048dc9224dee60beeecdaa549fd789c911285dc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Mar 2023 22:42:21 -0700 +Subject: net/mlx5: Stop waiting for PCI up if teardown was triggered + +From: Moshe Shemesh + +[ Upstream commit 8ff38e730c3f5ee717f25365ef8aa4739562d567 ] + +If driver teardown is called while PCI is turned off, there is a race +between health recovery and teardown. If health recovery already started +it will wait 60 sec trying to see if PCI gets back and it can recover, +but actually there is no need to wait anymore once teardown was called. + +Use the MLX5_BREAK_FW_WAIT flag which is set on driver teardown to break +waiting for PCI up. + +Signed-off-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20230314054234.267365-3-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: 33afbfcc105a ("net/mlx5: Stop waiting for PCI if pci channel is offline") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/health.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c +index e42e4ac231c64..e9462de771fd3 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c +@@ -325,6 +325,10 @@ int mlx5_health_wait_pci_up(struct mlx5_core_dev *dev) + while (sensor_pci_not_working(dev)) { + if (time_after(jiffies, end)) + return -ETIMEDOUT; ++ if (test_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state)) { ++ mlx5_core_warn(dev, "device is being removed, stop waiting for PCI\n"); ++ return -ENODEV; ++ } + msleep(100); + } + return 0; +-- +2.43.0 + diff --git a/queue-6.1/net-ncsi-fix-the-multi-thread-manner-of-ncsi-driver.patch b/queue-6.1/net-ncsi-fix-the-multi-thread-manner-of-ncsi-driver.patch new file mode 100644 index 00000000000..ffd3775b5a1 --- /dev/null +++ b/queue-6.1/net-ncsi-fix-the-multi-thread-manner-of-ncsi-driver.patch @@ -0,0 +1,220 @@ +From 7011b030c779fa3fe563be65d8e61f0c41517923 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 14:58:55 +0800 +Subject: net/ncsi: Fix the multi thread manner of NCSI driver + +From: DelphineCCChiu + +[ Upstream commit e85e271dec0270982afed84f70dc37703fcc1d52 ] + +Currently NCSI driver will send several NCSI commands back to back without +waiting the response of previous NCSI command or timeout in some state +when NIC have multi channel. This operation against the single thread +manner defined by NCSI SPEC(section 6.3.2.3 in DSP0222_1.1.1) + +According to NCSI SPEC(section 6.2.13.1 in DSP0222_1.1.1), we should probe +one channel at a time by sending NCSI commands (Clear initial state, Get +version ID, Get capabilities...), than repeat this steps until the max +number of channels which we got from NCSI command (Get capabilities) has +been probed. + +Fixes: e6f44ed6d04d ("net/ncsi: Package and channel management") +Signed-off-by: DelphineCCChiu +Link: https://lore.kernel.org/r/20240529065856.825241-1-delphine_cc_chiu@wiwynn.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ncsi/internal.h | 2 ++ + net/ncsi/ncsi-manage.c | 73 +++++++++++++++++++++--------------------- + net/ncsi/ncsi-rsp.c | 4 ++- + 3 files changed, 41 insertions(+), 38 deletions(-) + +diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h +index 374412ed780b6..ef0f8f73826f5 100644 +--- a/net/ncsi/internal.h ++++ b/net/ncsi/internal.h +@@ -325,6 +325,7 @@ struct ncsi_dev_priv { + spinlock_t lock; /* Protect the NCSI device */ + unsigned int package_probe_id;/* Current ID during probe */ + unsigned int package_num; /* Number of packages */ ++ unsigned int channel_probe_id;/* Current cahnnel ID during probe */ + struct list_head packages; /* List of packages */ + struct ncsi_channel *hot_channel; /* Channel was ever active */ + struct ncsi_request requests[256]; /* Request table */ +@@ -343,6 +344,7 @@ struct ncsi_dev_priv { + bool multi_package; /* Enable multiple packages */ + bool mlx_multi_host; /* Enable multi host Mellanox */ + u32 package_whitelist; /* Packages to configure */ ++ unsigned char channel_count; /* Num of channels to probe */ + }; + + struct ncsi_cmd_arg { +diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c +index f567957698935..760b33fa03a8b 100644 +--- a/net/ncsi/ncsi-manage.c ++++ b/net/ncsi/ncsi-manage.c +@@ -510,17 +510,19 @@ static void ncsi_suspend_channel(struct ncsi_dev_priv *ndp) + + break; + case ncsi_dev_state_suspend_gls: +- ndp->pending_req_num = np->channel_num; ++ ndp->pending_req_num = 1; + + nca.type = NCSI_PKT_CMD_GLS; + nca.package = np->id; ++ nca.channel = ndp->channel_probe_id; ++ ret = ncsi_xmit_cmd(&nca); ++ if (ret) ++ goto error; ++ ndp->channel_probe_id++; + +- nd->state = ncsi_dev_state_suspend_dcnt; +- NCSI_FOR_EACH_CHANNEL(np, nc) { +- nca.channel = nc->id; +- ret = ncsi_xmit_cmd(&nca); +- if (ret) +- goto error; ++ if (ndp->channel_probe_id == ndp->channel_count) { ++ ndp->channel_probe_id = 0; ++ nd->state = ncsi_dev_state_suspend_dcnt; + } + + break; +@@ -1340,7 +1342,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + { + struct ncsi_dev *nd = &ndp->ndev; + struct ncsi_package *np; +- struct ncsi_channel *nc; + struct ncsi_cmd_arg nca; + unsigned char index; + int ret; +@@ -1418,23 +1419,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + + nd->state = ncsi_dev_state_probe_cis; + break; +- case ncsi_dev_state_probe_cis: +- ndp->pending_req_num = NCSI_RESERVED_CHANNEL; +- +- /* Clear initial state */ +- nca.type = NCSI_PKT_CMD_CIS; +- nca.package = ndp->active_package->id; +- for (index = 0; index < NCSI_RESERVED_CHANNEL; index++) { +- nca.channel = index; +- ret = ncsi_xmit_cmd(&nca); +- if (ret) +- goto error; +- } +- +- nd->state = ncsi_dev_state_probe_gvi; +- if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)) +- nd->state = ncsi_dev_state_probe_keep_phy; +- break; + case ncsi_dev_state_probe_keep_phy: + ndp->pending_req_num = 1; + +@@ -1447,14 +1431,17 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + + nd->state = ncsi_dev_state_probe_gvi; + break; ++ case ncsi_dev_state_probe_cis: + case ncsi_dev_state_probe_gvi: + case ncsi_dev_state_probe_gc: + case ncsi_dev_state_probe_gls: + np = ndp->active_package; +- ndp->pending_req_num = np->channel_num; ++ ndp->pending_req_num = 1; + +- /* Retrieve version, capability or link status */ +- if (nd->state == ncsi_dev_state_probe_gvi) ++ /* Clear initial state Retrieve version, capability or link status */ ++ if (nd->state == ncsi_dev_state_probe_cis) ++ nca.type = NCSI_PKT_CMD_CIS; ++ else if (nd->state == ncsi_dev_state_probe_gvi) + nca.type = NCSI_PKT_CMD_GVI; + else if (nd->state == ncsi_dev_state_probe_gc) + nca.type = NCSI_PKT_CMD_GC; +@@ -1462,19 +1449,29 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + nca.type = NCSI_PKT_CMD_GLS; + + nca.package = np->id; +- NCSI_FOR_EACH_CHANNEL(np, nc) { +- nca.channel = nc->id; +- ret = ncsi_xmit_cmd(&nca); +- if (ret) +- goto error; +- } ++ nca.channel = ndp->channel_probe_id; + +- if (nd->state == ncsi_dev_state_probe_gvi) ++ ret = ncsi_xmit_cmd(&nca); ++ if (ret) ++ goto error; ++ ++ if (nd->state == ncsi_dev_state_probe_cis) { ++ nd->state = ncsi_dev_state_probe_gvi; ++ if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY) && ndp->channel_probe_id == 0) ++ nd->state = ncsi_dev_state_probe_keep_phy; ++ } else if (nd->state == ncsi_dev_state_probe_gvi) { + nd->state = ncsi_dev_state_probe_gc; +- else if (nd->state == ncsi_dev_state_probe_gc) ++ } else if (nd->state == ncsi_dev_state_probe_gc) { + nd->state = ncsi_dev_state_probe_gls; +- else ++ } else { ++ nd->state = ncsi_dev_state_probe_cis; ++ ndp->channel_probe_id++; ++ } ++ ++ if (ndp->channel_probe_id == ndp->channel_count) { ++ ndp->channel_probe_id = 0; + nd->state = ncsi_dev_state_probe_dp; ++ } + break; + case ncsi_dev_state_probe_dp: + ndp->pending_req_num = 1; +@@ -1775,6 +1772,7 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev, + ndp->requests[i].ndp = ndp; + timer_setup(&ndp->requests[i].timer, ncsi_request_timeout, 0); + } ++ ndp->channel_count = NCSI_RESERVED_CHANNEL; + + spin_lock_irqsave(&ncsi_dev_lock, flags); + list_add_tail_rcu(&ndp->node, &ncsi_dev_list); +@@ -1808,6 +1806,7 @@ int ncsi_start_dev(struct ncsi_dev *nd) + + if (!(ndp->flags & NCSI_DEV_PROBED)) { + ndp->package_probe_id = 0; ++ ndp->channel_probe_id = 0; + nd->state = ncsi_dev_state_probe; + schedule_work(&ndp->work); + return 0; +diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c +index 480e80e3c2836..f22d67cb04d37 100644 +--- a/net/ncsi/ncsi-rsp.c ++++ b/net/ncsi/ncsi-rsp.c +@@ -795,12 +795,13 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr) + struct ncsi_rsp_gc_pkt *rsp; + struct ncsi_dev_priv *ndp = nr->ndp; + struct ncsi_channel *nc; ++ struct ncsi_package *np; + size_t size; + + /* Find the channel */ + rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp); + ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, +- NULL, &nc); ++ &np, &nc); + if (!nc) + return -ENODEV; + +@@ -835,6 +836,7 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr) + */ + nc->vlan_filter.bitmap = U64_MAX; + nc->vlan_filter.n_vids = rsp->vlan_cnt; ++ np->ndp->channel_count = rsp->channel_cnt; + + return 0; + } +-- +2.43.0 + diff --git a/queue-6.1/net-ncsi-simplify-kconfig-dts-control-flow.patch b/queue-6.1/net-ncsi-simplify-kconfig-dts-control-flow.patch new file mode 100644 index 00000000000..49f8e282cd7 --- /dev/null +++ b/queue-6.1/net-ncsi-simplify-kconfig-dts-control-flow.patch @@ -0,0 +1,152 @@ +From b808af11eac107de7042f99237984f79f84dcfa4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 10:07:33 -0600 +Subject: net/ncsi: Simplify Kconfig/dts control flow + +From: Peter Delevoryas + +[ Upstream commit c797ce168930ce3d62a9b7fc4d7040963ee6a01e ] + +Background: + +1. CONFIG_NCSI_OEM_CMD_KEEP_PHY + +If this is enabled, we send an extra OEM Intel command in the probe +sequence immediately after discovering a channel (e.g. after "Clear +Initial State"). + +2. CONFIG_NCSI_OEM_CMD_GET_MAC + +If this is enabled, we send one of 3 OEM "Get MAC Address" commands from +Broadcom, Mellanox (Nvidida), and Intel in the *configuration* sequence +for a channel. + +3. mellanox,multi-host (or mlx,multi-host) + +Introduced by this patch: + +https://lore.kernel.org/all/20200108234341.2590674-1-vijaykhemka@fb.com/ + +Which was actually originally from cosmo.chou@quantatw.com: + +https://github.com/facebook/openbmc-linux/commit/9f132a10ec48db84613519258cd8a317fb9c8f1b + +Cosmo claimed that the Nvidia ConnectX-4 and ConnectX-6 NIC's don't +respond to Get Version ID, et. al in the probe sequence unless you send +the Set MC Affinity command first. + +Problem Statement: + +We've been using a combination of #ifdef code blocks and IS_ENABLED() +conditions to conditionally send these OEM commands. + +It makes adding any new code around these commands hard to understand. + +Solution: + +In this patch, I just want to remove the conditionally compiled blocks +of code, and always use IS_ENABLED(...) to do dynamic control flow. + +I don't think the small amount of code this adds to non-users of the OEM +Kconfigs is a big deal. + +Signed-off-by: Peter Delevoryas +Signed-off-by: David S. Miller +Stable-dep-of: e85e271dec02 ("net/ncsi: Fix the multi thread manner of NCSI driver") +Signed-off-by: Sasha Levin +--- + net/ncsi/ncsi-manage.c | 20 +++----------------- + 1 file changed, 3 insertions(+), 17 deletions(-) + +diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c +index 80713febfac6d..f567957698935 100644 +--- a/net/ncsi/ncsi-manage.c ++++ b/net/ncsi/ncsi-manage.c +@@ -689,8 +689,6 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc, + return 0; + } + +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY) +- + static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca) + { + unsigned char data[NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN]; +@@ -716,10 +714,6 @@ static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca) + return ret; + } + +-#endif +- +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC) +- + /* NCSI OEM Command APIs */ + static int ncsi_oem_gma_handler_bcm(struct ncsi_cmd_arg *nca) + { +@@ -856,8 +850,6 @@ static int ncsi_gma_handler(struct ncsi_cmd_arg *nca, unsigned int mf_id) + return nch->handler(nca); + } + +-#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */ +- + /* Determine if a given channel from the channel_queue should be used for Tx */ + static bool ncsi_channel_is_tx(struct ncsi_dev_priv *ndp, + struct ncsi_channel *nc) +@@ -1039,20 +1031,18 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) + goto error; + } + +- nd->state = ncsi_dev_state_config_oem_gma; ++ nd->state = IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC) ++ ? ncsi_dev_state_config_oem_gma ++ : ncsi_dev_state_config_clear_vids; + break; + case ncsi_dev_state_config_oem_gma: + nd->state = ncsi_dev_state_config_clear_vids; +- ret = -1; + +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC) + nca.type = NCSI_PKT_CMD_OEM; + nca.package = np->id; + nca.channel = nc->id; + ndp->pending_req_num = 1; + ret = ncsi_gma_handler(&nca, nc->version.mf_id); +-#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */ +- + if (ret < 0) + schedule_work(&ndp->work); + +@@ -1404,7 +1394,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + + schedule_work(&ndp->work); + break; +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC) + case ncsi_dev_state_probe_mlx_gma: + ndp->pending_req_num = 1; + +@@ -1429,7 +1418,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + + nd->state = ncsi_dev_state_probe_cis; + break; +-#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */ + case ncsi_dev_state_probe_cis: + ndp->pending_req_num = NCSI_RESERVED_CHANNEL; + +@@ -1447,7 +1435,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)) + nd->state = ncsi_dev_state_probe_keep_phy; + break; +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY) + case ncsi_dev_state_probe_keep_phy: + ndp->pending_req_num = 1; + +@@ -1460,7 +1447,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + + nd->state = ncsi_dev_state_probe_gvi; + break; +-#endif /* CONFIG_NCSI_OEM_CMD_KEEP_PHY */ + case ncsi_dev_state_probe_gvi: + case ncsi_dev_state_probe_gc: + case ncsi_dev_state_probe_gls: +-- +2.43.0 + diff --git a/queue-6.1/net-sched-sch_multiq-fix-possible-oob-write-in-multi.patch b/queue-6.1/net-sched-sch_multiq-fix-possible-oob-write-in-multi.patch new file mode 100644 index 00000000000..462bce87d3c --- /dev/null +++ b/queue-6.1/net-sched-sch_multiq-fix-possible-oob-write-in-multi.patch @@ -0,0 +1,38 @@ +From 0c82a4979310c759dca5c16ac04b6c7cdfbe4114 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 15:13:03 +0800 +Subject: net: sched: sch_multiq: fix possible OOB write in multiq_tune() + +From: Hangyu Hua + +[ Upstream commit affc18fdc694190ca7575b9a86632a73b9fe043d ] + +q->bands will be assigned to qopt->bands to execute subsequent code logic +after kmalloc. So the old q->bands should not be used in kmalloc. +Otherwise, an out-of-bounds write will occur. + +Fixes: c2999f7fb05b ("net: sched: multiq: don't call qdisc_put() while holding tree lock") +Signed-off-by: Hangyu Hua +Acked-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/sched/sch_multiq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c +index 75c9c860182b4..0d6649d937c9f 100644 +--- a/net/sched/sch_multiq.c ++++ b/net/sched/sch_multiq.c +@@ -185,7 +185,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt, + + qopt->bands = qdisc_dev(sch)->real_num_tx_queues; + +- removed = kmalloc(sizeof(*removed) * (q->max_bands - q->bands), ++ removed = kmalloc(sizeof(*removed) * (q->max_bands - qopt->bands), + GFP_KERNEL); + if (!removed) + return -ENOMEM; +-- +2.43.0 + diff --git a/queue-6.1/net-sched-taprio-always-validate-tca_taprio_attr_pri.patch b/queue-6.1/net-sched-taprio-always-validate-tca_taprio_attr_pri.patch new file mode 100644 index 00000000000..d113c57b000 --- /dev/null +++ b/queue-6.1/net-sched-taprio-always-validate-tca_taprio_attr_pri.patch @@ -0,0 +1,63 @@ +From 0c5fe8088d906646fee78f2b1a7f81a966bda73b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 18:15:11 +0000 +Subject: net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP + +From: Eric Dumazet + +[ Upstream commit f921a58ae20852d188f70842431ce6519c4fdc36 ] + +If one TCA_TAPRIO_ATTR_PRIOMAP attribute has been provided, +taprio_parse_mqprio_opt() must validate it, or userspace +can inject arbitrary data to the kernel, the second time +taprio_change() is called. + +First call (with valid attributes) sets dev->num_tc +to a non zero value. + +Second call (with arbitrary mqprio attributes) +returns early from taprio_parse_mqprio_opt() +and bad things can happen. + +Fixes: a3d43c0d56f1 ("taprio: Add support adding an admin schedule") +Reported-by: Noam Rathaus +Signed-off-by: Eric Dumazet +Acked-by: Vinicius Costa Gomes +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20240604181511.769870-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_taprio.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c +index 1d4638aa4254f..41187bbd25ee9 100644 +--- a/net/sched/sch_taprio.c ++++ b/net/sched/sch_taprio.c +@@ -938,16 +938,13 @@ static int taprio_parse_mqprio_opt(struct net_device *dev, + { + int i, j; + +- if (!qopt && !dev->num_tc) { +- NL_SET_ERR_MSG(extack, "'mqprio' configuration is necessary"); +- return -EINVAL; +- } +- +- /* If num_tc is already set, it means that the user already +- * configured the mqprio part +- */ +- if (dev->num_tc) ++ if (!qopt) { ++ if (!dev->num_tc) { ++ NL_SET_ERR_MSG(extack, "'mqprio' configuration is necessary"); ++ return -EINVAL; ++ } + return 0; ++ } + + /* Verify num_tc is not out of max range */ + if (qopt->num_tc > TC_MAX_QUEUE) { +-- +2.43.0 + diff --git a/queue-6.1/net-smc-avoid-overwriting-when-adjusting-sock-bufsiz.patch b/queue-6.1/net-smc-avoid-overwriting-when-adjusting-sock-bufsiz.patch new file mode 100644 index 00000000000..b703e8a7dc4 --- /dev/null +++ b/queue-6.1/net-smc-avoid-overwriting-when-adjusting-sock-bufsiz.patch @@ -0,0 +1,68 @@ +From 6ca42f77ddfd213d53fa7f27418615e952538fb9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 May 2024 16:54:17 +0800 +Subject: net/smc: avoid overwriting when adjusting sock bufsizes + +From: Wen Gu + +[ Upstream commit fb0aa0781a5f457e3864da68af52c3b1f4f7fd8f ] + +When copying smc settings to clcsock, avoid setting clcsock's sk_sndbuf +to sysctl_tcp_wmem[1], since this may overwrite the value set by +tcp_sndbuf_expand() in TCP connection establishment. + +And the other setting sk_{snd|rcv}buf to sysctl value in +smc_adjust_sock_bufsizes() can also be omitted since the initialization +of smc sock and clcsock has set sk_{snd|rcv}buf to smc.sysctl_{w|r}mem +or ipv4_sysctl_tcp_{w|r}mem[1]. + +Fixes: 30c3c4a4497c ("net/smc: Use correct buffer sizes when switching between TCP and SMC") +Link: https://lore.kernel.org/r/5eaf3858-e7fd-4db8-83e8-3d7a3e0e9ae2@linux.alibaba.com +Signed-off-by: Wen Gu +Reviewed-by: Wenjia Zhang +Reviewed-by: Gerd Bayer , too. +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/smc/af_smc.c | 22 ++-------------------- + 1 file changed, 2 insertions(+), 20 deletions(-) + +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index b6609527dff62..e86db21fef6e5 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -462,29 +462,11 @@ static int smc_bind(struct socket *sock, struct sockaddr *uaddr, + static void smc_adjust_sock_bufsizes(struct sock *nsk, struct sock *osk, + unsigned long mask) + { +- struct net *nnet = sock_net(nsk); +- + nsk->sk_userlocks = osk->sk_userlocks; +- if (osk->sk_userlocks & SOCK_SNDBUF_LOCK) { ++ if (osk->sk_userlocks & SOCK_SNDBUF_LOCK) + nsk->sk_sndbuf = osk->sk_sndbuf; +- } else { +- if (mask == SK_FLAGS_SMC_TO_CLC) +- WRITE_ONCE(nsk->sk_sndbuf, +- READ_ONCE(nnet->ipv4.sysctl_tcp_wmem[1])); +- else +- WRITE_ONCE(nsk->sk_sndbuf, +- 2 * READ_ONCE(nnet->smc.sysctl_wmem)); +- } +- if (osk->sk_userlocks & SOCK_RCVBUF_LOCK) { ++ if (osk->sk_userlocks & SOCK_RCVBUF_LOCK) + nsk->sk_rcvbuf = osk->sk_rcvbuf; +- } else { +- if (mask == SK_FLAGS_SMC_TO_CLC) +- WRITE_ONCE(nsk->sk_rcvbuf, +- READ_ONCE(nnet->ipv4.sysctl_tcp_rmem[1])); +- else +- WRITE_ONCE(nsk->sk_rcvbuf, +- 2 * READ_ONCE(nnet->smc.sysctl_rmem)); +- } + } + + static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk, +-- +2.43.0 + diff --git a/queue-6.1/net-wwan-iosm-fix-tainted-pointer-delete-is-case-of-.patch b/queue-6.1/net-wwan-iosm-fix-tainted-pointer-delete-is-case-of-.patch new file mode 100644 index 00000000000..988914843e4 --- /dev/null +++ b/queue-6.1/net-wwan-iosm-fix-tainted-pointer-delete-is-case-of-.patch @@ -0,0 +1,44 @@ +From 039c9a66d803ebf62a965e963c78c034fe011b28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 11:25:00 +0300 +Subject: net: wwan: iosm: Fix tainted pointer delete is case of region + creation fail + +From: Aleksandr Mishin + +[ Upstream commit b0c9a26435413b81799047a7be53255640432547 ] + +In case of region creation fail in ipc_devlink_create_region(), previously +created regions delete process starts from tainted pointer which actually +holds error code value. +Fix this bug by decreasing region index before delete. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 4dcd183fbd67 ("net: wwan: iosm: devlink registration") +Signed-off-by: Aleksandr Mishin +Acked-by: Sergey Ryazanov +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240604082500.20769-1-amishin@t-argos.ru +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/wwan/iosm/iosm_ipc_devlink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wwan/iosm/iosm_ipc_devlink.c b/drivers/net/wwan/iosm/iosm_ipc_devlink.c +index 2fe724d623c06..33c5a46f1b922 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_devlink.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_devlink.c +@@ -210,7 +210,7 @@ static int ipc_devlink_create_region(struct iosm_devlink *devlink) + rc = PTR_ERR(devlink->cd_regions[i]); + dev_err(devlink->dev, "Devlink region fail,err %d", rc); + /* Delete previously created regions */ +- for ( ; i >= 0; i--) ++ for (i--; i >= 0; i--) + devlink_region_destroy(devlink->cd_regions[i]); + goto region_create_fail; + } +-- +2.43.0 + diff --git a/queue-6.1/nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch b/queue-6.1/nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch new file mode 100644 index 00000000000..76aa08f0431 --- /dev/null +++ b/queue-6.1/nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch @@ -0,0 +1,51 @@ +From 9f5c71a6729d3967349e6fc940d3d0848010dba7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 22:42:55 +0900 +Subject: nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors + +From: Ryusuke Konishi + +[ Upstream commit 7373a51e7998b508af7136530f3a997b286ce81c ] + +The error handling in nilfs_empty_dir() when a directory folio/page read +fails is incorrect, as in the old ext2 implementation, and if the +folio/page cannot be read or nilfs_check_folio() fails, it will falsely +determine the directory as empty and corrupt the file system. + +In addition, since nilfs_empty_dir() does not immediately return on a +failed folio/page read, but continues to loop, this can cause a long loop +with I/O if i_size of the directory's inode is also corrupted, causing the +log writer thread to wait and hang, as reported by syzbot. + +Fix these issues by making nilfs_empty_dir() immediately return a false +value (0) if it fails to get a directory folio/page. + +Link: https://lkml.kernel.org/r/20240604134255.7165-1-konishi.ryusuke@gmail.com +Signed-off-by: Ryusuke Konishi +Reported-by: syzbot+c8166c541d3971bf6c87@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=c8166c541d3971bf6c87 +Fixes: 2ba466d74ed7 ("nilfs2: directory entry operations") +Tested-by: Ryusuke Konishi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/nilfs2/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c +index 4911f09eb68b0..e9668e455a35e 100644 +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -627,7 +627,7 @@ int nilfs_empty_dir(struct inode *inode) + + kaddr = nilfs_get_page(inode, i, &page); + if (IS_ERR(kaddr)) +- continue; ++ return 0; + + de = (struct nilfs_dir_entry *)kaddr; + kaddr += nilfs_last_byte(inode, i) - NILFS_DIR_REC_LEN(1); +-- +2.43.0 + diff --git a/queue-6.1/nilfs2-return-the-mapped-address-from-nilfs_get_page.patch b/queue-6.1/nilfs2-return-the-mapped-address-from-nilfs_get_page.patch new file mode 100644 index 00000000000..0bfd198e90b --- /dev/null +++ b/queue-6.1/nilfs2-return-the-mapped-address-from-nilfs_get_page.patch @@ -0,0 +1,146 @@ +From c7c371149f13369f093be2ee0aebe4fa8d83c30f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Nov 2023 23:30:25 +0900 +Subject: nilfs2: return the mapped address from nilfs_get_page() + +From: Matthew Wilcox (Oracle) + +[ Upstream commit 09a46acb3697e50548bb265afa1d79163659dd85 ] + +In prepartion for switching from kmap() to kmap_local(), return the kmap +address from nilfs_get_page() instead of having the caller look up +page_address(). + +[konishi.ryusuke: fixed a missing blank line after declaration] +Link: https://lkml.kernel.org/r/20231127143036.2425-7-konishi.ryusuke@gmail.com +Signed-off-by: Matthew Wilcox (Oracle) +Signed-off-by: Ryusuke Konishi +Signed-off-by: Andrew Morton +Stable-dep-of: 7373a51e7998 ("nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors") +Signed-off-by: Sasha Levin +--- + fs/nilfs2/dir.c | 57 +++++++++++++++++++++++-------------------------- + 1 file changed, 27 insertions(+), 30 deletions(-) + +diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c +index 760405da852f6..4911f09eb68b0 100644 +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -186,19 +186,24 @@ static bool nilfs_check_page(struct page *page) + return false; + } + +-static struct page *nilfs_get_page(struct inode *dir, unsigned long n) ++static void *nilfs_get_page(struct inode *dir, unsigned long n, ++ struct page **pagep) + { + struct address_space *mapping = dir->i_mapping; + struct page *page = read_mapping_page(mapping, n, NULL); ++ void *kaddr; + +- if (!IS_ERR(page)) { +- kmap(page); +- if (unlikely(!PageChecked(page))) { +- if (!nilfs_check_page(page)) +- goto fail; +- } ++ if (IS_ERR(page)) ++ return page; ++ ++ kaddr = kmap(page); ++ if (unlikely(!PageChecked(page))) { ++ if (!nilfs_check_page(page)) ++ goto fail; + } +- return page; ++ ++ *pagep = page; ++ return kaddr; + + fail: + nilfs_put_page(page); +@@ -275,14 +280,14 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx) + for ( ; n < npages; n++, offset = 0) { + char *kaddr, *limit; + struct nilfs_dir_entry *de; +- struct page *page = nilfs_get_page(inode, n); ++ struct page *page; + +- if (IS_ERR(page)) { ++ kaddr = nilfs_get_page(inode, n, &page); ++ if (IS_ERR(kaddr)) { + nilfs_error(sb, "bad page in #%lu", inode->i_ino); + ctx->pos += PAGE_SIZE - offset; + return -EIO; + } +- kaddr = page_address(page); + de = (struct nilfs_dir_entry *)(kaddr + offset); + limit = kaddr + nilfs_last_byte(inode, n) - + NILFS_DIR_REC_LEN(1); +@@ -345,11 +350,9 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, + start = 0; + n = start; + do { +- char *kaddr; ++ char *kaddr = nilfs_get_page(dir, n, &page); + +- page = nilfs_get_page(dir, n); +- if (!IS_ERR(page)) { +- kaddr = page_address(page); ++ if (!IS_ERR(kaddr)) { + de = (struct nilfs_dir_entry *)kaddr; + kaddr += nilfs_last_byte(dir, n) - reclen; + while ((char *) de <= kaddr) { +@@ -387,15 +390,11 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, + + struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p) + { +- struct page *page = nilfs_get_page(dir, 0); +- struct nilfs_dir_entry *de = NULL; ++ struct nilfs_dir_entry *de = nilfs_get_page(dir, 0, p); + +- if (!IS_ERR(page)) { +- de = nilfs_next_entry( +- (struct nilfs_dir_entry *)page_address(page)); +- *p = page; +- } +- return de; ++ if (IS_ERR(de)) ++ return NULL; ++ return nilfs_next_entry(de); + } + + ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr) +@@ -459,12 +458,11 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode) + for (n = 0; n <= npages; n++) { + char *dir_end; + +- page = nilfs_get_page(dir, n); +- err = PTR_ERR(page); +- if (IS_ERR(page)) ++ kaddr = nilfs_get_page(dir, n, &page); ++ err = PTR_ERR(kaddr); ++ if (IS_ERR(kaddr)) + goto out; + lock_page(page); +- kaddr = page_address(page); + dir_end = kaddr + nilfs_last_byte(dir, n); + de = (struct nilfs_dir_entry *)kaddr; + kaddr += PAGE_SIZE - reclen; +@@ -627,11 +625,10 @@ int nilfs_empty_dir(struct inode *inode) + char *kaddr; + struct nilfs_dir_entry *de; + +- page = nilfs_get_page(inode, i); +- if (IS_ERR(page)) ++ kaddr = nilfs_get_page(inode, i, &page); ++ if (IS_ERR(kaddr)) + continue; + +- kaddr = page_address(page); + de = (struct nilfs_dir_entry *)kaddr; + kaddr += nilfs_last_byte(inode, i) - NILFS_DIR_REC_LEN(1); + +-- +2.43.0 + diff --git a/queue-6.1/octeontx2-af-always-allocate-pf-entries-from-low-pri.patch b/queue-6.1/octeontx2-af-always-allocate-pf-entries-from-low-pri.patch new file mode 100644 index 00000000000..0864376471a --- /dev/null +++ b/queue-6.1/octeontx2-af-always-allocate-pf-entries-from-low-pri.patch @@ -0,0 +1,87 @@ +From 0e3360f0aba9eda0c7e75bf0ca6a851f07322ff2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 20:59:44 +0530 +Subject: octeontx2-af: Always allocate PF entries from low prioriy zone + +From: Subbaraya Sundeep + +[ Upstream commit 8b0f7410942cdc420c4557eda02bfcdf60ccec17 ] + +PF mcam entries has to be at low priority always so that VF +can install longest prefix match rules at higher priority. +This was taken care currently but when priority allocation +wrt reference entry is requested then entries are allocated +from mid-zone instead of low priority zone. Fix this and +always allocate entries from low priority zone for PFs. + +Fixes: 7df5b4b260dd ("octeontx2-af: Allocate low priority entries for PF") +Signed-off-by: Subbaraya Sundeep +Reviewed-by: Jacob Keller +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../ethernet/marvell/octeontx2/af/rvu_npc.c | 33 ++++++++++++------- + 1 file changed, 22 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 91a4ea529d077..00ef6d201b973 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -2506,7 +2506,17 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc, + * - when available free entries are less. + * Lower priority ones out of avaialble free entries are always + * chosen when 'high vs low' question arises. ++ * ++ * For a VF base MCAM match rule is set by its PF. And all the ++ * further MCAM rules installed by VF on its own are ++ * concatenated with the base rule set by its PF. Hence PF entries ++ * should be at lower priority compared to VF entries. Otherwise ++ * base rule is hit always and rules installed by VF will be of ++ * no use. Hence if the request is from PF then allocate low ++ * priority entries. + */ ++ if (!(pcifunc & RVU_PFVF_FUNC_MASK)) ++ goto lprio_alloc; + + /* Get the search range for priority allocation request */ + if (req->priority) { +@@ -2515,17 +2525,6 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc, + goto alloc; + } + +- /* For a VF base MCAM match rule is set by its PF. And all the +- * further MCAM rules installed by VF on its own are +- * concatenated with the base rule set by its PF. Hence PF entries +- * should be at lower priority compared to VF entries. Otherwise +- * base rule is hit always and rules installed by VF will be of +- * no use. Hence if the request is from PF and NOT a priority +- * allocation request then allocate low priority entries. +- */ +- if (!(pcifunc & RVU_PFVF_FUNC_MASK)) +- goto lprio_alloc; +- + /* Find out the search range for non-priority allocation request + * + * Get MCAM free entry count in middle zone. +@@ -2555,6 +2554,18 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc, + reverse = true; + start = 0; + end = mcam->bmap_entries; ++ /* Ensure PF requests are always at bottom and if PF requests ++ * for higher/lower priority entry wrt reference entry then ++ * honour that criteria and start search for entries from bottom ++ * and not in mid zone. ++ */ ++ if (!(pcifunc & RVU_PFVF_FUNC_MASK) && ++ req->priority == NPC_MCAM_HIGHER_PRIO) ++ end = req->ref_entry; ++ ++ if (!(pcifunc & RVU_PFVF_FUNC_MASK) && ++ req->priority == NPC_MCAM_LOWER_PRIO) ++ start = req->ref_entry; + } + + alloc: +-- +2.43.0 + diff --git a/queue-6.1/ptp-fix-error-message-on-failed-pin-verification.patch b/queue-6.1/ptp-fix-error-message-on-failed-pin-verification.patch new file mode 100644 index 00000000000..a0142ffe96a --- /dev/null +++ b/queue-6.1/ptp-fix-error-message-on-failed-pin-verification.patch @@ -0,0 +1,42 @@ +From 9e35548beedad5a4f0d124dd91f6bf8e645a9dfc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 14:05:27 +0200 +Subject: ptp: Fix error message on failed pin verification + +From: Karol Kolacinski + +[ Upstream commit 323a359f9b077f382f4483023d096a4d316fd135 ] + +On failed verification of PTP clock pin, error message prints channel +number instead of pin index after "pin", which is incorrect. + +Fix error message by adding channel number to the message and printing +pin number instead of channel number. + +Fixes: 6092315dfdec ("ptp: introduce programmable pins.") +Signed-off-by: Karol Kolacinski +Acked-by: Richard Cochran +Link: https://lore.kernel.org/r/20240604120555.16643-1-karol.kolacinski@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/ptp/ptp_chardev.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c +index 9311f3d09c8fc..8eb902fe73a98 100644 +--- a/drivers/ptp/ptp_chardev.c ++++ b/drivers/ptp/ptp_chardev.c +@@ -84,7 +84,8 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, + } + + if (info->verify(info, pin, func, chan)) { +- pr_err("driver cannot use function %u on pin %u\n", func, chan); ++ pr_err("driver cannot use function %u and channel %u on pin %u\n", ++ func, chan, pin); + return -EOPNOTSUPP; + } + +-- +2.43.0 + diff --git a/queue-6.1/selftests-mm-compaction_test-fix-bogus-test-success-.patch b/queue-6.1/selftests-mm-compaction_test-fix-bogus-test-success-.patch new file mode 100644 index 00000000000..bdd45f0a18d --- /dev/null +++ b/queue-6.1/selftests-mm-compaction_test-fix-bogus-test-success-.patch @@ -0,0 +1,109 @@ +From 177025fe7de60effb910577363000415e4e82bf4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 May 2024 13:13:56 +0530 +Subject: selftests/mm: compaction_test: fix bogus test success on Aarch64 + +From: Dev Jain + +[ Upstream commit d4202e66a4b1fe6968f17f9f09bbc30d08f028a1 ] + +Patch series "Fixes for compaction_test", v2. + +The compaction_test memory selftest introduces fragmentation in memory +and then tries to allocate as many hugepages as possible. This series +addresses some problems. + +On Aarch64, if nr_hugepages == 0, then the test trivially succeeds since +compaction_index becomes 0, which is less than 3, due to no division by +zero exception being raised. We fix that by checking for division by +zero. + +Secondly, correctly set the number of hugepages to zero before trying +to set a large number of them. + +Now, consider a situation in which, at the start of the test, a non-zero +number of hugepages have been already set (while running the entire +selftests/mm suite, or manually by the admin). The test operates on 80% +of memory to avoid OOM-killer invocation, and because some memory is +already blocked by hugepages, it would increase the chance of OOM-killing. +Also, since mem_free used in check_compaction() is the value before we +set nr_hugepages to zero, the chance that the compaction_index will +be small is very high if the preset nr_hugepages was high, leading to a +bogus test success. + +This patch (of 3): + +Currently, if at runtime we are not able to allocate a huge page, the test +will trivially pass on Aarch64 due to no exception being raised on +division by zero while computing compaction_index. Fix that by checking +for nr_hugepages == 0. Anyways, in general, avoid a division by zero by +exiting the program beforehand. While at it, fix a typo, and handle the +case where the number of hugepages may overflow an integer. + +Link: https://lkml.kernel.org/r/20240521074358.675031-1-dev.jain@arm.com +Link: https://lkml.kernel.org/r/20240521074358.675031-2-dev.jain@arm.com +Fixes: bd67d5c15cc1 ("Test compaction of mlocked memory") +Signed-off-by: Dev Jain +Cc: Anshuman Khandual +Cc: Shuah Khan +Cc: Sri Jayaramappa +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/compaction_test.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index 6aa6460b854ea..309b3750e57e1 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -82,12 +82,13 @@ int prereq(void) + return -1; + } + +-int check_compaction(unsigned long mem_free, unsigned int hugepage_size) ++int check_compaction(unsigned long mem_free, unsigned long hugepage_size) + { ++ unsigned long nr_hugepages_ul; + int fd, ret = -1; + int compaction_index = 0; +- char initial_nr_hugepages[10] = {0}; +- char nr_hugepages[10] = {0}; ++ char initial_nr_hugepages[20] = {0}; ++ char nr_hugepages[20] = {0}; + + /* We want to test with 80% of available memory. Else, OOM killer comes + in to play */ +@@ -136,7 +137,12 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + /* We should have been able to request at least 1/3 rd of the memory in + huge pages */ +- compaction_index = mem_free/(atoi(nr_hugepages) * hugepage_size); ++ nr_hugepages_ul = strtoul(nr_hugepages, NULL, 10); ++ if (!nr_hugepages_ul) { ++ ksft_print_msg("ERROR: No memory is available as huge pages\n"); ++ goto close_fd; ++ } ++ compaction_index = mem_free/(nr_hugepages_ul * hugepage_size); + + lseek(fd, 0, SEEK_SET); + +@@ -147,11 +153,11 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + goto close_fd; + } + +- ksft_print_msg("Number of huge pages allocated = %d\n", +- atoi(nr_hugepages)); ++ ksft_print_msg("Number of huge pages allocated = %lu\n", ++ nr_hugepages_ul); + + if (compaction_index > 3) { +- ksft_print_msg("ERROR: Less that 1/%d of memory is available\n" ++ ksft_print_msg("ERROR: Less than 1/%d of memory is available\n" + "as huge pages\n", compaction_index); + goto close_fd; + } +-- +2.43.0 + diff --git a/queue-6.1/selftests-mm-compaction_test-fix-incorrect-write-of-.patch b/queue-6.1/selftests-mm-compaction_test-fix-incorrect-write-of-.patch new file mode 100644 index 00000000000..cb1dce37e83 --- /dev/null +++ b/queue-6.1/selftests-mm-compaction_test-fix-incorrect-write-of-.patch @@ -0,0 +1,43 @@ +From 4548468867ce648f77e7cfec167c77893072d227 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 May 2024 13:13:57 +0530 +Subject: selftests/mm: compaction_test: fix incorrect write of zero to + nr_hugepages + +From: Dev Jain + +[ Upstream commit 9ad665ef55eaad1ead1406a58a34f615a7c18b5e ] + +Currently, the test tries to set nr_hugepages to zero, but that is not +actually done because the file offset is not reset after read(). Fix that +using lseek(). + +Link: https://lkml.kernel.org/r/20240521074358.675031-3-dev.jain@arm.com +Fixes: bd67d5c15cc1 ("Test compaction of mlocked memory") +Signed-off-by: Dev Jain +Cc: +Cc: Anshuman Khandual +Cc: Shuah Khan +Cc: Sri Jayaramappa +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/compaction_test.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index 9b420140ba2ba..55dec92e1e58c 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -103,6 +103,8 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + goto close_fd; + } + ++ lseek(fd, 0, SEEK_SET); ++ + /* Start with the initial condition of 0 huge pages*/ + if (write(fd, "0", sizeof(char)) != sizeof(char)) { + perror("Failed to write 0 to /proc/sys/vm/nr_hugepages\n"); +-- +2.43.0 + diff --git a/queue-6.1/selftests-mm-conform-test-to-tap-format-output.patch b/queue-6.1/selftests-mm-conform-test-to-tap-format-output.patch new file mode 100644 index 00000000000..ad043150853 --- /dev/null +++ b/queue-6.1/selftests-mm-conform-test-to-tap-format-output.patch @@ -0,0 +1,229 @@ +From ae0c8bb54bec9c90f328d6355efb4a63aabf0dac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Jan 2024 13:36:12 +0500 +Subject: selftests/mm: conform test to TAP format output + +From: Muhammad Usama Anjum + +[ Upstream commit 9a21701edc41465de56f97914741bfb7bfc2517d ] + +Conform the layout, informational and status messages to TAP. No +functional change is intended other than the layout of output messages. + +Link: https://lkml.kernel.org/r/20240101083614.1076768-1-usama.anjum@collabora.com +Signed-off-by: Muhammad Usama Anjum +Cc: Shuah Khan +Signed-off-by: Andrew Morton +Stable-dep-of: d4202e66a4b1 ("selftests/mm: compaction_test: fix bogus test success on Aarch64") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/compaction_test.c | 91 ++++++++++---------- + 1 file changed, 44 insertions(+), 47 deletions(-) + +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index 55dec92e1e58c..f81931c1f8386 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -33,7 +33,7 @@ int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize) + FILE *cmdfile = popen(cmd, "r"); + + if (!(fgets(buffer, sizeof(buffer), cmdfile))) { +- perror("Failed to read meminfo\n"); ++ ksft_print_msg("Failed to read meminfo: %s\n", strerror(errno)); + return -1; + } + +@@ -44,7 +44,7 @@ int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize) + cmdfile = popen(cmd, "r"); + + if (!(fgets(buffer, sizeof(buffer), cmdfile))) { +- perror("Failed to read meminfo\n"); ++ ksft_print_msg("Failed to read meminfo: %s\n", strerror(errno)); + return -1; + } + +@@ -62,14 +62,14 @@ int prereq(void) + fd = open("/proc/sys/vm/compact_unevictable_allowed", + O_RDONLY | O_NONBLOCK); + if (fd < 0) { +- perror("Failed to open\n" +- "/proc/sys/vm/compact_unevictable_allowed\n"); ++ ksft_print_msg("Failed to open /proc/sys/vm/compact_unevictable_allowed: %s\n", ++ strerror(errno)); + return -1; + } + + if (read(fd, &allowed, sizeof(char)) != sizeof(char)) { +- perror("Failed to read from\n" +- "/proc/sys/vm/compact_unevictable_allowed\n"); ++ ksft_print_msg("Failed to read from /proc/sys/vm/compact_unevictable_allowed: %s\n", ++ strerror(errno)); + close(fd); + return -1; + } +@@ -78,12 +78,13 @@ int prereq(void) + if (allowed == '1') + return 0; + ++ ksft_print_msg("Compaction isn't allowed\n"); + return -1; + } + + int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + { +- int fd; ++ int fd, ret = -1; + int compaction_index = 0; + char initial_nr_hugepages[10] = {0}; + char nr_hugepages[10] = {0}; +@@ -94,12 +95,14 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK); + if (fd < 0) { +- perror("Failed to open /proc/sys/vm/nr_hugepages"); ++ ksft_test_result_fail("Failed to open /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + return -1; + } + + if (read(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) <= 0) { +- perror("Failed to read from /proc/sys/vm/nr_hugepages"); ++ ksft_test_result_fail("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -107,7 +110,8 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + /* Start with the initial condition of 0 huge pages*/ + if (write(fd, "0", sizeof(char)) != sizeof(char)) { +- perror("Failed to write 0 to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -116,14 +120,16 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + /* Request a large number of huge pages. The Kernel will allocate + as much as it can */ + if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { +- perror("Failed to write 100000 to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + + lseek(fd, 0, SEEK_SET); + + if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { +- perror("Failed to re-read from /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to re-read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -131,67 +137,58 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + huge pages */ + compaction_index = mem_free/(atoi(nr_hugepages) * hugepage_size); + +- if (compaction_index > 3) { +- printf("No of huge pages allocated = %d\n", +- (atoi(nr_hugepages))); +- fprintf(stderr, "ERROR: Less that 1/%d of memory is available\n" +- "as huge pages\n", compaction_index); +- goto close_fd; +- } +- +- printf("No of huge pages allocated = %d\n", +- (atoi(nr_hugepages))); +- + lseek(fd, 0, SEEK_SET); + + if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) + != strlen(initial_nr_hugepages)) { +- perror("Failed to write value to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +- close(fd); +- return 0; ++ if (compaction_index > 3) { ++ ksft_print_msg("ERROR: Less that 1/%d of memory is available\n" ++ "as huge pages\n", compaction_index); ++ ksft_test_result_fail("No of huge pages allocated = %d\n", (atoi(nr_hugepages))); ++ goto close_fd; ++ } ++ ++ ksft_test_result_pass("Memory compaction succeeded. No of huge pages allocated = %d\n", ++ (atoi(nr_hugepages))); ++ ret = 0; + + close_fd: + close(fd); +- printf("Not OK. Compaction test failed."); +- return -1; ++ return ret; + } + + + int main(int argc, char **argv) + { + struct rlimit lim; +- struct map_list *list, *entry; ++ struct map_list *list = NULL, *entry; + size_t page_size, i; + void *map = NULL; + unsigned long mem_free = 0; + unsigned long hugepage_size = 0; + long mem_fragmentable_MB = 0; + +- if (prereq() != 0) { +- printf("Either the sysctl compact_unevictable_allowed is not\n" +- "set to 1 or couldn't read the proc file.\n" +- "Skipping the test\n"); +- return KSFT_SKIP; +- } ++ ksft_print_header(); ++ ++ if (prereq() != 0) ++ return ksft_exit_pass(); ++ ++ ksft_set_plan(1); + + lim.rlim_cur = RLIM_INFINITY; + lim.rlim_max = RLIM_INFINITY; +- if (setrlimit(RLIMIT_MEMLOCK, &lim)) { +- perror("Failed to set rlimit:\n"); +- return -1; +- } ++ if (setrlimit(RLIMIT_MEMLOCK, &lim)) ++ ksft_exit_fail_msg("Failed to set rlimit: %s\n", strerror(errno)); + + page_size = getpagesize(); + +- list = NULL; +- +- if (read_memory_info(&mem_free, &hugepage_size) != 0) { +- printf("ERROR: Cannot read meminfo\n"); +- return -1; +- } ++ if (read_memory_info(&mem_free, &hugepage_size) != 0) ++ ksft_exit_fail_msg("Failed to get meminfo\n"); + + mem_fragmentable_MB = mem_free * 0.8 / 1024; + +@@ -227,7 +224,7 @@ int main(int argc, char **argv) + } + + if (check_compaction(mem_free, hugepage_size) == 0) +- return 0; ++ return ksft_exit_pass(); + +- return -1; ++ return ksft_exit_fail(); + } +-- +2.43.0 + diff --git a/queue-6.1/selftests-mm-log-a-consistent-test-name-for-check_co.patch b/queue-6.1/selftests-mm-log-a-consistent-test-name-for-check_co.patch new file mode 100644 index 00000000000..da40b4d8622 --- /dev/null +++ b/queue-6.1/selftests-mm-log-a-consistent-test-name-for-check_co.patch @@ -0,0 +1,124 @@ +From eae947d0d189223575ad473d0168670ed27dd8b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Feb 2024 14:30:04 +0000 +Subject: selftests/mm: log a consistent test name for check_compaction + +From: Mark Brown + +[ Upstream commit f3b7568c49420d2dcd251032c9ca1e069ec8a6c9 ] + +Every test result report in the compaction test prints a distinct log +messae, and some of the reports print a name that varies at runtime. This +causes problems for automation since a lot of automation software uses the +printed string as the name of the test, if the name varies from run to run +and from pass to fail then the automation software can't identify that a +test changed result or that the same tests are being run. + +Refactor the logging to use a consistent name when printing the result of +the test, printing the existing messages as diagnostic information instead +so they are still available for people trying to interpret the results. + +Link: https://lkml.kernel.org/r/20240209-kselftest-mm-cleanup-v1-2-a3c0386496b5@kernel.org +Signed-off-by: Mark Brown +Cc: Muhammad Usama Anjum +Cc: Ryan Roberts +Cc: Shuah Khan +Signed-off-by: Andrew Morton +Stable-dep-of: d4202e66a4b1 ("selftests/mm: compaction_test: fix bogus test success on Aarch64") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/compaction_test.c | 35 +++++++++++--------- + 1 file changed, 19 insertions(+), 16 deletions(-) + +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index f81931c1f8386..6aa6460b854ea 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -95,14 +95,15 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK); + if (fd < 0) { +- ksft_test_result_fail("Failed to open /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); +- return -1; ++ ksft_print_msg("Failed to open /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); ++ ret = -1; ++ goto out; + } + + if (read(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) <= 0) { +- ksft_test_result_fail("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -110,8 +111,8 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + /* Start with the initial condition of 0 huge pages*/ + if (write(fd, "0", sizeof(char)) != sizeof(char)) { +- ksft_test_result_fail("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -120,16 +121,16 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + /* Request a large number of huge pages. The Kernel will allocate + as much as it can */ + if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { +- ksft_test_result_fail("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + + lseek(fd, 0, SEEK_SET); + + if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { +- ksft_test_result_fail("Failed to re-read from /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to re-read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -141,24 +142,26 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) + != strlen(initial_nr_hugepages)) { +- ksft_test_result_fail("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n", +- strerror(errno)); ++ ksft_print_msg("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + ++ ksft_print_msg("Number of huge pages allocated = %d\n", ++ atoi(nr_hugepages)); ++ + if (compaction_index > 3) { + ksft_print_msg("ERROR: Less that 1/%d of memory is available\n" + "as huge pages\n", compaction_index); +- ksft_test_result_fail("No of huge pages allocated = %d\n", (atoi(nr_hugepages))); + goto close_fd; + } + +- ksft_test_result_pass("Memory compaction succeeded. No of huge pages allocated = %d\n", +- (atoi(nr_hugepages))); + ret = 0; + + close_fd: + close(fd); ++ out: ++ ksft_test_result(ret == 0, "check_compaction\n"); + return ret; + } + +-- +2.43.0 + diff --git a/queue-6.1/serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch b/queue-6.1/serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch new file mode 100644 index 00000000000..004c6e1254d --- /dev/null +++ b/queue-6.1/serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch @@ -0,0 +1,96 @@ +From ae484c97448fb7df665e32b00dc096f202514e82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 16:04:30 -0400 +Subject: serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using + prescaler + +From: Hugo Villeneuve + +[ Upstream commit 8492bd91aa055907c67ef04f2b56f6dadd1f44bf ] + +When using a high speed clock with a low baud rate, the 4x prescaler is +automatically selected if required. In that case, sc16is7xx_set_baud() +properly configures the chip registers, but returns an incorrect baud +rate by not taking into account the prescaler value. This incorrect baud +rate is then fed to uart_update_timeout(). + +For example, with an input clock of 80MHz, and a selected baud rate of 50, +sc16is7xx_set_baud() will return 200 instead of 50. + +Fix this by first changing the prescaler variable to hold the selected +prescaler value instead of the MCR bitfield. Then properly take into +account the selected prescaler value in the return value computation. + +Also add better documentation about the divisor value computation. + +Fixes: dfeae619d781 ("serial: sc16is7xx") +Cc: stable@vger.kernel.org +Signed-off-by: Hugo Villeneuve +Reviewed-by: Jiri Slaby +Link: https://lore.kernel.org/r/20240430200431.4102923-1-hugo@hugovil.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/sc16is7xx.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index 08da7cc221d0e..a723df9b37dd9 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -482,16 +482,28 @@ static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg) + return reg == SC16IS7XX_RHR_REG; + } + ++/* ++ * Configure programmable baud rate generator (divisor) according to the ++ * desired baud rate. ++ * ++ * From the datasheet, the divisor is computed according to: ++ * ++ * XTAL1 input frequency ++ * ----------------------- ++ * prescaler ++ * divisor = --------------------------- ++ * baud-rate x sampling-rate ++ */ + static int sc16is7xx_set_baud(struct uart_port *port, int baud) + { + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); + u8 lcr; +- u8 prescaler = 0; ++ unsigned int prescaler = 1; + unsigned long clk = port->uartclk, div = clk / 16 / baud; + + if (div >= BIT(16)) { +- prescaler = SC16IS7XX_MCR_CLKSEL_BIT; +- div /= 4; ++ prescaler = 4; ++ div /= prescaler; + } + + /* In an amazing feat of design, the Enhanced Features Register shares +@@ -528,9 +540,10 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) + + mutex_unlock(&one->efr_lock); + ++ /* If bit MCR_CLKSEL is set, the divide by 4 prescaler is activated. */ + sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, + SC16IS7XX_MCR_CLKSEL_BIT, +- prescaler); ++ prescaler == 1 ? 0 : SC16IS7XX_MCR_CLKSEL_BIT); + + /* Open the LCR divisors for configuration */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, +@@ -545,7 +558,7 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) + /* Put LCR back to the normal mode */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); + +- return DIV_ROUND_CLOSEST(clk / 16, div); ++ return DIV_ROUND_CLOSEST((clk / prescaler) / 16, div); + } + + static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen, +-- +2.43.0 + diff --git a/queue-6.1/serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch b/queue-6.1/serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch new file mode 100644 index 00000000000..840989fd2a9 --- /dev/null +++ b/queue-6.1/serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch @@ -0,0 +1,39 @@ +From bcfbe26036f7e2f68ad815eb9e4c3f577c1231de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Dec 2023 18:18:19 -0500 +Subject: serial: sc16is7xx: replace hardcoded divisor value with BIT() macro + +From: Hugo Villeneuve + +[ Upstream commit 2e57cefc4477659527f7adab1f87cdbf60ef1ae6 ] + +To better show why the limit is what it is, since we have only 16 bits for +the divisor. + +Reviewed-by: Andy Shevchenko +Suggested-by: Andy Shevchenko +Signed-off-by: Hugo Villeneuve +Link: https://lore.kernel.org/r/20231221231823.2327894-13-hugo@hugovil.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 8492bd91aa05 ("serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler") +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/sc16is7xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index e6eedebf67765..08da7cc221d0e 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -489,7 +489,7 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) + u8 prescaler = 0; + unsigned long clk = port->uartclk, div = clk / 16 / baud; + +- if (div > 0xffff) { ++ if (div >= BIT(16)) { + prescaler = SC16IS7XX_MCR_CLKSEL_BIT; + div /= 4; + } +-- +2.43.0 + diff --git a/queue-6.1/series b/queue-6.1/series index e93200a7b46..681f60d2fb7 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -84,3 +84,89 @@ btrfs-fix-crash-on-racing-fsync-and-size-extending-write-into-prealloc.patch powerpc-bpf-enforce-full-ordering-for-atomic-operations-with-bpf_fetch.patch smb-client-fix-deadlock-in-smb2_find_smb_tcon.patch smp-provide-setup_max_cpus-definition-on-up-too.patch +wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch +wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch +wifi-cfg80211-fully-move-wiphy-work-to-unbound-workq.patch +wifi-cfg80211-lock-wiphy-in-cfg80211_get_station.patch +wifi-cfg80211-pmsr-use-correct-nla_get_ux-functions.patch +wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch +wifi-iwlwifi-dbg_ini-move-iwl_dbg_tlv_free-outside-o.patch +wifi-iwlwifi-mvm-check-n_ssids-before-accessing-the-.patch +wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch +wifi-mac80211-correctly-parse-spatial-reuse-paramete.patch +ax25-fix-refcount-imbalance-on-inbound-connections.patch +ax25-replace-kfree-in-ax25_dev_free-with-ax25_dev_pu.patch +net-ncsi-simplify-kconfig-dts-control-flow.patch +net-ncsi-fix-the-multi-thread-manner-of-ncsi-driver.patch +ipv6-ioam-block-bh-from-ioam6_output.patch +ipv6-sr-block-bh-in-seg6_output_core-and-seg6_input_.patch +bpf-set-run-context-for-rawtp-test_run-callback.patch +octeontx2-af-always-allocate-pf-entries-from-low-pri.patch +net-smc-avoid-overwriting-when-adjusting-sock-bufsiz.patch +net-sched-sch_multiq-fix-possible-oob-write-in-multi.patch +vxlan-fix-regression-when-dropping-packets-due-to-in.patch +tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch +net-mlx5-stop-waiting-for-pci-up-if-teardown-was-tri.patch +net-mlx5-stop-waiting-for-pci-if-pci-channel-is-offl.patch +net-mlx5-split-function_setup-to-enable-and-open-fun.patch +net-mlx5-always-stop-health-timer-during-driver-remo.patch +net-mlx5-fix-tainted-pointer-delete-is-case-of-flow-.patch +net-sched-taprio-always-validate-tca_taprio_attr_pri.patch +ptp-fix-error-message-on-failed-pin-verification.patch +ice-fix-iteration-of-tlvs-in-preserved-fields-area.patch +ice-introduce-new-parameters-in-ice_sched_node.patch +ice-remove-null-checks-before-devm_kfree-calls.patch +ice-remove-af_xdp_zc_qps-bitmap.patch +net-wwan-iosm-fix-tainted-pointer-delete-is-case-of-.patch +af_unix-set-sk-sk_state-under-unix_state_lock-for-tr.patch +af_unix-annodate-data-races-around-sk-sk_state-for-w.patch +af_unix-annotate-data-race-of-sk-sk_state-in-unix_in.patch +af_unix-annotate-data-races-around-sk-sk_state-in-un.patch +af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch +af_unix-annotate-data-races-around-sk-sk_state-in-se.patch +af_unix-annotate-data-race-of-sk-sk_state-in-unix_st.patch-1419 +af_unix-annotate-data-races-around-sk-sk_state-in-un.patch-22249 +af_unix-annotate-data-race-of-net-unx.sysctl_max_dgr.patch +af_unix-use-unix_recvq_full_lockless-in-unix_stream_.patch +af_unix-annotate-lockless-accesses-to-sk-sk_err.patch +af_unix-use-skb_queue_empty_lockless-in-unix_release.patch +af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch +af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch +ipv6-fix-possible-race-in-__fib6_drop_pcpu_from.patch +kbuild-rust-force-alloc-extern-to-allow-empty-rust-f.patch +bluetooth-qca-fix-invalid-device-address-check.patch +btrfs-fix-wrong-block_start-calculation-for-btrfs_dr.patch +usb-gadget-f_fs-use-io_data-status-consistently.patch +usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch +iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch +iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch +xtensa-stacktrace-include-asm-ftrace.h-for-prototype.patch +xtensa-fix-make_pc_from_ra-second-argument.patch +drm-amd-display-drop-unnecessary-null-checks-in-debu.patch +drm-amd-display-fix-incorrect-dsc-instance-for-mst.patch +arm64-dts-qcom-sm8150-align-tlmm-pin-configuration-w.patch +arm64-dts-qcom-sa8155p-adp-fix-sdhc2-cd-pin-configur.patch +misc-pvpanic-deduplicate-common-code.patch +misc-pvpanic-pci-register-attributes-via-pci_driver.patch +serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch +serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch +mmc-davinci-don-t-strip-remove-function-when-driver-.patch +firmware-qcom_scm-disable-clocks-if-qcom_scm_bw_enab.patch +hid-i2c-hid-elan-add-ili9882t-timing.patch +hid-i2c-hid-elan-fix-reset-suspend-current-leakage.patch +i2c-add-fwnode-apis.patch +i2c-acpi-unbind-mux-adapters-before-delete.patch +mm-vmalloc-fix-high-order-__gfp_nofail-allocations.patch +mm-vmalloc-fix-vmalloc-which-may-return-null-if-call.patch +selftests-mm-compaction_test-fix-incorrect-write-of-.patch +selftests-mm-conform-test-to-tap-format-output.patch +selftests-mm-log-a-consistent-test-name-for-check_co.patch +selftests-mm-compaction_test-fix-bogus-test-success-.patch +wifi-ath10k-store-wlan-firmware-version-in-smem-imag.patch +wifi-ath10k-fix-qcom_smem-dependency.patch +wifi-ath10k-fix-qcom_rproc_common-dependency.patch +btrfs-remove-unnecessary-prototype-declarations-at-d.patch +btrfs-make-btrfs_destroy_delayed_refs-return-void.patch +btrfs-fix-leak-of-qgroup-extent-records-after-transa.patch +nilfs2-return-the-mapped-address-from-nilfs_get_page.patch +nilfs2-fix-nilfs_empty_dir-misjudgment-and-long-loop.patch diff --git a/queue-6.1/tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch b/queue-6.1/tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch new file mode 100644 index 00000000000..8b86d0812ee --- /dev/null +++ b/queue-6.1/tcp-count-close-wait-sockets-for-tcp_mib_currestab.patch @@ -0,0 +1,71 @@ +From 2a240a9ca1e69221439f1aa37862299c9dd8cf44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 01:02:16 +0800 +Subject: tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB + +From: Jason Xing + +[ Upstream commit a46d0ea5c94205f40ecf912d1bb7806a8a64704f ] + +According to RFC 1213, we should also take CLOSE-WAIT sockets into +consideration: + + "tcpCurrEstab OBJECT-TYPE + ... + The number of TCP connections for which the current state + is either ESTABLISHED or CLOSE- WAIT." + +After this, CurrEstab counter will display the total number of +ESTABLISHED and CLOSE-WAIT sockets. + +The logic of counting +When we increment the counter? +a) if we change the state to ESTABLISHED. +b) if we change the state from SYN-RECEIVED to CLOSE-WAIT. + +When we decrement the counter? +a) if the socket leaves ESTABLISHED and will never go into CLOSE-WAIT, +say, on the client side, changing from ESTABLISHED to FIN-WAIT-1. +b) if the socket leaves CLOSE-WAIT, say, on the server side, changing +from CLOSE-WAIT to LAST-ACK. + +Please note: there are two chances that old state of socket can be changed +to CLOSE-WAIT in tcp_fin(). One is SYN-RECV, the other is ESTABLISHED. +So we have to take care of the former case. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Jason Xing +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 3447a09ee83a2..2d4f697d338f5 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2758,6 +2758,10 @@ void tcp_set_state(struct sock *sk, int state) + if (oldstate != TCP_ESTABLISHED) + TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); + break; ++ case TCP_CLOSE_WAIT: ++ if (oldstate == TCP_SYN_RECV) ++ TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); ++ break; + + case TCP_CLOSE: + if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED) +@@ -2769,7 +2773,7 @@ void tcp_set_state(struct sock *sk, int state) + inet_put_port(sk); + fallthrough; + default: +- if (oldstate == TCP_ESTABLISHED) ++ if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT) + TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); + } + +-- +2.43.0 + diff --git a/queue-6.1/usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch b/queue-6.1/usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch new file mode 100644 index 00000000000..134bcd80b8f --- /dev/null +++ b/queue-6.1/usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch @@ -0,0 +1,95 @@ +From 57dfa6e90d8993c888fbff383a10be3f9980e1ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Apr 2024 18:40:59 -0700 +Subject: usb: gadget: f_fs: Fix race between aio_cancel() and AIO request + complete + +From: Wesley Cheng + +[ Upstream commit 24729b307eefcd7c476065cd7351c1a018082c19 ] + +FFS based applications can utilize the aio_cancel() callback to dequeue +pending USB requests submitted to the UDC. There is a scenario where the +FFS application issues an AIO cancel call, while the UDC is handling a +soft disconnect. For a DWC3 based implementation, the callstack looks +like the following: + + DWC3 Gadget FFS Application +dwc3_gadget_soft_disconnect() ... + --> dwc3_stop_active_transfers() + --> dwc3_gadget_giveback(-ESHUTDOWN) + --> ffs_epfile_async_io_complete() ffs_aio_cancel() + --> usb_ep_free_request() --> usb_ep_dequeue() + +There is currently no locking implemented between the AIO completion +handler and AIO cancel, so the issue occurs if the completion routine is +running in parallel to an AIO cancel call coming from the FFS application. +As the completion call frees the USB request (io_data->req) the FFS +application is also referencing it for the usb_ep_dequeue() call. This can +lead to accessing a stale/hanging pointer. + +commit b566d38857fc ("usb: gadget: f_fs: use io_data->status consistently") +relocated the usb_ep_free_request() into ffs_epfile_async_io_complete(). +However, in order to properly implement locking to mitigate this issue, the +spinlock can't be added to ffs_epfile_async_io_complete(), as +usb_ep_dequeue() (if successfully dequeuing a USB request) will call the +function driver's completion handler in the same context. Hence, leading +into a deadlock. + +Fix this issue by moving the usb_ep_free_request() back to +ffs_user_copy_worker(), and ensuring that it explicitly sets io_data->req +to NULL after freeing it within the ffs->eps_lock. This resolves the race +condition above, as the ffs_aio_cancel() routine will not continue +attempting to dequeue a request that has already been freed, or the +ffs_user_copy_work() not freeing the USB request until the AIO cancel is +done referencing it. + +This fix depends on + commit b566d38857fc ("usb: gadget: f_fs: use io_data->status + consistently") + +Fixes: 2e4c7553cd6f ("usb: gadget: f_fs: add aio support") +Cc: stable # b566d38857fc ("usb: gadget: f_fs: use io_data->status consistently") +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/20240409014059.6740-1-quic_wcheng@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/function/f_fs.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index d32e1ece3e0a1..698bf24ba44c7 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -832,6 +832,7 @@ static void ffs_user_copy_worker(struct work_struct *work) + work); + int ret = io_data->status; + bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD; ++ unsigned long flags; + + if (io_data->read && ret > 0) { + kthread_use_mm(io_data->mm); +@@ -844,6 +845,11 @@ static void ffs_user_copy_worker(struct work_struct *work) + if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd) + eventfd_signal(io_data->ffs->ffs_eventfd, 1); + ++ spin_lock_irqsave(&io_data->ffs->eps_lock, flags); ++ usb_ep_free_request(io_data->ep, io_data->req); ++ io_data->req = NULL; ++ spin_unlock_irqrestore(&io_data->ffs->eps_lock, flags); ++ + if (io_data->read) + kfree(io_data->to_free); + ffs_free_buffer(io_data); +@@ -859,7 +865,6 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep, + ENTER(); + + io_data->status = req->status ? req->status : req->actual; +- usb_ep_free_request(_ep, req); + + INIT_WORK(&io_data->work, ffs_user_copy_worker); + queue_work(ffs->io_completion_wq, &io_data->work); +-- +2.43.0 + diff --git a/queue-6.1/usb-gadget-f_fs-use-io_data-status-consistently.patch b/queue-6.1/usb-gadget-f_fs-use-io_data-status-consistently.patch new file mode 100644 index 00000000000..6f3c8894df0 --- /dev/null +++ b/queue-6.1/usb-gadget-f_fs-use-io_data-status-consistently.patch @@ -0,0 +1,65 @@ +From a91ef6a9b9ee75c5a08076b05f4e58795588b63c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Nov 2022 17:04:28 +0000 +Subject: usb: gadget: f_fs: use io_data->status consistently + +From: John Keeping + +[ Upstream commit b566d38857fcb6777f25b674b90a831eec0817a2 ] + +Commit fb1f16d74e26 ("usb: gadget: f_fs: change ep->status safe in +ffs_epfile_io()") added a new ffs_io_data::status field to fix lifetime +issues in synchronous requests. + +While there are no similar lifetime issues for asynchronous requests +(the separate ep member in ffs_io_data avoids them) using the status +field means the USB request can be freed earlier and that there is more +consistency between the synchronous and asynchronous I/O paths. + +Cc: Linyu Yuan +Signed-off-by: John Keeping +Reviewed-by: Linyu Yuan +Link: https://lore.kernel.org/r/20221124170430.3998755-1-john@metanate.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 24729b307eef ("usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete") +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/function/f_fs.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index b2da74bb107af..d32e1ece3e0a1 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -830,8 +830,7 @@ static void ffs_user_copy_worker(struct work_struct *work) + { + struct ffs_io_data *io_data = container_of(work, struct ffs_io_data, + work); +- int ret = io_data->req->status ? io_data->req->status : +- io_data->req->actual; ++ int ret = io_data->status; + bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD; + + if (io_data->read && ret > 0) { +@@ -845,8 +844,6 @@ static void ffs_user_copy_worker(struct work_struct *work) + if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd) + eventfd_signal(io_data->ffs->ffs_eventfd, 1); + +- usb_ep_free_request(io_data->ep, io_data->req); +- + if (io_data->read) + kfree(io_data->to_free); + ffs_free_buffer(io_data); +@@ -861,6 +858,9 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep, + + ENTER(); + ++ io_data->status = req->status ? req->status : req->actual; ++ usb_ep_free_request(_ep, req); ++ + INIT_WORK(&io_data->work, ffs_user_copy_worker); + queue_work(ffs->io_completion_wq, &io_data->work); + } +-- +2.43.0 + diff --git a/queue-6.1/vxlan-fix-regression-when-dropping-packets-due-to-in.patch b/queue-6.1/vxlan-fix-regression-when-dropping-packets-due-to-in.patch new file mode 100644 index 00000000000..9ae91ef110f --- /dev/null +++ b/queue-6.1/vxlan-fix-regression-when-dropping-packets-due-to-in.patch @@ -0,0 +1,65 @@ +From fc598c721a1378d50bf16ac4207d791d53e06e8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 10:59:26 +0200 +Subject: vxlan: Fix regression when dropping packets due to invalid src + addresses + +From: Daniel Borkmann + +[ Upstream commit 1cd4bc987abb2823836cbb8f887026011ccddc8a ] + +Commit f58f45c1e5b9 ("vxlan: drop packets from invalid src-address") +has recently been added to vxlan mainly in the context of source +address snooping/learning so that when it is enabled, an entry in the +FDB is not being created for an invalid address for the corresponding +tunnel endpoint. + +Before commit f58f45c1e5b9 vxlan was similarly behaving as geneve in +that it passed through whichever macs were set in the L2 header. It +turns out that this change in behavior breaks setups, for example, +Cilium with netkit in L3 mode for Pods as well as tunnel mode has been +passing before the change in f58f45c1e5b9 for both vxlan and geneve. +After mentioned change it is only passing for geneve as in case of +vxlan packets are dropped due to vxlan_set_mac() returning false as +source and destination macs are zero which for E/W traffic via tunnel +is totally fine. + +Fix it by only opting into the is_valid_ether_addr() check in +vxlan_set_mac() when in fact source address snooping/learning is +actually enabled in vxlan. This is done by moving the check into +vxlan_snoop(). With this change, the Cilium connectivity test suite +passes again for both tunnel flavors. + +Fixes: f58f45c1e5b9 ("vxlan: drop packets from invalid src-address") +Signed-off-by: Daniel Borkmann +Cc: David Bauer +Cc: Ido Schimmel +Cc: Nikolay Aleksandrov +Cc: Martin KaFai Lau +Reviewed-by: Ido Schimmel +Reviewed-by: Nikolay Aleksandrov +Reviewed-by: David Bauer +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan/vxlan_core.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index a7ae68f490c4c..61224a5a877cb 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -1493,6 +1493,10 @@ static bool vxlan_snoop(struct net_device *dev, + struct vxlan_fdb *f; + u32 ifindex = 0; + ++ /* Ignore packets from invalid src-address */ ++ if (!is_valid_ether_addr(src_mac)) ++ return true; ++ + #if IS_ENABLED(CONFIG_IPV6) + if (src_ip->sa.sa_family == AF_INET6 && + (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)) +-- +2.43.0 + diff --git a/queue-6.1/wifi-ath10k-fix-qcom_rproc_common-dependency.patch b/queue-6.1/wifi-ath10k-fix-qcom_rproc_common-dependency.patch new file mode 100644 index 00000000000..0d3f181db77 --- /dev/null +++ b/queue-6.1/wifi-ath10k-fix-qcom_rproc_common-dependency.patch @@ -0,0 +1,45 @@ +From 62297443537543f8fa7f0ef8fcd226f3f23375a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 May 2024 10:00:28 +0300 +Subject: wifi: ath10k: fix QCOM_RPROC_COMMON dependency + +From: Dmitry Baryshkov + +[ Upstream commit 21ae74e1bf18331ae5e279bd96304b3630828009 ] + +If ath10k_snoc is built-in, while Qualcomm remoteprocs are built as +modules, compilation fails with: + +/usr/bin/aarch64-linux-gnu-ld: drivers/net/wireless/ath/ath10k/snoc.o: in function `ath10k_modem_init': +drivers/net/wireless/ath/ath10k/snoc.c:1534: undefined reference to `qcom_register_ssr_notifier' +/usr/bin/aarch64-linux-gnu-ld: drivers/net/wireless/ath/ath10k/snoc.o: in function `ath10k_modem_deinit': +drivers/net/wireless/ath/ath10k/snoc.c:1551: undefined reference to `qcom_unregister_ssr_notifier' + +Add corresponding dependency to ATH10K_SNOC Kconfig entry so that it's +built as module if QCOM_RPROC_COMMON is built as module too. + +Fixes: 747ff7d3d742 ("ath10k: Don't always treat modem stop events as crashes") +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240511-ath10k-snoc-dep-v1-1-9666e3af5c27@linaro.org +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig +index e6ea884cafc19..4f385f4a8cef2 100644 +--- a/drivers/net/wireless/ath/ath10k/Kconfig ++++ b/drivers/net/wireless/ath/ath10k/Kconfig +@@ -45,6 +45,7 @@ config ATH10K_SNOC + depends on ATH10K + depends on ARCH_QCOM || COMPILE_TEST + depends on QCOM_SMEM ++ depends on QCOM_RPROC_COMMON || QCOM_RPROC_COMMON=n + select QCOM_SCM + select QCOM_QMI_HELPERS + help +-- +2.43.0 + diff --git a/queue-6.1/wifi-ath10k-fix-qcom_smem-dependency.patch b/queue-6.1/wifi-ath10k-fix-qcom_smem-dependency.patch new file mode 100644 index 00000000000..90df438939e --- /dev/null +++ b/queue-6.1/wifi-ath10k-fix-qcom_smem-dependency.patch @@ -0,0 +1,47 @@ +From 8c32056d242ffa412783887f8c1842919612b0c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Dec 2022 12:30:27 +0200 +Subject: wifi: ath10k: fix QCOM_SMEM dependency + +From: Kalle Valo + +[ Upstream commit d03407183d97554dfffea70f385b5bdd520f846c ] + +Nathan noticed that when HWSPINLOCK is disabled there's a Kconfig warning: + + WARNING: unmet direct dependencies detected for QCOM_SMEM + Depends on [n]: (ARCH_QCOM [=y] || COMPILE_TEST [=n]) && HWSPINLOCK [=n] + Selected by [m]: + - ATH10K_SNOC [=m] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_ATH [=y] && ATH10K [=m] && (ARCH_QCOM [=y] || COMPILE_TEST [=n]) + +The problem here is that QCOM_SMEM depends on HWSPINLOCK so we cannot select +QCOM_SMEM and instead we neeed to use 'depends on'. + +Reported-by: Nathan Chancellor +Link: https://lore.kernel.org/all/Y4YsyaIW+CPdHWv3@dev-arch.thelio-3990X/ +Fixes: 4d79f6f34bbb ("wifi: ath10k: Store WLAN firmware version in SMEM image table") +Signed-off-by: Kalle Valo +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20221202103027.25974-1-kvalo@kernel.org +Stable-dep-of: 21ae74e1bf18 ("wifi: ath10k: fix QCOM_RPROC_COMMON dependency") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig +index e0a51dad8e420..e6ea884cafc19 100644 +--- a/drivers/net/wireless/ath/ath10k/Kconfig ++++ b/drivers/net/wireless/ath/ath10k/Kconfig +@@ -44,7 +44,7 @@ config ATH10K_SNOC + tristate "Qualcomm ath10k SNOC support" + depends on ATH10K + depends on ARCH_QCOM || COMPILE_TEST +- select QCOM_SMEM ++ depends on QCOM_SMEM + select QCOM_SCM + select QCOM_QMI_HELPERS + help +-- +2.43.0 + diff --git a/queue-6.1/wifi-ath10k-store-wlan-firmware-version-in-smem-imag.patch b/queue-6.1/wifi-ath10k-store-wlan-firmware-version-in-smem-imag.patch new file mode 100644 index 00000000000..e7e2291ec1d --- /dev/null +++ b/queue-6.1/wifi-ath10k-store-wlan-firmware-version-in-smem-imag.patch @@ -0,0 +1,123 @@ +From 8fbb44c360d4ec3a85f36e55ab9c05309c7c30eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 23:35:34 +0530 +Subject: wifi: ath10k: Store WLAN firmware version in SMEM image table + +From: Youghandhar Chintala + +[ Upstream commit 4d79f6f34bbb01c6715b31ef457d5ab0390501a1 ] + +In a SoC based solution, it would be useful to know the versions of the +various binary firmware blobs the system is running on. On a QCOM based +SoC, this info can be obtained from socinfo debugfs infrastructure. For +this to work, respective subsystem drivers have to export the firmware +version information to an SMEM based version information table. + +Having firmware version information at one place will help quickly +figure out the firmware versions of various subsystems on the device +instead of going through builds/logs in an event of a system crash. + +Fill WLAN firmware version information in SMEM version table to be +printed as part of socinfo debugfs infrastructure on a Qualcomm based +SoC. + +This change is applicable only for SNOC/QMI based targets. + +Example: +cat /sys/kernel/debug/qcom_socinfo/cnss/name +QC_IMAGE_VERSION_STRING=WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1 + +Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1 + +Signed-off-by: Youghandhar Chintala +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20221117180534.2267-1-quic_youghand@quicinc.com +Stable-dep-of: 21ae74e1bf18 ("wifi: ath10k: fix QCOM_RPROC_COMMON dependency") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/Kconfig | 1 + + drivers/net/wireless/ath/ath10k/qmi.c | 35 +++++++++++++++++++++++++ + 2 files changed, 36 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig +index ca007b800f756..e0a51dad8e420 100644 +--- a/drivers/net/wireless/ath/ath10k/Kconfig ++++ b/drivers/net/wireless/ath/ath10k/Kconfig +@@ -44,6 +44,7 @@ config ATH10K_SNOC + tristate "Qualcomm ath10k SNOC support" + depends on ATH10K + depends on ARCH_QCOM || COMPILE_TEST ++ select QCOM_SMEM + select QCOM_SCM + select QCOM_QMI_HELPERS + help +diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c +index 66cb7a1e628a4..cdcb162f93c2b 100644 +--- a/drivers/net/wireless/ath/ath10k/qmi.c ++++ b/drivers/net/wireless/ath/ath10k/qmi.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -22,6 +23,10 @@ + + #define ATH10K_QMI_CLIENT_ID 0x4b4e454c + #define ATH10K_QMI_TIMEOUT 30 ++#define SMEM_IMAGE_VERSION_TABLE 469 ++#define SMEM_IMAGE_TABLE_CNSS_INDEX 13 ++#define SMEM_IMAGE_VERSION_ENTRY_SIZE 128 ++#define SMEM_IMAGE_VERSION_NAME_SIZE 75 + + static int ath10k_qmi_map_msa_permission(struct ath10k_qmi *qmi, + struct ath10k_msa_mem_info *mem_info) +@@ -536,6 +541,33 @@ int ath10k_qmi_wlan_disable(struct ath10k *ar) + return ath10k_qmi_mode_send_sync_msg(ar, QMI_WLFW_OFF_V01); + } + ++static void ath10k_qmi_add_wlan_ver_smem(struct ath10k *ar, const char *fw_build_id) ++{ ++ u8 *table_ptr; ++ size_t smem_item_size; ++ const u32 smem_img_idx_wlan = SMEM_IMAGE_TABLE_CNSS_INDEX * ++ SMEM_IMAGE_VERSION_ENTRY_SIZE; ++ ++ table_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY, ++ SMEM_IMAGE_VERSION_TABLE, ++ &smem_item_size); ++ ++ if (IS_ERR(table_ptr)) { ++ ath10k_err(ar, "smem image version table not found\n"); ++ return; ++ } ++ ++ if (smem_img_idx_wlan + SMEM_IMAGE_VERSION_ENTRY_SIZE > ++ smem_item_size) { ++ ath10k_err(ar, "smem block size too small: %zu\n", ++ smem_item_size); ++ return; ++ } ++ ++ strscpy(table_ptr + smem_img_idx_wlan, fw_build_id, ++ SMEM_IMAGE_VERSION_NAME_SIZE); ++} ++ + static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi) + { + struct wlfw_cap_resp_msg_v01 *resp; +@@ -606,6 +638,9 @@ static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi) + qmi->fw_version, qmi->fw_build_timestamp, qmi->fw_build_id); + } + ++ if (resp->fw_build_id_valid) ++ ath10k_qmi_add_wlan_ver_smem(ar, qmi->fw_build_id); ++ + kfree(resp); + return 0; + +-- +2.43.0 + diff --git a/queue-6.1/wifi-cfg80211-fully-move-wiphy-work-to-unbound-workq.patch b/queue-6.1/wifi-cfg80211-fully-move-wiphy-work-to-unbound-workq.patch new file mode 100644 index 00000000000..f6557348eff --- /dev/null +++ b/queue-6.1/wifi-cfg80211-fully-move-wiphy-work-to-unbound-workq.patch @@ -0,0 +1,62 @@ +From f11b1f293130f2b2a32b9908f6fd2d99fc38777e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 May 2024 12:41:25 +0200 +Subject: wifi: cfg80211: fully move wiphy work to unbound workqueue + +From: Johannes Berg + +[ Upstream commit e296c95eac655008d5a709b8cf54d0018da1c916 ] + +Previously I had moved the wiphy work to the unbound +system workqueue, but missed that when it restarts and +during resume it was still using the normal system +workqueue. Fix that. + +Fixes: 91d20ab9d9ca ("wifi: cfg80211: use system_unbound_wq for wiphy work") +Reviewed-by: Miriam Rachel Korenblit +Link: https://msgid.link/20240522124126.7ca959f2cbd3.I3e2a71ef445d167b84000ccf934ea245aef8d395@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/core.c | 2 +- + net/wireless/sysfs.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/net/wireless/core.c b/net/wireless/core.c +index 3fcddc8687ed4..22f67b64135d2 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -427,7 +427,7 @@ static void cfg80211_wiphy_work(struct work_struct *work) + if (wk) { + list_del_init(&wk->entry); + if (!list_empty(&rdev->wiphy_work_list)) +- schedule_work(work); ++ queue_work(system_unbound_wq, work); + spin_unlock_irq(&rdev->wiphy_work_lock); + + wk->func(&rdev->wiphy, wk); +diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c +index a88f338c61d31..17ccb9c6091e8 100644 +--- a/net/wireless/sysfs.c ++++ b/net/wireless/sysfs.c +@@ -5,7 +5,7 @@ + * + * Copyright 2005-2006 Jiri Benc + * Copyright 2006 Johannes Berg +- * Copyright (C) 2020-2021, 2023 Intel Corporation ++ * Copyright (C) 2020-2021, 2023-2024 Intel Corporation + */ + + #include +@@ -137,7 +137,7 @@ static int wiphy_resume(struct device *dev) + if (rdev->wiphy.registered && rdev->ops->resume) + ret = rdev_resume(rdev); + rdev->suspended = false; +- schedule_work(&rdev->wiphy_work); ++ queue_work(system_unbound_wq, &rdev->wiphy_work); + wiphy_unlock(&rdev->wiphy); + + if (ret) +-- +2.43.0 + diff --git a/queue-6.1/wifi-cfg80211-lock-wiphy-in-cfg80211_get_station.patch b/queue-6.1/wifi-cfg80211-lock-wiphy-in-cfg80211_get_station.patch new file mode 100644 index 00000000000..1d320662f98 --- /dev/null +++ b/queue-6.1/wifi-cfg80211-lock-wiphy-in-cfg80211_get_station.patch @@ -0,0 +1,103 @@ +From 37cd5e505e3284c44d3b93454bfa404c265f2478 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 May 2024 21:47:26 +0200 +Subject: wifi: cfg80211: Lock wiphy in cfg80211_get_station + +From: Remi Pommarel + +[ Upstream commit 642f89daa34567d02f312d03e41523a894906dae ] + +Wiphy should be locked before calling rdev_get_station() (see lockdep +assert in ieee80211_get_station()). + +This fixes the following kernel NULL dereference: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050 + Mem abort info: + ESR = 0x0000000096000006 + EC = 0x25: DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x06: level 2 translation fault + Data abort info: + ISV = 0, ISS = 0x00000006 + CM = 0, WnR = 0 + user pgtable: 4k pages, 48-bit VAs, pgdp=0000000003001000 + [0000000000000050] pgd=0800000002dca003, p4d=0800000002dca003, pud=08000000028e9003, pmd=0000000000000000 + Internal error: Oops: 0000000096000006 [#1] SMP + Modules linked in: netconsole dwc3_meson_g12a dwc3_of_simple dwc3 ip_gre gre ath10k_pci ath10k_core ath9k ath9k_common ath9k_hw ath + CPU: 0 PID: 1091 Comm: kworker/u8:0 Not tainted 6.4.0-02144-g565f9a3a7911-dirty #705 + Hardware name: RPT (r1) (DT) + Workqueue: bat_events batadv_v_elp_throughput_metric_update + pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : ath10k_sta_statistics+0x10/0x2dc [ath10k_core] + lr : sta_set_sinfo+0xcc/0xbd4 + sp : ffff000007b43ad0 + x29: ffff000007b43ad0 x28: ffff0000071fa900 x27: ffff00000294ca98 + x26: ffff000006830880 x25: ffff000006830880 x24: ffff00000294c000 + x23: 0000000000000001 x22: ffff000007b43c90 x21: ffff800008898acc + x20: ffff00000294c6e8 x19: ffff000007b43c90 x18: 0000000000000000 + x17: 445946354d552d78 x16: 62661f7200000000 x15: 57464f445946354d + x14: 0000000000000000 x13: 00000000000000e3 x12: d5f0acbcebea978e + x11: 00000000000000e3 x10: 000000010048fe41 x9 : 0000000000000000 + x8 : ffff000007b43d90 x7 : 000000007a1e2125 x6 : 0000000000000000 + x5 : ffff0000024e0900 x4 : ffff800000a0250c x3 : ffff000007b43c90 + x2 : ffff00000294ca98 x1 : ffff000006831920 x0 : 0000000000000000 + Call trace: + ath10k_sta_statistics+0x10/0x2dc [ath10k_core] + sta_set_sinfo+0xcc/0xbd4 + ieee80211_get_station+0x2c/0x44 + cfg80211_get_station+0x80/0x154 + batadv_v_elp_get_throughput+0x138/0x1fc + batadv_v_elp_throughput_metric_update+0x1c/0xa4 + process_one_work+0x1ec/0x414 + worker_thread+0x70/0x46c + kthread+0xdc/0xe0 + ret_from_fork+0x10/0x20 + Code: a9bb7bfd 910003fd a90153f3 f9411c40 (f9402814) + +This happens because STA has time to disconnect and reconnect before +batadv_v_elp_throughput_metric_update() delayed work gets scheduled. In +this situation, ath10k_sta_state() can be in the middle of resetting +arsta data when the work queue get chance to be scheduled and ends up +accessing it. Locking wiphy prevents that. + +Fixes: 7406353d43c8 ("cfg80211: implement cfg80211_get_station cfg80211 API") +Signed-off-by: Remi Pommarel +Reviewed-by: Nicolas Escande +Acked-by: Antonio Quartulli +Link: https://msgid.link/983b24a6a176e0800c01aedcd74480d9b551cb13.1716046653.git.repk@triplefau.lt +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/util.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index f433f3fdd9e94..73b3648e1b4c3 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -2202,6 +2202,7 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, + { + struct cfg80211_registered_device *rdev; + struct wireless_dev *wdev; ++ int ret; + + wdev = dev->ieee80211_ptr; + if (!wdev) +@@ -2213,7 +2214,11 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, + + memset(sinfo, 0, sizeof(*sinfo)); + +- return rdev_get_station(rdev, dev, mac_addr, sinfo); ++ wiphy_lock(&rdev->wiphy); ++ ret = rdev_get_station(rdev, dev, mac_addr, sinfo); ++ wiphy_unlock(&rdev->wiphy); ++ ++ return ret; + } + EXPORT_SYMBOL(cfg80211_get_station); + +-- +2.43.0 + diff --git a/queue-6.1/wifi-cfg80211-pmsr-use-correct-nla_get_ux-functions.patch b/queue-6.1/wifi-cfg80211-pmsr-use-correct-nla_get_ux-functions.patch new file mode 100644 index 00000000000..0719653fda7 --- /dev/null +++ b/queue-6.1/wifi-cfg80211-pmsr-use-correct-nla_get_ux-functions.patch @@ -0,0 +1,85 @@ +From 9ec9d28d2d13865d73c2975a52c9390919c73036 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 May 2024 15:50:59 +0800 +Subject: wifi: cfg80211: pmsr: use correct nla_get_uX functions + +From: Lin Ma + +[ Upstream commit ab904521f4de52fef4f179d2dfc1877645ef5f5c ] + +The commit 9bb7e0f24e7e ("cfg80211: add peer measurement with FTM +initiator API") defines four attributes NL80211_PMSR_FTM_REQ_ATTR_ +{NUM_BURSTS_EXP}/{BURST_PERIOD}/{BURST_DURATION}/{FTMS_PER_BURST} in +following ways. + +static const struct nla_policy +nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = { + ... + [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] = + NLA_POLICY_MAX(NLA_U8, 15), + [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 }, + [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] = + NLA_POLICY_MAX(NLA_U8, 15), + [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] = + NLA_POLICY_MAX(NLA_U8, 31), + ... +}; + +That is, those attributes are expected to be NLA_U8 and NLA_U16 types. +However, the consumers of these attributes in `pmsr_parse_ftm` blindly +all use `nla_get_u32`, which is incorrect and causes functionality issues +on little-endian platforms. Hence, fix them with the correct `nla_get_u8` +and `nla_get_u16` functions. + +Fixes: 9bb7e0f24e7e ("cfg80211: add peer measurement with FTM initiator API") +Signed-off-by: Lin Ma +Link: https://msgid.link/20240521075059.47999-1-linma@zju.edu.cn +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/pmsr.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c +index 2bc647720cda5..d26daa0370e71 100644 +--- a/net/wireless/pmsr.c ++++ b/net/wireless/pmsr.c +@@ -56,7 +56,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, + out->ftm.burst_period = 0; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]) + out->ftm.burst_period = +- nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]); ++ nla_get_u16(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]); + + out->ftm.asap = !!tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP]; + if (out->ftm.asap && !capa->ftm.asap) { +@@ -75,7 +75,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, + out->ftm.num_bursts_exp = 0; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]) + out->ftm.num_bursts_exp = +- nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]); ++ nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]); + + if (capa->ftm.max_bursts_exponent >= 0 && + out->ftm.num_bursts_exp > capa->ftm.max_bursts_exponent) { +@@ -88,7 +88,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, + out->ftm.burst_duration = 15; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]) + out->ftm.burst_duration = +- nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]); ++ nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]); + + out->ftm.ftms_per_burst = 0; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]) +@@ -107,7 +107,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, + out->ftm.ftmr_retries = 3; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]) + out->ftm.ftmr_retries = +- nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]); ++ nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]); + + out->ftm.request_lci = !!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI]; + if (out->ftm.request_lci && !capa->ftm.request_lci) { +-- +2.43.0 + diff --git a/queue-6.1/wifi-iwlwifi-dbg_ini-move-iwl_dbg_tlv_free-outside-o.patch b/queue-6.1/wifi-iwlwifi-dbg_ini-move-iwl_dbg_tlv_free-outside-o.patch new file mode 100644 index 00000000000..49fed3377bd --- /dev/null +++ b/queue-6.1/wifi-iwlwifi-dbg_ini-move-iwl_dbg_tlv_free-outside-o.patch @@ -0,0 +1,41 @@ +From 2d77a69c53567c38be5464668e4b5586728f3374 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 May 2024 17:06:39 +0300 +Subject: wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs + ifdef + +From: Shahar S Matityahu + +[ Upstream commit 87821b67dea87addbc4ab093ba752753b002176a ] + +The driver should call iwl_dbg_tlv_free even if debugfs is not defined +since ini mode does not depend on debugfs ifdef. + +Fixes: 68f6f492c4fa ("iwlwifi: trans: support loading ini TLVs from external file") +Signed-off-by: Shahar S Matityahu +Reviewed-by: Luciano Coelho +Signed-off-by: Miri Korenblit +Link: https://msgid.link/20240510170500.c8e3723f55b0.I5e805732b0be31ee6b83c642ec652a34e974ff10@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +index 5eba1a355f043..024c37062a60b 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +@@ -1750,8 +1750,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) + err_fw: + #ifdef CONFIG_IWLWIFI_DEBUGFS + debugfs_remove_recursive(drv->dbgfs_drv); +- iwl_dbg_tlv_free(drv->trans); + #endif ++ iwl_dbg_tlv_free(drv->trans); + kfree(drv); + err: + return ERR_PTR(ret); +-- +2.43.0 + diff --git a/queue-6.1/wifi-iwlwifi-mvm-check-n_ssids-before-accessing-the-.patch b/queue-6.1/wifi-iwlwifi-mvm-check-n_ssids-before-accessing-the-.patch new file mode 100644 index 00000000000..292eb27bf7d --- /dev/null +++ b/queue-6.1/wifi-iwlwifi-mvm-check-n_ssids-before-accessing-the-.patch @@ -0,0 +1,49 @@ +From c2c26adf87da474b1afb685023cb73df60aaa4f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 May 2024 13:27:12 +0300 +Subject: wifi: iwlwifi: mvm: check n_ssids before accessing the ssids + +From: Miri Korenblit + +[ Upstream commit 60d62757df30b74bf397a2847a6db7385c6ee281 ] + +In some versions of cfg80211, the ssids poinet might be a valid one even +though n_ssids is 0. Accessing the pointer in this case will cuase an +out-of-bound access. Fix this by checking n_ssids first. + +Fixes: c1a7515393e4 ("iwlwifi: mvm: add adaptive dwell support") +Signed-off-by: Miri Korenblit +Reviewed-by: Ilan Peer +Reviewed-by: Johannes Berg +Link: https://msgid.link/20240513132416.6e4d1762bf0d.I5a0e6cc8f02050a766db704d15594c61fe583d45@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +index b20d64dbba1ad..a7a29f1659ea6 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +@@ -1298,7 +1298,7 @@ static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm, + if (IWL_MVM_ADWELL_MAX_BUDGET) + cmd->v7.adwell_max_budget = + cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET); +- else if (params->ssids && params->ssids[0].ssid_len) ++ else if (params->n_ssids && params->ssids[0].ssid_len) + cmd->v7.adwell_max_budget = + cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN); + else +@@ -1400,7 +1400,7 @@ iwl_mvm_scan_umac_dwell_v11(struct iwl_mvm *mvm, + if (IWL_MVM_ADWELL_MAX_BUDGET) + general_params->adwell_max_budget = + cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET); +- else if (params->ssids && params->ssids[0].ssid_len) ++ else if (params->n_ssids && params->ssids[0].ssid_len) + general_params->adwell_max_budget = + cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN); + else +-- +2.43.0 + diff --git a/queue-6.1/wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch b/queue-6.1/wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch new file mode 100644 index 00000000000..ca57daead19 --- /dev/null +++ b/queue-6.1/wifi-iwlwifi-mvm-don-t-read-past-the-mfuart-notifcat.patch @@ -0,0 +1,55 @@ +From 0044215ada474ea13c26922f21d0ecbb26b6e50e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 May 2024 13:27:14 +0300 +Subject: wifi: iwlwifi: mvm: don't read past the mfuart notifcation + +From: Emmanuel Grumbach + +[ Upstream commit 4bb95f4535489ed830cf9b34b0a891e384d1aee4 ] + +In case the firmware sends a notification that claims it has more data +than it has, we will read past that was allocated for the notification. +Remove the print of the buffer, we won't see it by default. If needed, +we can see the content with tracing. + +This was reported by KFENCE. + +Fixes: bdccdb854f2f ("iwlwifi: mvm: support MFUART dump in case of MFUART assert") +Signed-off-by: Emmanuel Grumbach +Reviewed-by: Johannes Berg +Signed-off-by: Miri Korenblit +Link: https://msgid.link/20240513132416.ba82a01a559e.Ia91dd20f5e1ca1ad380b95e68aebf2794f553d9b@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +index 2e3c98eaa400c..668bb9ce293db 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +@@ -91,20 +91,10 @@ void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm, + { + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_mfu_assert_dump_notif *mfu_dump_notif = (void *)pkt->data; +- __le32 *dump_data = mfu_dump_notif->data; +- int n_words = le32_to_cpu(mfu_dump_notif->data_size) / sizeof(__le32); +- int i; + + if (mfu_dump_notif->index_num == 0) + IWL_INFO(mvm, "MFUART assert id 0x%x occurred\n", + le32_to_cpu(mfu_dump_notif->assert_id)); +- +- for (i = 0; i < n_words; i++) +- IWL_DEBUG_INFO(mvm, +- "MFUART assert dump, dword %u: 0x%08x\n", +- le16_to_cpu(mfu_dump_notif->index_num) * +- n_words + i, +- le32_to_cpu(dump_data[i])); + } + + static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, +-- +2.43.0 + diff --git a/queue-6.1/wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch b/queue-6.1/wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch new file mode 100644 index 00000000000..3fed7f76617 --- /dev/null +++ b/queue-6.1/wifi-iwlwifi-mvm-revert-gen2-tx-a-mpdu-size-to-64.patch @@ -0,0 +1,49 @@ +From 8db8763931333b769d25f7d86d3d65822f3d37b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 May 2024 17:06:33 +0300 +Subject: wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64 + +From: Johannes Berg + +[ Upstream commit 4a7aace2899711592327463c1a29ffee44fcc66e ] + +We don't actually support >64 even for HE devices, so revert +back to 64. This fixes an issue where the session is refused +because the queue is configured differently from the actual +session later. + +Fixes: 514c30696fbc ("iwlwifi: add support for IEEE802.11ax") +Signed-off-by: Johannes Berg +Reviewed-by: Liad Kaufman +Reviewed-by: Luciano Coelho +Signed-off-by: Miri Korenblit +Link: https://msgid.link/20240510170500.52f7b4cf83aa.If47e43adddf7fe250ed7f5571fbb35d8221c7c47@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +index b7bc8c1b2ddae..00f04f675cbbb 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +@@ -123,13 +123,8 @@ enum { + + #define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) + #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) +-/* +- * FIXME - various places in firmware API still use u8, +- * e.g. LQ command and SCD config command. +- * This should be 256 instead. +- */ +-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (255) +-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (255) ++#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (64) ++#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (64) + #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) + + #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ +-- +2.43.0 + diff --git a/queue-6.1/wifi-mac80211-correctly-parse-spatial-reuse-paramete.patch b/queue-6.1/wifi-mac80211-correctly-parse-spatial-reuse-paramete.patch new file mode 100644 index 00000000000..dd80598a370 --- /dev/null +++ b/queue-6.1/wifi-mac80211-correctly-parse-spatial-reuse-paramete.patch @@ -0,0 +1,65 @@ +From 6d4b2d420d17c48c0dd93f006542190e418328a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 May 2024 10:18:54 +0800 +Subject: wifi: mac80211: correctly parse Spatial Reuse Parameter Set element + +From: Lingbo Kong + +[ Upstream commit a26d8dc5227f449a54518a8b40733a54c6600a8b ] + +Currently, the way of parsing Spatial Reuse Parameter Set element is +incorrect and some members of struct ieee80211_he_obss_pd are not assigned. + +To address this issue, it must be parsed in the order of the elements of +Spatial Reuse Parameter Set defined in the IEEE Std 802.11ax specification. + +The diagram of the Spatial Reuse Parameter Set element (IEEE Std 802.11ax +-2021-9.4.2.252). + +------------------------------------------------------------------------- +| | | | |Non-SRG| SRG | SRG | SRG | SRG | +|Element|Length| Element | SR |OBSS PD|OBSS PD|OBSS PD| BSS |Partial| +| ID | | ID |Control| Max | Min | Max |Color | BSSID | +| | |Extension| | Offset| Offset|Offset |Bitmap|Bitmap | +------------------------------------------------------------------------- + +Fixes: 1ced169cc1c2 ("mac80211: allow setting spatial reuse parameters from bss_conf") +Signed-off-by: Lingbo Kong +Link: https://msgid.link/20240516021854.5682-3-quic_lingbok@quicinc.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/he.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/net/mac80211/he.c b/net/mac80211/he.c +index 0322abae08250..147ff0f71b9bb 100644 +--- a/net/mac80211/he.c ++++ b/net/mac80211/he.c +@@ -231,15 +231,21 @@ ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif, + + if (!he_spr_ie_elem) + return; ++ ++ he_obss_pd->sr_ctrl = he_spr_ie_elem->he_sr_control; + data = he_spr_ie_elem->optional; + + if (he_spr_ie_elem->he_sr_control & + IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT) +- data++; ++ he_obss_pd->non_srg_max_offset = *data++; ++ + if (he_spr_ie_elem->he_sr_control & + IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) { +- he_obss_pd->max_offset = *data++; + he_obss_pd->min_offset = *data++; ++ he_obss_pd->max_offset = *data++; ++ memcpy(he_obss_pd->bss_color_bitmap, data, 8); ++ data += 8; ++ memcpy(he_obss_pd->partial_bssid_bitmap, data, 8); + he_obss_pd->enable = true; + } + } +-- +2.43.0 + diff --git a/queue-6.1/wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch b/queue-6.1/wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch new file mode 100644 index 00000000000..9046abf7c8a --- /dev/null +++ b/queue-6.1/wifi-mac80211-fix-deadlock-in-ieee80211_sta_ps_deliv.patch @@ -0,0 +1,109 @@ +From f7193a6930d8d87bd3dd2718e48017508b84e219 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 08:57:53 +0200 +Subject: wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup() + +From: Remi Pommarel + +[ Upstream commit 44c06bbde6443de206b30f513100b5670b23fc5e ] + +The ieee80211_sta_ps_deliver_wakeup() function takes sta->ps_lock to +synchronizes with ieee80211_tx_h_unicast_ps_buf() which is called from +softirq context. However using only spin_lock() to get sta->ps_lock in +ieee80211_sta_ps_deliver_wakeup() does not prevent softirq to execute +on this same CPU, to run ieee80211_tx_h_unicast_ps_buf() and try to +take this same lock ending in deadlock. Below is an example of rcu stall +that arises in such situation. + + rcu: INFO: rcu_sched self-detected stall on CPU + rcu: 2-....: (42413413 ticks this GP) idle=b154/1/0x4000000000000000 softirq=1763/1765 fqs=21206996 + rcu: (t=42586894 jiffies g=2057 q=362405 ncpus=4) + CPU: 2 PID: 719 Comm: wpa_supplicant Tainted: G W 6.4.0-02158-g1b062f552873 #742 + Hardware name: RPT (r1) (DT) + pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : queued_spin_lock_slowpath+0x58/0x2d0 + lr : invoke_tx_handlers_early+0x5b4/0x5c0 + sp : ffff00001ef64660 + x29: ffff00001ef64660 x28: ffff000009bc1070 x27: ffff000009bc0ad8 + x26: ffff000009bc0900 x25: ffff00001ef647a8 x24: 0000000000000000 + x23: ffff000009bc0900 x22: ffff000009bc0900 x21: ffff00000ac0e000 + x20: ffff00000a279e00 x19: ffff00001ef646e8 x18: 0000000000000000 + x17: ffff800016468000 x16: ffff00001ef608c0 x15: 0010533c93f64f80 + x14: 0010395c9faa3946 x13: 0000000000000000 x12: 00000000fa83b2da + x11: 000000012edeceea x10: ffff0000010fbe00 x9 : 0000000000895440 + x8 : 000000000010533c x7 : ffff00000ad8b740 x6 : ffff00000c350880 + x5 : 0000000000000007 x4 : 0000000000000001 x3 : 0000000000000000 + x2 : 0000000000000000 x1 : 0000000000000001 x0 : ffff00000ac0e0e8 + Call trace: + queued_spin_lock_slowpath+0x58/0x2d0 + ieee80211_tx+0x80/0x12c + ieee80211_tx_pending+0x110/0x278 + tasklet_action_common.constprop.0+0x10c/0x144 + tasklet_action+0x20/0x28 + _stext+0x11c/0x284 + ____do_softirq+0xc/0x14 + call_on_irq_stack+0x24/0x34 + do_softirq_own_stack+0x18/0x20 + do_softirq+0x74/0x7c + __local_bh_enable_ip+0xa0/0xa4 + _ieee80211_wake_txqs+0x3b0/0x4b8 + __ieee80211_wake_queue+0x12c/0x168 + ieee80211_add_pending_skbs+0xec/0x138 + ieee80211_sta_ps_deliver_wakeup+0x2a4/0x480 + ieee80211_mps_sta_status_update.part.0+0xd8/0x11c + ieee80211_mps_sta_status_update+0x18/0x24 + sta_apply_parameters+0x3bc/0x4c0 + ieee80211_change_station+0x1b8/0x2dc + nl80211_set_station+0x444/0x49c + genl_family_rcv_msg_doit.isra.0+0xa4/0xfc + genl_rcv_msg+0x1b0/0x244 + netlink_rcv_skb+0x38/0x10c + genl_rcv+0x34/0x48 + netlink_unicast+0x254/0x2bc + netlink_sendmsg+0x190/0x3b4 + ____sys_sendmsg+0x1e8/0x218 + ___sys_sendmsg+0x68/0x8c + __sys_sendmsg+0x44/0x84 + __arm64_sys_sendmsg+0x20/0x28 + do_el0_svc+0x6c/0xe8 + el0_svc+0x14/0x48 + el0t_64_sync_handler+0xb0/0xb4 + el0t_64_sync+0x14c/0x150 + +Using spin_lock_bh()/spin_unlock_bh() instead prevents softirq to raise +on the same CPU that is holding the lock. + +Fixes: 1d147bfa6429 ("mac80211: fix AP powersave TX vs. wakeup race") +Signed-off-by: Remi Pommarel +Link: https://msgid.link/8e36fe07d0fbc146f89196cd47a53c8a0afe84aa.1716910344.git.repk@triplefau.lt +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/sta_info.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index bd56015b29258..f388b39531748 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -1555,7 +1555,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) + skb_queue_head_init(&pending); + + /* sync with ieee80211_tx_h_unicast_ps_buf */ +- spin_lock(&sta->ps_lock); ++ spin_lock_bh(&sta->ps_lock); + /* Send all buffered frames to the station */ + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + int count = skb_queue_len(&pending), tmp; +@@ -1584,7 +1584,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) + */ + clear_sta_flag(sta, WLAN_STA_PSPOLL); + clear_sta_flag(sta, WLAN_STA_UAPSD); +- spin_unlock(&sta->ps_lock); ++ spin_unlock_bh(&sta->ps_lock); + + atomic_dec(&ps->num_sta_ps); + +-- +2.43.0 + diff --git a/queue-6.1/wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch b/queue-6.1/wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch new file mode 100644 index 00000000000..ebb3d55be16 --- /dev/null +++ b/queue-6.1/wifi-mac80211-mesh-fix-leak-of-mesh_preq_queue-objec.patch @@ -0,0 +1,100 @@ +From c34943df328fd1f172f7ca46fd16e66019b93209 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 May 2024 16:26:05 +0200 +Subject: wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects + +From: Nicolas Escande + +[ Upstream commit b7d7f11a291830fdf69d3301075dd0fb347ced84 ] + +The hwmp code use objects of type mesh_preq_queue, added to a list in +ieee80211_if_mesh, to keep track of mpath we need to resolve. If the mpath +gets deleted, ex mesh interface is removed, the entries in that list will +never get cleaned. Fix this by flushing all corresponding items of the +preq_queue in mesh_path_flush_pending(). + +This should take care of KASAN reports like this: + +unreferenced object 0xffff00000668d800 (size 128): + comm "kworker/u8:4", pid 67, jiffies 4295419552 (age 1836.444s) + hex dump (first 32 bytes): + 00 1f 05 09 00 00 ff ff 00 d5 68 06 00 00 ff ff ..........h..... + 8e 97 ea eb 3e b8 01 00 00 00 00 00 00 00 00 00 ....>........... + backtrace: + [<000000007302a0b6>] __kmem_cache_alloc_node+0x1e0/0x35c + [<00000000049bd418>] kmalloc_trace+0x34/0x80 + [<0000000000d792bb>] mesh_queue_preq+0x44/0x2a8 + [<00000000c99c3696>] mesh_nexthop_resolve+0x198/0x19c + [<00000000926bf598>] ieee80211_xmit+0x1d0/0x1f4 + [<00000000fc8c2284>] __ieee80211_subif_start_xmit+0x30c/0x764 + [<000000005926ee38>] ieee80211_subif_start_xmit+0x9c/0x7a4 + [<000000004c86e916>] dev_hard_start_xmit+0x174/0x440 + [<0000000023495647>] __dev_queue_xmit+0xe24/0x111c + [<00000000cfe9ca78>] batadv_send_skb_packet+0x180/0x1e4 + [<000000007bacc5d5>] batadv_v_elp_periodic_work+0x2f4/0x508 + [<00000000adc3cd94>] process_one_work+0x4b8/0xa1c + [<00000000b36425d1>] worker_thread+0x9c/0x634 + [<0000000005852dd5>] kthread+0x1bc/0x1c4 + [<000000005fccd770>] ret_from_fork+0x10/0x20 +unreferenced object 0xffff000009051f00 (size 128): + comm "kworker/u8:4", pid 67, jiffies 4295419553 (age 1836.440s) + hex dump (first 32 bytes): + 90 d6 92 0d 00 00 ff ff 00 d8 68 06 00 00 ff ff ..........h..... + 36 27 92 e4 02 e0 01 00 00 58 79 06 00 00 ff ff 6'.......Xy..... + backtrace: + [<000000007302a0b6>] __kmem_cache_alloc_node+0x1e0/0x35c + [<00000000049bd418>] kmalloc_trace+0x34/0x80 + [<0000000000d792bb>] mesh_queue_preq+0x44/0x2a8 + [<00000000c99c3696>] mesh_nexthop_resolve+0x198/0x19c + [<00000000926bf598>] ieee80211_xmit+0x1d0/0x1f4 + [<00000000fc8c2284>] __ieee80211_subif_start_xmit+0x30c/0x764 + [<000000005926ee38>] ieee80211_subif_start_xmit+0x9c/0x7a4 + [<000000004c86e916>] dev_hard_start_xmit+0x174/0x440 + [<0000000023495647>] __dev_queue_xmit+0xe24/0x111c + [<00000000cfe9ca78>] batadv_send_skb_packet+0x180/0x1e4 + [<000000007bacc5d5>] batadv_v_elp_periodic_work+0x2f4/0x508 + [<00000000adc3cd94>] process_one_work+0x4b8/0xa1c + [<00000000b36425d1>] worker_thread+0x9c/0x634 + [<0000000005852dd5>] kthread+0x1bc/0x1c4 + [<000000005fccd770>] ret_from_fork+0x10/0x20 + +Fixes: 050ac52cbe1f ("mac80211: code for on-demand Hybrid Wireless Mesh Protocol") +Signed-off-by: Nicolas Escande +Link: https://msgid.link/20240528142605.1060566-1-nico.escande@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/mesh_pathtbl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c +index 69d5e1ec6edef..e7b9dcf30adc9 100644 +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -723,10 +723,23 @@ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, + */ + void mesh_path_flush_pending(struct mesh_path *mpath) + { ++ struct ieee80211_sub_if_data *sdata = mpath->sdata; ++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; ++ struct mesh_preq_queue *preq, *tmp; + struct sk_buff *skb; + + while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL) + mesh_path_discard_frame(mpath->sdata, skb); ++ ++ spin_lock_bh(&ifmsh->mesh_preq_queue_lock); ++ list_for_each_entry_safe(preq, tmp, &ifmsh->preq_queue.list, list) { ++ if (ether_addr_equal(mpath->dst, preq->dst)) { ++ list_del(&preq->list); ++ kfree(preq); ++ --ifmsh->preq_queue_len; ++ } ++ } ++ spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); + } + + /** +-- +2.43.0 + diff --git a/queue-6.1/xtensa-fix-make_pc_from_ra-second-argument.patch b/queue-6.1/xtensa-fix-make_pc_from_ra-second-argument.patch new file mode 100644 index 00000000000..fae82d4bee7 --- /dev/null +++ b/queue-6.1/xtensa-fix-make_pc_from_ra-second-argument.patch @@ -0,0 +1,126 @@ +From a15d6ea3d267c31a44bb259f6682b3a46a9575e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Feb 2024 05:15:42 -0800 +Subject: xtensa: fix MAKE_PC_FROM_RA second argument + +From: Max Filippov + +[ Upstream commit 0e60f0b75884677fb9f4f2ad40d52b43451564d5 ] + +Xtensa has two-argument MAKE_PC_FROM_RA macro to convert a0 to an actual +return address because when windowed ABI is used call{,x}{4,8,12} +opcodes stuff encoded window size into the top 2 bits of the register +that becomes a return address in the called function. Second argument of +that macro is supposed to be an address having these 2 topmost bits set +correctly, but the comment suggested that that could be the stack +address. However the stack doesn't have to be in the same 1GByte region +as the code, especially in noMMU XIP configurations. + +Fix the comment and use either _text or regs->pc as the second argument +for the MAKE_PC_FROM_RA macro. + +Cc: stable@vger.kernel.org +Signed-off-by: Max Filippov +Signed-off-by: Sasha Levin +--- + arch/xtensa/include/asm/processor.h | 8 ++++---- + arch/xtensa/include/asm/ptrace.h | 2 +- + arch/xtensa/kernel/process.c | 5 +++-- + arch/xtensa/kernel/stacktrace.c | 3 ++- + 4 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h +index 228e4dff5fb2d..ab555a980147b 100644 +--- a/arch/xtensa/include/asm/processor.h ++++ b/arch/xtensa/include/asm/processor.h +@@ -113,9 +113,9 @@ + #define MAKE_RA_FOR_CALL(ra,ws) (((ra) & 0x3fffffff) | (ws) << 30) + + /* Convert return address to a valid pc +- * Note: We assume that the stack pointer is in the same 1GB ranges as the ra ++ * Note: 'text' is the address within the same 1GB range as the ra + */ +-#define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) ++#define MAKE_PC_FROM_RA(ra, text) (((ra) & 0x3fffffff) | ((unsigned long)(text) & 0xc0000000)) + + #elif defined(__XTENSA_CALL0_ABI__) + +@@ -125,9 +125,9 @@ + #define MAKE_RA_FOR_CALL(ra, ws) (ra) + + /* Convert return address to a valid pc +- * Note: We assume that the stack pointer is in the same 1GB ranges as the ra ++ * Note: 'text' is not used as 'ra' is always the full address + */ +-#define MAKE_PC_FROM_RA(ra, sp) (ra) ++#define MAKE_PC_FROM_RA(ra, text) (ra) + + #else + #error Unsupported Xtensa ABI +diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h +index 308f209a47407..17c5cbd1832e7 100644 +--- a/arch/xtensa/include/asm/ptrace.h ++++ b/arch/xtensa/include/asm/ptrace.h +@@ -87,7 +87,7 @@ struct pt_regs { + # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) + # define instruction_pointer(regs) ((regs)->pc) + # define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \ +- (regs)->areg[1])) ++ (regs)->pc)) + + # ifndef CONFIG_SMP + # define profile_pc(regs) instruction_pointer(regs) +diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c +index 68e0e2f06d660..3138f72dcbe2e 100644 +--- a/arch/xtensa/kernel/process.c ++++ b/arch/xtensa/kernel/process.c +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + #include + + extern void ret_from_fork(void); +@@ -379,7 +380,7 @@ unsigned long __get_wchan(struct task_struct *p) + int count = 0; + + sp = p->thread.sp; +- pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp); ++ pc = MAKE_PC_FROM_RA(p->thread.ra, _text); + + do { + if (sp < stack_page + sizeof(struct task_struct) || +@@ -391,7 +392,7 @@ unsigned long __get_wchan(struct task_struct *p) + + /* Stack layout: sp-4: ra, sp-3: sp' */ + +- pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp); ++ pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), _text); + sp = SPILL_SLOT(sp, 1); + } while (count++ < 16); + return 0; +diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c +index dcba743305efe..b69044893287f 100644 +--- a/arch/xtensa/kernel/stacktrace.c ++++ b/arch/xtensa/kernel/stacktrace.c +@@ -13,6 +13,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -189,7 +190,7 @@ void walk_stackframe(unsigned long *sp, + if (a1 <= (unsigned long)sp) + break; + +- frame.pc = MAKE_PC_FROM_RA(a0, a1); ++ frame.pc = MAKE_PC_FROM_RA(a0, _text); + frame.sp = a1; + + if (fn(&frame, data)) +-- +2.43.0 + diff --git a/queue-6.1/xtensa-stacktrace-include-asm-ftrace.h-for-prototype.patch b/queue-6.1/xtensa-stacktrace-include-asm-ftrace.h-for-prototype.patch new file mode 100644 index 00000000000..3ffaa2b847a --- /dev/null +++ b/queue-6.1/xtensa-stacktrace-include-asm-ftrace.h-for-prototype.patch @@ -0,0 +1,40 @@ +From ab5d6887e43f48dbbbbed7f2270595af4435a879 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 22:21:30 -0700 +Subject: xtensa: stacktrace: include for prototype + +From: Randy Dunlap + +[ Upstream commit 1b6ceeb99ee05eb2c62a9e5512623e63cf8490ba ] + +Use to prevent a build warning: + +arch/xtensa/kernel/stacktrace.c:263:15: warning: no previous prototype for 'return_address' [-Wmissing-prototypes] + 263 | unsigned long return_address(unsigned level) + +Signed-off-by: Randy Dunlap +Cc: Chris Zankel +Cc: Max Filippov +Message-Id: <20230920052139.10570-8-rdunlap@infradead.org> +Signed-off-by: Max Filippov +Stable-dep-of: 0e60f0b75884 ("xtensa: fix MAKE_PC_FROM_RA second argument") +Signed-off-by: Sasha Levin +--- + arch/xtensa/kernel/stacktrace.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c +index 7f7755cd28f07..dcba743305efe 100644 +--- a/arch/xtensa/kernel/stacktrace.c ++++ b/arch/xtensa/kernel/stacktrace.c +@@ -12,6 +12,7 @@ + #include + #include + ++#include + #include + #include + #include +-- +2.43.0 + -- 2.47.3