]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Sun, 17 Sep 2023 02:27:55 +0000 (22:27 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 17 Sep 2023 02:27:55 +0000 (22:27 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
20 files changed:
queue-5.4/arm-dts-bcm5301x-extend-ram-to-full-256mb-for-linksy.patch [new file with mode: 0644]
queue-5.4/clk-imx-clk-pll14xx-make-two-variables-static.patch [new file with mode: 0644]
queue-5.4/clk-imx-pll14xx-add-new-frequency-entries-for-pll144.patch [new file with mode: 0644]
queue-5.4/clk-imx-pll14xx-dynamically-configure-pll-for-393216.patch [new file with mode: 0644]
queue-5.4/clk-imx8mm-move-1443x-1416x-pll-clock-structure-to-c.patch [new file with mode: 0644]
queue-5.4/ixgbe-fix-timestamp-configuration-code.patch [new file with mode: 0644]
queue-5.4/kcm-fix-error-handling-for-sock_dgram-in-kcm_sendmsg.patch [new file with mode: 0644]
queue-5.4/kcm-fix-memory-leak-in-error-path-of-kcm_sendmsg.patch [new file with mode: 0644]
queue-5.4/mlxbf-tmfifo-sparse-tags-for-config-access.patch [new file with mode: 0644]
queue-5.4/net-ethernet-mtk_eth_soc-fix-possible-null-pointer-d.patch [new file with mode: 0644]
queue-5.4/net-ethernet-mvpp2_main-fix-possible-oob-write-in-mv.patch [new file with mode: 0644]
queue-5.4/net-ipv4-fix-one-memleak-in-__inet_del_ifa.patch [new file with mode: 0644]
queue-5.4/net-tls-do-not-free-tls_rec-on-async-operation-in-bp.patch [new file with mode: 0644]
queue-5.4/platform-mellanox-mlxbf-tmfifo-drop-jumbo-frames.patch [new file with mode: 0644]
queue-5.4/platform-mellanox-mlxbf-tmfifo-drop-the-rx-packet-if.patch [new file with mode: 0644]
queue-5.4/r8152-check-budget-for-r8152_poll.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/usb-typec-bus-verify-partner-exists-in-typec_altmode.patch [new file with mode: 0644]
queue-5.4/usb-typec-tcpm-refactor-tcpm_handle_vdm_request-payl.patch [new file with mode: 0644]
queue-5.4/usb-typec-tcpm-refactor-tcpm_handle_vdm_request.patch [new file with mode: 0644]

diff --git a/queue-5.4/arm-dts-bcm5301x-extend-ram-to-full-256mb-for-linksy.patch b/queue-5.4/arm-dts-bcm5301x-extend-ram-to-full-256mb-for-linksy.patch
new file mode 100644 (file)
index 0000000..4894c23
--- /dev/null
@@ -0,0 +1,44 @@
+From f6368100c307478e21a99236de62a8c34596c522 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 03:40:17 +0200
+Subject: ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys EA6500 V2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aleksey Nasibulin <alealexpro100@ya.ru>
+
+[ Upstream commit 91994e59079dcb455783d3f9ea338eea6f671af3 ]
+
+Linksys ea6500-v2 have 256MB of ram. Currently we only use 128MB.
+Expand the definition to use all the available RAM.
+
+Fixes: 03e96644d7a8 ("ARM: dts: BCM5301X: Add basic DT for Linksys EA6500 V2")
+Signed-off-by: Aleksey Nasibulin <alealexpro100@ya.ru>
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Cc: stable@vger.kernel.org
+Acked-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230712014017.28123-1-ansuelsmth@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
+index cd797b4202ad8..01c48faabfade 100644
+--- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
++++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
+@@ -19,7 +19,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       gpio-keys {
+-- 
+2.40.1
+
diff --git a/queue-5.4/clk-imx-clk-pll14xx-make-two-variables-static.patch b/queue-5.4/clk-imx-clk-pll14xx-make-two-variables-static.patch
new file mode 100644 (file)
index 0000000..d1d7b3e
--- /dev/null
@@ -0,0 +1,51 @@
+From 4025fa88dcde5fb13d8a0eba0bf1fce984b06dc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2019 15:19:08 +0800
+Subject: clk: imx: clk-pll14xx: Make two variables static
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+[ Upstream commit 8f2d3c1759d19232edf1e9ef43d40a44e31493d6 ]
+
+Fix sparse warnings:
+
+drivers/clk/imx/clk-pll14xx.c:44:37:
+ warning: symbol 'imx_pll1416x_tbl' was not declared. Should it be static?
+drivers/clk/imx/clk-pll14xx.c:57:37:
+ warning: symbol 'imx_pll1443x_tbl' was not declared. Should it be static?
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Reviewed-by: Anson Huang <Anson.Huang@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 72d00e560d10 ("clk: imx: pll14xx: dynamically configure PLL for 393216000/361267200Hz")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-pll14xx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
+index c43e9653b4156..129a28c3366eb 100644
+--- a/drivers/clk/imx/clk-pll14xx.c
++++ b/drivers/clk/imx/clk-pll14xx.c
+@@ -41,7 +41,7 @@ struct clk_pll14xx {
+ #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
+-const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
++static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
+       PLL_1416X_RATE(1800000000U, 225, 3, 0),
+       PLL_1416X_RATE(1600000000U, 200, 3, 0),
+       PLL_1416X_RATE(1200000000U, 300, 3, 1),
+@@ -52,7 +52,7 @@ const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
+       PLL_1416X_RATE(600000000U,  300, 3, 2),
+ };
+-const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
++static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+       PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+       PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+-- 
+2.40.1
+
diff --git a/queue-5.4/clk-imx-pll14xx-add-new-frequency-entries-for-pll144.patch b/queue-5.4/clk-imx-pll14xx-add-new-frequency-entries-for-pll144.patch
new file mode 100644 (file)
index 0000000..c63cb3f
--- /dev/null
@@ -0,0 +1,39 @@
+From 83b2f46dab7f20ee4881e8afc89adf0d628303a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jan 2020 14:50:49 +0800
+Subject: clk: imx: pll14xx: Add new frequency entries for pll1443x table
+
+From: Anson Huang <Anson.Huang@nxp.com>
+
+[ Upstream commit 57795654fb553a78f07a9f92d87fb2582379cd93 ]
+
+Add new frequency entries to pll1443x table to meet different
+display settings requirement.
+
+Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 72d00e560d10 ("clk: imx: pll14xx: dynamically configure PLL for 393216000/361267200Hz")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-pll14xx.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
+index 129a28c3366eb..e7bf6babc28b4 100644
+--- a/drivers/clk/imx/clk-pll14xx.c
++++ b/drivers/clk/imx/clk-pll14xx.c
+@@ -53,8 +53,10 @@ static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
+ };
+ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
++      PLL_1443X_RATE(1039500000U, 173, 2, 1, 16384),
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+       PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
++      PLL_1443X_RATE(519750000U, 173, 2, 2, 16384),
+       PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+       PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
+ };
+-- 
+2.40.1
+
diff --git a/queue-5.4/clk-imx-pll14xx-dynamically-configure-pll-for-393216.patch b/queue-5.4/clk-imx-pll14xx-dynamically-configure-pll-for-393216.patch
new file mode 100644 (file)
index 0000000..96e53c6
--- /dev/null
@@ -0,0 +1,78 @@
+From 3c1a0cd1360ac0d0ccc454af27778439077968b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 10:47:44 +0200
+Subject: clk: imx: pll14xx: dynamically configure PLL for
+ 393216000/361267200Hz
+
+From: Ahmad Fatoum <a.fatoum@pengutronix.de>
+
+[ Upstream commit 72d00e560d10665e6139c9431956a87ded6e9880 ]
+
+Since commit b09c68dc57c9 ("clk: imx: pll14xx: Support dynamic rates"),
+the driver has the ability to dynamically compute PLL parameters to
+approximate the requested rates. This is not always used, because the
+logic is as follows:
+
+  - Check if the target rate is hardcoded in the frequency table
+  - Check if varying only kdiv is possible, so switch over is glitch free
+  - Compute rate dynamically by iterating over pdiv range
+
+If we skip the frequency table for the 1443x PLL, we find that the
+computed values differ to the hardcoded ones. This can be valid if the
+hardcoded values guarantee for example an earlier lock-in or if the
+divisors are chosen, so that other important rates are more likely to
+be reached glitch-free.
+
+For rates (393216000 and 361267200, this doesn't seem to be the case:
+They are only approximated by existing parameters (393215995 and
+361267196 Hz, respectively) and they aren't reachable glitch-free from
+other hardcoded frequencies. Dropping them from the table allows us
+to lock-in to these frequencies exactly.
+
+This is immediately noticeable because they are the assigned-clock-rates
+for IMX8MN_AUDIO_PLL1 and IMX8MN_AUDIO_PLL2, respectively and a look
+into clk_summary so far showed that they were a few Hz short of the target:
+
+imx8mn-board:~# grep audio_pll[12]_out /sys/kernel/debug/clk/clk_summary
+audio_pll2_out           0        0        0   361267196 0     0  50000   N
+audio_pll1_out           1        1        0   393215995 0     0  50000   Y
+
+and afterwards:
+
+imx8mn-board:~# grep audio_pll[12]_out /sys/kernel/debug/clk/clk_summary
+audio_pll2_out           0        0        0   361267200 0     0  50000   N
+audio_pll1_out           1        1        0   393216000 0     0  50000   Y
+
+This change is equivalent to adding following hardcoded values:
+
+  /*               rate     mdiv  pdiv  sdiv   kdiv */
+  PLL_1443X_RATE(393216000, 655,    5,    3,  23593),
+  PLL_1443X_RATE(361267200, 497,   33,    0, -16882),
+
+Fixes: 053a4ffe2988 ("clk: imx: imx8mm: fix audio pll setting")
+Cc: stable@vger.kernel.org # v5.18+
+Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
+Link: https://lore.kernel.org/r/20230807084744.1184791-2-m.felsch@pengutronix.de
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-pll14xx.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
+index e7bf6babc28b4..0dbe8c05af478 100644
+--- a/drivers/clk/imx/clk-pll14xx.c
++++ b/drivers/clk/imx/clk-pll14xx.c
+@@ -57,8 +57,6 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+       PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+       PLL_1443X_RATE(519750000U, 173, 2, 2, 16384),
+-      PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+-      PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
+ };
+ struct imx_pll14xx_clk imx_1443x_pll = {
+-- 
+2.40.1
+
diff --git a/queue-5.4/clk-imx8mm-move-1443x-1416x-pll-clock-structure-to-c.patch b/queue-5.4/clk-imx8mm-move-1443x-1416x-pll-clock-structure-to-c.patch
new file mode 100644 (file)
index 0000000..f756387
--- /dev/null
@@ -0,0 +1,193 @@
+From 2808ef712431c5985da352ee94264d395ce2ff35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2019 09:34:05 -0400
+Subject: clk: imx8mm: Move 1443X/1416X PLL clock structure to common place
+
+From: Anson Huang <Anson.Huang@nxp.com>
+
+[ Upstream commit 43cdaa1567ad3931fbde438853947d45238cc040 ]
+
+Many i.MX8M SoCs use same 1443X/1416X PLL, such as i.MX8MM,
+i.MX8MN and later i.MX8M SoCs, moving these PLL definitions
+to pll14xx driver can save a lot of duplicated code on each
+platform.
+
+Meanwhile, no need to define PLL clock structure for every
+module which uses same type of PLL, e.g., audio/video/dram use
+1443X PLL, arm/gpu/vpu/sys use 1416X PLL, define 2 PLL clock
+structure for each group is enough.
+
+Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
+Reviewed-by: Leonard Crestez <leonard.crestez@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 72d00e560d10 ("clk: imx: pll14xx: dynamically configure PLL for 393216000/361267200Hz")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mm.c  | 87 ++++-------------------------------
+ drivers/clk/imx/clk-pll14xx.c | 30 ++++++++++++
+ drivers/clk/imx/clk.h         |  3 ++
+ 3 files changed, 43 insertions(+), 77 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
+index 172589e94f60e..ec34c52416369 100644
+--- a/drivers/clk/imx/clk-imx8mm.c
++++ b/drivers/clk/imx/clk-imx8mm.c
+@@ -26,73 +26,6 @@ static u32 share_count_disp;
+ static u32 share_count_pdm;
+ static u32 share_count_nand;
+-static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
+-      PLL_1416X_RATE(1800000000U, 225, 3, 0),
+-      PLL_1416X_RATE(1600000000U, 200, 3, 0),
+-      PLL_1416X_RATE(1200000000U, 300, 3, 1),
+-      PLL_1416X_RATE(1000000000U, 250, 3, 1),
+-      PLL_1416X_RATE(800000000U,  200, 3, 1),
+-      PLL_1416X_RATE(750000000U,  250, 2, 2),
+-      PLL_1416X_RATE(700000000U,  350, 3, 2),
+-      PLL_1416X_RATE(600000000U,  300, 3, 2),
+-};
+-
+-static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = {
+-      PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+-      PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
+-};
+-
+-static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = {
+-      PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+-      PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+-};
+-
+-static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = {
+-      PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+-};
+-
+-static struct imx_pll14xx_clk imx8mm_audio_pll = {
+-              .type = PLL_1443X,
+-              .rate_table = imx8mm_audiopll_tbl,
+-              .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl),
+-};
+-
+-static struct imx_pll14xx_clk imx8mm_video_pll = {
+-              .type = PLL_1443X,
+-              .rate_table = imx8mm_videopll_tbl,
+-              .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl),
+-};
+-
+-static struct imx_pll14xx_clk imx8mm_dram_pll = {
+-              .type = PLL_1443X,
+-              .rate_table = imx8mm_drampll_tbl,
+-              .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl),
+-};
+-
+-static struct imx_pll14xx_clk imx8mm_arm_pll = {
+-              .type = PLL_1416X,
+-              .rate_table = imx8mm_pll1416x_tbl,
+-              .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+-};
+-
+-static struct imx_pll14xx_clk imx8mm_gpu_pll = {
+-              .type = PLL_1416X,
+-              .rate_table = imx8mm_pll1416x_tbl,
+-              .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+-};
+-
+-static struct imx_pll14xx_clk imx8mm_vpu_pll = {
+-              .type = PLL_1416X,
+-              .rate_table = imx8mm_pll1416x_tbl,
+-              .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+-};
+-
+-static struct imx_pll14xx_clk imx8mm_sys_pll = {
+-              .type = PLL_1416X,
+-              .rate_table = imx8mm_pll1416x_tbl,
+-              .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+-};
+-
+ static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+ static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+ static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+@@ -396,16 +329,16 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
+       clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+-      clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
+-      clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
+-      clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
+-      clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
+-      clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
+-      clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
+-      clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
+-      clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
+-      clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
+-      clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
++      clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
++      clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
++      clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
++      clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll);
++      clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
++      clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
++      clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
++      clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx_1416x_pll);
++      clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx_1416x_pll);
++      clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
+       /* PLL bypass out */
+       clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
+index 047f1d8fe323f..c43e9653b4156 100644
+--- a/drivers/clk/imx/clk-pll14xx.c
++++ b/drivers/clk/imx/clk-pll14xx.c
+@@ -41,6 +41,36 @@ struct clk_pll14xx {
+ #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
++const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
++      PLL_1416X_RATE(1800000000U, 225, 3, 0),
++      PLL_1416X_RATE(1600000000U, 200, 3, 0),
++      PLL_1416X_RATE(1200000000U, 300, 3, 1),
++      PLL_1416X_RATE(1000000000U, 250, 3, 1),
++      PLL_1416X_RATE(800000000U,  200, 3, 1),
++      PLL_1416X_RATE(750000000U,  250, 2, 2),
++      PLL_1416X_RATE(700000000U,  350, 3, 2),
++      PLL_1416X_RATE(600000000U,  300, 3, 2),
++};
++
++const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
++      PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
++      PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
++      PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
++      PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
++};
++
++struct imx_pll14xx_clk imx_1443x_pll = {
++      .type = PLL_1443X,
++      .rate_table = imx_pll1443x_tbl,
++      .rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
++};
++
++struct imx_pll14xx_clk imx_1416x_pll = {
++      .type = PLL_1416X,
++      .rate_table = imx_pll1416x_tbl,
++      .rate_count = ARRAY_SIZE(imx_pll1416x_tbl),
++};
++
+ static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
+               struct clk_pll14xx *pll, unsigned long rate)
+ {
+diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
+index 6fe64ff8ffa12..30ddbc1ced2ee 100644
+--- a/drivers/clk/imx/clk.h
++++ b/drivers/clk/imx/clk.h
+@@ -50,6 +50,9 @@ struct imx_pll14xx_clk {
+       int flags;
+ };
++extern struct imx_pll14xx_clk imx_1416x_pll;
++extern struct imx_pll14xx_clk imx_1443x_pll;
++
+ #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
+       to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
+-- 
+2.40.1
+
diff --git a/queue-5.4/ixgbe-fix-timestamp-configuration-code.patch b/queue-5.4/ixgbe-fix-timestamp-configuration-code.patch
new file mode 100644 (file)
index 0000000..46c6af0
--- /dev/null
@@ -0,0 +1,149 @@
+From 8165c9e7180a148d2904b54d6681eb6f68d7d9dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 13:28:14 -0700
+Subject: ixgbe: fix timestamp configuration code
+
+From: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+
+[ Upstream commit 3c44191dd76cf9c0cc49adaf34384cbd42ef8ad2 ]
+
+The commit in fixes introduced flags to control the status of hardware
+configuration while processing packets. At the same time another structure
+is used to provide configuration of timestamper to user-space applications.
+The way it was coded makes this structures go out of sync easily. The
+repro is easy for 82599 chips:
+
+[root@hostname ~]# hwstamp_ctl -i eth0 -r 12 -t 1
+current settings:
+tx_type 0
+rx_filter 0
+new settings:
+tx_type 1
+rx_filter 12
+
+The eth0 device is properly configured to timestamp any PTPv2 events.
+
+[root@hostname ~]# hwstamp_ctl -i eth0 -r 1 -t 1
+current settings:
+tx_type 1
+rx_filter 12
+SIOCSHWTSTAMP failed: Numerical result out of range
+The requested time stamping mode is not supported by the hardware.
+
+The error is properly returned because HW doesn't support all packets
+timestamping. But the adapter->flags is cleared of timestamp flags
+even though no HW configuration was done. From that point no RX timestamps
+are received by user-space application. But configuration shows good
+values:
+
+[root@hostname ~]# hwstamp_ctl -i eth0
+current settings:
+tx_type 1
+rx_filter 12
+
+Fix the issue by applying new flags only when the HW was actually
+configured.
+
+Fixes: a9763f3cb54c ("ixgbe: Update PTP to support X550EM_x devices")
+Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 28 +++++++++++---------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+index d155181b939e4..f5e36417c33e2 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+@@ -989,6 +989,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
+       u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
+       u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED;
+       u32 tsync_rx_mtrl = PTP_EV_PORT << 16;
++      u32 aflags = adapter->flags;
+       bool is_l2 = false;
+       u32 regval;
+@@ -1009,20 +1010,20 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
+       case HWTSTAMP_FILTER_NONE:
+               tsync_rx_ctl = 0;
+               tsync_rx_mtrl = 0;
+-              adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+-                                  IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
++              aflags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
++                          IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+               break;
+       case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+               tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
+               tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG;
+-              adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+-                                 IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
++              aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
++                         IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+               break;
+       case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+               tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
+               tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
+-              adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+-                                 IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
++              aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
++                         IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+               break;
+       case HWTSTAMP_FILTER_PTP_V2_EVENT:
+       case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+@@ -1036,8 +1037,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
+               tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
+               is_l2 = true;
+               config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+-              adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+-                                 IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
++              aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
++                         IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+               break;
+       case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+       case HWTSTAMP_FILTER_NTP_ALL:
+@@ -1048,7 +1049,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
+               if (hw->mac.type >= ixgbe_mac_X550) {
+                       tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL;
+                       config->rx_filter = HWTSTAMP_FILTER_ALL;
+-                      adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
++                      aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
+                       break;
+               }
+               /* fall through */
+@@ -1059,8 +1060,6 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
+                * Delay_Req messages and hardware does not support
+                * timestamping all packets => return error
+                */
+-              adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+-                                  IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+               config->rx_filter = HWTSTAMP_FILTER_NONE;
+               return -ERANGE;
+       }
+@@ -1092,8 +1091,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
+                              IXGBE_TSYNCRXCTL_TYPE_ALL |
+                              IXGBE_TSYNCRXCTL_TSIP_UT_EN;
+               config->rx_filter = HWTSTAMP_FILTER_ALL;
+-              adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
+-              adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER;
++              aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
++              aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER;
+               is_l2 = true;
+               break;
+       default:
+@@ -1126,6 +1125,9 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
+       IXGBE_WRITE_FLUSH(hw);
++      /* configure adapter flags only when HW is actually configured */
++      adapter->flags = aflags;
++
+       /* clear TX/RX time stamp registers, just to be sure */
+       ixgbe_ptp_clear_tx_timestamp(adapter);
+       IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
+-- 
+2.40.1
+
diff --git a/queue-5.4/kcm-fix-error-handling-for-sock_dgram-in-kcm_sendmsg.patch b/queue-5.4/kcm-fix-error-handling-for-sock_dgram-in-kcm_sendmsg.patch
new file mode 100644 (file)
index 0000000..7a9f9c0
--- /dev/null
@@ -0,0 +1,70 @@
+From 43de74cbd7f8c0eae96a6019364482e37b80923e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 19:27:53 -0700
+Subject: kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit a22730b1b4bf437c6bbfdeff5feddf54be4aeada ]
+
+syzkaller found a memory leak in kcm_sendmsg(), and commit c821a88bd720
+("kcm: Fix memory leak in error path of kcm_sendmsg()") suppressed it by
+updating kcm_tx_msg(head)->last_skb if partial data is copied so that the
+following sendmsg() will resume from the skb.
+
+However, we cannot know how many bytes were copied when we get the error.
+Thus, we could mess up the MSG_MORE queue.
+
+When kcm_sendmsg() fails for SOCK_DGRAM, we should purge the queue as we
+do so for UDP by udp_flush_pending_frames().
+
+Even without this change, when the error occurred, the following sendmsg()
+resumed from a wrong skb and the queue was messed up.  However, we have
+yet to get such a report, and only syzkaller stumbled on it.  So, this
+can be changed safely.
+
+Note this does not change SOCK_SEQPACKET behaviour.
+
+Fixes: c821a88bd720 ("kcm: Fix memory leak in error path of kcm_sendmsg()")
+Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://lore.kernel.org/r/20230912022753.33327-1-kuniyu@amazon.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/kcm/kcmsock.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index 8668348aa3f2b..8a8ea7e6774d5 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -1066,17 +1066,18 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+ out_error:
+       kcm_push(kcm);
+-      if (copied && sock->type == SOCK_SEQPACKET) {
++      if (sock->type == SOCK_SEQPACKET) {
+               /* Wrote some bytes before encountering an
+                * error, return partial success.
+                */
+-              goto partial_message;
+-      }
+-
+-      if (head != kcm->seq_skb)
++              if (copied)
++                      goto partial_message;
++              if (head != kcm->seq_skb)
++                      kfree_skb(head);
++      } else {
+               kfree_skb(head);
+-      else if (copied)
+-              kcm_tx_msg(head)->last_skb = skb;
++              kcm->seq_skb = NULL;
++      }
+       err = sk_stream_error(sk, msg->msg_flags, err);
+-- 
+2.40.1
+
diff --git a/queue-5.4/kcm-fix-memory-leak-in-error-path-of-kcm_sendmsg.patch b/queue-5.4/kcm-fix-memory-leak-in-error-path-of-kcm_sendmsg.patch
new file mode 100644 (file)
index 0000000..79a76a5
--- /dev/null
@@ -0,0 +1,65 @@
+From 6b4d45b80f4871e75c1608d088c957a4f1748d0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Sep 2023 02:03:10 +0900
+Subject: kcm: Fix memory leak in error path of kcm_sendmsg()
+
+From: Shigeru Yoshida <syoshida@redhat.com>
+
+[ Upstream commit c821a88bd720b0046433173185fd841a100d44ad ]
+
+syzbot reported a memory leak like below:
+
+BUG: memory leak
+unreferenced object 0xffff88810b088c00 (size 240):
+  comm "syz-executor186", pid 5012, jiffies 4294943306 (age 13.680s)
+  hex dump (first 32 bytes):
+    00 89 08 0b 81 88 ff ff 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+  backtrace:
+    [<ffffffff83e5d5ff>] __alloc_skb+0x1ef/0x230 net/core/skbuff.c:634
+    [<ffffffff84606e59>] alloc_skb include/linux/skbuff.h:1289 [inline]
+    [<ffffffff84606e59>] kcm_sendmsg+0x269/0x1050 net/kcm/kcmsock.c:815
+    [<ffffffff83e479c6>] sock_sendmsg_nosec net/socket.c:725 [inline]
+    [<ffffffff83e479c6>] sock_sendmsg+0x56/0xb0 net/socket.c:748
+    [<ffffffff83e47f55>] ____sys_sendmsg+0x365/0x470 net/socket.c:2494
+    [<ffffffff83e4c389>] ___sys_sendmsg+0xc9/0x130 net/socket.c:2548
+    [<ffffffff83e4c536>] __sys_sendmsg+0xa6/0x120 net/socket.c:2577
+    [<ffffffff84ad7bb8>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+    [<ffffffff84ad7bb8>] do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
+    [<ffffffff84c0008b>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+In kcm_sendmsg(), kcm_tx_msg(head)->last_skb is used as a cursor to append
+newly allocated skbs to 'head'. If some bytes are copied, an error occurred,
+and jumped to out_error label, 'last_skb' is left unmodified. A later
+kcm_sendmsg() will use an obsoleted 'last_skb' reference, corrupting the
+'head' frag_list and causing the leak.
+
+This patch fixes this issue by properly updating the last allocated skb in
+'last_skb'.
+
+Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module")
+Reported-and-tested-by: syzbot+6f98de741f7dbbfc4ccb@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6f98de741f7dbbfc4ccb
+Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/kcm/kcmsock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index 50bcfc71389ab..8668348aa3f2b 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -1075,6 +1075,8 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+       if (head != kcm->seq_skb)
+               kfree_skb(head);
++      else if (copied)
++              kcm_tx_msg(head)->last_skb = skb;
+       err = sk_stream_error(sk, msg->msg_flags, err);
+-- 
+2.40.1
+
diff --git a/queue-5.4/mlxbf-tmfifo-sparse-tags-for-config-access.patch b/queue-5.4/mlxbf-tmfifo-sparse-tags-for-config-access.patch
new file mode 100644 (file)
index 0000000..2ffeed5
--- /dev/null
@@ -0,0 +1,65 @@
+From 30cc793a09c4e65de1e339b00d646b664c35fc0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2020 10:56:34 -0400
+Subject: mlxbf-tmfifo: sparse tags for config access
+
+From: Michael S. Tsirkin <mst@redhat.com>
+
+[ Upstream commit 03bea764bf61c9f9918324bda7362616024386e8 ]
+
+mlxbf-tmfifo accesses config space using native types -
+which works for it since the legacy virtio native types.
+
+This will break if it ever needs to support modern virtio,
+so with new tags previously introduced for virtio net config,
+sparse now warns for this in drivers.
+
+Since this is a legacy only device, fix it up using
+virtio_legacy_is_little_endian for now.
+
+No functional changes.
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Cornelia Huck <cohuck@redhat.com>
+Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Stable-dep-of: fc4c65582154 ("platform/mellanox: mlxbf-tmfifo: Drop jumbo frames")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/mellanox/mlxbf-tmfifo.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
+index 0d77cc94c3f0e..42fcccf06157f 100644
+--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
++++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
+@@ -645,7 +645,10 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
+                       vdev_id = VIRTIO_ID_NET;
+                       hdr_len = sizeof(struct virtio_net_hdr);
+                       config = &fifo->vdev[vdev_id]->config.net;
+-                      if (ntohs(hdr.len) > config->mtu +
++                      /* A legacy-only interface for now. */
++                      if (ntohs(hdr.len) >
++                          __virtio16_to_cpu(virtio_legacy_is_little_endian(),
++                                            config->mtu) +
+                           MLXBF_TMFIFO_NET_L2_OVERHEAD)
+                               return;
+               } else {
+@@ -1273,8 +1276,12 @@ static int mlxbf_tmfifo_probe(struct platform_device *pdev)
+       /* Create the network vdev. */
+       memset(&net_config, 0, sizeof(net_config));
+-      net_config.mtu = ETH_DATA_LEN;
+-      net_config.status = VIRTIO_NET_S_LINK_UP;
++
++      /* A legacy-only interface for now. */
++      net_config.mtu = __cpu_to_virtio16(virtio_legacy_is_little_endian(),
++                                         ETH_DATA_LEN);
++      net_config.status = __cpu_to_virtio16(virtio_legacy_is_little_endian(),
++                                            VIRTIO_NET_S_LINK_UP);
+       mlxbf_tmfifo_get_cfg_mac(net_config.mac);
+       rc = mlxbf_tmfifo_create_vdev(dev, fifo, VIRTIO_ID_NET,
+                                     MLXBF_TMFIFO_NET_FEATURES, &net_config,
+-- 
+2.40.1
+
diff --git a/queue-5.4/net-ethernet-mtk_eth_soc-fix-possible-null-pointer-d.patch b/queue-5.4/net-ethernet-mtk_eth_soc-fix-possible-null-pointer-d.patch
new file mode 100644 (file)
index 0000000..e598044
--- /dev/null
@@ -0,0 +1,40 @@
+From b4c142dc0e8af7442ac10d69159be8ce763019be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Sep 2023 14:19:50 +0800
+Subject: net: ethernet: mtk_eth_soc: fix possible NULL pointer dereference in
+ mtk_hwlro_get_fdir_all()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit e4c79810755f66c9a933ca810da2724133b1165a ]
+
+rule_locs is allocated in ethtool_get_rxnfc and the size is determined by
+rule_cnt from user space. So rule_cnt needs to be check before using
+rule_locs to avoid NULL pointer dereference.
+
+Fixes: 7aab747e5563 ("net: ethernet: mediatek: add ethtool functions to configure RX flows of HW LRO")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index f9139150a8a26..7b9f5eba78dcc 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2008,6 +2008,9 @@ static int mtk_hwlro_get_fdir_all(struct net_device *dev,
+       int i;
+       for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) {
++              if (cnt == cmd->rule_cnt)
++                      return -EMSGSIZE;
++
+               if (mac->hwlro_ip[i]) {
+                       rule_locs[cnt] = i;
+                       cnt++;
+-- 
+2.40.1
+
diff --git a/queue-5.4/net-ethernet-mvpp2_main-fix-possible-oob-write-in-mv.patch b/queue-5.4/net-ethernet-mvpp2_main-fix-possible-oob-write-in-mv.patch
new file mode 100644 (file)
index 0000000..a10d171
--- /dev/null
@@ -0,0 +1,43 @@
+From d368f003759f9c6ebc42dd56822302d6d6c1fd5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Sep 2023 14:19:49 +0800
+Subject: net: ethernet: mvpp2_main: fix possible OOB write in
+ mvpp2_ethtool_get_rxnfc()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 51fe0a470543f345e3c62b6798929de3ddcedc1d ]
+
+rules is allocated in ethtool_get_rxnfc and the size is determined by
+rule_cnt from user space. So rule_cnt needs to be check before using
+rules to avoid OOB writing or NULL pointer dereference.
+
+Fixes: 90b509b39ac9 ("net: mvpp2: cls: Add Classification offload support")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Reviewed-by: Marcin Wojtas <mw@semihalf.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 31dde6fbdbdca..7a2293a5bcc9f 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -4233,6 +4233,11 @@ static int mvpp2_ethtool_get_rxnfc(struct net_device *dev,
+               break;
+       case ETHTOOL_GRXCLSRLALL:
+               for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) {
++                      if (loc == info->rule_cnt) {
++                              ret = -EMSGSIZE;
++                              break;
++                      }
++
+                       if (port->rfs_rules[i])
+                               rules[loc++] = i;
+               }
+-- 
+2.40.1
+
diff --git a/queue-5.4/net-ipv4-fix-one-memleak-in-__inet_del_ifa.patch b/queue-5.4/net-ipv4-fix-one-memleak-in-__inet_del_ifa.patch
new file mode 100644 (file)
index 0000000..2d9dc80
--- /dev/null
@@ -0,0 +1,85 @@
+From 41053fc71ad8f65698d253b1598b2c51f23cee19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 10:57:09 +0800
+Subject: net: ipv4: fix one memleak in __inet_del_ifa()
+
+From: Liu Jian <liujian56@huawei.com>
+
+[ Upstream commit ac28b1ec6135649b5d78b028e47264cb3ebca5ea ]
+
+I got the below warning when do fuzzing test:
+unregister_netdevice: waiting for bond0 to become free. Usage count = 2
+
+It can be repoduced via:
+
+ip link add bond0 type bond
+sysctl -w net.ipv4.conf.bond0.promote_secondaries=1
+ip addr add 4.117.174.103/0 scope 0x40 dev bond0
+ip addr add 192.168.100.111/255.255.255.254 scope 0 dev bond0
+ip addr add 0.0.0.4/0 scope 0x40 secondary dev bond0
+ip addr del 4.117.174.103/0 scope 0x40 dev bond0
+ip link delete bond0 type bond
+
+In this reproduction test case, an incorrect 'last_prim' is found in
+__inet_del_ifa(), as a result, the secondary address(0.0.0.4/0 scope 0x40)
+is lost. The memory of the secondary address is leaked and the reference of
+in_device and net_device is leaked.
+
+Fix this problem:
+Look for 'last_prim' starting at location of the deleted IP and inserting
+the promoted IP into the location of 'last_prim'.
+
+Fixes: 0ff60a45678e ("[IPV4]: Fix secondary IP addresses after promotion")
+Signed-off-by: Liu Jian <liujian56@huawei.com>
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/devinet.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
+index 4a8ad46397c0e..4c013f8800f0c 100644
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -351,14 +351,14 @@ static void __inet_del_ifa(struct in_device *in_dev,
+ {
+       struct in_ifaddr *promote = NULL;
+       struct in_ifaddr *ifa, *ifa1;
+-      struct in_ifaddr *last_prim;
++      struct in_ifaddr __rcu **last_prim;
+       struct in_ifaddr *prev_prom = NULL;
+       int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);
+       ASSERT_RTNL();
+       ifa1 = rtnl_dereference(*ifap);
+-      last_prim = rtnl_dereference(in_dev->ifa_list);
++      last_prim = ifap;
+       if (in_dev->dead)
+               goto no_promotions;
+@@ -372,7 +372,7 @@ static void __inet_del_ifa(struct in_device *in_dev,
+               while ((ifa = rtnl_dereference(*ifap1)) != NULL) {
+                       if (!(ifa->ifa_flags & IFA_F_SECONDARY) &&
+                           ifa1->ifa_scope <= ifa->ifa_scope)
+-                              last_prim = ifa;
++                              last_prim = &ifa->ifa_next;
+                       if (!(ifa->ifa_flags & IFA_F_SECONDARY) ||
+                           ifa1->ifa_mask != ifa->ifa_mask ||
+@@ -436,9 +436,9 @@ static void __inet_del_ifa(struct in_device *in_dev,
+                       rcu_assign_pointer(prev_prom->ifa_next, next_sec);
+-                      last_sec = rtnl_dereference(last_prim->ifa_next);
++                      last_sec = rtnl_dereference(*last_prim);
+                       rcu_assign_pointer(promote->ifa_next, last_sec);
+-                      rcu_assign_pointer(last_prim->ifa_next, promote);
++                      rcu_assign_pointer(*last_prim, promote);
+               }
+               promote->ifa_flags &= ~IFA_F_SECONDARY;
+-- 
+2.40.1
+
diff --git a/queue-5.4/net-tls-do-not-free-tls_rec-on-async-operation-in-bp.patch b/queue-5.4/net-tls-do-not-free-tls_rec-on-async-operation-in-bp.patch
new file mode 100644 (file)
index 0000000..aa564b6
--- /dev/null
@@ -0,0 +1,85 @@
+From fe6fa2c76073891d22812882d68df9a39e0b3299 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Sep 2023 16:14:34 +0800
+Subject: net/tls: do not free tls_rec on async operation in
+ bpf_exec_tx_verdict()
+
+From: Liu Jian <liujian56@huawei.com>
+
+[ Upstream commit cfaa80c91f6f99b9342b6557f0f0e1143e434066 ]
+
+I got the below warning when do fuzzing test:
+BUG: KASAN: null-ptr-deref in scatterwalk_copychunks+0x320/0x470
+Read of size 4 at addr 0000000000000008 by task kworker/u8:1/9
+
+CPU: 0 PID: 9 Comm: kworker/u8:1 Tainted: G           OE
+Hardware name: linux,dummy-virt (DT)
+Workqueue: pencrypt_parallel padata_parallel_worker
+Call trace:
+ dump_backtrace+0x0/0x420
+ show_stack+0x34/0x44
+ dump_stack+0x1d0/0x248
+ __kasan_report+0x138/0x140
+ kasan_report+0x44/0x6c
+ __asan_load4+0x94/0xd0
+ scatterwalk_copychunks+0x320/0x470
+ skcipher_next_slow+0x14c/0x290
+ skcipher_walk_next+0x2fc/0x480
+ skcipher_walk_first+0x9c/0x110
+ skcipher_walk_aead_common+0x380/0x440
+ skcipher_walk_aead_encrypt+0x54/0x70
+ ccm_encrypt+0x13c/0x4d0
+ crypto_aead_encrypt+0x7c/0xfc
+ pcrypt_aead_enc+0x28/0x84
+ padata_parallel_worker+0xd0/0x2dc
+ process_one_work+0x49c/0xbdc
+ worker_thread+0x124/0x880
+ kthread+0x210/0x260
+ ret_from_fork+0x10/0x18
+
+This is because the value of rec_seq of tls_crypto_info configured by the
+user program is too large, for example, 0xffffffffffffff. In addition, TLS
+is asynchronously accelerated. When tls_do_encryption() returns
+-EINPROGRESS and sk->sk_err is set to EBADMSG due to rec_seq overflow,
+skmsg is released before the asynchronous encryption process ends. As a
+result, the UAF problem occurs during the asynchronous processing of the
+encryption module.
+
+If the operation is asynchronous and the encryption module returns
+EINPROGRESS, do not free the record information.
+
+Fixes: 635d93981786 ("net/tls: free record only on encryption error")
+Signed-off-by: Liu Jian <liujian56@huawei.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://lore.kernel.org/r/20230909081434.2324940-1-liujian56@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tls/tls_sw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
+index f4091fba4c722..62bc7e5c58e53 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -807,7 +807,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
+       psock = sk_psock_get(sk);
+       if (!psock || !policy) {
+               err = tls_push_record(sk, flags, record_type);
+-              if (err && sk->sk_err == EBADMSG) {
++              if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) {
+                       *copied -= sk_msg_free(sk, msg);
+                       tls_free_open_rec(sk);
+                       err = -sk->sk_err;
+@@ -836,7 +836,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
+       switch (psock->eval) {
+       case __SK_PASS:
+               err = tls_push_record(sk, flags, record_type);
+-              if (err && sk->sk_err == EBADMSG) {
++              if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) {
+                       *copied -= sk_msg_free(sk, msg);
+                       tls_free_open_rec(sk);
+                       err = -sk->sk_err;
+-- 
+2.40.1
+
diff --git a/queue-5.4/platform-mellanox-mlxbf-tmfifo-drop-jumbo-frames.patch b/queue-5.4/platform-mellanox-mlxbf-tmfifo-drop-jumbo-frames.patch
new file mode 100644 (file)
index 0000000..7ae3d94
--- /dev/null
@@ -0,0 +1,103 @@
+From c470288232b9f506989da0036e6ff03115f42a56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Aug 2023 13:43:00 -0400
+Subject: platform/mellanox: mlxbf-tmfifo: Drop jumbo frames
+
+From: Liming Sun <limings@nvidia.com>
+
+[ Upstream commit fc4c655821546239abb3cf4274d66b9747aa87dd ]
+
+This commit drops over-sized network packets to avoid tmfifo
+queue stuck.
+
+Fixes: 1357dfd7261f ("platform/mellanox: Add TmFifo driver for Mellanox BlueField Soc")
+Signed-off-by: Liming Sun <limings@nvidia.com>
+Reviewed-by: Vadim Pasternak <vadimp@nvidia.com>
+Reviewed-by: David Thompson <davthompson@nvidia.com>
+Link: https://lore.kernel.org/r/9318936c2447f76db475c985ca6d91f057efcd41.1693322547.git.limings@nvidia.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/mellanox/mlxbf-tmfifo.c | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
+index 42fcccf06157f..194f3205e5597 100644
+--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
++++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
+@@ -205,7 +205,7 @@ static u8 mlxbf_tmfifo_net_default_mac[ETH_ALEN] = {
+ static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr";
+ /* Maximum L2 header length. */
+-#define MLXBF_TMFIFO_NET_L2_OVERHEAD  36
++#define MLXBF_TMFIFO_NET_L2_OVERHEAD  (ETH_HLEN + VLAN_HLEN)
+ /* Supported virtio-net features. */
+ #define MLXBF_TMFIFO_NET_FEATURES \
+@@ -623,13 +623,14 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring,
+  * flag is set.
+  */
+ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
+-                                   struct vring_desc *desc,
++                                   struct vring_desc **desc,
+                                    bool is_rx, bool *vring_change)
+ {
+       struct mlxbf_tmfifo *fifo = vring->fifo;
+       struct virtio_net_config *config;
+       struct mlxbf_tmfifo_msg_hdr hdr;
+       int vdev_id, hdr_len;
++      bool drop_rx = false;
+       /* Read/Write packet header. */
+       if (is_rx) {
+@@ -649,8 +650,8 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
+                       if (ntohs(hdr.len) >
+                           __virtio16_to_cpu(virtio_legacy_is_little_endian(),
+                                             config->mtu) +
+-                          MLXBF_TMFIFO_NET_L2_OVERHEAD)
+-                              return;
++                                            MLXBF_TMFIFO_NET_L2_OVERHEAD)
++                              drop_rx = true;
+               } else {
+                       vdev_id = VIRTIO_ID_CONSOLE;
+                       hdr_len = 0;
+@@ -665,16 +666,25 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
+                       if (!tm_dev2)
+                               return;
+-                      vring->desc = desc;
++                      vring->desc = *desc;
+                       vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX];
+                       *vring_change = true;
+               }
++
++              if (drop_rx && !IS_VRING_DROP(vring)) {
++                      if (vring->desc_head)
++                              mlxbf_tmfifo_release_pkt(vring);
++                      *desc = &vring->drop_desc;
++                      vring->desc_head = *desc;
++                      vring->desc = *desc;
++              }
++
+               vring->pkt_len = ntohs(hdr.len) + hdr_len;
+       } else {
+               /* Network virtio has an extra header. */
+               hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ?
+                          sizeof(struct virtio_net_hdr) : 0;
+-              vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, desc);
++              vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, *desc);
+               hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ?
+                           VIRTIO_ID_NET : VIRTIO_ID_CONSOLE;
+               hdr.len = htons(vring->pkt_len - hdr_len);
+@@ -723,7 +733,7 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
+       /* Beginning of a packet. Start to Rx/Tx packet header. */
+       if (vring->pkt_len == 0) {
+-              mlxbf_tmfifo_rxtx_header(vring, desc, is_rx, &vring_change);
++              mlxbf_tmfifo_rxtx_header(vring, &desc, is_rx, &vring_change);
+               (*avail)--;
+               /* Return if new packet is for another ring. */
+-- 
+2.40.1
+
diff --git a/queue-5.4/platform-mellanox-mlxbf-tmfifo-drop-the-rx-packet-if.patch b/queue-5.4/platform-mellanox-mlxbf-tmfifo-drop-the-rx-packet-if.patch
new file mode 100644 (file)
index 0000000..6e6259a
--- /dev/null
@@ -0,0 +1,176 @@
+From 7d28391cb365f88c24c9da78457a79d7da9bc1d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Aug 2023 13:42:59 -0400
+Subject: platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more
+ descriptors
+
+From: Liming Sun <limings@nvidia.com>
+
+[ Upstream commit 78034cbece79c2d730ad0770b3b7f23eedbbecf5 ]
+
+This commit fixes tmfifo console stuck issue when the virtual
+networking interface is in down state. In such case, the network
+Rx descriptors runs out and causes the Rx network packet staying
+in the head of the tmfifo thus blocking the console packets. The
+fix is to drop the Rx network packet when no more Rx descriptors.
+Function name mlxbf_tmfifo_release_pending_pkt() is also renamed
+to mlxbf_tmfifo_release_pkt() to be more approperiate.
+
+Fixes: 1357dfd7261f ("platform/mellanox: Add TmFifo driver for Mellanox BlueField Soc")
+Signed-off-by: Liming Sun <limings@nvidia.com>
+Reviewed-by: Vadim Pasternak <vadimp@nvidia.com>
+Reviewed-by: David Thompson <davthompson@nvidia.com>
+Link: https://lore.kernel.org/r/8c0177dc938ae03f52ff7e0b62dbeee74b7bec09.1693322547.git.limings@nvidia.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/mellanox/mlxbf-tmfifo.c | 66 ++++++++++++++++++------
+ 1 file changed, 49 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
+index 4b18ebd7e850c..0d77cc94c3f0e 100644
+--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
++++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
+@@ -56,6 +56,7 @@ struct mlxbf_tmfifo;
+  * @vq: pointer to the virtio virtqueue
+  * @desc: current descriptor of the pending packet
+  * @desc_head: head descriptor of the pending packet
++ * @drop_desc: dummy desc for packet dropping
+  * @cur_len: processed length of the current descriptor
+  * @rem_len: remaining length of the pending packet
+  * @pkt_len: total length of the pending packet
+@@ -72,6 +73,7 @@ struct mlxbf_tmfifo_vring {
+       struct virtqueue *vq;
+       struct vring_desc *desc;
+       struct vring_desc *desc_head;
++      struct vring_desc drop_desc;
+       int cur_len;
+       int rem_len;
+       u32 pkt_len;
+@@ -83,6 +85,14 @@ struct mlxbf_tmfifo_vring {
+       struct mlxbf_tmfifo *fifo;
+ };
++/* Check whether vring is in drop mode. */
++#define IS_VRING_DROP(_r) ({ \
++      typeof(_r) (r) = (_r); \
++      (r->desc_head == &r->drop_desc ? true : false); })
++
++/* A stub length to drop maximum length packet. */
++#define VRING_DROP_DESC_MAX_LEN               GENMASK(15, 0)
++
+ /* Interrupt types. */
+ enum {
+       MLXBF_TM_RX_LWM_IRQ,
+@@ -243,6 +253,7 @@ static int mlxbf_tmfifo_alloc_vrings(struct mlxbf_tmfifo *fifo,
+               vring->align = SMP_CACHE_BYTES;
+               vring->index = i;
+               vring->vdev_id = tm_vdev->vdev.id.device;
++              vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN;
+               dev = &tm_vdev->vdev.dev;
+               size = vring_size(vring->num, vring->align);
+@@ -348,7 +359,7 @@ static u32 mlxbf_tmfifo_get_pkt_len(struct mlxbf_tmfifo_vring *vring,
+       return len;
+ }
+-static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring)
++static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring)
+ {
+       struct vring_desc *desc_head;
+       u32 len = 0;
+@@ -577,19 +588,25 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring,
+       if (vring->cur_len + sizeof(u64) <= len) {
+               /* The whole word. */
+-              if (is_rx)
+-                      memcpy(addr + vring->cur_len, &data, sizeof(u64));
+-              else
+-                      memcpy(&data, addr + vring->cur_len, sizeof(u64));
++              if (!IS_VRING_DROP(vring)) {
++                      if (is_rx)
++                              memcpy(addr + vring->cur_len, &data,
++                                     sizeof(u64));
++                      else
++                              memcpy(&data, addr + vring->cur_len,
++                                     sizeof(u64));
++              }
+               vring->cur_len += sizeof(u64);
+       } else {
+               /* Leftover bytes. */
+-              if (is_rx)
+-                      memcpy(addr + vring->cur_len, &data,
+-                             len - vring->cur_len);
+-              else
+-                      memcpy(&data, addr + vring->cur_len,
+-                             len - vring->cur_len);
++              if (!IS_VRING_DROP(vring)) {
++                      if (is_rx)
++                              memcpy(addr + vring->cur_len, &data,
++                                     len - vring->cur_len);
++                      else
++                              memcpy(&data, addr + vring->cur_len,
++                                     len - vring->cur_len);
++              }
+               vring->cur_len = len;
+       }
+@@ -687,8 +704,16 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
+       /* Get the descriptor of the next packet. */
+       if (!vring->desc) {
+               desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx);
+-              if (!desc)
+-                      return false;
++              if (!desc) {
++                      /* Drop next Rx packet to avoid stuck. */
++                      if (is_rx) {
++                              desc = &vring->drop_desc;
++                              vring->desc_head = desc;
++                              vring->desc = desc;
++                      } else {
++                              return false;
++                      }
++              }
+       } else {
+               desc = vring->desc;
+       }
+@@ -721,17 +746,24 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
+               vring->rem_len -= len;
+               /* Get the next desc on the chain. */
+-              if (vring->rem_len > 0 &&
++              if (!IS_VRING_DROP(vring) && vring->rem_len > 0 &&
+                   (virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) {
+                       idx = virtio16_to_cpu(vdev, desc->next);
+                       desc = &vr->desc[idx];
+                       goto mlxbf_tmfifo_desc_done;
+               }
+-              /* Done and release the pending packet. */
+-              mlxbf_tmfifo_release_pending_pkt(vring);
++              /* Done and release the packet. */
+               desc = NULL;
+               fifo->vring[is_rx] = NULL;
++              if (!IS_VRING_DROP(vring)) {
++                      mlxbf_tmfifo_release_pkt(vring);
++              } else {
++                      vring->pkt_len = 0;
++                      vring->desc_head = NULL;
++                      vring->desc = NULL;
++                      return false;
++              }
+               /*
+                * Make sure the load/store are in order before
+@@ -911,7 +943,7 @@ static void mlxbf_tmfifo_virtio_del_vqs(struct virtio_device *vdev)
+               /* Release the pending packet. */
+               if (vring->desc)
+-                      mlxbf_tmfifo_release_pending_pkt(vring);
++                      mlxbf_tmfifo_release_pkt(vring);
+               vq = vring->vq;
+               if (vq) {
+                       vring->vq = NULL;
+-- 
+2.40.1
+
diff --git a/queue-5.4/r8152-check-budget-for-r8152_poll.patch b/queue-5.4/r8152-check-budget-for-r8152_poll.patch
new file mode 100644 (file)
index 0000000..bab75d6
--- /dev/null
@@ -0,0 +1,38 @@
+From fc9f8fa5b66e57f76d2847a91a3210e1b40b43d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Sep 2023 15:01:52 +0800
+Subject: r8152: check budget for r8152_poll()
+
+From: Hayes Wang <hayeswang@realtek.com>
+
+[ Upstream commit a7b8d60b37237680009dd0b025fe8c067aba0ee3 ]
+
+According to the document of napi, there is no rx process when the
+budget is 0. Therefore, r8152_poll() has to return 0 directly when the
+budget is equal to 0.
+
+Fixes: d2187f8e4454 ("r8152: divide the tx and rx bottom functions")
+Signed-off-by: Hayes Wang <hayeswang@realtek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index b0412d14e8f6c..a19f0431e6f99 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -2253,6 +2253,9 @@ static int r8152_poll(struct napi_struct *napi, int budget)
+       struct r8152 *tp = container_of(napi, struct r8152, napi);
+       int work_done;
++      if (!budget)
++              return 0;
++
+       work_done = rx_bottom(tp, budget);
+       if (work_done < budget) {
+-- 
+2.40.1
+
index 469c25e57b42d5104092df608b6011359e3e3298..6ad699f15a437b2376daa15f10b727b77d266967 100644 (file)
@@ -287,3 +287,22 @@ mtd-rawnand-brcmnand-fix-potential-out-of-bounds-access-in-oob-write.patch
 mtd-rawnand-brcmnand-fix-potential-false-time-out-warning.patch
 perf-hists-browser-fix-hierarchy-mode-header.patch
 perf-tools-handle-old-data-in-perf_record_attr.patch
+usb-typec-tcpm-refactor-tcpm_handle_vdm_request-payl.patch
+usb-typec-tcpm-refactor-tcpm_handle_vdm_request.patch
+usb-typec-bus-verify-partner-exists-in-typec_altmode.patch
+arm-dts-bcm5301x-extend-ram-to-full-256mb-for-linksy.patch
+clk-imx8mm-move-1443x-1416x-pll-clock-structure-to-c.patch
+clk-imx-clk-pll14xx-make-two-variables-static.patch
+clk-imx-pll14xx-add-new-frequency-entries-for-pll144.patch
+clk-imx-pll14xx-dynamically-configure-pll-for-393216.patch
+net-ipv4-fix-one-memleak-in-__inet_del_ifa.patch
+net-ethernet-mvpp2_main-fix-possible-oob-write-in-mv.patch
+net-ethernet-mtk_eth_soc-fix-possible-null-pointer-d.patch
+r8152-check-budget-for-r8152_poll.patch
+kcm-fix-memory-leak-in-error-path-of-kcm_sendmsg.patch
+platform-mellanox-mlxbf-tmfifo-drop-the-rx-packet-if.patch
+mlxbf-tmfifo-sparse-tags-for-config-access.patch
+platform-mellanox-mlxbf-tmfifo-drop-jumbo-frames.patch
+net-tls-do-not-free-tls_rec-on-async-operation-in-bp.patch
+ixgbe-fix-timestamp-configuration-code.patch
+kcm-fix-error-handling-for-sock_dgram-in-kcm_sendmsg.patch
diff --git a/queue-5.4/usb-typec-bus-verify-partner-exists-in-typec_altmode.patch b/queue-5.4/usb-typec-bus-verify-partner-exists-in-typec_altmode.patch
new file mode 100644 (file)
index 0000000..6ba109a
--- /dev/null
@@ -0,0 +1,93 @@
+From 4ac7e78250202f45ecb6e29d2729298909ad966b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 18:05:59 +0000
+Subject: usb: typec: bus: verify partner exists in typec_altmode_attention
+
+From: RD Babiera <rdbabiera@google.com>
+
+[ Upstream commit f23643306430f86e2f413ee2b986e0773e79da31 ]
+
+Some usb hubs will negotiate DisplayPort Alt mode with the device
+but will then negotiate a data role swap after entering the alt
+mode. The data role swap causes the device to unregister all alt
+modes, however the usb hub will still send Attention messages
+even after failing to reregister the Alt Mode. type_altmode_attention
+currently does not verify whether or not a device's altmode partner
+exists, which results in a NULL pointer error when dereferencing
+the typec_altmode and typec_altmode_ops belonging to the altmode
+partner.
+
+Verify the presence of a device's altmode partner before sending
+the Attention message to the Alt Mode driver.
+
+Fixes: 8a37d87d72f0 ("usb: typec: Bus type for alternate modes")
+Cc: stable@vger.kernel.org
+Signed-off-by: RD Babiera <rdbabiera@google.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20230814180559.923475-1-rdbabiera@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/bus.c           | 12 ++++++++++--
+ drivers/usb/typec/tcpm/tcpm.c     |  3 ++-
+ include/linux/usb/typec_altmode.h |  2 +-
+ 3 files changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
+index 0369ad92a1c8e..052b8fb21344c 100644
+--- a/drivers/usb/typec/bus.c
++++ b/drivers/usb/typec/bus.c
+@@ -146,12 +146,20 @@ EXPORT_SYMBOL_GPL(typec_altmode_exit);
+  *
+  * Notifies the partner of @adev about Attention command.
+  */
+-void typec_altmode_attention(struct typec_altmode *adev, u32 vdo)
++int typec_altmode_attention(struct typec_altmode *adev, u32 vdo)
+ {
+-      struct typec_altmode *pdev = &to_altmode(adev)->partner->adev;
++      struct altmode *partner = to_altmode(adev)->partner;
++      struct typec_altmode *pdev;
++
++      if (!partner)
++              return -ENODEV;
++
++      pdev = &partner->adev;
+       if (pdev->ops && pdev->ops->attention)
+               pdev->ops->attention(pdev, vdo);
++
++      return 0;
+ }
+ EXPORT_SYMBOL_GPL(typec_altmode_attention);
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index 9e71e0d9a09cd..07db1f1a1f72a 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1270,7 +1270,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
+                       }
+                       break;
+               case ADEV_ATTENTION:
+-                      typec_altmode_attention(adev, p[1]);
++                      if (typec_altmode_attention(adev, p[1]))
++                              tcpm_log(port, "typec_altmode_attention no port partner altmode");
+                       break;
+               }
+       }
+diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
+index 9a88c74a1d0d0..969b7c5040875 100644
+--- a/include/linux/usb/typec_altmode.h
++++ b/include/linux/usb/typec_altmode.h
+@@ -67,7 +67,7 @@ struct typec_altmode_ops {
+ int typec_altmode_enter(struct typec_altmode *altmode);
+ int typec_altmode_exit(struct typec_altmode *altmode);
+-void typec_altmode_attention(struct typec_altmode *altmode, u32 vdo);
++int typec_altmode_attention(struct typec_altmode *altmode, u32 vdo);
+ int typec_altmode_vdm(struct typec_altmode *altmode,
+                     const u32 header, const u32 *vdo, int count);
+ int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
+-- 
+2.40.1
+
diff --git a/queue-5.4/usb-typec-tcpm-refactor-tcpm_handle_vdm_request-payl.patch b/queue-5.4/usb-typec-tcpm-refactor-tcpm_handle_vdm_request-payl.patch
new file mode 100644 (file)
index 0000000..38a437f
--- /dev/null
@@ -0,0 +1,186 @@
+From 6274675333c60039aa4076d2c592d9ffd81e2534 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jul 2020 19:46:59 +0200
+Subject: usb: typec: tcpm: Refactor tcpm_handle_vdm_request payload handling
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 8afe9a3548f9d1805dcea6d97978f2179c8403a3 ]
+
+Refactor the tcpm_handle_vdm_request payload handling by doing the
+endianness conversion only once directly inside tcpm_handle_vdm_request
+itself instead of doing it multiple times inside various helper functions
+called by tcpm_handle_vdm_request.
+
+This is a preparation patch for some further refactoring to fix an AB BA
+lock inversion between the tcpm code and some altmode drivers.
+
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20200724174702.61754-3-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: f23643306430 ("usb: typec: bus: verify partner exists in typec_altmode_attention")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 49 ++++++++++++++++-------------------
+ 1 file changed, 22 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index b259a4a28f81a..949325692e664 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -969,16 +969,15 @@ static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header,
+       port->vdm_state = VDM_STATE_READY;
+ }
+-static void svdm_consume_identity(struct tcpm_port *port, const __le32 *payload,
+-                                int cnt)
++static void svdm_consume_identity(struct tcpm_port *port, const u32 *p, int cnt)
+ {
+-      u32 vdo = le32_to_cpu(payload[VDO_INDEX_IDH]);
+-      u32 product = le32_to_cpu(payload[VDO_INDEX_PRODUCT]);
++      u32 vdo = p[VDO_INDEX_IDH];
++      u32 product = p[VDO_INDEX_PRODUCT];
+       memset(&port->mode_data, 0, sizeof(port->mode_data));
+       port->partner_ident.id_header = vdo;
+-      port->partner_ident.cert_stat = le32_to_cpu(payload[VDO_INDEX_CSTAT]);
++      port->partner_ident.cert_stat = p[VDO_INDEX_CSTAT];
+       port->partner_ident.product = product;
+       typec_partner_set_identity(port->partner);
+@@ -988,17 +987,15 @@ static void svdm_consume_identity(struct tcpm_port *port, const __le32 *payload,
+                PD_PRODUCT_PID(product), product & 0xffff);
+ }
+-static bool svdm_consume_svids(struct tcpm_port *port, const __le32 *payload,
+-                             int cnt)
++static bool svdm_consume_svids(struct tcpm_port *port, const u32 *p, int cnt)
+ {
+       struct pd_mode_data *pmdata = &port->mode_data;
+       int i;
+       for (i = 1; i < cnt; i++) {
+-              u32 p = le32_to_cpu(payload[i]);
+               u16 svid;
+-              svid = (p >> 16) & 0xffff;
++              svid = (p[i] >> 16) & 0xffff;
+               if (!svid)
+                       return false;
+@@ -1008,7 +1005,7 @@ static bool svdm_consume_svids(struct tcpm_port *port, const __le32 *payload,
+               pmdata->svids[pmdata->nsvids++] = svid;
+               tcpm_log(port, "SVID %d: 0x%x", pmdata->nsvids, svid);
+-              svid = p & 0xffff;
++              svid = p[i] & 0xffff;
+               if (!svid)
+                       return false;
+@@ -1038,8 +1035,7 @@ static bool svdm_consume_svids(struct tcpm_port *port, const __le32 *payload,
+       return false;
+ }
+-static void svdm_consume_modes(struct tcpm_port *port, const __le32 *payload,
+-                             int cnt)
++static void svdm_consume_modes(struct tcpm_port *port, const u32 *p, int cnt)
+ {
+       struct pd_mode_data *pmdata = &port->mode_data;
+       struct typec_altmode_desc *paltmode;
+@@ -1056,7 +1052,7 @@ static void svdm_consume_modes(struct tcpm_port *port, const __le32 *payload,
+               paltmode->svid = pmdata->svids[pmdata->svid_index];
+               paltmode->mode = i;
+-              paltmode->vdo = le32_to_cpu(payload[i]);
++              paltmode->vdo = p[i];
+               tcpm_log(port, " Alternate mode %d: SVID 0x%04x, VDO %d: 0x%08x",
+                        pmdata->altmodes, paltmode->svid,
+@@ -1084,21 +1080,17 @@ static void tcpm_register_partner_altmodes(struct tcpm_port *port)
+ #define supports_modal(port)  PD_IDH_MODAL_SUPP((port)->partner_ident.id_header)
+-static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
++static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt,
+                       u32 *response)
+ {
+       struct typec_altmode *adev;
+       struct typec_altmode *pdev;
+       struct pd_mode_data *modep;
+-      u32 p[PD_MAX_PAYLOAD];
+       int rlen = 0;
+       int cmd_type;
+       int cmd;
+       int i;
+-      for (i = 0; i < cnt; i++)
+-              p[i] = le32_to_cpu(payload[i]);
+-
+       cmd_type = PD_VDO_CMDT(p[0]);
+       cmd = PD_VDO_CMD(p[0]);
+@@ -1159,13 +1151,13 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
+               switch (cmd) {
+               case CMD_DISCOVER_IDENT:
+                       /* 6.4.4.3.1 */
+-                      svdm_consume_identity(port, payload, cnt);
++                      svdm_consume_identity(port, p, cnt);
+                       response[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID);
+                       rlen = 1;
+                       break;
+               case CMD_DISCOVER_SVID:
+                       /* 6.4.4.3.2 */
+-                      if (svdm_consume_svids(port, payload, cnt)) {
++                      if (svdm_consume_svids(port, p, cnt)) {
+                               response[0] = VDO(USB_SID_PD, 1,
+                                                 CMD_DISCOVER_SVID);
+                               rlen = 1;
+@@ -1177,7 +1169,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
+                       break;
+               case CMD_DISCOVER_MODES:
+                       /* 6.4.4.3.3 */
+-                      svdm_consume_modes(port, payload, cnt);
++                      svdm_consume_modes(port, p, cnt);
+                       modep->svid_index++;
+                       if (modep->svid_index < modep->nsvids) {
+                               u16 svid = modep->svids[modep->svid_index];
+@@ -1240,15 +1232,18 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
+ static void tcpm_handle_vdm_request(struct tcpm_port *port,
+                                   const __le32 *payload, int cnt)
+ {
+-      int rlen = 0;
++      u32 p[PD_MAX_PAYLOAD];
+       u32 response[8] = { };
+-      u32 p0 = le32_to_cpu(payload[0]);
++      int i, rlen = 0;
++
++      for (i = 0; i < cnt; i++)
++              p[i] = le32_to_cpu(payload[i]);
+       if (port->vdm_state == VDM_STATE_BUSY) {
+               /* If UFP responded busy retry after timeout */
+-              if (PD_VDO_CMDT(p0) == CMDT_RSP_BUSY) {
++              if (PD_VDO_CMDT(p[0]) == CMDT_RSP_BUSY) {
+                       port->vdm_state = VDM_STATE_WAIT_RSP_BUSY;
+-                      port->vdo_retry = (p0 & ~VDO_CMDT_MASK) |
++                      port->vdo_retry = (p[0] & ~VDO_CMDT_MASK) |
+                               CMDT_INIT;
+                       mod_delayed_work(port->wq, &port->vdm_state_machine,
+                                        msecs_to_jiffies(PD_T_VDM_BUSY));
+@@ -1257,8 +1252,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
+               port->vdm_state = VDM_STATE_DONE;
+       }
+-      if (PD_VDO_SVDM(p0))
+-              rlen = tcpm_pd_svdm(port, payload, cnt, response);
++      if (PD_VDO_SVDM(p[0]))
++              rlen = tcpm_pd_svdm(port, p, cnt, response);
+       if (rlen > 0) {
+               tcpm_queue_vdm(port, response[0], &response[1], rlen - 1);
+-- 
+2.40.1
+
diff --git a/queue-5.4/usb-typec-tcpm-refactor-tcpm_handle_vdm_request.patch b/queue-5.4/usb-typec-tcpm-refactor-tcpm_handle_vdm_request.patch
new file mode 100644 (file)
index 0000000..f074ee5
--- /dev/null
@@ -0,0 +1,187 @@
+From 86416c46402cc088cdce1a3aca5c63bf7e31a833 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jul 2020 19:47:00 +0200
+Subject: usb: typec: tcpm: Refactor tcpm_handle_vdm_request
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 95b4d51c96a87cd760c2a4f27fb28a59a27b6368 ]
+
+Refactor tcpm_handle_vdm_request and its tcpm_pd_svdm helper function so
+that reporting the results of the vdm to the altmode-driver is separated
+out into a clear separate step inside tcpm_handle_vdm_request, instead
+of being scattered over various places inside the tcpm_pd_svdm helper.
+
+This is a preparation patch for fixing an AB BA lock inversion between the
+tcpm code and some altmode drivers.
+
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20200724174702.61754-4-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: f23643306430 ("usb: typec: bus: verify partner exists in typec_altmode_attention")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 76 ++++++++++++++++++++++-------------
+ 1 file changed, 48 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index 949325692e664..9e71e0d9a09cd 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -159,6 +159,14 @@ enum pd_msg_request {
+       PD_MSG_DATA_SOURCE_CAP,
+ };
++enum adev_actions {
++      ADEV_NONE = 0,
++      ADEV_NOTIFY_USB_AND_QUEUE_VDM,
++      ADEV_QUEUE_VDM,
++      ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL,
++      ADEV_ATTENTION,
++};
++
+ /* Events from low level driver */
+ #define TCPM_CC_EVENT         BIT(0)
+@@ -1080,10 +1088,10 @@ static void tcpm_register_partner_altmodes(struct tcpm_port *port)
+ #define supports_modal(port)  PD_IDH_MODAL_SUPP((port)->partner_ident.id_header)
+-static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt,
+-                      u32 *response)
++static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
++                      const u32 *p, int cnt, u32 *response,
++                      enum adev_actions *adev_action)
+ {
+-      struct typec_altmode *adev;
+       struct typec_altmode *pdev;
+       struct pd_mode_data *modep;
+       int rlen = 0;
+@@ -1099,9 +1107,6 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt,
+       modep = &port->mode_data;
+-      adev = typec_match_altmode(port->port_altmode, ALTMODE_DISCOVERY_MAX,
+-                                 PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0]));
+-
+       pdev = typec_match_altmode(port->partner_altmode, ALTMODE_DISCOVERY_MAX,
+                                  PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0]));
+@@ -1127,8 +1132,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt,
+                       break;
+               case CMD_ATTENTION:
+                       /* Attention command does not have response */
+-                      if (adev)
+-                              typec_altmode_attention(adev, p[1]);
++                      *adev_action = ADEV_ATTENTION;
+                       return 0;
+               default:
+                       break;
+@@ -1182,23 +1186,15 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt,
+               case CMD_ENTER_MODE:
+                       if (adev && pdev) {
+                               typec_altmode_update_active(pdev, true);
+-
+-                              if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) {
+-                                      response[0] = VDO(adev->svid, 1,
+-                                                        CMD_EXIT_MODE);
+-                                      response[0] |= VDO_OPOS(adev->mode);
+-                                      return 1;
+-                              }
++                              *adev_action = ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL;
+                       }
+                       return 0;
+               case CMD_EXIT_MODE:
+                       if (adev && pdev) {
+                               typec_altmode_update_active(pdev, false);
+-
+                               /* Back to USB Operation */
+-                              WARN_ON(typec_altmode_notify(adev,
+-                                                           TYPEC_STATE_USB,
+-                                                           NULL));
++                              *adev_action = ADEV_NOTIFY_USB_AND_QUEUE_VDM;
++                              return 0;
+                       }
+                       break;
+               default:
+@@ -1209,11 +1205,8 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt,
+               switch (cmd) {
+               case CMD_ENTER_MODE:
+                       /* Back to USB Operation */
+-                      if (adev)
+-                              WARN_ON(typec_altmode_notify(adev,
+-                                                           TYPEC_STATE_USB,
+-                                                           NULL));
+-                      break;
++                      *adev_action = ADEV_NOTIFY_USB_AND_QUEUE_VDM;
++                      return 0;
+               default:
+                       break;
+               }
+@@ -1223,15 +1216,15 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt,
+       }
+       /* Informing the alternate mode drivers about everything */
+-      if (adev)
+-              typec_altmode_vdm(adev, p[0], &p[1], cnt);
+-
++      *adev_action = ADEV_QUEUE_VDM;
+       return rlen;
+ }
+ static void tcpm_handle_vdm_request(struct tcpm_port *port,
+                                   const __le32 *payload, int cnt)
+ {
++      enum adev_actions adev_action = ADEV_NONE;
++      struct typec_altmode *adev;
+       u32 p[PD_MAX_PAYLOAD];
+       u32 response[8] = { };
+       int i, rlen = 0;
+@@ -1239,6 +1232,9 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
+       for (i = 0; i < cnt; i++)
+               p[i] = le32_to_cpu(payload[i]);
++      adev = typec_match_altmode(port->port_altmode, ALTMODE_DISCOVERY_MAX,
++                                 PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0]));
++
+       if (port->vdm_state == VDM_STATE_BUSY) {
+               /* If UFP responded busy retry after timeout */
+               if (PD_VDO_CMDT(p[0]) == CMDT_RSP_BUSY) {
+@@ -1253,7 +1249,31 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
+       }
+       if (PD_VDO_SVDM(p[0]))
+-              rlen = tcpm_pd_svdm(port, p, cnt, response);
++              rlen = tcpm_pd_svdm(port, adev, p, cnt, response, &adev_action);
++
++      if (adev) {
++              switch (adev_action) {
++              case ADEV_NONE:
++                      break;
++              case ADEV_NOTIFY_USB_AND_QUEUE_VDM:
++                      WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB, NULL));
++                      typec_altmode_vdm(adev, p[0], &p[1], cnt);
++                      break;
++              case ADEV_QUEUE_VDM:
++                      typec_altmode_vdm(adev, p[0], &p[1], cnt);
++                      break;
++              case ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL:
++                      if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) {
++                              response[0] = VDO(adev->svid, 1, CMD_EXIT_MODE);
++                              response[0] |= VDO_OPOS(adev->mode);
++                              rlen = 1;
++                      }
++                      break;
++              case ADEV_ATTENTION:
++                      typec_altmode_attention(adev, p[1]);
++                      break;
++              }
++      }
+       if (rlen > 0) {
+               tcpm_queue_vdm(port, response[0], &response[1], rlen - 1);
+-- 
+2.40.1
+