--- /dev/null
+From fed68f0920237588eab34df2bddf2a407d0b6400 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Oct 2024 22:46:34 +0200
+Subject: ASoC: cs42l51: Fix some error handling paths in cs42l51_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit d221b844ee79823ffc29b7badc4010bdb0960224 ]
+
+If devm_gpiod_get_optional() fails, we need to disable previously enabled
+regulators, as done in the other error handling path of the function.
+
+Also, gpiod_set_value_cansleep(, 1) needs to be called to undo a
+potential gpiod_set_value_cansleep(, 0).
+If the "reset" gpio is not defined, this additional call is just a no-op.
+
+This behavior is the same as the one already in the .remove() function.
+
+Fixes: 11b9cd748e31 ("ASoC: cs42l51: add reset management")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://patch.msgid.link/a5e5f4b9fb03f46abd2c93ed94b5c395972ce0d1.1729975570.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs42l51.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
+index e4827b8c2bde4..6e51954bdb1ec 100644
+--- a/sound/soc/codecs/cs42l51.c
++++ b/sound/soc/codecs/cs42l51.c
+@@ -747,8 +747,10 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
+
+ cs42l51->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_LOW);
+- if (IS_ERR(cs42l51->reset_gpio))
+- return PTR_ERR(cs42l51->reset_gpio);
++ if (IS_ERR(cs42l51->reset_gpio)) {
++ ret = PTR_ERR(cs42l51->reset_gpio);
++ goto error;
++ }
+
+ if (cs42l51->reset_gpio) {
+ dev_dbg(dev, "Release reset gpio\n");
+@@ -780,6 +782,7 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
+ return 0;
+
+ error:
++ gpiod_set_value_cansleep(cs42l51->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(cs42l51->supplies),
+ cs42l51->supplies);
+ return ret;
+--
+2.43.0
+
--- /dev/null
+From 81fe2c8b24e8cd2b92529b2f23556cca6374cca9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Oct 2024 22:50:30 +0000
+Subject: ASoC: dapm: fix bounds checker error in dapm_widget_list_create
+
+From: Aleksei Vetrov <vvvvvv@google.com>
+
+[ Upstream commit 2ef9439f7a19fd3d43b288d38b1c6e55b668a4fe ]
+
+The widgets array in the snd_soc_dapm_widget_list has a __counted_by
+attribute attached to it, which points to the num_widgets variable. This
+attribute is used in bounds checking, and if it is not set before the
+array is filled, then the bounds sanitizer will issue a warning or a
+kernel panic if CONFIG_UBSAN_TRAP is set.
+
+This patch sets the size of the widgets list calculated with
+list_for_each as the initial value for num_widgets as it is used for
+allocating memory for the array. It is updated with the actual number of
+added elements after the array is filled.
+
+Signed-off-by: Aleksei Vetrov <vvvvvv@google.com>
+Fixes: 80e698e2df5b ("ASoC: soc-dapm: Annotate struct snd_soc_dapm_widget_list with __counted_by")
+Link: https://patch.msgid.link/20241028-soc-dapm-bounds-checker-fix-v1-1-262b0394e89e@google.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-dapm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
+index e39df5d10b07d..1647b24ca34d7 100644
+--- a/sound/soc/soc-dapm.c
++++ b/sound/soc/soc-dapm.c
+@@ -1147,6 +1147,8 @@ static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list,
+ if (*list == NULL)
+ return -ENOMEM;
+
++ (*list)->num_widgets = size;
++
+ list_for_each_entry(w, widgets, work_list)
+ (*list)->widgets[i++] = w;
+
+--
+2.43.0
+
--- /dev/null
+From c3dba75253e9d125e872dacd434bf25f4bbef74e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2024 19:44:41 +0000
+Subject: Bluetooth: hci: fix null-ptr-deref in hci_read_supported_codecs
+
+From: Sungwoo Kim <iam@sung-woo.kim>
+
+[ Upstream commit 1e67d8641813f1876a42eeb4f532487b8a7fb0a8 ]
+
+Fix __hci_cmd_sync_sk() to return not NULL for unknown opcodes.
+
+__hci_cmd_sync_sk() returns NULL if a command returns a status event.
+However, it also returns NULL where an opcode doesn't exist in the
+hci_cc table because hci_cmd_complete_evt() assumes status = skb->data[0]
+for unknown opcodes.
+This leads to null-ptr-deref in cmd_sync for HCI_OP_READ_LOCAL_CODECS as
+there is no hci_cc for HCI_OP_READ_LOCAL_CODECS, which always assumes
+status = skb->data[0].
+
+KASAN: null-ptr-deref in range [0x0000000000000070-0x0000000000000077]
+CPU: 1 PID: 2000 Comm: kworker/u9:5 Not tainted 6.9.0-ga6bcb805883c-dirty #10
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+Workqueue: hci7 hci_power_on
+RIP: 0010:hci_read_supported_codecs+0xb9/0x870 net/bluetooth/hci_codec.c:138
+Code: 08 48 89 ef e8 b8 c1 8f fd 48 8b 75 00 e9 96 00 00 00 49 89 c6 48 ba 00 00 00 00 00 fc ff df 4c 8d 60 70 4c 89 e3 48 c1 eb 03 <0f> b6 04 13 84 c0 0f 85 82 06 00 00 41 83 3c 24 02 77 0a e8 bf 78
+RSP: 0018:ffff888120bafac8 EFLAGS: 00010212
+RAX: 0000000000000000 RBX: 000000000000000e RCX: ffff8881173f0040
+RDX: dffffc0000000000 RSI: ffffffffa58496c0 RDI: ffff88810b9ad1e4
+RBP: ffff88810b9ac000 R08: ffffffffa77882a7 R09: 1ffffffff4ef1054
+R10: dffffc0000000000 R11: fffffbfff4ef1055 R12: 0000000000000070
+R13: 0000000000000000 R14: 0000000000000000 R15: ffff88810b9ac000
+FS: 0000000000000000(0000) GS:ffff8881f6c00000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f6ddaa3439e CR3: 0000000139764003 CR4: 0000000000770ef0
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ hci_read_local_codecs_sync net/bluetooth/hci_sync.c:4546 [inline]
+ hci_init_stage_sync net/bluetooth/hci_sync.c:3441 [inline]
+ hci_init4_sync net/bluetooth/hci_sync.c:4706 [inline]
+ hci_init_sync net/bluetooth/hci_sync.c:4742 [inline]
+ hci_dev_init_sync net/bluetooth/hci_sync.c:4912 [inline]
+ hci_dev_open_sync+0x19a9/0x2d30 net/bluetooth/hci_sync.c:4994
+ hci_dev_do_open net/bluetooth/hci_core.c:483 [inline]
+ hci_power_on+0x11e/0x560 net/bluetooth/hci_core.c:1015
+ process_one_work kernel/workqueue.c:3267 [inline]
+ process_scheduled_works+0x8ef/0x14f0 kernel/workqueue.c:3348
+ worker_thread+0x91f/0xe50 kernel/workqueue.c:3429
+ kthread+0x2cb/0x360 kernel/kthread.c:388
+ ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
+
+Fixes: abfeea476c68 ("Bluetooth: hci_sync: Convert MGMT_OP_START_DISCOVERY")
+
+Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index ae7a5817883aa..c0203a2b51075 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -206,6 +206,12 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
+ return ERR_PTR(err);
+ }
+
++ /* If command return a status event skb will be set to NULL as there are
++ * no parameters.
++ */
++ if (!skb)
++ return ERR_PTR(-ENODATA);
++
+ return skb;
+ }
+ EXPORT_SYMBOL(__hci_cmd_sync_sk);
+@@ -255,6 +261,11 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
+ u8 status;
+
+ skb = __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout, sk);
++
++ /* If command return a status event, skb will be set to -ENODATA */
++ if (skb == ERR_PTR(-ENODATA))
++ return 0;
++
+ if (IS_ERR(skb)) {
+ if (!event)
+ bt_dev_err(hdev, "Opcode 0x%4.4x failed: %ld", opcode,
+@@ -262,13 +273,6 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
+ return PTR_ERR(skb);
+ }
+
+- /* If command return a status event skb will be set to NULL as there are
+- * no parameters, in case of failure IS_ERR(skb) would have be set to
+- * the actual error would be found with PTR_ERR(skb).
+- */
+- if (!skb)
+- return 0;
+-
+ status = skb->data[0];
+
+ kfree_skb(skb);
+--
+2.43.0
+
--- /dev/null
+From aadab41bfc1c8292563ff8505806e8e75f4db457 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Oct 2024 18:05:13 +0800
+Subject: bpf: Add bpf_mem_alloc_check_size() helper
+
+From: Hou Tao <houtao1@huawei.com>
+
+[ Upstream commit 62a898b07b83f6f407003d8a70f0827a5af08a59 ]
+
+Introduce bpf_mem_alloc_check_size() to check whether the allocation
+size exceeds the limitation for the kmalloc-equivalent allocator. The
+upper limit for percpu allocation is LLIST_NODE_SZ bytes larger than
+non-percpu allocation, so a percpu argument is added to the helper.
+
+The helper will be used in the following patch to check whether the size
+parameter passed to bpf_mem_alloc() is too big.
+
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20241030100516.3633640-3-houtao@huaweicloud.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Stable-dep-of: 393397fbdcad ("bpf: Check the validity of nr_words in bpf_iter_bits_new()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf_mem_alloc.h | 3 +++
+ kernel/bpf/memalloc.c | 14 +++++++++++++-
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/bpf_mem_alloc.h b/include/linux/bpf_mem_alloc.h
+index aaf004d943228..e45162ef59bb1 100644
+--- a/include/linux/bpf_mem_alloc.h
++++ b/include/linux/bpf_mem_alloc.h
+@@ -33,6 +33,9 @@ int bpf_mem_alloc_percpu_init(struct bpf_mem_alloc *ma, struct obj_cgroup *objcg
+ int bpf_mem_alloc_percpu_unit_init(struct bpf_mem_alloc *ma, int size);
+ void bpf_mem_alloc_destroy(struct bpf_mem_alloc *ma);
+
++/* Check the allocation size for kmalloc equivalent allocator */
++int bpf_mem_alloc_check_size(bool percpu, size_t size);
++
+ /* kmalloc/kfree equivalent: */
+ void *bpf_mem_alloc(struct bpf_mem_alloc *ma, size_t size);
+ void bpf_mem_free(struct bpf_mem_alloc *ma, void *ptr);
+diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c
+index dec892ded031e..b2c7a4c49be77 100644
+--- a/kernel/bpf/memalloc.c
++++ b/kernel/bpf/memalloc.c
+@@ -35,6 +35,8 @@
+ */
+ #define LLIST_NODE_SZ sizeof(struct llist_node)
+
++#define BPF_MEM_ALLOC_SIZE_MAX 4096
++
+ /* similar to kmalloc, but sizeof == 8 bucket is gone */
+ static u8 size_index[24] __ro_after_init = {
+ 3, /* 8 */
+@@ -65,7 +67,7 @@ static u8 size_index[24] __ro_after_init = {
+
+ static int bpf_mem_cache_idx(size_t size)
+ {
+- if (!size || size > 4096)
++ if (!size || size > BPF_MEM_ALLOC_SIZE_MAX)
+ return -1;
+
+ if (size <= 192)
+@@ -1005,3 +1007,13 @@ void notrace *bpf_mem_cache_alloc_flags(struct bpf_mem_alloc *ma, gfp_t flags)
+
+ return !ret ? NULL : ret + LLIST_NODE_SZ;
+ }
++
++int bpf_mem_alloc_check_size(bool percpu, size_t size)
++{
++ /* The size of percpu allocation doesn't have LLIST_NODE_SZ overhead */
++ if ((percpu && size > BPF_MEM_ALLOC_SIZE_MAX) ||
++ (!percpu && size > BPF_MEM_ALLOC_SIZE_MAX - LLIST_NODE_SZ))
++ return -E2BIG;
++
++ return 0;
++}
+--
+2.43.0
+
--- /dev/null
+From 15efe7ec95eb967accc01f729f9f542f2767e258 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Oct 2024 18:05:14 +0800
+Subject: bpf: Check the validity of nr_words in bpf_iter_bits_new()
+
+From: Hou Tao <houtao1@huawei.com>
+
+[ Upstream commit 393397fbdcad7396639d7077c33f86169184ba99 ]
+
+Check the validity of nr_words in bpf_iter_bits_new(). Without this
+check, when multiplication overflow occurs for nr_bits (e.g., when
+nr_words = 0x0400-0001, nr_bits becomes 64), stack corruption may occur
+due to bpf_probe_read_kernel_common(..., nr_bytes = 0x2000-0008).
+
+Fix it by limiting the maximum value of nr_words to 511. The value is
+derived from the current implementation of BPF memory allocator. To
+ensure compatibility if the BPF memory allocator's size limitation
+changes in the future, use the helper bpf_mem_alloc_check_size() to
+check whether nr_bytes is too larger. And return -E2BIG instead of
+-ENOMEM for oversized nr_bytes.
+
+Fixes: 4665415975b0 ("bpf: Add bits iterator")
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20241030100516.3633640-4-houtao@huaweicloud.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/helpers.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index a4521d2606b6b..8419de44c5174 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -2830,6 +2830,8 @@ struct bpf_iter_bits {
+ __u64 __opaque[2];
+ } __aligned(8);
+
++#define BITS_ITER_NR_WORDS_MAX 511
++
+ struct bpf_iter_bits_kern {
+ union {
+ unsigned long *bits;
+@@ -2844,7 +2846,8 @@ struct bpf_iter_bits_kern {
+ * @it: The new bpf_iter_bits to be created
+ * @unsafe_ptr__ign: A pointer pointing to a memory area to be iterated over
+ * @nr_words: The size of the specified memory area, measured in 8-byte units.
+- * Due to the limitation of memalloc, it can't be greater than 512.
++ * The maximum value of @nr_words is @BITS_ITER_NR_WORDS_MAX. This limit may be
++ * further reduced by the BPF memory allocator implementation.
+ *
+ * This function initializes a new bpf_iter_bits structure for iterating over
+ * a memory area which is specified by the @unsafe_ptr__ign and @nr_words. It
+@@ -2871,6 +2874,8 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
+
+ if (!unsafe_ptr__ign || !nr_words)
+ return -EINVAL;
++ if (nr_words > BITS_ITER_NR_WORDS_MAX)
++ return -E2BIG;
+
+ /* Optimization for u64 mask */
+ if (nr_bits == 64) {
+@@ -2882,6 +2887,9 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
+ return 0;
+ }
+
++ if (bpf_mem_alloc_check_size(false, nr_bytes))
++ return -E2BIG;
++
+ /* Fallback to memalloc */
+ kit->bits = bpf_mem_alloc(&bpf_global_ma, nr_bytes);
+ if (!kit->bits)
+--
+2.43.0
+
--- /dev/null
+From 17faf1cc8a2c5ca684855f59265133cd4c32c91e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Oct 2024 14:02:43 +0900
+Subject: bpf: Fix out-of-bounds write in trie_get_next_key()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Byeonguk Jeong <jungbu2855@gmail.com>
+
+[ Upstream commit 13400ac8fb80c57c2bfb12ebd35ee121ce9b4d21 ]
+
+trie_get_next_key() allocates a node stack with size trie->max_prefixlen,
+while it writes (trie->max_prefixlen + 1) nodes to the stack when it has
+full paths from the root to leaves. For example, consider a trie with
+max_prefixlen is 8, and the nodes with key 0x00/0, 0x00/1, 0x00/2, ...
+0x00/8 inserted. Subsequent calls to trie_get_next_key with _key with
+.prefixlen = 8 make 9 nodes be written on the node stack with size 8.
+
+Fixes: b471f2f1de8b ("bpf: implement MAP_GET_NEXT_KEY command for LPM_TRIE map")
+Signed-off-by: Byeonguk Jeong <jungbu2855@gmail.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@kernel.org>
+Tested-by: Hou Tao <houtao1@huawei.com>
+Acked-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/Zxx384ZfdlFYnz6J@localhost.localdomain
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/lpm_trie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
+index 0218a5132ab56..9b60eda0f727b 100644
+--- a/kernel/bpf/lpm_trie.c
++++ b/kernel/bpf/lpm_trie.c
+@@ -655,7 +655,7 @@ static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key)
+ if (!key || key->prefixlen > trie->max_prefixlen)
+ goto find_leftmost;
+
+- node_stack = kmalloc_array(trie->max_prefixlen,
++ node_stack = kmalloc_array(trie->max_prefixlen + 1,
+ sizeof(struct lpm_trie_node *),
+ GFP_ATOMIC | __GFP_NOWARN);
+ if (!node_stack)
+--
+2.43.0
+
--- /dev/null
+From 72a72f67c81e7bf03d39a3871ce5080913d28400 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2024 10:26:40 -0700
+Subject: bpf: Force checkpoint when jmp history is too long
+
+From: Eduard Zingerman <eddyz87@gmail.com>
+
+[ Upstream commit aa30eb3260b2dea3a68d3c42a39f9a09c5e99cee ]
+
+A specifically crafted program might trick verifier into growing very
+long jump history within a single bpf_verifier_state instance.
+Very long jump history makes mark_chain_precision() unreasonably slow,
+especially in case if verifier processes a loop.
+
+Mitigate this by forcing new state in is_state_visited() in case if
+current state's jump history is too long.
+
+Use same constant as in `skip_inf_loop_check`, but multiply it by
+arbitrarily chosen value 2 to account for jump history containing not
+only information about jumps, but also information about stack access.
+
+For an example of problematic program consider the code below,
+w/o this patch the example is processed by verifier for ~15 minutes,
+before failing to allocate big-enough chunk for jmp_history.
+
+ 0: r7 = *(u16 *)(r1 +0);"
+ 1: r7 += 0x1ab064b9;"
+ 2: if r7 & 0x702000 goto 1b;
+ 3: r7 &= 0x1ee60e;"
+ 4: r7 += r1;"
+ 5: if r7 s> 0x37d2 goto +0;"
+ 6: r0 = 0;"
+ 7: exit;"
+
+Perf profiling shows that most of the time is spent in
+mark_chain_precision() ~95%.
+
+The easiest way to explain why this program causes problems is to
+apply the following patch:
+
+ diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+ index 0c216e71cec7..4b4823961abe 100644
+ \--- a/include/linux/bpf.h
+ \+++ b/include/linux/bpf.h
+ \@@ -1926,7 +1926,7 @@ struct bpf_array {
+ };
+ };
+
+ -#define BPF_COMPLEXITY_LIMIT_INSNS 1000000 /* yes. 1M insns */
+ +#define BPF_COMPLEXITY_LIMIT_INSNS 256 /* yes. 1M insns */
+ #define MAX_TAIL_CALL_CNT 33
+
+ /* Maximum number of loops for bpf_loop and bpf_iter_num.
+ diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+ index f514247ba8ba..75e88be3bb3e 100644
+ \--- a/kernel/bpf/verifier.c
+ \+++ b/kernel/bpf/verifier.c
+ \@@ -18024,8 +18024,13 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
+ skip_inf_loop_check:
+ if (!force_new_state &&
+ env->jmps_processed - env->prev_jmps_processed < 20 &&
+ - env->insn_processed - env->prev_insn_processed < 100)
+ + env->insn_processed - env->prev_insn_processed < 100) {
+ + verbose(env, "is_state_visited: suppressing checkpoint at %d, %d jmps processed, cur->jmp_history_cnt is %d\n",
+ + env->insn_idx,
+ + env->jmps_processed - env->prev_jmps_processed,
+ + cur->jmp_history_cnt);
+ add_new_state = false;
+ + }
+ goto miss;
+ }
+ /* If sl->state is a part of a loop and this loop's entry is a part of
+ \@@ -18142,6 +18147,9 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
+ if (!add_new_state)
+ return 0;
+
+ + verbose(env, "is_state_visited: new checkpoint at %d, resetting env->jmps_processed\n",
+ + env->insn_idx);
+ +
+ /* There were no equivalent states, remember the current one.
+ * Technically the current state is not proven to be safe yet,
+ * but it will either reach outer most bpf_exit (which means it's safe)
+
+And observe verification log:
+
+ ...
+ is_state_visited: new checkpoint at 5, resetting env->jmps_processed
+ 5: R1=ctx() R7=ctx(...)
+ 5: (65) if r7 s> 0x37d2 goto pc+0 ; R7=ctx(...)
+ 6: (b7) r0 = 0 ; R0_w=0
+ 7: (95) exit
+
+ from 5 to 6: R1=ctx() R7=ctx(...) R10=fp0
+ 6: R1=ctx() R7=ctx(...) R10=fp0
+ 6: (b7) r0 = 0 ; R0_w=0
+ 7: (95) exit
+ is_state_visited: suppressing checkpoint at 1, 3 jmps processed, cur->jmp_history_cnt is 74
+
+ from 2 to 1: R1=ctx() R7_w=scalar(...) R10=fp0
+ 1: R1=ctx() R7_w=scalar(...) R10=fp0
+ 1: (07) r7 += 447767737
+ is_state_visited: suppressing checkpoint at 2, 3 jmps processed, cur->jmp_history_cnt is 75
+ 2: R7_w=scalar(...)
+ 2: (45) if r7 & 0x702000 goto pc-2
+ ... mark_precise 152 steps for r7 ...
+ 2: R7_w=scalar(...)
+ is_state_visited: suppressing checkpoint at 1, 4 jmps processed, cur->jmp_history_cnt is 75
+ 1: (07) r7 += 447767737
+ is_state_visited: suppressing checkpoint at 2, 4 jmps processed, cur->jmp_history_cnt is 76
+ 2: R7_w=scalar(...)
+ 2: (45) if r7 & 0x702000 goto pc-2
+ ...
+ BPF program is too large. Processed 257 insn
+
+The log output shows that checkpoint at label (1) is never created,
+because it is suppressed by `skip_inf_loop_check` logic:
+a. When 'if' at (2) is processed it pushes a state with insn_idx (1)
+ onto stack and proceeds to (3);
+b. At (5) checkpoint is created, and this resets
+ env->{jmps,insns}_processed.
+c. Verification proceeds and reaches `exit`;
+d. State saved at step (a) is popped from stack and is_state_visited()
+ considers if checkpoint needs to be added, but because
+ env->{jmps,insns}_processed had been just reset at step (b)
+ the `skip_inf_loop_check` logic forces `add_new_state` to false.
+e. Verifier proceeds with current state, which slowly accumulates
+ more and more entries in the jump history.
+
+The accumulation of entries in the jump history is a problem because
+of two factors:
+- it eventually exhausts memory available for kmalloc() allocation;
+- mark_chain_precision() traverses the jump history of a state,
+ meaning that if `r7` is marked precise, verifier would iterate
+ ever growing jump history until parent state boundary is reached.
+
+(note: the log also shows a REG INVARIANTS VIOLATION warning
+ upon jset processing, but that's another bug to fix).
+
+With this patch applied, the example above is rejected by verifier
+under 1s of time, reaching 1M instructions limit.
+
+The program is a simplified reproducer from syzbot report.
+Previous discussion could be found at [1].
+The patch does not cause any changes in verification performance,
+when tested on selftests from veristat.cfg and cilium programs taken
+from [2].
+
+[1] https://lore.kernel.org/bpf/20241009021254.2805446-1-eddyz87@gmail.com/
+[2] https://github.com/anakryiko/cilium
+
+Changelog:
+- v1 -> v2:
+ - moved patch to bpf tree;
+ - moved force_new_state variable initialization after declaration and
+ shortened the comment.
+v1: https://lore.kernel.org/bpf/20241018020307.1766906-1-eddyz87@gmail.com/
+
+Fixes: 2589726d12a1 ("bpf: introduce bounded loops")
+Reported-by: syzbot+7e46cdef14bf496a3ab4@syzkaller.appspotmail.com
+Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20241029172641.1042523-1-eddyz87@gmail.com
+
+Closes: https://lore.kernel.org/bpf/670429f6.050a0220.49194.0517.GAE@google.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 77b60896200ef..626c5284ca5a8 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -17416,9 +17416,11 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
+ struct bpf_verifier_state_list *sl, **pprev;
+ struct bpf_verifier_state *cur = env->cur_state, *new, *loop_entry;
+ int i, j, n, err, states_cnt = 0;
+- bool force_new_state = env->test_state_freq || is_force_checkpoint(env, insn_idx);
+- bool add_new_state = force_new_state;
+- bool force_exact;
++ bool force_new_state, add_new_state, force_exact;
++
++ force_new_state = env->test_state_freq || is_force_checkpoint(env, insn_idx) ||
++ /* Avoid accumulating infinitely long jmp history */
++ cur->jmp_history_cnt > 40;
+
+ /* bpf progs typically have pruning point every 4 instructions
+ * http://vger.kernel.org/bpfconf2019.html#session-1
+@@ -17428,6 +17430,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
+ * In tests that amounts to up to 50% reduction into total verifier
+ * memory consumption and 20% verifier time speedup.
+ */
++ add_new_state = force_new_state;
+ if (env->jmps_processed - env->prev_jmps_processed >= 2 &&
+ env->insn_processed - env->prev_insn_processed >= 8)
+ add_new_state = true;
+--
+2.43.0
+
--- /dev/null
+From 78ff4912dee5a49329760c31205a4c0ad120bf6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Oct 2024 18:05:12 +0800
+Subject: bpf: Free dynamically allocated bits in bpf_iter_bits_destroy()
+
+From: Hou Tao <houtao1@huawei.com>
+
+[ Upstream commit 101ccfbabf4738041273ce64e2b116cf440dea13 ]
+
+bpf_iter_bits_destroy() uses "kit->nr_bits <= 64" to check whether the
+bits are dynamically allocated. However, the check is incorrect and may
+cause a kmemleak as shown below:
+
+unreferenced object 0xffff88812628c8c0 (size 32):
+ comm "swapper/0", pid 1, jiffies 4294727320
+ hex dump (first 32 bytes):
+ b0 c1 55 f5 81 88 ff ff f0 f0 f0 f0 f0 f0 f0 f0 ..U...........
+ f0 f0 f0 f0 f0 f0 f0 f0 00 00 00 00 00 00 00 00 ..............
+ backtrace (crc 781e32cc):
+ [<00000000c452b4ab>] kmemleak_alloc+0x4b/0x80
+ [<0000000004e09f80>] __kmalloc_node_noprof+0x480/0x5c0
+ [<00000000597124d6>] __alloc.isra.0+0x89/0xb0
+ [<000000004ebfffcd>] alloc_bulk+0x2af/0x720
+ [<00000000d9c10145>] prefill_mem_cache+0x7f/0xb0
+ [<00000000ff9738ff>] bpf_mem_alloc_init+0x3e2/0x610
+ [<000000008b616eac>] bpf_global_ma_init+0x19/0x30
+ [<00000000fc473efc>] do_one_initcall+0xd3/0x3c0
+ [<00000000ec81498c>] kernel_init_freeable+0x66a/0x940
+ [<00000000b119f72f>] kernel_init+0x20/0x160
+ [<00000000f11ac9a7>] ret_from_fork+0x3c/0x70
+ [<0000000004671da4>] ret_from_fork_asm+0x1a/0x30
+
+That is because nr_bits will be set as zero in bpf_iter_bits_next()
+after all bits have been iterated.
+
+Fix the issue by setting kit->bit to kit->nr_bits instead of setting
+kit->nr_bits to zero when the iteration completes in
+bpf_iter_bits_next(). In addition, use "!nr_bits || bits >= nr_bits" to
+check whether the iteration is complete and still use "nr_bits > 64" to
+indicate whether bits are dynamically allocated. The "!nr_bits" check is
+necessary because bpf_iter_bits_new() may fail before setting
+kit->nr_bits, and this condition will stop the iteration early instead
+of accessing the zeroed or freed kit->bits.
+
+Considering the initial value of kit->bits is -1 and the type of
+kit->nr_bits is unsigned int, change the type of kit->nr_bits to int.
+The potential overflow problem will be handled in the following patch.
+
+Fixes: 4665415975b0 ("bpf: Add bits iterator")
+Acked-by: Yafang Shao <laoar.shao@gmail.com>
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20241030100516.3633640-2-houtao@huaweicloud.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/helpers.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index cc8c00864a680..a4521d2606b6b 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -2835,7 +2835,7 @@ struct bpf_iter_bits_kern {
+ unsigned long *bits;
+ unsigned long bits_copy;
+ };
+- u32 nr_bits;
++ int nr_bits;
+ int bit;
+ } __aligned(8);
+
+@@ -2909,17 +2909,16 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
+ __bpf_kfunc int *bpf_iter_bits_next(struct bpf_iter_bits *it)
+ {
+ struct bpf_iter_bits_kern *kit = (void *)it;
+- u32 nr_bits = kit->nr_bits;
++ int bit = kit->bit, nr_bits = kit->nr_bits;
+ const unsigned long *bits;
+- int bit;
+
+- if (nr_bits == 0)
++ if (!nr_bits || bit >= nr_bits)
+ return NULL;
+
+ bits = nr_bits == 64 ? &kit->bits_copy : kit->bits;
+- bit = find_next_bit(bits, nr_bits, kit->bit + 1);
++ bit = find_next_bit(bits, nr_bits, bit + 1);
+ if (bit >= nr_bits) {
+- kit->nr_bits = 0;
++ kit->bit = bit;
+ return NULL;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 2d65f745d7d43c7170338fe80c8f89899aa6ba9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Oct 2024 11:48:26 +0100
+Subject: bpf, test_run: Fix LIVE_FRAME frame update after a page has been
+ recycled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit c40dd8c4732551605712985bc5b7045094c6458d ]
+
+The test_run code detects whether a page has been modified and
+re-initialises the xdp_frame structure if it has, using
+xdp_update_frame_from_buff(). However, xdp_update_frame_from_buff()
+doesn't touch frame->mem, so that wasn't correctly re-initialised, which
+led to the pages from page_pool not being returned correctly. Syzbot
+noticed this as a memory leak.
+
+Fix this by also copying the frame->mem structure when re-initialising
+the frame, like we do on initialisation of a new page from page_pool.
+
+Fixes: e5995bc7e2ba ("bpf, test_run: fix crashes due to XDP frame overwriting/corruption")
+Fixes: b530e9e1063e ("bpf: Add "live packet" mode for XDP in BPF_PROG_RUN")
+Reported-by: syzbot+d121e098da06af416d23@syzkaller.appspotmail.com
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Tested-by: syzbot+d121e098da06af416d23@syzkaller.appspotmail.com
+Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Acked-by: Stanislav Fomichev <sdf@fomichev.me>
+Link: https://lore.kernel.org/bpf/20241030-test-run-mem-fix-v1-1-41e88e8cae43@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bpf/test_run.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
+index 6d7a442ceb89b..501ec4249fedc 100644
+--- a/net/bpf/test_run.c
++++ b/net/bpf/test_run.c
+@@ -246,6 +246,7 @@ static void reset_ctx(struct xdp_page_head *head)
+ head->ctx.data_meta = head->orig_ctx.data_meta;
+ head->ctx.data_end = head->orig_ctx.data_end;
+ xdp_update_frame_from_buff(&head->ctx, head->frame);
++ head->frame->mem = head->orig_ctx.rxq->mem;
+ }
+
+ static int xdp_recv_frames(struct xdp_frame **frames, int nframes,
+--
+2.43.0
+
--- /dev/null
+From d75d9398c378d9344e21be7350ea721d95aff7a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Aug 2024 00:25:12 +0200
+Subject: dpll: add Embedded SYNC feature for a pin
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+[ Upstream commit cda1fba15cb2282b3c364805c9767698f11c3b0e ]
+
+Implement and document new pin attributes for providing Embedded SYNC
+capabilities to the DPLL subsystem users through a netlink pin-get
+do/dump messages. Allow the user to set Embedded SYNC frequency with
+pin-set do netlink message.
+
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://patch.msgid.link/20240822222513.255179-2-arkadiusz.kubalewski@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 6e58c3310622 ("ice: fix crash on probe for DPLL enabled E810 LOM")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/driver-api/dpll.rst | 21 +++++
+ Documentation/netlink/specs/dpll.yaml | 24 +++++
+ drivers/dpll/dpll_netlink.c | 130 ++++++++++++++++++++++++++
+ drivers/dpll/dpll_nl.c | 5 +-
+ include/linux/dpll.h | 15 +++
+ include/uapi/linux/dpll.h | 3 +
+ 6 files changed, 196 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst
+index ea8d16600e16a..e6855cd37e852 100644
+--- a/Documentation/driver-api/dpll.rst
++++ b/Documentation/driver-api/dpll.rst
+@@ -214,6 +214,27 @@ offset values are fractional with 3-digit decimal places and shell be
+ divided with ``DPLL_PIN_PHASE_OFFSET_DIVIDER`` to get integer part and
+ modulo divided to get fractional part.
+
++Embedded SYNC
++=============
++
++Device may provide ability to use Embedded SYNC feature. It allows
++to embed additional SYNC signal into the base frequency of a pin - a one
++special pulse of base frequency signal every time SYNC signal pulse
++happens. The user can configure the frequency of Embedded SYNC.
++The Embedded SYNC capability is always related to a given base frequency
++and HW capabilities. The user is provided a range of Embedded SYNC
++frequencies supported, depending on current base frequency configured for
++the pin.
++
++ ========================================= =================================
++ ``DPLL_A_PIN_ESYNC_FREQUENCY`` current Embedded SYNC frequency
++ ``DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED`` nest available Embedded SYNC
++ frequency ranges
++ ``DPLL_A_PIN_FREQUENCY_MIN`` attr minimum value of frequency
++ ``DPLL_A_PIN_FREQUENCY_MAX`` attr maximum value of frequency
++ ``DPLL_A_PIN_ESYNC_PULSE`` pulse type of Embedded SYNC
++ ========================================= =================================
++
+ Configuration commands group
+ ============================
+
+diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml
+index 94132d30e0e03..f2894ca35de84 100644
+--- a/Documentation/netlink/specs/dpll.yaml
++++ b/Documentation/netlink/specs/dpll.yaml
+@@ -345,6 +345,26 @@ attribute-sets:
+ Value is in PPM (parts per million).
+ This may be implemented for example for pin of type
+ PIN_TYPE_SYNCE_ETH_PORT.
++ -
++ name: esync-frequency
++ type: u64
++ doc: |
++ Frequency of Embedded SYNC signal. If provided, the pin is configured
++ with a SYNC signal embedded into its base clock frequency.
++ -
++ name: esync-frequency-supported
++ type: nest
++ multi-attr: true
++ nested-attributes: frequency-range
++ doc: |
++ If provided a pin is capable of embedding a SYNC signal (within given
++ range) into its base frequency signal.
++ -
++ name: esync-pulse
++ type: u32
++ doc: |
++ A ratio of high to low state of a SYNC signal pulse embedded
++ into base clock frequency. Value is in percents.
+ -
+ name: pin-parent-device
+ subset-of: pin
+@@ -510,6 +530,9 @@ operations:
+ - phase-adjust-max
+ - phase-adjust
+ - fractional-frequency-offset
++ - esync-frequency
++ - esync-frequency-supported
++ - esync-pulse
+
+ dump:
+ request:
+@@ -536,6 +559,7 @@ operations:
+ - parent-device
+ - parent-pin
+ - phase-adjust
++ - esync-frequency
+ -
+ name: pin-create-ntf
+ doc: Notification about pin appearing
+diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
+index 98e6ad8528d37..fc0280dcddd10 100644
+--- a/drivers/dpll/dpll_netlink.c
++++ b/drivers/dpll/dpll_netlink.c
+@@ -342,6 +342,51 @@ dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
+ return 0;
+ }
+
++static int
++dpll_msg_add_pin_esync(struct sk_buff *msg, struct dpll_pin *pin,
++ struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
++{
++ const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
++ struct dpll_device *dpll = ref->dpll;
++ struct dpll_pin_esync esync;
++ struct nlattr *nest;
++ int ret, i;
++
++ if (!ops->esync_get)
++ return 0;
++ ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
++ dpll_priv(dpll), &esync, extack);
++ if (ret == -EOPNOTSUPP)
++ return 0;
++ else if (ret)
++ return ret;
++ if (nla_put_64bit(msg, DPLL_A_PIN_ESYNC_FREQUENCY, sizeof(esync.freq),
++ &esync.freq, DPLL_A_PIN_PAD))
++ return -EMSGSIZE;
++ if (nla_put_u32(msg, DPLL_A_PIN_ESYNC_PULSE, esync.pulse))
++ return -EMSGSIZE;
++ for (i = 0; i < esync.range_num; i++) {
++ nest = nla_nest_start(msg,
++ DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED);
++ if (!nest)
++ return -EMSGSIZE;
++ if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN,
++ sizeof(esync.range[i].min),
++ &esync.range[i].min, DPLL_A_PIN_PAD))
++ goto nest_cancel;
++ if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX,
++ sizeof(esync.range[i].max),
++ &esync.range[i].max, DPLL_A_PIN_PAD))
++ goto nest_cancel;
++ nla_nest_end(msg, nest);
++ }
++ return 0;
++
++nest_cancel:
++ nla_nest_cancel(msg, nest);
++ return -EMSGSIZE;
++}
++
+ static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
+ {
+ int fs;
+@@ -481,6 +526,9 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
+ if (ret)
+ return ret;
+ ret = dpll_msg_add_ffo(msg, pin, ref, extack);
++ if (ret)
++ return ret;
++ ret = dpll_msg_add_pin_esync(msg, pin, ref, extack);
+ if (ret)
+ return ret;
+ if (xa_empty(&pin->parent_refs))
+@@ -738,6 +786,83 @@ dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a,
+ return ret;
+ }
+
++static int
++dpll_pin_esync_set(struct dpll_pin *pin, struct nlattr *a,
++ struct netlink_ext_ack *extack)
++{
++ struct dpll_pin_ref *ref, *failed;
++ const struct dpll_pin_ops *ops;
++ struct dpll_pin_esync esync;
++ u64 freq = nla_get_u64(a);
++ struct dpll_device *dpll;
++ bool supported = false;
++ unsigned long i;
++ int ret;
++
++ xa_for_each(&pin->dpll_refs, i, ref) {
++ ops = dpll_pin_ops(ref);
++ if (!ops->esync_set || !ops->esync_get) {
++ NL_SET_ERR_MSG(extack,
++ "embedded sync feature is not supported by this device");
++ return -EOPNOTSUPP;
++ }
++ }
++ ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
++ ops = dpll_pin_ops(ref);
++ dpll = ref->dpll;
++ ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
++ dpll_priv(dpll), &esync, extack);
++ if (ret) {
++ NL_SET_ERR_MSG(extack, "unable to get current embedded sync frequency value");
++ return ret;
++ }
++ if (freq == esync.freq)
++ return 0;
++ for (i = 0; i < esync.range_num; i++)
++ if (freq <= esync.range[i].max && freq >= esync.range[i].min)
++ supported = true;
++ if (!supported) {
++ NL_SET_ERR_MSG_ATTR(extack, a,
++ "requested embedded sync frequency value is not supported by this device");
++ return -EINVAL;
++ }
++
++ xa_for_each(&pin->dpll_refs, i, ref) {
++ void *pin_dpll_priv;
++
++ ops = dpll_pin_ops(ref);
++ dpll = ref->dpll;
++ pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
++ ret = ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
++ freq, extack);
++ if (ret) {
++ failed = ref;
++ NL_SET_ERR_MSG_FMT(extack,
++ "embedded sync frequency set failed for dpll_id: %u",
++ dpll->id);
++ goto rollback;
++ }
++ }
++ __dpll_pin_change_ntf(pin);
++
++ return 0;
++
++rollback:
++ xa_for_each(&pin->dpll_refs, i, ref) {
++ void *pin_dpll_priv;
++
++ if (ref == failed)
++ break;
++ ops = dpll_pin_ops(ref);
++ dpll = ref->dpll;
++ pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
++ if (ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
++ esync.freq, extack))
++ NL_SET_ERR_MSG(extack, "set embedded sync frequency rollback failed");
++ }
++ return ret;
++}
++
+ static int
+ dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
+ enum dpll_pin_state state,
+@@ -1039,6 +1164,11 @@ dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info)
+ if (ret)
+ return ret;
+ break;
++ case DPLL_A_PIN_ESYNC_FREQUENCY:
++ ret = dpll_pin_esync_set(pin, a, info->extack);
++ if (ret)
++ return ret;
++ break;
+ }
+ }
+
+diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c
+index 1e95f5397cfce..fe9b6893d2614 100644
+--- a/drivers/dpll/dpll_nl.c
++++ b/drivers/dpll/dpll_nl.c
+@@ -62,7 +62,7 @@ static const struct nla_policy dpll_pin_get_dump_nl_policy[DPLL_A_PIN_ID + 1] =
+ };
+
+ /* DPLL_CMD_PIN_SET - do */
+-static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PHASE_ADJUST + 1] = {
++static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_ESYNC_FREQUENCY + 1] = {
+ [DPLL_A_PIN_ID] = { .type = NLA_U32, },
+ [DPLL_A_PIN_FREQUENCY] = { .type = NLA_U64, },
+ [DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
+@@ -71,6 +71,7 @@ static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PHASE_ADJUST +
+ [DPLL_A_PIN_PARENT_DEVICE] = NLA_POLICY_NESTED(dpll_pin_parent_device_nl_policy),
+ [DPLL_A_PIN_PARENT_PIN] = NLA_POLICY_NESTED(dpll_pin_parent_pin_nl_policy),
+ [DPLL_A_PIN_PHASE_ADJUST] = { .type = NLA_S32, },
++ [DPLL_A_PIN_ESYNC_FREQUENCY] = { .type = NLA_U64, },
+ };
+
+ /* Ops table for dpll */
+@@ -138,7 +139,7 @@ static const struct genl_split_ops dpll_nl_ops[] = {
+ .doit = dpll_nl_pin_set_doit,
+ .post_doit = dpll_pin_post_doit,
+ .policy = dpll_pin_set_nl_policy,
+- .maxattr = DPLL_A_PIN_PHASE_ADJUST,
++ .maxattr = DPLL_A_PIN_ESYNC_FREQUENCY,
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
+ },
+ };
+diff --git a/include/linux/dpll.h b/include/linux/dpll.h
+index d275736230b3b..81f7b623d0ba6 100644
+--- a/include/linux/dpll.h
++++ b/include/linux/dpll.h
+@@ -15,6 +15,7 @@
+
+ struct dpll_device;
+ struct dpll_pin;
++struct dpll_pin_esync;
+
+ struct dpll_device_ops {
+ int (*mode_get)(const struct dpll_device *dpll, void *dpll_priv,
+@@ -83,6 +84,13 @@ struct dpll_pin_ops {
+ int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
+ const struct dpll_device *dpll, void *dpll_priv,
+ s64 *ffo, struct netlink_ext_ack *extack);
++ int (*esync_set)(const struct dpll_pin *pin, void *pin_priv,
++ const struct dpll_device *dpll, void *dpll_priv,
++ u64 freq, struct netlink_ext_ack *extack);
++ int (*esync_get)(const struct dpll_pin *pin, void *pin_priv,
++ const struct dpll_device *dpll, void *dpll_priv,
++ struct dpll_pin_esync *esync,
++ struct netlink_ext_ack *extack);
+ };
+
+ struct dpll_pin_frequency {
+@@ -111,6 +119,13 @@ struct dpll_pin_phase_adjust_range {
+ s32 max;
+ };
+
++struct dpll_pin_esync {
++ u64 freq;
++ const struct dpll_pin_frequency *range;
++ u8 range_num;
++ u8 pulse;
++};
++
+ struct dpll_pin_properties {
+ const char *board_label;
+ const char *panel_label;
+diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h
+index 0c13d7f1a1bc3..b0654ade7b7eb 100644
+--- a/include/uapi/linux/dpll.h
++++ b/include/uapi/linux/dpll.h
+@@ -210,6 +210,9 @@ enum dpll_a_pin {
+ DPLL_A_PIN_PHASE_ADJUST,
+ DPLL_A_PIN_PHASE_OFFSET,
+ DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
++ DPLL_A_PIN_ESYNC_FREQUENCY,
++ DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED,
++ DPLL_A_PIN_ESYNC_PULSE,
+
+ __DPLL_A_PIN_MAX,
+ DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)
+--
+2.43.0
+
--- /dev/null
+From 0470610a6c2cbbb35917a94b10930bff8ff2d336 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2024 16:48:25 +0200
+Subject: gtp: allow -1 to be specified as file description from userspace
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 7515e37bce5c428a56a9b04ea7e96b3f53f17150 ]
+
+Existing user space applications maintained by the Osmocom project are
+breaking since a recent fix that addresses incorrect error checking.
+
+Restore operation for user space programs that specify -1 as file
+descriptor to skip GTPv0 or GTPv1 only sockets.
+
+Fixes: defd8b3c37b0 ("gtp: fix a potential NULL pointer dereference")
+Reported-by: Pau Espin Pedrol <pespin@sysmocom.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Tested-by: Oliver Smith <osmith@sysmocom.de>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20241022144825.66740-1-pablo@netfilter.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/gtp.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
+index 2e94d10348cce..4cb925321785e 100644
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -1702,20 +1702,24 @@ static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
+ return -EINVAL;
+
+ if (data[IFLA_GTP_FD0]) {
+- u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
++ int fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
+
+- sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
+- if (IS_ERR(sk0))
+- return PTR_ERR(sk0);
++ if (fd0 >= 0) {
++ sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
++ if (IS_ERR(sk0))
++ return PTR_ERR(sk0);
++ }
+ }
+
+ if (data[IFLA_GTP_FD1]) {
+- u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
++ int fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
+
+- sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
+- if (IS_ERR(sk1u)) {
+- gtp_encap_disable_sock(sk0);
+- return PTR_ERR(sk1u);
++ if (fd1 >= 0) {
++ sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
++ if (IS_ERR(sk1u)) {
++ gtp_encap_disable_sock(sk0);
++ return PTR_ERR(sk1u);
++ }
+ }
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 91aab4757843df77ad752ac3ecfd863c17003cf2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Aug 2024 00:25:13 +0200
+Subject: ice: add callbacks for Embedded SYNC enablement on dpll pins
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+[ Upstream commit 87abc5666ab753e8c31a2d39df3b5233f4e47b43 ]
+
+Allow the user to get and set configuration of Embedded SYNC feature
+on the ice driver dpll pins.
+
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://patch.msgid.link/20240822222513.255179-3-arkadiusz.kubalewski@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 6e58c3310622 ("ice: fix crash on probe for DPLL enabled E810 LOM")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_dpll.c | 223 +++++++++++++++++++++-
+ drivers/net/ethernet/intel/ice/ice_dpll.h | 1 +
+ 2 files changed, 221 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
+index cc35d29ac9e6c..74c0e7319a4ca 100644
+--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
++++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
+@@ -9,6 +9,7 @@
+ #define ICE_CGU_STATE_ACQ_ERR_THRESHOLD 50
+ #define ICE_DPLL_PIN_IDX_INVALID 0xff
+ #define ICE_DPLL_RCLK_NUM_PER_PF 1
++#define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25
+
+ /**
+ * enum ice_dpll_pin_type - enumerate ice pin types:
+@@ -30,6 +31,10 @@ static const char * const pin_type_name[] = {
+ [ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
+ };
+
++static const struct dpll_pin_frequency ice_esync_range[] = {
++ DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),
++};
++
+ /**
+ * ice_dpll_is_reset - check if reset is in progress
+ * @pf: private board structure
+@@ -394,8 +399,8 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
+
+ switch (pin_type) {
+ case ICE_DPLL_PIN_TYPE_INPUT:
+- ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, NULL, NULL,
+- NULL, &pin->flags[0],
++ ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status,
++ NULL, NULL, &pin->flags[0],
+ &pin->freq, &pin->phase_adjust);
+ if (ret)
+ goto err;
+@@ -430,7 +435,7 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
+ goto err;
+
+ parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
+- if (ICE_AQC_SET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
++ if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
+ pin->state[pf->dplls.eec.dpll_idx] =
+ parent == pf->dplls.eec.dpll_idx ?
+ DPLL_PIN_STATE_CONNECTED :
+@@ -1100,6 +1105,214 @@ ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
+ return 0;
+ }
+
++/**
++ * ice_dpll_output_esync_set - callback for setting embedded sync
++ * @pin: pointer to a pin
++ * @pin_priv: private data pointer passed on pin registration
++ * @dpll: registered dpll pointer
++ * @dpll_priv: private data pointer passed on dpll registration
++ * @freq: requested embedded sync frequency
++ * @extack: error reporting
++ *
++ * Dpll subsystem callback. Handler for setting embedded sync frequency value
++ * on output pin.
++ *
++ * Context: Acquires pf->dplls.lock
++ * Return:
++ * * 0 - success
++ * * negative - error
++ */
++static int
++ice_dpll_output_esync_set(const struct dpll_pin *pin, void *pin_priv,
++ const struct dpll_device *dpll, void *dpll_priv,
++ u64 freq, struct netlink_ext_ack *extack)
++{
++ struct ice_dpll_pin *p = pin_priv;
++ struct ice_dpll *d = dpll_priv;
++ struct ice_pf *pf = d->pf;
++ u8 flags = 0;
++ int ret;
++
++ if (ice_dpll_is_reset(pf, extack))
++ return -EBUSY;
++ mutex_lock(&pf->dplls.lock);
++ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
++ flags = ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
++ if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
++ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
++ ret = 0;
++ } else {
++ flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
++ ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
++ 0, 0, 0);
++ }
++ } else {
++ if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)) {
++ ret = 0;
++ } else {
++ flags &= ~ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
++ ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
++ 0, 0, 0);
++ }
++ }
++ mutex_unlock(&pf->dplls.lock);
++
++ return ret;
++}
++
++/**
++ * ice_dpll_output_esync_get - callback for getting embedded sync config
++ * @pin: pointer to a pin
++ * @pin_priv: private data pointer passed on pin registration
++ * @dpll: registered dpll pointer
++ * @dpll_priv: private data pointer passed on dpll registration
++ * @esync: on success holds embedded sync pin properties
++ * @extack: error reporting
++ *
++ * Dpll subsystem callback. Handler for getting embedded sync frequency value
++ * and capabilities on output pin.
++ *
++ * Context: Acquires pf->dplls.lock
++ * Return:
++ * * 0 - success
++ * * negative - error
++ */
++static int
++ice_dpll_output_esync_get(const struct dpll_pin *pin, void *pin_priv,
++ const struct dpll_device *dpll, void *dpll_priv,
++ struct dpll_pin_esync *esync,
++ struct netlink_ext_ack *extack)
++{
++ struct ice_dpll_pin *p = pin_priv;
++ struct ice_dpll *d = dpll_priv;
++ struct ice_pf *pf = d->pf;
++
++ if (ice_dpll_is_reset(pf, extack))
++ return -EBUSY;
++ mutex_lock(&pf->dplls.lock);
++ if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_ABILITY) ||
++ p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
++ mutex_unlock(&pf->dplls.lock);
++ return -EOPNOTSUPP;
++ }
++ esync->range = ice_esync_range;
++ esync->range_num = ARRAY_SIZE(ice_esync_range);
++ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
++ esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
++ esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
++ } else {
++ esync->freq = 0;
++ esync->pulse = 0;
++ }
++ mutex_unlock(&pf->dplls.lock);
++
++ return 0;
++}
++
++/**
++ * ice_dpll_input_esync_set - callback for setting embedded sync
++ * @pin: pointer to a pin
++ * @pin_priv: private data pointer passed on pin registration
++ * @dpll: registered dpll pointer
++ * @dpll_priv: private data pointer passed on dpll registration
++ * @freq: requested embedded sync frequency
++ * @extack: error reporting
++ *
++ * Dpll subsystem callback. Handler for setting embedded sync frequency value
++ * on input pin.
++ *
++ * Context: Acquires pf->dplls.lock
++ * Return:
++ * * 0 - success
++ * * negative - error
++ */
++static int
++ice_dpll_input_esync_set(const struct dpll_pin *pin, void *pin_priv,
++ const struct dpll_device *dpll, void *dpll_priv,
++ u64 freq, struct netlink_ext_ack *extack)
++{
++ struct ice_dpll_pin *p = pin_priv;
++ struct ice_dpll *d = dpll_priv;
++ struct ice_pf *pf = d->pf;
++ u8 flags_en = 0;
++ int ret;
++
++ if (ice_dpll_is_reset(pf, extack))
++ return -EBUSY;
++ mutex_lock(&pf->dplls.lock);
++ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
++ flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
++ if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
++ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
++ ret = 0;
++ } else {
++ flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
++ ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
++ flags_en, 0, 0);
++ }
++ } else {
++ if (!(p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)) {
++ ret = 0;
++ } else {
++ flags_en &= ~ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
++ ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
++ flags_en, 0, 0);
++ }
++ }
++ mutex_unlock(&pf->dplls.lock);
++
++ return ret;
++}
++
++/**
++ * ice_dpll_input_esync_get - callback for getting embedded sync config
++ * @pin: pointer to a pin
++ * @pin_priv: private data pointer passed on pin registration
++ * @dpll: registered dpll pointer
++ * @dpll_priv: private data pointer passed on dpll registration
++ * @esync: on success holds embedded sync pin properties
++ * @extack: error reporting
++ *
++ * Dpll subsystem callback. Handler for getting embedded sync frequency value
++ * and capabilities on input pin.
++ *
++ * Context: Acquires pf->dplls.lock
++ * Return:
++ * * 0 - success
++ * * negative - error
++ */
++static int
++ice_dpll_input_esync_get(const struct dpll_pin *pin, void *pin_priv,
++ const struct dpll_device *dpll, void *dpll_priv,
++ struct dpll_pin_esync *esync,
++ struct netlink_ext_ack *extack)
++{
++ struct ice_dpll_pin *p = pin_priv;
++ struct ice_dpll *d = dpll_priv;
++ struct ice_pf *pf = d->pf;
++
++ if (ice_dpll_is_reset(pf, extack))
++ return -EBUSY;
++ mutex_lock(&pf->dplls.lock);
++ if (!(p->status & ICE_AQC_GET_CGU_IN_CFG_STATUS_ESYNC_CAP) ||
++ p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
++ mutex_unlock(&pf->dplls.lock);
++ return -EOPNOTSUPP;
++ }
++ esync->range = ice_esync_range;
++ esync->range_num = ARRAY_SIZE(ice_esync_range);
++ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
++ esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
++ esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
++ } else {
++ esync->freq = 0;
++ esync->pulse = 0;
++ }
++ mutex_unlock(&pf->dplls.lock);
++
++ return 0;
++}
++
+ /**
+ * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
+ * @pin: pointer to a pin
+@@ -1224,6 +1437,8 @@ static const struct dpll_pin_ops ice_dpll_input_ops = {
+ .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
+ .phase_adjust_set = ice_dpll_input_phase_adjust_set,
+ .phase_offset_get = ice_dpll_phase_offset_get,
++ .esync_set = ice_dpll_input_esync_set,
++ .esync_get = ice_dpll_input_esync_get,
+ };
+
+ static const struct dpll_pin_ops ice_dpll_output_ops = {
+@@ -1234,6 +1449,8 @@ static const struct dpll_pin_ops ice_dpll_output_ops = {
+ .direction_get = ice_dpll_output_direction,
+ .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
+ .phase_adjust_set = ice_dpll_output_phase_adjust_set,
++ .esync_set = ice_dpll_output_esync_set,
++ .esync_get = ice_dpll_output_esync_get,
+ };
+
+ static const struct dpll_device_ops ice_dpll_ops = {
+diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
+index 93172e93995b9..c320f1bf7d6d6 100644
+--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
++++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
+@@ -31,6 +31,7 @@ struct ice_dpll_pin {
+ struct dpll_pin_properties prop;
+ u32 freq;
+ s32 phase_adjust;
++ u8 status;
+ };
+
+ /** ice_dpll - store info required for DPLL control
+--
+2.43.0
+
--- /dev/null
+From 6a5d32ad49b5377bcd0f8558ab8860d59ad97ff9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 16:26:26 -0700
+Subject: ice: fix crash on probe for DPLL enabled E810 LOM
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+[ Upstream commit 6e58c33106220c6c0c8fbee9ab63eae76ad8f260 ]
+
+The E810 Lan On Motherboard (LOM) design is vendor specific. Intel
+provides the reference design, but it is up to vendor on the final
+product design. For some cases, like Linux DPLL support, the static
+values defined in the driver does not reflect the actual LOM design.
+Current implementation of dpll pins is causing the crash on probe
+of the ice driver for such DPLL enabled E810 LOM designs:
+
+WARNING: (...) at drivers/dpll/dpll_core.c:495 dpll_pin_get+0x2c4/0x330
+...
+Call Trace:
+ <TASK>
+ ? __warn+0x83/0x130
+ ? dpll_pin_get+0x2c4/0x330
+ ? report_bug+0x1b7/0x1d0
+ ? handle_bug+0x42/0x70
+ ? exc_invalid_op+0x18/0x70
+ ? asm_exc_invalid_op+0x1a/0x20
+ ? dpll_pin_get+0x117/0x330
+ ? dpll_pin_get+0x2c4/0x330
+ ? dpll_pin_get+0x117/0x330
+ ice_dpll_get_pins.isra.0+0x52/0xe0 [ice]
+...
+
+The number of dpll pins enabled by LOM vendor is greater than expected
+and defined in the driver for Intel designed NICs, which causes the crash.
+
+Prevent the crash and allow generic pin initialization within Linux DPLL
+subsystem for DPLL enabled E810 LOM designs.
+
+Newly designed solution for described issue will be based on "per HW
+design" pin initialization. It requires pin information dynamically
+acquired from the firmware and is already in progress, planned for
+next-tree only.
+
+Fixes: d7999f5ea64b ("ice: implement dpll interface to control cgu")
+Reviewed-by: Karol Kolacinski <karol.kolacinski@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_dpll.c | 70 +++++++++++++++++++++
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 21 ++++++-
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 +
+ 3 files changed, 90 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
+index 74c0e7319a4ca..d5ad6d84007c2 100644
+--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
++++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
+@@ -10,6 +10,7 @@
+ #define ICE_DPLL_PIN_IDX_INVALID 0xff
+ #define ICE_DPLL_RCLK_NUM_PER_PF 1
+ #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25
++#define ICE_DPLL_PIN_GEN_RCLK_FREQ 1953125
+
+ /**
+ * enum ice_dpll_pin_type - enumerate ice pin types:
+@@ -2063,6 +2064,73 @@ static int ice_dpll_init_worker(struct ice_pf *pf)
+ return 0;
+ }
+
++/**
++ * ice_dpll_init_info_pins_generic - initializes generic pins info
++ * @pf: board private structure
++ * @input: if input pins initialized
++ *
++ * Init information for generic pins, cache them in PF's pins structures.
++ *
++ * Return:
++ * * 0 - success
++ * * negative - init failure reason
++ */
++static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
++{
++ struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
++ static const char labels[][sizeof("99")] = {
++ "0", "1", "2", "3", "4", "5", "6", "7", "8",
++ "9", "10", "11", "12", "13", "14", "15" };
++ u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
++ enum ice_dpll_pin_type pin_type;
++ int i, pin_num, ret = -EINVAL;
++ struct ice_dpll_pin *pins;
++ u32 phase_adj_max;
++
++ if (input) {
++ pin_num = pf->dplls.num_inputs;
++ pins = pf->dplls.inputs;
++ phase_adj_max = pf->dplls.input_phase_adj_max;
++ pin_type = ICE_DPLL_PIN_TYPE_INPUT;
++ cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
++ } else {
++ pin_num = pf->dplls.num_outputs;
++ pins = pf->dplls.outputs;
++ phase_adj_max = pf->dplls.output_phase_adj_max;
++ pin_type = ICE_DPLL_PIN_TYPE_OUTPUT;
++ }
++ if (pin_num > ARRAY_SIZE(labels))
++ return ret;
++
++ for (i = 0; i < pin_num; i++) {
++ pins[i].idx = i;
++ pins[i].prop.board_label = labels[i];
++ pins[i].prop.phase_range.min = phase_adj_max;
++ pins[i].prop.phase_range.max = -phase_adj_max;
++ pins[i].prop.capabilities = cap;
++ pins[i].pf = pf;
++ ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
++ if (ret)
++ break;
++ if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ)
++ pins[i].prop.type = DPLL_PIN_TYPE_MUX;
++ else
++ pins[i].prop.type = DPLL_PIN_TYPE_EXT;
++ if (!input)
++ continue;
++ ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i,
++ &de->input_prio[i]);
++ if (ret)
++ break;
++ ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i,
++ &dp->input_prio[i]);
++ if (ret)
++ break;
++ }
++
++ return ret;
++}
++
+ /**
+ * ice_dpll_init_info_direct_pins - initializes direct pins info
+ * @pf: board private structure
+@@ -2101,6 +2169,8 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
+ default:
+ return -EINVAL;
+ }
++ if (num_pins != ice_cgu_get_num_pins(hw, input))
++ return ice_dpll_init_info_pins_generic(pf, input);
+
+ for (i = 0; i < num_pins; i++) {
+ caps = 0;
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+index 3a33e6b9b313d..ec8db830ac73a 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+@@ -34,7 +34,6 @@ static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_inputs[] = {
+ ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common },
+ { "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS,
+ ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz },
+- { "OCXO", ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, 0, },
+ };
+
+ static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = {
+@@ -52,7 +51,6 @@ static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = {
+ ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common },
+ { "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS,
+ ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz },
+- { "OCXO", ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, },
+ };
+
+ static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_outputs[] = {
+@@ -5964,6 +5962,25 @@ ice_cgu_get_pin_desc(struct ice_hw *hw, bool input, int *size)
+ return t;
+ }
+
++/**
++ * ice_cgu_get_num_pins - get pin description array size
++ * @hw: pointer to the hw struct
++ * @input: if request is done against input or output pins
++ *
++ * Return: size of pin description array for given hw.
++ */
++int ice_cgu_get_num_pins(struct ice_hw *hw, bool input)
++{
++ const struct ice_cgu_pin_desc *t;
++ int size;
++
++ t = ice_cgu_get_pin_desc(hw, input, &size);
++ if (t)
++ return size;
++
++ return 0;
++}
++
+ /**
+ * ice_cgu_get_pin_type - get pin's type
+ * @hw: pointer to the hw struct
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+index 0852a34ade918..6cedc1a906afb 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+@@ -404,6 +404,7 @@ int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
+ int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
+ int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data);
+ bool ice_is_pca9575_present(struct ice_hw *hw);
++int ice_cgu_get_num_pins(struct ice_hw *hw, bool input);
+ enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input);
+ struct dpll_pin_frequency *
+ ice_cgu_get_pin_freq_supp(struct ice_hw *hw, u8 pin, bool input, u8 *num);
+--
+2.43.0
+
--- /dev/null
+From 052382490ee4f0f6d783ddce02fe6f2d15e134b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 16:26:24 -0700
+Subject: igb: Disable threaded IRQ for igb_msix_other
+
+From: Wander Lairson Costa <wander@redhat.com>
+
+[ Upstream commit 338c4d3902feb5be49bfda530a72c7ab860e2c9f ]
+
+During testing of SR-IOV, Red Hat QE encountered an issue where the
+ip link up command intermittently fails for the igbvf interfaces when
+using the PREEMPT_RT variant. Investigation revealed that
+e1000_write_posted_mbx returns an error due to the lack of an ACK
+from e1000_poll_for_ack.
+
+The underlying issue arises from the fact that IRQs are threaded by
+default under PREEMPT_RT. While the exact hardware details are not
+available, it appears that the IRQ handled by igb_msix_other must
+be processed before e1000_poll_for_ack times out. However,
+e1000_write_posted_mbx is called with preemption disabled, leading
+to a scenario where the IRQ is serviced only after the failure of
+e1000_write_posted_mbx.
+
+To resolve this, we set IRQF_NO_THREAD for the affected interrupt,
+ensuring that the kernel handles it immediately, thereby preventing
+the aforementioned error.
+
+Reproducer:
+
+ #!/bin/bash
+
+ # echo 2 > /sys/class/net/ens14f0/device/sriov_numvfs
+ ipaddr_vlan=3
+ nic_test=ens14f0
+ vf=${nic_test}v0
+
+ while true; do
+ ip link set ${nic_test} mtu 1500
+ ip link set ${vf} mtu 1500
+ ip link set $vf up
+ ip link set ${nic_test} vf 0 vlan ${ipaddr_vlan}
+ ip addr add 172.30.${ipaddr_vlan}.1/24 dev ${vf}
+ ip addr add 2021:db8:${ipaddr_vlan}::1/64 dev ${vf}
+ if ! ip link show $vf | grep 'state UP'; then
+ echo 'Error found'
+ break
+ fi
+ ip link set $vf down
+ done
+
+Signed-off-by: Wander Lairson Costa <wander@redhat.com>
+Fixes: 9d5c824399de ("igb: PCI-Express 82575 Gigabit Ethernet driver")
+Reported-by: Yuying Ma <yuma@redhat.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igb/igb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index f1d0881687233..b83df5f94b1f5 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -907,7 +907,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
+ int i, err = 0, vector = 0, free_vector = 0;
+
+ err = request_irq(adapter->msix_entries[vector].vector,
+- igb_msix_other, 0, netdev->name, adapter);
++ igb_msix_other, IRQF_NO_THREAD, netdev->name, adapter);
+ if (err)
+ goto err_out;
+
+--
+2.43.0
+
--- /dev/null
+From 935d7f5741e91b39c44f144a3d03bd139e0f1e47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2024 09:38:22 +0300
+Subject: ipv4: ip_tunnel: Fix suspicious RCU usage warning in
+ ip_tunnel_init_flow()
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit ad4a3ca6a8e886f6491910a3ae5d53595e40597d ]
+
+There are code paths from which the function is called without holding
+the RCU read lock, resulting in a suspicious RCU usage warning [1].
+
+Fix by using l3mdev_master_upper_ifindex_by_index() which will acquire
+the RCU read lock before calling
+l3mdev_master_upper_ifindex_by_index_rcu().
+
+[1]
+WARNING: suspicious RCU usage
+6.12.0-rc3-custom-gac8f72681cf2 #141 Not tainted
+-----------------------------
+net/core/dev.c:876 RCU-list traversed in non-reader section!!
+
+other info that might help us debug this:
+
+rcu_scheduler_active = 2, debug_locks = 1
+1 lock held by ip/361:
+ #0: ffffffff86fc7cb0 (rtnl_mutex){+.+.}-{3:3}, at: rtnetlink_rcv_msg+0x377/0xf60
+
+stack backtrace:
+CPU: 3 UID: 0 PID: 361 Comm: ip Not tainted 6.12.0-rc3-custom-gac8f72681cf2 #141
+Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xba/0x110
+ lockdep_rcu_suspicious.cold+0x4f/0xd6
+ dev_get_by_index_rcu+0x1d3/0x210
+ l3mdev_master_upper_ifindex_by_index_rcu+0x2b/0xf0
+ ip_tunnel_bind_dev+0x72f/0xa00
+ ip_tunnel_newlink+0x368/0x7a0
+ ipgre_newlink+0x14c/0x170
+ __rtnl_newlink+0x1173/0x19c0
+ rtnl_newlink+0x6c/0xa0
+ rtnetlink_rcv_msg+0x3cc/0xf60
+ netlink_rcv_skb+0x171/0x450
+ netlink_unicast+0x539/0x7f0
+ netlink_sendmsg+0x8c1/0xd80
+ ____sys_sendmsg+0x8f9/0xc20
+ ___sys_sendmsg+0x197/0x1e0
+ __sys_sendmsg+0x122/0x1f0
+ do_syscall_64+0xbb/0x1d0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: db53cd3d88dc ("net: Handle l3mdev in ip_tunnel_init_flow")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20241022063822.462057-1-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip_tunnels.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
+index 1db2417b8ff52..35d1e09940b27 100644
+--- a/include/net/ip_tunnels.h
++++ b/include/net/ip_tunnels.h
+@@ -354,7 +354,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4,
+ memset(fl4, 0, sizeof(*fl4));
+
+ if (oif) {
+- fl4->flowi4_l3mdev = l3mdev_master_upper_ifindex_by_index_rcu(net, oif);
++ fl4->flowi4_l3mdev = l3mdev_master_upper_ifindex_by_index(net, oif);
+ /* Legacy VRF/l3mdev use case */
+ fl4->flowi4_oif = fl4->flowi4_l3mdev ? 0 : oif;
+ }
+--
+2.43.0
+
--- /dev/null
+From f443ccf96415fe21b45445da8b79b00ab612d765 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 15:30:09 +0300
+Subject: ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_find()
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 90e0569dd3d32f4f4d2ca691d3fa5a8a14a13c12 ]
+
+The per-netns IP tunnel hash table is protected by the RTNL mutex and
+ip_tunnel_find() is only called from the control path where the mutex is
+taken.
+
+Add a lockdep expression to hlist_for_each_entry_rcu() in
+ip_tunnel_find() in order to validate that the mutex is held and to
+silence the suspicious RCU usage warning [1].
+
+[1]
+WARNING: suspicious RCU usage
+6.12.0-rc3-custom-gd95d9a31aceb #139 Not tainted
+-----------------------------
+net/ipv4/ip_tunnel.c:221 RCU-list traversed in non-reader section!!
+
+other info that might help us debug this:
+
+rcu_scheduler_active = 2, debug_locks = 1
+1 lock held by ip/362:
+ #0: ffffffff86fc7cb0 (rtnl_mutex){+.+.}-{3:3}, at: rtnetlink_rcv_msg+0x377/0xf60
+
+stack backtrace:
+CPU: 12 UID: 0 PID: 362 Comm: ip Not tainted 6.12.0-rc3-custom-gd95d9a31aceb #139
+Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xba/0x110
+ lockdep_rcu_suspicious.cold+0x4f/0xd6
+ ip_tunnel_find+0x435/0x4d0
+ ip_tunnel_newlink+0x517/0x7a0
+ ipgre_newlink+0x14c/0x170
+ __rtnl_newlink+0x1173/0x19c0
+ rtnl_newlink+0x6c/0xa0
+ rtnetlink_rcv_msg+0x3cc/0xf60
+ netlink_rcv_skb+0x171/0x450
+ netlink_unicast+0x539/0x7f0
+ netlink_sendmsg+0x8c1/0xd80
+ ____sys_sendmsg+0x8f9/0xc20
+ ___sys_sendmsg+0x197/0x1e0
+ __sys_sendmsg+0x122/0x1f0
+ do_syscall_64+0xbb/0x1d0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.")
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20241023123009.749764-1-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
+index 5cffad42fe8ca..49937878d5e8a 100644
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -217,7 +217,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
+
+ ip_tunnel_flags_copy(flags, parms->i_flags);
+
+- hlist_for_each_entry_rcu(t, head, hash_node) {
++ hlist_for_each_entry_rcu(t, head, hash_node, lockdep_rtnl_is_held()) {
+ if (local == t->parms.iph.saddr &&
+ remote == t->parms.iph.daddr &&
+ link == READ_ONCE(t->parms.link) &&
+--
+2.43.0
+
--- /dev/null
+From e9eccc07a88837fbb1766b99253fd207a39bec2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Sep 2024 14:08:57 +0200
+Subject: mac80211: MAC80211_MESSAGE_TRACING should depend on TRACING
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+[ Upstream commit b3e046c31441d182b954fc2f57b2dc38c71ad4bc ]
+
+When tracing is disabled, there is no point in asking the user about
+enabling tracing of all mac80211 debug messages.
+
+Fixes: 3fae0273168026ed ("mac80211: trace debug messages")
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://patch.msgid.link/85bbe38ce0df13350f45714e2dc288cc70947a19.1727179690.git.geert@linux-m68k.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
+index 13438cc0a6b13..cf0f7780fb109 100644
+--- a/net/mac80211/Kconfig
++++ b/net/mac80211/Kconfig
+@@ -96,7 +96,7 @@ config MAC80211_DEBUGFS
+
+ config MAC80211_MESSAGE_TRACING
+ bool "Trace all mac80211 debug messages"
+- depends on MAC80211
++ depends on MAC80211 && TRACING
+ help
+ Select this option to have mac80211 register the
+ mac80211_msg trace subsystem with tracepoints to
+--
+2.43.0
+
--- /dev/null
+From b6993b2a721f1f406a7e9af0bc13aadfe4bfb134 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 13:03:09 +0300
+Subject: macsec: Fix use-after-free while sending the offloading packet
+
+From: Jianbo Liu <jianbol@nvidia.com>
+
+[ Upstream commit f1e54d11b210b53d418ff1476c6b58a2f434dfc0 ]
+
+KASAN reports the following UAF. The metadata_dst, which is used to
+store the SCI value for macsec offload, is already freed by
+metadata_dst_free() in macsec_free_netdev(), while driver still use it
+for sending the packet.
+
+To fix this issue, dst_release() is used instead to release
+metadata_dst. So it is not freed instantly in macsec_free_netdev() if
+still referenced by skb.
+
+ BUG: KASAN: slab-use-after-free in mlx5e_xmit+0x1e8f/0x4190 [mlx5_core]
+ Read of size 2 at addr ffff88813e42e038 by task kworker/7:2/714
+ [...]
+ Workqueue: mld mld_ifc_work
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x51/0x60
+ print_report+0xc1/0x600
+ kasan_report+0xab/0xe0
+ mlx5e_xmit+0x1e8f/0x4190 [mlx5_core]
+ dev_hard_start_xmit+0x120/0x530
+ sch_direct_xmit+0x149/0x11e0
+ __qdisc_run+0x3ad/0x1730
+ __dev_queue_xmit+0x1196/0x2ed0
+ vlan_dev_hard_start_xmit+0x32e/0x510 [8021q]
+ dev_hard_start_xmit+0x120/0x530
+ __dev_queue_xmit+0x14a7/0x2ed0
+ macsec_start_xmit+0x13e9/0x2340
+ dev_hard_start_xmit+0x120/0x530
+ __dev_queue_xmit+0x14a7/0x2ed0
+ ip6_finish_output2+0x923/0x1a70
+ ip6_finish_output+0x2d7/0x970
+ ip6_output+0x1ce/0x3a0
+ NF_HOOK.constprop.0+0x15f/0x190
+ mld_sendpack+0x59a/0xbd0
+ mld_ifc_work+0x48a/0xa80
+ process_one_work+0x5aa/0xe50
+ worker_thread+0x79c/0x1290
+ kthread+0x28f/0x350
+ ret_from_fork+0x2d/0x70
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+
+ Allocated by task 3922:
+ kasan_save_stack+0x20/0x40
+ kasan_save_track+0x10/0x30
+ __kasan_kmalloc+0x77/0x90
+ __kmalloc_noprof+0x188/0x400
+ metadata_dst_alloc+0x1f/0x4e0
+ macsec_newlink+0x914/0x1410
+ __rtnl_newlink+0xe08/0x15b0
+ rtnl_newlink+0x5f/0x90
+ rtnetlink_rcv_msg+0x667/0xa80
+ netlink_rcv_skb+0x12c/0x360
+ netlink_unicast+0x551/0x770
+ netlink_sendmsg+0x72d/0xbd0
+ __sock_sendmsg+0xc5/0x190
+ ____sys_sendmsg+0x52e/0x6a0
+ ___sys_sendmsg+0xeb/0x170
+ __sys_sendmsg+0xb5/0x140
+ do_syscall_64+0x4c/0x100
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+ Freed by task 4011:
+ kasan_save_stack+0x20/0x40
+ kasan_save_track+0x10/0x30
+ kasan_save_free_info+0x37/0x50
+ poison_slab_object+0x10c/0x190
+ __kasan_slab_free+0x11/0x30
+ kfree+0xe0/0x290
+ macsec_free_netdev+0x3f/0x140
+ netdev_run_todo+0x450/0xc70
+ rtnetlink_rcv_msg+0x66f/0xa80
+ netlink_rcv_skb+0x12c/0x360
+ netlink_unicast+0x551/0x770
+ netlink_sendmsg+0x72d/0xbd0
+ __sock_sendmsg+0xc5/0x190
+ ____sys_sendmsg+0x52e/0x6a0
+ ___sys_sendmsg+0xeb/0x170
+ __sys_sendmsg+0xb5/0x140
+ do_syscall_64+0x4c/0x100
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+Fixes: 0a28bfd4971f ("net/macsec: Add MACsec skb_metadata_dst Tx Data path support")
+Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
+Reviewed-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Chris Mi <cmi@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://patch.msgid.link/20241021100309.234125-1-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macsec.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 2a31d09d43ed4..edee2870f62ab 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -3798,8 +3798,7 @@ static void macsec_free_netdev(struct net_device *dev)
+ {
+ struct macsec_dev *macsec = macsec_priv(dev);
+
+- if (macsec->secy.tx_sc.md_dst)
+- metadata_dst_free(macsec->secy.tx_sc.md_dst);
++ dst_release(&macsec->secy.tx_sc.md_dst->dst);
+ free_percpu(macsec->stats);
+ free_percpu(macsec->secy.tx_sc.stats);
+
+--
+2.43.0
+
--- /dev/null
+From e466bae3481a89391145f48aaab761bfc7114f14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 16:26:26 +0200
+Subject: mlxsw: pci: Sync Rx buffers for CPU
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit 15f73e601a9c67aa83bde92b2d940a6532d8614d ]
+
+When Rx packet is received, drivers should sync the pages for CPU, to
+ensure the CPU reads the data written by the device and not stale
+data from its cache.
+
+Add the missing sync call in Rx path, sync the actual length of data for
+each fragment.
+
+Cc: Jiri Pirko <jiri@resnulli.us>
+Fixes: b5b60bb491b2 ("mlxsw: pci: Use page pool for Rx buffers allocation")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/461486fac91755ca4e04c2068c102250026dcd0b.1729866134.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/pci.c | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
+index 060e5b9392114..2320a5f323b45 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
+@@ -389,15 +389,27 @@ static void mlxsw_pci_wqe_frag_unmap(struct mlxsw_pci *mlxsw_pci, char *wqe,
+ dma_unmap_single(&pdev->dev, mapaddr, frag_len, direction);
+ }
+
+-static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
++static struct sk_buff *mlxsw_pci_rdq_build_skb(struct mlxsw_pci_queue *q,
++ struct page *pages[],
+ u16 byte_count)
+ {
++ struct mlxsw_pci_queue *cq = q->u.rdq.cq;
+ unsigned int linear_data_size;
++ struct page_pool *page_pool;
+ struct sk_buff *skb;
+ int page_index = 0;
+ bool linear_only;
+ void *data;
+
++ linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE;
++ linear_data_size = linear_only ? byte_count :
++ PAGE_SIZE -
++ MLXSW_PCI_RX_BUF_SW_OVERHEAD;
++
++ page_pool = cq->u.cq.page_pool;
++ page_pool_dma_sync_for_cpu(page_pool, pages[page_index],
++ MLXSW_PCI_SKB_HEADROOM, linear_data_size);
++
+ data = page_address(pages[page_index]);
+ net_prefetch(data);
+
+@@ -405,11 +417,6 @@ static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
+ if (unlikely(!skb))
+ return ERR_PTR(-ENOMEM);
+
+- linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE;
+- linear_data_size = linear_only ? byte_count :
+- PAGE_SIZE -
+- MLXSW_PCI_RX_BUF_SW_OVERHEAD;
+-
+ skb_reserve(skb, MLXSW_PCI_SKB_HEADROOM);
+ skb_put(skb, linear_data_size);
+
+@@ -425,6 +432,7 @@ static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
+
+ page = pages[page_index];
+ frag_size = min(byte_count, PAGE_SIZE);
++ page_pool_dma_sync_for_cpu(page_pool, page, 0, frag_size);
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+ page, 0, frag_size, PAGE_SIZE);
+ byte_count -= frag_size;
+@@ -760,7 +768,7 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
+ if (err)
+ goto out;
+
+- skb = mlxsw_pci_rdq_build_skb(pages, byte_count);
++ skb = mlxsw_pci_rdq_build_skb(q, pages, byte_count);
+ if (IS_ERR(skb)) {
+ dev_err_ratelimited(&pdev->dev, "Failed to build skb for RDQ\n");
+ mlxsw_pci_rdq_pages_recycle(q, pages, num_sg_entries);
+--
+2.43.0
+
--- /dev/null
+From a393d10bd08e88b9186261d950dda8dcb1afaea4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 16:26:27 +0200
+Subject: mlxsw: pci: Sync Rx buffers for device
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit d0fbdc3ae9ecc614ddffde55dccbcacef353da0b ]
+
+Non-coherent architectures, like ARM, may require invalidating caches
+before the device can use the DMA mapped memory, which means that before
+posting pages to device, drivers should sync the memory for device.
+
+Sync for device can be configured as page pool responsibility. Set the
+relevant flag and define max_len for sync.
+
+Cc: Jiri Pirko <jiri@resnulli.us>
+Fixes: b5b60bb491b2 ("mlxsw: pci: Use page pool for Rx buffers allocation")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/92e01f05c4f506a4f0a9b39c10175dcc01994910.1729866134.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/pci.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
+index 2320a5f323b45..d6f37456fb317 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
+@@ -996,12 +996,13 @@ static int mlxsw_pci_cq_page_pool_init(struct mlxsw_pci_queue *q,
+ if (cq_type != MLXSW_PCI_CQ_RDQ)
+ return 0;
+
+- pp_params.flags = PP_FLAG_DMA_MAP;
++ pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
+ pp_params.pool_size = MLXSW_PCI_WQE_COUNT * mlxsw_pci->num_sg_entries;
+ pp_params.nid = dev_to_node(&mlxsw_pci->pdev->dev);
+ pp_params.dev = &mlxsw_pci->pdev->dev;
+ pp_params.napi = &q->u.cq.napi;
+ pp_params.dma_dir = DMA_FROM_DEVICE;
++ pp_params.max_len = PAGE_SIZE;
+
+ page_pool = page_pool_create(&pp_params);
+ if (IS_ERR(page_pool))
+--
+2.43.0
+
--- /dev/null
+From 4caea33c382c5a75f33cdf744c47ebcc3571f2db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 16:26:28 +0200
+Subject: mlxsw: spectrum_ipip: Fix memory leak when changing remote IPv6
+ address
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 12ae97c531fcd3bfd774d4dfeaeac23eafe24280 ]
+
+The device stores IPv6 addresses that are used for encapsulation in
+linear memory that is managed by the driver.
+
+Changing the remote address of an ip6gre net device never worked
+properly, but since cited commit the following reproducer [1] would
+result in a warning [2] and a memory leak [3]. The problem is that the
+new remote address is never added by the driver to its hash table (and
+therefore the device) and the old address is never removed from it.
+
+Fix by programming the new address when the configuration of the ip6gre
+net device changes and removing the old one. If the address did not
+change, then the above would result in increasing the reference count of
+the address and then decreasing it.
+
+[1]
+ # ip link add name bla up type ip6gre local 2001:db8:1::1 remote 2001:db8:2::1 tos inherit ttl inherit
+ # ip link set dev bla type ip6gre remote 2001:db8:3::1
+ # ip link del dev bla
+ # devlink dev reload pci/0000:01:00.0
+
+[2]
+WARNING: CPU: 0 PID: 1682 at drivers/net/ethernet/mellanox/mlxsw/spectrum.c:3002 mlxsw_sp_ipv6_addr_put+0x140/0x1d0
+Modules linked in:
+CPU: 0 UID: 0 PID: 1682 Comm: ip Not tainted 6.12.0-rc3-custom-g86b5b55bc835 #151
+Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023
+RIP: 0010:mlxsw_sp_ipv6_addr_put+0x140/0x1d0
+[...]
+Call Trace:
+ <TASK>
+ mlxsw_sp_router_netdevice_event+0x55f/0x1240
+ notifier_call_chain+0x5a/0xd0
+ call_netdevice_notifiers_info+0x39/0x90
+ unregister_netdevice_many_notify+0x63e/0x9d0
+ rtnl_dellink+0x16b/0x3a0
+ rtnetlink_rcv_msg+0x142/0x3f0
+ netlink_rcv_skb+0x50/0x100
+ netlink_unicast+0x242/0x390
+ netlink_sendmsg+0x1de/0x420
+ ____sys_sendmsg+0x2bd/0x320
+ ___sys_sendmsg+0x9a/0xe0
+ __sys_sendmsg+0x7a/0xd0
+ do_syscall_64+0x9e/0x1a0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+[3]
+unreferenced object 0xffff898081f597a0 (size 32):
+ comm "ip", pid 1626, jiffies 4294719324
+ hex dump (first 32 bytes):
+ 20 01 0d b8 00 02 00 00 00 00 00 00 00 00 00 01 ...............
+ 21 49 61 83 80 89 ff ff 00 00 00 00 01 00 00 00 !Ia.............
+ backtrace (crc fd9be911):
+ [<00000000df89c55d>] __kmalloc_cache_noprof+0x1da/0x260
+ [<00000000ff2a1ddb>] mlxsw_sp_ipv6_addr_kvdl_index_get+0x281/0x340
+ [<000000009ddd445d>] mlxsw_sp_router_netdevice_event+0x47b/0x1240
+ [<00000000743e7757>] notifier_call_chain+0x5a/0xd0
+ [<000000007c7b9e13>] call_netdevice_notifiers_info+0x39/0x90
+ [<000000002509645d>] register_netdevice+0x5f7/0x7a0
+ [<00000000c2e7d2a9>] ip6gre_newlink_common.isra.0+0x65/0x130
+ [<0000000087cd6d8d>] ip6gre_newlink+0x72/0x120
+ [<000000004df7c7cc>] rtnl_newlink+0x471/0xa20
+ [<0000000057ed632a>] rtnetlink_rcv_msg+0x142/0x3f0
+ [<0000000032e0d5b5>] netlink_rcv_skb+0x50/0x100
+ [<00000000908bca63>] netlink_unicast+0x242/0x390
+ [<00000000cdbe1c87>] netlink_sendmsg+0x1de/0x420
+ [<0000000011db153e>] ____sys_sendmsg+0x2bd/0x320
+ [<000000003b6d53eb>] ___sys_sendmsg+0x9a/0xe0
+ [<00000000cae27c62>] __sys_sendmsg+0x7a/0xd0
+
+Fixes: cf42911523e0 ("mlxsw: spectrum_ipip: Use common hash table for IPv6 address mapping")
+Reported-by: Maksym Yaremchuk <maksymy@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/e91012edc5a6cb9df37b78fd377f669381facfcb.1729866134.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_ipip.c | 26 +++++++++++++++++--
+ 1 file changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
+index d761a1235994c..7ea798a4949e2 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
+@@ -481,11 +481,33 @@ mlxsw_sp_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_ipip_entry *ipip_entry,
+ struct netlink_ext_ack *extack)
+ {
++ u32 new_kvdl_index, old_kvdl_index = ipip_entry->dip_kvdl_index;
++ struct in6_addr old_addr6 = ipip_entry->parms.daddr.addr6;
+ struct mlxsw_sp_ipip_parms new_parms;
++ int err;
+
+ new_parms = mlxsw_sp_ipip_netdev_parms_init_gre6(ipip_entry->ol_dev);
+- return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
+- &new_parms, extack);
++
++ err = mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp,
++ &new_parms.daddr.addr6,
++ &new_kvdl_index);
++ if (err)
++ return err;
++ ipip_entry->dip_kvdl_index = new_kvdl_index;
++
++ err = mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
++ &new_parms, extack);
++ if (err)
++ goto err_change_gre;
++
++ mlxsw_sp_ipv6_addr_put(mlxsw_sp, &old_addr6);
++
++ return 0;
++
++err_change_gre:
++ ipip_entry->dip_kvdl_index = old_kvdl_index;
++ mlxsw_sp_ipv6_addr_put(mlxsw_sp, &new_parms.daddr.addr6);
++ return err;
+ }
+
+ static int
+--
+2.43.0
+
--- /dev/null
+From 3e3fb6985de856dc13d8b274b0e852c287f143ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 16:26:25 +0200
+Subject: mlxsw: spectrum_ptp: Add missing verification before pushing Tx
+ header
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit 0a66e5582b5102c4d7b866b977ff7c850c1174ce ]
+
+Tx header should be pushed for each packet which is transmitted via
+Spectrum ASICs. The cited commit moved the call to skb_cow_head() from
+mlxsw_sp_port_xmit() to functions which handle Tx header.
+
+In case that mlxsw_sp->ptp_ops->txhdr_construct() is used to handle Tx
+header, and txhdr_construct() is mlxsw_sp_ptp_txhdr_construct(), there is
+no call for skb_cow_head() before pushing Tx header size to SKB. This flow
+is relevant for Spectrum-1 and Spectrum-4, for PTP packets.
+
+Add the missing call to skb_cow_head() to make sure that there is both
+enough room to push the Tx header and that the SKB header is not cloned and
+can be modified.
+
+An additional set will be sent to net-next to centralize the handling of
+the Tx header by pushing it to every packet just before transmission.
+
+Cc: Richard Cochran <richardcochran@gmail.com>
+Fixes: 24157bc69f45 ("mlxsw: Send PTP packets as data packets to overcome a limitation")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/5145780b07ebbb5d3b3570f311254a3a2d554a44.1729866134.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+index 5b174cb95eb8a..d94081c7658e3 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+@@ -16,6 +16,7 @@
+ #include "spectrum.h"
+ #include "spectrum_ptp.h"
+ #include "core.h"
++#include "txheader.h"
+
+ #define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT 29
+ #define MLXSW_SP1_PTP_CLOCK_FREQ_KHZ 156257 /* 6.4nSec */
+@@ -1684,6 +1685,12 @@ int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
+ struct sk_buff *skb,
+ const struct mlxsw_tx_info *tx_info)
+ {
++ if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) {
++ this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
++ dev_kfree_skb_any(skb);
++ return -ENOMEM;
++ }
++
+ mlxsw_sp_txhdr_construct(skb, tx_info);
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From 93b59c9eb95af25800ee230e1057b20a4ea64c32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Oct 2024 14:52:25 +0100
+Subject: net: ethernet: mtk_wed: fix path of MT7988 WO firmware
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit 637f41476384c76d3cd7dcf5947caf2c8b8d7a9b ]
+
+linux-firmware commit 808cba84 ("mtk_wed: add firmware for mt7988
+Wireless Ethernet Dispatcher") added mt7988_wo_{0,1}.bin in the
+'mediatek/mt7988' directory while driver current expects the files in
+the 'mediatek' directory.
+
+Change path in the driver header now that the firmware has been added.
+
+Fixes: e2f64db13aa1 ("net: ethernet: mtk_wed: introduce WED support for MT7988")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/Zxz0GWTR5X5LdWPe@pidgin.makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_wed_wo.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+index 87a67fa3868d3..c01b1e8428f6d 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+@@ -91,8 +91,8 @@ enum mtk_wed_dummy_cr_idx {
+ #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
+ #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
+ #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
+-#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin"
+-#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin"
++#define MT7988_FIRMWARE_WO0 "mediatek/mt7988/mt7988_wo_0.bin"
++#define MT7988_FIRMWARE_WO1 "mediatek/mt7988/mt7988_wo_1.bin"
+
+ #define MTK_WO_MCU_CFG_LS_BASE 0
+ #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
+--
+2.43.0
+
--- /dev/null
+From 4fa08709946e0256aa1579fa38af4762f88ea026 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 11:52:13 +0800
+Subject: net: fix crash when config small gso_max_size/gso_ipv4_max_size
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 9ab5cf19fb0e4680f95e506d6c544259bf1111c4 ]
+
+Config a small gso_max_size/gso_ipv4_max_size will lead to an underflow
+in sk_dst_gso_max_size(), which may trigger a BUG_ON crash,
+because sk->sk_gso_max_size would be much bigger than device limits.
+Call Trace:
+tcp_write_xmit
+ tso_segs = tcp_init_tso_segs(skb, mss_now);
+ tcp_set_skb_tso_segs
+ tcp_skb_pcount_set
+ // skb->len = 524288, mss_now = 8
+ // u16 tso_segs = 524288/8 = 65535 -> 0
+ tso_segs = DIV_ROUND_UP(skb->len, mss_now)
+ BUG_ON(!tso_segs)
+Add check for the minimum value of gso_max_size and gso_ipv4_max_size.
+
+Fixes: 46e6b992c250 ("rtnetlink: allow GSO maximums to be set on device creation")
+Fixes: 9eefedd58ae1 ("net: add gso_ipv4_max_size and gro_ipv4_max_size per device")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20241023035213.517386-1-wangliang74@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnetlink.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index 97a38a7e1b2cc..3c5dead0c71ce 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -2032,7 +2032,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
+ [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
+ [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
+ [IFLA_GSO_MAX_SEGS] = { .type = NLA_U32 },
+- [IFLA_GSO_MAX_SIZE] = { .type = NLA_U32 },
++ [IFLA_GSO_MAX_SIZE] = NLA_POLICY_MIN(NLA_U32, MAX_TCP_HEADER + 1),
+ [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
+ [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
+ [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
+@@ -2057,7 +2057,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
+ [IFLA_TSO_MAX_SIZE] = { .type = NLA_REJECT },
+ [IFLA_TSO_MAX_SEGS] = { .type = NLA_REJECT },
+ [IFLA_ALLMULTI] = { .type = NLA_REJECT },
+- [IFLA_GSO_IPV4_MAX_SIZE] = { .type = NLA_U32 },
++ [IFLA_GSO_IPV4_MAX_SIZE] = NLA_POLICY_MIN(NLA_U32, MAX_TCP_HEADER + 1),
+ [IFLA_GRO_IPV4_MAX_SIZE] = { .type = NLA_U32 },
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 0ea8c71561bc40a678c7bf15e081737e1f2d15e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:31 +0800
+Subject: net: hns3: add sync command to sync io-pgtable
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit f2c14899caba76da93ff3fff46b4d5a8f43ce07e ]
+
+To avoid errors in pgtable prefectch, add a sync command to sync
+io-pagtable.
+
+This is a supplement for the previous patch.
+We want all the tx packet can be handled with tx bounce buffer path.
+But it depends on the remain space of the spare buffer, checked by the
+hns3_can_use_tx_bounce(). In most cases, maybe 99.99%, it returns true.
+But once it return false by no available space, the packet will be handled
+with the former path, which will map/unmap the skb buffer.
+Then the driver will face the smmu prefetch risk again.
+
+So add a sync command in this case to avoid smmu prefectch,
+just protects corner scenes.
+
+Fixes: 295ba232a8c3 ("net: hns3: add device version to replace pci revision")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Peiyang Wang <wangpeiyang1@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns3/hns3_enet.c | 27 +++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index ac88e301f2211..8760b4e9ade6b 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -381,6 +381,24 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
+ #define HNS3_INVALID_PTYPE \
+ ARRAY_SIZE(hns3_rx_ptype_tbl)
+
++static void hns3_dma_map_sync(struct device *dev, unsigned long iova)
++{
++ struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
++ struct iommu_iotlb_gather iotlb_gather;
++ size_t granule;
++
++ if (!domain || !iommu_is_dma_domain(domain))
++ return;
++
++ granule = 1 << __ffs(domain->pgsize_bitmap);
++ iova = ALIGN_DOWN(iova, granule);
++ iotlb_gather.start = iova;
++ iotlb_gather.end = iova + granule - 1;
++ iotlb_gather.pgsize = granule;
++
++ iommu_iotlb_sync(domain, &iotlb_gather);
++}
++
+ static irqreturn_t hns3_irq_handle(int irq, void *vector)
+ {
+ struct hns3_enet_tqp_vector *tqp_vector = vector;
+@@ -1728,7 +1746,9 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv,
+ unsigned int type)
+ {
+ struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
++ struct hnae3_handle *handle = ring->tqp->handle;
+ struct device *dev = ring_to_dev(ring);
++ struct hnae3_ae_dev *ae_dev;
+ unsigned int size;
+ dma_addr_t dma;
+
+@@ -1760,6 +1780,13 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv,
+ return -ENOMEM;
+ }
+
++ /* Add a SYNC command to sync io-pgtale to avoid errors in pgtable
++ * prefetch
++ */
++ ae_dev = hns3_get_ae_dev(handle);
++ if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
++ hns3_dma_map_sync(dev, dma);
++
+ desc_cb->priv = priv;
+ desc_cb->length = size;
+ desc_cb->dma = dma;
+--
+2.43.0
+
--- /dev/null
+From 3e9145dcb39ec7512a2d988438ecf38209f69103 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:30 +0800
+Subject: net: hns3: default enable tx bounce buffer when smmu enabled
+
+From: Peiyang Wang <wangpeiyang1@huawei.com>
+
+[ Upstream commit e6ab19443b36a45ebfb392775cb17d6a78dd07ea ]
+
+The SMMU engine on HIP09 chip has a hardware issue.
+SMMU pagetable prefetch features may prefetch and use a invalid PTE
+even the PTE is valid at that time. This will cause the device trigger
+fake pagefaults. The solution is to avoid prefetching by adding a
+SYNC command when smmu mapping a iova. But the performance of nic has a
+sharp drop. Then we do this workaround, always enable tx bounce buffer,
+avoid mapping/unmapping on TX path.
+
+This issue only affects HNS3, so we always enable
+tx bounce buffer when smmu enabled to improve performance.
+
+Fixes: 295ba232a8c3 ("net: hns3: add device version to replace pci revision")
+Signed-off-by: Peiyang Wang <wangpeiyang1@huawei.com>
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns3/hns3_enet.c | 31 +++++++++++++++++
+ .../net/ethernet/hisilicon/hns3/hns3_enet.h | 2 ++
+ .../ethernet/hisilicon/hns3/hns3_ethtool.c | 33 +++++++++++++++++++
+ 3 files changed, 66 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 4cbc4d069a1f3..ac88e301f2211 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -11,6 +11,7 @@
+ #include <linux/irq.h>
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
++#include <linux/iommu.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/skbuff.h>
+@@ -1032,6 +1033,8 @@ static bool hns3_can_use_tx_sgl(struct hns3_enet_ring *ring,
+ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring)
+ {
+ u32 alloc_size = ring->tqp->handle->kinfo.tx_spare_buf_size;
++ struct net_device *netdev = ring_to_netdev(ring);
++ struct hns3_nic_priv *priv = netdev_priv(netdev);
+ struct hns3_tx_spare *tx_spare;
+ struct page *page;
+ dma_addr_t dma;
+@@ -1073,6 +1076,7 @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring)
+ tx_spare->buf = page_address(page);
+ tx_spare->len = PAGE_SIZE << order;
+ ring->tx_spare = tx_spare;
++ ring->tx_copybreak = priv->tx_copybreak;
+ return;
+
+ dma_mapping_error:
+@@ -4868,6 +4872,30 @@ static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv)
+ devm_kfree(&pdev->dev, priv->tqp_vector);
+ }
+
++static void hns3_update_tx_spare_buf_config(struct hns3_nic_priv *priv)
++{
++#define HNS3_MIN_SPARE_BUF_SIZE (2 * 1024 * 1024)
++#define HNS3_MAX_PACKET_SIZE (64 * 1024)
++
++ struct iommu_domain *domain = iommu_get_domain_for_dev(priv->dev);
++ struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(priv->ae_handle);
++ struct hnae3_handle *handle = priv->ae_handle;
++
++ if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3)
++ return;
++
++ if (!(domain && iommu_is_dma_domain(domain)))
++ return;
++
++ priv->min_tx_copybreak = HNS3_MAX_PACKET_SIZE;
++ priv->min_tx_spare_buf_size = HNS3_MIN_SPARE_BUF_SIZE;
++
++ if (priv->tx_copybreak < priv->min_tx_copybreak)
++ priv->tx_copybreak = priv->min_tx_copybreak;
++ if (handle->kinfo.tx_spare_buf_size < priv->min_tx_spare_buf_size)
++ handle->kinfo.tx_spare_buf_size = priv->min_tx_spare_buf_size;
++}
++
+ static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv,
+ unsigned int ring_type)
+ {
+@@ -5101,6 +5129,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv)
+ int i, j;
+ int ret;
+
++ hns3_update_tx_spare_buf_config(priv);
+ for (i = 0; i < ring_num; i++) {
+ ret = hns3_alloc_ring_memory(&priv->ring[i]);
+ if (ret) {
+@@ -5305,6 +5334,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
+ priv->ae_handle = handle;
+ priv->tx_timeout_count = 0;
+ priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num;
++ priv->min_tx_copybreak = 0;
++ priv->min_tx_spare_buf_size = 0;
+ set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
+
+ handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL);
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+index d36c4ed16d8dd..caf7a4df85852 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+@@ -596,6 +596,8 @@ struct hns3_nic_priv {
+ struct hns3_enet_coalesce rx_coal;
+ u32 tx_copybreak;
+ u32 rx_copybreak;
++ u32 min_tx_copybreak;
++ u32 min_tx_spare_buf_size;
+ };
+
+ union l3_hdr_info {
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+index b1e9883473476..97eaeec1952bb 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+@@ -1933,6 +1933,31 @@ static int hns3_set_tx_spare_buf_size(struct net_device *netdev,
+ return ret;
+ }
+
++static int hns3_check_tx_copybreak(struct net_device *netdev, u32 copybreak)
++{
++ struct hns3_nic_priv *priv = netdev_priv(netdev);
++
++ if (copybreak < priv->min_tx_copybreak) {
++ netdev_err(netdev, "tx copybreak %u should be no less than %u!\n",
++ copybreak, priv->min_tx_copybreak);
++ return -EINVAL;
++ }
++ return 0;
++}
++
++static int hns3_check_tx_spare_buf_size(struct net_device *netdev, u32 buf_size)
++{
++ struct hns3_nic_priv *priv = netdev_priv(netdev);
++
++ if (buf_size < priv->min_tx_spare_buf_size) {
++ netdev_err(netdev,
++ "tx spare buf size %u should be no less than %u!\n",
++ buf_size, priv->min_tx_spare_buf_size);
++ return -EINVAL;
++ }
++ return 0;
++}
++
+ static int hns3_set_tunable(struct net_device *netdev,
+ const struct ethtool_tunable *tuna,
+ const void *data)
+@@ -1949,6 +1974,10 @@ static int hns3_set_tunable(struct net_device *netdev,
+
+ switch (tuna->id) {
+ case ETHTOOL_TX_COPYBREAK:
++ ret = hns3_check_tx_copybreak(netdev, *(u32 *)data);
++ if (ret)
++ return ret;
++
+ priv->tx_copybreak = *(u32 *)data;
+
+ for (i = 0; i < h->kinfo.num_tqps; i++)
+@@ -1963,6 +1992,10 @@ static int hns3_set_tunable(struct net_device *netdev,
+
+ break;
+ case ETHTOOL_TX_COPYBREAK_BUF_SIZE:
++ ret = hns3_check_tx_spare_buf_size(netdev, *(u32 *)data);
++ if (ret)
++ return ret;
++
+ old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size;
+ new_tx_spare_buf_size = *(u32 *)data;
+ netdev_info(netdev, "request to set tx spare buf size from %u to %u\n",
+--
+2.43.0
+
--- /dev/null
+From e3c9ddb035062a6ea334b5a0b660b1e074f51a7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:35 +0800
+Subject: net: hns3: don't auto enable misc vector
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 5f62009ff10826fefa215da68831f42b0c36b6fb ]
+
+Currently, there is a time window between misc irq enabled
+and service task inited. If an interrupte is reported at
+this time, it will cause warning like below:
+
+[ 16.324639] Call trace:
+[ 16.324641] __queue_delayed_work+0xb8/0xe0
+[ 16.324643] mod_delayed_work_on+0x78/0xd0
+[ 16.324655] hclge_errhand_task_schedule+0x58/0x90 [hclge]
+[ 16.324662] hclge_misc_irq_handle+0x168/0x240 [hclge]
+[ 16.324666] __handle_irq_event_percpu+0x64/0x1e0
+[ 16.324667] handle_irq_event+0x80/0x170
+[ 16.324670] handle_fasteoi_edge_irq+0x110/0x2bc
+[ 16.324671] __handle_domain_irq+0x84/0xfc
+[ 16.324673] gic_handle_irq+0x88/0x2c0
+[ 16.324674] el1_irq+0xb8/0x140
+[ 16.324677] arch_cpu_idle+0x18/0x40
+[ 16.324679] default_idle_call+0x5c/0x1bc
+[ 16.324682] cpuidle_idle_call+0x18c/0x1c4
+[ 16.324684] do_idle+0x174/0x17c
+[ 16.324685] cpu_startup_entry+0x30/0x6c
+[ 16.324687] secondary_start_kernel+0x1a4/0x280
+[ 16.324688] ---[ end trace 6aa0bff672a964aa ]---
+
+So don't auto enable misc vector when request irq..
+
+Fixes: 7be1b9f3e99f ("net: hns3: make hclge_service use delayed workqueue")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 116098033dfba..83a6cb9ceb020 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -6,6 +6,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/netdevice.h>
+@@ -3779,7 +3780,7 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev)
+ snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s",
+ HCLGE_NAME, pci_name(hdev->pdev));
+ ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle,
+- 0, hdev->misc_vector.name, hdev);
++ IRQ_NOAUTOEN, hdev->misc_vector.name, hdev);
+ if (ret) {
+ hclge_free_vector(hdev, 0);
+ dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n",
+@@ -11917,9 +11918,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
+
+ hclge_init_rxd_adv_layout(hdev);
+
+- /* Enable MISC vector(vector0) */
+- hclge_enable_vector(&hdev->misc_vector, true);
+-
+ ret = hclge_init_wol(hdev);
+ if (ret)
+ dev_warn(&pdev->dev,
+@@ -11932,6 +11930,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
+ hclge_state_init(hdev);
+ hdev->last_reset_time = jiffies;
+
++ /* Enable MISC vector(vector0) */
++ enable_irq(hdev->misc_vector.vector_irq);
++ hclge_enable_vector(&hdev->misc_vector, true);
++
+ dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n",
+ HCLGE_DRIVER_NAME);
+
+@@ -12337,7 +12339,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
+
+ /* Disable MISC vector(vector0) */
+ hclge_enable_vector(&hdev->misc_vector, false);
+- synchronize_irq(hdev->misc_vector.vector_irq);
++ disable_irq(hdev->misc_vector.vector_irq);
+
+ /* Disable all hw interrupts */
+ hclge_config_mac_tnl_int(hdev, false);
+--
+2.43.0
+
--- /dev/null
+From dd11a46806e62bed207553d45865bd3777ce3970 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:38 +0800
+Subject: net: hns3: fix kernel crash when 1588 is sent on HIP08 devices
+
+From: Jie Wang <wangjie125@huawei.com>
+
+[ Upstream commit 2cf246143519ecc11dab754385ec42d78b6b6a05 ]
+
+Currently, HIP08 devices does not register the ptp devices, so the
+hdev->ptp is NULL. But the tx process would still try to set hardware time
+stamp info with SKBTX_HW_TSTAMP flag and cause a kernel crash.
+
+[ 128.087798] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018
+...
+[ 128.280251] pc : hclge_ptp_set_tx_info+0x2c/0x140 [hclge]
+[ 128.286600] lr : hclge_ptp_set_tx_info+0x20/0x140 [hclge]
+[ 128.292938] sp : ffff800059b93140
+[ 128.297200] x29: ffff800059b93140 x28: 0000000000003280
+[ 128.303455] x27: ffff800020d48280 x26: ffff0cb9dc814080
+[ 128.309715] x25: ffff0cb9cde93fa0 x24: 0000000000000001
+[ 128.315969] x23: 0000000000000000 x22: 0000000000000194
+[ 128.322219] x21: ffff0cd94f986000 x20: 0000000000000000
+[ 128.328462] x19: ffff0cb9d2a166c0 x18: 0000000000000000
+[ 128.334698] x17: 0000000000000000 x16: ffffcf1fc523ed24
+[ 128.340934] x15: 0000ffffd530a518 x14: 0000000000000000
+[ 128.347162] x13: ffff0cd6bdb31310 x12: 0000000000000368
+[ 128.353388] x11: ffff0cb9cfbc7070 x10: ffff2cf55dd11e02
+[ 128.359606] x9 : ffffcf1f85a212b4 x8 : ffff0cd7cf27dab0
+[ 128.365831] x7 : 0000000000000a20 x6 : ffff0cd7cf27d000
+[ 128.372040] x5 : 0000000000000000 x4 : 000000000000ffff
+[ 128.378243] x3 : 0000000000000400 x2 : ffffcf1f85a21294
+[ 128.384437] x1 : ffff0cb9db520080 x0 : ffff0cb9db500080
+[ 128.390626] Call trace:
+[ 128.393964] hclge_ptp_set_tx_info+0x2c/0x140 [hclge]
+[ 128.399893] hns3_nic_net_xmit+0x39c/0x4c4 [hns3]
+[ 128.405468] xmit_one.constprop.0+0xc4/0x200
+[ 128.410600] dev_hard_start_xmit+0x54/0xf0
+[ 128.415556] sch_direct_xmit+0xe8/0x634
+[ 128.420246] __dev_queue_xmit+0x224/0xc70
+[ 128.425101] dev_queue_xmit+0x1c/0x40
+[ 128.429608] ovs_vport_send+0xac/0x1a0 [openvswitch]
+[ 128.435409] do_output+0x60/0x17c [openvswitch]
+[ 128.440770] do_execute_actions+0x898/0x8c4 [openvswitch]
+[ 128.446993] ovs_execute_actions+0x64/0xf0 [openvswitch]
+[ 128.453129] ovs_dp_process_packet+0xa0/0x224 [openvswitch]
+[ 128.459530] ovs_vport_receive+0x7c/0xfc [openvswitch]
+[ 128.465497] internal_dev_xmit+0x34/0xb0 [openvswitch]
+[ 128.471460] xmit_one.constprop.0+0xc4/0x200
+[ 128.476561] dev_hard_start_xmit+0x54/0xf0
+[ 128.481489] __dev_queue_xmit+0x968/0xc70
+[ 128.486330] dev_queue_xmit+0x1c/0x40
+[ 128.490856] ip_finish_output2+0x250/0x570
+[ 128.495810] __ip_finish_output+0x170/0x1e0
+[ 128.500832] ip_finish_output+0x3c/0xf0
+[ 128.505504] ip_output+0xbc/0x160
+[ 128.509654] ip_send_skb+0x58/0xd4
+[ 128.513892] udp_send_skb+0x12c/0x354
+[ 128.518387] udp_sendmsg+0x7a8/0x9c0
+[ 128.522793] inet_sendmsg+0x4c/0x8c
+[ 128.527116] __sock_sendmsg+0x48/0x80
+[ 128.531609] __sys_sendto+0x124/0x164
+[ 128.536099] __arm64_sys_sendto+0x30/0x5c
+[ 128.540935] invoke_syscall+0x50/0x130
+[ 128.545508] el0_svc_common.constprop.0+0x10c/0x124
+[ 128.551205] do_el0_svc+0x34/0xdc
+[ 128.555347] el0_svc+0x20/0x30
+[ 128.559227] el0_sync_handler+0xb8/0xc0
+[ 128.563883] el0_sync+0x160/0x180
+
+Fixes: 0bf5eb788512 ("net: hns3: add support for PTP")
+Signed-off-by: Jie Wang <wangjie125@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
+index 5fff8ed388f8b..787126358ceaf 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
+@@ -58,6 +58,9 @@ bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb)
+ struct hclge_dev *hdev = vport->back;
+ struct hclge_ptp *ptp = hdev->ptp;
+
++ if (!ptp)
++ return false;
++
+ if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) ||
+ test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) {
+ ptp->tx_skipped++;
+--
+2.43.0
+
--- /dev/null
+From 13a78ddb18ae91d5a4ed9b425510d9427574ddf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:33 +0800
+Subject: net: hns3: fix missing features due to dev->features configuration
+ too early
+
+From: Hao Lan <lanhao@huawei.com>
+
+[ Upstream commit 662ecfc46690e92cf630f51b5d4bbbcffe102980 ]
+
+Currently, the netdev->features is configured in hns3_nic_set_features.
+As a result, __netdev_update_features considers that there is no feature
+difference, and the procedures of the real features are missing.
+
+Fixes: 2a7556bb2b73 ("net: hns3: implement ndo_features_check ops for hns3 driver")
+Signed-off-by: Hao Lan <lanhao@huawei.com>
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 8760b4e9ade6b..b09f0cca34dc6 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -2483,7 +2483,6 @@ static int hns3_nic_set_features(struct net_device *netdev,
+ return ret;
+ }
+
+- netdev->features = features;
+ return 0;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From d3488bb5a2e123a6c1fff8992ee4fe95bd397598 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:37 +0800
+Subject: net: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds
+ issue
+
+From: Hao Lan <lanhao@huawei.com>
+
+[ Upstream commit 3e22b7de34cbdb991a2c9c5413eeb8a6fb7da2a5 ]
+
+The TQP BAR space is divided into two segments. TQPs 0-1023 and TQPs
+1024-1279 are in different BAR space addresses. However,
+hclge_fetch_pf_reg does not distinguish the tqp space information when
+reading the tqp space information. When the number of TQPs is greater
+than 1024, access bar space overwriting occurs.
+The problem of different segments has been considered during the
+initialization of tqp.io_base. Therefore, tqp.io_base is directly used
+when the queue is read in hclge_fetch_pf_reg.
+
+The error message:
+
+Unable to handle kernel paging request at virtual address ffff800037200000
+pc : hclge_fetch_pf_reg+0x138/0x250 [hclge]
+lr : hclge_get_regs+0x84/0x1d0 [hclge]
+Call trace:
+ hclge_fetch_pf_reg+0x138/0x250 [hclge]
+ hclge_get_regs+0x84/0x1d0 [hclge]
+ hns3_get_regs+0x2c/0x50 [hns3]
+ ethtool_get_regs+0xf4/0x270
+ dev_ethtool+0x674/0x8a0
+ dev_ioctl+0x270/0x36c
+ sock_do_ioctl+0x110/0x2a0
+ sock_ioctl+0x2ac/0x530
+ __arm64_sys_ioctl+0xa8/0x100
+ invoke_syscall+0x4c/0x124
+ el0_svc_common.constprop.0+0x140/0x15c
+ do_el0_svc+0x30/0xd0
+ el0_svc+0x1c/0x2c
+ el0_sync_handler+0xb0/0xb4
+ el0_sync+0x168/0x180
+
+Fixes: 939ccd107ffc ("net: hns3: move dump regs function to a separate file")
+Signed-off-by: Hao Lan <lanhao@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | 9 +++++----
+ .../net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 9 +++++----
+ 2 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+index 43c1c18fa81f8..8c057192aae6e 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+@@ -510,9 +510,9 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
+ struct hnae3_knic_private_info *kinfo)
+ {
+-#define HCLGE_RING_REG_OFFSET 0x200
+ #define HCLGE_RING_INT_REG_OFFSET 0x4
+
++ struct hnae3_queue *tqp;
+ int i, j, reg_num;
+ int data_num_sum;
+ u32 *reg = data;
+@@ -533,10 +533,11 @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
+ reg_num = ARRAY_SIZE(ring_reg_addr_list);
+ for (j = 0; j < kinfo->num_tqps; j++) {
+ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg);
++ tqp = kinfo->tqp[j];
+ for (i = 0; i < reg_num; i++)
+- *reg++ = hclge_read_dev(&hdev->hw,
+- ring_reg_addr_list[i] +
+- HCLGE_RING_REG_OFFSET * j);
++ *reg++ = readl_relaxed(tqp->io_base -
++ HCLGE_TQP_REG_OFFSET +
++ ring_reg_addr_list[i]);
+ }
+ data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps;
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
+index 65b9dcd381375..6ecf936c79b21 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
+@@ -123,10 +123,10 @@ int hclgevf_get_regs_len(struct hnae3_handle *handle)
+ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
+ void *data)
+ {
+-#define HCLGEVF_RING_REG_OFFSET 0x200
+ #define HCLGEVF_RING_INT_REG_OFFSET 0x4
+
+ struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
++ struct hnae3_queue *tqp;
+ int i, j, reg_um;
+ u32 *reg = data;
+
+@@ -147,10 +147,11 @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
+ reg_um = sizeof(ring_reg_addr_list) / sizeof(u32);
+ for (j = 0; j < hdev->num_tqps; j++) {
+ reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg);
++ tqp = &hdev->htqp[j].q;
+ for (i = 0; i < reg_um; i++)
+- *reg++ = hclgevf_read_dev(&hdev->hw,
+- ring_reg_addr_list[i] +
+- HCLGEVF_RING_REG_OFFSET * j);
++ *reg++ = readl_relaxed(tqp->io_base -
++ HCLGEVF_TQP_REG_OFFSET +
++ ring_reg_addr_list[i]);
+ }
+
+ reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32);
+--
+2.43.0
+
--- /dev/null
+From 9a3f53a287607c2d33c55cff28033af08335a814 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:32 +0800
+Subject: net: hns3: fixed reset failure issues caused by the incorrect reset
+ type
+
+From: Hao Lan <lanhao@huawei.com>
+
+[ Upstream commit 3e0f7cc887b77603182dceca4d3a6e84f6a40d0a ]
+
+When a reset type that is not supported by the driver is input, a reset
+pending flag bit of the HNAE3_NONE_RESET type is generated in
+reset_pending. The driver does not have a mechanism to clear this type
+of error. As a result, the driver considers that the reset is not
+complete. This patch provides a mechanism to clear the
+HNAE3_NONE_RESET flag and the parameter of
+hnae3_ae_ops.set_default_reset_request is verified.
+
+The error message:
+hns3 0000:39:01.0: cmd failed -16
+hns3 0000:39:01.0: hclge device re-init failed, VF is disabled!
+hns3 0000:39:01.0: failed to reset VF stack
+hns3 0000:39:01.0: failed to reset VF(4)
+hns3 0000:39:01.0: prepare reset(2) wait done
+hns3 0000:39:01.0 eth4: already uninitialized
+
+Use the crash tool to view struct hclgevf_dev:
+struct hclgevf_dev {
+...
+ default_reset_request = 0x20,
+ reset_level = HNAE3_NONE_RESET,
+ reset_pending = 0x100,
+ reset_type = HNAE3_NONE_RESET,
+...
+};
+
+Fixes: 720bd5837e37 ("net: hns3: add set_default_reset_request in the hnae3_ae_ops")
+Signed-off-by: Hao Lan <lanhao@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../hisilicon/hns3/hns3pf/hclge_main.c | 33 ++++++++++++++--
+ .../hisilicon/hns3/hns3vf/hclgevf_main.c | 38 ++++++++++++++++---
+ 2 files changed, 61 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 6c33195a1168f..116098033dfba 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -3583,6 +3583,17 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
+ return ret;
+ }
+
++static void hclge_set_reset_pending(struct hclge_dev *hdev,
++ enum hnae3_reset_type reset_type)
++{
++ /* When an incorrect reset type is executed, the get_reset_level
++ * function generates the HNAE3_NONE_RESET flag. As a result, this
++ * type do not need to pending.
++ */
++ if (reset_type != HNAE3_NONE_RESET)
++ set_bit(reset_type, &hdev->reset_pending);
++}
++
+ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
+ {
+ u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg;
+@@ -3603,7 +3614,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
+ */
+ if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) {
+ dev_info(&hdev->pdev->dev, "IMP reset interrupt\n");
+- set_bit(HNAE3_IMP_RESET, &hdev->reset_pending);
++ hclge_set_reset_pending(hdev, HNAE3_IMP_RESET);
+ set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
+ *clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B);
+ hdev->rst_stats.imp_rst_cnt++;
+@@ -3613,7 +3624,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
+ if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) {
+ dev_info(&hdev->pdev->dev, "global reset interrupt\n");
+ set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
+- set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending);
++ hclge_set_reset_pending(hdev, HNAE3_GLOBAL_RESET);
+ *clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B);
+ hdev->rst_stats.global_rst_cnt++;
+ return HCLGE_VECTOR0_EVENT_RST;
+@@ -4061,7 +4072,7 @@ static void hclge_do_reset(struct hclge_dev *hdev)
+ case HNAE3_FUNC_RESET:
+ dev_info(&pdev->dev, "PF reset requested\n");
+ /* schedule again to check later */
+- set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending);
++ hclge_set_reset_pending(hdev, HNAE3_FUNC_RESET);
+ hclge_reset_task_schedule(hdev);
+ break;
+ default:
+@@ -4095,6 +4106,8 @@ static enum hnae3_reset_type hclge_get_reset_level(struct hnae3_ae_dev *ae_dev,
+ clear_bit(HNAE3_FLR_RESET, addr);
+ }
+
++ clear_bit(HNAE3_NONE_RESET, addr);
++
+ if (hdev->reset_type != HNAE3_NONE_RESET &&
+ rst_level < hdev->reset_type)
+ return HNAE3_NONE_RESET;
+@@ -4236,7 +4249,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
+ return false;
+ } else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) {
+ hdev->rst_stats.reset_fail_cnt++;
+- set_bit(hdev->reset_type, &hdev->reset_pending);
++ hclge_set_reset_pending(hdev, hdev->reset_type);
+ dev_info(&hdev->pdev->dev,
+ "re-schedule reset task(%u)\n",
+ hdev->rst_stats.reset_fail_cnt);
+@@ -4479,8 +4492,20 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle)
+ static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
+ enum hnae3_reset_type rst_type)
+ {
++#define HCLGE_SUPPORT_RESET_TYPE \
++ (BIT(HNAE3_FLR_RESET) | BIT(HNAE3_FUNC_RESET) | \
++ BIT(HNAE3_GLOBAL_RESET) | BIT(HNAE3_IMP_RESET))
++
+ struct hclge_dev *hdev = ae_dev->priv;
+
++ if (!(BIT(rst_type) & HCLGE_SUPPORT_RESET_TYPE)) {
++ /* To prevent reset triggered by hclge_reset_event */
++ set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
++ dev_warn(&hdev->pdev->dev, "unsupported reset type %d\n",
++ rst_type);
++ return;
++ }
++
+ set_bit(rst_type, &hdev->default_reset_request);
+ }
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 094a7c7b55921..ab54e6155e933 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -1395,6 +1395,17 @@ static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev,
+ return ret;
+ }
+
++static void hclgevf_set_reset_pending(struct hclgevf_dev *hdev,
++ enum hnae3_reset_type reset_type)
++{
++ /* When an incorrect reset type is executed, the get_reset_level
++ * function generates the HNAE3_NONE_RESET flag. As a result, this
++ * type do not need to pending.
++ */
++ if (reset_type != HNAE3_NONE_RESET)
++ set_bit(reset_type, &hdev->reset_pending);
++}
++
+ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
+ {
+ #define HCLGEVF_RESET_WAIT_US 20000
+@@ -1544,7 +1555,7 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
+ hdev->rst_stats.rst_fail_cnt);
+
+ if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT)
+- set_bit(hdev->reset_type, &hdev->reset_pending);
++ hclgevf_set_reset_pending(hdev, hdev->reset_type);
+
+ if (hclgevf_is_reset_pending(hdev)) {
+ set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
+@@ -1664,6 +1675,8 @@ static enum hnae3_reset_type hclgevf_get_reset_level(unsigned long *addr)
+ clear_bit(HNAE3_FLR_RESET, addr);
+ }
+
++ clear_bit(HNAE3_NONE_RESET, addr);
++
+ return rst_level;
+ }
+
+@@ -1673,14 +1686,15 @@ static void hclgevf_reset_event(struct pci_dev *pdev,
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
+ struct hclgevf_dev *hdev = ae_dev->priv;
+
+- dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
+-
+ if (hdev->default_reset_request)
+ hdev->reset_level =
+ hclgevf_get_reset_level(&hdev->default_reset_request);
+ else
+ hdev->reset_level = HNAE3_VF_FUNC_RESET;
+
++ dev_info(&hdev->pdev->dev, "received reset request from VF enet, reset level is %d\n",
++ hdev->reset_level);
++
+ /* reset of this VF requested */
+ set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state);
+ hclgevf_reset_task_schedule(hdev);
+@@ -1691,8 +1705,20 @@ static void hclgevf_reset_event(struct pci_dev *pdev,
+ static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
+ enum hnae3_reset_type rst_type)
+ {
++#define HCLGEVF_SUPPORT_RESET_TYPE \
++ (BIT(HNAE3_VF_RESET) | BIT(HNAE3_VF_FUNC_RESET) | \
++ BIT(HNAE3_VF_PF_FUNC_RESET) | BIT(HNAE3_VF_FULL_RESET) | \
++ BIT(HNAE3_FLR_RESET) | BIT(HNAE3_VF_EXP_RESET))
++
+ struct hclgevf_dev *hdev = ae_dev->priv;
+
++ if (!(BIT(rst_type) & HCLGEVF_SUPPORT_RESET_TYPE)) {
++ /* To prevent reset triggered by hclge_reset_event */
++ set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
++ dev_info(&hdev->pdev->dev, "unsupported reset type %d\n",
++ rst_type);
++ return;
++ }
+ set_bit(rst_type, &hdev->default_reset_request);
+ }
+
+@@ -1849,14 +1875,14 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev)
+ */
+ if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) {
+ /* prepare for full reset of stack + pcie interface */
+- set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending);
++ hclgevf_set_reset_pending(hdev, HNAE3_VF_FULL_RESET);
+
+ /* "defer" schedule the reset task again */
+ set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
+ } else {
+ hdev->reset_attempts++;
+
+- set_bit(hdev->reset_level, &hdev->reset_pending);
++ hclgevf_set_reset_pending(hdev, hdev->reset_level);
+ set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
+ }
+ hclgevf_reset_task_schedule(hdev);
+@@ -1979,7 +2005,7 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
+ rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
+ dev_info(&hdev->pdev->dev,
+ "receive reset interrupt 0x%x!\n", rst_ing_reg);
+- set_bit(HNAE3_VF_RESET, &hdev->reset_pending);
++ hclgevf_set_reset_pending(hdev, HNAE3_VF_RESET);
+ set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
+ set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
+ *clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B);
+--
+2.43.0
+
--- /dev/null
+From 99dc677d4e8dc5524b5ea00653f2ac7e99eab74f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:36 +0800
+Subject: net: hns3: initialize reset_timer before hclgevf_misc_irq_init()
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit d1c2e2961ab460ac2433ff8ad46000582abc573c ]
+
+Currently the misc irq is initialized before reset_timer setup. But
+it will access the reset_timer in the irq handler. So initialize
+the reset_timer earlier.
+
+Fixes: ff200099d271 ("net: hns3: remove unnecessary work in hclgevf_main")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index ab54e6155e933..896f1eb172d30 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -2315,6 +2315,7 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev)
+ clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state);
+
+ INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task);
++ timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
+
+ mutex_init(&hdev->mbx_resp.mbx_mutex);
+ sema_init(&hdev->reset_sem, 1);
+@@ -3014,7 +3015,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
+ HCLGEVF_DRIVER_NAME);
+
+ hclgevf_task_schedule(hdev, round_jiffies_relative(HZ));
+- timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
+
+ return 0;
+
+--
+2.43.0
+
--- /dev/null
+From 7e07122807d23ae2d5e974a19b84949540a37002 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 17:29:34 +0800
+Subject: net: hns3: Resolved the issue that the debugfs query result is
+ inconsistent.
+
+From: Hao Lan <lanhao@huawei.com>
+
+[ Upstream commit 2758f18a83ef283d50c0566d3f672621cc658a1a ]
+
+This patch modifies the implementation of debugfs:
+When the user process stops unexpectedly, not all data of the file system
+is read. In this case, the save_buf pointer is not released. When the user
+process is called next time, save_buf is used to copy the cached data
+to the user space. As a result, the queried data is inconsistent. To solve
+this problem, determine whether the function is invoked for the first time
+based on the value of *ppos. If *ppos is 0, obtain the actual data.
+
+Fixes: 5e69ea7ee2a6 ("net: hns3: refactor the debugfs process")
+Signed-off-by: Hao Lan <lanhao@huawei.com>
+Signed-off-by: Guangwei Zhang <zhangwangwei6@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+index 807eb3bbb11c0..841e5af7b2bee 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+@@ -1293,8 +1293,10 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
+
+ /* save the buffer addr until the last read operation */
+ *save_buf = read_buf;
++ }
+
+- /* get data ready for the first time to read */
++ /* get data ready for the first time to read */
++ if (!*ppos) {
+ ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
+ read_buf, hns3_dbg_cmd[index].buf_len);
+ if (ret)
+--
+2.43.0
+
--- /dev/null
+From 793fcd719a656c0db67b988adf9d42911ff40b26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 13:05:41 +0300
+Subject: net/sched: sch_api: fix xa_insert() error path in tcf_block_get_ext()
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit a13e690191eafc154b3f60afe9ce35aa9b9128b4 ]
+
+This command:
+
+$ tc qdisc replace dev eth0 ingress_block 1 egress_block 1 clsact
+Error: block dev insert failed: -EBUSY.
+
+fails because user space requests the same block index to be set for
+both ingress and egress.
+
+[ side note, I don't think it even failed prior to commit 913b47d3424e
+ ("net/sched: Introduce tc block netdev tracking infra"), because this
+ is a command from an old set of notes of mine which used to work, but
+ alas, I did not scientifically bisect this ]
+
+The problem is not that it fails, but rather, that the second time
+around, it fails differently (and irrecoverably):
+
+$ tc qdisc replace dev eth0 ingress_block 1 egress_block 1 clsact
+Error: dsa_core: Flow block cb is busy.
+
+[ another note: the extack is added by me for illustration purposes.
+ the context of the problem is that clsact_init() obtains the same
+ &q->ingress_block pointer as &q->egress_block, and since we call
+ tcf_block_get_ext() on both of them, "dev" will be added to the
+ block->ports xarray twice, thus failing the operation: once through
+ the ingress block pointer, and once again through the egress block
+ pointer. the problem itself is that when xa_insert() fails, we have
+ emitted a FLOW_BLOCK_BIND command through ndo_setup_tc(), but the
+ offload never sees a corresponding FLOW_BLOCK_UNBIND. ]
+
+Even correcting the bad user input, we still cannot recover:
+
+$ tc qdisc replace dev swp3 ingress_block 1 egress_block 2 clsact
+Error: dsa_core: Flow block cb is busy.
+
+Basically the only way to recover is to reboot the system, or unbind and
+rebind the net device driver.
+
+To fix the bug, we need to fill the correct error teardown path which
+was missed during code movement, and call tcf_block_offload_unbind()
+when xa_insert() fails.
+
+[ last note, fundamentally I blame the label naming convention in
+ tcf_block_get_ext() for the bug. The labels should be named after what
+ they do, not after the error path that jumps to them. This way, it is
+ obviously wrong that two labels pointing to the same code mean
+ something is wrong, and checking the code correctness at the goto site
+ is also easier ]
+
+Fixes: 94e2557d086a ("net: sched: move block device tracking into tcf_block_get/put_ext()")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20241023100541.974362-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 17d97bbe890fd..bbc778c233c89 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -1518,6 +1518,7 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
+ return 0;
+
+ err_dev_insert:
++ tcf_block_offload_unbind(block, q, ei);
+ err_block_offload_bind:
+ tcf_chain0_head_change_cb_del(block, ei);
+ err_chain0_head_change_cb_add:
+--
+2.43.0
+
--- /dev/null
+From be3ae482e32c0f34cf4d11e63fe6c262f763e11e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Oct 2024 12:55:47 -0400
+Subject: net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT
+
+From: Pedro Tammela <pctammela@mojatatu.com>
+
+[ Upstream commit 2e95c4384438adeaa772caa560244b1a2efef816 ]
+
+In qdisc_tree_reduce_backlog, Qdiscs with major handle ffff: are assumed
+to be either root or ingress. This assumption is bogus since it's valid
+to create egress qdiscs with major handle ffff:
+Budimir Markovic found that for qdiscs like DRR that maintain an active
+class list, it will cause a UAF with a dangling class pointer.
+
+In 066a3b5b2346, the concern was to avoid iterating over the ingress
+qdisc since its parent is itself. The proper fix is to stop when parent
+TC_H_ROOT is reached because the only way to retrieve ingress is when a
+hierarchy which does not contain a ffff: major handle call into
+qdisc_lookup with TC_H_MAJ(TC_H_ROOT).
+
+In the scenario where major ffff: is an egress qdisc in any of the tree
+levels, the updates will also propagate to TC_H_ROOT, which then the
+iteration must stop.
+
+Fixes: 066a3b5b2346 ("[NET_SCHED] sch_api: fix qdisc_tree_decrease_qlen() loop")
+Reported-by: Budimir Markovic <markovicbudimir@gmail.com>
+Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+
+ net/sched/sch_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+Reviewed-by: Simon Horman <horms@kernel.org>
+
+Link: https://patch.msgid.link/20241024165547.418570-1-jhs@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
+index 2eefa47838799..a1d27bc039a36 100644
+--- a/net/sched/sch_api.c
++++ b/net/sched/sch_api.c
+@@ -791,7 +791,7 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len)
+ drops = max_t(int, n, 0);
+ rcu_read_lock();
+ while ((parentid = sch->parent)) {
+- if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
++ if (parentid == TC_H_ROOT)
+ break;
+
+ if (sch->flags & TCQ_F_NOPARENT)
+--
+2.43.0
+
--- /dev/null
+From 72702e0c918a074c655a654ccefbc39c24cd8d91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Oct 2024 16:01:54 +0200
+Subject: net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains
+ extension
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Benoît Monin <benoit.monin@gmx.fr>
+
+[ Upstream commit 04c20a9356f283da623903e81e7c6d5df7e4dc3c ]
+
+As documented in skbuff.h, devices with NETIF_F_IPV6_CSUM capability
+can only checksum TCP and UDP over IPv6 if the IP header does not
+contains extension.
+
+This is enforced for UDP packets emitted from user-space to an IPv6
+address as they go through ip6_make_skb(), which calls
+__ip6_append_data() where a check is done on the header size before
+setting CHECKSUM_PARTIAL.
+
+But the introduction of UDP encapsulation with fou6 added a code-path
+where it is possible to get an skb with a partial UDP checksum and an
+IPv6 header with extension:
+* fou6 adds a UDP header with a partial checksum if the inner packet
+does not contains a valid checksum.
+* ip6_tunnel adds an IPv6 header with a destination option extension
+header if encap_limit is non-zero (the default value is 4).
+
+The thread linked below describes in more details how to reproduce the
+problem with GRE-in-UDP tunnel.
+
+Add a check on the network header size in skb_csum_hwoffload_help() to
+make sure no IPv6 packet with extension header is handed to a network
+device with NETIF_F_IPV6_CSUM capability.
+
+Link: https://lore.kernel.org/netdev/26548921.1r3eYUQgxm@benoit.monin/T/#u
+Fixes: aa3463d65e7b ("fou: Add encap ops for IPv6 tunnels")
+Signed-off-by: Benoît Monin <benoit.monin@gmx.fr>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/5fbeecfc311ea182aa1d1c771725ab8b4cac515e.1729778144.git.benoit.monin@gmx.fr
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index dd87f5fb2f3a7..25f20c5cc8f55 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3631,6 +3631,9 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
+ return 0;
+
+ if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) {
++ if (vlan_get_protocol(skb) == htons(ETH_P_IPV6) &&
++ skb_network_header_len(skb) != sizeof(struct ipv6hdr))
++ goto sw_checksum;
+ switch (skb->csum_offset) {
+ case offsetof(struct tcphdr, check):
+ case offsetof(struct udphdr, check):
+@@ -3638,6 +3641,7 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
+ }
+ }
+
++sw_checksum:
+ return skb_checksum_help(skb);
+ }
+ EXPORT_SYMBOL(skb_csum_hwoffload_help);
+--
+2.43.0
+
--- /dev/null
+From 01e7b4c2646b9e6efb8a4839dd72ca4745965380 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 13:46:25 +0800
+Subject: net: stmmac: dwmac4: Fix high address display by updating reg_space[]
+ from register values
+
+From: Ley Foon Tan <leyfoon.tan@starfivetech.com>
+
+[ Upstream commit f84ef58e553206b02d06e02158c98fbccba25d19 ]
+
+The high address will display as 0 if the driver does not set the
+reg_space[]. To fix this, read the high address registers and
+update the reg_space[] accordingly.
+
+Fixes: fbf68229ffe7 ("net: stmmac: unify registers dumps methods")
+Signed-off-by: Ley Foon Tan <leyfoon.tan@starfivetech.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20241021054625.1791965-1-leyfoon.tan@starfivetech.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 8 ++++++++
+ drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h | 2 ++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+index 84d3a8551b032..071f128aa4907 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+@@ -203,8 +203,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv,
+ readl(ioaddr + DMA_CHAN_TX_CONTROL(dwmac4_addrs, channel));
+ reg_space[DMA_CHAN_RX_CONTROL(default_addrs, channel) / 4] =
+ readl(ioaddr + DMA_CHAN_RX_CONTROL(dwmac4_addrs, channel));
++ reg_space[DMA_CHAN_TX_BASE_ADDR_HI(default_addrs, channel) / 4] =
++ readl(ioaddr + DMA_CHAN_TX_BASE_ADDR_HI(dwmac4_addrs, channel));
+ reg_space[DMA_CHAN_TX_BASE_ADDR(default_addrs, channel) / 4] =
+ readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(dwmac4_addrs, channel));
++ reg_space[DMA_CHAN_RX_BASE_ADDR_HI(default_addrs, channel) / 4] =
++ readl(ioaddr + DMA_CHAN_RX_BASE_ADDR_HI(dwmac4_addrs, channel));
+ reg_space[DMA_CHAN_RX_BASE_ADDR(default_addrs, channel) / 4] =
+ readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(dwmac4_addrs, channel));
+ reg_space[DMA_CHAN_TX_END_ADDR(default_addrs, channel) / 4] =
+@@ -225,8 +229,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv,
+ readl(ioaddr + DMA_CHAN_CUR_TX_DESC(dwmac4_addrs, channel));
+ reg_space[DMA_CHAN_CUR_RX_DESC(default_addrs, channel) / 4] =
+ readl(ioaddr + DMA_CHAN_CUR_RX_DESC(dwmac4_addrs, channel));
++ reg_space[DMA_CHAN_CUR_TX_BUF_ADDR_HI(default_addrs, channel) / 4] =
++ readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR_HI(dwmac4_addrs, channel));
+ reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(default_addrs, channel) / 4] =
+ readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(dwmac4_addrs, channel));
++ reg_space[DMA_CHAN_CUR_RX_BUF_ADDR_HI(default_addrs, channel) / 4] =
++ readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR_HI(dwmac4_addrs, channel));
+ reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(default_addrs, channel) / 4] =
+ readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(dwmac4_addrs, channel));
+ reg_space[DMA_CHAN_STATUS(default_addrs, channel) / 4] =
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+index 17d9120db5fe9..4f980dcd39582 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+@@ -127,7 +127,9 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
+ #define DMA_CHAN_SLOT_CTRL_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x3c)
+ #define DMA_CHAN_CUR_TX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x44)
+ #define DMA_CHAN_CUR_RX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x4c)
++#define DMA_CHAN_CUR_TX_BUF_ADDR_HI(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x50)
+ #define DMA_CHAN_CUR_TX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x54)
++#define DMA_CHAN_CUR_RX_BUF_ADDR_HI(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x58)
+ #define DMA_CHAN_CUR_RX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x5c)
+ #define DMA_CHAN_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x60)
+
+--
+2.43.0
+
--- /dev/null
+From 9b0322970ce441e4b8b7408cc0efcb76e7e0e84e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 14:10:23 +0800
+Subject: net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data
+
+From: Furong Xu <0x1207@gmail.com>
+
+[ Upstream commit 66600fac7a984dea4ae095411f644770b2561ede ]
+
+In case the non-paged data of a SKB carries protocol header and protocol
+payload to be transmitted on a certain platform that the DMA AXI address
+width is configured to 40-bit/48-bit, or the size of the non-paged data
+is bigger than TSO_MAX_BUFF_SIZE on a certain platform that the DMA AXI
+address width is configured to 32-bit, then this SKB requires at least
+two DMA transmit descriptors to serve it.
+
+For example, three descriptors are allocated to split one DMA buffer
+mapped from one piece of non-paged data:
+ dma_desc[N + 0],
+ dma_desc[N + 1],
+ dma_desc[N + 2].
+Then three elements of tx_q->tx_skbuff_dma[] will be allocated to hold
+extra information to be reused in stmmac_tx_clean():
+ tx_q->tx_skbuff_dma[N + 0],
+ tx_q->tx_skbuff_dma[N + 1],
+ tx_q->tx_skbuff_dma[N + 2].
+Now we focus on tx_q->tx_skbuff_dma[entry].buf, which is the DMA buffer
+address returned by DMA mapping call. stmmac_tx_clean() will try to
+unmap the DMA buffer _ONLY_IF_ tx_q->tx_skbuff_dma[entry].buf
+is a valid buffer address.
+
+The expected behavior that saves DMA buffer address of this non-paged
+data to tx_q->tx_skbuff_dma[entry].buf is:
+ tx_q->tx_skbuff_dma[N + 0].buf = NULL;
+ tx_q->tx_skbuff_dma[N + 1].buf = NULL;
+ tx_q->tx_skbuff_dma[N + 2].buf = dma_map_single();
+Unfortunately, the current code misbehaves like this:
+ tx_q->tx_skbuff_dma[N + 0].buf = dma_map_single();
+ tx_q->tx_skbuff_dma[N + 1].buf = NULL;
+ tx_q->tx_skbuff_dma[N + 2].buf = NULL;
+
+On the stmmac_tx_clean() side, when dma_desc[N + 0] is closed by the
+DMA engine, tx_q->tx_skbuff_dma[N + 0].buf is a valid buffer address
+obviously, then the DMA buffer will be unmapped immediately.
+There may be a rare case that the DMA engine does not finish the
+pending dma_desc[N + 1], dma_desc[N + 2] yet. Now things will go
+horribly wrong, DMA is going to access a unmapped/unreferenced memory
+region, corrupted data will be transmited or iommu fault will be
+triggered :(
+
+In contrast, the for-loop that maps SKB fragments behaves perfectly
+as expected, and that is how the driver should do for both non-paged
+data and paged frags actually.
+
+This patch corrects DMA map/unmap sequences by fixing the array index
+for tx_q->tx_skbuff_dma[entry].buf when assigning DMA buffer address.
+
+Tested and verified on DWXGMAC CORE 3.20a
+
+Reported-by: Suraj Jaiswal <quic_jsuraj@quicinc.com>
+Fixes: f748be531d70 ("stmmac: support new GMAC4")
+Signed-off-by: Furong Xu <0x1207@gmail.com>
+Reviewed-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20241021061023.2162701-1-0x1207@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 22 ++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index f3a1b179aaeac..02368917efb4a 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -4330,11 +4330,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
+ if (dma_mapping_error(priv->device, des))
+ goto dma_map_err;
+
+- tx_q->tx_skbuff_dma[first_entry].buf = des;
+- tx_q->tx_skbuff_dma[first_entry].len = skb_headlen(skb);
+- tx_q->tx_skbuff_dma[first_entry].map_as_page = false;
+- tx_q->tx_skbuff_dma[first_entry].buf_type = STMMAC_TXBUF_T_SKB;
+-
+ if (priv->dma_cap.addr64 <= 32) {
+ first->des0 = cpu_to_le32(des);
+
+@@ -4353,6 +4348,23 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
+
+ stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
+
++ /* In case two or more DMA transmit descriptors are allocated for this
++ * non-paged SKB data, the DMA buffer address should be saved to
++ * tx_q->tx_skbuff_dma[].buf corresponding to the last descriptor,
++ * and leave the other tx_q->tx_skbuff_dma[].buf as NULL to guarantee
++ * that stmmac_tx_clean() does not unmap the entire DMA buffer too early
++ * since the tail areas of the DMA buffer can be accessed by DMA engine
++ * sooner or later.
++ * By saving the DMA buffer address to tx_q->tx_skbuff_dma[].buf
++ * corresponding to the last descriptor, stmmac_tx_clean() will unmap
++ * this DMA buffer right after the DMA engine completely finishes the
++ * full buffer transmission.
++ */
++ tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
++ tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
++ tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
++ tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
++
+ /* Prepare fragments */
+ for (i = 0; i < nfrags; i++) {
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+--
+2.43.0
+
--- /dev/null
+From 37092486866e7221d5b7452803d7182ceceb7f60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2024 12:19:08 -0500
+Subject: netdevsim: Add trailing zero to terminate the string in
+ nsim_nexthop_bucket_activity_write()
+
+From: Zichen Xie <zichenxie0106@gmail.com>
+
+[ Upstream commit 4ce1f56a1eaced2523329bef800d004e30f2f76c ]
+
+This was found by a static analyzer.
+We should not forget the trailing zero after copy_from_user()
+if we will further do some string operations, sscanf() in this
+case. Adding a trailing zero will ensure that the function
+performs properly.
+
+Fixes: c6385c0b67c5 ("netdevsim: Allow reporting activity on nexthop buckets")
+Signed-off-by: Zichen Xie <zichenxie0106@gmail.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20241022171907.8606-1-zichenxie0106@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/netdevsim/fib.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c
+index a1f91ff8ec568..f108e363b716a 100644
+--- a/drivers/net/netdevsim/fib.c
++++ b/drivers/net/netdevsim/fib.c
+@@ -1377,10 +1377,12 @@ static ssize_t nsim_nexthop_bucket_activity_write(struct file *file,
+
+ if (pos != 0)
+ return -EINVAL;
+- if (size > sizeof(buf))
++ if (size > sizeof(buf) - 1)
+ return -EINVAL;
+ if (copy_from_user(buf, user_buf, size))
+ return -EFAULT;
++ buf[size] = 0;
++
+ if (sscanf(buf, "%u %hu", &nhid, &bucket_index) != 2)
+ return -EINVAL;
+
+--
+2.43.0
+
--- /dev/null
+From bdf388cc37c2d81e2b65adb1e5303064d8bdeb8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Oct 2024 09:47:01 +0800
+Subject: netfilter: Fix use-after-free in get_info()
+
+From: Dong Chenchen <dongchenchen2@huawei.com>
+
+[ Upstream commit f48d258f0ac540f00fa617dac496c4c18b5dc2fa ]
+
+ip6table_nat module unload has refcnt warning for UAF. call trace is:
+
+WARNING: CPU: 1 PID: 379 at kernel/module/main.c:853 module_put+0x6f/0x80
+Modules linked in: ip6table_nat(-)
+CPU: 1 UID: 0 PID: 379 Comm: ip6tables Not tainted 6.12.0-rc4-00047-gc2ee9f594da8-dirty #205
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
+BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+RIP: 0010:module_put+0x6f/0x80
+Call Trace:
+ <TASK>
+ get_info+0x128/0x180
+ do_ip6t_get_ctl+0x6a/0x430
+ nf_getsockopt+0x46/0x80
+ ipv6_getsockopt+0xb9/0x100
+ rawv6_getsockopt+0x42/0x190
+ do_sock_getsockopt+0xaa/0x180
+ __sys_getsockopt+0x70/0xc0
+ __x64_sys_getsockopt+0x20/0x30
+ do_syscall_64+0xa2/0x1a0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Concurrent execution of module unload and get_info() trigered the warning.
+The root cause is as follows:
+
+cpu0 cpu1
+module_exit
+//mod->state = MODULE_STATE_GOING
+ ip6table_nat_exit
+ xt_unregister_template
+ kfree(t)
+ //removed from templ_list
+ getinfo()
+ t = xt_find_table_lock
+ list_for_each_entry(tmpl, &xt_templates[af]...)
+ if (strcmp(tmpl->name, name))
+ continue; //table not found
+ try_module_get
+ list_for_each_entry(t, &xt_net->tables[af]...)
+ return t; //not get refcnt
+ module_put(t->me) //uaf
+ unregister_pernet_subsys
+ //remove table from xt_net list
+
+While xt_table module was going away and has been removed from
+xt_templates list, we couldnt get refcnt of xt_table->me. Check
+module in xt_net->tables list re-traversal to fix it.
+
+Fixes: fdacd57c79b7 ("netfilter: x_tables: never register tables by default")
+Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/x_tables.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
+index da5d929c7c85b..709840612f0df 100644
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -1269,7 +1269,7 @@ struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
+
+ /* and once again: */
+ list_for_each_entry(t, &xt_net->tables[af], list)
+- if (strcmp(t->name, name) == 0)
++ if (strcmp(t->name, name) == 0 && owner == t->me)
+ return t;
+
+ module_put(owner);
+--
+2.43.0
+
--- /dev/null
+From 98e9bd68a52b19b1d4584b42690bb66211a988b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 08:02:29 +0000
+Subject: netfilter: nf_reject_ipv6: fix potential crash in nf_send_reset6()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 4ed234fe793f27a3b151c43d2106df2ff0d81aac ]
+
+I got a syzbot report without a repro [1] crashing in nf_send_reset6()
+
+I think the issue is that dev->hard_header_len is zero, and we attempt
+later to push an Ethernet header.
+
+Use LL_MAX_HEADER, as other functions in net/ipv6/netfilter/nf_reject_ipv6.c.
+
+[1]
+
+skbuff: skb_under_panic: text:ffffffff89b1d008 len:74 put:14 head:ffff88803123aa00 data:ffff88803123a9f2 tail:0x3c end:0x140 dev:syz_tun
+ kernel BUG at net/core/skbuff.c:206 !
+Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI
+CPU: 0 UID: 0 PID: 7373 Comm: syz.1.568 Not tainted 6.12.0-rc2-syzkaller-00631-g6d858708d465 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
+ RIP: 0010:skb_panic net/core/skbuff.c:206 [inline]
+ RIP: 0010:skb_under_panic+0x14b/0x150 net/core/skbuff.c:216
+Code: 0d 8d 48 c7 c6 60 a6 29 8e 48 8b 54 24 08 8b 0c 24 44 8b 44 24 04 4d 89 e9 50 41 54 41 57 41 56 e8 ba 30 38 02 48 83 c4 20 90 <0f> 0b 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3
+RSP: 0018:ffffc900045269b0 EFLAGS: 00010282
+RAX: 0000000000000088 RBX: dffffc0000000000 RCX: cd66dacdc5d8e800
+RDX: 0000000000000000 RSI: 0000000000000200 RDI: 0000000000000000
+RBP: ffff88802d39a3d0 R08: ffffffff8174afec R09: 1ffff920008a4ccc
+R10: dffffc0000000000 R11: fffff520008a4ccd R12: 0000000000000140
+R13: ffff88803123aa00 R14: ffff88803123a9f2 R15: 000000000000003c
+FS: 00007fdbee5ff6c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000000000000 CR3: 000000005d322000 CR4: 00000000003526f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ skb_push+0xe5/0x100 net/core/skbuff.c:2636
+ eth_header+0x38/0x1f0 net/ethernet/eth.c:83
+ dev_hard_header include/linux/netdevice.h:3208 [inline]
+ nf_send_reset6+0xce6/0x1270 net/ipv6/netfilter/nf_reject_ipv6.c:358
+ nft_reject_inet_eval+0x3b9/0x690 net/netfilter/nft_reject_inet.c:48
+ expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline]
+ nft_do_chain+0x4ad/0x1da0 net/netfilter/nf_tables_core.c:288
+ nft_do_chain_inet+0x418/0x6b0 net/netfilter/nft_chain_filter.c:161
+ nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+ nf_hook_slow+0xc3/0x220 net/netfilter/core.c:626
+ nf_hook include/linux/netfilter.h:269 [inline]
+ NF_HOOK include/linux/netfilter.h:312 [inline]
+ br_nf_pre_routing_ipv6+0x63e/0x770 net/bridge/br_netfilter_ipv6.c:184
+ nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+ nf_hook_bridge_pre net/bridge/br_input.c:277 [inline]
+ br_handle_frame+0x9fd/0x1530 net/bridge/br_input.c:424
+ __netif_receive_skb_core+0x13e8/0x4570 net/core/dev.c:5562
+ __netif_receive_skb_one_core net/core/dev.c:5666 [inline]
+ __netif_receive_skb+0x12f/0x650 net/core/dev.c:5781
+ netif_receive_skb_internal net/core/dev.c:5867 [inline]
+ netif_receive_skb+0x1e8/0x890 net/core/dev.c:5926
+ tun_rx_batched+0x1b7/0x8f0 drivers/net/tun.c:1550
+ tun_get_user+0x3056/0x47e0 drivers/net/tun.c:2007
+ tun_chr_write_iter+0x10d/0x1f0 drivers/net/tun.c:2053
+ new_sync_write fs/read_write.c:590 [inline]
+ vfs_write+0xa6d/0xc90 fs/read_write.c:683
+ ksys_write+0x183/0x2b0 fs/read_write.c:736
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7fdbeeb7d1ff
+Code: 89 54 24 18 48 89 74 24 10 89 7c 24 08 e8 c9 8d 02 00 48 8b 54 24 18 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 31 44 89 c7 48 89 44 24 08 e8 1c 8e 02 00 48
+RSP: 002b:00007fdbee5ff000 EFLAGS: 00000293 ORIG_RAX: 0000000000000001
+RAX: ffffffffffffffda RBX: 00007fdbeed36058 RCX: 00007fdbeeb7d1ff
+RDX: 000000000000008e RSI: 0000000020000040 RDI: 00000000000000c8
+RBP: 00007fdbeebf12be R08: 0000000000000000 R09: 0000000000000000
+R10: 000000000000008e R11: 0000000000000293 R12: 0000000000000000
+R13: 0000000000000000 R14: 00007fdbeed36058 R15: 00007ffc38de06e8
+ </TASK>
+
+Fixes: c8d7b98bec43 ("netfilter: move nf_send_resetX() code to nf_reject_ipvX modules")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/nf_reject_ipv6.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
+index 7db0437140bf2..9ae2b2725bf99 100644
+--- a/net/ipv6/netfilter/nf_reject_ipv6.c
++++ b/net/ipv6/netfilter/nf_reject_ipv6.c
+@@ -268,12 +268,12 @@ static int nf_reject6_fill_skb_dst(struct sk_buff *skb_in)
+ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+ int hook)
+ {
+- struct sk_buff *nskb;
+- struct tcphdr _otcph;
+- const struct tcphdr *otcph;
+- unsigned int otcplen, hh_len;
+ const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
+ struct dst_entry *dst = NULL;
++ const struct tcphdr *otcph;
++ struct sk_buff *nskb;
++ struct tcphdr _otcph;
++ unsigned int otcplen;
+ struct flowi6 fl6;
+
+ if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
+@@ -312,9 +312,8 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+ if (IS_ERR(dst))
+ return;
+
+- hh_len = (dst->dev->hard_header_len + 15)&~15;
+- nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
+- + sizeof(struct tcphdr) + dst->trailer_len,
++ nskb = alloc_skb(LL_MAX_HEADER + sizeof(struct ipv6hdr) +
++ sizeof(struct tcphdr) + dst->trailer_len,
+ GFP_ATOMIC);
+
+ if (!nskb) {
+@@ -327,7 +326,7 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+
+ nskb->mark = fl6.flowi6_mark;
+
+- skb_reserve(nskb, hh_len + dst->header_len);
++ skb_reserve(nskb, LL_MAX_HEADER);
+ nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP, ip6_dst_hoplimit(dst));
+ nf_reject_ip6_tcphdr_put(nskb, oldskb, otcph, otcplen);
+
+--
+2.43.0
+
--- /dev/null
+From 26bba4a51184c53920fe4827d9a6d7ecf97dd228 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Oct 2024 23:13:48 +0100
+Subject: netfilter: nft_payload: sanitize offset and length before calling
+ skb_checksum()
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit d5953d680f7e96208c29ce4139a0e38de87a57fe ]
+
+If access to offset + length is larger than the skbuff length, then
+skb_checksum() triggers BUG_ON().
+
+skb_checksum() internally subtracts the length parameter while iterating
+over skbuff, BUG_ON(len) at the end of it checks that the expected
+length to be included in the checksum calculation is fully consumed.
+
+Fixes: 7ec3f7b47b8d ("netfilter: nft_payload: add packet mangling support")
+Reported-by: Slavin Liu <slavin-ayu@qq.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_payload.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
+index 50429cbd42da4..2db38c06bedeb 100644
+--- a/net/netfilter/nft_payload.c
++++ b/net/netfilter/nft_payload.c
+@@ -904,6 +904,9 @@ static void nft_payload_set_eval(const struct nft_expr *expr,
+ ((priv->base != NFT_PAYLOAD_TRANSPORT_HEADER &&
+ priv->base != NFT_PAYLOAD_INNER_HEADER) ||
+ skb->ip_summed != CHECKSUM_PARTIAL)) {
++ if (offset + priv->len > skb->len)
++ goto err;
++
+ fsum = skb_checksum(skb, offset, priv->len, 0);
+ tsum = csum_partial(src, priv->len, 0);
+
+--
+2.43.0
+
--- /dev/null
+From d2ce09c2d88eebcbc29b19fe5db02b151b7d84e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Oct 2024 06:36:14 -0700
+Subject: RDMA/bnxt_re: Fix the usage of control path spin locks
+
+From: Selvin Xavier <selvin.xavier@broadcom.com>
+
+[ Upstream commit d71f4acd584cc861f54b3cb3ac07875f06550a05 ]
+
+Control path completion processing always runs in tasklet context. To
+synchronize with the posting thread, there is no need to use the irq
+variant of spin lock. Use spin_lock_bh instead.
+
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Link: https://patch.msgid.link/r/1728912975-19346-2-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 25 +++++++++-------------
+ 1 file changed, 10 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index 7294221b3316c..ca26b88a0a80f 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -290,7 +290,6 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ struct bnxt_qplib_hwq *hwq;
+ u32 sw_prod, cmdq_prod;
+ struct pci_dev *pdev;
+- unsigned long flags;
+ u16 cookie;
+ u8 *preq;
+
+@@ -301,7 +300,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ /* Cmdq are in 16-byte units, each request can consume 1 or more
+ * cmdqe
+ */
+- spin_lock_irqsave(&hwq->lock, flags);
++ spin_lock_bh(&hwq->lock);
+ required_slots = bnxt_qplib_get_cmd_slots(msg->req);
+ free_slots = HWQ_FREE_SLOTS(hwq);
+ cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE;
+@@ -311,7 +310,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ dev_info_ratelimited(&pdev->dev,
+ "CMDQ is full req/free %d/%d!",
+ required_slots, free_slots);
+- spin_unlock_irqrestore(&hwq->lock, flags);
++ spin_unlock_bh(&hwq->lock);
+ return -EAGAIN;
+ }
+ if (msg->block)
+@@ -367,7 +366,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ wmb();
+ writel(cmdq_prod, cmdq->cmdq_mbox.prod);
+ writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db);
+- spin_unlock_irqrestore(&hwq->lock, flags);
++ spin_unlock_bh(&hwq->lock);
+ /* Return the CREQ response pointer */
+ return 0;
+ }
+@@ -486,7 +485,6 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+ {
+ struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp;
+ struct bnxt_qplib_crsqe *crsqe;
+- unsigned long flags;
+ u16 cookie;
+ int rc;
+ u8 opcode;
+@@ -512,12 +510,12 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+ rc = __poll_for_resp(rcfw, cookie);
+
+ if (rc) {
+- spin_lock_irqsave(&rcfw->cmdq.hwq.lock, flags);
++ spin_lock_bh(&rcfw->cmdq.hwq.lock);
+ crsqe = &rcfw->crsqe_tbl[cookie];
+ crsqe->is_waiter_alive = false;
+ if (rc == -ENODEV)
+ set_bit(FIRMWARE_STALL_DETECTED, &rcfw->cmdq.flags);
+- spin_unlock_irqrestore(&rcfw->cmdq.hwq.lock, flags);
++ spin_unlock_bh(&rcfw->cmdq.hwq.lock);
+ return -ETIMEDOUT;
+ }
+
+@@ -628,7 +626,6 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
+ u16 cookie, blocked = 0;
+ bool is_waiter_alive;
+ struct pci_dev *pdev;
+- unsigned long flags;
+ u32 wait_cmds = 0;
+ int rc = 0;
+
+@@ -659,8 +656,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
+ *
+ */
+
+- spin_lock_irqsave_nested(&hwq->lock, flags,
+- SINGLE_DEPTH_NESTING);
++ spin_lock_nested(&hwq->lock, SINGLE_DEPTH_NESTING);
+ cookie = le16_to_cpu(qp_event->cookie);
+ blocked = cookie & RCFW_CMD_IS_BLOCKING;
+ cookie &= RCFW_MAX_COOKIE_VALUE;
+@@ -672,7 +668,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
+ dev_info(&pdev->dev,
+ "rcfw timedout: cookie = %#x, free_slots = %d",
+ cookie, crsqe->free_slots);
+- spin_unlock_irqrestore(&hwq->lock, flags);
++ spin_unlock(&hwq->lock);
+ return rc;
+ }
+
+@@ -720,7 +716,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
+ __destroy_timedout_ah(rcfw,
+ (struct creq_create_ah_resp *)
+ qp_event);
+- spin_unlock_irqrestore(&hwq->lock, flags);
++ spin_unlock(&hwq->lock);
+ }
+ *num_wait += wait_cmds;
+ return rc;
+@@ -734,12 +730,11 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
+ u32 type, budget = CREQ_ENTRY_POLL_BUDGET;
+ struct bnxt_qplib_hwq *hwq = &creq->hwq;
+ struct creq_base *creqe;
+- unsigned long flags;
+ u32 num_wakeup = 0;
+ u32 hw_polled = 0;
+
+ /* Service the CREQ until budget is over */
+- spin_lock_irqsave(&hwq->lock, flags);
++ spin_lock_bh(&hwq->lock);
+ while (budget > 0) {
+ creqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL);
+ if (!CREQ_CMP_VALID(creqe, creq->creq_db.dbinfo.flags))
+@@ -782,7 +777,7 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
+ if (hw_polled)
+ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo,
+ rcfw->res->cctx, true);
+- spin_unlock_irqrestore(&hwq->lock, flags);
++ spin_unlock_bh(&hwq->lock);
+ if (num_wakeup)
+ wake_up_nr(&rcfw->cmdq.waitq, num_wakeup);
+ }
+--
+2.43.0
+
--- /dev/null
+From 725a9acccb5bac27b204bdaa6868346a997c02fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Oct 2024 06:36:15 -0700
+Subject: RDMA/bnxt_re: synchronize the qp-handle table array
+
+From: Selvin Xavier <selvin.xavier@broadcom.com>
+
+[ Upstream commit 76d3ddff7153cc0bcc14a63798d19f5d0693ea71 ]
+
+There is a race between the CREQ tasklet and destroy qp when accessing the
+qp-handle table. There is a chance of reading a valid qp-handle in the
+CREQ tasklet handler while the QP is already moving ahead with the
+destruction.
+
+Fixing this race by implementing a table-lock to synchronize the access.
+
+Fixes: f218d67ef004 ("RDMA/bnxt_re: Allow posting when QPs are in error")
+Fixes: 84cf229f4001 ("RDMA/bnxt_re: Fix the qp table indexing")
+Link: https://patch.msgid.link/r/1728912975-19346-3-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 4 ++++
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 13 +++++++++----
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 2 ++
+ 3 files changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+index 03d517be9c52e..560a0f7bff85e 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -1532,9 +1532,11 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
+ u32 tbl_indx;
+ int rc;
+
++ spin_lock_bh(&rcfw->tbl_lock);
+ tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
+ rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID;
+ rcfw->qp_tbl[tbl_indx].qp_handle = NULL;
++ spin_unlock_bh(&rcfw->tbl_lock);
+
+ bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
+ CMDQ_BASE_OPCODE_DESTROY_QP,
+@@ -1545,8 +1547,10 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
+ sizeof(resp), 0);
+ rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
+ if (rc) {
++ spin_lock_bh(&rcfw->tbl_lock);
+ rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
+ rcfw->qp_tbl[tbl_indx].qp_handle = qp;
++ spin_unlock_bh(&rcfw->tbl_lock);
+ return rc;
+ }
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index ca26b88a0a80f..e82bd37158ad6 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -634,17 +634,21 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
+ case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION:
+ err_event = (struct creq_qp_error_notification *)qp_event;
+ qp_id = le32_to_cpu(err_event->xid);
++ spin_lock(&rcfw->tbl_lock);
+ tbl_indx = map_qp_id_to_tbl_indx(qp_id, rcfw);
+ qp = rcfw->qp_tbl[tbl_indx].qp_handle;
++ if (!qp) {
++ spin_unlock(&rcfw->tbl_lock);
++ break;
++ }
++ bnxt_qplib_mark_qp_error(qp);
++ rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp);
++ spin_unlock(&rcfw->tbl_lock);
+ dev_dbg(&pdev->dev, "Received QP error notification\n");
+ dev_dbg(&pdev->dev,
+ "qpid 0x%x, req_err=0x%x, resp_err=0x%x\n",
+ qp_id, err_event->req_err_state_reason,
+ err_event->res_err_state_reason);
+- if (!qp)
+- break;
+- bnxt_qplib_mark_qp_error(qp);
+- rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp);
+ break;
+ default:
+ /*
+@@ -973,6 +977,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
+ GFP_KERNEL);
+ if (!rcfw->qp_tbl)
+ goto fail;
++ spin_lock_init(&rcfw->tbl_lock);
+
+ rcfw->max_timeout = res->cctx->hwrm_cmd_max_timeout;
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+index 45996e60a0d03..07779aeb75759 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+@@ -224,6 +224,8 @@ struct bnxt_qplib_rcfw {
+ struct bnxt_qplib_crsqe *crsqe_tbl;
+ int qp_tbl_size;
+ struct bnxt_qplib_qp_node *qp_tbl;
++ /* To synchronize the qp-handle hash table */
++ spinlock_t tbl_lock;
+ u64 oos_prev;
+ u32 init_oos_stats;
+ u32 cmdq_depth;
+--
+2.43.0
+
--- /dev/null
+From 514ed9a0880ee2890aa412a81d6c5cc3da52aa6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 20:55:17 +0300
+Subject: RDMA/cxgb4: Dump vendor specific QP details
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 89f8c6f197f480fe05edf91eb9359d5425869d04 ]
+
+Restore the missing functionality to dump vendor specific QP details,
+which was mistakenly removed in the commit mentioned in Fixes line.
+
+Fixes: 5cc34116ccec ("RDMA: Add dedicated QP resource tracker function")
+Link: https://patch.msgid.link/r/ed9844829135cfdcac7d64285688195a5cd43f82.1728323026.git.leonro@nvidia.com
+Reported-by: Dr. David Alan Gilbert <linux@treblig.org>
+Closes: https://lore.kernel.org/all/Zv_4qAxuC0dLmgXP@gallifrey
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/cxgb4/provider.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
+index 246b739ddb2b2..9008584946c62 100644
+--- a/drivers/infiniband/hw/cxgb4/provider.c
++++ b/drivers/infiniband/hw/cxgb4/provider.c
+@@ -474,6 +474,7 @@ static const struct ib_device_ops c4iw_dev_ops = {
+ .fill_res_cq_entry = c4iw_fill_res_cq_entry,
+ .fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry,
+ .fill_res_mr_entry = c4iw_fill_res_mr_entry,
++ .fill_res_qp_entry = c4iw_fill_res_qp_entry,
+ .get_dev_fw_str = get_dev_fw_str,
+ .get_dma_mr = c4iw_get_dma_mr,
+ .get_hw_stats = c4iw_get_mib,
+--
+2.43.0
+
--- /dev/null
+From 59fdbe612aacd207b0e25f8d2cade1f67f5b4c70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2024 11:50:23 +0300
+Subject: RDMA/mlx5: Round max_rd_atomic/max_dest_rd_atomic up instead of down
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit 78ed28e08e74da6265e49e19206e1bcb8b9a7f0d ]
+
+After the cited commit below max_dest_rd_atomic and max_rd_atomic values
+are being rounded down to the next power of 2. As opposed to the old
+behavior and mlx4 driver where they used to be rounded up instead.
+
+In order to stay consistent with older code and other drivers, revert to
+using fls round function which rounds up to the next power of 2.
+
+Fixes: f18e26af6aba ("RDMA/mlx5: Convert modify QP to use MLX5_SET macros")
+Link: https://patch.msgid.link/r/d85515d6ef21a2fa8ef4c8293dce9b58df8a6297.1728550179.git.leon@kernel.org
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Maher Sanalla <msanalla@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/qp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index e39b1a101e972..10ce3b44f645f 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -4268,14 +4268,14 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
+ MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt);
+
+ if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic)
+- MLX5_SET(qpc, qpc, log_sra_max, ilog2(attr->max_rd_atomic));
++ MLX5_SET(qpc, qpc, log_sra_max, fls(attr->max_rd_atomic - 1));
+
+ if (attr_mask & IB_QP_SQ_PSN)
+ MLX5_SET(qpc, qpc, next_send_psn, attr->sq_psn);
+
+ if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic)
+ MLX5_SET(qpc, qpc, log_rra_max,
+- ilog2(attr->max_dest_rd_atomic));
++ fls(attr->max_dest_rd_atomic - 1));
+
+ if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) {
+ err = set_qpc_atomic_flags(qp, attr, attr_mask, qpc);
+--
+2.43.0
+
--- /dev/null
+From 1ade9e261839a64fc167117f218c3c01cbdff0d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2024 09:22:11 +0200
+Subject: Revert "wifi: iwlwifi: remove retry loops in start"
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+[ Upstream commit bfc0ed73e095cc3858d35731f191fa6e3d813262 ]
+
+Revert commit dfdfe4be183b ("wifi: iwlwifi: remove retry loops in
+start"), it turns out that there's an issue with the PNVM load
+notification from firmware not getting processed, that this patch
+has been somewhat successfully papering over. Since this is being
+reported, revert the loop removal for now.
+
+We will later at least clean this up to only attempt to retry if
+there was a timeout, but currently we don't even bubble up the
+failure reason to the correct layer, only returning NULL.
+
+Fixes: dfdfe4be183b ("wifi: iwlwifi: remove retry loops in start")
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Link: https://patch.msgid.link/20241022092212.4aa82a558a00.Ibdeff9c8f0d608bc97fc42024392ae763b6937b7@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 28 +++++++++++++------
+ drivers/net/wireless/intel/iwlwifi/iwl-drv.h | 3 ++
+ .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 10 ++++++-
+ 3 files changed, 31 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+index aaaabd67f9593..3709039a294d8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+@@ -1413,25 +1413,35 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
+ const struct iwl_op_mode_ops *ops = op->ops;
+ struct dentry *dbgfs_dir = NULL;
+ struct iwl_op_mode *op_mode = NULL;
++ int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY;
+
+ /* also protects start/stop from racing against each other */
+ lockdep_assert_held(&iwlwifi_opmode_table_mtx);
+
++ for (retry = 0; retry <= max_retry; retry++) {
++
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+- drv->dbgfs_op_mode = debugfs_create_dir(op->name,
+- drv->dbgfs_drv);
+- dbgfs_dir = drv->dbgfs_op_mode;
++ drv->dbgfs_op_mode = debugfs_create_dir(op->name,
++ drv->dbgfs_drv);
++ dbgfs_dir = drv->dbgfs_op_mode;
+ #endif
+
+- op_mode = ops->start(drv->trans, drv->trans->cfg,
+- &drv->fw, dbgfs_dir);
+- if (op_mode)
+- return op_mode;
++ op_mode = ops->start(drv->trans, drv->trans->cfg,
++ &drv->fw, dbgfs_dir);
++
++ if (op_mode)
++ return op_mode;
++
++ if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status))
++ break;
++
++ IWL_ERR(drv, "retry init count %d\n", retry);
+
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+- debugfs_remove_recursive(drv->dbgfs_op_mode);
+- drv->dbgfs_op_mode = NULL;
++ debugfs_remove_recursive(drv->dbgfs_op_mode);
++ drv->dbgfs_op_mode = NULL;
+ #endif
++ }
+
+ return NULL;
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h
+index 1549ff4295497..6a1d31892417b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h
+@@ -98,6 +98,9 @@ void iwl_drv_stop(struct iwl_drv *drv);
+ #define VISIBLE_IF_IWLWIFI_KUNIT static
+ #endif
+
++/* max retry for init flow */
++#define IWL_MAX_INIT_RETRY 2
++
+ #define FW_NAME_PRE_BUFSIZE 64
+ struct iwl_trans;
+ const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf);
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index e38cff6176dd3..63b2c6fe3f8ab 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -1292,12 +1292,14 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)
+ {
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ int ret;
++ int retry, max_retry = 0;
+
+ mutex_lock(&mvm->mutex);
+
+ /* we are starting the mac not in error flow, and restart is enabled */
+ if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) &&
+ iwlwifi_mod_params.fw_restart) {
++ max_retry = IWL_MAX_INIT_RETRY;
+ /*
+ * This will prevent mac80211 recovery flows to trigger during
+ * init failures
+@@ -1305,7 +1307,13 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)
+ set_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
+ }
+
+- ret = __iwl_mvm_mac_start(mvm);
++ for (retry = 0; retry <= max_retry; retry++) {
++ ret = __iwl_mvm_mac_start(mvm);
++ if (!ret)
++ break;
++
++ IWL_ERR(mvm, "mac start retry %d\n", retry);
++ }
+ clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
+
+ mutex_unlock(&mvm->mutex);
+--
+2.43.0
+
perf-trace-fix-non-listed-archs-in-the-syscalltbl-ro.patch
perf-python-fix-up-the-build-on-architectures-withou.patch
scsi-scsi_debug-fix-do_device_access-handling-of-une.patch
+wifi-iwlegacy-fix-field-spanning-write-warning-in-il.patch
+mac80211-mac80211_message_tracing-should-depend-on-t.patch
+wifi-mac80211-skip-non-uploaded-keys-in-ieee80211_it.patch
+wifi-ath11k-fix-invalid-ring-usage-in-full-monitor-m.patch
+wifi-rtw89-pci-early-chips-only-enable-36-bit-dma-on.patch
+wifi-brcm80211-brcm_tracing-should-depend-on-tracing.patch
+rdma-cxgb4-dump-vendor-specific-qp-details.patch
+rdma-mlx5-round-max_rd_atomic-max_dest_rd_atomic-up-.patch
+rdma-bnxt_re-fix-the-usage-of-control-path-spin-lock.patch
+rdma-bnxt_re-synchronize-the-qp-handle-table-array.patch
+wifi-iwlwifi-mvm-don-t-leak-a-link-on-ap-removal.patch
+wifi-iwlwifi-mvm-really-send-iwl_txpower_constraints.patch
+wifi-iwlwifi-mvm-fix-response-handling-in-iwl_mvm_se.patch
+wifi-iwlwifi-mvm-don-t-add-default-link-in-fw-restar.patch
+revert-wifi-iwlwifi-remove-retry-loops-in-start.patch
+asoc-cs42l51-fix-some-error-handling-paths-in-cs42l5.patch
+macsec-fix-use-after-free-while-sending-the-offloadi.patch
+asoc-dapm-fix-bounds-checker-error-in-dapm_widget_li.patch
+sock_map-fix-a-null-pointer-dereference-in-sock_map_.patch
+net-stmmac-dwmac4-fix-high-address-display-by-updati.patch
+net-stmmac-tso-fix-unbalanced-dma-map-unmap-for-non-.patch
+igb-disable-threaded-irq-for-igb_msix_other.patch
+dpll-add-embedded-sync-feature-for-a-pin.patch
+ice-add-callbacks-for-embedded-sync-enablement-on-dp.patch
+ice-fix-crash-on-probe-for-dpll-enabled-e810-lom.patch
+ipv4-ip_tunnel-fix-suspicious-rcu-usage-warning-in-i.patch
+ipv4-ip_tunnel-fix-suspicious-rcu-usage-warning-in-i.patch-3951
+gtp-allow-1-to-be-specified-as-file-description-from.patch
+net-sched-stop-qdisc_tree_reduce_backlog-on-tc_h_roo.patch
+bpf-force-checkpoint-when-jmp-history-is-too-long.patch
+netdevsim-add-trailing-zero-to-terminate-the-string-.patch
+net-sched-sch_api-fix-xa_insert-error-path-in-tcf_bl.patch
+bpf-fix-out-of-bounds-write-in-trie_get_next_key.patch
+net-fix-crash-when-config-small-gso_max_size-gso_ipv.patch
+netfilter-fix-use-after-free-in-get_info.patch
+netfilter-nf_reject_ipv6-fix-potential-crash-in-nf_s.patch
+bluetooth-hci-fix-null-ptr-deref-in-hci_read_support.patch
+bpf-free-dynamically-allocated-bits-in-bpf_iter_bits.patch
+bpf-add-bpf_mem_alloc_check_size-helper.patch
+bpf-check-the-validity-of-nr_words-in-bpf_iter_bits_.patch
+net-skip-offload-for-netif_f_ipv6_csum-if-ipv6-heade.patch
+mlxsw-spectrum_ptp-add-missing-verification-before-p.patch
+mlxsw-pci-sync-rx-buffers-for-cpu.patch
+mlxsw-pci-sync-rx-buffers-for-device.patch
+mlxsw-spectrum_ipip-fix-memory-leak-when-changing-re.patch
+net-ethernet-mtk_wed-fix-path-of-mt7988-wo-firmware.patch
+netfilter-nft_payload-sanitize-offset-and-length-bef.patch
+net-hns3-default-enable-tx-bounce-buffer-when-smmu-e.patch
+net-hns3-add-sync-command-to-sync-io-pgtable.patch
+net-hns3-fixed-reset-failure-issues-caused-by-the-in.patch
+net-hns3-fix-missing-features-due-to-dev-features-co.patch
+net-hns3-resolved-the-issue-that-the-debugfs-query-r.patch
+net-hns3-don-t-auto-enable-misc-vector.patch
+net-hns3-initialize-reset_timer-before-hclgevf_misc_.patch
+net-hns3-fixed-hclge_fetch_pf_reg-accesses-bar-space.patch
+net-hns3-fix-kernel-crash-when-1588-is-sent-on-hip08.patch
+bpf-test_run-fix-live_frame-frame-update-after-a-pag.patch
--- /dev/null
+From 58dbfe028aaf957aebbc0a0979a5a2c6b909404b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Oct 2024 11:55:22 -0700
+Subject: sock_map: fix a NULL pointer dereference in
+ sock_map_link_update_prog()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 740be3b9a6d73336f8c7d540842d0831dc7a808b ]
+
+The following race condition could trigger a NULL pointer dereference:
+
+sock_map_link_detach(): sock_map_link_update_prog():
+ mutex_lock(&sockmap_mutex);
+ ...
+ sockmap_link->map = NULL;
+ mutex_unlock(&sockmap_mutex);
+ mutex_lock(&sockmap_mutex);
+ ...
+ sock_map_prog_link_lookup(sockmap_link->map);
+ mutex_unlock(&sockmap_mutex);
+ <continue>
+
+Fix it by adding a NULL pointer check. In this specific case, it makes
+no sense to update a link which is being released.
+
+Reported-by: Ruan Bonan <bonan.ruan@u.nus.edu>
+Fixes: 699c23f02c65 ("bpf: Add bpf_link support for sk_msg and sk_skb progs")
+Cc: Yonghong Song <yonghong.song@linux.dev>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Jakub Sitnicki <jakub@cloudflare.com>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Link: https://lore.kernel.org/r/20241026185522.338562-1-xiyou.wangcong@gmail.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 219fd8f1ca2a4..0550837775d5e 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -1771,6 +1771,10 @@ static int sock_map_link_update_prog(struct bpf_link *link,
+ ret = -EINVAL;
+ goto out;
+ }
++ if (!sockmap_link->map) {
++ ret = -ENOLINK;
++ goto out;
++ }
+
+ ret = sock_map_prog_link_lookup(sockmap_link->map, &pprog, &plink,
+ sockmap_link->attach_type);
+--
+2.43.0
+
--- /dev/null
+From a8e7d7c85d66458cd00adb550f4162c2e38d4c32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Sep 2024 21:41:19 +0200
+Subject: wifi: ath11k: Fix invalid ring usage in full monitor mode
+
+From: Remi Pommarel <repk@triplefau.lt>
+
+[ Upstream commit befd716ed429b26eca7abde95da6195c548470de ]
+
+On full monitor HW the monitor destination rxdma ring does not have the
+same descriptor format as in the "classical" mode. The full monitor
+destination entries are of hal_sw_monitor_ring type and fetched using
+ath11k_dp_full_mon_process_rx while the classical ones are of type
+hal_reo_entrance_ring and fetched with ath11k_dp_rx_mon_dest_process.
+
+Although both hal_sw_monitor_ring and hal_reo_entrance_ring are of same
+size, the offset to useful info (such as sw_cookie, paddr, etc) are
+different. Thus if ath11k_dp_rx_mon_dest_process gets called on full
+monitor destination ring, invalid skb buffer id will be fetched from DMA
+ring causing issues such as the following rcu_sched stall:
+
+ rcu: INFO: rcu_sched self-detected stall on CPU
+ rcu: 0-....: (1 GPs behind) idle=c67/0/0x7 softirq=45768/45769 fqs=1012
+ (t=2100 jiffies g=14817 q=8703)
+ Task dump for CPU 0:
+ task:swapper/0 state:R running task stack: 0 pid: 0 ppid: 0 flags:0x0000000a
+ Call trace:
+ dump_backtrace+0x0/0x160
+ show_stack+0x14/0x20
+ sched_show_task+0x158/0x184
+ dump_cpu_task+0x40/0x4c
+ rcu_dump_cpu_stacks+0xec/0x12c
+ rcu_sched_clock_irq+0x6c8/0x8a0
+ update_process_times+0x88/0xd0
+ tick_sched_timer+0x74/0x1e0
+ __hrtimer_run_queues+0x150/0x204
+ hrtimer_interrupt+0xe4/0x240
+ arch_timer_handler_phys+0x30/0x40
+ handle_percpu_devid_irq+0x80/0x130
+ handle_domain_irq+0x5c/0x90
+ gic_handle_irq+0x8c/0xb4
+ do_interrupt_handler+0x30/0x54
+ el1_interrupt+0x2c/0x4c
+ el1h_64_irq_handler+0x14/0x1c
+ el1h_64_irq+0x74/0x78
+ do_raw_spin_lock+0x60/0x100
+ _raw_spin_lock_bh+0x1c/0x2c
+ ath11k_dp_rx_mon_mpdu_pop.constprop.0+0x174/0x650
+ ath11k_dp_rx_process_mon_status+0x8b4/0xa80
+ ath11k_dp_rx_process_mon_rings+0x244/0x510
+ ath11k_dp_service_srng+0x190/0x300
+ ath11k_pcic_ext_grp_napi_poll+0x30/0xc0
+ __napi_poll+0x34/0x174
+ net_rx_action+0xf8/0x2a0
+ _stext+0x12c/0x2ac
+ irq_exit+0x94/0xc0
+ handle_domain_irq+0x60/0x90
+ gic_handle_irq+0x8c/0xb4
+ call_on_irq_stack+0x28/0x44
+ do_interrupt_handler+0x4c/0x54
+ el1_interrupt+0x2c/0x4c
+ el1h_64_irq_handler+0x14/0x1c
+ el1h_64_irq+0x74/0x78
+ arch_cpu_idle+0x14/0x20
+ do_idle+0xf0/0x130
+ cpu_startup_entry+0x24/0x50
+ rest_init+0xf8/0x104
+ arch_call_rest_init+0xc/0x14
+ start_kernel+0x56c/0x58c
+ __primary_switched+0xa0/0xa8
+
+Thus ath11k_dp_rx_mon_dest_process(), which use classical destination
+entry format, should no be called on full monitor capable HW.
+
+Fixes: 67a9d399fcb0 ("ath11k: enable RX PPDU stats in monitor co-exist mode")
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Reviewed-by: Praneesh P <quic_ppranees@quicinc.com>
+Link: https://patch.msgid.link/20240924194119.15942-1-repk@triplefau.lt
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index c087d8a0f5b25..40088e62572e1 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -5291,8 +5291,11 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
+ hal_status == HAL_TLV_STATUS_PPDU_DONE) {
+ rx_mon_stats->status_ppdu_done++;
+ pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE;
+- ath11k_dp_rx_mon_dest_process(ar, mac_id, budget, napi);
+- pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
++ if (!ab->hw_params.full_monitor_mode) {
++ ath11k_dp_rx_mon_dest_process(ar, mac_id,
++ budget, napi);
++ pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
++ }
+ }
+
+ if (ppdu_info->peer_id == HAL_INVALID_PEERID ||
+--
+2.43.0
+
--- /dev/null
+From c89f26046a64a1e141974bee6dd9131e3d6ee5cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Sep 2024 14:09:32 +0200
+Subject: wifi: brcm80211: BRCM_TRACING should depend on TRACING
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+[ Upstream commit b73b2069528f90ec49d5fa1010a759baa2c2be05 ]
+
+When tracing is disabled, there is no point in asking the user about
+enabling Broadcom wireless device tracing.
+
+Fixes: f5c4f10852d42012 ("brcm80211: Allow trace support to be enabled separately from debug")
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://patch.msgid.link/81a29b15eaacc1ac1fb421bdace9ac0c3385f40f.1727179742.git.geert@linux-m68k.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/Kconfig b/drivers/net/wireless/broadcom/brcm80211/Kconfig
+index 3a1a35b5672f1..19d0c003f6262 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
++++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
+@@ -27,6 +27,7 @@ source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig"
+ config BRCM_TRACING
+ bool "Broadcom device tracing"
+ depends on BRCMSMAC || BRCMFMAC
++ depends on TRACING
+ help
+ If you say Y here, the Broadcom wireless drivers will register
+ with ftrace to dump event information into the trace ringbuffer.
+--
+2.43.0
+
--- /dev/null
+From c387be68798b4586d32e645df08179bafe375b5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 01:01:21 +0200
+Subject: wifi: iwlegacy: Fix "field-spanning write" warning in
+ il_enqueue_hcmd()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ Upstream commit d4cdc46ca16a5c78b36c5b9b6ad8cac09d6130a0 ]
+
+iwlegacy uses command buffers with a payload size of 320
+bytes (default) or 4092 bytes (huge). The struct il_device_cmd type
+describes the default buffers and there is no separate type describing
+the huge buffers.
+
+The il_enqueue_hcmd() function works with both default and huge
+buffers, and has a memcpy() to the buffer payload. The size of
+this copy may exceed 320 bytes when using a huge buffer, which
+now results in a run-time warning:
+
+ memcpy: detected field-spanning write (size 1014) of single field "&out_cmd->cmd.payload" at drivers/net/wireless/intel/iwlegacy/common.c:3170 (size 320)
+
+To fix this:
+
+- Define a new struct type for huge buffers, with a correctly sized
+ payload field
+- When using a huge buffer in il_enqueue_hcmd(), cast the command
+ buffer pointer to that type when looking up the payload field
+
+Reported-by: Martin-Éric Racine <martin-eric.racine@iki.fi>
+References: https://bugs.debian.org/1062421
+References: https://bugzilla.kernel.org/show_bug.cgi?id=219124
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Fixes: 54d9469bc515 ("fortify: Add run-time WARN for cross-field memcpy()")
+Tested-by: Martin-Éric Racine <martin-eric.racine@iki.fi>
+Tested-by: Brandon Nielsen <nielsenb@jetfuse.net>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://patch.msgid.link/ZuIhQRi/791vlUhE@decadent.org.uk
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlegacy/common.c | 13 ++++++++++++-
+ drivers/net/wireless/intel/iwlegacy/common.h | 12 ++++++++++++
+ 2 files changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
+index 9d33a66a49b59..4616293ec0cf4 100644
+--- a/drivers/net/wireless/intel/iwlegacy/common.c
++++ b/drivers/net/wireless/intel/iwlegacy/common.c
+@@ -3122,6 +3122,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
+ struct il_cmd_meta *out_meta;
+ dma_addr_t phys_addr;
+ unsigned long flags;
++ u8 *out_payload;
+ u32 idx;
+ u16 fix_size;
+
+@@ -3157,6 +3158,16 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
+ out_cmd = txq->cmd[idx];
+ out_meta = &txq->meta[idx];
+
++ /* The payload is in the same place in regular and huge
++ * command buffers, but we need to let the compiler know when
++ * we're using a larger payload buffer to avoid "field-
++ * spanning write" warnings at run-time for huge commands.
++ */
++ if (cmd->flags & CMD_SIZE_HUGE)
++ out_payload = ((struct il_device_cmd_huge *)out_cmd)->cmd.payload;
++ else
++ out_payload = out_cmd->cmd.payload;
++
+ if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
+ spin_unlock_irqrestore(&il->hcmd_lock, flags);
+ return -ENOSPC;
+@@ -3170,7 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
+ out_meta->callback = cmd->callback;
+
+ out_cmd->hdr.cmd = cmd->id;
+- memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
++ memcpy(out_payload, cmd->data, cmd->len);
+
+ /* At this point, the out_cmd now has all of the incoming cmd
+ * information */
+diff --git a/drivers/net/wireless/intel/iwlegacy/common.h b/drivers/net/wireless/intel/iwlegacy/common.h
+index 69687fcf963fc..027dae5619a37 100644
+--- a/drivers/net/wireless/intel/iwlegacy/common.h
++++ b/drivers/net/wireless/intel/iwlegacy/common.h
+@@ -560,6 +560,18 @@ struct il_device_cmd {
+
+ #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct il_device_cmd))
+
++/**
++ * struct il_device_cmd_huge
++ *
++ * For use when sending huge commands.
++ */
++struct il_device_cmd_huge {
++ struct il_cmd_header hdr; /* uCode API */
++ union {
++ u8 payload[IL_MAX_CMD_SIZE - sizeof(struct il_cmd_header)];
++ } __packed cmd;
++} __packed;
++
+ struct il_host_cmd {
+ const void *data;
+ unsigned long reply_page;
+--
+2.43.0
+
--- /dev/null
+From 863d8f0b4dc077dbf08f2b03eaf71100105c9d8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2024 14:05:06 +0300
+Subject: wifi: iwlwifi: mvm: don't add default link in fw restart flow
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+[ Upstream commit 734a377e1eacc5153bae0ccd4423365726876e93 ]
+
+When we add the vif (and its default link) in fw restart we may
+override the link that already exists. We take care of this but if
+link 0 is a valid MLO link, then we will re-create a default link on
+mvmvif->link[0] and we'll loose the real link we had there.
+
+In non-MLO, we need to re-create the default link upon the interface
+creation, this is fine. In MLO, we'll just wait for change_vif_links()
+to re-build the links.
+
+Fixes: bf976c814c86 ("wifi: iwlwifi: mvm: implement link change ops")
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20241010140328.385bfea1b2e9.I4a127312285ccb529cc95cc4edf6fbe1e0a136ad@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/intel/iwlwifi/mvm/mld-mac80211.c | 24 ++++++++++++++-----
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+index 27980d58e6956..c4ccc353a8fd4 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+@@ -41,8 +41,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
+ /* reset deflink MLO parameters */
+ mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;
+ mvmvif->deflink.active = 0;
+- /* the first link always points to the default one */
+- mvmvif->link[0] = &mvmvif->deflink;
+
+ ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif);
+ if (ret)
+@@ -60,9 +58,19 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
+ IEEE80211_VIF_SUPPORTS_CQM_RSSI;
+ }
+
+- ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf);
+- if (ret)
+- goto out_free_bf;
++ /* We want link[0] to point to the default link, unless we have MLO and
++ * in this case this will be modified later by .change_vif_links()
++ * If we are in the restart flow with an MLD connection, we will wait
++ * to .change_vif_links() to setup the links.
++ */
++ if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
++ !ieee80211_vif_is_mld(vif)) {
++ mvmvif->link[0] = &mvmvif->deflink;
++
++ ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf);
++ if (ret)
++ goto out_free_bf;
++ }
+
+ /* Save a pointer to p2p device vif, so it can later be used to
+ * update the p2p device MAC when a GO is started/stopped
+@@ -1188,7 +1196,11 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw,
+
+ mutex_lock(&mvm->mutex);
+
+- if (old_links == 0) {
++ /* If we're in RESTART flow, the default link wasn't added in
++ * drv_add_interface(), and link[0] doesn't point to it.
++ */
++ if (old_links == 0 && !test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
++ &mvm->status)) {
+ err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf);
+ if (err)
+ goto out_err;
+--
+2.43.0
+
--- /dev/null
+From b11e799aebcd9c4c52612bc92d144ea1909518f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2024 14:04:59 +0300
+Subject: wifi: iwlwifi: mvm: don't leak a link on AP removal
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+[ Upstream commit 3ed092997a004d68a3a5b0eeb94e71b69839d0f7 ]
+
+Release the link mapping resource in AP removal. This impacted devices
+that do not support the MLD API (9260 and down).
+On those devices, we couldn't start the AP again after the AP has been
+already started and stopped.
+
+Fixes: a8b5d4809b50 ("wifi: iwlwifi: mvm: Configure the link mapping for non-MLD FW")
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20241010140328.c54c42779882.Ied79e0d6244dc5a372e8b6ffa8ee9c6e1379ec1d@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index 1ebcc6417ecef..e38cff6176dd3 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -1951,7 +1951,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
+ mvm->p2p_device_vif = NULL;
+ }
+
+- iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
+ iwl_mvm_mac_ctxt_remove(mvm, vif);
+
+ RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL);
+@@ -1960,6 +1959,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
+ mvm->monitor_on = false;
+
+ out:
++ iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
+ if (vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_ADHOC) {
+ iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta);
+--
+2.43.0
+
--- /dev/null
+From a5d0769515e729a733fc72883d4dc24cffda45d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2024 14:05:05 +0300
+Subject: wifi: iwlwifi: mvm: Fix response handling in
+ iwl_mvm_send_recovery_cmd()
+
+From: Daniel Gabay <daniel.gabay@intel.com>
+
+[ Upstream commit 07a6e3b78a65f4b2796a8d0d4adb1a15a81edead ]
+
+1. The size of the response packet is not validated.
+2. The response buffer is not freed.
+
+Resolve these issues by switching to iwl_mvm_send_cmd_status(),
+which handles both size validation and frees the buffer.
+
+Fixes: f130bb75d881 ("iwlwifi: add FW recovery flow")
+Signed-off-by: Daniel Gabay <daniel.gabay@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20241010140328.76c73185951e.Id3b6ca82ced2081f5ee4f33c997491d0ebda83f7@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+index 08c4898c8f1a3..49d5278d078a5 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+@@ -1288,8 +1288,8 @@ static void iwl_mvm_disconnect_iterator(void *data, u8 *mac,
+ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
+ {
+ u32 error_log_size = mvm->fw->ucode_capa.error_log_size;
++ u32 status = 0;
+ int ret;
+- u32 resp;
+
+ struct iwl_fw_error_recovery_cmd recovery_cmd = {
+ .flags = cpu_to_le32(flags),
+@@ -1297,7 +1297,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
+ };
+ struct iwl_host_cmd host_cmd = {
+ .id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD),
+- .flags = CMD_WANT_SKB,
+ .data = {&recovery_cmd, },
+ .len = {sizeof(recovery_cmd), },
+ };
+@@ -1317,7 +1316,7 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
+ recovery_cmd.buf_size = cpu_to_le32(error_log_size);
+ }
+
+- ret = iwl_mvm_send_cmd(mvm, &host_cmd);
++ ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status);
+ kfree(mvm->error_recovery_buf);
+ mvm->error_recovery_buf = NULL;
+
+@@ -1328,11 +1327,10 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
+
+ /* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */
+ if (flags & ERROR_RECOVERY_UPDATE_DB) {
+- resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data);
+- if (resp) {
++ if (status) {
+ IWL_ERR(mvm,
+ "Failed to send recovery cmd blob was invalid %d\n",
+- resp);
++ status);
+
+ ieee80211_iterate_interfaces(mvm->hw, 0,
+ iwl_mvm_disconnect_iterator,
+--
+2.43.0
+
--- /dev/null
+From 1b43ee378f071e91273a6daa09914871ba8b22b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2024 14:05:01 +0300
+Subject: wifi: iwlwifi: mvm: really send iwl_txpower_constraints_cmd
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit cbe84e9ad5e28ef083beff7f6edf2e623fac09e4 ]
+
+iwl_mvm_send_ap_tx_power_constraint_cmd is a no-op if the link is not
+active (we need to know the band etc.)
+However, for the station case it will be called just before we set the
+link to active (by calling iwl_mvm_link_changed with
+the LINK_CONTEXT_MODIFY_ACTIVE bit set in the 'changed' flags and
+active = true), so it will end up doing nothing.
+
+Fix this by calling iwl_mvm_send_ap_tx_power_constraint_cmd before
+iwl_mvm_link_changed.
+
+Fixes: 6b82f4e119d1 ("wifi: iwlwifi: mvm: handle TPE advertised by AP")
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20241010140328.5c235fccd3f1.I2d40dea21e5547eba458565edcb4c354d094d82a@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+index 3c99396ad3692..27980d58e6956 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+@@ -347,11 +347,6 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
+ rcu_read_unlock();
+ }
+
+- if (vif->type == NL80211_IFTYPE_STATION)
+- iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif,
+- link_conf,
+- false);
+-
+ /* then activate */
+ ret = iwl_mvm_link_changed(mvm, vif, link_conf,
+ LINK_CONTEXT_MODIFY_ACTIVE |
+@@ -360,6 +355,11 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
+ if (ret)
+ goto out;
+
++ if (vif->type == NL80211_IFTYPE_STATION)
++ iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif,
++ link_conf,
++ false);
++
+ /*
+ * Power state must be updated before quotas,
+ * otherwise fw will complain.
+--
+2.43.0
+
--- /dev/null
+From 995e0cf9c8c34f6daa91ea4665f3a8e9085a1768 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Oct 2024 17:36:30 +0200
+Subject: wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 52009b419355195912a628d0a9847922e90c348c ]
+
+Sync iterator conditions with ieee80211_iter_keys_rcu.
+
+Fixes: 830af02f24fb ("mac80211: allow driver to iterate keys")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://patch.msgid.link/20241006153630.87885-1-nbd@nbd.name
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/key.c | 42 +++++++++++++++++++++++++-----------------
+ 1 file changed, 25 insertions(+), 17 deletions(-)
+
+diff --git a/net/mac80211/key.c b/net/mac80211/key.c
+index eecdd2265eaa6..e45b5f56c4055 100644
+--- a/net/mac80211/key.c
++++ b/net/mac80211/key.c
+@@ -987,6 +987,26 @@ void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata)
+ }
+ }
+
++static void
++ieee80211_key_iter(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct ieee80211_key *key,
++ void (*iter)(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct ieee80211_sta *sta,
++ struct ieee80211_key_conf *key,
++ void *data),
++ void *iter_data)
++{
++ /* skip keys of station in removal process */
++ if (key->sta && key->sta->removed)
++ return;
++ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
++ return;
++ iter(hw, vif, key->sta ? &key->sta->sta : NULL,
++ &key->conf, iter_data);
++}
++
+ void ieee80211_iter_keys(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ void (*iter)(struct ieee80211_hw *hw,
+@@ -1005,16 +1025,13 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,
+ if (vif) {
+ sdata = vif_to_sdata(vif);
+ list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
+- iter(hw, &sdata->vif,
+- key->sta ? &key->sta->sta : NULL,
+- &key->conf, iter_data);
++ ieee80211_key_iter(hw, vif, key, iter, iter_data);
+ } else {
+ list_for_each_entry(sdata, &local->interfaces, list)
+ list_for_each_entry_safe(key, tmp,
+ &sdata->key_list, list)
+- iter(hw, &sdata->vif,
+- key->sta ? &key->sta->sta : NULL,
+- &key->conf, iter_data);
++ ieee80211_key_iter(hw, &sdata->vif, key,
++ iter, iter_data);
+ }
+ }
+ EXPORT_SYMBOL(ieee80211_iter_keys);
+@@ -1031,17 +1048,8 @@ _ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
+ {
+ struct ieee80211_key *key;
+
+- list_for_each_entry_rcu(key, &sdata->key_list, list) {
+- /* skip keys of station in removal process */
+- if (key->sta && key->sta->removed)
+- continue;
+- if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
+- continue;
+-
+- iter(hw, &sdata->vif,
+- key->sta ? &key->sta->sta : NULL,
+- &key->conf, iter_data);
+- }
++ list_for_each_entry_rcu(key, &sdata->key_list, list)
++ ieee80211_key_iter(hw, &sdata->vif, key, iter, iter_data);
+ }
+
+ void ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
+--
+2.43.0
+
--- /dev/null
+From dadb29fa3c79754f559b7d7ad70b0186fe5f7c21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Sep 2024 10:16:33 +0800
+Subject: wifi: rtw89: pci: early chips only enable 36-bit DMA on specific PCI
+ hosts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit aa70ff0945fea2ed14046273609d04725f222616 ]
+
+The early chips including RTL8852A, RTL8851B, RTL8852B and RTL8852BT have
+interoperability problems of 36-bit DMA with some PCI hosts. Rollback
+to 32-bit DMA by default, and only enable 36-bit DMA for tested platforms.
+
+Since all Intel platforms we have can work correctly, add the vendor ID to
+white list. Otherwise, list vendor/device ID of bridge we have tested.
+
+Fixes: 1fd4b3fe52ef ("wifi: rtw89: pci: support 36-bit PCI DMA address")
+Reported-by: Marcel Weißenbach <mweissenbach@ignaz.org>
+Closes: https://lore.kernel.org/linux-wireless/20240918073237.Horde.VLueh0_KaiDw-9asEEcdM84@ignaz.org/T/#m07c5694df1acb173a42e1a0bab7ac22bd231a2b8
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Tested-by: Marcel Weißenbach <mweissenbach@ignaz.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://patch.msgid.link/20240924021633.19861-1-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/pci.c | 48 ++++++++++++++++++++----
+ 1 file changed, 41 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
+index 02afeb3acce46..5aef7fa378788 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.c
++++ b/drivers/net/wireless/realtek/rtw89/pci.c
+@@ -3026,24 +3026,54 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev,
+ pci_disable_device(pdev);
+ }
+
+-static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
++static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev)
+ {
+- struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+- if (!rtwpci->enable_dac)
+- return;
+-
+ switch (chip->chip_id) {
+ case RTL8852A:
+ case RTL8852B:
+ case RTL8851B:
+ case RTL8852BT:
+- break;
++ return true;
+ default:
+- return;
++ return false;
++ }
++}
++
++static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
++{
++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
++ struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev);
++
++ if (!rtw89_pci_chip_is_manual_dac(rtwdev))
++ return true;
++
++ if (!bridge)
++ return false;
++
++ switch (bridge->vendor) {
++ case PCI_VENDOR_ID_INTEL:
++ return true;
++ case PCI_VENDOR_ID_ASMEDIA:
++ if (bridge->device == 0x2806)
++ return true;
++ break;
+ }
+
++ return false;
++}
++
++static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
++{
++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
++
++ if (!rtwpci->enable_dac)
++ return;
++
++ if (!rtw89_pci_chip_is_manual_dac(rtwdev))
++ return;
++
+ rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS);
+ }
+
+@@ -3061,6 +3091,9 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
+ goto err;
+ }
+
++ if (!rtw89_pci_is_dac_compatible_bridge(rtwdev))
++ goto no_dac;
++
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
+ if (!ret) {
+ rtwpci->enable_dac = true;
+@@ -3073,6 +3106,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
+ goto err_release_regions;
+ }
+ }
++no_dac:
+
+ resource_len = pci_resource_len(pdev, bar_id);
+ rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len);
+--
+2.43.0
+