From: Sasha Levin Date: Sun, 11 Jun 2023 02:02:39 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v4.14.318~68 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c789814b49839c41ab18a0bf088d32776310530a;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/afs-fix-setting-of-mtime-when-creating-a-file-dir-sy.patch b/queue-5.15/afs-fix-setting-of-mtime-when-creating-a-file-dir-sy.patch new file mode 100644 index 00000000000..aa46d3ae922 --- /dev/null +++ b/queue-5.15/afs-fix-setting-of-mtime-when-creating-a-file-dir-sy.patch @@ -0,0 +1,61 @@ +From 8f3a7fd4128ace87e9aeea372b20a5c773f238fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jun 2023 09:47:13 +0100 +Subject: afs: Fix setting of mtime when creating a file/dir/symlink + +From: David Howells + +[ Upstream commit a27648c742104a833a01c54becc24429898d85bf ] + +kafs incorrectly passes a zero mtime (ie. 1st Jan 1970) to the server when +creating a file, dir or symlink because the mtime recorded in the +afs_operation struct gets passed to the server by the marshalling routines, +but the afs_mkdir(), afs_create() and afs_symlink() functions don't set it. + +This gets masked if a file or directory is subsequently modified. + +Fix this by filling in op->mtime before calling the create op. + +Fixes: e49c7b2f6de7 ("afs: Build an abstraction around an "operation" concept") +Signed-off-by: David Howells +Reviewed-by: Jeffrey Altman +Reviewed-by: Marc Dionne +cc: linux-afs@lists.infradead.org +cc: linux-fsdevel@vger.kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + fs/afs/dir.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/afs/dir.c b/fs/afs/dir.c +index 948a808a964d1..cec18f9f8bd7a 100644 +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -1394,6 +1394,7 @@ static int afs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + op->dentry = dentry; + op->create.mode = S_IFDIR | mode; + op->create.reason = afs_edit_dir_for_mkdir; ++ op->mtime = current_time(dir); + op->ops = &afs_mkdir_operation; + return afs_do_sync_operation(op); + } +@@ -1697,6 +1698,7 @@ static int afs_create(struct user_namespace *mnt_userns, struct inode *dir, + op->dentry = dentry; + op->create.mode = S_IFREG | mode; + op->create.reason = afs_edit_dir_for_create; ++ op->mtime = current_time(dir); + op->ops = &afs_create_operation; + return afs_do_sync_operation(op); + +@@ -1832,6 +1834,7 @@ static int afs_symlink(struct user_namespace *mnt_userns, struct inode *dir, + op->ops = &afs_symlink_operation; + op->create.reason = afs_edit_dir_for_symlink; + op->create.symlink = content; ++ op->mtime = current_time(dir); + return afs_do_sync_operation(op); + + error: +-- +2.39.2 + diff --git a/queue-5.15/bluetooth-fix-l2cap_disconnect_req-deadlock.patch b/queue-5.15/bluetooth-fix-l2cap_disconnect_req-deadlock.patch new file mode 100644 index 00000000000..0c5d2e83c73 --- /dev/null +++ b/queue-5.15/bluetooth-fix-l2cap_disconnect_req-deadlock.patch @@ -0,0 +1,61 @@ +From 71d3972dcec94a1413264e57cbdca8630f819687 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 May 2023 03:44:56 +0000 +Subject: Bluetooth: Fix l2cap_disconnect_req deadlock + +From: Ying Hsu + +[ Upstream commit 02c5ea5246a44d6ffde0fddebfc1d56188052976 ] + +L2CAP assumes that the locks conn->chan_lock and chan->lock are +acquired in the order conn->chan_lock, chan->lock to avoid +potential deadlock. +For example, l2sock_shutdown acquires these locks in the order: + mutex_lock(&conn->chan_lock) + l2cap_chan_lock(chan) + +However, l2cap_disconnect_req acquires chan->lock in +l2cap_get_chan_by_scid first and then acquires conn->chan_lock +before calling l2cap_chan_del. This means that these locks are +acquired in unexpected order, which leads to potential deadlock: + l2cap_chan_lock(c) + mutex_lock(&conn->chan_lock) + +This patch releases chan->lock before acquiring the conn_chan_lock +to avoid the potential deadlock. + +Fixes: a2a9339e1c9d ("Bluetooth: L2CAP: Fix use-after-free in l2cap_disconnect_{req,rsp}") +Signed-off-by: Ying Hsu +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index f01b77b037878..101a15256efe5 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -4664,7 +4664,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, + + chan->ops->set_shutdown(chan); + ++ l2cap_chan_unlock(chan); + mutex_lock(&conn->chan_lock); ++ l2cap_chan_lock(chan); + l2cap_chan_del(chan, ECONNRESET); + mutex_unlock(&conn->chan_lock); + +@@ -4703,7 +4705,9 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, + return 0; + } + ++ l2cap_chan_unlock(chan); + mutex_lock(&conn->chan_lock); ++ l2cap_chan_lock(chan); + l2cap_chan_del(chan, 0); + mutex_unlock(&conn->chan_lock); + +-- +2.39.2 + diff --git a/queue-5.15/bluetooth-l2cap-add-missing-checks-for-invalid-dcid.patch b/queue-5.15/bluetooth-l2cap-add-missing-checks-for-invalid-dcid.patch new file mode 100644 index 00000000000..460dc726fb4 --- /dev/null +++ b/queue-5.15/bluetooth-l2cap-add-missing-checks-for-invalid-dcid.patch @@ -0,0 +1,53 @@ +From 09bee9a5fd75ca05a5f2f30b9bc9064166054998 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 3 Jun 2023 08:28:09 -0400 +Subject: Bluetooth: L2CAP: Add missing checks for invalid DCID + +From: Sungwoo Kim + +[ Upstream commit 75767213f3d9b97f63694d02260b6a49a2271876 ] + +When receiving a connect response we should make sure that the DCID is +within the valid range and that we don't already have another channel +allocated for the same DCID. +Missing checks may violate the specification (BLUETOOTH CORE SPECIFICATION +Version 5.4 | Vol 3, Part A, Page 1046). + +Fixes: 40624183c202 ("Bluetooth: L2CAP: Add missing checks for invalid LE DCID") +Signed-off-by: Sungwoo Kim +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 101a15256efe5..9dd54247029a8 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -4307,6 +4307,10 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, + result = __le16_to_cpu(rsp->result); + status = __le16_to_cpu(rsp->status); + ++ if (result == L2CAP_CR_SUCCESS && (dcid < L2CAP_CID_DYN_START || ++ dcid > L2CAP_CID_DYN_END)) ++ return -EPROTO; ++ + BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", + dcid, scid, result, status); + +@@ -4338,6 +4342,11 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, + + switch (result) { + case L2CAP_CR_SUCCESS: ++ if (__l2cap_get_chan_by_dcid(conn, dcid)) { ++ err = -EBADSLT; ++ break; ++ } ++ + l2cap_state_change(chan, BT_CONFIG); + chan->ident = 0; + chan->dcid = dcid; +-- +2.39.2 + diff --git a/queue-5.15/bnxt_en-don-t-issue-ap-reset-during-ethtool-s-reset-.patch b/queue-5.15/bnxt_en-don-t-issue-ap-reset-during-ethtool-s-reset-.patch new file mode 100644 index 00000000000..f54634a2b00 --- /dev/null +++ b/queue-5.15/bnxt_en-don-t-issue-ap-reset-during-ethtool-s-reset-.patch @@ -0,0 +1,43 @@ +From 7599abf988938ff3952e49bf378d1b2edd094563 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jun 2023 00:54:05 -0700 +Subject: bnxt_en: Don't issue AP reset during ethtool's reset operation + +From: Sreekanth Reddy + +[ Upstream commit 1d997801c7cc6a7f542e46d5a6bf16f893ad3fe9 ] + +Only older NIC controller's firmware uses the PROC AP reset type. +Firmware on 5731X/5741X and newer chips does not support this reset +type. When bnxt_reset() issues a series of resets, this PROC AP +reset may actually fail on these newer chips because the firmware +is not ready to accept this unsupported command yet. Avoid this +unnecessary error by skipping this reset type on chips that don't +support it. + +Fixes: 7a13240e3718 ("bnxt_en: fix ethtool_reset_flags ABI violations") +Reviewed-by: Pavan Chebbi +Signed-off-by: Sreekanth Reddy +Signed-off-by: Michael Chan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +index 3c9ba116d5aff..8ebc1c522a05b 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -3597,7 +3597,7 @@ static int bnxt_reset(struct net_device *dev, u32 *flags) + } + } + +- if (req & BNXT_FW_RESET_AP) { ++ if (!BNXT_CHIP_P4_PLUS(bp) && (req & BNXT_FW_RESET_AP)) { + /* This feature is not supported in older firmware versions */ + if (bp->hwrm_spec_code >= 0x10803) { + if (!bnxt_firmware_reset_ap(dev)) { +-- +2.39.2 + diff --git a/queue-5.15/bnxt_en-implement-.set_port-.unset_port-udp-tunnel-c.patch b/queue-5.15/bnxt_en-implement-.set_port-.unset_port-udp-tunnel-c.patch new file mode 100644 index 00000000000..856af94b27b --- /dev/null +++ b/queue-5.15/bnxt_en-implement-.set_port-.unset_port-udp-tunnel-c.patch @@ -0,0 +1,81 @@ +From b4e1278c8692d7b827741d78718d2a30865efd80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jun 2023 00:54:09 -0700 +Subject: bnxt_en: Implement .set_port / .unset_port UDP tunnel callbacks + +From: Somnath Kotur + +[ Upstream commit 1eb4ef12591348c440ac9d6efcf7521e73cf2b10 ] + +As per the new udp tunnel framework, drivers which need to know the +details of a port entry (i.e. port type) when it gets deleted should +use the .set_port / .unset_port callbacks. + +Implementing the current .udp_tunnel_sync callback would mean that the +deleted tunnel port entry would be all zeros. This used to work on +older firmware because it would not check the input when deleting a +tunnel port. With newer firmware, the delete will now fail and +subsequent tunnel port allocation will fail as a result. + +Fixes: 442a35a5a7aa ("bnxt: convert to new udp_tunnel_nic infra") +Reviewed-by: Kalesh Anakkur Purayil +Signed-off-by: Somnath Kotur +Signed-off-by: Michael Chan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 25 ++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 2629e8805651e..931bb40ac05b5 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -12701,26 +12701,37 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp) + + #endif /* CONFIG_RFS_ACCEL */ + +-static int bnxt_udp_tunnel_sync(struct net_device *netdev, unsigned int table) ++static int bnxt_udp_tunnel_set_port(struct net_device *netdev, unsigned int table, ++ unsigned int entry, struct udp_tunnel_info *ti) + { + struct bnxt *bp = netdev_priv(netdev); +- struct udp_tunnel_info ti; + unsigned int cmd; + +- udp_tunnel_nic_get_port(netdev, table, 0, &ti); +- if (ti.type == UDP_TUNNEL_TYPE_VXLAN) ++ if (ti->type == UDP_TUNNEL_TYPE_VXLAN) + cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN; + else + cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE; + +- if (ti.port) +- return bnxt_hwrm_tunnel_dst_port_alloc(bp, ti.port, cmd); ++ return bnxt_hwrm_tunnel_dst_port_alloc(bp, ti->port, cmd); ++} ++ ++static int bnxt_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table, ++ unsigned int entry, struct udp_tunnel_info *ti) ++{ ++ struct bnxt *bp = netdev_priv(netdev); ++ unsigned int cmd; ++ ++ if (ti->type == UDP_TUNNEL_TYPE_VXLAN) ++ cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN; ++ else ++ cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE; + + return bnxt_hwrm_tunnel_dst_port_free(bp, cmd); + } + + static const struct udp_tunnel_nic_info bnxt_udp_tunnels = { +- .sync_table = bnxt_udp_tunnel_sync, ++ .set_port = bnxt_udp_tunnel_set_port, ++ .unset_port = bnxt_udp_tunnel_unset_port, + .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP | + UDP_TUNNEL_NIC_INFO_OPEN_ONLY, + .tables = { +-- +2.39.2 + diff --git a/queue-5.15/bnxt_en-query-default-vlan-before-vnic-setup-on-a-vf.patch b/queue-5.15/bnxt_en-query-default-vlan-before-vnic-setup-on-a-vf.patch new file mode 100644 index 00000000000..a4e9dbca5eb --- /dev/null +++ b/queue-5.15/bnxt_en-query-default-vlan-before-vnic-setup-on-a-vf.patch @@ -0,0 +1,51 @@ +From ac3e3caacb772c9a03c549d00046a262e2a3e547 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jun 2023 00:54:06 -0700 +Subject: bnxt_en: Query default VLAN before VNIC setup on a VF + +From: Somnath Kotur + +[ Upstream commit 1a9e4f501bc6ff1b6ecb60df54fbf2b54db43bfe ] + +We need to call bnxt_hwrm_func_qcfg() on a VF to query the default +VLAN that may be setup by the PF. If a default VLAN is enabled, +the VF cannot support VLAN acceleration on the receive side and +the VNIC must be setup to strip out the default VLAN tag. If a +default VLAN is not enabled, the VF can support VLAN acceleration +on the receive side. The VNIC should be set up to strip or not +strip the VLAN based on the RX VLAN acceleration setting. + +Without this call to determine the default VLAN before calling +bnxt_setup_vnic(), the VNIC may not be set up correctly. For +example, bnxt_setup_vnic() may set up to strip the VLAN tag based +on stale default VLAN information. If RX VLAN acceleration is +not enabled, the VLAN tag will be incorrectly stripped and the +RX data path will not work correctly. + +Fixes: cf6645f8ebc6 ("bnxt_en: Add function for VF driver to query default VLAN.") +Reviewed-by: Pavan Chebbi +Signed-off-by: Somnath Kotur +Signed-off-by: Michael Chan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 38fc2286f7cbd..2629e8805651e 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -8595,6 +8595,9 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) + goto err_out; + } + ++ if (BNXT_VF(bp)) ++ bnxt_hwrm_func_qcfg(bp); ++ + rc = bnxt_setup_vnic(bp, 0); + if (rc) + goto err_out; +-- +2.39.2 + diff --git a/queue-5.15/bpf-add-extra-path-pointer-check-to-d_path-helper.patch b/queue-5.15/bpf-add-extra-path-pointer-check-to-d_path-helper.patch new file mode 100644 index 00000000000..140fc174c3d --- /dev/null +++ b/queue-5.15/bpf-add-extra-path-pointer-check-to-d_path-helper.patch @@ -0,0 +1,98 @@ +From c142aada3c30babcb00f61ea444b5a72d24b693a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Jun 2023 11:17:14 -0700 +Subject: bpf: Add extra path pointer check to d_path helper + +From: Jiri Olsa + +[ Upstream commit f46fab0e36e611a2389d3843f34658c849b6bd60 ] + +Anastasios reported crash on stable 5.15 kernel with following +BPF attached to lsm hook: + + SEC("lsm.s/bprm_creds_for_exec") + int BPF_PROG(bprm_creds_for_exec, struct linux_binprm *bprm) + { + struct path *path = &bprm->executable->f_path; + char p[128] = { 0 }; + + bpf_d_path(path, p, 128); + return 0; + } + +But bprm->executable can be NULL, so bpf_d_path call will crash: + + BUG: kernel NULL pointer dereference, address: 0000000000000018 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 0 P4D 0 + Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC NOPTI + ... + RIP: 0010:d_path+0x22/0x280 + ... + Call Trace: + + bpf_d_path+0x21/0x60 + bpf_prog_db9cf176e84498d9_bprm_creds_for_exec+0x94/0x99 + bpf_trampoline_6442506293_0+0x55/0x1000 + bpf_lsm_bprm_creds_for_exec+0x5/0x10 + security_bprm_creds_for_exec+0x29/0x40 + bprm_execve+0x1c1/0x900 + do_execveat_common.isra.0+0x1af/0x260 + __x64_sys_execve+0x32/0x40 + +It's problem for all stable trees with bpf_d_path helper, which was +added in 5.9. + +This issue is fixed in current bpf code, where we identify and mark +trusted pointers, so the above code would fail even to load. + +For the sake of the stable trees and to workaround potentially broken +verifier in the future, adding the code that reads the path object from +the passed pointer and verifies it's valid in kernel space. + +Fixes: 6e22ab9da793 ("bpf: Add d_path helper") +Reported-by: Anastasios Papagiannis +Suggested-by: Alexei Starovoitov +Signed-off-by: Jiri Olsa +Signed-off-by: Daniel Borkmann +Acked-by: Stanislav Fomichev +Acked-by: Yonghong Song +Link: https://lore.kernel.org/bpf/20230606181714.532998-1-jolsa@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/trace/bpf_trace.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index b314e71a008ce..8b3531172d8e2 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -849,13 +849,23 @@ static const struct bpf_func_proto bpf_send_signal_thread_proto = { + + BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz) + { ++ struct path copy; + long len; + char *p; + + if (!sz) + return 0; + +- p = d_path(path, buf, sz); ++ /* ++ * The path pointer is verified as trusted and safe to use, ++ * but let's double check it's valid anyway to workaround ++ * potentially broken verifier. ++ */ ++ len = copy_from_kernel_nofault(©, path, sizeof(*path)); ++ if (len < 0) ++ return len; ++ ++ p = d_path(©, buf, sz); + if (IS_ERR(p)) { + len = PTR_ERR(p); + } else { +-- +2.39.2 + diff --git a/queue-5.15/bpf-fix-uaf-in-task-local-storage.patch b/queue-5.15/bpf-fix-uaf-in-task-local-storage.patch new file mode 100644 index 00000000000..c4dad79e720 --- /dev/null +++ b/queue-5.15/bpf-fix-uaf-in-task-local-storage.patch @@ -0,0 +1,56 @@ +From fc8803ce5d496781fcf110a0b368d90b2ebd1cb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Jun 2023 02:26:12 +0200 +Subject: bpf: Fix UAF in task local storage + +From: KP Singh + +[ Upstream commit b0fd1852bcc21accca6260ef245356d5c141ff66 ] + +When task local storage was generalized for tracing programs, the +bpf_task_local_storage callback was moved from a BPF LSM hook +callback for security_task_free LSM hook to it's own callback. But a +failure case in bad_fork_cleanup_security was missed which, when +triggered, led to a dangling task owner pointer and a subsequent +use-after-free. Move the bpf_task_storage_free to the very end of +free_task to handle all failure cases. + +This issue was noticed when a BPF LSM program was attached to the +task_alloc hook on a kernel with KASAN enabled. The program used +bpf_task_storage_get to copy the task local storage from the current +task to the new task being created. + +Fixes: a10787e6d58c ("bpf: Enable task local storage for tracing programs") +Reported-by: Kuba Piecuch +Signed-off-by: KP Singh +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20230602002612.1117381-1-kpsingh@kernel.org +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + kernel/fork.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/fork.c b/kernel/fork.c +index 68eab6ce30859..1906230a000e3 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -470,6 +470,7 @@ void free_task(struct task_struct *tsk) + arch_release_task_struct(tsk); + if (tsk->flags & PF_KTHREAD) + free_kthread_struct(tsk); ++ bpf_task_storage_free(tsk); + free_task_struct(tsk); + } + EXPORT_SYMBOL(free_task); +@@ -753,7 +754,6 @@ void __put_task_struct(struct task_struct *tsk) + cgroup_free(tsk); + task_numa_free(tsk, true); + security_task_free(tsk); +- bpf_task_storage_free(tsk); + exit_creds(tsk); + delayacct_tsk_free(tsk); + put_signal_struct(tsk->signal); +-- +2.39.2 + diff --git a/queue-5.15/drm-i915-explain-the-magic-numbers-for-aux-sync-prec.patch b/queue-5.15/drm-i915-explain-the-magic-numbers-for-aux-sync-prec.patch new file mode 100644 index 00000000000..157429a36bb --- /dev/null +++ b/queue-5.15/drm-i915-explain-the-magic-numbers-for-aux-sync-prec.patch @@ -0,0 +1,88 @@ +From 77805c37280d5a8a269a3ad3b6a18eb9c5876a6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Mar 2023 20:24:34 +0300 +Subject: drm/i915: Explain the magic numbers for AUX SYNC/precharge length +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +[ Upstream commit 26bfc3f36f2104c174dfc72415547d5c28ef3f1c ] + +Replace the hardcoded final numbers in the AUX SYNC/precharge +setup, and derive those from numbers from the (e)DP specs. + +The new functions can serve as the single point of truth for +the number of SYNC pulses we use. + +Cc: Jouni Högander +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20230329172434.18744-2-ville.syrjala@linux.intel.com +Reviewed-by: Jouni Högander +Stable-dep-of: 2d6f2f79e065 ("drm/i915: Use 18 fast wake AUX sync len") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_dp_aux.c | 32 +++++++++++++++++++-- + 1 file changed, 29 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c +index fd7527a3087ff..f0485521e58ad 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_aux.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c +@@ -119,6 +119,32 @@ static u32 skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index) + return index ? 0 : 1; + } + ++static int intel_dp_aux_sync_len(void) ++{ ++ int precharge = 16; /* 10-16 */ ++ int preamble = 16; ++ ++ return precharge + preamble; ++} ++ ++static int intel_dp_aux_fw_sync_len(void) ++{ ++ int precharge = 16; /* 10-16 */ ++ int preamble = 8; ++ ++ return precharge + preamble; ++} ++ ++static int g4x_dp_aux_precharge_len(void) ++{ ++ int precharge_min = 10; ++ int preamble = 16; ++ ++ /* HW wants the length of the extra precharge in 2us units */ ++ return (intel_dp_aux_sync_len() - ++ precharge_min - preamble) / 2; ++} ++ + static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp, + int send_bytes, + u32 aux_clock_divider) +@@ -141,7 +167,7 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp, + timeout | + DP_AUX_CH_CTL_RECEIVE_ERROR | + (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | +- (3 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | ++ (g4x_dp_aux_precharge_len() << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | + (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT); + } + +@@ -167,8 +193,8 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp, + DP_AUX_CH_CTL_TIME_OUT_MAX | + DP_AUX_CH_CTL_RECEIVE_ERROR | + (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | +- DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(24) | +- DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); ++ DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(intel_dp_aux_fw_sync_len()) | ++ DP_AUX_CH_CTL_SYNC_PULSE_SKL(intel_dp_aux_sync_len()); + + if (intel_phy_is_tc(i915, phy) && + dig_port->tc_mode == TC_PORT_TBT_ALT) +-- +2.39.2 + diff --git a/queue-5.15/drm-i915-selftests-add-some-missing-error-propagatio.patch b/queue-5.15/drm-i915-selftests-add-some-missing-error-propagatio.patch new file mode 100644 index 00000000000..864dee3d66c --- /dev/null +++ b/queue-5.15/drm-i915-selftests-add-some-missing-error-propagatio.patch @@ -0,0 +1,73 @@ +From 378b40753ca551ef5f624de3b771aedb37ca8a03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jun 2023 14:11:35 +0100 +Subject: drm/i915/selftests: Add some missing error propagation + +From: Tvrtko Ursulin + +[ Upstream commit 79d0150d2d983a4f6efee676cea06027f586fcd0 ] + +Add some missing error propagation in live_parallel_switch. + +To avoid needlessly burdening the various backport processes, note I am +not marking it as a fix against any patches and not copying stable since +it is debug/selftests only code. + +Signed-off-by: Tvrtko Ursulin +Reported-by: Dan Carpenter +Cc: Andi Shyti +Reviewed-by: Andi Shyti +Fixes: 50d16d44cce4 ("drm/i915/selftests: Exercise context switching in parallel") +Fixes: 6407cf533217 ("drm/i915/selftests: Stop using kthread_stop()") +Link: https://patchwork.freedesktop.org/patch/msgid/20230605131135.396854-1-tvrtko.ursulin@linux.intel.com +(cherry picked from commit 412fa1f097f48c8c1321806dd25e46618e0da147) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + .../gpu/drm/i915/gem/selftests/i915_gem_context.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +index 9369893ca1048..907e02d4085cc 100644 +--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +@@ -349,8 +349,10 @@ static int live_parallel_switch(void *arg) + continue; + + ce = intel_context_create(data[m].ce[0]->engine); +- if (IS_ERR(ce)) ++ if (IS_ERR(ce)) { ++ err = PTR_ERR(ce); + goto out; ++ } + + err = intel_context_pin(ce); + if (err) { +@@ -370,8 +372,10 @@ static int live_parallel_switch(void *arg) + + worker = kthread_create_worker(0, "igt/parallel:%s", + data[n].ce[0]->engine->name); +- if (IS_ERR(worker)) ++ if (IS_ERR(worker)) { ++ err = PTR_ERR(worker); + goto out; ++ } + + data[n].worker = worker; + } +@@ -400,8 +404,10 @@ static int live_parallel_switch(void *arg) + } + } + +- if (igt_live_test_end(&t)) +- err = -EIO; ++ if (igt_live_test_end(&t)) { ++ err = err ?: -EIO; ++ break; ++ } + } + + out: +-- +2.39.2 + diff --git a/queue-5.15/drm-i915-selftests-increase-timeout-for-live_paralle.patch b/queue-5.15/drm-i915-selftests-increase-timeout-for-live_paralle.patch new file mode 100644 index 00000000000..cd9b247da51 --- /dev/null +++ b/queue-5.15/drm-i915-selftests-increase-timeout-for-live_paralle.patch @@ -0,0 +1,41 @@ +From 6ae6d8d4c3923f5da1f56abc5b8b0e9b19f46d6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jun 2022 15:11:04 +0100 +Subject: drm/i915/selftests: Increase timeout for live_parallel_switch + +From: Akeem G Abodunrin + +[ Upstream commit 373269ae6f90bbbe945abde4c0811a991a27901a ] + +With GuC submission, it takes a little bit longer switching contexts +among all available engines simultaneously, when running +live_parallel_switch subtest. Increase the timeout. + +Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5885 +Signed-off-by: Akeem G Abodunrin +Cc: Matthew Brost +Reviewed-by: Matthew Auld +Signed-off-by: Matthew Auld +Link: https://patchwork.freedesktop.org/patch/msgid/20220622141104.334432-1-matthew.auld@intel.com +Stable-dep-of: 79d0150d2d98 ("drm/i915/selftests: Add some missing error propagation") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +index 8eb5050f8cb3e..a1cdb852ecc82 100644 +--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +@@ -215,7 +215,7 @@ static int __live_parallel_switch1(void *data) + + i915_request_add(rq); + } +- if (i915_request_wait(rq, 0, HZ / 5) < 0) ++ if (i915_request_wait(rq, 0, HZ) < 0) + err = -ETIME; + i915_request_put(rq); + if (err) +-- +2.39.2 + diff --git a/queue-5.15/drm-i915-selftests-stop-using-kthread_stop.patch b/queue-5.15/drm-i915-selftests-stop-using-kthread_stop.patch new file mode 100644 index 00000000000..f82d4c1488b --- /dev/null +++ b/queue-5.15/drm-i915-selftests-stop-using-kthread_stop.patch @@ -0,0 +1,1075 @@ +From 224e96d290cded832da606146efcf028100a2296 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Oct 2022 14:08:41 +0100 +Subject: drm/i915/selftests: Stop using kthread_stop() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tvrtko Ursulin + +[ Upstream commit 6407cf533217e09dfd895e64984c3f1ee3802373 ] + +Since a7c01fa93aeb ("signal: break out of wait loops on kthread_stop()") +kthread_stop() started asserting a pending signal which wreaks havoc with +a few of our selftests. Mainly because they are not fully expecting to +handle signals, but also cutting the intended test runtimes short due +signal_pending() now returning true (via __igt_timeout), which therefore +breaks both the patterns of: + + kthread_run() + ..sleep for igt_timeout_ms to allow test to exercise stuff.. + kthread_stop() + +And check for errors recorded in the thread. + +And also: + + Main thread | Test thread + ---------------+------------------------------ + kthread_run() | + kthread_stop() | do stuff until __igt_timeout + | -- exits early due signal -- + +Where this kthread_stop() was assume would have a "join" semantics, which +it would have had if not the new signal assertion issue. + +To recap, threads are now likely to catch a previously impossible +ERESTARTSYS or EINTR, marking the test as failed, or have a pointlessly +short run time. + +To work around this start using kthread_work(er) API which provides +an explicit way of waiting for threads to exit. And for cases where +parent controls the test duration we add explicit signaling which threads +will now use instead of relying on kthread_should_stop(). + +Signed-off-by: Tvrtko Ursulin +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20221020130841.3845791-1-tvrtko.ursulin@linux.intel.com +Stable-dep-of: 79d0150d2d98 ("drm/i915/selftests: Add some missing error propagation") +Signed-off-by: Sasha Levin +--- + .../drm/i915/gem/selftests/i915_gem_context.c | 118 ++++---- + drivers/gpu/drm/i915/gt/selftest_execlists.c | 48 ++-- + drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 51 ++-- + drivers/gpu/drm/i915/selftests/i915_request.c | 252 +++++++++++------- + 4 files changed, 281 insertions(+), 188 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +index a1cdb852ecc82..9369893ca1048 100644 +--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +@@ -182,97 +182,108 @@ static int live_nop_switch(void *arg) + } + + struct parallel_switch { +- struct task_struct *tsk; ++ struct kthread_worker *worker; ++ struct kthread_work work; + struct intel_context *ce[2]; ++ int result; + }; + +-static int __live_parallel_switch1(void *data) ++static void __live_parallel_switch1(struct kthread_work *work) + { +- struct parallel_switch *arg = data; ++ struct parallel_switch *arg = ++ container_of(work, typeof(*arg), work); + IGT_TIMEOUT(end_time); + unsigned long count; + + count = 0; ++ arg->result = 0; + do { + struct i915_request *rq = NULL; +- int err, n; ++ int n; + +- err = 0; +- for (n = 0; !err && n < ARRAY_SIZE(arg->ce); n++) { ++ for (n = 0; !arg->result && n < ARRAY_SIZE(arg->ce); n++) { + struct i915_request *prev = rq; + + rq = i915_request_create(arg->ce[n]); + if (IS_ERR(rq)) { + i915_request_put(prev); +- return PTR_ERR(rq); ++ arg->result = PTR_ERR(rq); ++ break; + } + + i915_request_get(rq); + if (prev) { +- err = i915_request_await_dma_fence(rq, &prev->fence); ++ arg->result = ++ i915_request_await_dma_fence(rq, ++ &prev->fence); + i915_request_put(prev); + } + + i915_request_add(rq); + } ++ ++ if (IS_ERR_OR_NULL(rq)) ++ break; ++ + if (i915_request_wait(rq, 0, HZ) < 0) +- err = -ETIME; ++ arg->result = -ETIME; ++ + i915_request_put(rq); +- if (err) +- return err; + + count++; +- } while (!__igt_timeout(end_time, NULL)); ++ } while (!arg->result && !__igt_timeout(end_time, NULL)); + +- pr_info("%s: %lu switches (sync)\n", arg->ce[0]->engine->name, count); +- return 0; ++ pr_info("%s: %lu switches (sync) <%d>\n", ++ arg->ce[0]->engine->name, count, arg->result); + } + +-static int __live_parallel_switchN(void *data) ++static void __live_parallel_switchN(struct kthread_work *work) + { +- struct parallel_switch *arg = data; ++ struct parallel_switch *arg = ++ container_of(work, typeof(*arg), work); + struct i915_request *rq = NULL; + IGT_TIMEOUT(end_time); + unsigned long count; + int n; + + count = 0; ++ arg->result = 0; + do { +- for (n = 0; n < ARRAY_SIZE(arg->ce); n++) { ++ for (n = 0; !arg->result && n < ARRAY_SIZE(arg->ce); n++) { + struct i915_request *prev = rq; +- int err = 0; + + rq = i915_request_create(arg->ce[n]); + if (IS_ERR(rq)) { + i915_request_put(prev); +- return PTR_ERR(rq); ++ arg->result = PTR_ERR(rq); ++ break; + } + + i915_request_get(rq); + if (prev) { +- err = i915_request_await_dma_fence(rq, &prev->fence); ++ arg->result = ++ i915_request_await_dma_fence(rq, ++ &prev->fence); + i915_request_put(prev); + } + + i915_request_add(rq); +- if (err) { +- i915_request_put(rq); +- return err; +- } + } + + count++; +- } while (!__igt_timeout(end_time, NULL)); +- i915_request_put(rq); ++ } while (!arg->result && !__igt_timeout(end_time, NULL)); + +- pr_info("%s: %lu switches (many)\n", arg->ce[0]->engine->name, count); +- return 0; ++ if (!IS_ERR_OR_NULL(rq)) ++ i915_request_put(rq); ++ ++ pr_info("%s: %lu switches (many) <%d>\n", ++ arg->ce[0]->engine->name, count, arg->result); + } + + static int live_parallel_switch(void *arg) + { + struct drm_i915_private *i915 = arg; +- static int (* const func[])(void *arg) = { ++ static void (* const func[])(struct kthread_work *) = { + __live_parallel_switch1, + __live_parallel_switchN, + NULL, +@@ -280,7 +291,7 @@ static int live_parallel_switch(void *arg) + struct parallel_switch *data = NULL; + struct i915_gem_engines *engines; + struct i915_gem_engines_iter it; +- int (* const *fn)(void *arg); ++ void (* const *fn)(struct kthread_work *); + struct i915_gem_context *ctx; + struct intel_context *ce; + struct file *file; +@@ -351,9 +362,22 @@ static int live_parallel_switch(void *arg) + } + } + ++ for (n = 0; n < count; n++) { ++ struct kthread_worker *worker; ++ ++ if (!data[n].ce[0]) ++ continue; ++ ++ worker = kthread_create_worker(0, "igt/parallel:%s", ++ data[n].ce[0]->engine->name); ++ if (IS_ERR(worker)) ++ goto out; ++ ++ data[n].worker = worker; ++ } ++ + for (fn = func; !err && *fn; fn++) { + struct igt_live_test t; +- int n; + + err = igt_live_test_begin(&t, i915, __func__, ""); + if (err) +@@ -363,30 +387,17 @@ static int live_parallel_switch(void *arg) + if (!data[n].ce[0]) + continue; + +- data[n].tsk = kthread_run(*fn, &data[n], +- "igt/parallel:%s", +- data[n].ce[0]->engine->name); +- if (IS_ERR(data[n].tsk)) { +- err = PTR_ERR(data[n].tsk); +- break; +- } +- get_task_struct(data[n].tsk); ++ data[n].result = 0; ++ kthread_init_work(&data[n].work, *fn); ++ kthread_queue_work(data[n].worker, &data[n].work); + } + +- yield(); /* start all threads before we kthread_stop() */ +- + for (n = 0; n < count; n++) { +- int status; +- +- if (IS_ERR_OR_NULL(data[n].tsk)) +- continue; +- +- status = kthread_stop(data[n].tsk); +- if (status && !err) +- err = status; +- +- put_task_struct(data[n].tsk); +- data[n].tsk = NULL; ++ if (data[n].ce[0]) { ++ kthread_flush_work(&data[n].work); ++ if (data[n].result && !err) ++ err = data[n].result; ++ } + } + + if (igt_live_test_end(&t)) +@@ -402,6 +413,9 @@ static int live_parallel_switch(void *arg) + intel_context_unpin(data[n].ce[m]); + intel_context_put(data[n].ce[m]); + } ++ ++ if (data[n].worker) ++ kthread_destroy_worker(data[n].worker); + } + kfree(data); + out_file: +diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c +index f12ffe7976394..7c39175330e8f 100644 +--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c ++++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c +@@ -3468,12 +3468,14 @@ static int random_priority(struct rnd_state *rnd) + + struct preempt_smoke { + struct intel_gt *gt; ++ struct kthread_work work; + struct i915_gem_context **contexts; + struct intel_engine_cs *engine; + struct drm_i915_gem_object *batch; + unsigned int ncontext; + struct rnd_state prng; + unsigned long count; ++ int result; + }; + + static struct i915_gem_context *smoke_context(struct preempt_smoke *smoke) +@@ -3533,34 +3535,31 @@ static int smoke_submit(struct preempt_smoke *smoke, + return err; + } + +-static int smoke_crescendo_thread(void *arg) ++static void smoke_crescendo_work(struct kthread_work *work) + { +- struct preempt_smoke *smoke = arg; ++ struct preempt_smoke *smoke = container_of(work, typeof(*smoke), work); + IGT_TIMEOUT(end_time); + unsigned long count; + + count = 0; + do { + struct i915_gem_context *ctx = smoke_context(smoke); +- int err; + +- err = smoke_submit(smoke, +- ctx, count % I915_PRIORITY_MAX, +- smoke->batch); +- if (err) +- return err; ++ smoke->result = smoke_submit(smoke, ctx, ++ count % I915_PRIORITY_MAX, ++ smoke->batch); + + count++; +- } while (count < smoke->ncontext && !__igt_timeout(end_time, NULL)); ++ } while (!smoke->result && count < smoke->ncontext && ++ !__igt_timeout(end_time, NULL)); + + smoke->count = count; +- return 0; + } + + static int smoke_crescendo(struct preempt_smoke *smoke, unsigned int flags) + #define BATCH BIT(0) + { +- struct task_struct *tsk[I915_NUM_ENGINES] = {}; ++ struct kthread_worker *worker[I915_NUM_ENGINES] = {}; + struct preempt_smoke *arg; + struct intel_engine_cs *engine; + enum intel_engine_id id; +@@ -3571,6 +3570,8 @@ static int smoke_crescendo(struct preempt_smoke *smoke, unsigned int flags) + if (!arg) + return -ENOMEM; + ++ memset(arg, 0, I915_NUM_ENGINES * sizeof(*arg)); ++ + for_each_engine(engine, smoke->gt, id) { + arg[id] = *smoke; + arg[id].engine = engine; +@@ -3578,31 +3579,28 @@ static int smoke_crescendo(struct preempt_smoke *smoke, unsigned int flags) + arg[id].batch = NULL; + arg[id].count = 0; + +- tsk[id] = kthread_run(smoke_crescendo_thread, arg, +- "igt/smoke:%d", id); +- if (IS_ERR(tsk[id])) { +- err = PTR_ERR(tsk[id]); ++ worker[id] = kthread_create_worker(0, "igt/smoke:%d", id); ++ if (IS_ERR(worker[id])) { ++ err = PTR_ERR(worker[id]); + break; + } +- get_task_struct(tsk[id]); +- } + +- yield(); /* start all threads before we kthread_stop() */ ++ kthread_init_work(&arg[id].work, smoke_crescendo_work); ++ kthread_queue_work(worker[id], &arg[id].work); ++ } + + count = 0; + for_each_engine(engine, smoke->gt, id) { +- int status; +- +- if (IS_ERR_OR_NULL(tsk[id])) ++ if (IS_ERR_OR_NULL(worker[id])) + continue; + +- status = kthread_stop(tsk[id]); +- if (status && !err) +- err = status; ++ kthread_flush_work(&arg[id].work); ++ if (arg[id].result && !err) ++ err = arg[id].result; + + count += arg[id].count; + +- put_task_struct(tsk[id]); ++ kthread_destroy_worker(worker[id]); + } + + pr_info("Submitted %lu crescendo:%x requests across %d engines and %d contexts\n", +diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c +index 2c1ed32ca5acd..f164912cea30f 100644 +--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c ++++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c +@@ -861,10 +861,13 @@ static int igt_reset_active_engine(void *arg) + } + + struct active_engine { +- struct task_struct *task; ++ struct kthread_worker *worker; ++ struct kthread_work work; + struct intel_engine_cs *engine; + unsigned long resets; + unsigned int flags; ++ bool stop; ++ int result; + }; + + #define TEST_ACTIVE BIT(0) +@@ -895,10 +898,10 @@ static int active_request_put(struct i915_request *rq) + return err; + } + +-static int active_engine(void *data) ++static void active_engine(struct kthread_work *work) + { + I915_RND_STATE(prng); +- struct active_engine *arg = data; ++ struct active_engine *arg = container_of(work, typeof(*arg), work); + struct intel_engine_cs *engine = arg->engine; + struct i915_request *rq[8] = {}; + struct intel_context *ce[ARRAY_SIZE(rq)]; +@@ -908,16 +911,17 @@ static int active_engine(void *data) + for (count = 0; count < ARRAY_SIZE(ce); count++) { + ce[count] = intel_context_create(engine); + if (IS_ERR(ce[count])) { +- err = PTR_ERR(ce[count]); +- pr_err("[%s] Create context #%ld failed: %d!\n", engine->name, count, err); ++ arg->result = PTR_ERR(ce[count]); ++ pr_err("[%s] Create context #%ld failed: %d!\n", ++ engine->name, count, arg->result); + while (--count) + intel_context_put(ce[count]); +- return err; ++ return; + } + } + + count = 0; +- while (!kthread_should_stop()) { ++ while (!READ_ONCE(arg->stop)) { + unsigned int idx = count++ & (ARRAY_SIZE(rq) - 1); + struct i915_request *old = rq[idx]; + struct i915_request *new; +@@ -962,7 +966,7 @@ static int active_engine(void *data) + intel_context_put(ce[count]); + } + +- return err; ++ arg->result = err; + } + + static int __igt_reset_engines(struct intel_gt *gt, +@@ -1013,7 +1017,7 @@ static int __igt_reset_engines(struct intel_gt *gt, + + memset(threads, 0, sizeof(threads)); + for_each_engine(other, gt, tmp) { +- struct task_struct *tsk; ++ struct kthread_worker *worker; + + threads[tmp].resets = + i915_reset_engine_count(global, other); +@@ -1027,19 +1031,21 @@ static int __igt_reset_engines(struct intel_gt *gt, + threads[tmp].engine = other; + threads[tmp].flags = flags; + +- tsk = kthread_run(active_engine, &threads[tmp], +- "igt/%s", other->name); +- if (IS_ERR(tsk)) { +- err = PTR_ERR(tsk); +- pr_err("[%s] Thread spawn failed: %d!\n", engine->name, err); ++ worker = kthread_create_worker(0, "igt/%s", ++ other->name); ++ if (IS_ERR(worker)) { ++ err = PTR_ERR(worker); ++ pr_err("[%s] Worker create failed: %d!\n", ++ engine->name, err); + goto unwind; + } + +- threads[tmp].task = tsk; +- get_task_struct(tsk); +- } ++ threads[tmp].worker = worker; + +- yield(); /* start all threads before we begin */ ++ kthread_init_work(&threads[tmp].work, active_engine); ++ kthread_queue_work(threads[tmp].worker, ++ &threads[tmp].work); ++ } + + st_engine_heartbeat_disable_no_pm(engine); + set_bit(I915_RESET_ENGINE + id, >->reset.flags); +@@ -1187,17 +1193,20 @@ static int __igt_reset_engines(struct intel_gt *gt, + for_each_engine(other, gt, tmp) { + int ret; + +- if (!threads[tmp].task) ++ if (!threads[tmp].worker) + continue; + +- ret = kthread_stop(threads[tmp].task); ++ WRITE_ONCE(threads[tmp].stop, true); ++ kthread_flush_work(&threads[tmp].work); ++ ret = READ_ONCE(threads[tmp].result); + if (ret) { + pr_err("kthread for other engine %s failed, err=%d\n", + other->name, ret); + if (!err) + err = ret; + } +- put_task_struct(threads[tmp].task); ++ ++ kthread_destroy_worker(threads[tmp].worker); + + /* GuC based resets are not logged per engine */ + if (!using_guc) { +diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c +index d67710d10615d..0e1a64b179a55 100644 +--- a/drivers/gpu/drm/i915/selftests/i915_request.c ++++ b/drivers/gpu/drm/i915/selftests/i915_request.c +@@ -288,9 +288,18 @@ __live_request_alloc(struct intel_context *ce) + return intel_context_create_request(ce); + } + +-static int __igt_breadcrumbs_smoketest(void *arg) ++struct smoke_thread { ++ struct kthread_worker *worker; ++ struct kthread_work work; ++ struct smoketest *t; ++ bool stop; ++ int result; ++}; ++ ++static void __igt_breadcrumbs_smoketest(struct kthread_work *work) + { +- struct smoketest *t = arg; ++ struct smoke_thread *thread = container_of(work, typeof(*thread), work); ++ struct smoketest *t = thread->t; + const unsigned int max_batch = min(t->ncontexts, t->max_batch) - 1; + const unsigned int total = 4 * t->ncontexts + 1; + unsigned int num_waits = 0, num_fences = 0; +@@ -309,8 +318,10 @@ static int __igt_breadcrumbs_smoketest(void *arg) + */ + + requests = kcalloc(total, sizeof(*requests), GFP_KERNEL); +- if (!requests) +- return -ENOMEM; ++ if (!requests) { ++ thread->result = -ENOMEM; ++ return; ++ } + + order = i915_random_order(total, &prng); + if (!order) { +@@ -318,7 +329,7 @@ static int __igt_breadcrumbs_smoketest(void *arg) + goto out_requests; + } + +- while (!kthread_should_stop()) { ++ while (!READ_ONCE(thread->stop)) { + struct i915_sw_fence *submit, *wait; + unsigned int n, count; + +@@ -426,7 +437,7 @@ static int __igt_breadcrumbs_smoketest(void *arg) + kfree(order); + out_requests: + kfree(requests); +- return err; ++ thread->result = err; + } + + static int mock_breadcrumbs_smoketest(void *arg) +@@ -439,7 +450,7 @@ static int mock_breadcrumbs_smoketest(void *arg) + .request_alloc = __mock_request_alloc + }; + unsigned int ncpus = num_online_cpus(); +- struct task_struct **threads; ++ struct smoke_thread *threads; + unsigned int n; + int ret = 0; + +@@ -468,28 +479,37 @@ static int mock_breadcrumbs_smoketest(void *arg) + } + + for (n = 0; n < ncpus; n++) { +- threads[n] = kthread_run(__igt_breadcrumbs_smoketest, +- &t, "igt/%d", n); +- if (IS_ERR(threads[n])) { +- ret = PTR_ERR(threads[n]); ++ struct kthread_worker *worker; ++ ++ worker = kthread_create_worker(0, "igt/%d", n); ++ if (IS_ERR(worker)) { ++ ret = PTR_ERR(worker); + ncpus = n; + break; + } + +- get_task_struct(threads[n]); ++ threads[n].worker = worker; ++ threads[n].t = &t; ++ threads[n].stop = false; ++ threads[n].result = 0; ++ ++ kthread_init_work(&threads[n].work, ++ __igt_breadcrumbs_smoketest); ++ kthread_queue_work(worker, &threads[n].work); + } + +- yield(); /* start all threads before we begin */ + msleep(jiffies_to_msecs(i915_selftest.timeout_jiffies)); + + for (n = 0; n < ncpus; n++) { + int err; + +- err = kthread_stop(threads[n]); ++ WRITE_ONCE(threads[n].stop, true); ++ kthread_flush_work(&threads[n].work); ++ err = READ_ONCE(threads[n].result); + if (err < 0 && !ret) + ret = err; + +- put_task_struct(threads[n]); ++ kthread_destroy_worker(threads[n].worker); + } + pr_info("Completed %lu waits for %lu fence across %d cpus\n", + atomic_long_read(&t.num_waits), +@@ -1291,9 +1311,18 @@ static int live_sequential_engines(void *arg) + return err; + } + +-static int __live_parallel_engine1(void *arg) ++struct parallel_thread { ++ struct kthread_worker *worker; ++ struct kthread_work work; ++ struct intel_engine_cs *engine; ++ int result; ++}; ++ ++static void __live_parallel_engine1(struct kthread_work *work) + { +- struct intel_engine_cs *engine = arg; ++ struct parallel_thread *thread = ++ container_of(work, typeof(*thread), work); ++ struct intel_engine_cs *engine = thread->engine; + IGT_TIMEOUT(end_time); + unsigned long count; + int err = 0; +@@ -1324,12 +1353,14 @@ static int __live_parallel_engine1(void *arg) + intel_engine_pm_put(engine); + + pr_info("%s: %lu request + sync\n", engine->name, count); +- return err; ++ thread->result = err; + } + +-static int __live_parallel_engineN(void *arg) ++static void __live_parallel_engineN(struct kthread_work *work) + { +- struct intel_engine_cs *engine = arg; ++ struct parallel_thread *thread = ++ container_of(work, typeof(*thread), work); ++ struct intel_engine_cs *engine = thread->engine; + IGT_TIMEOUT(end_time); + unsigned long count; + int err = 0; +@@ -1351,7 +1382,7 @@ static int __live_parallel_engineN(void *arg) + intel_engine_pm_put(engine); + + pr_info("%s: %lu requests\n", engine->name, count); +- return err; ++ thread->result = err; + } + + static bool wake_all(struct drm_i915_private *i915) +@@ -1377,9 +1408,11 @@ static int wait_for_all(struct drm_i915_private *i915) + return -ETIME; + } + +-static int __live_parallel_spin(void *arg) ++static void __live_parallel_spin(struct kthread_work *work) + { +- struct intel_engine_cs *engine = arg; ++ struct parallel_thread *thread = ++ container_of(work, typeof(*thread), work); ++ struct intel_engine_cs *engine = thread->engine; + struct igt_spinner spin; + struct i915_request *rq; + int err = 0; +@@ -1392,7 +1425,8 @@ static int __live_parallel_spin(void *arg) + + if (igt_spinner_init(&spin, engine->gt)) { + wake_all(engine->i915); +- return -ENOMEM; ++ thread->result = -ENOMEM; ++ return; + } + + intel_engine_pm_get(engine); +@@ -1425,22 +1459,22 @@ static int __live_parallel_spin(void *arg) + + out_spin: + igt_spinner_fini(&spin); +- return err; ++ thread->result = err; + } + + static int live_parallel_engines(void *arg) + { + struct drm_i915_private *i915 = arg; +- static int (* const func[])(void *arg) = { ++ static void (* const func[])(struct kthread_work *) = { + __live_parallel_engine1, + __live_parallel_engineN, + __live_parallel_spin, + NULL, + }; + const unsigned int nengines = num_uabi_engines(i915); ++ struct parallel_thread *threads; + struct intel_engine_cs *engine; +- int (* const *fn)(void *arg); +- struct task_struct **tsk; ++ void (* const *fn)(struct kthread_work *); + int err = 0; + + /* +@@ -1448,8 +1482,8 @@ static int live_parallel_engines(void *arg) + * tests that we load up the system maximally. + */ + +- tsk = kcalloc(nengines, sizeof(*tsk), GFP_KERNEL); +- if (!tsk) ++ threads = kcalloc(nengines, sizeof(*threads), GFP_KERNEL); ++ if (!threads) + return -ENOMEM; + + for (fn = func; !err && *fn; fn++) { +@@ -1466,37 +1500,44 @@ static int live_parallel_engines(void *arg) + + idx = 0; + for_each_uabi_engine(engine, i915) { +- tsk[idx] = kthread_run(*fn, engine, +- "igt/parallel:%s", +- engine->name); +- if (IS_ERR(tsk[idx])) { +- err = PTR_ERR(tsk[idx]); ++ struct kthread_worker *worker; ++ ++ worker = kthread_create_worker(0, "igt/parallel:%s", ++ engine->name); ++ if (IS_ERR(worker)) { ++ err = PTR_ERR(worker); + break; + } +- get_task_struct(tsk[idx++]); +- } + +- yield(); /* start all threads before we kthread_stop() */ ++ threads[idx].worker = worker; ++ threads[idx].result = 0; ++ threads[idx].engine = engine; ++ ++ kthread_init_work(&threads[idx].work, *fn); ++ kthread_queue_work(worker, &threads[idx].work); ++ idx++; ++ } + + idx = 0; + for_each_uabi_engine(engine, i915) { + int status; + +- if (IS_ERR(tsk[idx])) ++ if (!threads[idx].worker) + break; + +- status = kthread_stop(tsk[idx]); ++ kthread_flush_work(&threads[idx].work); ++ status = READ_ONCE(threads[idx].result); + if (status && !err) + err = status; + +- put_task_struct(tsk[idx++]); ++ kthread_destroy_worker(threads[idx++].worker); + } + + if (igt_live_test_end(&t)) + err = -EIO; + } + +- kfree(tsk); ++ kfree(threads); + return err; + } + +@@ -1544,7 +1585,7 @@ static int live_breadcrumbs_smoketest(void *arg) + const unsigned int ncpus = num_online_cpus(); + unsigned long num_waits, num_fences; + struct intel_engine_cs *engine; +- struct task_struct **threads; ++ struct smoke_thread *threads; + struct igt_live_test live; + intel_wakeref_t wakeref; + struct smoketest *smoke; +@@ -1618,23 +1659,26 @@ static int live_breadcrumbs_smoketest(void *arg) + smoke[idx].max_batch, engine->name); + + for (n = 0; n < ncpus; n++) { +- struct task_struct *tsk; ++ unsigned int i = idx * ncpus + n; ++ struct kthread_worker *worker; + +- tsk = kthread_run(__igt_breadcrumbs_smoketest, +- &smoke[idx], "igt/%d.%d", idx, n); +- if (IS_ERR(tsk)) { +- ret = PTR_ERR(tsk); ++ worker = kthread_create_worker(0, "igt/%d.%d", idx, n); ++ if (IS_ERR(worker)) { ++ ret = PTR_ERR(worker); + goto out_flush; + } + +- get_task_struct(tsk); +- threads[idx * ncpus + n] = tsk; ++ threads[i].worker = worker; ++ threads[i].t = &smoke[idx]; ++ ++ kthread_init_work(&threads[i].work, ++ __igt_breadcrumbs_smoketest); ++ kthread_queue_work(worker, &threads[i].work); + } + + idx++; + } + +- yield(); /* start all threads before we begin */ + msleep(jiffies_to_msecs(i915_selftest.timeout_jiffies)); + + out_flush: +@@ -1643,17 +1687,19 @@ static int live_breadcrumbs_smoketest(void *arg) + num_fences = 0; + for_each_uabi_engine(engine, i915) { + for (n = 0; n < ncpus; n++) { +- struct task_struct *tsk = threads[idx * ncpus + n]; ++ unsigned int i = idx * ncpus + n; + int err; + +- if (!tsk) ++ if (!threads[i].worker) + continue; + +- err = kthread_stop(tsk); ++ WRITE_ONCE(threads[i].stop, true); ++ kthread_flush_work(&threads[i].work); ++ err = READ_ONCE(threads[i].result); + if (err < 0 && !ret) + ret = err; + +- put_task_struct(tsk); ++ kthread_destroy_worker(threads[i].worker); + } + + num_waits += atomic_long_read(&smoke[idx].num_waits); +@@ -2763,9 +2809,18 @@ static int perf_series_engines(void *arg) + return err; + } + +-static int p_sync0(void *arg) ++struct p_thread { ++ struct perf_stats p; ++ struct kthread_worker *worker; ++ struct kthread_work work; ++ struct intel_engine_cs *engine; ++ int result; ++}; ++ ++static void p_sync0(struct kthread_work *work) + { +- struct perf_stats *p = arg; ++ struct p_thread *thread = container_of(work, typeof(*thread), work); ++ struct perf_stats *p = &thread->p; + struct intel_engine_cs *engine = p->engine; + struct intel_context *ce; + IGT_TIMEOUT(end_time); +@@ -2774,13 +2829,16 @@ static int p_sync0(void *arg) + int err = 0; + + ce = intel_context_create(engine); +- if (IS_ERR(ce)) +- return PTR_ERR(ce); ++ if (IS_ERR(ce)) { ++ thread->result = PTR_ERR(ce); ++ return; ++ } + + err = intel_context_pin(ce); + if (err) { + intel_context_put(ce); +- return err; ++ thread->result = err; ++ return; + } + + if (intel_engine_supports_stats(engine)) { +@@ -2830,12 +2888,13 @@ static int p_sync0(void *arg) + + intel_context_unpin(ce); + intel_context_put(ce); +- return err; ++ thread->result = err; + } + +-static int p_sync1(void *arg) ++static void p_sync1(struct kthread_work *work) + { +- struct perf_stats *p = arg; ++ struct p_thread *thread = container_of(work, typeof(*thread), work); ++ struct perf_stats *p = &thread->p; + struct intel_engine_cs *engine = p->engine; + struct i915_request *prev = NULL; + struct intel_context *ce; +@@ -2845,13 +2904,16 @@ static int p_sync1(void *arg) + int err = 0; + + ce = intel_context_create(engine); +- if (IS_ERR(ce)) +- return PTR_ERR(ce); ++ if (IS_ERR(ce)) { ++ thread->result = PTR_ERR(ce); ++ return; ++ } + + err = intel_context_pin(ce); + if (err) { + intel_context_put(ce); +- return err; ++ thread->result = err; ++ return; + } + + if (intel_engine_supports_stats(engine)) { +@@ -2903,12 +2965,13 @@ static int p_sync1(void *arg) + + intel_context_unpin(ce); + intel_context_put(ce); +- return err; ++ thread->result = err; + } + +-static int p_many(void *arg) ++static void p_many(struct kthread_work *work) + { +- struct perf_stats *p = arg; ++ struct p_thread *thread = container_of(work, typeof(*thread), work); ++ struct perf_stats *p = &thread->p; + struct intel_engine_cs *engine = p->engine; + struct intel_context *ce; + IGT_TIMEOUT(end_time); +@@ -2917,13 +2980,16 @@ static int p_many(void *arg) + bool busy; + + ce = intel_context_create(engine); +- if (IS_ERR(ce)) +- return PTR_ERR(ce); ++ if (IS_ERR(ce)) { ++ thread->result = PTR_ERR(ce); ++ return; ++ } + + err = intel_context_pin(ce); + if (err) { + intel_context_put(ce); +- return err; ++ thread->result = err; ++ return; + } + + if (intel_engine_supports_stats(engine)) { +@@ -2964,26 +3030,23 @@ static int p_many(void *arg) + + intel_context_unpin(ce); + intel_context_put(ce); +- return err; ++ thread->result = err; + } + + static int perf_parallel_engines(void *arg) + { + struct drm_i915_private *i915 = arg; +- static int (* const func[])(void *arg) = { ++ static void (* const func[])(struct kthread_work *) = { + p_sync0, + p_sync1, + p_many, + NULL, + }; + const unsigned int nengines = num_uabi_engines(i915); ++ void (* const *fn)(struct kthread_work *); + struct intel_engine_cs *engine; +- int (* const *fn)(void *arg); + struct pm_qos_request qos; +- struct { +- struct perf_stats p; +- struct task_struct *tsk; +- } *engines; ++ struct p_thread *engines; + int err = 0; + + engines = kcalloc(nengines, sizeof(*engines), GFP_KERNEL); +@@ -3006,36 +3069,45 @@ static int perf_parallel_engines(void *arg) + + idx = 0; + for_each_uabi_engine(engine, i915) { ++ struct kthread_worker *worker; ++ + intel_engine_pm_get(engine); + + memset(&engines[idx].p, 0, sizeof(engines[idx].p)); +- engines[idx].p.engine = engine; + +- engines[idx].tsk = kthread_run(*fn, &engines[idx].p, +- "igt:%s", engine->name); +- if (IS_ERR(engines[idx].tsk)) { +- err = PTR_ERR(engines[idx].tsk); ++ worker = kthread_create_worker(0, "igt:%s", ++ engine->name); ++ if (IS_ERR(worker)) { ++ err = PTR_ERR(worker); + intel_engine_pm_put(engine); + break; + } +- get_task_struct(engines[idx++].tsk); +- } ++ engines[idx].worker = worker; ++ engines[idx].result = 0; ++ engines[idx].p.engine = engine; ++ engines[idx].engine = engine; + +- yield(); /* start all threads before we kthread_stop() */ ++ kthread_init_work(&engines[idx].work, *fn); ++ kthread_queue_work(worker, &engines[idx].work); ++ idx++; ++ } + + idx = 0; + for_each_uabi_engine(engine, i915) { + int status; + +- if (IS_ERR(engines[idx].tsk)) ++ if (!engines[idx].worker) + break; + +- status = kthread_stop(engines[idx].tsk); ++ kthread_flush_work(&engines[idx].work); ++ status = READ_ONCE(engines[idx].result); + if (status && !err) + err = status; + + intel_engine_pm_put(engine); +- put_task_struct(engines[idx++].tsk); ++ ++ kthread_destroy_worker(engines[idx].worker); ++ idx++; + } + + if (igt_live_test_end(&t)) +-- +2.39.2 + diff --git a/queue-5.15/drm-i915-use-18-fast-wake-aux-sync-len.patch b/queue-5.15/drm-i915-use-18-fast-wake-aux-sync-len.patch new file mode 100644 index 00000000000..570e915d378 --- /dev/null +++ b/queue-5.15/drm-i915-use-18-fast-wake-aux-sync-len.patch @@ -0,0 +1,47 @@ +From c628d60c547c0a30183d885b531160a75e5c16a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 May 2023 13:16:49 +0300 +Subject: drm/i915: Use 18 fast wake AUX sync len +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jouni Högander + +[ Upstream commit 2d6f2f79e06571d41eb1223abebe9097511c9544 ] + +HW default for wake sync pulses is 18. 10 precharge and 8 preamble. There +is no reason to change this especially as it is causing problems with +certain eDP panels. + +v3: Change "Fixes:" commit +v2: Remove "fast wake" repeat from subject + +Signed-off-by: Jouni Högander +Fixes: e1c71f8f9180 ("drm/i915: Fix fast wake AUX sync len") +Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8475 +Reviewed-by: Luca Coelho +Link: https://patchwork.freedesktop.org/patch/msgid/20230530101649.2549949-1-jouni.hogander@intel.com +(cherry picked from commit b29a20f7c4995a059ed764ce42389857426397c7) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_dp_aux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c +index f0485521e58ad..d507a20822db1 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_aux.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c +@@ -129,7 +129,7 @@ static int intel_dp_aux_sync_len(void) + + static int intel_dp_aux_fw_sync_len(void) + { +- int precharge = 16; /* 10-16 */ ++ int precharge = 10; /* 10-16 */ + int preamble = 8; + + return precharge + preamble; +-- +2.39.2 + diff --git a/queue-5.15/ipv6-rpl-fix-route-of-death.patch b/queue-5.15/ipv6-rpl-fix-route-of-death.patch new file mode 100644 index 00000000000..5c93971987d --- /dev/null +++ b/queue-5.15/ipv6-rpl-fix-route-of-death.patch @@ -0,0 +1,195 @@ +From c33032e9e0d40c684b772dbe72f6a76b0e342249 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jun 2023 11:06:17 -0700 +Subject: ipv6: rpl: Fix Route of Death. + +From: Kuniyuki Iwashima + +[ Upstream commit a2f4c143d76b1a47c91ef9bc46907116b111da0b ] + +A remote DoS vulnerability of RPL Source Routing is assigned CVE-2023-2156. + +The Source Routing Header (SRH) has the following format: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next Header | Hdr Ext Len | Routing Type | Segments Left | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | CmprI | CmprE | Pad | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + . . + . Addresses[1..n] . + . . + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +The originator of an SRH places the first hop's IPv6 address in the IPv6 +header's IPv6 Destination Address and the second hop's IPv6 address as +the first address in Addresses[1..n]. + +The CmprI and CmprE fields indicate the number of prefix octets that are +shared with the IPv6 Destination Address. When CmprI or CmprE is not 0, +Addresses[1..n] are compressed as follows: + + 1..n-1 : (16 - CmprI) bytes + n : (16 - CmprE) bytes + +Segments Left indicates the number of route segments remaining. When the +value is not zero, the SRH is forwarded to the next hop. Its address +is extracted from Addresses[n - Segment Left + 1] and swapped with IPv6 +Destination Address. + +When Segment Left is greater than or equal to 2, the size of SRH is not +changed because Addresses[1..n-1] are decompressed and recompressed with +CmprI. + +OTOH, when Segment Left changes from 1 to 0, the new SRH could have a +different size because Addresses[1..n-1] are decompressed with CmprI and +recompressed with CmprE. + +Let's say CmprI is 15 and CmprE is 0. When we receive SRH with Segment +Left >= 2, Addresses[1..n-1] have 1 byte for each, and Addresses[n] has +16 bytes. When Segment Left is 1, Addresses[1..n-1] is decompressed to +16 bytes and not recompressed. Finally, the new SRH will need more room +in the header, and the size is (16 - 1) * (n - 1) bytes. + +Here the max value of n is 255 as Segment Left is u8, so in the worst case, +we have to allocate 3825 bytes in the skb headroom. However, now we only +allocate a small fixed buffer that is IPV6_RPL_SRH_WORST_SWAP_SIZE (16 + 7 +bytes). If the decompressed size overflows the room, skb_push() hits BUG() +below [0]. + +Instead of allocating the fixed buffer for every packet, let's allocate +enough headroom only when we receive SRH with Segment Left 1. + +[0]: +skbuff: skb_under_panic: text:ffffffff81c9f6e2 len:576 put:576 head:ffff8880070b5180 data:ffff8880070b4fb0 tail:0x70 end:0x140 dev:lo +kernel BUG at net/core/skbuff.c:200! +invalid opcode: 0000 [#1] PREEMPT SMP PTI +CPU: 0 PID: 154 Comm: python3 Not tainted 6.4.0-rc4-00190-gc308e9ec0047 #7 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 +RIP: 0010:skb_panic (net/core/skbuff.c:200) +Code: 4f 70 50 8b 87 bc 00 00 00 50 8b 87 b8 00 00 00 50 ff b7 c8 00 00 00 4c 8b 8f c0 00 00 00 48 c7 c7 80 6e 77 82 e8 ad 8b 60 ff <0f> 0b 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 +RSP: 0018:ffffc90000003da0 EFLAGS: 00000246 +RAX: 0000000000000085 RBX: ffff8880058a6600 RCX: 0000000000000000 +RDX: 0000000000000000 RSI: ffff88807dc1c540 RDI: ffff88807dc1c540 +RBP: ffffc90000003e48 R08: ffffffff82b392c8 R09: 00000000ffffdfff +R10: ffffffff82a592e0 R11: ffffffff82b092e0 R12: ffff888005b1c800 +R13: ffff8880070b51b8 R14: ffff888005b1ca18 R15: ffff8880070b5190 +FS: 00007f4539f0b740(0000) GS:ffff88807dc00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 000055670baf3000 CR3: 0000000005b0e000 CR4: 00000000007506f0 +PKRU: 55555554 +Call Trace: + + skb_push (net/core/skbuff.c:210) + ipv6_rthdr_rcv (./include/linux/skbuff.h:2880 net/ipv6/exthdrs.c:634 net/ipv6/exthdrs.c:718) + ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:437 (discriminator 5)) + ip6_input_finish (./include/linux/rcupdate.h:805 net/ipv6/ip6_input.c:483) + __netif_receive_skb_one_core (net/core/dev.c:5494) + process_backlog (./include/linux/rcupdate.h:805 net/core/dev.c:5934) + __napi_poll (net/core/dev.c:6496) + net_rx_action (net/core/dev.c:6565 net/core/dev.c:6696) + __do_softirq (./arch/x86/include/asm/jump_label.h:27 ./include/linux/jump_label.h:207 ./include/trace/events/irq.h:142 kernel/softirq.c:572) + do_softirq (kernel/softirq.c:472 kernel/softirq.c:459) + + + __local_bh_enable_ip (kernel/softirq.c:396) + __dev_queue_xmit (net/core/dev.c:4272) + ip6_finish_output2 (./include/net/neighbour.h:544 net/ipv6/ip6_output.c:134) + rawv6_sendmsg (./include/net/dst.h:458 ./include/linux/netfilter.h:303 net/ipv6/raw.c:656 net/ipv6/raw.c:914) + sock_sendmsg (net/socket.c:724 net/socket.c:747) + __sys_sendto (net/socket.c:2144) + __x64_sys_sendto (net/socket.c:2156 net/socket.c:2152 net/socket.c:2152) + do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) +RIP: 0033:0x7f453a138aea +Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 7e c3 0f 1f 44 00 00 41 54 48 83 ec 30 44 89 +RSP: 002b:00007ffcc212a1c8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c +RAX: ffffffffffffffda RBX: 00007ffcc212a288 RCX: 00007f453a138aea +RDX: 0000000000000060 RSI: 00007f4539084c20 RDI: 0000000000000003 +RBP: 00007f4538308e80 R08: 00007ffcc212a300 R09: 000000000000001c +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: ffffffffc4653600 R14: 0000000000000001 R15: 00007f4539712d1b + +Modules linked in: + +Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr") +Reported-by: Max VA +Closes: https://www.interruptlabs.co.uk/articles/linux-ipv6-route-of-death +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20230605180617.67284-1-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/rpl.h | 3 --- + net/ipv6/exthdrs.c | 29 +++++++++++------------------ + 2 files changed, 11 insertions(+), 21 deletions(-) + +diff --git a/include/net/rpl.h b/include/net/rpl.h +index 308ef0a05caef..30fe780d1e7c8 100644 +--- a/include/net/rpl.h ++++ b/include/net/rpl.h +@@ -23,9 +23,6 @@ static inline int rpl_init(void) + static inline void rpl_exit(void) {} + #endif + +-/* Worst decompression memory usage ipv6 address (16) + pad 7 */ +-#define IPV6_RPL_SRH_WORST_SWAP_SIZE (sizeof(struct in6_addr) + 7) +- + size_t ipv6_rpl_srh_size(unsigned char n, unsigned char cmpri, + unsigned char cmpre); + +diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c +index 3a871a09f9625..d273f6fe19c20 100644 +--- a/net/ipv6/exthdrs.c ++++ b/net/ipv6/exthdrs.c +@@ -564,24 +564,6 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb) + return -1; + } + +- if (skb_cloned(skb)) { +- if (pskb_expand_head(skb, IPV6_RPL_SRH_WORST_SWAP_SIZE, 0, +- GFP_ATOMIC)) { +- __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), +- IPSTATS_MIB_OUTDISCARDS); +- kfree_skb(skb); +- return -1; +- } +- } else { +- err = skb_cow_head(skb, IPV6_RPL_SRH_WORST_SWAP_SIZE); +- if (unlikely(err)) { +- kfree_skb(skb); +- return -1; +- } +- } +- +- hdr = (struct ipv6_rpl_sr_hdr *)skb_transport_header(skb); +- + if (!pskb_may_pull(skb, ipv6_rpl_srh_size(n, hdr->cmpri, + hdr->cmpre))) { + kfree_skb(skb); +@@ -627,6 +609,17 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb) + skb_pull(skb, ((hdr->hdrlen + 1) << 3)); + skb_postpull_rcsum(skb, oldhdr, + sizeof(struct ipv6hdr) + ((hdr->hdrlen + 1) << 3)); ++ if (unlikely(!hdr->segments_left)) { ++ if (pskb_expand_head(skb, sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3), 0, ++ GFP_ATOMIC)) { ++ __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_OUTDISCARDS); ++ kfree_skb(skb); ++ kfree(buf); ++ return -1; ++ } ++ ++ oldhdr = ipv6_hdr(skb); ++ } + skb_push(skb, ((chdr->hdrlen + 1) << 3) + sizeof(struct ipv6hdr)); + skb_reset_network_header(skb); + skb_mac_header_rebuild(skb); +-- +2.39.2 + diff --git a/queue-5.15/lib-cpu_rmap-fix-potential-use-after-free-in-irq_cpu.patch b/queue-5.15/lib-cpu_rmap-fix-potential-use-after-free-in-irq_cpu.patch new file mode 100644 index 00000000000..8d1fb8261d8 --- /dev/null +++ b/queue-5.15/lib-cpu_rmap-fix-potential-use-after-free-in-irq_cpu.patch @@ -0,0 +1,40 @@ +From 9c0f0edb9075d0e285c981d9d6fee8ad9ace0261 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Jun 2023 20:28:15 +0200 +Subject: lib: cpu_rmap: Fix potential use-after-free in irq_cpu_rmap_release() + +From: Ben Hutchings + +[ Upstream commit 7c5d4801ecf0564c860033d89726b99723c55146 ] + +irq_cpu_rmap_release() calls cpu_rmap_put(), which may free the rmap. +So we need to clear the pointer to our glue structure in rmap before +doing that, not after. + +Fixes: 4e0473f1060a ("lib: cpu_rmap: Avoid use after free on rmap->obj array entries") +Signed-off-by: Ben Hutchings +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/ZHo0vwquhOy3FaXc@decadent.org.uk +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + lib/cpu_rmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c +index e77f12bb3c774..1833ad73de6fc 100644 +--- a/lib/cpu_rmap.c ++++ b/lib/cpu_rmap.c +@@ -268,8 +268,8 @@ static void irq_cpu_rmap_release(struct kref *ref) + struct irq_glue *glue = + container_of(ref, struct irq_glue, notify.kref); + +- cpu_rmap_put(glue->rmap); + glue->rmap->obj[glue->index] = NULL; ++ cpu_rmap_put(glue->rmap); + kfree(glue); + } + +-- +2.39.2 + diff --git a/queue-5.15/neighbour-fix-unaligned-access-to-pneigh_entry.patch b/queue-5.15/neighbour-fix-unaligned-access-to-pneigh_entry.patch new file mode 100644 index 00000000000..5e33aa81a83 --- /dev/null +++ b/queue-5.15/neighbour-fix-unaligned-access-to-pneigh_entry.patch @@ -0,0 +1,41 @@ +From 06bd6d3e599d2d9b09afbe14db0815b2dffc739c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Jun 2023 09:54:32 +0800 +Subject: neighbour: fix unaligned access to pneigh_entry + +From: Qingfang DENG + +[ Upstream commit ed779fe4c9b5a20b4ab4fd6f3e19807445bb78c7 ] + +After the blamed commit, the member key is longer 4-byte aligned. On +platforms that do not support unaligned access, e.g., MIPS32R2 with +unaligned_action set to 1, this will trigger a crash when accessing +an IPv6 pneigh_entry, as the key is cast to an in6_addr pointer. + +Change the type of the key to u32 to make it aligned. + +Fixes: 62dd93181aaa ("[IPV6] NDISC: Set per-entry is_router flag in Proxy NA.") +Signed-off-by: Qingfang DENG +Link: https://lore.kernel.org/r/20230601015432.159066-1-dqfext@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/neighbour.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/neighbour.h b/include/net/neighbour.h +index d5767e25509cc..abb22cfd4827f 100644 +--- a/include/net/neighbour.h ++++ b/include/net/neighbour.h +@@ -174,7 +174,7 @@ struct pneigh_entry { + struct net_device *dev; + u8 flags; + u8 protocol; +- u8 key[]; ++ u32 key[]; + }; + + /* +-- +2.39.2 + diff --git a/queue-5.15/net-dsa-lan9303-allow-vid-0-in-port_fdb_-add-del-met.patch b/queue-5.15/net-dsa-lan9303-allow-vid-0-in-port_fdb_-add-del-met.patch new file mode 100644 index 00000000000..63181db752c --- /dev/null +++ b/queue-5.15/net-dsa-lan9303-allow-vid-0-in-port_fdb_-add-del-met.patch @@ -0,0 +1,56 @@ +From c9d0804e38f86a208a86cd897c7d933c91aac568 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 May 2023 16:38:26 +0200 +Subject: net: dsa: lan9303: allow vid != 0 in port_fdb_{add|del} methods + +From: Alexander Sverdlin + +[ Upstream commit 5a59a58ec25d44f853c26bdbfda47d73b3067435 ] + +LAN9303 doesn't associate FDB (ALR) entries with VLANs, it has just one +global Address Logic Resolution table [1]. + +Ignore VID in port_fdb_{add|del} methods, go on with the global table. This +is the same semantics as hellcreek or RZ/N1 implement. + +Visible symptoms: +LAN9303_MDIO 5b050000.ethernet-1:00: port 2 failed to delete 00:xx:xx:xx:xx:cf vid 1 from fdb: -2 +LAN9303_MDIO 5b050000.ethernet-1:00: port 2 failed to add 00:xx:xx:xx:xx:cf vid 1 to fdb: -95 + +[1] https://ww1.microchip.com/downloads/en/DeviceDoc/00002308A.pdf + +Fixes: 0620427ea0d6 ("net: dsa: lan9303: Add fdb/mdb manipulation") +Signed-off-by: Alexander Sverdlin +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20230531143826.477267-1-alexander.sverdlin@siemens.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/lan9303-core.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c +index 22547b10dfe50..63826553719bf 100644 +--- a/drivers/net/dsa/lan9303-core.c ++++ b/drivers/net/dsa/lan9303-core.c +@@ -1194,8 +1194,6 @@ static int lan9303_port_fdb_add(struct dsa_switch *ds, int port, + struct lan9303 *chip = ds->priv; + + dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, addr, vid); +- if (vid) +- return -EOPNOTSUPP; + + return lan9303_alr_add_port(chip, addr, port, false); + } +@@ -1207,8 +1205,6 @@ static int lan9303_port_fdb_del(struct dsa_switch *ds, int port, + struct lan9303 *chip = ds->priv; + + dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, addr, vid); +- if (vid) +- return -EOPNOTSUPP; + lan9303_alr_del_port(chip, addr, port); + + return 0; +-- +2.39.2 + diff --git a/queue-5.15/net-enetc-correct-the-statistics-of-rx-bytes.patch b/queue-5.15/net-enetc-correct-the-statistics-of-rx-bytes.patch new file mode 100644 index 00000000000..11a48fe4858 --- /dev/null +++ b/queue-5.15/net-enetc-correct-the-statistics-of-rx-bytes.patch @@ -0,0 +1,50 @@ +From cb5a832ae2d32580ad2de97b56bbba7e11de7878 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Jun 2023 17:46:58 +0800 +Subject: net: enetc: correct the statistics of rx bytes + +From: Wei Fang + +[ Upstream commit 7190d0ff0e17690a9b1279d84a06473600ba2060 ] + +The rx_bytes of struct net_device_stats should count the length of +ethernet frames excluding the FCS. However, there are two problems +with the rx_bytes statistics of the current enetc driver. one is +that the length of VLAN header is not counted if the VLAN extraction +feature is enabled. The other is that the length of L2 header is not +counted, because eth_type_trans() is invoked before updating rx_bytes +which will subtract the length of L2 header from skb->len. +BTW, the rx_bytes statistics of XDP path also have similar problem, +I will fix it in another patch. + +Fixes: a800abd3ecb9 ("net: enetc: move skb creation into enetc_build_skb") +Signed-off-by: Wei Fang +Reviewed-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/enetc/enetc.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c +index 8b7c93447770c..e16bd2b7692f3 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -940,7 +940,13 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, + if (!skb) + break; + +- rx_byte_cnt += skb->len; ++ /* When set, the outer VLAN header is extracted and reported ++ * in the receive buffer descriptor. So rx_byte_cnt should ++ * add the length of the extracted VLAN header. ++ */ ++ if (bd_status & ENETC_RXBD_FLAG_VLAN) ++ rx_byte_cnt += VLAN_HLEN; ++ rx_byte_cnt += skb->len + ETH_HLEN; + rx_frm_cnt++; + + napi_gro_receive(napi, skb); +-- +2.39.2 + diff --git a/queue-5.15/net-ipv6-fix-bool-int-mismatch-for-skip_notify_on_de.patch b/queue-5.15/net-ipv6-fix-bool-int-mismatch-for-skip_notify_on_de.patch new file mode 100644 index 00000000000..336f1241ab7 --- /dev/null +++ b/queue-5.15/net-ipv6-fix-bool-int-mismatch-for-skip_notify_on_de.patch @@ -0,0 +1,43 @@ +From 359d9c28c3ce8355cacf93fec20c3decacfe22f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Jun 2023 16:04:44 +0000 +Subject: net/ipv6: fix bool/int mismatch for skip_notify_on_dev_down + +From: Eric Dumazet + +[ Upstream commit edf2e1d2019b2730d6076dbe4c040d37d7c10bbe ] + +skip_notify_on_dev_down ctl table expects this field +to be an int (4 bytes), not a bool (1 byte). + +Because proc_dou8vec_minmax() was added in 5.13, +this patch converts skip_notify_on_dev_down to an int. + +Following patch then converts the field to u8 and use proc_dou8vec_minmax(). + +Fixes: 7c6bb7d2faaf ("net/ipv6: Add knob to skip DELROUTE message on device down") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Acked-by: Matthieu Baerts +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/netns/ipv6.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h +index ff82983b7ab41..181b44f6fb686 100644 +--- a/include/net/netns/ipv6.h ++++ b/include/net/netns/ipv6.h +@@ -53,7 +53,7 @@ struct netns_sysctl_ipv6 { + int seg6_flowlabel; + u32 ioam6_id; + u64 ioam6_id_wide; +- bool skip_notify_on_dev_down; ++ int skip_notify_on_dev_down; + u8 fib_notify_on_flag_change; + }; + +-- +2.39.2 + diff --git a/queue-5.15/net-sched-act_police-fix-sparse-errors-in-tcf_police.patch b/queue-5.15/net-sched-act_police-fix-sparse-errors-in-tcf_police.patch new file mode 100644 index 00000000000..4a0d5e7134a --- /dev/null +++ b/queue-5.15/net-sched-act_police-fix-sparse-errors-in-tcf_police.patch @@ -0,0 +1,66 @@ +From b4ede3113fc8ef3634dab050c525623cb31be2de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Jun 2023 13:13:04 +0000 +Subject: net: sched: act_police: fix sparse errors in tcf_police_dump() + +From: Eric Dumazet + +[ Upstream commit 682881ee45c81daa883dcd4fe613b0b0d988bb22 ] + +Fixes following sparse errors: + +net/sched/act_police.c:360:28: warning: dereference of noderef expression +net/sched/act_police.c:362:45: warning: dereference of noderef expression +net/sched/act_police.c:362:45: warning: dereference of noderef expression +net/sched/act_police.c:368:28: warning: dereference of noderef expression +net/sched/act_police.c:370:45: warning: dereference of noderef expression +net/sched/act_police.c:370:45: warning: dereference of noderef expression +net/sched/act_police.c:376:45: warning: dereference of noderef expression +net/sched/act_police.c:376:45: warning: dereference of noderef expression + +Fixes: d1967e495a8d ("net_sched: act_police: add 2 new attributes to support police 64bit rate and peakrate") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/sched/act_police.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/sched/act_police.c b/net/sched/act_police.c +index d44b933b821d7..db1d021c16be8 100644 +--- a/net/sched/act_police.c ++++ b/net/sched/act_police.c +@@ -366,23 +366,23 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a, + opt.burst = PSCHED_NS2TICKS(p->tcfp_burst); + if (p->rate_present) { + psched_ratecfg_getrate(&opt.rate, &p->rate); +- if ((police->params->rate.rate_bytes_ps >= (1ULL << 32)) && ++ if ((p->rate.rate_bytes_ps >= (1ULL << 32)) && + nla_put_u64_64bit(skb, TCA_POLICE_RATE64, +- police->params->rate.rate_bytes_ps, ++ p->rate.rate_bytes_ps, + TCA_POLICE_PAD)) + goto nla_put_failure; + } + if (p->peak_present) { + psched_ratecfg_getrate(&opt.peakrate, &p->peak); +- if ((police->params->peak.rate_bytes_ps >= (1ULL << 32)) && ++ if ((p->peak.rate_bytes_ps >= (1ULL << 32)) && + nla_put_u64_64bit(skb, TCA_POLICE_PEAKRATE64, +- police->params->peak.rate_bytes_ps, ++ p->peak.rate_bytes_ps, + TCA_POLICE_PAD)) + goto nla_put_failure; + } + if (p->pps_present) { + if (nla_put_u64_64bit(skb, TCA_POLICE_PKTRATE64, +- police->params->ppsrate.rate_pkts_ps, ++ p->ppsrate.rate_pkts_ps, + TCA_POLICE_PAD)) + goto nla_put_failure; + if (nla_put_u64_64bit(skb, TCA_POLICE_PKTBURST64, +-- +2.39.2 + diff --git a/queue-5.15/net-sched-fix-possible-refcount-leak-in-tc_chain_tmp.patch b/queue-5.15/net-sched-fix-possible-refcount-leak-in-tc_chain_tmp.patch new file mode 100644 index 00000000000..0bac6901e82 --- /dev/null +++ b/queue-5.15/net-sched-fix-possible-refcount-leak-in-tc_chain_tmp.patch @@ -0,0 +1,37 @@ +From dac86e9de9ba10d1bbec4c984775fbb49cdc7e14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jun 2023 10:23:01 +0800 +Subject: net: sched: fix possible refcount leak in tc_chain_tmplt_add() + +From: Hangyu Hua + +[ Upstream commit 44f8baaf230c655c249467ca415b570deca8df77 ] + +try_module_get will be called in tcf_proto_lookup_ops. So module_put needs +to be called to drop the refcount if ops don't implement the required +function. + +Fixes: 9f407f1768d3 ("net: sched: introduce chain templates") +Signed-off-by: Hangyu Hua +Reviewed-by: Larysa Zaremba +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/sched/cls_api.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c +index 0aca0ecb029bd..d88a0946301c5 100644 +--- a/net/sched/cls_api.c ++++ b/net/sched/cls_api.c +@@ -2766,6 +2766,7 @@ static int tc_chain_tmplt_add(struct tcf_chain *chain, struct net *net, + return PTR_ERR(ops); + if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) { + NL_SET_ERR_MSG(extack, "Chain templates are not supported with specified classifier"); ++ module_put(ops->owner); + return -EOPNOTSUPP; + } + +-- +2.39.2 + diff --git a/queue-5.15/net-sched-fq_pie-ensure-reasonable-tca_fq_pie_quantu.patch b/queue-5.15/net-sched-fq_pie-ensure-reasonable-tca_fq_pie_quantu.patch new file mode 100644 index 00000000000..004ecb52b59 --- /dev/null +++ b/queue-5.15/net-sched-fq_pie-ensure-reasonable-tca_fq_pie_quantu.patch @@ -0,0 +1,129 @@ +From 2abb44ca0ce13c7e784cd630575d1432f06bb60f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Jun 2023 12:37:47 +0000 +Subject: net/sched: fq_pie: ensure reasonable TCA_FQ_PIE_QUANTUM values + +From: Eric Dumazet + +[ Upstream commit cd2b8113c2e8b9f5a88a942e1eaca61eba401b85 ] + +We got multiple syzbot reports, all duplicates of the following [1] + +syzbot managed to install fq_pie with a zero TCA_FQ_PIE_QUANTUM, +thus triggering infinite loops. + +Use limits similar to sch_fq, with commits +3725a269815b ("pkt_sched: fq: avoid hang when quantum 0") and +d9e15a273306 ("pkt_sched: fq: do not accept silly TCA_FQ_QUANTUM") + +[1] +watchdog: BUG: soft lockup - CPU#0 stuck for 26s! [swapper/0:0] +Modules linked in: +irq event stamp: 172817 +hardirqs last enabled at (172816): [] __el1_irq arch/arm64/kernel/entry-common.c:476 [inline] +hardirqs last enabled at (172816): [] el1_interrupt+0x58/0x68 arch/arm64/kernel/entry-common.c:486 +hardirqs last disabled at (172817): [] __el1_irq arch/arm64/kernel/entry-common.c:468 [inline] +hardirqs last disabled at (172817): [] el1_interrupt+0x24/0x68 arch/arm64/kernel/entry-common.c:486 +softirqs last enabled at (167634): [] softirq_handle_end kernel/softirq.c:414 [inline] +softirqs last enabled at (167634): [] __do_softirq+0xac0/0xd54 kernel/softirq.c:600 +softirqs last disabled at (167701): [] ____do_softirq+0x14/0x20 arch/arm64/kernel/irq.c:80 +CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.4.0-rc3-syzkaller-geb0f1697d729 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/28/2023 +pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : fq_pie_qdisc_dequeue+0x10c/0x8ac net/sched/sch_fq_pie.c:246 +lr : fq_pie_qdisc_dequeue+0xe4/0x8ac net/sched/sch_fq_pie.c:240 +sp : ffff800008007210 +x29: ffff800008007280 x28: ffff0000c86f7890 x27: ffff0000cb20c2e8 +x26: ffff0000cb20c2f0 x25: dfff800000000000 x24: ffff0000cb20c2e0 +x23: ffff0000c86f7880 x22: 0000000000000040 x21: 1fffe000190def10 +x20: ffff0000cb20c2e0 x19: ffff0000cb20c2e0 x18: ffff800008006e60 +x17: 0000000000000000 x16: ffff80000850af6c x15: 0000000000000302 +x14: 0000000000000100 x13: 0000000000000000 x12: 0000000000000001 +x11: 0000000000000302 x10: 0000000000000100 x9 : 0000000000000000 +x8 : 0000000000000000 x7 : ffff80000841c468 x6 : 0000000000000000 +x5 : 0000000000000001 x4 : 0000000000000001 x3 : 0000000000000000 +x2 : ffff0000cb20c2e0 x1 : ffff0000cb20c2e0 x0 : 0000000000000001 +Call trace: +fq_pie_qdisc_dequeue+0x10c/0x8ac net/sched/sch_fq_pie.c:246 +dequeue_skb net/sched/sch_generic.c:292 [inline] +qdisc_restart net/sched/sch_generic.c:397 [inline] +__qdisc_run+0x1fc/0x231c net/sched/sch_generic.c:415 +__dev_xmit_skb net/core/dev.c:3868 [inline] +__dev_queue_xmit+0xc80/0x3318 net/core/dev.c:4210 +dev_queue_xmit include/linux/netdevice.h:3085 [inline] +neigh_connected_output+0x2f8/0x38c net/core/neighbour.c:1581 +neigh_output include/net/neighbour.h:544 [inline] +ip6_finish_output2+0xd60/0x1a1c net/ipv6/ip6_output.c:134 +__ip6_finish_output net/ipv6/ip6_output.c:195 [inline] +ip6_finish_output+0x538/0x8c8 net/ipv6/ip6_output.c:206 +NF_HOOK_COND include/linux/netfilter.h:292 [inline] +ip6_output+0x270/0x594 net/ipv6/ip6_output.c:227 +dst_output include/net/dst.h:458 [inline] +NF_HOOK include/linux/netfilter.h:303 [inline] +ndisc_send_skb+0xc30/0x1790 net/ipv6/ndisc.c:508 +ndisc_send_rs+0x47c/0x5d4 net/ipv6/ndisc.c:718 +addrconf_rs_timer+0x300/0x58c net/ipv6/addrconf.c:3936 +call_timer_fn+0x19c/0x8cc kernel/time/timer.c:1700 +expire_timers kernel/time/timer.c:1751 [inline] +__run_timers+0x55c/0x734 kernel/time/timer.c:2022 +run_timer_softirq+0x7c/0x114 kernel/time/timer.c:2035 +__do_softirq+0x2d0/0xd54 kernel/softirq.c:571 +____do_softirq+0x14/0x20 arch/arm64/kernel/irq.c:80 +call_on_irq_stack+0x24/0x4c arch/arm64/kernel/entry.S:882 +do_softirq_own_stack+0x20/0x2c arch/arm64/kernel/irq.c:85 +invoke_softirq kernel/softirq.c:452 [inline] +__irq_exit_rcu+0x28c/0x534 kernel/softirq.c:650 +irq_exit_rcu+0x14/0x84 kernel/softirq.c:662 +__el1_irq arch/arm64/kernel/entry-common.c:472 [inline] +el1_interrupt+0x38/0x68 arch/arm64/kernel/entry-common.c:486 +el1h_64_irq_handler+0x18/0x24 arch/arm64/kernel/entry-common.c:491 +el1h_64_irq+0x64/0x68 arch/arm64/kernel/entry.S:587 +__daif_local_irq_enable arch/arm64/include/asm/irqflags.h:33 [inline] +arch_local_irq_enable+0x8/0xc arch/arm64/include/asm/irqflags.h:55 +cpuidle_idle_call kernel/sched/idle.c:170 [inline] +do_idle+0x1f0/0x4e8 kernel/sched/idle.c:282 +cpu_startup_entry+0x24/0x28 kernel/sched/idle.c:379 +rest_init+0x2dc/0x2f4 init/main.c:735 +start_kernel+0x0/0x55c init/main.c:834 +start_kernel+0x3f0/0x55c init/main.c:1088 +__primary_switched+0xb8/0xc0 arch/arm64/kernel/head.S:523 + +Fixes: ec97ecf1ebe4 ("net: sched: add Flow Queue PIE packet scheduler") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Reviewed-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/sched/sch_fq_pie.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c +index 35c35465226bd..ce7833f95214f 100644 +--- a/net/sched/sch_fq_pie.c ++++ b/net/sched/sch_fq_pie.c +@@ -201,6 +201,11 @@ static int fq_pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return NET_XMIT_CN; + } + ++static struct netlink_range_validation fq_pie_q_range = { ++ .min = 1, ++ .max = 1 << 20, ++}; ++ + static const struct nla_policy fq_pie_policy[TCA_FQ_PIE_MAX + 1] = { + [TCA_FQ_PIE_LIMIT] = {.type = NLA_U32}, + [TCA_FQ_PIE_FLOWS] = {.type = NLA_U32}, +@@ -208,7 +213,8 @@ static const struct nla_policy fq_pie_policy[TCA_FQ_PIE_MAX + 1] = { + [TCA_FQ_PIE_TUPDATE] = {.type = NLA_U32}, + [TCA_FQ_PIE_ALPHA] = {.type = NLA_U32}, + [TCA_FQ_PIE_BETA] = {.type = NLA_U32}, +- [TCA_FQ_PIE_QUANTUM] = {.type = NLA_U32}, ++ [TCA_FQ_PIE_QUANTUM] = ++ NLA_POLICY_FULL_RANGE(NLA_U32, &fq_pie_q_range), + [TCA_FQ_PIE_MEMORY_LIMIT] = {.type = NLA_U32}, + [TCA_FQ_PIE_ECN_PROB] = {.type = NLA_U32}, + [TCA_FQ_PIE_ECN] = {.type = NLA_U32}, +-- +2.39.2 + diff --git a/queue-5.15/net-sched-move-rtm_tca_policy-declaration-to-include.patch b/queue-5.15/net-sched-move-rtm_tca_policy-declaration-to-include.patch new file mode 100644 index 00000000000..f981ae7a359 --- /dev/null +++ b/queue-5.15/net-sched-move-rtm_tca_policy-declaration-to-include.patch @@ -0,0 +1,54 @@ +From 0dd31dc60e56199f42d9e6a28f05b6afb4f5e8cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Jun 2023 11:42:33 +0000 +Subject: net: sched: move rtm_tca_policy declaration to include file + +From: Eric Dumazet + +[ Upstream commit 886bc7d6ed3357975c5f1d3c784da96000d4bbb4 ] + +rtm_tca_policy is used from net/sched/sch_api.c and net/sched/cls_api.c, +thus should be declared in an include file. + +This fixes the following sparse warning: +net/sched/sch_api.c:1434:25: warning: symbol 'rtm_tca_policy' was not declared. Should it be static? + +Fixes: e331473fee3d ("net/sched: cls_api: add missing validation of netlink attributes") +Signed-off-by: Eric Dumazet +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/pkt_sched.h | 2 ++ + net/sched/cls_api.c | 2 -- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h +index 9e7b21c0b3a6d..9cd2d4e84913f 100644 +--- a/include/net/pkt_sched.h ++++ b/include/net/pkt_sched.h +@@ -134,6 +134,8 @@ static inline void qdisc_run(struct Qdisc *q) + } + } + ++extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; ++ + /* Calculate maximal size of packet seen by hard_start_xmit + routine of this device. + */ +diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c +index 501e05943f02b..0aca0ecb029bd 100644 +--- a/net/sched/cls_api.c ++++ b/net/sched/cls_api.c +@@ -41,8 +41,6 @@ + #include + #include + +-extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; +- + /* The list of all installed classifier types */ + static LIST_HEAD(tcf_proto_base); + +-- +2.39.2 + diff --git a/queue-5.15/net-smc-avoid-to-access-invalid-rmbs-mrs-in-smcrv1-a.patch b/queue-5.15/net-smc-avoid-to-access-invalid-rmbs-mrs-in-smcrv1-a.patch new file mode 100644 index 00000000000..9bb5a812b1d --- /dev/null +++ b/queue-5.15/net-smc-avoid-to-access-invalid-rmbs-mrs-in-smcrv1-a.patch @@ -0,0 +1,89 @@ +From 5f8330746d165027eefeaf2e14ed4d9b0edff589 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Jun 2023 16:41:52 +0800 +Subject: net/smc: Avoid to access invalid RMBs' MRs in SMCRv1 ADD LINK CONT + +From: Wen Gu + +[ Upstream commit c308e9ec004721a656c193243eab61a8be324657 ] + +SMCRv1 has a similar issue to SMCRv2 (see link below) that may access +invalid MRs of RMBs when construct LLC ADD LINK CONT messages. + + BUG: kernel NULL pointer dereference, address: 0000000000000014 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 0 P4D 0 + Oops: 0000 [#1] PREEMPT SMP PTI + CPU: 5 PID: 48 Comm: kworker/5:0 Kdump: loaded Tainted: G W E 6.4.0-rc3+ #49 + Workqueue: events smc_llc_add_link_work [smc] + RIP: 0010:smc_llc_add_link_cont+0x160/0x270 [smc] + RSP: 0018:ffffa737801d3d50 EFLAGS: 00010286 + RAX: ffff964f82144000 RBX: ffffa737801d3dd8 RCX: 0000000000000000 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff964f81370c30 + RBP: ffffa737801d3dd4 R08: ffff964f81370000 R09: ffffa737801d3db0 + R10: 0000000000000001 R11: 0000000000000060 R12: ffff964f82e70000 + R13: ffff964f81370c38 R14: ffffa737801d3dd3 R15: 0000000000000001 + FS: 0000000000000000(0000) GS:ffff9652bfd40000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000014 CR3: 000000008fa20004 CR4: 00000000003706e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Call Trace: + + smc_llc_srv_rkey_exchange+0xa7/0x190 [smc] + smc_llc_srv_add_link+0x3ae/0x5a0 [smc] + smc_llc_add_link_work+0xb8/0x140 [smc] + process_one_work+0x1e5/0x3f0 + worker_thread+0x4d/0x2f0 + ? __pfx_worker_thread+0x10/0x10 + kthread+0xe5/0x120 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x2c/0x50 + + +When an alernate RNIC is available in system, SMC will try to add a new +link based on the RNIC for resilience. All the RMBs in use will be mapped +to the new link. Then the RMBs' MRs corresponding to the new link will +be filled into LLC messages. For SMCRv1, they are ADD LINK CONT messages. + +However smc_llc_add_link_cont() may mistakenly access to unused RMBs which +haven't been mapped to the new link and have no valid MRs, thus causing a +crash. So this patch fixes it. + +Fixes: 87f88cda2128 ("net/smc: rkey processing for a new link as SMC client") +Link: https://lore.kernel.org/r/1685101741-74826-3-git-send-email-guwen@linux.alibaba.com +Signed-off-by: Wen Gu +Reviewed-by: Wenjia Zhang +Reviewed-by: Tony Lu +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/smc/smc_llc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c +index 0ef15f8fba902..d5ee961ca72d5 100644 +--- a/net/smc/smc_llc.c ++++ b/net/smc/smc_llc.c +@@ -716,6 +716,8 @@ static int smc_llc_add_link_cont(struct smc_link *link, + addc_llc->num_rkeys = *num_rkeys_todo; + n = *num_rkeys_todo; + for (i = 0; i < min_t(u8, n, SMC_LLC_RKEYS_PER_CONT_MSG); i++) { ++ while (*buf_pos && !(*buf_pos)->used) ++ *buf_pos = smc_llc_get_next_rmb(lgr, buf_lst, *buf_pos); + if (!*buf_pos) { + addc_llc->num_rkeys = addc_llc->num_rkeys - + *num_rkeys_todo; +@@ -731,8 +733,6 @@ static int smc_llc_add_link_cont(struct smc_link *link, + + (*num_rkeys_todo)--; + *buf_pos = smc_llc_get_next_rmb(lgr, buf_lst, *buf_pos); +- while (*buf_pos && !(*buf_pos)->used) +- *buf_pos = smc_llc_get_next_rmb(lgr, buf_lst, *buf_pos); + } + addc_llc->hd.common.type = SMC_LLC_ADD_LINK_CONT; + addc_llc->hd.length = sizeof(struct smc_llc_msg_add_link_cont); +-- +2.39.2 + diff --git a/queue-5.15/netfilter-conntrack-fix-null-pointer-dereference-in-.patch b/queue-5.15/netfilter-conntrack-fix-null-pointer-dereference-in-.patch new file mode 100644 index 00000000000..545194872ed --- /dev/null +++ b/queue-5.15/netfilter-conntrack-fix-null-pointer-dereference-in-.patch @@ -0,0 +1,59 @@ +From 1f51122ad28a9165953841b548e4b19dabe8ee95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 May 2023 12:25:26 +0200 +Subject: netfilter: conntrack: fix NULL pointer dereference in + nf_confirm_cthelper + +From: Tijs Van Buggenhout + +[ Upstream commit e1f543dc660b44618a1bd72ddb4ca0828a95f7ad ] + +An nf_conntrack_helper from nf_conn_help may become NULL after DNAT. + +Observed when TCP port 1720 (Q931_PORT), associated with h323 conntrack +helper, is DNAT'ed to another destination port (e.g. 1730), while +nfqueue is being used for final acceptance (e.g. snort). + +This happenned after transition from kernel 4.14 to 5.10.161. + +Workarounds: + * keep the same port (1720) in DNAT + * disable nfqueue + * disable/unload h323 NAT helper + +$ linux-5.10/scripts/decode_stacktrace.sh vmlinux < /tmp/kernel.log +BUG: kernel NULL pointer dereference, address: 0000000000000084 +[..] +RIP: 0010:nf_conntrack_update (net/netfilter/nf_conntrack_core.c:2080 net/netfilter/nf_conntrack_core.c:2134) nf_conntrack +[..] +nfqnl_reinject (net/netfilter/nfnetlink_queue.c:237) nfnetlink_queue +nfqnl_recv_verdict (net/netfilter/nfnetlink_queue.c:1230) nfnetlink_queue +nfnetlink_rcv_msg (net/netfilter/nfnetlink.c:241) nfnetlink +[..] + +Fixes: ee04805ff54a ("netfilter: conntrack: make conntrack userspace helpers work again") +Signed-off-by: Tijs Van Buggenhout +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index 7ff0da5f998a0..10622760f894a 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -2224,6 +2224,9 @@ static int nf_confirm_cthelper(struct sk_buff *skb, struct nf_conn *ct, + return 0; + + helper = rcu_dereference(help->helper); ++ if (!helper) ++ return 0; ++ + if (!(helper->flags & NF_CT_HELPER_F_USERSPACE)) + return 0; + +-- +2.39.2 + diff --git a/queue-5.15/netfilter-ipset-add-schedule-point-in-call_ad.patch b/queue-5.15/netfilter-ipset-add-schedule-point-in-call_ad.patch new file mode 100644 index 00000000000..2b2230f37dd --- /dev/null +++ b/queue-5.15/netfilter-ipset-add-schedule-point-in-call_ad.patch @@ -0,0 +1,100 @@ +From 97edfd1826e04f5251015cbd30f5b4cb44717be6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 May 2023 10:33:00 -0700 +Subject: netfilter: ipset: Add schedule point in call_ad(). + +From: Kuniyuki Iwashima + +[ Upstream commit 24e227896bbf003165e006732dccb3516f87f88e ] + +syzkaller found a repro that causes Hung Task [0] with ipset. The repro +first creates an ipset and then tries to delete a large number of IPs +from the ipset concurrently: + + IPSET_ATTR_IPADDR_IPV4 : 172.20.20.187 + IPSET_ATTR_CIDR : 2 + +The first deleting thread hogs a CPU with nfnl_lock(NFNL_SUBSYS_IPSET) +held, and other threads wait for it to be released. + +Previously, the same issue existed in set->variant->uadt() that could run +so long under ip_set_lock(set). Commit 5e29dc36bd5e ("netfilter: ipset: +Rework long task execution when adding/deleting entries") tried to fix it, +but the issue still exists in the caller with another mutex. + +While adding/deleting many IPs, we should release the CPU periodically to +prevent someone from abusing ipset to hang the system. + +Note we need to increment the ipset's refcnt to prevent the ipset from +being destroyed while rescheduling. + +[0]: +INFO: task syz-executor174:268 blocked for more than 143 seconds. + Not tainted 6.4.0-rc1-00145-gba79e9a73284 #1 +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +task:syz-executor174 state:D stack:0 pid:268 ppid:260 flags:0x0000000d +Call trace: + __switch_to+0x308/0x714 arch/arm64/kernel/process.c:556 + context_switch kernel/sched/core.c:5343 [inline] + __schedule+0xd84/0x1648 kernel/sched/core.c:6669 + schedule+0xf0/0x214 kernel/sched/core.c:6745 + schedule_preempt_disabled+0x58/0xf0 kernel/sched/core.c:6804 + __mutex_lock_common kernel/locking/mutex.c:679 [inline] + __mutex_lock+0x6fc/0xdb0 kernel/locking/mutex.c:747 + __mutex_lock_slowpath+0x14/0x20 kernel/locking/mutex.c:1035 + mutex_lock+0x98/0xf0 kernel/locking/mutex.c:286 + nfnl_lock net/netfilter/nfnetlink.c:98 [inline] + nfnetlink_rcv_msg+0x480/0x70c net/netfilter/nfnetlink.c:295 + netlink_rcv_skb+0x1c0/0x350 net/netlink/af_netlink.c:2546 + nfnetlink_rcv+0x18c/0x199c net/netfilter/nfnetlink.c:658 + netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] + netlink_unicast+0x664/0x8cc net/netlink/af_netlink.c:1365 + netlink_sendmsg+0x6d0/0xa4c net/netlink/af_netlink.c:1913 + sock_sendmsg_nosec net/socket.c:724 [inline] + sock_sendmsg net/socket.c:747 [inline] + ____sys_sendmsg+0x4b8/0x810 net/socket.c:2503 + ___sys_sendmsg net/socket.c:2557 [inline] + __sys_sendmsg+0x1f8/0x2a4 net/socket.c:2586 + __do_sys_sendmsg net/socket.c:2595 [inline] + __se_sys_sendmsg net/socket.c:2593 [inline] + __arm64_sys_sendmsg+0x80/0x94 net/socket.c:2593 + __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline] + invoke_syscall+0x84/0x270 arch/arm64/kernel/syscall.c:52 + el0_svc_common+0x134/0x24c arch/arm64/kernel/syscall.c:142 + do_el0_svc+0x64/0x198 arch/arm64/kernel/syscall.c:193 + el0_svc+0x2c/0x7c arch/arm64/kernel/entry-common.c:637 + el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:655 + el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:591 + +Reported-by: syzkaller +Fixes: a7b4f989a629 ("netfilter: ipset: IP set core support") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipset/ip_set_core.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index ae061b27e4465..c911fc09f363c 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -1694,6 +1694,14 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb, + bool eexist = flags & IPSET_FLAG_EXIST, retried = false; + + do { ++ if (retried) { ++ __ip_set_get(set); ++ nfnl_unlock(NFNL_SUBSYS_IPSET); ++ cond_resched(); ++ nfnl_lock(NFNL_SUBSYS_IPSET); ++ __ip_set_put(set); ++ } ++ + ip_set_lock(set); + ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried); + ip_set_unlock(set); +-- +2.39.2 + diff --git a/queue-5.15/platform-surface-aggregator-allow-completion-work-it.patch b/queue-5.15/platform-surface-aggregator-allow-completion-work-it.patch new file mode 100644 index 00000000000..a860c79566e --- /dev/null +++ b/queue-5.15/platform-surface-aggregator-allow-completion-work-it.patch @@ -0,0 +1,67 @@ +From 0559c785230129e966b1a219e4c0606bb6ffe121 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 May 2023 23:01:10 +0200 +Subject: platform/surface: aggregator: Allow completion work-items to be + executed in parallel + +From: Maximilian Luz + +[ Upstream commit 539e0a7f9105d19c00629c3f4da00330488e8c60 ] + +Currently, event completion work-items are restricted to be run strictly +in non-parallel fashion by the respective workqueue. However, this has +lead to some problems: + +In some instances, the event notifier function called inside this +completion workqueue takes a non-negligible amount of time to execute. +One such example is the battery event handling code (surface_battery.c), +which can result in a full battery information refresh, involving +further synchronous communication with the EC inside the event handler. +This is made worse if the communication fails spuriously, generally +incurring a multi-second timeout. + +Since the event completions are run strictly non-parallel, this blocks +other events from being propagated to the respective subsystems. This +becomes especially noticeable for keyboard and touchpad input, which +also funnel their events through this system. Here, users have reported +occasional multi-second "freezes". + +Note, however, that the event handling system was never intended to run +purely sequentially. Instead, we have one work struct per EC/SAM +subsystem, processing the event queue for that subsystem. These work +structs were intended to run in parallel, allowing sequential processing +of work items for each subsystem but parallel processing of work items +across subsystems. + +The only restriction to this is the way the workqueue is created. +Therefore, replace create_workqueue() with alloc_workqueue() and do not +restrict the maximum number of parallel work items to be executed on +that queue, resolving any cross-subsystem blockage. + +Fixes: c167b9c7e3d6 ("platform/surface: Add Surface Aggregator subsystem") +Link: https://github.com/linux-surface/linux-surface/issues/1026 +Signed-off-by: Maximilian Luz +Link: https://lore.kernel.org/r/20230525210110.2785470-1-luzmaximilian@gmail.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/surface/aggregator/controller.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c +index f23f7128cf2b4..5542b768890c9 100644 +--- a/drivers/platform/surface/aggregator/controller.c ++++ b/drivers/platform/surface/aggregator/controller.c +@@ -825,7 +825,7 @@ static int ssam_cplt_init(struct ssam_cplt *cplt, struct device *dev) + + cplt->dev = dev; + +- cplt->wq = create_workqueue(SSAM_CPLT_WQ_NAME); ++ cplt->wq = alloc_workqueue(SSAM_CPLT_WQ_NAME, WQ_UNBOUND | WQ_MEM_RECLAIM, 0); + if (!cplt->wq) + return -ENOMEM; + +-- +2.39.2 + diff --git a/queue-5.15/qed-qede-fix-scheduling-while-atomic.patch b/queue-5.15/qed-qede-fix-scheduling-while-atomic.patch new file mode 100644 index 00000000000..bed297000eb --- /dev/null +++ b/queue-5.15/qed-qede-fix-scheduling-while-atomic.patch @@ -0,0 +1,275 @@ +From 8898a017561a7df12599d80bb0dc44ba51030894 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jun 2023 16:56:00 +0530 +Subject: qed/qede: Fix scheduling while atomic + +From: Manish Chopra + +[ Upstream commit 42510dffd0e2c27046905f742172ed6662af5557 ] + +Statistics read through bond interface via sysfs causes +below bug and traces as it triggers the bonding module to +collect the slave device statistics while holding the spinlock, +beneath that qede->qed driver statistics flow gets scheduled out +due to usleep_range() used in PTT acquire logic + +[ 3673.988874] Hardware name: HPE ProLiant DL365 Gen10 Plus/ProLiant DL365 Gen10 Plus, BIOS A42 10/29/2021 +[ 3673.988878] Call Trace: +[ 3673.988891] dump_stack_lvl+0x34/0x44 +[ 3673.988908] __schedule_bug.cold+0x47/0x53 +[ 3673.988918] __schedule+0x3fb/0x560 +[ 3673.988929] schedule+0x43/0xb0 +[ 3673.988932] schedule_hrtimeout_range_clock+0xbf/0x1b0 +[ 3673.988937] ? __hrtimer_init+0xc0/0xc0 +[ 3673.988950] usleep_range+0x5e/0x80 +[ 3673.988955] qed_ptt_acquire+0x2b/0xd0 [qed] +[ 3673.988981] _qed_get_vport_stats+0x141/0x240 [qed] +[ 3673.989001] qed_get_vport_stats+0x18/0x80 [qed] +[ 3673.989016] qede_fill_by_demand_stats+0x37/0x400 [qede] +[ 3673.989028] qede_get_stats64+0x19/0xe0 [qede] +[ 3673.989034] dev_get_stats+0x5c/0xc0 +[ 3673.989045] netstat_show.constprop.0+0x52/0xb0 +[ 3673.989055] dev_attr_show+0x19/0x40 +[ 3673.989065] sysfs_kf_seq_show+0x9b/0xf0 +[ 3673.989076] seq_read_iter+0x120/0x4b0 +[ 3673.989087] new_sync_read+0x118/0x1a0 +[ 3673.989095] vfs_read+0xf3/0x180 +[ 3673.989099] ksys_read+0x5f/0xe0 +[ 3673.989102] do_syscall_64+0x3b/0x90 +[ 3673.989109] entry_SYSCALL_64_after_hwframe+0x44/0xae +[ 3673.989115] RIP: 0033:0x7f8467d0b082 +[ 3673.989119] Code: c0 e9 b2 fe ff ff 50 48 8d 3d ca 05 08 00 e8 35 e7 01 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24 +[ 3673.989121] RSP: 002b:00007ffffb21fd08 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 +[ 3673.989127] RAX: ffffffffffffffda RBX: 000000000100eca0 RCX: 00007f8467d0b082 +[ 3673.989128] RDX: 00000000000003ff RSI: 00007ffffb21fdc0 RDI: 0000000000000003 +[ 3673.989130] RBP: 00007f8467b96028 R08: 0000000000000010 R09: 00007ffffb21ec00 +[ 3673.989132] R10: 00007ffffb27b170 R11: 0000000000000246 R12: 00000000000000f0 +[ 3673.989134] R13: 0000000000000003 R14: 00007f8467b92000 R15: 0000000000045a05 +[ 3673.989139] CPU: 30 PID: 285188 Comm: read_all Kdump: loaded Tainted: G W OE + +Fix this by collecting the statistics asynchronously from a periodic +delayed work scheduled at default stats coalescing interval and return +the recent copy of statisitcs from .ndo_get_stats64(), also add ability +to configure/retrieve stats coalescing interval using below commands - + +ethtool -C ethx stats-block-usecs +ethtool -c ethx + +Fixes: 133fac0eedc3 ("qede: Add basic ethtool support") +Cc: Sudarsana Kalluru +Cc: David Miller +Signed-off-by: Manish Chopra +Link: https://lore.kernel.org/r/20230605112600.48238-1-manishc@marvell.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_l2.c | 2 +- + drivers/net/ethernet/qlogic/qede/qede.h | 4 +++ + .../net/ethernet/qlogic/qede/qede_ethtool.c | 24 +++++++++++-- + drivers/net/ethernet/qlogic/qede/qede_main.c | 34 ++++++++++++++++++- + 4 files changed, 60 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c +index ba8c7a31cce1f..bc17bc36d346e 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c +@@ -1903,7 +1903,7 @@ void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats) + { + u32 i; + +- if (!cdev) { ++ if (!cdev || cdev->recov_in_prog) { + memset(stats, 0, sizeof(*stats)); + return; + } +diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h +index f90dcfe9ee688..8a63f99d499c4 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede.h ++++ b/drivers/net/ethernet/qlogic/qede/qede.h +@@ -271,6 +271,10 @@ struct qede_dev { + #define QEDE_ERR_WARN 3 + + struct qede_dump_info dump_info; ++ struct delayed_work periodic_task; ++ unsigned long stats_coal_ticks; ++ u32 stats_coal_usecs; ++ spinlock_t stats_lock; /* lock for vport stats access */ + }; + + enum QEDE_STATE { +diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c +index 8284c4c1528f7..28108f6324fb2 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c +@@ -426,6 +426,8 @@ static void qede_get_ethtool_stats(struct net_device *dev, + } + } + ++ spin_lock(&edev->stats_lock); ++ + for (i = 0; i < QEDE_NUM_STATS; i++) { + if (qede_is_irrelevant_stat(edev, i)) + continue; +@@ -435,6 +437,8 @@ static void qede_get_ethtool_stats(struct net_device *dev, + buf++; + } + ++ spin_unlock(&edev->stats_lock); ++ + __qede_unlock(edev); + } + +@@ -817,6 +821,7 @@ static int qede_get_coalesce(struct net_device *dev, + + coal->rx_coalesce_usecs = rx_coal; + coal->tx_coalesce_usecs = tx_coal; ++ coal->stats_block_coalesce_usecs = edev->stats_coal_usecs; + + return rc; + } +@@ -830,6 +835,19 @@ int qede_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal, + int i, rc = 0; + u16 rxc, txc; + ++ if (edev->stats_coal_usecs != coal->stats_block_coalesce_usecs) { ++ edev->stats_coal_usecs = coal->stats_block_coalesce_usecs; ++ if (edev->stats_coal_usecs) { ++ edev->stats_coal_ticks = usecs_to_jiffies(edev->stats_coal_usecs); ++ schedule_delayed_work(&edev->periodic_task, 0); ++ ++ DP_INFO(edev, "Configured stats coal ticks=%lu jiffies\n", ++ edev->stats_coal_ticks); ++ } else { ++ cancel_delayed_work_sync(&edev->periodic_task); ++ } ++ } ++ + if (!netif_running(dev)) { + DP_INFO(edev, "Interface is down\n"); + return -EINVAL; +@@ -2236,7 +2254,8 @@ static int qede_get_per_coalesce(struct net_device *dev, + } + + static const struct ethtool_ops qede_ethtool_ops = { +- .supported_coalesce_params = ETHTOOL_COALESCE_USECS, ++ .supported_coalesce_params = ETHTOOL_COALESCE_USECS | ++ ETHTOOL_COALESCE_STATS_BLOCK_USECS, + .get_link_ksettings = qede_get_link_ksettings, + .set_link_ksettings = qede_set_link_ksettings, + .get_drvinfo = qede_get_drvinfo, +@@ -2287,7 +2306,8 @@ static const struct ethtool_ops qede_ethtool_ops = { + }; + + static const struct ethtool_ops qede_vf_ethtool_ops = { +- .supported_coalesce_params = ETHTOOL_COALESCE_USECS, ++ .supported_coalesce_params = ETHTOOL_COALESCE_USECS | ++ ETHTOOL_COALESCE_STATS_BLOCK_USECS, + .get_link_ksettings = qede_get_link_ksettings, + .get_drvinfo = qede_get_drvinfo, + .get_msglevel = qede_get_msglevel, +diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c +index 2d3f0ae4f8897..41f0a3433c3a2 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_main.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_main.c +@@ -308,6 +308,8 @@ void qede_fill_by_demand_stats(struct qede_dev *edev) + + edev->ops->get_vport_stats(edev->cdev, &stats); + ++ spin_lock(&edev->stats_lock); ++ + p_common->no_buff_discards = stats.common.no_buff_discards; + p_common->packet_too_big_discard = stats.common.packet_too_big_discard; + p_common->ttl0_discard = stats.common.ttl0_discard; +@@ -405,6 +407,8 @@ void qede_fill_by_demand_stats(struct qede_dev *edev) + p_ah->tx_1519_to_max_byte_packets = + stats.ah.tx_1519_to_max_byte_packets; + } ++ ++ spin_unlock(&edev->stats_lock); + } + + static void qede_get_stats64(struct net_device *dev, +@@ -413,9 +417,10 @@ static void qede_get_stats64(struct net_device *dev, + struct qede_dev *edev = netdev_priv(dev); + struct qede_stats_common *p_common; + +- qede_fill_by_demand_stats(edev); + p_common = &edev->stats.common; + ++ spin_lock(&edev->stats_lock); ++ + stats->rx_packets = p_common->rx_ucast_pkts + p_common->rx_mcast_pkts + + p_common->rx_bcast_pkts; + stats->tx_packets = p_common->tx_ucast_pkts + p_common->tx_mcast_pkts + +@@ -435,6 +440,8 @@ static void qede_get_stats64(struct net_device *dev, + stats->collisions = edev->stats.bb.tx_total_collisions; + stats->rx_crc_errors = p_common->rx_crc_errors; + stats->rx_frame_errors = p_common->rx_align_errors; ++ ++ spin_unlock(&edev->stats_lock); + } + + #ifdef CONFIG_QED_SRIOV +@@ -1000,6 +1007,23 @@ static void qede_unlock(struct qede_dev *edev) + rtnl_unlock(); + } + ++static void qede_periodic_task(struct work_struct *work) ++{ ++ struct qede_dev *edev = container_of(work, struct qede_dev, ++ periodic_task.work); ++ ++ qede_fill_by_demand_stats(edev); ++ schedule_delayed_work(&edev->periodic_task, edev->stats_coal_ticks); ++} ++ ++static void qede_init_periodic_task(struct qede_dev *edev) ++{ ++ INIT_DELAYED_WORK(&edev->periodic_task, qede_periodic_task); ++ spin_lock_init(&edev->stats_lock); ++ edev->stats_coal_usecs = USEC_PER_SEC; ++ edev->stats_coal_ticks = usecs_to_jiffies(USEC_PER_SEC); ++} ++ + static void qede_sp_task(struct work_struct *work) + { + struct qede_dev *edev = container_of(work, struct qede_dev, +@@ -1019,6 +1043,7 @@ static void qede_sp_task(struct work_struct *work) + */ + + if (test_and_clear_bit(QEDE_SP_RECOVERY, &edev->sp_flags)) { ++ cancel_delayed_work_sync(&edev->periodic_task); + #ifdef CONFIG_QED_SRIOV + /* SRIOV must be disabled outside the lock to avoid a deadlock. + * The recovery of the active VFs is currently not supported. +@@ -1209,6 +1234,7 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level, + */ + INIT_DELAYED_WORK(&edev->sp_task, qede_sp_task); + mutex_init(&edev->qede_lock); ++ qede_init_periodic_task(edev); + + rc = register_netdev(edev->ndev); + if (rc) { +@@ -1233,6 +1259,11 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level, + edev->rx_copybreak = QEDE_RX_HDR_SIZE; + + qede_log_probe(edev); ++ ++ /* retain user config (for example - after recovery) */ ++ if (edev->stats_coal_usecs) ++ schedule_delayed_work(&edev->periodic_task, 0); ++ + return 0; + + err4: +@@ -1301,6 +1332,7 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode) + unregister_netdev(ndev); + + cancel_delayed_work_sync(&edev->sp_task); ++ cancel_delayed_work_sync(&edev->periodic_task); + + edev->ops->common->set_power_state(cdev, PCI_D0); + +-- +2.39.2 + diff --git a/queue-5.15/rfs-annotate-lockless-accesses-to-rfs-sock-flow-tabl.patch b/queue-5.15/rfs-annotate-lockless-accesses-to-rfs-sock-flow-tabl.patch new file mode 100644 index 00000000000..10a1bbd7640 --- /dev/null +++ b/queue-5.15/rfs-annotate-lockless-accesses-to-rfs-sock-flow-tabl.patch @@ -0,0 +1,67 @@ +From 412ac7f82e21790affb8bc2bf15b9fa500c09ae3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Jun 2023 07:41:15 +0000 +Subject: rfs: annotate lockless accesses to RFS sock flow table + +From: Eric Dumazet + +[ Upstream commit 5c3b74a92aa285a3df722bf6329ba7ccf70346d6 ] + +Add READ_ONCE()/WRITE_ONCE() on accesses to the sock flow table. + +This also prevents a (smart ?) compiler to remove the condition in: + +if (table->ents[index] != newval) + table->ents[index] = newval; + +We need the condition to avoid dirtying a shared cache line. + +Fixes: fec5e652e58f ("rfs: Receive Flow Steering") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/linux/netdevice.h | 7 +++++-- + net/core/dev.c | 6 ++++-- + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 5b6c38f748076..823f5ed4ec0cc 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -737,8 +737,11 @@ static inline void rps_record_sock_flow(struct rps_sock_flow_table *table, + /* We only give a hint, preemption can change CPU under us */ + val |= raw_smp_processor_id(); + +- if (table->ents[index] != val) +- table->ents[index] = val; ++ /* The following WRITE_ONCE() is paired with the READ_ONCE() ++ * here, and another one in get_rps_cpu(). ++ */ ++ if (READ_ONCE(table->ents[index]) != val) ++ WRITE_ONCE(table->ents[index], val); + } + } + +diff --git a/net/core/dev.c b/net/core/dev.c +index 56a3bff7249d4..24d711fe376a3 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4458,8 +4458,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, + u32 next_cpu; + u32 ident; + +- /* First check into global flow table if there is a match */ +- ident = sock_flow_table->ents[hash & sock_flow_table->mask]; ++ /* First check into global flow table if there is a match. ++ * This READ_ONCE() pairs with WRITE_ONCE() from rps_record_sock_flow(). ++ */ ++ ident = READ_ONCE(sock_flow_table->ents[hash & sock_flow_table->mask]); + if ((ident ^ hash) & ~rps_cpu_mask) + goto try_rps; + +-- +2.39.2 + diff --git a/queue-5.15/rfs-annotate-lockless-accesses-to-sk-sk_rxhash.patch b/queue-5.15/rfs-annotate-lockless-accesses-to-sk-sk_rxhash.patch new file mode 100644 index 00000000000..b6e5e373029 --- /dev/null +++ b/queue-5.15/rfs-annotate-lockless-accesses-to-sk-sk_rxhash.patch @@ -0,0 +1,73 @@ +From 629bff6dda24edbb0d8b0f99e73d15a8b0d38b95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Jun 2023 07:41:14 +0000 +Subject: rfs: annotate lockless accesses to sk->sk_rxhash + +From: Eric Dumazet + +[ Upstream commit 1e5c647c3f6d4f8497dedcd226204e1880e0ffb3 ] + +Add READ_ONCE()/WRITE_ONCE() on accesses to sk->sk_rxhash. + +This also prevents a (smart ?) compiler to remove the condition in: + +if (sk->sk_rxhash != newval) + sk->sk_rxhash = newval; + +We need the condition to avoid dirtying a shared cache line. + +Fixes: fec5e652e58f ("rfs: Receive Flow Steering") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index 104d80d850e41..0eb6a4d07a4d1 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1093,8 +1093,12 @@ static inline void sock_rps_record_flow(const struct sock *sk) + * OR an additional socket flag + * [1] : sk_state and sk_prot are in the same cache line. + */ +- if (sk->sk_state == TCP_ESTABLISHED) +- sock_rps_record_flow_hash(sk->sk_rxhash); ++ if (sk->sk_state == TCP_ESTABLISHED) { ++ /* This READ_ONCE() is paired with the WRITE_ONCE() ++ * from sock_rps_save_rxhash() and sock_rps_reset_rxhash(). ++ */ ++ sock_rps_record_flow_hash(READ_ONCE(sk->sk_rxhash)); ++ } + } + #endif + } +@@ -1103,15 +1107,19 @@ static inline void sock_rps_save_rxhash(struct sock *sk, + const struct sk_buff *skb) + { + #ifdef CONFIG_RPS +- if (unlikely(sk->sk_rxhash != skb->hash)) +- sk->sk_rxhash = skb->hash; ++ /* The following WRITE_ONCE() is paired with the READ_ONCE() ++ * here, and another one in sock_rps_record_flow(). ++ */ ++ if (unlikely(READ_ONCE(sk->sk_rxhash) != skb->hash)) ++ WRITE_ONCE(sk->sk_rxhash, skb->hash); + #endif + } + + static inline void sock_rps_reset_rxhash(struct sock *sk) + { + #ifdef CONFIG_RPS +- sk->sk_rxhash = 0; ++ /* Paired with READ_ONCE() in sock_rps_record_flow() */ ++ WRITE_ONCE(sk->sk_rxhash, 0); + #endif + } + +-- +2.39.2 + diff --git a/queue-5.15/selftests-bpf-fix-sockopt_sk-selftest.patch b/queue-5.15/selftests-bpf-fix-sockopt_sk-selftest.patch new file mode 100644 index 00000000000..54478d47424 --- /dev/null +++ b/queue-5.15/selftests-bpf-fix-sockopt_sk-selftest.patch @@ -0,0 +1,54 @@ +From 7e6d6e55954ff3f5b4d117188f1d1e7558f4c7d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Jun 2023 10:22:02 -0700 +Subject: selftests/bpf: Fix sockopt_sk selftest + +From: Yonghong Song + +[ Upstream commit 69844e335d8c22454746c7903776533d8b4ab8fa ] + +Commit f4e4534850a9 ("net/netlink: fix NETLINK_LIST_MEMBERSHIPS length report") +fixed NETLINK_LIST_MEMBERSHIPS length report which caused +selftest sockopt_sk failure. The failure log looks like + + test_sockopt_sk:PASS:join_cgroup /sockopt_sk 0 nsec + run_test:PASS:skel_load 0 nsec + run_test:PASS:setsockopt_link 0 nsec + run_test:PASS:getsockopt_link 0 nsec + getsetsockopt:FAIL:Unexpected NETLINK_LIST_MEMBERSHIPS value unexpected Unexpected NETLINK_LIST_MEMBERSHIPS value: actual 8 != expected 4 + run_test:PASS:getsetsockopt 0 nsec + #201 sockopt_sk:FAIL + +In net/netlink/af_netlink.c, function netlink_getsockopt(), for NETLINK_LIST_MEMBERSHIPS, +nlk->ngroups equals to 36. Before Commit f4e4534850a9, the optlen is calculated as + ALIGN(nlk->ngroups / 8, sizeof(u32)) = 4 +After that commit, the optlen is + ALIGN(BITS_TO_BYTES(nlk->ngroups), sizeof(u32)) = 8 + +Fix the test by setting the expected optlen to be 8. + +Fixes: f4e4534850a9 ("net/netlink: fix NETLINK_LIST_MEMBERSHIPS length report") +Signed-off-by: Yonghong Song +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20230606172202.1606249-1-yhs@fb.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/sockopt_sk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c +index ced75783bacfa..f3cd8db26bf7e 100644 +--- a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c ++++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c +@@ -209,7 +209,7 @@ static int getsetsockopt(void) + err, errno); + goto err; + } +- ASSERT_EQ(optlen, 4, "Unexpected NETLINK_LIST_MEMBERSHIPS value"); ++ ASSERT_EQ(optlen, 8, "Unexpected NETLINK_LIST_MEMBERSHIPS value"); + + free(big_buf); + close(fd); +-- +2.39.2 + diff --git a/queue-5.15/selftests-bpf-verify-optval-null-case.patch b/queue-5.15/selftests-bpf-verify-optval-null-case.patch new file mode 100644 index 00000000000..33ba365b3e9 --- /dev/null +++ b/queue-5.15/selftests-bpf-verify-optval-null-case.patch @@ -0,0 +1,100 @@ +From e533a75d6541cf89d20e3c4d3055377356cde0cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Apr 2023 15:53:39 -0700 +Subject: selftests/bpf: Verify optval=NULL case + +From: Stanislav Fomichev + +[ Upstream commit 833d67ecdc5f35f1ebf59d0fccc1ce771434be9c ] + +Make sure we get optlen exported instead of getting EFAULT. + +Signed-off-by: Stanislav Fomichev +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20230418225343.553806-3-sdf@google.com +Stable-dep-of: 69844e335d8c ("selftests/bpf: Fix sockopt_sk selftest") +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/sockopt_sk.c | 28 +++++++++++++++++++ + .../testing/selftests/bpf/progs/sockopt_sk.c | 12 ++++++++ + 2 files changed, 40 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c +index 4b937e5dbacae..ced75783bacfa 100644 +--- a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c ++++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c +@@ -3,6 +3,7 @@ + #include "cgroup_helpers.h" + + #include ++#include + #include "sockopt_sk.skel.h" + + #ifndef SOL_TCP +@@ -183,6 +184,33 @@ static int getsetsockopt(void) + goto err; + } + ++ /* optval=NULL case is handled correctly */ ++ ++ close(fd); ++ fd = socket(AF_NETLINK, SOCK_RAW, 0); ++ if (fd < 0) { ++ log_err("Failed to create AF_NETLINK socket"); ++ return -1; ++ } ++ ++ buf.u32 = 1; ++ optlen = sizeof(__u32); ++ err = setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &buf, optlen); ++ if (err) { ++ log_err("Unexpected getsockopt(NETLINK_ADD_MEMBERSHIP) err=%d errno=%d", ++ err, errno); ++ goto err; ++ } ++ ++ optlen = 0; ++ err = getsockopt(fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &optlen); ++ if (err) { ++ log_err("Unexpected getsockopt(NETLINK_LIST_MEMBERSHIPS) err=%d errno=%d", ++ err, errno); ++ goto err; ++ } ++ ASSERT_EQ(optlen, 4, "Unexpected NETLINK_LIST_MEMBERSHIPS value"); ++ + free(big_buf); + close(fd); + return 0; +diff --git a/tools/testing/selftests/bpf/progs/sockopt_sk.c b/tools/testing/selftests/bpf/progs/sockopt_sk.c +index 79c8139b63b80..9cf72ae132020 100644 +--- a/tools/testing/selftests/bpf/progs/sockopt_sk.c ++++ b/tools/testing/selftests/bpf/progs/sockopt_sk.c +@@ -32,6 +32,12 @@ int _getsockopt(struct bpf_sockopt *ctx) + __u8 *optval_end = ctx->optval_end; + __u8 *optval = ctx->optval; + struct sockopt_sk *storage; ++ struct bpf_sock *sk; ++ ++ /* Bypass AF_NETLINK. */ ++ sk = ctx->sk; ++ if (sk && sk->family == AF_NETLINK) ++ return 1; + + /* Make sure bpf_get_netns_cookie is callable. + */ +@@ -130,6 +136,12 @@ int _setsockopt(struct bpf_sockopt *ctx) + __u8 *optval_end = ctx->optval_end; + __u8 *optval = ctx->optval; + struct sockopt_sk *storage; ++ struct bpf_sock *sk; ++ ++ /* Bypass AF_NETLINK. */ ++ sk = ctx->sk; ++ if (sk && sk->family == AF_NETLINK) ++ return 1; + + /* Make sure bpf_get_netns_cookie is callable. + */ +-- +2.39.2 + diff --git a/queue-5.15/series b/queue-5.15/series index 4fa92bf5739..2a0b395b230 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -8,3 +8,39 @@ i40e-fix-build-warning-in-ice_fltr_add_mac_to_list.patch bonding-gcc13-synchronize-bond_-a-t-lb_xmit-types.patch f2fs-fix-iostat-lock-protection.patch blk-iocost-avoid-64-bit-division-in-ioc_timer_fn.patch +platform-surface-aggregator-allow-completion-work-it.patch +spi-qup-request-dma-before-enabling-clocks.patch +afs-fix-setting-of-mtime-when-creating-a-file-dir-sy.patch +wifi-mt76-mt7615-fix-possible-race-in-mt7615_mac_sta.patch +neighbour-fix-unaligned-access-to-pneigh_entry.patch +net-dsa-lan9303-allow-vid-0-in-port_fdb_-add-del-met.patch +bpf-fix-uaf-in-task-local-storage.patch +net-ipv6-fix-bool-int-mismatch-for-skip_notify_on_de.patch +net-smc-avoid-to-access-invalid-rmbs-mrs-in-smcrv1-a.patch +net-enetc-correct-the-statistics-of-rx-bytes.patch +net-sched-fq_pie-ensure-reasonable-tca_fq_pie_quantu.patch +drm-i915-explain-the-magic-numbers-for-aux-sync-prec.patch +drm-i915-use-18-fast-wake-aux-sync-len.patch +bluetooth-fix-l2cap_disconnect_req-deadlock.patch +bluetooth-l2cap-add-missing-checks-for-invalid-dcid.patch +qed-qede-fix-scheduling-while-atomic.patch +wifi-cfg80211-fix-locking-in-sched-scan-stop-work.patch +wifi-cfg80211-fix-locking-in-regulatory-disconnect.patch +selftests-bpf-verify-optval-null-case.patch +selftests-bpf-fix-sockopt_sk-selftest.patch +netfilter-conntrack-fix-null-pointer-dereference-in-.patch +netfilter-ipset-add-schedule-point-in-call_ad.patch +ipv6-rpl-fix-route-of-death.patch +rfs-annotate-lockless-accesses-to-sk-sk_rxhash.patch +rfs-annotate-lockless-accesses-to-rfs-sock-flow-tabl.patch +drm-i915-selftests-increase-timeout-for-live_paralle.patch +drm-i915-selftests-stop-using-kthread_stop.patch +drm-i915-selftests-add-some-missing-error-propagatio.patch +net-sched-move-rtm_tca_policy-declaration-to-include.patch +net-sched-act_police-fix-sparse-errors-in-tcf_police.patch +net-sched-fix-possible-refcount-leak-in-tc_chain_tmp.patch +bpf-add-extra-path-pointer-check-to-d_path-helper.patch +lib-cpu_rmap-fix-potential-use-after-free-in-irq_cpu.patch +bnxt_en-don-t-issue-ap-reset-during-ethtool-s-reset-.patch +bnxt_en-query-default-vlan-before-vnic-setup-on-a-vf.patch +bnxt_en-implement-.set_port-.unset_port-udp-tunnel-c.patch diff --git a/queue-5.15/spi-qup-request-dma-before-enabling-clocks.patch b/queue-5.15/spi-qup-request-dma-before-enabling-clocks.patch new file mode 100644 index 00000000000..578d6180f01 --- /dev/null +++ b/queue-5.15/spi-qup-request-dma-before-enabling-clocks.patch @@ -0,0 +1,122 @@ +From 9430070ad73ae3666d326fa9f7dc2ae4196ebdee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 May 2023 15:04:25 +0200 +Subject: spi: qup: Request DMA before enabling clocks + +From: Stephan Gerhold + +[ Upstream commit 0c331fd1dccfba657129380ee084b95c1cedfbef ] + +It is usually better to request all necessary resources (clocks, +regulators, ...) before starting to make use of them. That way they do +not change state in case one of the resources is not available yet and +probe deferral (-EPROBE_DEFER) is necessary. This is particularly +important for DMA channels and IOMMUs which are not enforced by +fw_devlink yet (unless you use fw_devlink.strict=1). + +spi-qup does this in the wrong order, the clocks are enabled and +disabled again when the DMA channels are not available yet. + +This causes issues in some cases: On most SoCs one of the SPI QUP +clocks is shared with the UART controller. When using earlycon UART is +actively used during boot but might not have probed yet, usually for +the same reason (waiting for the DMA controller). In this case, the +brief enable/disable cycle ends up gating the clock and further UART +console output will halt the system completely. + +Avoid this by requesting the DMA channels before changing the clock +state. + +Fixes: 612762e82ae6 ("spi: qup: Add DMA capabilities") +Signed-off-by: Stephan Gerhold +Link: https://lore.kernel.org/r/20230518-spi-qup-clk-defer-v1-1-f49fc9ca4e02@gerhold.net +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-qup.c | 37 ++++++++++++++++++------------------- + 1 file changed, 18 insertions(+), 19 deletions(-) + +diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c +index 8bf58510cca6d..2cc9bb413c108 100644 +--- a/drivers/spi/spi-qup.c ++++ b/drivers/spi/spi-qup.c +@@ -1030,23 +1030,8 @@ static int spi_qup_probe(struct platform_device *pdev) + return -ENXIO; + } + +- ret = clk_prepare_enable(cclk); +- if (ret) { +- dev_err(dev, "cannot enable core clock\n"); +- return ret; +- } +- +- ret = clk_prepare_enable(iclk); +- if (ret) { +- clk_disable_unprepare(cclk); +- dev_err(dev, "cannot enable iface clock\n"); +- return ret; +- } +- + master = spi_alloc_master(dev, sizeof(struct spi_qup)); + if (!master) { +- clk_disable_unprepare(cclk); +- clk_disable_unprepare(iclk); + dev_err(dev, "cannot allocate master\n"); + return -ENOMEM; + } +@@ -1092,6 +1077,19 @@ static int spi_qup_probe(struct platform_device *pdev) + spin_lock_init(&controller->lock); + init_completion(&controller->done); + ++ ret = clk_prepare_enable(cclk); ++ if (ret) { ++ dev_err(dev, "cannot enable core clock\n"); ++ goto error_dma; ++ } ++ ++ ret = clk_prepare_enable(iclk); ++ if (ret) { ++ clk_disable_unprepare(cclk); ++ dev_err(dev, "cannot enable iface clock\n"); ++ goto error_dma; ++ } ++ + iomode = readl_relaxed(base + QUP_IO_M_MODES); + + size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode); +@@ -1121,7 +1119,7 @@ static int spi_qup_probe(struct platform_device *pdev) + ret = spi_qup_set_state(controller, QUP_STATE_RESET); + if (ret) { + dev_err(dev, "cannot set RESET state\n"); +- goto error_dma; ++ goto error_clk; + } + + writel_relaxed(0, base + QUP_OPERATIONAL); +@@ -1145,7 +1143,7 @@ static int spi_qup_probe(struct platform_device *pdev) + ret = devm_request_irq(dev, irq, spi_qup_qup_irq, + IRQF_TRIGGER_HIGH, pdev->name, controller); + if (ret) +- goto error_dma; ++ goto error_clk; + + pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); + pm_runtime_use_autosuspend(dev); +@@ -1160,11 +1158,12 @@ static int spi_qup_probe(struct platform_device *pdev) + + disable_pm: + pm_runtime_disable(&pdev->dev); ++error_clk: ++ clk_disable_unprepare(cclk); ++ clk_disable_unprepare(iclk); + error_dma: + spi_qup_release_dma(master); + error: +- clk_disable_unprepare(cclk); +- clk_disable_unprepare(iclk); + spi_master_put(master); + return ret; + } +-- +2.39.2 + diff --git a/queue-5.15/wifi-cfg80211-fix-locking-in-regulatory-disconnect.patch b/queue-5.15/wifi-cfg80211-fix-locking-in-regulatory-disconnect.patch new file mode 100644 index 00000000000..1176cb9ecfc --- /dev/null +++ b/queue-5.15/wifi-cfg80211-fix-locking-in-regulatory-disconnect.patch @@ -0,0 +1,41 @@ +From 7cdaf883ec16963a7c32c4efb821a3518c3533a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Jun 2023 14:34:48 +0200 +Subject: wifi: cfg80211: fix locking in regulatory disconnect + +From: Johannes Berg + +[ Upstream commit f7e60032c6618dfd643c7210d5cba2789e2de2e2 ] + +This should use wiphy_lock() now instead of requiring the +RTNL, since __cfg80211_leave() via cfg80211_leave() is now +requiring that lock to be held. + +Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver") +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/reg.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/wireless/reg.c b/net/wireless/reg.c +index d0fbe822e7934..0e49264ce1f67 100644 +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -2423,11 +2423,11 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy) + struct wireless_dev *wdev; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + +- ASSERT_RTNL(); +- ++ wiphy_lock(wiphy); + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) + if (!reg_wdev_chan_valid(wiphy, wdev)) + cfg80211_leave(rdev, wdev); ++ wiphy_unlock(wiphy); + } + + static void reg_check_chans_work(struct work_struct *work) +-- +2.39.2 + diff --git a/queue-5.15/wifi-cfg80211-fix-locking-in-sched-scan-stop-work.patch b/queue-5.15/wifi-cfg80211-fix-locking-in-sched-scan-stop-work.patch new file mode 100644 index 00000000000..6a10073a915 --- /dev/null +++ b/queue-5.15/wifi-cfg80211-fix-locking-in-sched-scan-stop-work.patch @@ -0,0 +1,41 @@ +From df303a1034840bf9579201394a769ecea1115f98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Jun 2023 14:34:47 +0200 +Subject: wifi: cfg80211: fix locking in sched scan stop work + +From: Johannes Berg + +[ Upstream commit 3e54ed8247c94c8bdf370bd872bd9dfe72b1b12b ] + +This should use wiphy_lock() now instead of acquiring the +RTNL, since cfg80211_stop_sched_scan_req() now needs that. + +Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver") +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/wireless/core.c b/net/wireless/core.c +index 441136646f89a..d10686f4bf153 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -368,12 +368,12 @@ static void cfg80211_sched_scan_stop_wk(struct work_struct *work) + rdev = container_of(work, struct cfg80211_registered_device, + sched_scan_stop_wk); + +- rtnl_lock(); ++ wiphy_lock(&rdev->wiphy); + list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) { + if (req->nl_owner_dead) + cfg80211_stop_sched_scan_req(rdev, req, false); + } +- rtnl_unlock(); ++ wiphy_unlock(&rdev->wiphy); + } + + static void cfg80211_propagate_radar_detect_wk(struct work_struct *work) +-- +2.39.2 + diff --git a/queue-5.15/wifi-mt76-mt7615-fix-possible-race-in-mt7615_mac_sta.patch b/queue-5.15/wifi-mt76-mt7615-fix-possible-race-in-mt7615_mac_sta.patch new file mode 100644 index 00000000000..3f5fc6b4ae4 --- /dev/null +++ b/queue-5.15/wifi-mt76-mt7615-fix-possible-race-in-mt7615_mac_sta.patch @@ -0,0 +1,40 @@ +From 92586330c7c2ae41368b130d1c9a51c948b09ff6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 May 2023 16:39:32 +0200 +Subject: wifi: mt76: mt7615: fix possible race in mt7615_mac_sta_poll + +From: Lorenzo Bianconi + +[ Upstream commit 30bc32c7c1f975cc3c14e1c7dc437266311282cf ] + +Grab sta_poll_lock spinlock in mt7615_mac_sta_poll routine in order to +avoid possible races with mt7615_mac_add_txs() or mt7615_mac_fill_rx() +removing msta pointer from sta_poll_list. + +Fixes: a621372a04ac ("mt76: mt7615: rework mt7615_mac_sta_poll for usb code") +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/48b23404b759de4f1db2ef85975c72a4aeb1097c.1684938695.git.lorenzo@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +index 37bc307c19719..2f0ba8a75d71b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +@@ -869,7 +869,10 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev) + + msta = list_first_entry(&sta_poll_list, struct mt7615_sta, + poll_list); ++ ++ spin_lock_bh(&dev->sta_poll_lock); + list_del_init(&msta->poll_list); ++ spin_unlock_bh(&dev->sta_poll_lock); + + addr = mt7615_mac_wtbl_addr(dev, msta->wcid.idx) + 19 * 4; + +-- +2.39.2 +