From: Sasha Levin Date: Sun, 24 Sep 2023 19:27:45 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v6.5.6~100 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5685195141997b93cb43ecd5dea974a83344469c;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/asoc-imx-audmix-fix-return-error-with-devm_clk_get.patch b/queue-5.4/asoc-imx-audmix-fix-return-error-with-devm_clk_get.patch new file mode 100644 index 00000000000..20b48ae1894 --- /dev/null +++ b/queue-5.4/asoc-imx-audmix-fix-return-error-with-devm_clk_get.patch @@ -0,0 +1,41 @@ +From 8ae5e97fc86b6a895cb27f24ed01d8267b99c36e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 14:02:11 +0800 +Subject: ASoC: imx-audmix: Fix return error with devm_clk_get() + +From: Shengjiu Wang + +[ Upstream commit b19a5733de255cabba5feecabf6e900638b582d1 ] + +The devm_clk_get() can return -EPROBE_DEFER error, +modify the error code to be -EINVAL is not correct, which +cause the -EPROBE_DEFER error is not correctly handled. + +This patch is to fix the return error code. + +Fixes: b86ef5367761 ("ASoC: fsl: Add Audio Mixer machine driver") +Signed-off-by: Shengjiu Wang +Reviewed-by: Daniel Baluta +Link: https://lore.kernel.org/r/1694757731-18308-1-git-send-email-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/imx-audmix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c +index 08c044a72250a..119a3a9684f51 100644 +--- a/sound/soc/fsl/imx-audmix.c ++++ b/sound/soc/fsl/imx-audmix.c +@@ -322,7 +322,7 @@ static int imx_audmix_probe(struct platform_device *pdev) + if (IS_ERR(priv->cpu_mclk)) { + ret = PTR_ERR(priv->cpu_mclk); + dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret); +- return -EINVAL; ++ return ret; + } + + priv->audmix_pdev = audmix_pdev; +-- +2.40.1 + diff --git a/queue-5.4/asoc-meson-spdifin-start-hw-on-dai-probe.patch b/queue-5.4/asoc-meson-spdifin-start-hw-on-dai-probe.patch new file mode 100644 index 00000000000..db2f4613fb3 --- /dev/null +++ b/queue-5.4/asoc-meson-spdifin-start-hw-on-dai-probe.patch @@ -0,0 +1,107 @@ +From 768cd64b13ae9c671587914fa9999539e41f713b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 11:05:04 +0200 +Subject: ASoC: meson: spdifin: start hw on dai probe + +From: Jerome Brunet + +[ Upstream commit aedf323b66b2b875137422ecb7d2525179759076 ] + +For spdif input to report the locked rate correctly, even when no capture +is running, the HW and reference clock must be started as soon as +the dai is probed. + +Fixes: 5ce5658375e6 ("ASoC: meson: add axg spdif input") +Signed-off-by: Jerome Brunet +Link: https://lore.kernel.org/r/20230907090504.12700-1-jbrunet@baylibre.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/meson/axg-spdifin.c | 49 ++++++++++++----------------------- + 1 file changed, 17 insertions(+), 32 deletions(-) + +diff --git a/sound/soc/meson/axg-spdifin.c b/sound/soc/meson/axg-spdifin.c +index d0d09f945b489..7aaded1fc376b 100644 +--- a/sound/soc/meson/axg-spdifin.c ++++ b/sound/soc/meson/axg-spdifin.c +@@ -112,34 +112,6 @@ static int axg_spdifin_prepare(struct snd_pcm_substream *substream, + return 0; + } + +-static int axg_spdifin_startup(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai) +-{ +- struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); +- int ret; +- +- ret = clk_prepare_enable(priv->refclk); +- if (ret) { +- dev_err(dai->dev, +- "failed to enable spdifin reference clock\n"); +- return ret; +- } +- +- regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, +- SPDIFIN_CTRL0_EN); +- +- return 0; +-} +- +-static void axg_spdifin_shutdown(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai) +-{ +- struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); +- +- regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); +- clk_disable_unprepare(priv->refclk); +-} +- + static void axg_spdifin_write_mode_param(struct regmap *map, int mode, + unsigned int val, + unsigned int num_per_reg, +@@ -251,25 +223,38 @@ static int axg_spdifin_dai_probe(struct snd_soc_dai *dai) + ret = axg_spdifin_sample_mode_config(dai, priv); + if (ret) { + dev_err(dai->dev, "mode configuration failed\n"); +- clk_disable_unprepare(priv->pclk); +- return ret; ++ goto pclk_err; + } + ++ ret = clk_prepare_enable(priv->refclk); ++ if (ret) { ++ dev_err(dai->dev, ++ "failed to enable spdifin reference clock\n"); ++ goto pclk_err; ++ } ++ ++ regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, ++ SPDIFIN_CTRL0_EN); ++ + return 0; ++ ++pclk_err: ++ clk_disable_unprepare(priv->pclk); ++ return ret; + } + + static int axg_spdifin_dai_remove(struct snd_soc_dai *dai) + { + struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); + ++ regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); ++ clk_disable_unprepare(priv->refclk); + clk_disable_unprepare(priv->pclk); + return 0; + } + + static const struct snd_soc_dai_ops axg_spdifin_ops = { + .prepare = axg_spdifin_prepare, +- .startup = axg_spdifin_startup, +- .shutdown = axg_spdifin_shutdown, + }; + + static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol, +-- +2.40.1 + diff --git a/queue-5.4/bpf-avoid-deadlock-when-using-queue-and-stack-maps-f.patch b/queue-5.4/bpf-avoid-deadlock-when-using-queue-and-stack-maps-f.patch new file mode 100644 index 00000000000..d478678a6dc --- /dev/null +++ b/queue-5.4/bpf-avoid-deadlock-when-using-queue-and-stack-maps-f.patch @@ -0,0 +1,79 @@ +From 884a4db9c4b6509d0fb5ff9ada013573fb00686c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 15:28:14 +0200 +Subject: bpf: Avoid deadlock when using queue and stack maps from NMI +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit a34a9f1a19afe9c60ca0ea61dfeee63a1c2baac8 ] + +Sysbot discovered that the queue and stack maps can deadlock if they are +being used from a BPF program that can be called from NMI context (such as +one that is attached to a perf HW counter event). To fix this, add an +in_nmi() check and use raw_spin_trylock() in NMI context, erroring out if +grabbing the lock fails. + +Fixes: f1a2e44a3aec ("bpf: add queue and stack maps") +Reported-by: Hsin-Wei Hung +Tested-by: Hsin-Wei Hung +Co-developed-by: Hsin-Wei Hung +Signed-off-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/20230911132815.717240-1-toke@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/queue_stack_maps.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c +index f697647ceb547..26ba7cb01136c 100644 +--- a/kernel/bpf/queue_stack_maps.c ++++ b/kernel/bpf/queue_stack_maps.c +@@ -118,7 +118,12 @@ static int __queue_map_get(struct bpf_map *map, void *value, bool delete) + int err = 0; + void *ptr; + +- raw_spin_lock_irqsave(&qs->lock, flags); ++ if (in_nmi()) { ++ if (!raw_spin_trylock_irqsave(&qs->lock, flags)) ++ return -EBUSY; ++ } else { ++ raw_spin_lock_irqsave(&qs->lock, flags); ++ } + + if (queue_stack_map_is_empty(qs)) { + memset(value, 0, qs->map.value_size); +@@ -148,7 +153,12 @@ static int __stack_map_get(struct bpf_map *map, void *value, bool delete) + void *ptr; + u32 index; + +- raw_spin_lock_irqsave(&qs->lock, flags); ++ if (in_nmi()) { ++ if (!raw_spin_trylock_irqsave(&qs->lock, flags)) ++ return -EBUSY; ++ } else { ++ raw_spin_lock_irqsave(&qs->lock, flags); ++ } + + if (queue_stack_map_is_empty(qs)) { + memset(value, 0, qs->map.value_size); +@@ -213,7 +223,12 @@ static int queue_stack_map_push_elem(struct bpf_map *map, void *value, + if (flags & BPF_NOEXIST || flags > BPF_EXIST) + return -EINVAL; + +- raw_spin_lock_irqsave(&qs->lock, irq_flags); ++ if (in_nmi()) { ++ if (!raw_spin_trylock_irqsave(&qs->lock, irq_flags)) ++ return -EBUSY; ++ } else { ++ raw_spin_lock_irqsave(&qs->lock, irq_flags); ++ } + + if (queue_stack_map_is_full(qs)) { + if (!replace) { +-- +2.40.1 + diff --git a/queue-5.4/dccp-fix-dccp_v4_err-dccp_v6_err-again.patch b/queue-5.4/dccp-fix-dccp_v4_err-dccp_v6_err-again.patch new file mode 100644 index 00000000000..ba87acd5f4a --- /dev/null +++ b/queue-5.4/dccp-fix-dccp_v4_err-dccp_v6_err-again.patch @@ -0,0 +1,132 @@ +From 5de0fdde00dd32fd499dd179f85ed4622979956c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 19:00:35 +0000 +Subject: dccp: fix dccp_v4_err()/dccp_v6_err() again + +From: Eric Dumazet + +[ Upstream commit 6af289746a636f71f4c0535a9801774118486c7a ] + +dh->dccph_x is the 9th byte (offset 8) in "struct dccp_hdr", +not in the "byte 7" as Jann claimed. + +We need to make sure the ICMP messages are big enough, +using more standard ways (no more assumptions). + +syzbot reported: +BUG: KMSAN: uninit-value in pskb_may_pull_reason include/linux/skbuff.h:2667 [inline] +BUG: KMSAN: uninit-value in pskb_may_pull include/linux/skbuff.h:2681 [inline] +BUG: KMSAN: uninit-value in dccp_v6_err+0x426/0x1aa0 net/dccp/ipv6.c:94 +pskb_may_pull_reason include/linux/skbuff.h:2667 [inline] +pskb_may_pull include/linux/skbuff.h:2681 [inline] +dccp_v6_err+0x426/0x1aa0 net/dccp/ipv6.c:94 +icmpv6_notify+0x4c7/0x880 net/ipv6/icmp.c:867 +icmpv6_rcv+0x19d5/0x30d0 +ip6_protocol_deliver_rcu+0xda6/0x2a60 net/ipv6/ip6_input.c:438 +ip6_input_finish net/ipv6/ip6_input.c:483 [inline] +NF_HOOK include/linux/netfilter.h:304 [inline] +ip6_input+0x15d/0x430 net/ipv6/ip6_input.c:492 +ip6_mc_input+0xa7e/0xc80 net/ipv6/ip6_input.c:586 +dst_input include/net/dst.h:468 [inline] +ip6_rcv_finish+0x5db/0x870 net/ipv6/ip6_input.c:79 +NF_HOOK include/linux/netfilter.h:304 [inline] +ipv6_rcv+0xda/0x390 net/ipv6/ip6_input.c:310 +__netif_receive_skb_one_core net/core/dev.c:5523 [inline] +__netif_receive_skb+0x1a6/0x5a0 net/core/dev.c:5637 +netif_receive_skb_internal net/core/dev.c:5723 [inline] +netif_receive_skb+0x58/0x660 net/core/dev.c:5782 +tun_rx_batched+0x83b/0x920 +tun_get_user+0x564c/0x6940 drivers/net/tun.c:2002 +tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2048 +call_write_iter include/linux/fs.h:1985 [inline] +new_sync_write fs/read_write.c:491 [inline] +vfs_write+0x8ef/0x15c0 fs/read_write.c:584 +ksys_write+0x20f/0x4c0 fs/read_write.c:637 +__do_sys_write fs/read_write.c:649 [inline] +__se_sys_write fs/read_write.c:646 [inline] +__x64_sys_write+0x93/0xd0 fs/read_write.c:646 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Uninit was created at: +slab_post_alloc_hook+0x12f/0xb70 mm/slab.h:767 +slab_alloc_node mm/slub.c:3478 [inline] +kmem_cache_alloc_node+0x577/0xa80 mm/slub.c:3523 +kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:559 +__alloc_skb+0x318/0x740 net/core/skbuff.c:650 +alloc_skb include/linux/skbuff.h:1286 [inline] +alloc_skb_with_frags+0xc8/0xbd0 net/core/skbuff.c:6313 +sock_alloc_send_pskb+0xa80/0xbf0 net/core/sock.c:2795 +tun_alloc_skb drivers/net/tun.c:1531 [inline] +tun_get_user+0x23cf/0x6940 drivers/net/tun.c:1846 +tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2048 +call_write_iter include/linux/fs.h:1985 [inline] +new_sync_write fs/read_write.c:491 [inline] +vfs_write+0x8ef/0x15c0 fs/read_write.c:584 +ksys_write+0x20f/0x4c0 fs/read_write.c:637 +__do_sys_write fs/read_write.c:649 [inline] +__se_sys_write fs/read_write.c:646 [inline] +__x64_sys_write+0x93/0xd0 fs/read_write.c:646 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +CPU: 0 PID: 4995 Comm: syz-executor153 Not tainted 6.6.0-rc1-syzkaller-00014-ga747acc0b752 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/04/2023 + +Fixes: 977ad86c2a1b ("dccp: Fix out of bounds access in DCCP error handler") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Jann Horn +Reviewed-by: Jann Horn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/dccp/ipv4.c | 9 ++------- + net/dccp/ipv6.c | 9 ++------- + 2 files changed, 4 insertions(+), 14 deletions(-) + +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index bc4fef1250f45..249beb41ff89d 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -243,13 +243,8 @@ static int dccp_v4_err(struct sk_buff *skb, u32 info) + int err; + struct net *net = dev_net(skb->dev); + +- /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, +- * which is in byte 7 of the dccp header. +- * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. +- * +- * Later on, we want to access the sequence number fields, which are +- * beyond 8 bytes, so we have to pskb_may_pull() ourselves. +- */ ++ if (!pskb_may_pull(skb, offset + sizeof(*dh))) ++ return -EINVAL; + dh = (struct dccp_hdr *)(skb->data + offset); + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) + return -EINVAL; +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index 5554752c21822..a7e3939022534 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -76,13 +76,8 @@ static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + __u64 seq; + struct net *net = dev_net(skb->dev); + +- /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, +- * which is in byte 7 of the dccp header. +- * Our caller (icmpv6_notify()) already pulled 8 bytes for us. +- * +- * Later on, we want to access the sequence number fields, which are +- * beyond 8 bytes, so we have to pskb_may_pull() ourselves. +- */ ++ if (!pskb_may_pull(skb, offset + sizeof(*dh))) ++ return -EINVAL; + dh = (struct dccp_hdr *)(skb->data + offset); + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) + return -EINVAL; +-- +2.40.1 + diff --git a/queue-5.4/i40e-fix-for-persistent-lldp-support.patch b/queue-5.4/i40e-fix-for-persistent-lldp-support.patch new file mode 100644 index 00000000000..0c8740635ee --- /dev/null +++ b/queue-5.4/i40e-fix-for-persistent-lldp-support.patch @@ -0,0 +1,171 @@ +From b03b1ebce9fe6abc88b738cb6b6ce46db52b22ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Sep 2019 02:17:15 -0700 +Subject: i40e: Fix for persistent lldp support + +From: Sylwia Wnuczko + +[ Upstream commit ff9246571a2e79944d6d4d22de4f717081beb5d3 ] + +This patch fixes function to read NVM module data and uses it to +read current LLDP agent configuration from NVM API version 1.8. + +Signed-off-by: Sylwia Wnuczko +Tested-by: Andrew Bowers +Signed-off-by: Jeff Kirsher +Stable-dep-of: d0d362ffa33d ("i40e: Fix VF VLAN offloading when port VLAN is configured") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_dcb.c | 4 +- + drivers/net/ethernet/intel/i40e/i40e_dcb.h | 3 + + drivers/net/ethernet/intel/i40e/i40e_nvm.c | 61 ++++++++++--------- + .../net/ethernet/intel/i40e/i40e_prototype.h | 10 +-- + 4 files changed, 44 insertions(+), 34 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.c b/drivers/net/ethernet/intel/i40e/i40e_dcb.c +index 200a1cb3b5363..9de503c5f99b3 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_dcb.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.c +@@ -889,7 +889,9 @@ i40e_status i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change) + + ret = i40e_read_nvm_module_data(hw, + I40E_SR_EMP_SR_SETTINGS_PTR, +- offset, 1, ++ offset, ++ I40E_LLDP_CURRENT_STATUS_OFFSET, ++ I40E_LLDP_CURRENT_STATUS_SIZE, + &lldp_cfg.adminstatus); + } else { + ret = i40e_read_lldp_cfg(hw, &lldp_cfg); +diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.h b/drivers/net/ethernet/intel/i40e/i40e_dcb.h +index 2a80c5daa376e..ba86ad833bee8 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_dcb.h ++++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.h +@@ -32,6 +32,9 @@ + #define I40E_CEE_MAX_FEAT_TYPE 3 + #define I40E_LLDP_CURRENT_STATUS_XL710_OFFSET 0x2B + #define I40E_LLDP_CURRENT_STATUS_X722_OFFSET 0x31 ++#define I40E_LLDP_CURRENT_STATUS_OFFSET 1 ++#define I40E_LLDP_CURRENT_STATUS_SIZE 1 ++ + /* Defines for LLDP TLV header */ + #define I40E_LLDP_TLV_LEN_SHIFT 0 + #define I40E_LLDP_TLV_LEN_MASK (0x01FF << I40E_LLDP_TLV_LEN_SHIFT) +diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c +index 37a29b5fc2afd..6b1996451a4bd 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c +@@ -323,20 +323,24 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, + + /** + * i40e_read_nvm_module_data - Reads NVM Buffer to specified memory location +- * @hw: pointer to the HW structure ++ * @hw: Pointer to the HW structure + * @module_ptr: Pointer to module in words with respect to NVM beginning +- * @offset: offset in words from module start ++ * @module_offset: Offset in words from module start ++ * @data_offset: Offset in words from reading data area start + * @words_data_size: Words to read from NVM + * @data_ptr: Pointer to memory location where resulting buffer will be stored + **/ +-i40e_status i40e_read_nvm_module_data(struct i40e_hw *hw, +- u8 module_ptr, u16 offset, +- u16 words_data_size, +- u16 *data_ptr) ++enum i40e_status_code i40e_read_nvm_module_data(struct i40e_hw *hw, ++ u8 module_ptr, ++ u16 module_offset, ++ u16 data_offset, ++ u16 words_data_size, ++ u16 *data_ptr) + { + i40e_status status; ++ u16 specific_ptr = 0; + u16 ptr_value = 0; +- u32 flat_offset; ++ u32 offset = 0; + + if (module_ptr != 0) { + status = i40e_read_nvm_word(hw, module_ptr, &ptr_value); +@@ -352,36 +356,35 @@ i40e_status i40e_read_nvm_module_data(struct i40e_hw *hw, + + /* Pointer not initialized */ + if (ptr_value == I40E_NVM_INVALID_PTR_VAL || +- ptr_value == I40E_NVM_INVALID_VAL) ++ ptr_value == I40E_NVM_INVALID_VAL) { ++ i40e_debug(hw, I40E_DEBUG_ALL, "Pointer not initialized.\n"); + return I40E_ERR_BAD_PTR; ++ } + + /* Check whether the module is in SR mapped area or outside */ + if (ptr_value & I40E_PTR_TYPE) { + /* Pointer points outside of the Shared RAM mapped area */ +- ptr_value &= ~I40E_PTR_TYPE; ++ i40e_debug(hw, I40E_DEBUG_ALL, ++ "Reading nvm data failed. Pointer points outside of the Shared RAM mapped area.\n"); + +- /* PtrValue in 4kB units, need to convert to words */ +- ptr_value /= 2; +- flat_offset = ((u32)ptr_value * 0x1000) + (u32)offset; +- status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); +- if (!status) { +- status = i40e_aq_read_nvm(hw, 0, 2 * flat_offset, +- 2 * words_data_size, +- data_ptr, true, NULL); +- i40e_release_nvm(hw); +- if (status) { +- i40e_debug(hw, I40E_DEBUG_ALL, +- "Reading nvm aq failed.Error code: %d.\n", +- status); +- return I40E_ERR_NVM; +- } +- } else { +- return I40E_ERR_NVM; +- } ++ return I40E_ERR_PARAM; + } else { + /* Read from the Shadow RAM */ +- status = i40e_read_nvm_buffer(hw, ptr_value + offset, +- &words_data_size, data_ptr); ++ ++ status = i40e_read_nvm_word(hw, ptr_value + module_offset, ++ &specific_ptr); ++ if (status) { ++ i40e_debug(hw, I40E_DEBUG_ALL, ++ "Reading nvm word failed.Error code: %d.\n", ++ status); ++ return I40E_ERR_NVM; ++ } ++ ++ offset = ptr_value + module_offset + specific_ptr + ++ data_offset; ++ ++ status = i40e_read_nvm_buffer(hw, offset, &words_data_size, ++ data_ptr); + if (status) { + i40e_debug(hw, I40E_DEBUG_ALL, + "Reading nvm buffer failed.Error code: %d.\n", +diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h +index 5250441bf75b8..7effe5010e326 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h ++++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h +@@ -315,10 +315,12 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw, + void i40e_release_nvm(struct i40e_hw *hw); + i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, + u16 *data); +-i40e_status i40e_read_nvm_module_data(struct i40e_hw *hw, +- u8 module_ptr, u16 offset, +- u16 words_data_size, +- u16 *data_ptr); ++enum i40e_status_code i40e_read_nvm_module_data(struct i40e_hw *hw, ++ u8 module_ptr, ++ u16 module_offset, ++ u16 data_offset, ++ u16 words_data_size, ++ u16 *data_ptr); + i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, + u16 *words, u16 *data); + i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw); +-- +2.40.1 + diff --git a/queue-5.4/i40e-fix-vf-vlan-offloading-when-port-vlan-is-config.patch b/queue-5.4/i40e-fix-vf-vlan-offloading-when-port-vlan-is-config.patch new file mode 100644 index 00000000000..a9a69a1f892 --- /dev/null +++ b/queue-5.4/i40e-fix-vf-vlan-offloading-when-port-vlan-is-config.patch @@ -0,0 +1,88 @@ +From f8306c216f95d93e1406c18535391b462c84c43d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 17:44:57 +0200 +Subject: i40e: Fix VF VLAN offloading when port VLAN is configured + +From: Ivan Vecera + +[ Upstream commit d0d362ffa33da4acdcf7aee2116ceef8c8fef658 ] + +If port VLAN is configured on a VF then any other VLANs on top of this VF +are broken. + +During i40e_ndo_set_vf_port_vlan() call the i40e driver reset the VF and +iavf driver asks PF (using VIRTCHNL_OP_GET_VF_RESOURCES) for VF capabilities +but this reset occurs too early, prior setting of vf->info.pvid field +and because this field can be zero during i40e_vc_get_vf_resources_msg() +then VIRTCHNL_VF_OFFLOAD_VLAN capability is reported to iavf driver. + +This is wrong because iavf driver should not report VLAN offloading +capability when port VLAN is configured as i40e does not support QinQ +offloading. + +Fix the issue by moving VF reset after setting of vf->port_vlan_id +field. + +Without this patch: +$ echo 1 > /sys/class/net/enp2s0f0/device/sriov_numvfs +$ ip link set enp2s0f0 vf 0 vlan 3 +$ ip link set enp2s0f0v0 up +$ ip link add link enp2s0f0v0 name vlan4 type vlan id 4 +$ ip link set vlan4 up +... +$ ethtool -k enp2s0f0v0 | grep vlan-offload +rx-vlan-offload: on +tx-vlan-offload: on +$ dmesg -l err | grep iavf +[1292500.742914] iavf 0000:02:02.0: Failed to add VLAN filter, error IAVF_ERR_INVALID_QP_ID + +With this patch: +$ echo 1 > /sys/class/net/enp2s0f0/device/sriov_numvfs +$ ip link set enp2s0f0 vf 0 vlan 3 +$ ip link set enp2s0f0v0 up +$ ip link add link enp2s0f0v0 name vlan4 type vlan id 4 +$ ip link set vlan4 up +... +$ ethtool -k enp2s0f0v0 | grep vlan-offload +rx-vlan-offload: off [requested on] +tx-vlan-offload: off [requested on] +$ dmesg -l err | grep iavf + +Fixes: f9b4b6278d51 ("i40e: Reset the VF upon conflicting VLAN configuration") +Signed-off-by: Ivan Vecera +Reviewed-by: Jesse Brandeburg +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 7a52be82d05a2..1a3017e5f44c1 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -4268,9 +4268,6 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, + /* duplicate request, so just return success */ + goto error_pvid; + +- i40e_vc_reset_vf(vf, true); +- /* During reset the VF got a new VSI, so refresh a pointer. */ +- vsi = pf->vsi[vf->lan_vsi_idx]; + /* Locked once because multiple functions below iterate list */ + spin_lock_bh(&vsi->mac_filter_hash_lock); + +@@ -4356,6 +4353,10 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, + */ + vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); + ++ i40e_vc_reset_vf(vf, true); ++ /* During reset the VF got a new VSI, so refresh a pointer. */ ++ vsi = pf->vsi[vf->lan_vsi_idx]; ++ + ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni); + if (ret) { + dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n"); +-- +2.40.1 + diff --git a/queue-5.4/i40e-fix-warning-message-and-call-stack-during-rmmod.patch b/queue-5.4/i40e-fix-warning-message-and-call-stack-during-rmmod.patch new file mode 100644 index 00000000000..d425e9d4aed --- /dev/null +++ b/queue-5.4/i40e-fix-warning-message-and-call-stack-during-rmmod.patch @@ -0,0 +1,164 @@ +From f18b243430f50bf145170c9582b4f47ee3fb46be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Apr 2021 10:19:41 +0200 +Subject: i40e: Fix warning message and call stack during rmmod i40e driver + +From: Karen Sornek + +[ Upstream commit 3a3b311e3881172fc8e019b6508f04bc40c92d9d ] + +Restore part of reset functionality used when reset is called +from the VF to reset itself. Without this fix warning message +is displayed when VF is being removed via sysfs. + +Fix the crash of the VF during reset by ensuring +that the PF receives the reset message successfully. +Refactor code to use one function instead of two. + +Fixes: 5c3c48ac6bf5 ("i40e: implement virtual device interface") +Signed-off-by: Grzegorz Szczurek +Signed-off-by: Karen Sornek +Tested-by: Tony Brelinski +Signed-off-by: Tony Nguyen +Stable-dep-of: d0d362ffa33d ("i40e: Fix VF VLAN offloading when port VLAN is configured") +Signed-off-by: Sasha Levin +--- + .../ethernet/intel/i40e/i40e_virtchnl_pf.c | 53 ++++++++----------- + 1 file changed, 21 insertions(+), 32 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 590469c4a1b00..7a52be82d05a2 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -130,17 +130,18 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf) + /***********************misc routines*****************************/ + + /** +- * i40e_vc_disable_vf ++ * i40e_vc_reset_vf + * @vf: pointer to the VF info +- * +- * Disable the VF through a SW reset. ++ * @notify_vf: notify vf about reset or not ++ * Reset VF handler. + **/ +-static inline void i40e_vc_disable_vf(struct i40e_vf *vf) ++static void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf) + { + struct i40e_pf *pf = vf->pf; + int i; + +- i40e_vc_notify_vf_reset(vf); ++ if (notify_vf) ++ i40e_vc_notify_vf_reset(vf); + + /* We want to ensure that an actual reset occurs initiated after this + * function was called. However, we do not want to wait forever, so +@@ -158,9 +159,14 @@ static inline void i40e_vc_disable_vf(struct i40e_vf *vf) + usleep_range(10000, 20000); + } + +- dev_warn(&vf->pf->pdev->dev, +- "Failed to initiate reset for VF %d after 200 milliseconds\n", +- vf->vf_id); ++ if (notify_vf) ++ dev_warn(&vf->pf->pdev->dev, ++ "Failed to initiate reset for VF %d after 200 milliseconds\n", ++ vf->vf_id); ++ else ++ dev_dbg(&vf->pf->pdev->dev, ++ "Failed to initiate reset for VF %d after 200 milliseconds\n", ++ vf->vf_id); + } + + /** +@@ -2097,20 +2103,6 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) + return ret; + } + +-/** +- * i40e_vc_reset_vf_msg +- * @vf: pointer to the VF info +- * +- * called from the VF to reset itself, +- * unlike other virtchnl messages, PF driver +- * doesn't send the response back to the VF +- **/ +-static void i40e_vc_reset_vf_msg(struct i40e_vf *vf) +-{ +- if (test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) +- i40e_reset_vf(vf, false); +-} +- + /** + * i40e_vc_config_promiscuous_mode_msg + * @vf: pointer to the VF info +@@ -2664,8 +2656,7 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg) + } else { + /* successful request */ + vf->num_req_queues = req_pairs; +- i40e_vc_notify_vf_reset(vf); +- i40e_reset_vf(vf, false); ++ i40e_vc_reset_vf(vf, true); + return 0; + } + +@@ -3857,8 +3848,7 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg) + vf->adq_enabled = true; + + /* reset the VF in order to allocate resources */ +- i40e_vc_notify_vf_reset(vf); +- i40e_reset_vf(vf, false); ++ i40e_vc_reset_vf(vf, true); + + return I40E_SUCCESS; + +@@ -3898,8 +3888,7 @@ static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg) + } + + /* reset the VF in order to allocate resources */ +- i40e_vc_notify_vf_reset(vf); +- i40e_reset_vf(vf, false); ++ i40e_vc_reset_vf(vf, true); + + return I40E_SUCCESS; + +@@ -3961,7 +3950,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode, + i40e_vc_notify_vf_link_state(vf); + break; + case VIRTCHNL_OP_RESET_VF: +- i40e_vc_reset_vf_msg(vf); ++ i40e_vc_reset_vf(vf, false); + ret = 0; + break; + case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: +@@ -4215,7 +4204,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) + /* Force the VF interface down so it has to bring up with new MAC + * address + */ +- i40e_vc_disable_vf(vf); ++ i40e_vc_reset_vf(vf, true); + dev_info(&pf->pdev->dev, "Bring down and up the VF interface to make this change effective.\n"); + + error_param: +@@ -4279,7 +4268,7 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, + /* duplicate request, so just return success */ + goto error_pvid; + +- i40e_vc_disable_vf(vf); ++ i40e_vc_reset_vf(vf, true); + /* During reset the VF got a new VSI, so refresh a pointer. */ + vsi = pf->vsi[vf->lan_vsi_idx]; + /* Locked once because multiple functions below iterate list */ +@@ -4662,7 +4651,7 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting) + goto out; + + vf->trusted = setting; +- i40e_vc_disable_vf(vf); ++ i40e_vc_reset_vf(vf, true); + dev_info(&pf->pdev->dev, "VF %u is now %strusted\n", + vf_id, setting ? "" : "un"); + +-- +2.40.1 + diff --git a/queue-5.4/i40e-remove-scheduling-while-atomic-possibility.patch b/queue-5.4/i40e-remove-scheduling-while-atomic-possibility.patch new file mode 100644 index 00000000000..4ac330aa4b4 --- /dev/null +++ b/queue-5.4/i40e-remove-scheduling-while-atomic-possibility.patch @@ -0,0 +1,326 @@ +From be3204401fa57a3bedc2b0e5cda16ea64ccf019b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 May 2020 14:10:39 -0700 +Subject: i40e: Remove scheduling while atomic possibility + +From: Aleksandr Loktionov + +[ Upstream commit 37d318d7805f25b672bfd74fc694f19a2ee9665d ] + +In some occasions task held spinlock (mac_filter_hash_lock), +while being rescheduled due to admin queue mutex_lock. The struct +i40e_spinlock asq_spinlock, which later expands to struct mutex +spinlock. Moved i40e_aq_set_vsi_multicast_promiscuous(), +i40e_aq_set_vsi_unicast_promiscuous(), +i40e_aq_set_vsi_mc_promisc_on_vlan(), and +i40e_aq_set_vsi_uc_promisc_on_vlan() outside of atomic context. Without +this patch there is a race condition, which might result in scheduling +while in atomic context. The race condition is between the thread, which +holds mac_filter_hash_lock, while trying to acquire an admin queue mutex +and a thread, which already has said admin queue mutex. The thread, which +holds spinlock, fails to acquire the mutex, which causes this thread to +sleep. + +Signed-off-by: Arkadiusz Kubalewski +Signed-off-by: Aleksandr Loktionov +Tested-by: Andrew Bowers +Signed-off-by: Jeff Kirsher +Stable-dep-of: d0d362ffa33d ("i40e: Fix VF VLAN offloading when port VLAN is configured") +Signed-off-by: Sasha Levin +--- + .../ethernet/intel/i40e/i40e_virtchnl_pf.c | 234 ++++++++++-------- + 1 file changed, 137 insertions(+), 97 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index be07148a7b294..590469c4a1b00 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -1110,39 +1110,81 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf) + return -EIO; + } + +-static inline int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi); ++/** ++ * i40e_getnum_vf_vsi_vlan_filters ++ * @vsi: pointer to the vsi ++ * ++ * called to get the number of VLANs offloaded on this VF ++ **/ ++static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi) ++{ ++ struct i40e_mac_filter *f; ++ int num_vlans = 0, bkt; ++ ++ hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) { ++ if (f->vlan >= 0 && f->vlan <= I40E_MAX_VLANID) ++ num_vlans++; ++ } ++ ++ return num_vlans; ++} + + /** +- * i40e_config_vf_promiscuous_mode +- * @vf: pointer to the VF info +- * @vsi_id: VSI id +- * @allmulti: set MAC L2 layer multicast promiscuous enable/disable +- * @alluni: set MAC L2 layer unicast promiscuous enable/disable ++ * i40e_get_vlan_list_sync ++ * @vsi: pointer to the VSI ++ * @num_vlans: number of VLANs in mac_filter_hash, returned to caller ++ * @vlan_list: list of VLANs present in mac_filter_hash, returned to caller. ++ * This array is allocated here, but has to be freed in caller. + * +- * Called from the VF to configure the promiscuous mode of +- * VF vsis and from the VF reset path to reset promiscuous mode. ++ * Called to get number of VLANs and VLAN list present in mac_filter_hash. + **/ +-static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf, +- u16 vsi_id, +- bool allmulti, +- bool alluni) ++static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, int *num_vlans, ++ s16 **vlan_list) + { +- struct i40e_pf *pf = vf->pf; +- struct i40e_hw *hw = &pf->hw; + struct i40e_mac_filter *f; +- i40e_status aq_ret = 0; +- struct i40e_vsi *vsi; ++ int i = 0; + int bkt; + +- vsi = i40e_find_vsi_from_id(pf, vsi_id); +- if (!i40e_vc_isvalid_vsi_id(vf, vsi_id) || !vsi) +- return I40E_ERR_PARAM; ++ spin_lock_bh(&vsi->mac_filter_hash_lock); ++ *num_vlans = i40e_getnum_vf_vsi_vlan_filters(vsi); ++ *vlan_list = kcalloc(*num_vlans, sizeof(**vlan_list), GFP_ATOMIC); ++ if (!(*vlan_list)) ++ goto err; + +- if (vf->port_vlan_id) { +- aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw, vsi->seid, +- allmulti, +- vf->port_vlan_id, +- NULL); ++ hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) { ++ if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID) ++ continue; ++ (*vlan_list)[i++] = f->vlan; ++ } ++err: ++ spin_unlock_bh(&vsi->mac_filter_hash_lock); ++} ++ ++/** ++ * i40e_set_vsi_promisc ++ * @vf: pointer to the VF struct ++ * @seid: VSI number ++ * @multi_enable: set MAC L2 layer multicast promiscuous enable/disable ++ * for a given VLAN ++ * @unicast_enable: set MAC L2 layer unicast promiscuous enable/disable ++ * for a given VLAN ++ * @vl: List of VLANs - apply filter for given VLANs ++ * @num_vlans: Number of elements in @vl ++ **/ ++static i40e_status ++i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable, ++ bool unicast_enable, s16 *vl, int num_vlans) ++{ ++ struct i40e_pf *pf = vf->pf; ++ struct i40e_hw *hw = &pf->hw; ++ i40e_status aq_ret; ++ int i; ++ ++ /* No VLAN to set promisc on, set on VSI */ ++ if (!num_vlans || !vl) { ++ aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, seid, ++ multi_enable, ++ NULL); + if (aq_ret) { + int aq_err = pf->hw.aq.asq_last_status; + +@@ -1151,13 +1193,14 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf, + vf->vf_id, + i40e_stat_str(&pf->hw, aq_ret), + i40e_aq_str(&pf->hw, aq_err)); ++ + return aq_ret; + } + +- aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, vsi->seid, +- alluni, +- vf->port_vlan_id, +- NULL); ++ aq_ret = i40e_aq_set_vsi_unicast_promiscuous(hw, seid, ++ unicast_enable, ++ NULL, true); ++ + if (aq_ret) { + int aq_err = pf->hw.aq.asq_last_status; + +@@ -1167,68 +1210,84 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf, + i40e_stat_str(&pf->hw, aq_ret), + i40e_aq_str(&pf->hw, aq_err)); + } ++ + return aq_ret; +- } else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) { +- hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) { +- if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID) +- continue; +- aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw, +- vsi->seid, +- allmulti, +- f->vlan, +- NULL); +- if (aq_ret) { +- int aq_err = pf->hw.aq.asq_last_status; ++ } + +- dev_err(&pf->pdev->dev, +- "Could not add VLAN %d to multicast promiscuous domain err %s aq_err %s\n", +- f->vlan, +- i40e_stat_str(&pf->hw, aq_ret), +- i40e_aq_str(&pf->hw, aq_err)); +- } ++ for (i = 0; i < num_vlans; i++) { ++ aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw, seid, ++ multi_enable, ++ vl[i], NULL); ++ if (aq_ret) { ++ int aq_err = pf->hw.aq.asq_last_status; ++ ++ dev_err(&pf->pdev->dev, ++ "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n", ++ vf->vf_id, ++ i40e_stat_str(&pf->hw, aq_ret), ++ i40e_aq_str(&pf->hw, aq_err)); ++ } + +- aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, +- vsi->seid, +- alluni, +- f->vlan, +- NULL); +- if (aq_ret) { +- int aq_err = pf->hw.aq.asq_last_status; ++ aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, seid, ++ unicast_enable, ++ vl[i], NULL); ++ if (aq_ret) { ++ int aq_err = pf->hw.aq.asq_last_status; + +- dev_err(&pf->pdev->dev, +- "Could not add VLAN %d to Unicast promiscuous domain err %s aq_err %s\n", +- f->vlan, +- i40e_stat_str(&pf->hw, aq_ret), +- i40e_aq_str(&pf->hw, aq_err)); +- } ++ dev_err(&pf->pdev->dev, ++ "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n", ++ vf->vf_id, ++ i40e_stat_str(&pf->hw, aq_ret), ++ i40e_aq_str(&pf->hw, aq_err)); + } +- return aq_ret; + } +- aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, allmulti, +- NULL); +- if (aq_ret) { +- int aq_err = pf->hw.aq.asq_last_status; ++ return aq_ret; ++} + +- dev_err(&pf->pdev->dev, +- "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n", +- vf->vf_id, +- i40e_stat_str(&pf->hw, aq_ret), +- i40e_aq_str(&pf->hw, aq_err)); ++/** ++ * i40e_config_vf_promiscuous_mode ++ * @vf: pointer to the VF info ++ * @vsi_id: VSI id ++ * @allmulti: set MAC L2 layer multicast promiscuous enable/disable ++ * @alluni: set MAC L2 layer unicast promiscuous enable/disable ++ * ++ * Called from the VF to configure the promiscuous mode of ++ * VF vsis and from the VF reset path to reset promiscuous mode. ++ **/ ++static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf, ++ u16 vsi_id, ++ bool allmulti, ++ bool alluni) ++{ ++ i40e_status aq_ret = I40E_SUCCESS; ++ struct i40e_pf *pf = vf->pf; ++ struct i40e_vsi *vsi; ++ int num_vlans; ++ s16 *vl; ++ ++ vsi = i40e_find_vsi_from_id(pf, vsi_id); ++ if (!i40e_vc_isvalid_vsi_id(vf, vsi_id) || !vsi) ++ return I40E_ERR_PARAM; ++ ++ if (vf->port_vlan_id) { ++ aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti, ++ alluni, &vf->port_vlan_id, 1); + return aq_ret; +- } ++ } else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) { ++ i40e_get_vlan_list_sync(vsi, &num_vlans, &vl); + +- aq_ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, alluni, +- NULL, true); +- if (aq_ret) { +- int aq_err = pf->hw.aq.asq_last_status; ++ if (!vl) ++ return I40E_ERR_NO_MEMORY; + +- dev_err(&pf->pdev->dev, +- "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n", +- vf->vf_id, +- i40e_stat_str(&pf->hw, aq_ret), +- i40e_aq_str(&pf->hw, aq_err)); ++ aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti, alluni, ++ vl, num_vlans); ++ kfree(vl); ++ return aq_ret; + } + ++ /* no VLANs to set on, set on VSI */ ++ aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti, alluni, ++ NULL, 0); + return aq_ret; + } + +@@ -2052,25 +2111,6 @@ static void i40e_vc_reset_vf_msg(struct i40e_vf *vf) + i40e_reset_vf(vf, false); + } + +-/** +- * i40e_getnum_vf_vsi_vlan_filters +- * @vsi: pointer to the vsi +- * +- * called to get the number of VLANs offloaded on this VF +- **/ +-static inline int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi) +-{ +- struct i40e_mac_filter *f; +- int num_vlans = 0, bkt; +- +- hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) { +- if (f->vlan >= 0 && f->vlan <= I40E_MAX_VLANID) +- num_vlans++; +- } +- +- return num_vlans; +-} +- + /** + * i40e_vc_config_promiscuous_mode_msg + * @vf: pointer to the VF info +-- +2.40.1 + diff --git a/queue-5.4/ipv4-fix-null-deref-in-ipv4_link_failure.patch b/queue-5.4/ipv4-fix-null-deref-in-ipv4_link_failure.patch new file mode 100644 index 00000000000..2b91c6c817d --- /dev/null +++ b/queue-5.4/ipv4-fix-null-deref-in-ipv4_link_failure.patch @@ -0,0 +1,53 @@ +From 1255b814d059cc51f7794f288b353e26db6ed907 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 22:12:57 -0700 +Subject: ipv4: fix null-deref in ipv4_link_failure + +From: Kyle Zeng + +[ Upstream commit 0113d9c9d1ccc07f5a3710dac4aa24b6d711278c ] + +Currently, we assume the skb is associated with a device before calling +__ip_options_compile, which is not always the case if it is re-routed by +ipvs. +When skb->dev is NULL, dev_net(skb->dev) will become null-dereference. +This patch adds a check for the edge case and switch to use the net_device +from the rtable when skb->dev is NULL. + +Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure") +Suggested-by: David Ahern +Signed-off-by: Kyle Zeng +Cc: Stephen Suryaputra +Cc: Vadim Fedorenko +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/route.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 7004e379c325f..f82d456afd0ed 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1221,6 +1221,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) + + static void ipv4_send_dest_unreach(struct sk_buff *skb) + { ++ struct net_device *dev; + struct ip_options opt; + int res; + +@@ -1238,7 +1239,8 @@ static void ipv4_send_dest_unreach(struct sk_buff *skb) + opt.optlen = ip_hdr(skb)->ihl * 4 - sizeof(struct iphdr); + + rcu_read_lock(); +- res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); ++ dev = skb->dev ? skb->dev : skb_rtable(skb)->dst.dev; ++ res = __ip_options_compile(dev_net(dev), &opt, skb, NULL); + rcu_read_unlock(); + + if (res) +-- +2.40.1 + diff --git a/queue-5.4/net-bridge-use-dev_stats_inc.patch b/queue-5.4/net-bridge-use-dev_stats_inc.patch new file mode 100644 index 00000000000..03363ae5416 --- /dev/null +++ b/queue-5.4/net-bridge-use-dev_stats_inc.patch @@ -0,0 +1,139 @@ +From 689df4fc0c0e887c7a31383e900be02654cba6ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 09:13:51 +0000 +Subject: net: bridge: use DEV_STATS_INC() + +From: Eric Dumazet + +[ Upstream commit 44bdb313da57322c9b3c108eb66981c6ec6509f4 ] + +syzbot/KCSAN reported data-races in br_handle_frame_finish() [1] +This function can run from multiple cpus without mutual exclusion. + +Adopt SMP safe DEV_STATS_INC() to update dev->stats fields. + +Handles updates to dev->stats.tx_dropped while we are at it. + +[1] +BUG: KCSAN: data-race in br_handle_frame_finish / br_handle_frame_finish + +read-write to 0xffff8881374b2178 of 8 bytes by interrupt on cpu 1: +br_handle_frame_finish+0xd4f/0xef0 net/bridge/br_input.c:189 +br_nf_hook_thresh+0x1ed/0x220 +br_nf_pre_routing_finish_ipv6+0x50f/0x540 +NF_HOOK include/linux/netfilter.h:304 [inline] +br_nf_pre_routing_ipv6+0x1e3/0x2a0 net/bridge/br_netfilter_ipv6.c:178 +br_nf_pre_routing+0x526/0xba0 net/bridge/br_netfilter_hooks.c:508 +nf_hook_entry_hookfn include/linux/netfilter.h:144 [inline] +nf_hook_bridge_pre net/bridge/br_input.c:272 [inline] +br_handle_frame+0x4c9/0x940 net/bridge/br_input.c:417 +__netif_receive_skb_core+0xa8a/0x21e0 net/core/dev.c:5417 +__netif_receive_skb_one_core net/core/dev.c:5521 [inline] +__netif_receive_skb+0x57/0x1b0 net/core/dev.c:5637 +process_backlog+0x21f/0x380 net/core/dev.c:5965 +__napi_poll+0x60/0x3b0 net/core/dev.c:6527 +napi_poll net/core/dev.c:6594 [inline] +net_rx_action+0x32b/0x750 net/core/dev.c:6727 +__do_softirq+0xc1/0x265 kernel/softirq.c:553 +run_ksoftirqd+0x17/0x20 kernel/softirq.c:921 +smpboot_thread_fn+0x30a/0x4a0 kernel/smpboot.c:164 +kthread+0x1d7/0x210 kernel/kthread.c:388 +ret_from_fork+0x48/0x60 arch/x86/kernel/process.c:147 +ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:304 + +read-write to 0xffff8881374b2178 of 8 bytes by interrupt on cpu 0: +br_handle_frame_finish+0xd4f/0xef0 net/bridge/br_input.c:189 +br_nf_hook_thresh+0x1ed/0x220 +br_nf_pre_routing_finish_ipv6+0x50f/0x540 +NF_HOOK include/linux/netfilter.h:304 [inline] +br_nf_pre_routing_ipv6+0x1e3/0x2a0 net/bridge/br_netfilter_ipv6.c:178 +br_nf_pre_routing+0x526/0xba0 net/bridge/br_netfilter_hooks.c:508 +nf_hook_entry_hookfn include/linux/netfilter.h:144 [inline] +nf_hook_bridge_pre net/bridge/br_input.c:272 [inline] +br_handle_frame+0x4c9/0x940 net/bridge/br_input.c:417 +__netif_receive_skb_core+0xa8a/0x21e0 net/core/dev.c:5417 +__netif_receive_skb_one_core net/core/dev.c:5521 [inline] +__netif_receive_skb+0x57/0x1b0 net/core/dev.c:5637 +process_backlog+0x21f/0x380 net/core/dev.c:5965 +__napi_poll+0x60/0x3b0 net/core/dev.c:6527 +napi_poll net/core/dev.c:6594 [inline] +net_rx_action+0x32b/0x750 net/core/dev.c:6727 +__do_softirq+0xc1/0x265 kernel/softirq.c:553 +do_softirq+0x5e/0x90 kernel/softirq.c:454 +__local_bh_enable_ip+0x64/0x70 kernel/softirq.c:381 +__raw_spin_unlock_bh include/linux/spinlock_api_smp.h:167 [inline] +_raw_spin_unlock_bh+0x36/0x40 kernel/locking/spinlock.c:210 +spin_unlock_bh include/linux/spinlock.h:396 [inline] +batadv_tt_local_purge+0x1a8/0x1f0 net/batman-adv/translation-table.c:1356 +batadv_tt_purge+0x2b/0x630 net/batman-adv/translation-table.c:3560 +process_one_work kernel/workqueue.c:2630 [inline] +process_scheduled_works+0x5b8/0xa30 kernel/workqueue.c:2703 +worker_thread+0x525/0x730 kernel/workqueue.c:2784 +kthread+0x1d7/0x210 kernel/kthread.c:388 +ret_from_fork+0x48/0x60 arch/x86/kernel/process.c:147 +ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:304 + +value changed: 0x00000000000d7190 -> 0x00000000000d7191 + +Reported by Kernel Concurrency Sanitizer on: +CPU: 0 PID: 14848 Comm: kworker/u4:11 Not tainted 6.6.0-rc1-syzkaller-00236-gad8a69f361b9 #0 + +Fixes: 1c29fc4989bc ("[BRIDGE]: keep track of received multicast packets") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Roopa Prabhu +Cc: Nikolay Aleksandrov +Cc: bridge@lists.linux-foundation.org +Acked-by: Nikolay Aleksandrov +Link: https://lore.kernel.org/r/20230918091351.1356153-1-edumazet@google.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/bridge/br_forward.c | 4 ++-- + net/bridge/br_input.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c +index a92d5359b5c0c..4f8eb83976f10 100644 +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -118,7 +118,7 @@ static int deliver_clone(const struct net_bridge_port *prev, + + skb = skb_clone(skb, GFP_ATOMIC); + if (!skb) { +- dev->stats.tx_dropped++; ++ DEV_STATS_INC(dev, tx_dropped); + return -ENOMEM; + } + +@@ -255,7 +255,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, + + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) { +- dev->stats.tx_dropped++; ++ DEV_STATS_INC(dev, tx_dropped); + return; + } + +diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c +index 464f6a619444d..3d07dedd93bd0 100644 +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -141,12 +141,12 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb + if ((mdst && mdst->host_joined) || + br_multicast_is_router(br)) { + local_rcv = true; +- br->dev->stats.multicast++; ++ DEV_STATS_INC(br->dev, multicast); + } + mcast_hit = true; + } else { + local_rcv = true; +- br->dev->stats.multicast++; ++ DEV_STATS_INC(br->dev, multicast); + } + break; + case BR_PKT_UNICAST: +-- +2.40.1 + diff --git a/queue-5.4/net-hns3-add-5ms-delay-before-clear-firmware-reset-i.patch b/queue-5.4/net-hns3-add-5ms-delay-before-clear-firmware-reset-i.patch new file mode 100644 index 00000000000..cad102c5d97 --- /dev/null +++ b/queue-5.4/net-hns3-add-5ms-delay-before-clear-firmware-reset-i.patch @@ -0,0 +1,47 @@ +From 5b983c69eec941dff8fa69ba4fff6f802e32849a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 15:48:40 +0800 +Subject: net: hns3: add 5ms delay before clear firmware reset irq source + +From: Jie Wang + +[ Upstream commit 0770063096d5da4a8e467b6e73c1646a75589628 ] + +Currently the reset process in hns3 and firmware watchdog init process is +asynchronous. we think firmware watchdog initialization is completed +before hns3 clear the firmware interrupt source. However, firmware +initialization may not complete early. + +so we add delay before hns3 clear firmware interrupt source and 5 ms delay +is enough to avoid second firmware reset interrupt. + +Fixes: c1a81619d73a ("net: hns3: Add mailbox interrupt handling to PF driver") +Signed-off-by: Jie Wang +Signed-off-by: Jijie Shao +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 08277c3cf2806..6b2d54c972b7c 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -2939,8 +2939,13 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) + static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, + u32 regclr) + { ++#define HCLGE_IMP_RESET_DELAY 5 ++ + switch (event_type) { + case HCLGE_VECTOR0_EVENT_RST: ++ if (regclr == BIT(HCLGE_VECTOR0_IMPRESET_INT_B)) ++ mdelay(HCLGE_IMP_RESET_DELAY); ++ + hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); + break; + case HCLGE_VECTOR0_EVENT_MBX: +-- +2.40.1 + diff --git a/queue-5.4/net-rds-fix-possible-null-pointer-dereference.patch b/queue-5.4/net-rds-fix-possible-null-pointer-dereference.patch new file mode 100644 index 00000000000..1de81f0866d --- /dev/null +++ b/queue-5.4/net-rds-fix-possible-null-pointer-dereference.patch @@ -0,0 +1,45 @@ +From 74f990abc2dee431a5faa8ab4621fd22585e9101 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 16:56:23 +0300 +Subject: net: rds: Fix possible NULL-pointer dereference + +From: Artem Chernyshev + +[ Upstream commit f1d95df0f31048f1c59092648997686e3f7d9478 ] + +In rds_rdma_cm_event_handler_cmn() check, if conn pointer exists +before dereferencing it as rdma_set_service_type() argument + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: fd261ce6a30e ("rds: rdma: update rdma transport for tos") +Signed-off-by: Artem Chernyshev +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/rds/rdma_transport.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c +index 5f741e51b4baa..bb38124a5d3db 100644 +--- a/net/rds/rdma_transport.c ++++ b/net/rds/rdma_transport.c +@@ -86,10 +86,12 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id, + break; + + case RDMA_CM_EVENT_ADDR_RESOLVED: +- rdma_set_service_type(cm_id, conn->c_tos); +- /* XXX do we need to clean up if this fails? */ +- ret = rdma_resolve_route(cm_id, ++ if (conn) { ++ rdma_set_service_type(cm_id, conn->c_tos); ++ /* XXX do we need to clean up if this fails? */ ++ ret = rdma_resolve_route(cm_id, + RDS_RDMA_RESOLVE_TIMEOUT_MS); ++ } + break; + + case RDMA_CM_EVENT_ROUTE_RESOLVED: +-- +2.40.1 + diff --git a/queue-5.4/netfilter-ipset-fix-race-between-ipset_cmd_create-an.patch b/queue-5.4/netfilter-ipset-fix-race-between-ipset_cmd_create-an.patch new file mode 100644 index 00000000000..600022fec13 --- /dev/null +++ b/queue-5.4/netfilter-ipset-fix-race-between-ipset_cmd_create-an.patch @@ -0,0 +1,64 @@ +From dea4bfa57820822d380db522e85e328167ac3e56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 20:04:45 +0200 +Subject: netfilter: ipset: Fix race between IPSET_CMD_CREATE and + IPSET_CMD_SWAP + +From: Jozsef Kadlecsik + +[ Upstream commit 7433b6d2afd512d04398c73aa984d1e285be125b ] + +Kyle Zeng reported that there is a race between IPSET_CMD_ADD and IPSET_CMD_SWAP +in netfilter/ip_set, which can lead to the invocation of `__ip_set_put` on a +wrong `set`, triggering the `BUG_ON(set->ref == 0);` check in it. + +The race is caused by using the wrong reference counter, i.e. the ref counter instead +of ref_netlink. + +Fixes: 24e227896bbf ("netfilter: ipset: Add schedule point in call_ad().") +Reported-by: Kyle Zeng +Closes: https://lore.kernel.org/netfilter-devel/ZPZqetxOmH+w%2Fmyc@westworld/#r +Tested-by: Kyle Zeng +Signed-off-by: Jozsef Kadlecsik +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/ipset/ip_set_core.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 1cf143f5df2e9..d3be0d0b0bdad 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -530,6 +530,14 @@ __ip_set_put(struct ip_set *set) + /* set->ref can be swapped out by ip_set_swap, netlink events (like dump) need + * a separate reference counter + */ ++static void ++__ip_set_get_netlink(struct ip_set *set) ++{ ++ write_lock_bh(&ip_set_ref_lock); ++ set->ref_netlink++; ++ write_unlock_bh(&ip_set_ref_lock); ++} ++ + static inline void + __ip_set_put_netlink(struct ip_set *set) + { +@@ -1529,11 +1537,11 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set, + + do { + if (retried) { +- __ip_set_get(set); ++ __ip_set_get_netlink(set); + nfnl_unlock(NFNL_SUBSYS_IPSET); + cond_resched(); + nfnl_lock(NFNL_SUBSYS_IPSET); +- __ip_set_put(set); ++ __ip_set_put_netlink(set); + } + + ip_set_lock(set); +-- +2.40.1 + diff --git a/queue-5.4/netfilter-nf_tables-disallow-element-removal-on-anon.patch b/queue-5.4/netfilter-nf_tables-disallow-element-removal-on-anon.patch new file mode 100644 index 00000000000..0d988348a8b --- /dev/null +++ b/queue-5.4/netfilter-nf_tables-disallow-element-removal-on-anon.patch @@ -0,0 +1,58 @@ +From be4df9f2962c981c10b96018d06d0ac6c32b5da6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 10 Sep 2023 19:04:45 +0200 +Subject: netfilter: nf_tables: disallow element removal on anonymous sets + +From: Pablo Neira Ayuso + +[ Upstream commit 23a3bfd4ba7acd36abf52b78605f61b21bdac216 ] + +Anonymous sets need to be populated once at creation and then they are +bound to rule since 938154b93be8 ("netfilter: nf_tables: reject unbound +anonymous set before commit phase"), otherwise transaction reports +EINVAL. + +Userspace does not need to delete elements of anonymous sets that are +not yet bound, reject this with EOPNOTSUPP. + +From flush command path, skip anonymous sets, they are expected to be +bound already. Otherwise, EINVAL is hit at the end of this transaction +for unbound sets. + +Fixes: 96518518cc41 ("netfilter: add nftables") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index a1a1f715fb624..9fc4431242e2a 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -1047,8 +1047,7 @@ static int nft_flush_table(struct nft_ctx *ctx) + if (!nft_is_active_next(ctx->net, set)) + continue; + +- if (nft_set_is_anonymous(set) && +- !list_empty(&set->bindings)) ++ if (nft_set_is_anonymous(set)) + continue; + + err = nft_delset(ctx, set); +@@ -5066,8 +5065,10 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk, + if (IS_ERR(set)) + return PTR_ERR(set); + +- if (!list_empty(&set->bindings) && +- (set->flags & (NFT_SET_CONSTANT | NFT_SET_ANONYMOUS))) ++ if (nft_set_is_anonymous(set)) ++ return -EOPNOTSUPP; ++ ++ if (!list_empty(&set->bindings) && (set->flags & NFT_SET_CONSTANT)) + return -EBUSY; + + if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) { +-- +2.40.1 + diff --git a/queue-5.4/powerpc-perf-hv-24x7-update-domain-value-check.patch b/queue-5.4/powerpc-perf-hv-24x7-update-domain-value-check.patch new file mode 100644 index 00000000000..af45ec6fb4e --- /dev/null +++ b/queue-5.4/powerpc-perf-hv-24x7-update-domain-value-check.patch @@ -0,0 +1,63 @@ +From 0896c7447450d098388c2588b29bd7d326fedd8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Aug 2023 11:26:01 +0530 +Subject: powerpc/perf/hv-24x7: Update domain value check + +From: Kajol Jain + +[ Upstream commit 4ff3ba4db5943cac1045e3e4a3c0463ea10f6930 ] + +Valid domain value is in range 1 to HV_PERF_DOMAIN_MAX. Current code has +check for domain value greater than or equal to HV_PERF_DOMAIN_MAX. But +the check for domain value 0 is missing. + +Fix this issue by adding check for domain value 0. + +Before: + # ./perf stat -v -e hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/ sleep 1 + Using CPUID 00800200 + Control descriptor is not initialized + Error: + The sys_perf_event_open() syscall returned with 5 (Input/output error) for + event (hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/). + /bin/dmesg | grep -i perf may provide additional information. + + Result from dmesg: + [ 37.819387] hv-24x7: hcall failed: [0 0x60040000 0x100 0] => ret + 0xfffffffffffffffc (-4) detail=0x2000000 failing ix=0 + +After: + # ./perf stat -v -e hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/ sleep 1 + Using CPUID 00800200 + Control descriptor is not initialized + Warning: + hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/ event is not supported by the kernel. + failed to read counter hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/ + +Fixes: ebd4a5a3ebd9 ("powerpc/perf/hv-24x7: Minor improvements") +Reported-by: Krishan Gopal Sarawast +Signed-off-by: Kajol Jain +Tested-by: Disha Goel +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20230825055601.360083-1-kjain@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/perf/hv-24x7.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c +index 48e8f4b17b91b..c5c7a30bd0fd4 100644 +--- a/arch/powerpc/perf/hv-24x7.c ++++ b/arch/powerpc/perf/hv-24x7.c +@@ -1313,7 +1313,7 @@ static int h_24x7_event_init(struct perf_event *event) + } + + domain = event_get_domain(event); +- if (domain >= HV_PERF_DOMAIN_MAX) { ++ if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) { + pr_devel("invalid domain %d\n", domain); + return -EINVAL; + } +-- +2.40.1 + diff --git a/queue-5.4/selftests-tls-add-to-avoid-static-checker-warning.patch b/queue-5.4/selftests-tls-add-to-avoid-static-checker-warning.patch new file mode 100644 index 00000000000..ffbeeac80e9 --- /dev/null +++ b/queue-5.4/selftests-tls-add-to-avoid-static-checker-warning.patch @@ -0,0 +1,41 @@ +From a9316abc5944258247579abecc6f9a3768cacf56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 May 2021 20:27:19 -0700 +Subject: selftests/tls: Add {} to avoid static checker warning + +From: Kees Cook + +[ Upstream commit f50688b47c5858d2ff315d020332bf4cb6710837 ] + +This silences a static checker warning due to the unusual macro +construction of EXPECT_*() by adding explicit {}s around the enclosing +while loop. + +Reported-by: Dan Carpenter +Fixes: 7f657d5bf507 ("selftests: tls: add selftests for TLS sockets") +Signed-off-by: Kees Cook +Signed-off-by: Shuah Khan +Stable-dep-of: c326ca98446e ("selftests: tls: swap the TX and RX sockets in some tests") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/tls.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c +index 0ea44d975b6c1..032e08e8ce016 100644 +--- a/tools/testing/selftests/net/tls.c ++++ b/tools/testing/selftests/net/tls.c +@@ -314,8 +314,9 @@ TEST_F(tls, sendmsg_large) + EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len); + } + +- while (recvs++ < sends) ++ while (recvs++ < sends) { + EXPECT_NE(recv(self->fd, mem, send_len, 0), -1); ++ } + + free(mem); + } +-- +2.40.1 + diff --git a/queue-5.4/selftests-tls-swap-the-tx-and-rx-sockets-in-some-tes.patch b/queue-5.4/selftests-tls-swap-the-tx-and-rx-sockets-in-some-tes.patch new file mode 100644 index 00000000000..daf81cdff8e --- /dev/null +++ b/queue-5.4/selftests-tls-swap-the-tx-and-rx-sockets-in-some-tes.patch @@ -0,0 +1,55 @@ +From bac7fb956151218e62b7cfb3f179fb4c47493ccd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 16:16:25 +0200 +Subject: selftests: tls: swap the TX and RX sockets in some tests + +From: Sabrina Dubroca + +[ Upstream commit c326ca98446e0ae4fee43a40acf79412b74cfedb ] + +tls.sendmsg_large and tls.sendmsg_multiple are trying to send through +the self->cfd socket (only configured with TLS_RX) and to receive through +the self->fd socket (only configured with TLS_TX), so they're not using +kTLS at all. Swap the sockets. + +Fixes: 7f657d5bf507 ("selftests: tls: add selftests for TLS sockets") +Signed-off-by: Sabrina Dubroca +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/tls.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c +index 032e08e8ce016..837206dbe5d6e 100644 +--- a/tools/testing/selftests/net/tls.c ++++ b/tools/testing/selftests/net/tls.c +@@ -311,11 +311,11 @@ TEST_F(tls, sendmsg_large) + + msg.msg_iov = &vec; + msg.msg_iovlen = 1; +- EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len); ++ EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len); + } + + while (recvs++ < sends) { +- EXPECT_NE(recv(self->fd, mem, send_len, 0), -1); ++ EXPECT_NE(recv(self->cfd, mem, send_len, 0), -1); + } + + free(mem); +@@ -344,9 +344,9 @@ TEST_F(tls, sendmsg_multiple) + msg.msg_iov = vec; + msg.msg_iovlen = iov_len; + +- EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len); ++ EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len); + buf = malloc(total_len); +- EXPECT_NE(recv(self->fd, buf, total_len, 0), -1); ++ EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1); + for (i = 0; i < iov_len; i++) { + EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp, + strlen(test_strs[i])), +-- +2.40.1 + diff --git a/queue-5.4/series b/queue-5.4/series index e3d15ae88c5..e0f8fec57de 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -10,3 +10,21 @@ ext4-mark-group-as-trimmed-only-if-it-was-fully-scan.patch ext4-replace-the-traditional-ternary-conditional-ope.patch ext4-move-setting-of-trimmed-bit-into-ext4_try_to_tr.patch ext4-do-not-let-fstrim-block-system-suspend.patch +asoc-meson-spdifin-start-hw-on-dai-probe.patch +netfilter-nf_tables-disallow-element-removal-on-anon.patch +bpf-avoid-deadlock-when-using-queue-and-stack-maps-f.patch +selftests-tls-add-to-avoid-static-checker-warning.patch +selftests-tls-swap-the-tx-and-rx-sockets-in-some-tes.patch +asoc-imx-audmix-fix-return-error-with-devm_clk_get.patch +i40e-fix-for-persistent-lldp-support.patch +i40e-remove-scheduling-while-atomic-possibility.patch +i40e-fix-warning-message-and-call-stack-during-rmmod.patch +i40e-fix-vf-vlan-offloading-when-port-vlan-is-config.patch +ipv4-fix-null-deref-in-ipv4_link_failure.patch +powerpc-perf-hv-24x7-update-domain-value-check.patch +dccp-fix-dccp_v4_err-dccp_v6_err-again.patch +net-hns3-add-5ms-delay-before-clear-firmware-reset-i.patch +net-bridge-use-dev_stats_inc.patch +team-fix-null-ptr-deref-when-team-device-type-is-cha.patch +net-rds-fix-possible-null-pointer-dereference.patch +netfilter-ipset-fix-race-between-ipset_cmd_create-an.patch diff --git a/queue-5.4/team-fix-null-ptr-deref-when-team-device-type-is-cha.patch b/queue-5.4/team-fix-null-ptr-deref-when-team-device-type-is-cha.patch new file mode 100644 index 00000000000..ce4d05d562d --- /dev/null +++ b/queue-5.4/team-fix-null-ptr-deref-when-team-device-type-is-cha.patch @@ -0,0 +1,121 @@ +From dea3ac4cef14dd11ead543e1bd98aafcf46b963b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 20:30:11 +0800 +Subject: team: fix null-ptr-deref when team device type is changed + +From: Ziyang Xuan + +[ Upstream commit 492032760127251e5540a5716a70996bacf2a3fd ] + +Get a null-ptr-deref bug as follows with reproducer [1]. + +BUG: kernel NULL pointer dereference, address: 0000000000000228 +... +RIP: 0010:vlan_dev_hard_header+0x35/0x140 [8021q] +... +Call Trace: + + ? __die+0x24/0x70 + ? page_fault_oops+0x82/0x150 + ? exc_page_fault+0x69/0x150 + ? asm_exc_page_fault+0x26/0x30 + ? vlan_dev_hard_header+0x35/0x140 [8021q] + ? vlan_dev_hard_header+0x8e/0x140 [8021q] + neigh_connected_output+0xb2/0x100 + ip6_finish_output2+0x1cb/0x520 + ? nf_hook_slow+0x43/0xc0 + ? ip6_mtu+0x46/0x80 + ip6_finish_output+0x2a/0xb0 + mld_sendpack+0x18f/0x250 + mld_ifc_work+0x39/0x160 + process_one_work+0x1e6/0x3f0 + worker_thread+0x4d/0x2f0 + ? __pfx_worker_thread+0x10/0x10 + kthread+0xe5/0x120 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x34/0x50 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + +[1] +$ teamd -t team0 -d -c '{"runner": {"name": "loadbalance"}}' +$ ip link add name t-dummy type dummy +$ ip link add link t-dummy name t-dummy.100 type vlan id 100 +$ ip link add name t-nlmon type nlmon +$ ip link set t-nlmon master team0 +$ ip link set t-nlmon nomaster +$ ip link set t-dummy up +$ ip link set team0 up +$ ip link set t-dummy.100 down +$ ip link set t-dummy.100 master team0 + +When enslave a vlan device to team device and team device type is changed +from non-ether to ether, header_ops of team device is changed to +vlan_header_ops. That is incorrect and will trigger null-ptr-deref +for vlan->real_dev in vlan_dev_hard_header() because team device is not +a vlan device. + +Cache eth_header_ops in team_setup(), then assign cached header_ops to +header_ops of team net device when its type is changed from non-ether +to ether to fix the bug. + +Fixes: 1d76efe1577b ("team: add support for non-ethernet devices") +Suggested-by: Hangbin Liu +Reviewed-by: Hangbin Liu +Signed-off-by: Ziyang Xuan +Reviewed-by: Jiri Pirko +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20230918123011.1884401-1-william.xuanziyang@huawei.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/team/team.c | 10 +++++++++- + include/linux/if_team.h | 2 ++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 4dc98832bbba6..60af6956286d4 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2121,7 +2121,12 @@ static const struct ethtool_ops team_ethtool_ops = { + static void team_setup_by_port(struct net_device *dev, + struct net_device *port_dev) + { +- dev->header_ops = port_dev->header_ops; ++ struct team *team = netdev_priv(dev); ++ ++ if (port_dev->type == ARPHRD_ETHER) ++ dev->header_ops = team->header_ops_cache; ++ else ++ dev->header_ops = port_dev->header_ops; + dev->type = port_dev->type; + dev->hard_header_len = port_dev->hard_header_len; + dev->needed_headroom = port_dev->needed_headroom; +@@ -2168,8 +2173,11 @@ static int team_dev_type_check_change(struct net_device *dev, + + static void team_setup(struct net_device *dev) + { ++ struct team *team = netdev_priv(dev); ++ + ether_setup(dev); + dev->max_mtu = ETH_MAX_MTU; ++ team->header_ops_cache = dev->header_ops; + + dev->netdev_ops = &team_netdev_ops; + dev->ethtool_ops = &team_ethtool_ops; +diff --git a/include/linux/if_team.h b/include/linux/if_team.h +index b216a28920f29..4182fa746d498 100644 +--- a/include/linux/if_team.h ++++ b/include/linux/if_team.h +@@ -192,6 +192,8 @@ struct team { + struct net_device *dev; /* associated netdevice */ + struct team_pcpu_stats __percpu *pcpu_stats; + ++ const struct header_ops *header_ops_cache; ++ + struct mutex lock; /* used for overall locking, e.g. port lists write */ + + /* +-- +2.40.1 +