From: Sasha Levin Date: Mon, 26 Feb 2024 22:21:33 +0000 (-0500) Subject: Fixes for 6.1 X-Git-Tag: v4.19.308~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3a583d81e4a4d849c98af11d2889f77244dedc54;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/afs-increase-buffer-size-in-afs_update_volume_status.patch b/queue-6.1/afs-increase-buffer-size-in-afs_update_volume_status.patch new file mode 100644 index 00000000000..3be26c60e21 --- /dev/null +++ b/queue-6.1/afs-increase-buffer-size-in-afs_update_volume_status.patch @@ -0,0 +1,53 @@ +From a65752a6372cfe2f82366306ffe39165b8f9c361 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Feb 2024 14:39:03 +0000 +Subject: afs: Increase buffer size in afs_update_volume_status() + +From: Daniil Dulov + +[ Upstream commit 6ea38e2aeb72349cad50e38899b0ba6fbcb2af3d ] + +The max length of volume->vid value is 20 characters. +So increase idbuf[] size up to 24 to avoid overflow. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +[DH: Actually, it's 20 + NUL, so increase it to 24 and use snprintf()] + +Fixes: d2ddc776a458 ("afs: Overhaul volume and server record caching and fileserver rotation") +Signed-off-by: Daniil Dulov +Signed-off-by: David Howells +Link: https://lore.kernel.org/r/20240211150442.3416-1-d.dulov@aladdin.ru/ # v1 +Link: https://lore.kernel.org/r/20240212083347.10742-1-d.dulov@aladdin.ru/ # v2 +Link: https://lore.kernel.org/r/20240219143906.138346-3-dhowells@redhat.com +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/afs/volume.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/afs/volume.c b/fs/afs/volume.c +index 1c9144e3e83ac..a146d70efa650 100644 +--- a/fs/afs/volume.c ++++ b/fs/afs/volume.c +@@ -341,7 +341,7 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) + { + struct afs_server_list *new, *old, *discard; + struct afs_vldb_entry *vldb; +- char idbuf[16]; ++ char idbuf[24]; + int ret, idsz; + + _enter(""); +@@ -349,7 +349,7 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) + /* We look up an ID by passing it as a decimal string in the + * operation's name parameter. + */ +- idsz = sprintf(idbuf, "%llu", volume->vid); ++ idsz = snprintf(idbuf, sizeof(idbuf), "%llu", volume->vid); + + vldb = afs_vl_lookup_vldb(volume->cell, key, idbuf, idsz); + if (IS_ERR(vldb)) { +-- +2.43.0 + diff --git a/queue-6.1/arm64-dts-rockchip-set-num-cs-property-for-spi-on-px.patch b/queue-6.1/arm64-dts-rockchip-set-num-cs-property-for-spi-on-px.patch new file mode 100644 index 00000000000..a6dff74cf78 --- /dev/null +++ b/queue-6.1/arm64-dts-rockchip-set-num-cs-property-for-spi-on-px.patch @@ -0,0 +1,50 @@ +From 0fde352f5cd32e52437427f3f3afd3c7e20b4792 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Jan 2024 11:16:56 +0100 +Subject: arm64: dts: rockchip: set num-cs property for spi on px30 + +From: Heiko Stuebner + +[ Upstream commit 334bf0710c98d391f4067b72f535d6c4c84dfb6f ] + +The px30 has two spi controllers with two chip-selects each. +The num-cs property is specified as the total number of chip +selects a controllers has and is used since 2020 to find uses +of chipselects outside that range in the Rockchip spi driver. + +Without the property set, the default is 1, so spi devices +using the second chipselect will not be created. + +Fixes: eb1262e3cc8b ("spi: spi-rockchip: use num-cs property and ctlr->enable_gpiods") +Signed-off-by: Heiko Stuebner +Reviewed-by: Quentin Schulz +Link: https://lore.kernel.org/r/20240119101656.965744-1-heiko@sntech.de +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/px30.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi +index bfa3580429d10..61f0186447dad 100644 +--- a/arch/arm64/boot/dts/rockchip/px30.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30.dtsi +@@ -607,6 +607,7 @@ + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac 12>, <&dmac 13>; + dma-names = "tx", "rx"; ++ num-cs = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>; + #address-cells = <1>; +@@ -622,6 +623,7 @@ + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac 14>, <&dmac 15>; + dma-names = "tx", "rx"; ++ num-cs = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>; + #address-cells = <1>; +-- +2.43.0 + diff --git a/queue-6.1/arm64-sme-restore-sme-registers-on-exit-from-suspend.patch b/queue-6.1/arm64-sme-restore-sme-registers-on-exit-from-suspend.patch new file mode 100644 index 00000000000..ac143b79714 --- /dev/null +++ b/queue-6.1/arm64-sme-restore-sme-registers-on-exit-from-suspend.patch @@ -0,0 +1,98 @@ +From d9397ef594bd26a946745e7f94e350618f180d2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 23:06:32 +0000 +Subject: arm64/sme: Restore SME registers on exit from suspend + +From: Mark Brown + +[ Upstream commit 9533864816fb4a6207c63b7a98396351ce1a9fae ] + +The fields in SMCR_EL1 and SMPRI_EL1 reset to an architecturally UNKNOWN +value. Since we do not otherwise manage the traps configured in this +register at runtime we need to reconfigure them after a suspend in case +nothing else was kind enough to preserve them for us. + +The vector length will be restored as part of restoring the SME state for +the next SME using task. + +Fixes: a1f4ccd25cc2 ("arm64/sme: Provide Kconfig for SME") +Reported-by: Jackson Cooper-Driver +Signed-off-by: Mark Brown +Link: https://lore.kernel.org/r/20240213-arm64-sme-resume-v3-1-17e05e493471@kernel.org +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + arch/arm64/include/asm/fpsimd.h | 2 ++ + arch/arm64/kernel/fpsimd.c | 14 ++++++++++++++ + arch/arm64/kernel/suspend.c | 3 +++ + 3 files changed, 19 insertions(+) + +diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h +index d720b6f7e5f9c..da18413712c04 100644 +--- a/arch/arm64/include/asm/fpsimd.h ++++ b/arch/arm64/include/asm/fpsimd.h +@@ -343,6 +343,7 @@ extern void sme_alloc(struct task_struct *task, bool flush); + extern unsigned int sme_get_vl(void); + extern int sme_set_current_vl(unsigned long arg); + extern int sme_get_current_vl(void); ++extern void sme_suspend_exit(void); + + /* + * Return how many bytes of memory are required to store the full SME +@@ -372,6 +373,7 @@ static inline int sme_max_vl(void) { return 0; } + static inline int sme_max_virtualisable_vl(void) { return 0; } + static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; } + static inline int sme_get_current_vl(void) { return -EINVAL; } ++static inline void sme_suspend_exit(void) { } + + static inline size_t za_state_size(struct task_struct const *task) + { +diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c +index 8c226d79abdfc..59b5a16bab5d6 100644 +--- a/arch/arm64/kernel/fpsimd.c ++++ b/arch/arm64/kernel/fpsimd.c +@@ -1347,6 +1347,20 @@ void __init sme_setup(void) + get_sme_default_vl()); + } + ++void sme_suspend_exit(void) ++{ ++ u64 smcr = 0; ++ ++ if (!system_supports_sme()) ++ return; ++ ++ if (system_supports_fa64()) ++ smcr |= SMCR_ELx_FA64; ++ ++ write_sysreg_s(smcr, SYS_SMCR_EL1); ++ write_sysreg_s(0, SYS_SMPRI_EL1); ++} ++ + #endif /* CONFIG_ARM64_SME */ + + static void sve_init_regs(void) +diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c +index 8b02d310838f9..064d996cc55b2 100644 +--- a/arch/arm64/kernel/suspend.c ++++ b/arch/arm64/kernel/suspend.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -77,6 +78,8 @@ void notrace __cpu_suspend_exit(void) + */ + spectre_v4_enable_mitigation(NULL); + ++ sme_suspend_exit(); ++ + /* Restore additional feature-specific configuration */ + ptrauth_suspend_exit(); + } +-- +2.43.0 + diff --git a/queue-6.1/ata-ahci_ceva-fix-error-handling-for-xilinx-gt-phy-s.patch b/queue-6.1/ata-ahci_ceva-fix-error-handling-for-xilinx-gt-phy-s.patch new file mode 100644 index 00000000000..822625742a2 --- /dev/null +++ b/queue-6.1/ata-ahci_ceva-fix-error-handling-for-xilinx-gt-phy-s.patch @@ -0,0 +1,245 @@ +From f3c32de86f769a5d6ee79bc5ddc66e2b1b939948 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Feb 2024 23:44:57 +0530 +Subject: ata: ahci_ceva: fix error handling for Xilinx GT PHY support + +From: Radhey Shyam Pandey + +[ Upstream commit 26c8404e162b43dddcb037ba2d0cb58c0ed60aab ] + +Platform clock and phy error resources are not cleaned up in Xilinx GT PHY +error path. + +To fix introduce the function ceva_ahci_platform_enable_resources() which +is a customized version of ahci_platform_enable_resources() and inline with +SATA IP programming sequence it does: + +- Assert SATA reset +- Program PS GTR phy +- Bring SATA by de-asserting the reset +- Wait for GT lane PLL to be locked + +ceva_ahci_platform_enable_resources() is also used in the resume path +as the same SATA programming sequence (as in probe) should be followed. +Also cleanup the mixed usage of ahci_platform_enable_resources() and custom +implementation in the probe function as both are not required. + +Fixes: 9a9d3abe24bb ("ata: ahci: ceva: Update the driver to support xilinx GT phy") +Signed-off-by: Radhey Shyam Pandey +Reviewed-by: Damien Le Moal +Signed-off-by: Niklas Cassel +Signed-off-by: Sasha Levin +--- + drivers/ata/ahci_ceva.c | 125 +++++++++++++++++++++++++--------------- + 1 file changed, 79 insertions(+), 46 deletions(-) + +diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c +index cb24ecf36fafe..50e07ea60e45c 100644 +--- a/drivers/ata/ahci_ceva.c ++++ b/drivers/ata/ahci_ceva.c +@@ -88,7 +88,6 @@ struct ceva_ahci_priv { + u32 axicc; + bool is_cci_enabled; + int flags; +- struct reset_control *rst; + }; + + static unsigned int ceva_ahci_read_id(struct ata_device *dev, +@@ -189,6 +188,60 @@ static struct scsi_host_template ahci_platform_sht = { + AHCI_SHT(DRV_NAME), + }; + ++static int ceva_ahci_platform_enable_resources(struct ahci_host_priv *hpriv) ++{ ++ int rc, i; ++ ++ rc = ahci_platform_enable_regulators(hpriv); ++ if (rc) ++ return rc; ++ ++ rc = ahci_platform_enable_clks(hpriv); ++ if (rc) ++ goto disable_regulator; ++ ++ /* Assert the controller reset */ ++ rc = ahci_platform_assert_rsts(hpriv); ++ if (rc) ++ goto disable_clks; ++ ++ for (i = 0; i < hpriv->nports; i++) { ++ rc = phy_init(hpriv->phys[i]); ++ if (rc) ++ goto disable_rsts; ++ } ++ ++ /* De-assert the controller reset */ ++ ahci_platform_deassert_rsts(hpriv); ++ ++ for (i = 0; i < hpriv->nports; i++) { ++ rc = phy_power_on(hpriv->phys[i]); ++ if (rc) { ++ phy_exit(hpriv->phys[i]); ++ goto disable_phys; ++ } ++ } ++ ++ return 0; ++ ++disable_rsts: ++ ahci_platform_deassert_rsts(hpriv); ++ ++disable_phys: ++ while (--i >= 0) { ++ phy_power_off(hpriv->phys[i]); ++ phy_exit(hpriv->phys[i]); ++ } ++ ++disable_clks: ++ ahci_platform_disable_clks(hpriv); ++ ++disable_regulator: ++ ahci_platform_disable_regulators(hpriv); ++ ++ return rc; ++} ++ + static int ceva_ahci_probe(struct platform_device *pdev) + { + struct device_node *np = pdev->dev.of_node; +@@ -203,47 +256,19 @@ static int ceva_ahci_probe(struct platform_device *pdev) + return -ENOMEM; + + cevapriv->ahci_pdev = pdev; +- +- cevapriv->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, +- NULL); +- if (IS_ERR(cevapriv->rst)) +- dev_err_probe(&pdev->dev, PTR_ERR(cevapriv->rst), +- "failed to get reset\n"); +- + hpriv = ahci_platform_get_resources(pdev, 0); + if (IS_ERR(hpriv)) + return PTR_ERR(hpriv); + +- if (!cevapriv->rst) { +- rc = ahci_platform_enable_resources(hpriv); +- if (rc) +- return rc; +- } else { +- int i; ++ hpriv->rsts = devm_reset_control_get_optional_exclusive(&pdev->dev, ++ NULL); ++ if (IS_ERR(hpriv->rsts)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(hpriv->rsts), ++ "failed to get reset\n"); + +- rc = ahci_platform_enable_clks(hpriv); +- if (rc) +- return rc; +- /* Assert the controller reset */ +- reset_control_assert(cevapriv->rst); +- +- for (i = 0; i < hpriv->nports; i++) { +- rc = phy_init(hpriv->phys[i]); +- if (rc) +- return rc; +- } +- +- /* De-assert the controller reset */ +- reset_control_deassert(cevapriv->rst); +- +- for (i = 0; i < hpriv->nports; i++) { +- rc = phy_power_on(hpriv->phys[i]); +- if (rc) { +- phy_exit(hpriv->phys[i]); +- return rc; +- } +- } +- } ++ rc = ceva_ahci_platform_enable_resources(hpriv); ++ if (rc) ++ return rc; + + if (of_property_read_bool(np, "ceva,broken-gen2")) + cevapriv->flags = CEVA_FLAG_BROKEN_GEN2; +@@ -252,52 +277,60 @@ static int ceva_ahci_probe(struct platform_device *pdev) + if (of_property_read_u8_array(np, "ceva,p0-cominit-params", + (u8 *)&cevapriv->pp2c[0], 4) < 0) { + dev_warn(dev, "ceva,p0-cominit-params property not defined\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto disable_resources; + } + + if (of_property_read_u8_array(np, "ceva,p1-cominit-params", + (u8 *)&cevapriv->pp2c[1], 4) < 0) { + dev_warn(dev, "ceva,p1-cominit-params property not defined\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto disable_resources; + } + + /* Read OOB timing value for COMWAKE from device-tree*/ + if (of_property_read_u8_array(np, "ceva,p0-comwake-params", + (u8 *)&cevapriv->pp3c[0], 4) < 0) { + dev_warn(dev, "ceva,p0-comwake-params property not defined\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto disable_resources; + } + + if (of_property_read_u8_array(np, "ceva,p1-comwake-params", + (u8 *)&cevapriv->pp3c[1], 4) < 0) { + dev_warn(dev, "ceva,p1-comwake-params property not defined\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto disable_resources; + } + + /* Read phy BURST timing value from device-tree */ + if (of_property_read_u8_array(np, "ceva,p0-burst-params", + (u8 *)&cevapriv->pp4c[0], 4) < 0) { + dev_warn(dev, "ceva,p0-burst-params property not defined\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto disable_resources; + } + + if (of_property_read_u8_array(np, "ceva,p1-burst-params", + (u8 *)&cevapriv->pp4c[1], 4) < 0) { + dev_warn(dev, "ceva,p1-burst-params property not defined\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto disable_resources; + } + + /* Read phy RETRY interval timing value from device-tree */ + if (of_property_read_u16_array(np, "ceva,p0-retry-params", + (u16 *)&cevapriv->pp5c[0], 2) < 0) { + dev_warn(dev, "ceva,p0-retry-params property not defined\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto disable_resources; + } + + if (of_property_read_u16_array(np, "ceva,p1-retry-params", + (u16 *)&cevapriv->pp5c[1], 2) < 0) { + dev_warn(dev, "ceva,p1-retry-params property not defined\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto disable_resources; + } + + /* +@@ -335,7 +368,7 @@ static int __maybe_unused ceva_ahci_resume(struct device *dev) + struct ahci_host_priv *hpriv = host->private_data; + int rc; + +- rc = ahci_platform_enable_resources(hpriv); ++ rc = ceva_ahci_platform_enable_resources(hpriv); + if (rc) + return rc; + +-- +2.43.0 + diff --git a/queue-6.1/bpf-fix-racing-between-bpf_timer_cancel_and_free-and.patch b/queue-6.1/bpf-fix-racing-between-bpf_timer_cancel_and_free-and.patch new file mode 100644 index 00000000000..a52379847ba --- /dev/null +++ b/queue-6.1/bpf-fix-racing-between-bpf_timer_cancel_and_free-and.patch @@ -0,0 +1,98 @@ +From b40a1d11ef5753f5ad57c0f6c6fd13daef0a1ad4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 13:12:17 -0800 +Subject: bpf: Fix racing between bpf_timer_cancel_and_free and + bpf_timer_cancel + +From: Martin KaFai Lau + +[ Upstream commit 0281b919e175bb9c3128bd3872ac2903e9436e3f ] + +The following race is possible between bpf_timer_cancel_and_free +and bpf_timer_cancel. It will lead a UAF on the timer->timer. + +bpf_timer_cancel(); + spin_lock(); + t = timer->time; + spin_unlock(); + + bpf_timer_cancel_and_free(); + spin_lock(); + t = timer->timer; + timer->timer = NULL; + spin_unlock(); + hrtimer_cancel(&t->timer); + kfree(t); + + /* UAF on t */ + hrtimer_cancel(&t->timer); + +In bpf_timer_cancel_and_free, this patch frees the timer->timer +after a rcu grace period. This requires a rcu_head addition +to the "struct bpf_hrtimer". Another kfree(t) happens in bpf_timer_init, +this does not need a kfree_rcu because it is still under the +spin_lock and timer->timer has not been visible by others yet. + +In bpf_timer_cancel, rcu_read_lock() is added because this helper +can be used in a non rcu critical section context (e.g. from +a sleepable bpf prog). Other timer->timer usages in helpers.c +have been audited, bpf_timer_cancel() is the only place where +timer->timer is used outside of the spin_lock. + +Another solution considered is to mark a t->flag in bpf_timer_cancel +and clear it after hrtimer_cancel() is done. In bpf_timer_cancel_and_free, +it busy waits for the flag to be cleared before kfree(t). This patch +goes with a straight forward solution and frees timer->timer after +a rcu grace period. + +Fixes: b00628b1c7d5 ("bpf: Introduce bpf timers.") +Suggested-by: Alexei Starovoitov +Signed-off-by: Martin KaFai Lau +Signed-off-by: Daniel Borkmann +Acked-by: Hou Tao +Link: https://lore.kernel.org/bpf/20240215211218.990808-1-martin.lau@linux.dev +Signed-off-by: Sasha Levin +--- + kernel/bpf/helpers.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c +index 6a61a98d602cd..83f8f67e933df 100644 +--- a/kernel/bpf/helpers.c ++++ b/kernel/bpf/helpers.c +@@ -1091,6 +1091,7 @@ struct bpf_hrtimer { + struct bpf_prog *prog; + void __rcu *callback_fn; + void *value; ++ struct rcu_head rcu; + }; + + /* the actual struct hidden inside uapi struct bpf_timer */ +@@ -1312,6 +1313,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_timer_kern *, timer) + + if (in_nmi()) + return -EOPNOTSUPP; ++ rcu_read_lock(); + __bpf_spin_lock_irqsave(&timer->lock); + t = timer->timer; + if (!t) { +@@ -1333,6 +1335,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_timer_kern *, timer) + * if it was running. + */ + ret = ret ?: hrtimer_cancel(&t->timer); ++ rcu_read_unlock(); + return ret; + } + +@@ -1387,7 +1390,7 @@ void bpf_timer_cancel_and_free(void *val) + */ + if (this_cpu_read(hrtimer_running) != t) + hrtimer_cancel(&t->timer); +- kfree(t); ++ kfree_rcu(t, rcu); + } + + BPF_CALL_2(bpf_kptr_xchg, void *, map_value, void *, ptr) +-- +2.43.0 + diff --git a/queue-6.1/bpf-scripts-correct-gpl-license-name.patch b/queue-6.1/bpf-scripts-correct-gpl-license-name.patch new file mode 100644 index 00000000000..e728074cc03 --- /dev/null +++ b/queue-6.1/bpf-scripts-correct-gpl-license-name.patch @@ -0,0 +1,41 @@ +From 9927185100ea7644df6d3daa30f9300cfbcdd86a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 23:05:46 +0000 +Subject: bpf, scripts: Correct GPL license name + +From: Gianmarco Lusvardi + +[ Upstream commit e37243b65d528a8a9f8b9a57a43885f8e8dfc15c ] + +The bpf_doc script refers to the GPL as the "GNU Privacy License". +I strongly suspect that the author wanted to refer to the GNU General +Public License, under which the Linux kernel is released, as, to the +best of my knowledge, there is no license named "GNU Privacy License". +This patch corrects the license name in the script accordingly. + +Fixes: 56a092c89505 ("bpf: add script and prepare bpf.h for new helpers documentation") +Signed-off-by: Gianmarco Lusvardi +Signed-off-by: Daniel Borkmann +Reviewed-by: Quentin Monnet +Link: https://lore.kernel.org/bpf/20240213230544.930018-3-glusvardi@posteo.net +Signed-off-by: Sasha Levin +--- + scripts/bpf_doc.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py +index d5c389df6045e..4de98b7bbea95 100755 +--- a/scripts/bpf_doc.py ++++ b/scripts/bpf_doc.py +@@ -495,7 +495,7 @@ eBPF programs can have an associated license, passed along with the bytecode + instructions to the kernel when the programs are loaded. The format for that + string is identical to the one in use for kernel modules (Dual licenses, such + as "Dual BSD/GPL", may be used). Some helper functions are only accessible to +-programs that are compatible with the GNU Privacy License (GPL). ++programs that are compatible with the GNU General Public License (GNU GPL). + + In order to use such helpers, the eBPF program must be loaded with the correct + license string passed (via **attr**) to the **bpf**\ () system call, and this +-- +2.43.0 + diff --git a/queue-6.1/bpf-sockmap-fix-null-pointer-dereference-in-sk_psock.patch b/queue-6.1/bpf-sockmap-fix-null-pointer-dereference-in-sk_psock.patch new file mode 100644 index 00000000000..006903c0e9e --- /dev/null +++ b/queue-6.1/bpf-sockmap-fix-null-pointer-dereference-in-sk_psock.patch @@ -0,0 +1,69 @@ +From 2bdda0d2f8d6d6a45074bcc1d06a26f6f8158438 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Feb 2024 00:09:33 +0900 +Subject: bpf, sockmap: Fix NULL pointer dereference in + sk_psock_verdict_data_ready() + +From: Shigeru Yoshida + +[ Upstream commit 4cd12c6065dfcdeba10f49949bffcf383b3952d8 ] + +syzbot reported the following NULL pointer dereference issue [1]: + + BUG: kernel NULL pointer dereference, address: 0000000000000000 + [...] + RIP: 0010:0x0 + [...] + Call Trace: + + sk_psock_verdict_data_ready+0x232/0x340 net/core/skmsg.c:1230 + unix_stream_sendmsg+0x9b4/0x1230 net/unix/af_unix.c:2293 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg+0x221/0x270 net/socket.c:745 + ____sys_sendmsg+0x525/0x7d0 net/socket.c:2584 + ___sys_sendmsg net/socket.c:2638 [inline] + __sys_sendmsg+0x2b0/0x3a0 net/socket.c:2667 + do_syscall_64+0xf9/0x240 + entry_SYSCALL_64_after_hwframe+0x6f/0x77 + +If sk_psock_verdict_data_ready() and sk_psock_stop_verdict() are called +concurrently, psock->saved_data_ready can be NULL, causing the above issue. + +This patch fixes this issue by calling the appropriate data ready function +using the sk_psock_data_ready() helper and protecting it from concurrency +with sk->sk_callback_lock. + +Fixes: 6df7f764cd3c ("bpf, sockmap: Wake up polling after data copy") +Reported-by: syzbot+fd7b34375c1c8ce29c93@syzkaller.appspotmail.com +Signed-off-by: Shigeru Yoshida +Signed-off-by: Daniel Borkmann +Tested-by: syzbot+fd7b34375c1c8ce29c93@syzkaller.appspotmail.com +Acked-by: John Fastabend +Closes: https://syzkaller.appspot.com/bug?extid=fd7b34375c1c8ce29c93 [1] +Link: https://lore.kernel.org/bpf/20240218150933.6004-1-syoshida@redhat.com +Signed-off-by: Sasha Levin +--- + net/core/skmsg.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/net/core/skmsg.c b/net/core/skmsg.c +index 3818035ea0021..39643f78cf782 100644 +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -1217,8 +1217,11 @@ static void sk_psock_verdict_data_ready(struct sock *sk) + + rcu_read_lock(); + psock = sk_psock(sk); +- if (psock) +- psock->saved_data_ready(sk); ++ if (psock) { ++ read_lock_bh(&sk->sk_callback_lock); ++ sk_psock_data_ready(sk, psock); ++ read_unlock_bh(&sk->sk_callback_lock); ++ } + rcu_read_unlock(); + } + } +-- +2.43.0 + diff --git a/queue-6.1/dccp-tcp-unhash-sk-from-ehash-for-tb2-alloc-failure-.patch b/queue-6.1/dccp-tcp-unhash-sk-from-ehash-for-tb2-alloc-failure-.patch new file mode 100644 index 00000000000..4d15ea1034b --- /dev/null +++ b/queue-6.1/dccp-tcp-unhash-sk-from-ehash-for-tb2-alloc-failure-.patch @@ -0,0 +1,157 @@ +From 7d0af6406456ee500c384154aea5ac25a7e2afae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 11:13:08 -0800 +Subject: dccp/tcp: Unhash sk from ehash for tb2 alloc failure after + check_estalblished(). + +From: Kuniyuki Iwashima + +[ Upstream commit 66b60b0c8c4a163b022a9f0ad6769b0fd3dc662f ] + +syzkaller reported a warning [0] in inet_csk_destroy_sock() with no +repro. + + WARN_ON(inet_sk(sk)->inet_num && !inet_csk(sk)->icsk_bind_hash); + +However, the syzkaller's log hinted that connect() failed just before +the warning due to FAULT_INJECTION. [1] + +When connect() is called for an unbound socket, we search for an +available ephemeral port. If a bhash bucket exists for the port, we +call __inet_check_established() or __inet6_check_established() to check +if the bucket is reusable. + +If reusable, we add the socket into ehash and set inet_sk(sk)->inet_num. + +Later, we look up the corresponding bhash2 bucket and try to allocate +it if it does not exist. + +Although it rarely occurs in real use, if the allocation fails, we must +revert the changes by check_established(). Otherwise, an unconnected +socket could illegally occupy an ehash entry. + +Note that we do not put tw back into ehash because sk might have +already responded to a packet for tw and it would be better to free +tw earlier under such memory presure. + +[0]: +WARNING: CPU: 0 PID: 350830 at net/ipv4/inet_connection_sock.c:1193 inet_csk_destroy_sock (net/ipv4/inet_connection_sock.c:1193) +Modules linked in: +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 +RIP: 0010:inet_csk_destroy_sock (net/ipv4/inet_connection_sock.c:1193) +Code: 41 5c 41 5d 41 5e e9 2d 4a 3d fd e8 28 4a 3d fd 48 89 ef e8 f0 cd 7d ff 5b 5d 41 5c 41 5d 41 5e e9 13 4a 3d fd e8 0e 4a 3d fd <0f> 0b e9 61 fe ff ff e8 02 4a 3d fd 4c 89 e7 be 03 00 00 00 e8 05 +RSP: 0018:ffffc9000b21fd38 EFLAGS: 00010293 +RAX: 0000000000000000 RBX: 0000000000009e78 RCX: ffffffff840bae40 +RDX: ffff88806e46c600 RSI: ffffffff840bb012 RDI: ffff88811755cca8 +RBP: ffff88811755c880 R08: 0000000000000003 R09: 0000000000000000 +R10: 0000000000009e78 R11: 0000000000000000 R12: ffff88811755c8e0 +R13: ffff88811755c892 R14: ffff88811755c918 R15: 0000000000000000 +FS: 00007f03e5243800(0000) GS:ffff88811ae00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000001b32f21000 CR3: 0000000112ffe001 CR4: 0000000000770ef0 +PKRU: 55555554 +Call Trace: + + ? inet_csk_destroy_sock (net/ipv4/inet_connection_sock.c:1193) + dccp_close (net/dccp/proto.c:1078) + inet_release (net/ipv4/af_inet.c:434) + __sock_release (net/socket.c:660) + sock_close (net/socket.c:1423) + __fput (fs/file_table.c:377) + __fput_sync (fs/file_table.c:462) + __x64_sys_close (fs/open.c:1557 fs/open.c:1539 fs/open.c:1539) + do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129) +RIP: 0033:0x7f03e53852bb +Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 43 c9 f5 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 89 44 24 0c e8 a1 c9 f5 ff 8b 44 +RSP: 002b:00000000005dfba0 EFLAGS: 00000293 ORIG_RAX: 0000000000000003 +RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007f03e53852bb +RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000003 +RBP: 0000000000000000 R08: 0000000000000000 R09: 000000000000167c +R10: 0000000008a79680 R11: 0000000000000293 R12: 00007f03e4e43000 +R13: 00007f03e4e43170 R14: 00007f03e4e43178 R15: 00007f03e4e43170 + + +[1]: +FAULT_INJECTION: forcing a failure. +name failslab, interval 1, probability 0, space 0, times 0 +CPU: 0 PID: 350833 Comm: syz-executor.1 Not tainted 6.7.0-12272-g2121c43f88f5 #9 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 +Call Trace: + + dump_stack_lvl (lib/dump_stack.c:107 (discriminator 1)) + should_fail_ex (lib/fault-inject.c:52 lib/fault-inject.c:153) + should_failslab (mm/slub.c:3748) + kmem_cache_alloc (mm/slub.c:3763 mm/slub.c:3842 mm/slub.c:3867) + inet_bind2_bucket_create (net/ipv4/inet_hashtables.c:135) + __inet_hash_connect (net/ipv4/inet_hashtables.c:1100) + dccp_v4_connect (net/dccp/ipv4.c:116) + __inet_stream_connect (net/ipv4/af_inet.c:676) + inet_stream_connect (net/ipv4/af_inet.c:747) + __sys_connect_file (net/socket.c:2048 (discriminator 2)) + __sys_connect (net/socket.c:2065) + __x64_sys_connect (net/socket.c:2072) + do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129) +RIP: 0033:0x7f03e5284e5d +Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48 +RSP: 002b:00007f03e4641cc8 EFLAGS: 00000246 ORIG_RAX: 000000000000002a +RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007f03e5284e5d +RDX: 0000000000000010 RSI: 0000000020000000 RDI: 0000000000000003 +RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001 +R13: 000000000000000b R14: 00007f03e52e5530 R15: 0000000000000000 + + +Reported-by: syzkaller +Fixes: 28044fc1d495 ("net: Add a bhash2 table hashed by port and address") +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/inet_hashtables.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index f2ed2aed08ab3..56776e1b1de52 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -1111,10 +1111,33 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, + return 0; + + error: ++ if (sk_hashed(sk)) { ++ spinlock_t *lock = inet_ehash_lockp(hinfo, sk->sk_hash); ++ ++ sock_prot_inuse_add(net, sk->sk_prot, -1); ++ ++ spin_lock(lock); ++ sk_nulls_del_node_init_rcu(sk); ++ spin_unlock(lock); ++ ++ sk->sk_hash = 0; ++ inet_sk(sk)->inet_sport = 0; ++ inet_sk(sk)->inet_num = 0; ++ ++ if (tw) ++ inet_twsk_bind_unhash(tw, hinfo); ++ } ++ + spin_unlock(&head2->lock); + if (tb_created) + inet_bind_bucket_destroy(hinfo->bind_bucket_cachep, tb); +- spin_unlock_bh(&head->lock); ++ spin_unlock(&head->lock); ++ ++ if (tw) ++ inet_twsk_deschedule_put(tw); ++ ++ local_bh_enable(); ++ + return -ENOMEM; + } + +-- +2.43.0 + diff --git a/queue-6.1/drm-amd-display-fix-memory-leak-in-dm_sw_fini.patch b/queue-6.1/drm-amd-display-fix-memory-leak-in-dm_sw_fini.patch new file mode 100644 index 00000000000..3127fae1b44 --- /dev/null +++ b/queue-6.1/drm-amd-display-fix-memory-leak-in-dm_sw_fini.patch @@ -0,0 +1,60 @@ +From 55f59837c7ffbd5e784366e4e70f4f08e752056c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 01:50:50 +0100 +Subject: drm/amd/display: Fix memory leak in dm_sw_fini() + +From: Armin Wolf + +[ Upstream commit bae67893578d608e35691dcdfa90c4957debf1d3 ] + +After destroying dmub_srv, the memory associated with it is +not freed, causing a memory leak: + +unreferenced object 0xffff896302b45800 (size 1024): + comm "(udev-worker)", pid 222, jiffies 4294894636 + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 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 (crc 6265fd77): + [] kmalloc_trace+0x29d/0x340 + [] dm_dmub_sw_init+0xb4/0x450 [amdgpu] + [] dm_sw_init+0x15/0x2b0 [amdgpu] + [] amdgpu_device_init+0x1417/0x24e0 [amdgpu] + [] amdgpu_driver_load_kms+0x15/0x190 [amdgpu] + [] amdgpu_pci_probe+0x187/0x4e0 [amdgpu] + [] local_pci_probe+0x3e/0x90 + [] pci_device_probe+0xc3/0x230 + [] really_probe+0xe2/0x480 + [] __driver_probe_device+0x78/0x160 + [] driver_probe_device+0x1f/0x90 + [] __driver_attach+0xce/0x1c0 + [] bus_for_each_dev+0x70/0xc0 + [] bus_add_driver+0x112/0x210 + [] driver_register+0x55/0x100 + [] do_one_initcall+0x41/0x300 + +Fix this by freeing dmub_srv after destroying it. + +Fixes: 743b9786b14a ("drm/amd/display: Hook up the DMUB service in DM") +Signed-off-by: Armin Wolf +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index a826c92933199..da16048bf1004 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2255,6 +2255,7 @@ static int dm_sw_fini(void *handle) + + if (adev->dm.dmub_srv) { + dmub_srv_destroy(adev->dm.dmub_srv); ++ kfree(adev->dm.dmub_srv); + adev->dm.dmub_srv = NULL; + } + +-- +2.43.0 + diff --git a/queue-6.1/drm-syncobj-call-drm_syncobj_fence_add_wait-when-wai.patch b/queue-6.1/drm-syncobj-call-drm_syncobj_fence_add_wait-when-wai.patch new file mode 100644 index 00000000000..c343509bdb8 --- /dev/null +++ b/queue-6.1/drm-syncobj-call-drm_syncobj_fence_add_wait-when-wai.patch @@ -0,0 +1,75 @@ +From 69fbeb6ad5938362c0c75b25b5d16f858260b813 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Jan 2024 08:32:06 -0800 +Subject: drm/syncobj: call drm_syncobj_fence_add_wait when WAIT_AVAILABLE flag + is set + +From: Erik Kurzinger + +[ Upstream commit 3c43177ffb54ea5be97505eb8e2690e99ac96bc9 ] + +When waiting for a syncobj timeline point whose fence has not yet been +submitted with the WAIT_FOR_SUBMIT flag, a callback is registered using +drm_syncobj_fence_add_wait and the thread is put to sleep until the +timeout expires. If the fence is submitted before then, +drm_syncobj_add_point will wake up the sleeping thread immediately which +will proceed to wait for the fence to be signaled. + +However, if the WAIT_AVAILABLE flag is used instead, +drm_syncobj_fence_add_wait won't get called, meaning the waiting thread +will always sleep for the full timeout duration, even if the fence gets +submitted earlier. If it turns out that the fence *has* been submitted +by the time it eventually wakes up, it will still indicate to userspace +that the wait completed successfully (it won't return -ETIME), but it +will have taken much longer than it should have. + +To fix this, we must call drm_syncobj_fence_add_wait if *either* the +WAIT_FOR_SUBMIT flag or the WAIT_AVAILABLE flag is set. The only +difference being that with WAIT_FOR_SUBMIT we will also wait for the +fence to be signaled after it has been submitted while with +WAIT_AVAILABLE we will return immediately. + +IGT test patch: https://lists.freedesktop.org/archives/igt-dev/2024-January/067537.html + +v1 -> v2: adjust lockdep_assert_none_held_once condition + +(cherry picked from commit 8c44ea81634a4a337df70a32621a5f3791be23df) + +Fixes: 01d6c3578379 ("drm/syncobj: add support for timeline point wait v8") +Signed-off-by: Erik Kurzinger +Signed-off-by: Simon Ser +Reviewed-by: Daniel Vetter +Reviewed-by: Simon Ser +Link: https://patchwork.freedesktop.org/patch/msgid/20240119163208.3723457-1-ekurzinger@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_syncobj.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c +index da0145bc104a8..8f2737075dc2f 100644 +--- a/drivers/gpu/drm/drm_syncobj.c ++++ b/drivers/gpu/drm/drm_syncobj.c +@@ -980,7 +980,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, + uint64_t *points; + uint32_t signaled_count, i; + +- if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) ++ if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | ++ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) + lockdep_assert_none_held_once(); + + points = kmalloc_array(count, sizeof(*points), GFP_KERNEL); +@@ -1049,7 +1050,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, + * fallthough and try a 0 timeout wait! + */ + +- if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { ++ if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | ++ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) { + for (i = 0; i < count; ++i) + drm_syncobj_fence_add_wait(syncobjs[i], &entries[i]); + } +-- +2.43.0 + diff --git a/queue-6.1/fix-write-to-cloned-skb-in-ipv6_hop_ioam.patch b/queue-6.1/fix-write-to-cloned-skb-in-ipv6_hop_ioam.patch new file mode 100644 index 00000000000..2a3c7a4d486 --- /dev/null +++ b/queue-6.1/fix-write-to-cloned-skb-in-ipv6_hop_ioam.patch @@ -0,0 +1,56 @@ +From d5f33c4846b7832dd4325b5e021c8c101ae4bee7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Feb 2024 14:52:54 +0100 +Subject: Fix write to cloned skb in ipv6_hop_ioam() + +From: Justin Iurman + +[ Upstream commit f198d933c2e4f8f89e0620fbaf1ea7eac384a0eb ] + +ioam6_fill_trace_data() writes inside the skb payload without ensuring +it's writeable (e.g., not cloned). This function is called both from the +input and output path. The output path (ioam6_iptunnel) already does the +check. This commit provides a fix for the input path, inside +ipv6_hop_ioam(). It also updates ip6_parse_tlv() to refresh the network +header pointer ("nh") when returning from ipv6_hop_ioam(). + +Fixes: 9ee11f0fff20 ("ipv6: ioam: Data plane support for Pre-allocated Trace") +Reported-by: Paolo Abeni +Signed-off-by: Justin Iurman +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv6/exthdrs.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c +index 5fa0e37305d9d..1cfdd9d950123 100644 +--- a/net/ipv6/exthdrs.c ++++ b/net/ipv6/exthdrs.c +@@ -180,6 +180,8 @@ static bool ip6_parse_tlv(bool hopbyhop, + case IPV6_TLV_IOAM: + if (!ipv6_hop_ioam(skb, off)) + return false; ++ ++ nh = skb_network_header(skb); + break; + case IPV6_TLV_JUMBO: + if (!ipv6_hop_jumbo(skb, off)) +@@ -974,6 +976,14 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff) + if (!skb_valid_dst(skb)) + ip6_route_input(skb); + ++ /* About to mangle packet header */ ++ if (skb_ensure_writable(skb, optoff + 2 + hdr->opt_len)) ++ goto drop; ++ ++ /* Trace pointer may have changed */ ++ trace = (struct ioam6_trace_hdr *)(skb_network_header(skb) ++ + optoff + sizeof(*hdr)); ++ + ioam6_fill_trace_data(skb, ns, trace, true); + break; + default: +-- +2.43.0 + diff --git a/queue-6.1/i2c-imx-when-being-a-target-mark-the-last-read-as-pr.patch b/queue-6.1/i2c-imx-when-being-a-target-mark-the-last-read-as-pr.patch new file mode 100644 index 00000000000..e161d4ce732 --- /dev/null +++ b/queue-6.1/i2c-imx-when-being-a-target-mark-the-last-read-as-pr.patch @@ -0,0 +1,45 @@ +From 6bf36e7eb78ca226b2f1e51e83cc3bd107aec4d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Feb 2024 20:27:13 +0100 +Subject: i2c: imx: when being a target, mark the last read as processed + +From: Corey Minyard + +[ Upstream commit 87aec499368d488c20292952d6d4be7cb9e49c5e ] + +When being a target, NAK from the controller means that all bytes have +been transferred. So, the last byte needs also to be marked as +'processed'. Otherwise index registers of backends may not increase. + +Fixes: f7414cd6923f ("i2c: imx: support slave mode for imx I2C driver") +Signed-off-by: Corey Minyard +Tested-by: Andrew Manley +Reviewed-by: Andrew Manley +Reviewed-by: Oleksij Rempel +[wsa: fixed comment and commit message to properly describe the case] +Signed-off-by: Wolfram Sang +Signed-off-by: Andi Shyti +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-imx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c +index fc70920c4ddab..0c203c614197c 100644 +--- a/drivers/i2c/busses/i2c-imx.c ++++ b/drivers/i2c/busses/i2c-imx.c +@@ -804,6 +804,11 @@ static irqreturn_t i2c_imx_slave_handle(struct imx_i2c_struct *i2c_imx, + ctl &= ~I2CR_MTX; + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR); + imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); ++ ++ /* flag the last byte as processed */ ++ i2c_imx_slave_event(i2c_imx, ++ I2C_SLAVE_READ_PROCESSED, &value); ++ + i2c_imx_slave_finish_op(i2c_imx); + return IRQ_HANDLED; + } +-- +2.43.0 + diff --git a/queue-6.1/ib-hfi1-fix-a-memleak-in-init_credit_return.patch b/queue-6.1/ib-hfi1-fix-a-memleak-in-init_credit_return.patch new file mode 100644 index 00000000000..682963d8f69 --- /dev/null +++ b/queue-6.1/ib-hfi1-fix-a-memleak-in-init_credit_return.patch @@ -0,0 +1,51 @@ +From 700de167e0f662ff0bebb86d5667a690c808b492 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Jan 2024 16:55:23 +0800 +Subject: IB/hfi1: Fix a memleak in init_credit_return + +From: Zhipeng Lu + +[ Upstream commit 809aa64ebff51eb170ee31a95f83b2d21efa32e2 ] + +When dma_alloc_coherent fails to allocate dd->cr_base[i].va, +init_credit_return should deallocate dd->cr_base and +dd->cr_base[i] that allocated before. Or those resources +would be never freed and a memleak is triggered. + +Fixes: 7724105686e7 ("IB/hfi1: add driver files") +Signed-off-by: Zhipeng Lu +Link: https://lore.kernel.org/r/20240112085523.3731720-1-alexious@zju.edu.cn +Acked-by: Dennis Dalessandro +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/pio.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c +index 51ae58c02b15c..802b0e5801a7d 100644 +--- a/drivers/infiniband/hw/hfi1/pio.c ++++ b/drivers/infiniband/hw/hfi1/pio.c +@@ -2089,7 +2089,7 @@ int init_credit_return(struct hfi1_devdata *dd) + "Unable to allocate credit return DMA range for NUMA %d\n", + i); + ret = -ENOMEM; +- goto done; ++ goto free_cr_base; + } + } + set_dev_node(&dd->pcidev->dev, dd->node); +@@ -2097,6 +2097,10 @@ int init_credit_return(struct hfi1_devdata *dd) + ret = 0; + done: + return ret; ++ ++free_cr_base: ++ free_credit_return(dd); ++ goto done; + } + + void free_credit_return(struct hfi1_devdata *dd) +-- +2.43.0 + diff --git a/queue-6.1/iommufd-iova_bitmap-bounds-check-mapped-pages-access.patch b/queue-6.1/iommufd-iova_bitmap-bounds-check-mapped-pages-access.patch new file mode 100644 index 00000000000..ea989e54dc9 --- /dev/null +++ b/queue-6.1/iommufd-iova_bitmap-bounds-check-mapped-pages-access.patch @@ -0,0 +1,55 @@ +From 7bba0b52763dad2f32cf509dc2182a28561504d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 13:34:07 +0000 +Subject: iommufd/iova_bitmap: Bounds check mapped::pages access + +From: Joao Martins + +[ Upstream commit a4ab7dedaee0e39b15653c5fd0367e420739f7ef ] + +Dirty IOMMU hugepages reported on a base page page-size granularity can +lead to an attempt to set dirty pages in the bitmap beyond the limits that +are pinned. + +Bounds check the page index of the array we are trying to access is within +the limits before we kmap() and return otherwise. + +While it is also a defensive check, this is also in preparation to defer +setting bits (outside the mapped range) to the next iteration(s) when the +pages become available. + +Fixes: b058ea3ab5af ("vfio/iova_bitmap: refactor iova_bitmap_set() to better handle page boundaries") +Link: https://lore.kernel.org/r/20240202133415.23819-2-joao.m.martins@oracle.com +Signed-off-by: Joao Martins +Tested-by: Avihai Horon +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/vfio/iova_bitmap.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/vfio/iova_bitmap.c b/drivers/vfio/iova_bitmap.c +index 0f19d502f351b..5b540a164c98f 100644 +--- a/drivers/vfio/iova_bitmap.c ++++ b/drivers/vfio/iova_bitmap.c +@@ -405,6 +405,7 @@ void iova_bitmap_set(struct iova_bitmap *bitmap, + mapped->pgshift) + mapped->pgoff * BITS_PER_BYTE; + unsigned long last_bit = (((iova + length - 1) - mapped->iova) >> + mapped->pgshift) + mapped->pgoff * BITS_PER_BYTE; ++ unsigned long last_page_idx = mapped->npages - 1; + + do { + unsigned int page_idx = cur_bit / BITS_PER_PAGE; +@@ -413,6 +414,9 @@ void iova_bitmap_set(struct iova_bitmap *bitmap, + last_bit - cur_bit + 1); + void *kaddr; + ++ if (unlikely(page_idx > last_page_idx)) ++ break; ++ + kaddr = kmap_local_page(mapped->pages[page_idx]); + bitmap_set(kaddr, offset, nbits); + kunmap_local(kaddr); +-- +2.43.0 + diff --git a/queue-6.1/iommufd-iova_bitmap-consider-page-offset-for-the-pag.patch b/queue-6.1/iommufd-iova_bitmap-consider-page-offset-for-the-pag.patch new file mode 100644 index 00000000000..46ab2042a57 --- /dev/null +++ b/queue-6.1/iommufd-iova_bitmap-consider-page-offset-for-the-pag.patch @@ -0,0 +1,57 @@ +From 004a1804da6246f4cc50987a96f35a5a51e5f679 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 13:34:15 +0000 +Subject: iommufd/iova_bitmap: Consider page offset for the pages to be pinned + +From: Joao Martins + +[ Upstream commit 4bbcbc6ea2fa379632a24c14cfb47aa603816ac6 ] + +For small bitmaps that aren't PAGE_SIZE aligned *and* that are less than +512 pages in bitmap length, use an extra page to be able to cover the +entire range e.g. [1M..3G] which would be iterated more efficiently in a +single iteration, rather than two. + +Fixes: b058ea3ab5af ("vfio/iova_bitmap: refactor iova_bitmap_set() to better handle page boundaries") +Link: https://lore.kernel.org/r/20240202133415.23819-10-joao.m.martins@oracle.com +Signed-off-by: Joao Martins +Tested-by: Avihai Horon +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/vfio/iova_bitmap.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/vfio/iova_bitmap.c b/drivers/vfio/iova_bitmap.c +index c748a1e3ba53a..dfab5b742191a 100644 +--- a/drivers/vfio/iova_bitmap.c ++++ b/drivers/vfio/iova_bitmap.c +@@ -174,18 +174,19 @@ static int iova_bitmap_get(struct iova_bitmap *bitmap) + bitmap->mapped_base_index) * + sizeof(*bitmap->bitmap), PAGE_SIZE); + +- /* +- * We always cap at max number of 'struct page' a base page can fit. +- * This is, for example, on x86 means 2M of bitmap data max. +- */ +- npages = min(npages, PAGE_SIZE / sizeof(struct page *)); +- + /* + * Bitmap address to be pinned is calculated via pointer arithmetic + * with bitmap u64 word index. + */ + addr = bitmap->bitmap + bitmap->mapped_base_index; + ++ /* ++ * We always cap at max number of 'struct page' a base page can fit. ++ * This is, for example, on x86 means 2M of bitmap data max. ++ */ ++ npages = min(npages + !!offset_in_page(addr), ++ PAGE_SIZE / sizeof(struct page *)); ++ + ret = pin_user_pages_fast((unsigned long)addr, npages, + FOLL_WRITE, mapped->pages); + if (ret <= 0) +-- +2.43.0 + diff --git a/queue-6.1/iommufd-iova_bitmap-switch-iova_bitmap-bitmap-to-an-.patch b/queue-6.1/iommufd-iova_bitmap-switch-iova_bitmap-bitmap-to-an-.patch new file mode 100644 index 00000000000..74c1df75f1f --- /dev/null +++ b/queue-6.1/iommufd-iova_bitmap-switch-iova_bitmap-bitmap-to-an-.patch @@ -0,0 +1,72 @@ +From 14456a14353a37a04f39a8871b2cd65a35d84cdc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 13:34:08 +0000 +Subject: iommufd/iova_bitmap: Switch iova_bitmap::bitmap to an u8 array + +From: Joao Martins + +[ Upstream commit d18411ec305728c6371806c4fb09be07016aad0b ] + +iova_bitmap_mapped_length() don't deal correctly with the small bitmaps +(< 2M bitmaps) when the starting address isn't u64 aligned, leading to +skipping a tiny part of the IOVA range. This is materialized as not +marking data dirty that should otherwise have been. + +Fix that by using a u8 * in the internal state of IOVA bitmap. Most of the +data structures use the type of the bitmap to adjust its indexes, thus +changing the type of the bitmap decreases the granularity of the bitmap +indexes. + +Fixes: b058ea3ab5af ("vfio/iova_bitmap: refactor iova_bitmap_set() to better handle page boundaries") +Link: https://lore.kernel.org/r/20240202133415.23819-3-joao.m.martins@oracle.com +Signed-off-by: Joao Martins +Tested-by: Avihai Horon +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/vfio/iova_bitmap.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/vfio/iova_bitmap.c b/drivers/vfio/iova_bitmap.c +index 5b540a164c98f..c748a1e3ba53a 100644 +--- a/drivers/vfio/iova_bitmap.c ++++ b/drivers/vfio/iova_bitmap.c +@@ -99,7 +99,7 @@ struct iova_bitmap { + struct iova_bitmap_map mapped; + + /* userspace address of the bitmap */ +- u64 __user *bitmap; ++ u8 __user *bitmap; + + /* u64 index that @mapped points to */ + unsigned long mapped_base_index; +@@ -161,7 +161,7 @@ static int iova_bitmap_get(struct iova_bitmap *bitmap) + { + struct iova_bitmap_map *mapped = &bitmap->mapped; + unsigned long npages; +- u64 __user *addr; ++ u8 __user *addr; + long ret; + + /* +@@ -246,7 +246,7 @@ struct iova_bitmap *iova_bitmap_alloc(unsigned long iova, size_t length, + + mapped = &bitmap->mapped; + mapped->pgshift = __ffs(page_size); +- bitmap->bitmap = data; ++ bitmap->bitmap = (u8 __user *)data; + bitmap->mapped_total_index = + iova_bitmap_offset_to_index(bitmap, length - 1) + 1; + bitmap->iova = iova; +@@ -301,7 +301,7 @@ static unsigned long iova_bitmap_mapped_remaining(struct iova_bitmap *bitmap) + + remaining = bitmap->mapped_total_index - bitmap->mapped_base_index; + remaining = min_t(unsigned long, remaining, +- bytes / sizeof(*bitmap->bitmap)); ++ DIV_ROUND_UP(bytes, sizeof(*bitmap->bitmap))); + + return remaining; + } +-- +2.43.0 + diff --git a/queue-6.1/ipv4-properly-combine-dev_base_seq-and-ipv4.dev_addr.patch b/queue-6.1/ipv4-properly-combine-dev_base_seq-and-ipv4.dev_addr.patch new file mode 100644 index 00000000000..ffcaddaf6d1 --- /dev/null +++ b/queue-6.1/ipv4-properly-combine-dev_base_seq-and-ipv4.dev_addr.patch @@ -0,0 +1,73 @@ +From 750d26da67e860ecb33259e352815c3094a5b39b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 17:21:06 +0000 +Subject: ipv4: properly combine dev_base_seq and ipv4.dev_addr_genid + +From: Eric Dumazet + +[ Upstream commit 081a0e3b0d4c061419d3f4679dec9f68725b17e4 ] + +net->dev_base_seq and ipv4.dev_addr_genid are monotonically increasing. + +If we XOR their values, we could miss to detect if both values +were changed with the same amount. + +Fixes: 0465277f6b3f ("ipv4: provide addr and netconf dump consistency info") +Signed-off-by: Eric Dumazet +Cc: Nicolas Dichtel +Acked-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/devinet.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c +index 35d6e74be8406..bb0d1252cad86 100644 +--- a/net/ipv4/devinet.c ++++ b/net/ipv4/devinet.c +@@ -1804,6 +1804,21 @@ static int in_dev_dump_addr(struct in_device *in_dev, struct sk_buff *skb, + return err; + } + ++/* Combine dev_addr_genid and dev_base_seq to detect changes. ++ */ ++static u32 inet_base_seq(const struct net *net) ++{ ++ u32 res = atomic_read(&net->ipv4.dev_addr_genid) + ++ net->dev_base_seq; ++ ++ /* Must not return 0 (see nl_dump_check_consistent()). ++ * Chose a value far away from 0. ++ */ ++ if (!res) ++ res = 0x80000000; ++ return res; ++} ++ + static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) + { + const struct nlmsghdr *nlh = cb->nlh; +@@ -1855,8 +1870,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) + idx = 0; + head = &tgt_net->dev_index_head[h]; + rcu_read_lock(); +- cb->seq = atomic_read(&tgt_net->ipv4.dev_addr_genid) ^ +- tgt_net->dev_base_seq; ++ cb->seq = inet_base_seq(tgt_net); + hlist_for_each_entry_rcu(dev, head, index_hlist) { + if (idx < s_idx) + goto cont; +@@ -2257,8 +2271,7 @@ static int inet_netconf_dump_devconf(struct sk_buff *skb, + idx = 0; + head = &net->dev_index_head[h]; + rcu_read_lock(); +- cb->seq = atomic_read(&net->ipv4.dev_addr_genid) ^ +- net->dev_base_seq; ++ cb->seq = inet_base_seq(net); + hlist_for_each_entry_rcu(dev, head, index_hlist) { + if (idx < s_idx) + goto cont; +-- +2.43.0 + diff --git a/queue-6.1/ipv6-properly-combine-dev_base_seq-and-ipv6.dev_addr.patch b/queue-6.1/ipv6-properly-combine-dev_base_seq-and-ipv6.dev_addr.patch new file mode 100644 index 00000000000..f096bd8c9d3 --- /dev/null +++ b/queue-6.1/ipv6-properly-combine-dev_base_seq-and-ipv6.dev_addr.patch @@ -0,0 +1,75 @@ +From f7da708e69d9514808bbbbb16d619d6054f75118 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 17:21:07 +0000 +Subject: ipv6: properly combine dev_base_seq and ipv6.dev_addr_genid + +From: Eric Dumazet + +[ Upstream commit e898e4cd1aab271ca414f9ac6e08e4c761f6913c ] + +net->dev_base_seq and ipv6.dev_addr_genid are monotonically increasing. + +If we XOR their values, we could miss to detect if both values +were changed with the same amount. + +Fixes: 63998ac24f83 ("ipv6: provide addr and netconf dump consistency info") +Signed-off-by: Eric Dumazet +Cc: Nicolas Dichtel + +Signed-off-by: Eric Dumazet +Acked-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv6/addrconf.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index b8dc20fe7a4e2..46527b5cc8f0c 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -706,6 +706,22 @@ static int inet6_netconf_get_devconf(struct sk_buff *in_skb, + return err; + } + ++/* Combine dev_addr_genid and dev_base_seq to detect changes. ++ */ ++static u32 inet6_base_seq(const struct net *net) ++{ ++ u32 res = atomic_read(&net->ipv6.dev_addr_genid) + ++ net->dev_base_seq; ++ ++ /* Must not return 0 (see nl_dump_check_consistent()). ++ * Chose a value far away from 0. ++ */ ++ if (!res) ++ res = 0x80000000; ++ return res; ++} ++ ++ + static int inet6_netconf_dump_devconf(struct sk_buff *skb, + struct netlink_callback *cb) + { +@@ -739,8 +755,7 @@ static int inet6_netconf_dump_devconf(struct sk_buff *skb, + idx = 0; + head = &net->dev_index_head[h]; + rcu_read_lock(); +- cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ +- net->dev_base_seq; ++ cb->seq = inet6_base_seq(net); + hlist_for_each_entry_rcu(dev, head, index_hlist) { + if (idx < s_idx) + goto cont; +@@ -5326,7 +5341,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, + } + + rcu_read_lock(); +- cb->seq = atomic_read(&tgt_net->ipv6.dev_addr_genid) ^ tgt_net->dev_base_seq; ++ cb->seq = inet6_base_seq(tgt_net); + for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { + idx = 0; + head = &tgt_net->dev_index_head[h]; +-- +2.43.0 + diff --git a/queue-6.1/ipv6-sr-fix-possible-use-after-free-and-null-ptr-der.patch b/queue-6.1/ipv6-sr-fix-possible-use-after-free-and-null-ptr-der.patch new file mode 100644 index 00000000000..ac6c59efe84 --- /dev/null +++ b/queue-6.1/ipv6-sr-fix-possible-use-after-free-and-null-ptr-der.patch @@ -0,0 +1,74 @@ +From 4b4260b4f2e796090c2ac011fab7dbc7d303c84f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 23:27:17 +0300 +Subject: ipv6: sr: fix possible use-after-free and null-ptr-deref + +From: Vasiliy Kovalev + +[ Upstream commit 5559cea2d5aa3018a5f00dd2aca3427ba09b386b ] + +The pernet operations structure for the subsystem must be registered +before registering the generic netlink family. + +Fixes: 915d7e5e5930 ("ipv6: sr: add code base for control plane support of SR-IPv6") +Signed-off-by: Vasiliy Kovalev +Link: https://lore.kernel.org/r/20240215202717.29815-1-kovalev@altlinux.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv6/seg6.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c +index 29346a6eec9ff..35508abd76f43 100644 +--- a/net/ipv6/seg6.c ++++ b/net/ipv6/seg6.c +@@ -512,22 +512,24 @@ int __init seg6_init(void) + { + int err; + +- err = genl_register_family(&seg6_genl_family); ++ err = register_pernet_subsys(&ip6_segments_ops); + if (err) + goto out; + +- err = register_pernet_subsys(&ip6_segments_ops); ++ err = genl_register_family(&seg6_genl_family); + if (err) +- goto out_unregister_genl; ++ goto out_unregister_pernet; + + #ifdef CONFIG_IPV6_SEG6_LWTUNNEL + err = seg6_iptunnel_init(); + if (err) +- goto out_unregister_pernet; ++ goto out_unregister_genl; + + err = seg6_local_init(); +- if (err) +- goto out_unregister_pernet; ++ if (err) { ++ seg6_iptunnel_exit(); ++ goto out_unregister_genl; ++ } + #endif + + #ifdef CONFIG_IPV6_SEG6_HMAC +@@ -548,11 +550,11 @@ int __init seg6_init(void) + #endif + #endif + #ifdef CONFIG_IPV6_SEG6_LWTUNNEL +-out_unregister_pernet: +- unregister_pernet_subsys(&ip6_segments_ops); +-#endif + out_unregister_genl: + genl_unregister_family(&seg6_genl_family); ++#endif ++out_unregister_pernet: ++ unregister_pernet_subsys(&ip6_segments_ops); + goto out; + } + +-- +2.43.0 + diff --git a/queue-6.1/net-bridge-switchdev-ensure-deferred-event-delivery-.patch b/queue-6.1/net-bridge-switchdev-ensure-deferred-event-delivery-.patch new file mode 100644 index 00000000000..774746f6872 --- /dev/null +++ b/queue-6.1/net-bridge-switchdev-ensure-deferred-event-delivery-.patch @@ -0,0 +1,74 @@ +From f896fa41ab0e1d43e09769ca8c0717a437c23ba0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 22:40:04 +0100 +Subject: net: bridge: switchdev: Ensure deferred event delivery on unoffload + +From: Tobias Waldekranz + +[ Upstream commit f7a70d650b0b6b0134ccba763d672c8439d9f09b ] + +When unoffloading a device, it is important to ensure that all +relevant deferred events are delivered to it before it disassociates +itself from the bridge. + +Before this change, this was true for the normal case when a device +maps 1:1 to a net_bridge_port, i.e. + + br0 + / +swp0 + +When swp0 leaves br0, the call to switchdev_deferred_process() in +del_nbp() makes sure to process any outstanding events while the +device is still associated with the bridge. + +In the case when the association is indirect though, i.e. when the +device is attached to the bridge via an intermediate device, like a +LAG... + + br0 + / + lag0 + / +swp0 + +...then detaching swp0 from lag0 does not cause any net_bridge_port to +be deleted, so there was no guarantee that all events had been +processed before the device disassociated itself from the bridge. + +Fix this by always synchronously processing all deferred events before +signaling completion of unoffloading back to the driver. + +Fixes: 4e51bf44a03a ("net: bridge: move the switchdev object replay helpers to "push" mode") +Signed-off-by: Tobias Waldekranz +Reviewed-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/bridge/br_switchdev.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c +index 65567d1c8b853..b61ef2dff7a4b 100644 +--- a/net/bridge/br_switchdev.c ++++ b/net/bridge/br_switchdev.c +@@ -798,6 +798,16 @@ static void nbp_switchdev_unsync_objs(struct net_bridge_port *p, + br_switchdev_mdb_replay(br_dev, dev, ctx, false, blocking_nb, NULL); + + br_switchdev_vlan_replay(br_dev, ctx, false, blocking_nb, NULL); ++ ++ /* Make sure that the device leaving this bridge has seen all ++ * relevant events before it is disassociated. In the normal ++ * case, when the device is directly attached to the bridge, ++ * this is covered by del_nbp(). If the association was indirect ++ * however, e.g. via a team or bond, and the device is leaving ++ * that intermediate device, then the bridge port remains in ++ * place. ++ */ ++ switchdev_deferred_process(); + } + + /* Let the bridge know that this port is offloaded, so that it can assign a +-- +2.43.0 + diff --git a/queue-6.1/net-bridge-switchdev-skip-mdb-replays-of-deferred-ev.patch b/queue-6.1/net-bridge-switchdev-skip-mdb-replays-of-deferred-ev.patch new file mode 100644 index 00000000000..826e13fcacc --- /dev/null +++ b/queue-6.1/net-bridge-switchdev-skip-mdb-replays-of-deferred-ev.patch @@ -0,0 +1,329 @@ +From 2e7af85b7ffd41521e3ec638faded487ec08488e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 22:40:03 +0100 +Subject: net: bridge: switchdev: Skip MDB replays of deferred events on + offload + +From: Tobias Waldekranz + +[ Upstream commit dc489f86257cab5056e747344f17a164f63bff4b ] + +Before this change, generation of the list of MDB events to replay +would race against the creation of new group memberships, either from +the IGMP/MLD snooping logic or from user configuration. + +While new memberships are immediately visible to walkers of +br->mdb_list, the notification of their existence to switchdev event +subscribers is deferred until a later point in time. So if a replay +list was generated during a time that overlapped with such a window, +it would also contain a replay of the not-yet-delivered event. + +The driver would thus receive two copies of what the bridge internally +considered to be one single event. On destruction of the bridge, only +a single membership deletion event was therefore sent. As a +consequence of this, drivers which reference count memberships (at +least DSA), would be left with orphan groups in their hardware +database when the bridge was destroyed. + +This is only an issue when replaying additions. While deletion events +may still be pending on the deferred queue, they will already have +been removed from br->mdb_list, so no duplicates can be generated in +that scenario. + +To a user this meant that old group memberships, from a bridge in +which a port was previously attached, could be reanimated (in +hardware) when the port joined a new bridge, without the new bridge's +knowledge. + +For example, on an mv88e6xxx system, create a snooping bridge and +immediately add a port to it: + + root@infix-06-0b-00:~$ ip link add dev br0 up type bridge mcast_snooping 1 && \ + > ip link set dev x3 up master br0 + +And then destroy the bridge: + + root@infix-06-0b-00:~$ ip link del dev br0 + root@infix-06-0b-00:~$ mvls atu + ADDRESS FID STATE Q F 0 1 2 3 4 5 6 7 8 9 a + DEV:0 Marvell 88E6393X + 33:33:00:00:00:6a 1 static - - 0 . . . . . . . . . . + 33:33:ff:87:e4:3f 1 static - - 0 . . . . . . . . . . + ff:ff:ff:ff:ff:ff 1 static - - 0 1 2 3 4 5 6 7 8 9 a + root@infix-06-0b-00:~$ + +The two IPv6 groups remain in the hardware database because the +port (x3) is notified of the host's membership twice: once via the +original event and once via a replay. Since only a single delete +notification is sent, the count remains at 1 when the bridge is +destroyed. + +Then add the same port (or another port belonging to the same hardware +domain) to a new bridge, this time with snooping disabled: + + root@infix-06-0b-00:~$ ip link add dev br1 up type bridge mcast_snooping 0 && \ + > ip link set dev x3 up master br1 + +All multicast, including the two IPv6 groups from br0, should now be +flooded, according to the policy of br1. But instead the old +memberships are still active in the hardware database, causing the +switch to only forward traffic to those groups towards the CPU (port +0). + +Eliminate the race in two steps: + +1. Grab the write-side lock of the MDB while generating the replay + list. + +This prevents new memberships from showing up while we are generating +the replay list. But it leaves the scenario in which a deferred event +was already generated, but not delivered, before we grabbed the +lock. Therefore: + +2. Make sure that no deferred version of a replay event is already + enqueued to the switchdev deferred queue, before adding it to the + replay list, when replaying additions. + +Fixes: 4f2673b3a2b6 ("net: bridge: add helper to replay port and host-joined mdb entries") +Signed-off-by: Tobias Waldekranz +Reviewed-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/switchdev.h | 3 ++ + net/bridge/br_switchdev.c | 74 ++++++++++++++++++++++++--------------- + net/switchdev/switchdev.c | 73 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 122 insertions(+), 28 deletions(-) + +diff --git a/include/net/switchdev.h b/include/net/switchdev.h +index 7dcdc97c0bc33..a3d8f013adcd5 100644 +--- a/include/net/switchdev.h ++++ b/include/net/switchdev.h +@@ -303,6 +303,9 @@ void switchdev_deferred_process(void); + int switchdev_port_attr_set(struct net_device *dev, + const struct switchdev_attr *attr, + struct netlink_ext_ack *extack); ++bool switchdev_port_obj_act_is_deferred(struct net_device *dev, ++ enum switchdev_notifier_type nt, ++ const struct switchdev_obj *obj); + int switchdev_port_obj_add(struct net_device *dev, + const struct switchdev_obj *obj, + struct netlink_ext_ack *extack); +diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c +index 4b3982c368b35..65567d1c8b853 100644 +--- a/net/bridge/br_switchdev.c ++++ b/net/bridge/br_switchdev.c +@@ -593,21 +593,40 @@ br_switchdev_mdb_replay_one(struct notifier_block *nb, struct net_device *dev, + } + + static int br_switchdev_mdb_queue_one(struct list_head *mdb_list, ++ struct net_device *dev, ++ unsigned long action, + enum switchdev_obj_id id, + const struct net_bridge_mdb_entry *mp, + struct net_device *orig_dev) + { +- struct switchdev_obj_port_mdb *mdb; ++ struct switchdev_obj_port_mdb mdb = { ++ .obj = { ++ .id = id, ++ .orig_dev = orig_dev, ++ }, ++ }; ++ struct switchdev_obj_port_mdb *pmdb; + +- mdb = kzalloc(sizeof(*mdb), GFP_ATOMIC); +- if (!mdb) +- return -ENOMEM; ++ br_switchdev_mdb_populate(&mdb, mp); + +- mdb->obj.id = id; +- mdb->obj.orig_dev = orig_dev; +- br_switchdev_mdb_populate(mdb, mp); +- list_add_tail(&mdb->obj.list, mdb_list); ++ if (action == SWITCHDEV_PORT_OBJ_ADD && ++ switchdev_port_obj_act_is_deferred(dev, action, &mdb.obj)) { ++ /* This event is already in the deferred queue of ++ * events, so this replay must be elided, lest the ++ * driver receives duplicate events for it. This can ++ * only happen when replaying additions, since ++ * modifications are always immediately visible in ++ * br->mdb_list, whereas actual event delivery may be ++ * delayed. ++ */ ++ return 0; ++ } ++ ++ pmdb = kmemdup(&mdb, sizeof(mdb), GFP_ATOMIC); ++ if (!pmdb) ++ return -ENOMEM; + ++ list_add_tail(&pmdb->obj.list, mdb_list); + return 0; + } + +@@ -675,51 +694,50 @@ br_switchdev_mdb_replay(struct net_device *br_dev, struct net_device *dev, + if (!br_opt_get(br, BROPT_MULTICAST_ENABLED)) + return 0; + +- /* We cannot walk over br->mdb_list protected just by the rtnl_mutex, +- * because the write-side protection is br->multicast_lock. But we +- * need to emulate the [ blocking ] calling context of a regular +- * switchdev event, so since both br->multicast_lock and RCU read side +- * critical sections are atomic, we have no choice but to pick the RCU +- * read side lock, queue up all our events, leave the critical section +- * and notify switchdev from blocking context. ++ if (adding) ++ action = SWITCHDEV_PORT_OBJ_ADD; ++ else ++ action = SWITCHDEV_PORT_OBJ_DEL; ++ ++ /* br_switchdev_mdb_queue_one() will take care to not queue a ++ * replay of an event that is already pending in the switchdev ++ * deferred queue. In order to safely determine that, there ++ * must be no new deferred MDB notifications enqueued for the ++ * duration of the MDB scan. Therefore, grab the write-side ++ * lock to avoid racing with any concurrent IGMP/MLD snooping. + */ +- rcu_read_lock(); ++ spin_lock_bh(&br->multicast_lock); + +- hlist_for_each_entry_rcu(mp, &br->mdb_list, mdb_node) { ++ hlist_for_each_entry(mp, &br->mdb_list, mdb_node) { + struct net_bridge_port_group __rcu * const *pp; + const struct net_bridge_port_group *p; + + if (mp->host_joined) { +- err = br_switchdev_mdb_queue_one(&mdb_list, ++ err = br_switchdev_mdb_queue_one(&mdb_list, dev, action, + SWITCHDEV_OBJ_ID_HOST_MDB, + mp, br_dev); + if (err) { +- rcu_read_unlock(); ++ spin_unlock_bh(&br->multicast_lock); + goto out_free_mdb; + } + } + +- for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL; ++ for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL; + pp = &p->next) { + if (p->key.port->dev != dev) + continue; + +- err = br_switchdev_mdb_queue_one(&mdb_list, ++ err = br_switchdev_mdb_queue_one(&mdb_list, dev, action, + SWITCHDEV_OBJ_ID_PORT_MDB, + mp, dev); + if (err) { +- rcu_read_unlock(); ++ spin_unlock_bh(&br->multicast_lock); + goto out_free_mdb; + } + } + } + +- rcu_read_unlock(); +- +- if (adding) +- action = SWITCHDEV_PORT_OBJ_ADD; +- else +- action = SWITCHDEV_PORT_OBJ_DEL; ++ spin_unlock_bh(&br->multicast_lock); + + list_for_each_entry(obj, &mdb_list, list) { + err = br_switchdev_mdb_replay_one(nb, dev, +diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c +index 8cc42aea19c7e..2e14d4c37e2dc 100644 +--- a/net/switchdev/switchdev.c ++++ b/net/switchdev/switchdev.c +@@ -19,6 +19,35 @@ + #include + #include + ++static bool switchdev_obj_eq(const struct switchdev_obj *a, ++ const struct switchdev_obj *b) ++{ ++ const struct switchdev_obj_port_vlan *va, *vb; ++ const struct switchdev_obj_port_mdb *ma, *mb; ++ ++ if (a->id != b->id || a->orig_dev != b->orig_dev) ++ return false; ++ ++ switch (a->id) { ++ case SWITCHDEV_OBJ_ID_PORT_VLAN: ++ va = SWITCHDEV_OBJ_PORT_VLAN(a); ++ vb = SWITCHDEV_OBJ_PORT_VLAN(b); ++ return va->flags == vb->flags && ++ va->vid == vb->vid && ++ va->changed == vb->changed; ++ case SWITCHDEV_OBJ_ID_PORT_MDB: ++ case SWITCHDEV_OBJ_ID_HOST_MDB: ++ ma = SWITCHDEV_OBJ_PORT_MDB(a); ++ mb = SWITCHDEV_OBJ_PORT_MDB(b); ++ return ma->vid == mb->vid && ++ ether_addr_equal(ma->addr, mb->addr); ++ default: ++ break; ++ } ++ ++ BUG(); ++} ++ + static LIST_HEAD(deferred); + static DEFINE_SPINLOCK(deferred_lock); + +@@ -307,6 +336,50 @@ int switchdev_port_obj_del(struct net_device *dev, + } + EXPORT_SYMBOL_GPL(switchdev_port_obj_del); + ++/** ++ * switchdev_port_obj_act_is_deferred - Is object action pending? ++ * ++ * @dev: port device ++ * @nt: type of action; add or delete ++ * @obj: object to test ++ * ++ * Returns true if a deferred item is pending, which is ++ * equivalent to the action @nt on an object @obj. ++ * ++ * rtnl_lock must be held. ++ */ ++bool switchdev_port_obj_act_is_deferred(struct net_device *dev, ++ enum switchdev_notifier_type nt, ++ const struct switchdev_obj *obj) ++{ ++ struct switchdev_deferred_item *dfitem; ++ bool found = false; ++ ++ ASSERT_RTNL(); ++ ++ spin_lock_bh(&deferred_lock); ++ ++ list_for_each_entry(dfitem, &deferred, list) { ++ if (dfitem->dev != dev) ++ continue; ++ ++ if ((dfitem->func == switchdev_port_obj_add_deferred && ++ nt == SWITCHDEV_PORT_OBJ_ADD) || ++ (dfitem->func == switchdev_port_obj_del_deferred && ++ nt == SWITCHDEV_PORT_OBJ_DEL)) { ++ if (switchdev_obj_eq((const void *)dfitem->data, obj)) { ++ found = true; ++ break; ++ } ++ } ++ } ++ ++ spin_unlock_bh(&deferred_lock); ++ ++ return found; ++} ++EXPORT_SYMBOL_GPL(switchdev_port_obj_act_is_deferred); ++ + static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain); + static BLOCKING_NOTIFIER_HEAD(switchdev_blocking_notif_chain); + +-- +2.43.0 + diff --git a/queue-6.1/net-dev-convert-sa_data-to-flexible-array-in-struct-.patch b/queue-6.1/net-dev-convert-sa_data-to-flexible-array-in-struct-.patch new file mode 100644 index 00000000000..7981f692e85 --- /dev/null +++ b/queue-6.1/net-dev-convert-sa_data-to-flexible-array-in-struct-.patch @@ -0,0 +1,135 @@ +From b612f045d7213f210e1bfc3ce9ba04fb7a0812b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Oct 2022 02:56:03 -0700 +Subject: net: dev: Convert sa_data to flexible array in struct sockaddr + +From: Kees Cook + +[ Upstream commit b5f0de6df6dce8d641ef58ef7012f3304dffb9a1 ] + +One of the worst offenders of "fake flexible arrays" is struct sockaddr, +as it is the classic example of why GCC and Clang have been traditionally +forced to treat all trailing arrays as fake flexible arrays: in the +distant misty past, sa_data became too small, and code started just +treating it as a flexible array, even though it was fixed-size. The +special case by the compiler is specifically that sizeof(sa->sa_data) +and FORTIFY_SOURCE (which uses __builtin_object_size(sa->sa_data, 1)) +do not agree (14 and -1 respectively), which makes FORTIFY_SOURCE treat +it as a flexible array. + +However, the coming -fstrict-flex-arrays compiler flag will remove +these special cases so that FORTIFY_SOURCE can gain coverage over all +the trailing arrays in the kernel that are _not_ supposed to be treated +as a flexible array. To deal with this change, convert sa_data to a true +flexible array. To keep the structure size the same, move sa_data into +a union with a newly introduced sa_data_min with the original size. The +result is that FORTIFY_SOURCE can continue to have no idea how large +sa_data may actually be, but anything using sizeof(sa->sa_data) must +switch to sizeof(sa->sa_data_min). + +Cc: Jens Axboe +Cc: Pavel Begunkov +Cc: David Ahern +Cc: Dylan Yudaken +Cc: Yajun Deng +Cc: Petr Machata +Cc: Hangbin Liu +Cc: Leon Romanovsky +Cc: syzbot +Cc: Willem de Bruijn +Cc: Pablo Neira Ayuso +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20221018095503.never.671-kees@kernel.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: a7d6027790ac ("arp: Prevent overflow in arp_req_get().") +Signed-off-by: Sasha Levin +--- + include/linux/socket.h | 5 ++++- + net/core/dev.c | 2 +- + net/core/dev_ioctl.c | 2 +- + net/packet/af_packet.c | 10 +++++----- + 4 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/include/linux/socket.h b/include/linux/socket.h +index b3c58042bd254..d79efd0268809 100644 +--- a/include/linux/socket.h ++++ b/include/linux/socket.h +@@ -33,7 +33,10 @@ typedef __kernel_sa_family_t sa_family_t; + + struct sockaddr { + sa_family_t sa_family; /* address family, AF_xxx */ +- char sa_data[14]; /* 14 bytes of protocol address */ ++ union { ++ char sa_data_min[14]; /* Minimum 14 bytes of protocol address */ ++ DECLARE_FLEX_ARRAY(char, sa_data); ++ }; + }; + + struct linger { +diff --git a/net/core/dev.c b/net/core/dev.c +index 1ba3662faf0aa..60619fe8af5fc 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -8861,7 +8861,7 @@ EXPORT_SYMBOL(dev_set_mac_address_user); + + int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name) + { +- size_t size = sizeof(sa->sa_data); ++ size_t size = sizeof(sa->sa_data_min); + struct net_device *dev; + int ret = 0; + +diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c +index 7674bb9f3076c..5cdbfbf9a7dcf 100644 +--- a/net/core/dev_ioctl.c ++++ b/net/core/dev_ioctl.c +@@ -342,7 +342,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, + if (ifr->ifr_hwaddr.sa_family != dev->type) + return -EINVAL; + memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, +- min(sizeof(ifr->ifr_hwaddr.sa_data), ++ min(sizeof(ifr->ifr_hwaddr.sa_data_min), + (size_t)dev->addr_len)); + call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); + return 0; +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 51882f07ef70c..c3117350f5fbb 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3284,7 +3284,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, + int addr_len) + { + struct sock *sk = sock->sk; +- char name[sizeof(uaddr->sa_data) + 1]; ++ char name[sizeof(uaddr->sa_data_min) + 1]; + + /* + * Check legality +@@ -3295,8 +3295,8 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, + /* uaddr->sa_data comes from the userspace, it's not guaranteed to be + * zero-terminated. + */ +- memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data)); +- name[sizeof(uaddr->sa_data)] = 0; ++ memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data_min)); ++ name[sizeof(uaddr->sa_data_min)] = 0; + + return packet_do_bind(sk, name, 0, 0); + } +@@ -3566,11 +3566,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, + return -EOPNOTSUPP; + + uaddr->sa_family = AF_PACKET; +- memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); ++ memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data_min)); + rcu_read_lock(); + dev = dev_get_by_index_rcu(sock_net(sk), READ_ONCE(pkt_sk(sk)->ifindex)); + if (dev) +- strscpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); ++ strscpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data_min)); + rcu_read_unlock(); + + return sizeof(*uaddr); +-- +2.43.0 + diff --git a/queue-6.1/net-ethernet-adi-requires-phylib-support.patch b/queue-6.1/net-ethernet-adi-requires-phylib-support.patch new file mode 100644 index 00000000000..0b074b09374 --- /dev/null +++ b/queue-6.1/net-ethernet-adi-requires-phylib-support.patch @@ -0,0 +1,70 @@ +From 7c3bab1514e02cefe9ce458103a053030f09ef07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 23:00:50 -0800 +Subject: net: ethernet: adi: requires PHYLIB support + +From: Randy Dunlap + +[ Upstream commit a9f80df4f51440303d063b55bb98720857693821 ] + +This driver uses functions that are supplied by the Kconfig symbol +PHYLIB, so select it to ensure that they are built as needed. + +When CONFIG_ADIN1110=y and CONFIG_PHYLIB=m, there are multiple build +(linker) errors that are resolved by this Kconfig change: + + ld: drivers/net/ethernet/adi/adin1110.o: in function `adin1110_net_open': + drivers/net/ethernet/adi/adin1110.c:933: undefined reference to `phy_start' + ld: drivers/net/ethernet/adi/adin1110.o: in function `adin1110_probe_netdevs': + drivers/net/ethernet/adi/adin1110.c:1603: undefined reference to `get_phy_device' + ld: drivers/net/ethernet/adi/adin1110.c:1609: undefined reference to `phy_connect' + ld: drivers/net/ethernet/adi/adin1110.o: in function `adin1110_disconnect_phy': + drivers/net/ethernet/adi/adin1110.c:1226: undefined reference to `phy_disconnect' + ld: drivers/net/ethernet/adi/adin1110.o: in function `devm_mdiobus_alloc': + include/linux/phy.h:455: undefined reference to `devm_mdiobus_alloc_size' + ld: drivers/net/ethernet/adi/adin1110.o: in function `adin1110_register_mdiobus': + drivers/net/ethernet/adi/adin1110.c:529: undefined reference to `__devm_mdiobus_register' + ld: drivers/net/ethernet/adi/adin1110.o: in function `adin1110_net_stop': + drivers/net/ethernet/adi/adin1110.c:958: undefined reference to `phy_stop' + ld: drivers/net/ethernet/adi/adin1110.o: in function `adin1110_disconnect_phy': + drivers/net/ethernet/adi/adin1110.c:1226: undefined reference to `phy_disconnect' + ld: drivers/net/ethernet/adi/adin1110.o: in function `adin1110_adjust_link': + drivers/net/ethernet/adi/adin1110.c:1077: undefined reference to `phy_print_status' + ld: drivers/net/ethernet/adi/adin1110.o: in function `adin1110_ioctl': + drivers/net/ethernet/adi/adin1110.c:790: undefined reference to `phy_do_ioctl' + ld: drivers/net/ethernet/adi/adin1110.o:(.rodata+0xf60): undefined reference to `phy_ethtool_get_link_ksettings' + ld: drivers/net/ethernet/adi/adin1110.o:(.rodata+0xf68): undefined reference to `phy_ethtool_set_link_ksettings' + +Fixes: bc93e19d088b ("net: ethernet: adi: Add ADIN1110 support") +Signed-off-by: Randy Dunlap +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202402070626.eZsfVHG5-lkp@intel.com/ +Cc: Lennart Franzen +Cc: Alexandru Tachici +Cc: "David S. Miller" +Cc: Eric Dumazet +Cc: Jakub Kicinski +Cc: Paolo Abeni +Cc: netdev@vger.kernel.org +Reviewed-by: Nuno Sa +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/adi/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/adi/Kconfig b/drivers/net/ethernet/adi/Kconfig +index da3bdd3025022..c91b4dcef4ec2 100644 +--- a/drivers/net/ethernet/adi/Kconfig ++++ b/drivers/net/ethernet/adi/Kconfig +@@ -7,6 +7,7 @@ config NET_VENDOR_ADI + bool "Analog Devices devices" + default y + depends on SPI ++ select PHYLIB + help + If you have a network (Ethernet) card belonging to this class, say Y. + +-- +2.43.0 + diff --git a/queue-6.1/net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch b/queue-6.1/net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch new file mode 100644 index 00000000000..994244ae120 --- /dev/null +++ b/queue-6.1/net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch @@ -0,0 +1,1078 @@ +From 411791fe82c0b08a8c4ee827713133f47c2e890d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jun 2023 08:27:42 -0700 +Subject: net: ioctl: Use kernel memory on protocol ioctl callbacks + +From: Breno Leitao + +[ Upstream commit e1d001fa5b477c4da46a29be1fcece91db7c7c6f ] + +Most of the ioctls to net protocols operates directly on userspace +argument (arg). Usually doing get_user()/put_user() directly in the +ioctl callback. This is not flexible, because it is hard to reuse these +functions without passing userspace buffers. + +Change the "struct proto" ioctls to avoid touching userspace memory and +operate on kernel buffers, i.e., all protocol's ioctl callbacks is +adapted to operate on a kernel memory other than on userspace (so, no +more {put,get}_user() and friends being called in the ioctl callback). + +This changes the "struct proto" ioctl format in the following way: + + int (*ioctl)(struct sock *sk, int cmd, +- unsigned long arg); ++ int *karg); + +(Important to say that this patch does not touch the "struct proto_ops" +protocols) + +So, the "karg" argument, which is passed to the ioctl callback, is a +pointer allocated to kernel space memory (inside a function wrapper). +This buffer (karg) may contain input argument (copied from userspace in +a prep function) and it might return a value/buffer, which is copied +back to userspace if necessary. There is not one-size-fits-all format +(that is I am using 'may' above), but basically, there are three type of +ioctls: + +1) Do not read from userspace, returns a result to userspace +2) Read an input parameter from userspace, and does not return anything + to userspace +3) Read an input from userspace, and return a buffer to userspace. + +The default case (1) (where no input parameter is given, and an "int" is +returned to userspace) encompasses more than 90% of the cases, but there +are two other exceptions. Here is a list of exceptions: + +* Protocol RAW: + * cmd = SIOCGETVIFCNT: + * input and output = struct sioc_vif_req + * cmd = SIOCGETSGCNT + * input and output = struct sioc_sg_req + * Explanation: for the SIOCGETVIFCNT case, userspace passes the input + argument, which is struct sioc_vif_req. Then the callback populates + the struct, which is copied back to userspace. + +* Protocol RAW6: + * cmd = SIOCGETMIFCNT_IN6 + * input and output = struct sioc_mif_req6 + * cmd = SIOCGETSGCNT_IN6 + * input and output = struct sioc_sg_req6 + +* Protocol PHONET: + * cmd == SIOCPNADDRESOURCE | SIOCPNDELRESOURCE + * input int (4 bytes) + * Nothing is copied back to userspace. + +For the exception cases, functions sock_sk_ioctl_inout() will +copy the userspace input, and copy it back to kernel space. + +The wrapper that prepare the buffer and put the buffer back to user is +sk_ioctl(), so, instead of calling sk->sk_prot->ioctl(), the callee now +calls sk_ioctl(), which will handle all cases. + +Signed-off-by: Breno Leitao +Reviewed-by: Willem de Bruijn +Reviewed-by: David Ahern +Reviewed-by: Kuniyuki Iwashima +Link: https://lore.kernel.org/r/20230609152800.830401-1-leitao@debian.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: 3b2d9bc4d4ac ("phonet: take correct lock to peek at the RX queue") +Signed-off-by: Sasha Levin +--- + include/linux/icmpv6.h | 6 ++++ + include/linux/mroute.h | 22 +++++++++++-- + include/linux/mroute6.h | 31 ++++++++++++++++-- + include/net/phonet/phonet.h | 21 ++++++++++++ + include/net/sock.h | 5 ++- + include/net/tcp.h | 2 +- + include/net/udp.h | 2 +- + net/core/sock.c | 64 +++++++++++++++++++++++++++++++++++++ + net/dccp/dccp.h | 2 +- + net/dccp/proto.c | 12 +++---- + net/ieee802154/socket.c | 15 ++++----- + net/ipv4/af_inet.c | 2 +- + net/ipv4/ipmr.c | 63 ++++++++++++++++++++++-------------- + net/ipv4/raw.c | 16 +++++----- + net/ipv4/tcp.c | 5 +-- + net/ipv4/udp.c | 12 +++---- + net/ipv6/af_inet6.c | 2 +- + net/ipv6/ip6mr.c | 44 +++++++++++-------------- + net/ipv6/raw.c | 16 +++++----- + net/l2tp/l2tp_core.h | 2 +- + net/l2tp/l2tp_ip.c | 9 +++--- + net/mptcp/protocol.c | 11 +++---- + net/phonet/datagram.c | 11 +++---- + net/phonet/pep.c | 11 +++---- + net/phonet/socket.c | 2 +- + net/sctp/socket.c | 8 ++--- + 26 files changed, 267 insertions(+), 129 deletions(-) + +diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h +index db0f4fcfdaf4f..1fe33e6741cca 100644 +--- a/include/linux/icmpv6.h ++++ b/include/linux/icmpv6.h +@@ -111,4 +111,10 @@ static inline bool icmpv6_is_err(int type) + return false; + } + ++static inline int sk_is_icmpv6(struct sock *sk) ++{ ++ return sk->sk_family == AF_INET6 && ++ inet_sk(sk)->inet_num == IPPROTO_ICMPV6; ++} ++ + #endif +diff --git a/include/linux/mroute.h b/include/linux/mroute.h +index 80b8400ab8b24..94c6e6f549f0a 100644 +--- a/include/linux/mroute.h ++++ b/include/linux/mroute.h +@@ -16,12 +16,19 @@ static inline int ip_mroute_opt(int opt) + return opt >= MRT_BASE && opt <= MRT_MAX; + } + ++static inline int sk_is_ipmr(struct sock *sk) ++{ ++ return sk->sk_family == AF_INET && ++ inet_sk(sk)->inet_num == IPPROTO_IGMP; ++} ++ + int ip_mroute_setsockopt(struct sock *, int, sockptr_t, unsigned int); + int ip_mroute_getsockopt(struct sock *, int, sockptr_t, sockptr_t); +-int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg); ++int ipmr_ioctl(struct sock *sk, int cmd, void *arg); + int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); + int ip_mr_init(void); + bool ipmr_rule_default(const struct fib_rule *rule); ++int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); + #else + static inline int ip_mroute_setsockopt(struct sock *sock, int optname, + sockptr_t optval, unsigned int optlen) +@@ -35,7 +42,7 @@ static inline int ip_mroute_getsockopt(struct sock *sk, int optname, + return -ENOPROTOOPT; + } + +-static inline int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) ++static inline int ipmr_ioctl(struct sock *sk, int cmd, void *arg) + { + return -ENOIOCTLCMD; + } +@@ -50,10 +57,21 @@ static inline int ip_mroute_opt(int opt) + return 0; + } + ++static inline int sk_is_ipmr(struct sock *sk) ++{ ++ return 0; ++} ++ + static inline bool ipmr_rule_default(const struct fib_rule *rule) + { + return true; + } ++ ++static inline int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd, ++ void __user *arg) ++{ ++ return 1; ++} + #endif + + #define VIFF_STATIC 0x8000 +diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h +index 8f2b307fb1241..2f95d5b4e47af 100644 +--- a/include/linux/mroute6.h ++++ b/include/linux/mroute6.h +@@ -29,10 +29,10 @@ struct sock; + extern int ip6_mroute_setsockopt(struct sock *, int, sockptr_t, unsigned int); + extern int ip6_mroute_getsockopt(struct sock *, int, sockptr_t, sockptr_t); + extern int ip6_mr_input(struct sk_buff *skb); +-extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg); + extern int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); + extern int ip6_mr_init(void); + extern void ip6_mr_cleanup(void); ++int ip6mr_ioctl(struct sock *sk, int cmd, void *arg); + #else + static inline int ip6_mroute_setsockopt(struct sock *sock, int optname, + sockptr_t optval, unsigned int optlen) +@@ -48,7 +48,7 @@ int ip6_mroute_getsockopt(struct sock *sock, + } + + static inline +-int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) ++int ip6mr_ioctl(struct sock *sk, int cmd, void *arg) + { + return -ENOIOCTLCMD; + } +@@ -100,6 +100,27 @@ extern int ip6mr_get_route(struct net *net, struct sk_buff *skb, + #ifdef CONFIG_IPV6_MROUTE + bool mroute6_is_socket(struct net *net, struct sk_buff *skb); + extern int ip6mr_sk_done(struct sock *sk); ++static inline int ip6mr_sk_ioctl(struct sock *sk, unsigned int cmd, ++ void __user *arg) ++{ ++ switch (cmd) { ++ /* These userspace buffers will be consumed by ip6mr_ioctl() */ ++ case SIOCGETMIFCNT_IN6: { ++ struct sioc_mif_req6 buffer; ++ ++ return sock_ioctl_inout(sk, cmd, arg, &buffer, ++ sizeof(buffer)); ++ } ++ case SIOCGETSGCNT_IN6: { ++ struct sioc_mif_req6 buffer; ++ ++ return sock_ioctl_inout(sk, cmd, arg, &buffer, ++ sizeof(buffer)); ++ } ++ } ++ ++ return 1; ++} + #else + static inline bool mroute6_is_socket(struct net *net, struct sk_buff *skb) + { +@@ -109,5 +130,11 @@ static inline int ip6mr_sk_done(struct sock *sk) + { + return 0; + } ++ ++static inline int ip6mr_sk_ioctl(struct sock *sk, unsigned int cmd, ++ void __user *arg) ++{ ++ return 1; ++} + #endif + #endif +diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h +index 862f1719b5230..cf5ecae4a2fcd 100644 +--- a/include/net/phonet/phonet.h ++++ b/include/net/phonet/phonet.h +@@ -109,4 +109,25 @@ void phonet_sysctl_exit(void); + int isi_register(void); + void isi_unregister(void); + ++static inline bool sk_is_phonet(struct sock *sk) ++{ ++ return sk->sk_family == PF_PHONET; ++} ++ ++static inline int phonet_sk_ioctl(struct sock *sk, unsigned int cmd, ++ void __user *arg) ++{ ++ int karg; ++ ++ switch (cmd) { ++ case SIOCPNADDRESOURCE: ++ case SIOCPNDELRESOURCE: ++ if (get_user(karg, (int __user *)arg)) ++ return -EFAULT; ++ ++ return sk->sk_prot->ioctl(sk, cmd, &karg); ++ } ++ /* A positive return value means that the ioctl was not processed */ ++ return 1; ++} + #endif +diff --git a/include/net/sock.h b/include/net/sock.h +index 579732d47dfc4..6ea961ee257d2 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1258,7 +1258,7 @@ struct proto { + bool kern); + + int (*ioctl)(struct sock *sk, int cmd, +- unsigned long arg); ++ int *karg); + int (*init)(struct sock *sk); + void (*destroy)(struct sock *sk); + void (*shutdown)(struct sock *sk, int how); +@@ -3048,6 +3048,9 @@ int sock_get_timeout(long timeo, void *optval, bool old_timeval); + int sock_copy_user_timeval(struct __kernel_sock_timeval *tv, + sockptr_t optval, int optlen, bool old_timeval); + ++int sock_ioctl_inout(struct sock *sk, unsigned int cmd, ++ void __user *arg, void *karg, size_t size); ++int sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); + static inline bool sk_is_readable(struct sock *sk) + { + if (sk->sk_prot->sock_is_readable) +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 8ea1fba84eff9..8d3777e476e0e 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -346,7 +346,7 @@ void tcp_release_cb(struct sock *sk); + void tcp_wfree(struct sk_buff *skb); + void tcp_write_timer_handler(struct sock *sk); + void tcp_delack_timer_handler(struct sock *sk); +-int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); ++int tcp_ioctl(struct sock *sk, int cmd, int *karg); + int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb); + void tcp_rcv_established(struct sock *sk, struct sk_buff *skb); + void tcp_rcv_space_adjust(struct sock *sk); +diff --git a/include/net/udp.h b/include/net/udp.h +index fa4cdbe55552c..b5e5d5e2b4e1b 100644 +--- a/include/net/udp.h ++++ b/include/net/udp.h +@@ -275,7 +275,7 @@ void udp_flush_pending_frames(struct sock *sk); + int udp_cmsg_send(struct sock *sk, struct msghdr *msg, u16 *gso_size); + void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst); + int udp_rcv(struct sk_buff *skb); +-int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); ++int udp_ioctl(struct sock *sk, int cmd, int *karg); + int udp_init_sock(struct sock *sk); + int udp_pre_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); + int __udp_disconnect(struct sock *sk, int flags); +diff --git a/net/core/sock.c b/net/core/sock.c +index c8803b95ea0da..e55220cc08640 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -115,6 +115,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include + +@@ -139,6 +142,7 @@ + + #include + #include ++#include + + #include + +@@ -4129,3 +4133,63 @@ int sock_bind_add(struct sock *sk, struct sockaddr *addr, int addr_len) + return sk->sk_prot->bind_add(sk, addr, addr_len); + } + EXPORT_SYMBOL(sock_bind_add); ++ ++/* Copy 'size' bytes from userspace and return `size` back to userspace */ ++int sock_ioctl_inout(struct sock *sk, unsigned int cmd, ++ void __user *arg, void *karg, size_t size) ++{ ++ int ret; ++ ++ if (copy_from_user(karg, arg, size)) ++ return -EFAULT; ++ ++ ret = READ_ONCE(sk->sk_prot)->ioctl(sk, cmd, karg); ++ if (ret) ++ return ret; ++ ++ if (copy_to_user(arg, karg, size)) ++ return -EFAULT; ++ ++ return 0; ++} ++EXPORT_SYMBOL(sock_ioctl_inout); ++ ++/* This is the most common ioctl prep function, where the result (4 bytes) is ++ * copied back to userspace if the ioctl() returns successfully. No input is ++ * copied from userspace as input argument. ++ */ ++static int sock_ioctl_out(struct sock *sk, unsigned int cmd, void __user *arg) ++{ ++ int ret, karg = 0; ++ ++ ret = READ_ONCE(sk->sk_prot)->ioctl(sk, cmd, &karg); ++ if (ret) ++ return ret; ++ ++ return put_user(karg, (int __user *)arg); ++} ++ ++/* A wrapper around sock ioctls, which copies the data from userspace ++ * (depending on the protocol/ioctl), and copies back the result to userspace. ++ * The main motivation for this function is to pass kernel memory to the ++ * protocol ioctl callbacks, instead of userspace memory. ++ */ ++int sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) ++{ ++ int rc = 1; ++ ++ if (sk_is_ipmr(sk)) ++ rc = ipmr_sk_ioctl(sk, cmd, arg); ++ else if (sk_is_icmpv6(sk)) ++ rc = ip6mr_sk_ioctl(sk, cmd, arg); ++ else if (sk_is_phonet(sk)) ++ rc = phonet_sk_ioctl(sk, cmd, arg); ++ ++ /* If ioctl was processed, returns its value */ ++ if (rc <= 0) ++ return rc; ++ ++ /* Otherwise call the default handler */ ++ return sock_ioctl_out(sk, cmd, arg); ++} ++EXPORT_SYMBOL(sk_ioctl); +diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h +index 9ddc3a9e89e40..1f748ed1279d3 100644 +--- a/net/dccp/dccp.h ++++ b/net/dccp/dccp.h +@@ -292,7 +292,7 @@ int dccp_getsockopt(struct sock *sk, int level, int optname, + char __user *optval, int __user *optlen); + int dccp_setsockopt(struct sock *sk, int level, int optname, + sockptr_t optval, unsigned int optlen); +-int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg); ++int dccp_ioctl(struct sock *sk, int cmd, int *karg); + int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size); + int dccp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, + int *addr_len); +diff --git a/net/dccp/proto.c b/net/dccp/proto.c +index c522c76a9f89f..1d25cfcdbe5dc 100644 +--- a/net/dccp/proto.c ++++ b/net/dccp/proto.c +@@ -363,7 +363,7 @@ __poll_t dccp_poll(struct file *file, struct socket *sock, + } + EXPORT_SYMBOL_GPL(dccp_poll); + +-int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) ++int dccp_ioctl(struct sock *sk, int cmd, int *karg) + { + int rc = -ENOTCONN; + +@@ -374,17 +374,17 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) + + switch (cmd) { + case SIOCOUTQ: { +- int amount = sk_wmem_alloc_get(sk); ++ *karg = sk_wmem_alloc_get(sk); + /* Using sk_wmem_alloc here because sk_wmem_queued is not used by DCCP and + * always 0, comparably to UDP. + */ + +- rc = put_user(amount, (int __user *)arg); ++ rc = 0; + } + break; + case SIOCINQ: { + struct sk_buff *skb; +- unsigned long amount = 0; ++ *karg = 0; + + skb = skb_peek(&sk->sk_receive_queue); + if (skb != NULL) { +@@ -392,9 +392,9 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) + * We will only return the amount of this packet since + * that is all that will be read. + */ +- amount = skb->len; ++ *karg = skb->len; + } +- rc = put_user(amount, (int __user *)arg); ++ rc = 0; + } + break; + default: +diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c +index 1fa2fe041ec03..9c124705120dd 100644 +--- a/net/ieee802154/socket.c ++++ b/net/ieee802154/socket.c +@@ -162,7 +162,7 @@ static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd, + default: + if (!sk->sk_prot->ioctl) + return -ENOIOCTLCMD; +- return sk->sk_prot->ioctl(sk, cmd, arg); ++ return sk_ioctl(sk, cmd, (void __user *)arg); + } + } + +@@ -531,22 +531,21 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len) + return err; + } + +-static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg) ++static int dgram_ioctl(struct sock *sk, int cmd, int *karg) + { + switch (cmd) { + case SIOCOUTQ: + { +- int amount = sk_wmem_alloc_get(sk); ++ *karg = sk_wmem_alloc_get(sk); + +- return put_user(amount, (int __user *)arg); ++ return 0; + } + + case SIOCINQ: + { + struct sk_buff *skb; +- unsigned long amount; + +- amount = 0; ++ *karg = 0; + spin_lock_bh(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); + if (skb) { +@@ -554,10 +553,10 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg) + * of this packet since that is all + * that will be read. + */ +- amount = skb->len - ieee802154_hdr_length(skb); ++ *karg = skb->len - ieee802154_hdr_length(skb); + } + spin_unlock_bh(&sk->sk_receive_queue.lock); +- return put_user(amount, (int __user *)arg); ++ return 0; + } + } + +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 9408dc3bb42d3..eddedc2f8c5c9 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1007,7 +1007,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + break; + default: + if (sk->sk_prot->ioctl) +- err = sk->sk_prot->ioctl(sk, cmd, arg); ++ err = sk_ioctl(sk, cmd, (void __user *)arg); + else + err = -ENOIOCTLCMD; + break; +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index d5421c38c2aae..e20f7ab8099ad 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -1546,6 +1546,28 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval, + return ret; + } + ++/* Execute if this ioctl is a special mroute ioctl */ ++int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) ++{ ++ switch (cmd) { ++ /* These userspace buffers will be consumed by ipmr_ioctl() */ ++ case SIOCGETVIFCNT: { ++ struct sioc_vif_req buffer; ++ ++ return sock_ioctl_inout(sk, cmd, arg, &buffer, ++ sizeof(buffer)); ++ } ++ case SIOCGETSGCNT: { ++ struct sioc_sg_req buffer; ++ ++ return sock_ioctl_inout(sk, cmd, arg, &buffer, ++ sizeof(buffer)); ++ } ++ } ++ /* return code > 0 means that the ioctl was not executed */ ++ return 1; ++} ++ + /* Getsock opt support for the multicast routing system. */ + int ip_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval, + sockptr_t optlen) +@@ -1592,13 +1614,13 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval, + } + + /* The IP multicast ioctl support routines. */ +-int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) ++int ipmr_ioctl(struct sock *sk, int cmd, void *arg) + { +- struct sioc_sg_req sr; +- struct sioc_vif_req vr; + struct vif_device *vif; + struct mfc_cache *c; + struct net *net = sock_net(sk); ++ struct sioc_vif_req *vr; ++ struct sioc_sg_req *sr; + struct mr_table *mrt; + + mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); +@@ -1607,40 +1629,33 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) + + switch (cmd) { + case SIOCGETVIFCNT: +- if (copy_from_user(&vr, arg, sizeof(vr))) +- return -EFAULT; +- if (vr.vifi >= mrt->maxvif) ++ vr = (struct sioc_vif_req *)arg; ++ if (vr->vifi >= mrt->maxvif) + return -EINVAL; +- vr.vifi = array_index_nospec(vr.vifi, mrt->maxvif); ++ vr->vifi = array_index_nospec(vr->vifi, mrt->maxvif); + rcu_read_lock(); +- vif = &mrt->vif_table[vr.vifi]; +- if (VIF_EXISTS(mrt, vr.vifi)) { +- vr.icount = READ_ONCE(vif->pkt_in); +- vr.ocount = READ_ONCE(vif->pkt_out); +- vr.ibytes = READ_ONCE(vif->bytes_in); +- vr.obytes = READ_ONCE(vif->bytes_out); ++ vif = &mrt->vif_table[vr->vifi]; ++ if (VIF_EXISTS(mrt, vr->vifi)) { ++ vr->icount = READ_ONCE(vif->pkt_in); ++ vr->ocount = READ_ONCE(vif->pkt_out); ++ vr->ibytes = READ_ONCE(vif->bytes_in); ++ vr->obytes = READ_ONCE(vif->bytes_out); + rcu_read_unlock(); + +- if (copy_to_user(arg, &vr, sizeof(vr))) +- return -EFAULT; + return 0; + } + rcu_read_unlock(); + return -EADDRNOTAVAIL; + case SIOCGETSGCNT: +- if (copy_from_user(&sr, arg, sizeof(sr))) +- return -EFAULT; ++ sr = (struct sioc_sg_req *)arg; + + rcu_read_lock(); +- c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); ++ c = ipmr_cache_find(mrt, sr->src.s_addr, sr->grp.s_addr); + if (c) { +- sr.pktcnt = c->_c.mfc_un.res.pkt; +- sr.bytecnt = c->_c.mfc_un.res.bytes; +- sr.wrong_if = c->_c.mfc_un.res.wrong_if; ++ sr->pktcnt = c->_c.mfc_un.res.pkt; ++ sr->bytecnt = c->_c.mfc_un.res.bytes; ++ sr->wrong_if = c->_c.mfc_un.res.wrong_if; + rcu_read_unlock(); +- +- if (copy_to_user(arg, &sr, sizeof(sr))) +- return -EFAULT; + return 0; + } + rcu_read_unlock(); +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index 7c63b91edbf7a..a2d1f1ee7df59 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -858,29 +858,29 @@ static int raw_getsockopt(struct sock *sk, int level, int optname, + return do_raw_getsockopt(sk, level, optname, optval, optlen); + } + +-static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) ++static int raw_ioctl(struct sock *sk, int cmd, int *karg) + { + switch (cmd) { + case SIOCOUTQ: { +- int amount = sk_wmem_alloc_get(sk); +- +- return put_user(amount, (int __user *)arg); ++ *karg = sk_wmem_alloc_get(sk); ++ return 0; + } + case SIOCINQ: { + struct sk_buff *skb; +- int amount = 0; + + spin_lock_bh(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); + if (skb) +- amount = skb->len; ++ *karg = skb->len; ++ else ++ *karg = 0; + spin_unlock_bh(&sk->sk_receive_queue.lock); +- return put_user(amount, (int __user *)arg); ++ return 0; + } + + default: + #ifdef CONFIG_IP_MROUTE +- return ipmr_ioctl(sk, cmd, (void __user *)arg); ++ return ipmr_ioctl(sk, cmd, karg); + #else + return -ENOIOCTLCMD; + #endif +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 86e7695d91adf..dcbcf238bf3ab 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -598,7 +598,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait) + } + EXPORT_SYMBOL(tcp_poll); + +-int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) ++int tcp_ioctl(struct sock *sk, int cmd, int *karg) + { + struct tcp_sock *tp = tcp_sk(sk); + int answ; +@@ -640,7 +640,8 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) + return -ENOIOCTLCMD; + } + +- return put_user(answ, (int __user *)arg); ++ *karg = answ; ++ return 0; + } + EXPORT_SYMBOL(tcp_ioctl); + +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 87d759bab0012..2a5748c246e24 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1694,21 +1694,19 @@ static int first_packet_length(struct sock *sk) + * IOCTL requests applicable to the UDP protocol + */ + +-int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) ++int udp_ioctl(struct sock *sk, int cmd, int *karg) + { + switch (cmd) { + case SIOCOUTQ: + { +- int amount = sk_wmem_alloc_get(sk); +- +- return put_user(amount, (int __user *)arg); ++ *karg = sk_wmem_alloc_get(sk); ++ return 0; + } + + case SIOCINQ: + { +- int amount = max_t(int, 0, first_packet_length(sk)); +- +- return put_user(amount, (int __user *)arg); ++ *karg = max_t(int, 0, first_packet_length(sk)); ++ return 0; + } + + default: +diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c +index 0b42eb8c55aaf..37190217d650c 100644 +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -598,7 +598,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + prot = READ_ONCE(sk->sk_prot); + if (!prot->ioctl) + return -ENOIOCTLCMD; +- return prot->ioctl(sk, cmd, arg); ++ return sk_ioctl(sk, cmd, (void __user *)arg); + } + /*NOTREACHED*/ + return 0; +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 27fb5479988af..76db80a7124c8 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -1879,11 +1879,10 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval, + /* + * The IP multicast ioctl support routines. + */ +- +-int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) ++int ip6mr_ioctl(struct sock *sk, int cmd, void *arg) + { +- struct sioc_sg_req6 sr; +- struct sioc_mif_req6 vr; ++ struct sioc_sg_req6 *sr; ++ struct sioc_mif_req6 *vr; + struct vif_device *vif; + struct mfc6_cache *c; + struct net *net = sock_net(sk); +@@ -1895,40 +1894,33 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) + + switch (cmd) { + case SIOCGETMIFCNT_IN6: +- if (copy_from_user(&vr, arg, sizeof(vr))) +- return -EFAULT; +- if (vr.mifi >= mrt->maxvif) ++ vr = (struct sioc_mif_req6 *)arg; ++ if (vr->mifi >= mrt->maxvif) + return -EINVAL; +- vr.mifi = array_index_nospec(vr.mifi, mrt->maxvif); ++ vr->mifi = array_index_nospec(vr->mifi, mrt->maxvif); + rcu_read_lock(); +- vif = &mrt->vif_table[vr.mifi]; +- if (VIF_EXISTS(mrt, vr.mifi)) { +- vr.icount = READ_ONCE(vif->pkt_in); +- vr.ocount = READ_ONCE(vif->pkt_out); +- vr.ibytes = READ_ONCE(vif->bytes_in); +- vr.obytes = READ_ONCE(vif->bytes_out); ++ vif = &mrt->vif_table[vr->mifi]; ++ if (VIF_EXISTS(mrt, vr->mifi)) { ++ vr->icount = READ_ONCE(vif->pkt_in); ++ vr->ocount = READ_ONCE(vif->pkt_out); ++ vr->ibytes = READ_ONCE(vif->bytes_in); ++ vr->obytes = READ_ONCE(vif->bytes_out); + rcu_read_unlock(); +- +- if (copy_to_user(arg, &vr, sizeof(vr))) +- return -EFAULT; + return 0; + } + rcu_read_unlock(); + return -EADDRNOTAVAIL; + case SIOCGETSGCNT_IN6: +- if (copy_from_user(&sr, arg, sizeof(sr))) +- return -EFAULT; ++ sr = (struct sioc_sg_req6 *)arg; + + rcu_read_lock(); +- c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr); ++ c = ip6mr_cache_find(mrt, &sr->src.sin6_addr, ++ &sr->grp.sin6_addr); + if (c) { +- sr.pktcnt = c->_c.mfc_un.res.pkt; +- sr.bytecnt = c->_c.mfc_un.res.bytes; +- sr.wrong_if = c->_c.mfc_un.res.wrong_if; ++ sr->pktcnt = c->_c.mfc_un.res.pkt; ++ sr->bytecnt = c->_c.mfc_un.res.bytes; ++ sr->wrong_if = c->_c.mfc_un.res.wrong_if; + rcu_read_unlock(); +- +- if (copy_to_user(arg, &sr, sizeof(sr))) +- return -EFAULT; + return 0; + } + rcu_read_unlock(); +diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c +index dc31752a7edcc..e361953ca7f45 100644 +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -1116,29 +1116,29 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname, + return do_rawv6_getsockopt(sk, level, optname, optval, optlen); + } + +-static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) ++static int rawv6_ioctl(struct sock *sk, int cmd, int *karg) + { + switch (cmd) { + case SIOCOUTQ: { +- int amount = sk_wmem_alloc_get(sk); +- +- return put_user(amount, (int __user *)arg); ++ *karg = sk_wmem_alloc_get(sk); ++ return 0; + } + case SIOCINQ: { + struct sk_buff *skb; +- int amount = 0; + + spin_lock_bh(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); + if (skb) +- amount = skb->len; ++ *karg = skb->len; ++ else ++ *karg = 0; + spin_unlock_bh(&sk->sk_receive_queue.lock); +- return put_user(amount, (int __user *)arg); ++ return 0; + } + + default: + #ifdef CONFIG_IPV6_MROUTE +- return ip6mr_ioctl(sk, cmd, (void __user *)arg); ++ return ip6mr_ioctl(sk, cmd, karg); + #else + return -ENOIOCTLCMD; + #endif +diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h +index a88e070b431d8..91ebf0a3f4997 100644 +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -272,7 +272,7 @@ int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops + void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type); + + /* IOCTL helper for IP encap modules. */ +-int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg); ++int l2tp_ioctl(struct sock *sk, int cmd, int *karg); + + /* Extract the tunnel structure from a socket's sk_user_data pointer, + * validating the tunnel magic feather. +diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c +index 41a74fc84ca13..2b795c1064f5c 100644 +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -562,19 +562,18 @@ static int l2tp_ip_recvmsg(struct sock *sk, struct msghdr *msg, + return err ? err : copied; + } + +-int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg) ++int l2tp_ioctl(struct sock *sk, int cmd, int *karg) + { + struct sk_buff *skb; +- int amount; + + switch (cmd) { + case SIOCOUTQ: +- amount = sk_wmem_alloc_get(sk); ++ *karg = sk_wmem_alloc_get(sk); + break; + case SIOCINQ: + spin_lock_bh(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); +- amount = skb ? skb->len : 0; ++ *karg = skb ? skb->len : 0; + spin_unlock_bh(&sk->sk_receive_queue.lock); + break; + +@@ -582,7 +581,7 @@ int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg) + return -ENOIOCTLCMD; + } + +- return put_user(amount, (int __user *)arg); ++ return 0; + } + EXPORT_SYMBOL_GPL(l2tp_ioctl); + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 859b18cb8e4f6..7ea10d7aec961 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -3640,11 +3640,10 @@ static int mptcp_ioctl_outq(const struct mptcp_sock *msk, u64 v) + return (int)delta; + } + +-static int mptcp_ioctl(struct sock *sk, int cmd, unsigned long arg) ++static int mptcp_ioctl(struct sock *sk, int cmd, int *karg) + { + struct mptcp_sock *msk = mptcp_sk(sk); + bool slow; +- int answ; + + switch (cmd) { + case SIOCINQ: +@@ -3653,24 +3652,24 @@ static int mptcp_ioctl(struct sock *sk, int cmd, unsigned long arg) + + lock_sock(sk); + __mptcp_move_skbs(msk); +- answ = mptcp_inq_hint(sk); ++ *karg = mptcp_inq_hint(sk); + release_sock(sk); + break; + case SIOCOUTQ: + slow = lock_sock_fast(sk); +- answ = mptcp_ioctl_outq(msk, READ_ONCE(msk->snd_una)); ++ *karg = mptcp_ioctl_outq(msk, READ_ONCE(msk->snd_una)); + unlock_sock_fast(sk, slow); + break; + case SIOCOUTQNSD: + slow = lock_sock_fast(sk); +- answ = mptcp_ioctl_outq(msk, msk->snd_nxt); ++ *karg = mptcp_ioctl_outq(msk, msk->snd_nxt); + unlock_sock_fast(sk, slow); + break; + default: + return -ENOIOCTLCMD; + } + +- return put_user(answ, (int __user *)arg); ++ return 0; + } + + static void mptcp_subflow_early_fallback(struct mptcp_sock *msk, +diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c +index ff5f49ab236ed..3aa50dc7535b7 100644 +--- a/net/phonet/datagram.c ++++ b/net/phonet/datagram.c +@@ -28,24 +28,21 @@ static void pn_sock_close(struct sock *sk, long timeout) + sk_common_release(sk); + } + +-static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg) ++static int pn_ioctl(struct sock *sk, int cmd, int *karg) + { + struct sk_buff *skb; +- int answ; + + switch (cmd) { + case SIOCINQ: + lock_sock(sk); + skb = skb_peek(&sk->sk_receive_queue); +- answ = skb ? skb->len : 0; ++ *karg = skb ? skb->len : 0; + release_sock(sk); +- return put_user(answ, (int __user *)arg); ++ return 0; + + case SIOCPNADDRESOURCE: + case SIOCPNDELRESOURCE: { +- u32 res; +- if (get_user(res, (u32 __user *)arg)) +- return -EFAULT; ++ u32 res = *karg; + if (res >= 256) + return -EINVAL; + if (cmd == SIOCPNADDRESOURCE) +diff --git a/net/phonet/pep.c b/net/phonet/pep.c +index 83ea13a50690b..faba31f2eff29 100644 +--- a/net/phonet/pep.c ++++ b/net/phonet/pep.c +@@ -917,10 +917,9 @@ static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len) + return 0; + } + +-static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg) ++static int pep_ioctl(struct sock *sk, int cmd, int *karg) + { + struct pep_sock *pn = pep_sk(sk); +- int answ; + int ret = -ENOIOCTLCMD; + + switch (cmd) { +@@ -933,13 +932,13 @@ static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg) + lock_sock(sk); + if (sock_flag(sk, SOCK_URGINLINE) && + !skb_queue_empty(&pn->ctrlreq_queue)) +- answ = skb_peek(&pn->ctrlreq_queue)->len; ++ *karg = skb_peek(&pn->ctrlreq_queue)->len; + else if (!skb_queue_empty(&sk->sk_receive_queue)) +- answ = skb_peek(&sk->sk_receive_queue)->len; ++ *karg = skb_peek(&sk->sk_receive_queue)->len; + else +- answ = 0; ++ *karg = 0; + release_sock(sk); +- ret = put_user(answ, (int __user *)arg); ++ ret = 0; + break; + + case SIOCPNENABLEPIPE: +diff --git a/net/phonet/socket.c b/net/phonet/socket.c +index 71e2caf6ab859..967f9b4dc0265 100644 +--- a/net/phonet/socket.c ++++ b/net/phonet/socket.c +@@ -387,7 +387,7 @@ static int pn_socket_ioctl(struct socket *sock, unsigned int cmd, + return put_user(handle, (__u16 __user *)arg); + } + +- return sk->sk_prot->ioctl(sk, cmd, arg); ++ return sk_ioctl(sk, cmd, (void __user *)arg); + } + + static int pn_socket_listen(struct socket *sock, int backlog) +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 237a6b04adf6f..9c29bff647a11 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -4902,7 +4902,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err, bool kern) + } + + /* The SCTP ioctl handler. */ +-static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) ++static int sctp_ioctl(struct sock *sk, int cmd, int *karg) + { + int rc = -ENOTCONN; + +@@ -4918,7 +4918,7 @@ static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) + switch (cmd) { + case SIOCINQ: { + struct sk_buff *skb; +- unsigned int amount = 0; ++ *karg = 0; + + skb = skb_peek(&sk->sk_receive_queue); + if (skb != NULL) { +@@ -4926,9 +4926,9 @@ static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) + * We will only return the amount of this packet since + * that is all that will be read. + */ +- amount = skb->len; ++ *karg = skb->len; + } +- rc = put_user(amount, (int __user *)arg); ++ rc = 0; + break; + } + default: +-- +2.43.0 + diff --git a/queue-6.1/net-mctp-put-sock-on-tag-allocation-failure.patch b/queue-6.1/net-mctp-put-sock-on-tag-allocation-failure.patch new file mode 100644 index 00000000000..c8029cafe9d --- /dev/null +++ b/queue-6.1/net-mctp-put-sock-on-tag-allocation-failure.patch @@ -0,0 +1,42 @@ +From f806cb6e3a4b66b68257cefbadf0a8b5e11f2f79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 15:53:08 +0800 +Subject: net: mctp: put sock on tag allocation failure + +From: Jeremy Kerr + +[ Upstream commit 9990889be14288d4f1743e4768222d5032a79c27 ] + +We may hold an extra reference on a socket if a tag allocation fails: we +optimistically allocate the sk_key, and take a ref there, but do not +drop if we end up not using the allocated key. + +Ensure we're dropping the sock on this failure by doing a proper unref +rather than directly kfree()ing. + +Fixes: de8a6b15d965 ("net: mctp: add an explicit reference from a mctp_sk_key to sock") +Signed-off-by: Jeremy Kerr +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/ce9b61e44d1cdae7797be0c5e3141baf582d23a0.1707983487.git.jk@codeconstruct.com.au +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/mctp/route.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/mctp/route.c b/net/mctp/route.c +index 68be8f2b622dd..256bf0b89e6ca 100644 +--- a/net/mctp/route.c ++++ b/net/mctp/route.c +@@ -663,7 +663,7 @@ struct mctp_sk_key *mctp_alloc_local_tag(struct mctp_sock *msk, + spin_unlock_irqrestore(&mns->keys_lock, flags); + + if (!tagbits) { +- kfree(key); ++ mctp_key_unref(key); + return ERR_PTR(-EBUSY); + } + +-- +2.43.0 + diff --git a/queue-6.1/net-phy-realtek-fix-rtl8211f_config_init-for-rtl8211.patch b/queue-6.1/net-phy-realtek-fix-rtl8211f_config_init-for-rtl8211.patch new file mode 100644 index 00000000000..985ebced2bc --- /dev/null +++ b/queue-6.1/net-phy-realtek-fix-rtl8211f_config_init-for-rtl8211.patch @@ -0,0 +1,57 @@ +From 49b249c7a3d94e62196e307624d89b4212f923a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Feb 2024 12:30:07 +0530 +Subject: net: phy: realtek: Fix rtl8211f_config_init() for + RTL8211F(D)(I)-VD-CG PHY + +From: Siddharth Vadapalli + +[ Upstream commit 3489182b11d35f1944c1245fc9c4867cf622c50f ] + +Commit bb726b753f75 ("net: phy: realtek: add support for +RTL8211F(D)(I)-VD-CG") extended support of the driver from the existing +support for RTL8211F(D)(I)-CG PHY to the newer RTL8211F(D)(I)-VD-CG PHY. + +While that commit indicated that the RTL8211F_PHYCR2 register is not +supported by the "VD-CG" PHY model and therefore updated the corresponding +section in rtl8211f_config_init() to be invoked conditionally, the call to +"genphy_soft_reset()" was left as-is, when it should have also been invoked +conditionally. This is because the call to "genphy_soft_reset()" was first +introduced by the commit 0a4355c2b7f8 ("net: phy: realtek: add dt property +to disable CLKOUT clock") since the RTL8211F guide indicates that a PHY +reset should be issued after setting bits in the PHYCR2 register. + +As the PHYCR2 register is not applicable to the "VD-CG" PHY model, fix the +rtl8211f_config_init() function by invoking "genphy_soft_reset()" +conditionally based on the presence of the "PHYCR2" register. + +Fixes: bb726b753f75 ("net: phy: realtek: add support for RTL8211F(D)(I)-VD-CG") +Signed-off-by: Siddharth Vadapalli +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240220070007.968762-1-s-vadapalli@ti.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/phy/realtek.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c +index 3d99fd6664d7a..70e52d27064ec 100644 +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -414,9 +414,11 @@ static int rtl8211f_config_init(struct phy_device *phydev) + ERR_PTR(ret)); + return ret; + } ++ ++ return genphy_soft_reset(phydev); + } + +- return genphy_soft_reset(phydev); ++ return 0; + } + + static int rtl821x_resume(struct phy_device *phydev) +-- +2.43.0 + diff --git a/queue-6.1/net-sparx5-add-spinlock-for-frame-transmission-from-.patch b/queue-6.1/net-sparx5-add-spinlock-for-frame-transmission-from-.patch new file mode 100644 index 00000000000..f01cae7eb29 --- /dev/null +++ b/queue-6.1/net-sparx5-add-spinlock-for-frame-transmission-from-.patch @@ -0,0 +1,79 @@ +From 5051d5e36fb20f1bedb77327b708977af28d1647 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Feb 2024 09:00:43 +0100 +Subject: net: sparx5: Add spinlock for frame transmission from CPU + +From: Horatiu Vultur + +[ Upstream commit 603ead96582d85903baec2d55f021b8dac5c25d2 ] + +Both registers used when doing manual injection or fdma injection are +shared between all the net devices of the switch. It was noticed that +when having two process which each of them trying to inject frames on +different ethernet ports, that the HW started to behave strange, by +sending out more frames then expected. When doing fdma injection it is +required to set the frame in the DCB and then make sure that the next +pointer of the last DCB is invalid. But because there is no locks for +this, then easily this pointer between the DCB can be broken and then it +would create a loop of DCBs. And that means that the HW will +continuously transmit these frames in a loop. Until the SW will break +this loop. +Therefore to fix this issue, add a spin lock for when accessing the +registers for manual or fdma injection. + +Signed-off-by: Horatiu Vultur +Reviewed-by: Daniel Machon +Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support") +Link: https://lore.kernel.org/r/20240219080043.1561014-1-horatiu.vultur@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 1 + + drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 1 + + drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 2 ++ + 3 files changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +index 3423c95cc84ae..7031f41287e09 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +@@ -744,6 +744,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, sparx5); + sparx5->pdev = pdev; + sparx5->dev = &pdev->dev; ++ spin_lock_init(&sparx5->tx_lock); + + /* Do switch core reset if available */ + reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch"); +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h +index 7a83222caa737..cb3173d2b0e8d 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h +@@ -278,6 +278,7 @@ struct sparx5 { + int xtr_irq; + /* Frame DMA */ + int fdma_irq; ++ spinlock_t tx_lock; /* lock for frame transmission */ + struct sparx5_rx rx; + struct sparx5_tx tx; + /* PTP */ +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c +index 6db6ac6a3bbc2..ac7e1cffbcecf 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c +@@ -244,10 +244,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev) + } + + skb_tx_timestamp(skb); ++ spin_lock(&sparx5->tx_lock); + if (sparx5->fdma_irq > 0) + ret = sparx5_fdma_xmit(sparx5, ifh, skb); + else + ret = sparx5_inject(sparx5, ifh, skb, dev); ++ spin_unlock(&sparx5->tx_lock); + + if (ret == -EBUSY) + goto busy; +-- +2.43.0 + diff --git a/queue-6.1/net-stmmac-fix-incorrect-dereference-in-interrupt-ha.patch b/queue-6.1/net-stmmac-fix-incorrect-dereference-in-interrupt-ha.patch new file mode 100644 index 00000000000..0b0705d9578 --- /dev/null +++ b/queue-6.1/net-stmmac-fix-incorrect-dereference-in-interrupt-ha.patch @@ -0,0 +1,84 @@ +From f94bc64bb302393c14f3102fe0832a33b5d73756 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Feb 2024 12:27:17 +0300 +Subject: net: stmmac: Fix incorrect dereference in interrupt handlers + +From: Pavel Sakharov + +[ Upstream commit 97dde84026339e4b4af9a6301f825d1828d7874b ] + +If 'dev' or 'data' is NULL, the 'priv' variable has an incorrect address +when dereferencing calling netdev_err(). + +Since we get as 'dev_id' or 'data' what was passed as the 'dev' argument +to request_irq() during interrupt initialization (that is, the net_device +and rx/tx queue pointers initialized at the time of the call) and since +there are usually no checks for the 'dev_id' argument in such handlers +in other drivers, remove these checks from the handlers in stmmac driver. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 8532f613bc78 ("net: stmmac: introduce MSI Interrupt routines for mac, safety, RX & TX") +Signed-off-by: Pavel Sakharov +Reviewed-by: Serge Semin +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ------------------- + 1 file changed, 20 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 66178ce6d000e..91b2aa81914ba 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5823,11 +5823,6 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id) + struct net_device *dev = (struct net_device *)dev_id; + struct stmmac_priv *priv = netdev_priv(dev); + +- if (unlikely(!dev)) { +- netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); +- return IRQ_NONE; +- } +- + /* Check if adapter is up */ + if (test_bit(STMMAC_DOWN, &priv->state)) + return IRQ_HANDLED; +@@ -5843,11 +5838,6 @@ static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id) + struct net_device *dev = (struct net_device *)dev_id; + struct stmmac_priv *priv = netdev_priv(dev); + +- if (unlikely(!dev)) { +- netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); +- return IRQ_NONE; +- } +- + /* Check if adapter is up */ + if (test_bit(STMMAC_DOWN, &priv->state)) + return IRQ_HANDLED; +@@ -5869,11 +5859,6 @@ static irqreturn_t stmmac_msi_intr_tx(int irq, void *data) + dma_conf = container_of(tx_q, struct stmmac_dma_conf, tx_queue[chan]); + priv = container_of(dma_conf, struct stmmac_priv, dma_conf); + +- if (unlikely(!data)) { +- netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); +- return IRQ_NONE; +- } +- + /* Check if adapter is up */ + if (test_bit(STMMAC_DOWN, &priv->state)) + return IRQ_HANDLED; +@@ -5900,11 +5885,6 @@ static irqreturn_t stmmac_msi_intr_rx(int irq, void *data) + dma_conf = container_of(rx_q, struct stmmac_dma_conf, rx_queue[chan]); + priv = container_of(dma_conf, struct stmmac_priv, dma_conf); + +- if (unlikely(!data)) { +- netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); +- return IRQ_NONE; +- } +- + /* Check if adapter is up */ + if (test_bit(STMMAC_DOWN, &priv->state)) + return IRQ_HANDLED; +-- +2.43.0 + diff --git a/queue-6.1/netfilter-flowtable-simplify-route-logic.patch b/queue-6.1/netfilter-flowtable-simplify-route-logic.patch new file mode 100644 index 00000000000..61b6e75399e --- /dev/null +++ b/queue-6.1/netfilter-flowtable-simplify-route-logic.patch @@ -0,0 +1,128 @@ +From 4149f11f589a89e2246d7845a6c61e87d9430340 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 May 2023 07:35:33 +0200 +Subject: netfilter: flowtable: simplify route logic + +From: Pablo Neira Ayuso + +[ Upstream commit fa502c86566680ac62bc28ec883a069bf7a2aa5e ] + +Grab reference to dst from skbuff earlier to simplify route caching. + +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Stable-dep-of: 9e0f0430389b ("netfilter: nft_flow_offload: reset dst in route object after setting up flow") +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_flow_table.h | 4 ++-- + net/netfilter/nf_flow_table_core.c | 24 +++--------------------- + net/netfilter/nft_flow_offload.c | 12 ++++++++---- + 3 files changed, 13 insertions(+), 27 deletions(-) + +diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h +index dde4dd9c4012c..692d5955911c7 100644 +--- a/include/net/netfilter/nf_flow_table.h ++++ b/include/net/netfilter/nf_flow_table.h +@@ -274,8 +274,8 @@ nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table, + flow_table->type->put(flow_table); + } + +-int flow_offload_route_init(struct flow_offload *flow, +- const struct nf_flow_route *route); ++void flow_offload_route_init(struct flow_offload *flow, ++ const struct nf_flow_route *route); + + int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); + void flow_offload_refresh(struct nf_flowtable *flow_table, +diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c +index c1d99cb370b44..78e4aba52b22a 100644 +--- a/net/netfilter/nf_flow_table_core.c ++++ b/net/netfilter/nf_flow_table_core.c +@@ -125,9 +125,6 @@ static int flow_offload_fill_route(struct flow_offload *flow, + break; + case FLOW_OFFLOAD_XMIT_XFRM: + case FLOW_OFFLOAD_XMIT_NEIGH: +- if (!dst_hold_safe(route->tuple[dir].dst)) +- return -1; +- + flow_tuple->dst_cache = dst; + flow_tuple->dst_cookie = flow_offload_dst_cookie(flow_tuple); + break; +@@ -148,27 +145,12 @@ static void nft_flow_dst_release(struct flow_offload *flow, + dst_release(flow->tuplehash[dir].tuple.dst_cache); + } + +-int flow_offload_route_init(struct flow_offload *flow, ++void flow_offload_route_init(struct flow_offload *flow, + const struct nf_flow_route *route) + { +- int err; +- +- err = flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_ORIGINAL); +- if (err < 0) +- return err; +- +- err = flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_REPLY); +- if (err < 0) +- goto err_route_reply; +- ++ flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_ORIGINAL); ++ flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_REPLY); + flow->type = NF_FLOW_OFFLOAD_ROUTE; +- +- return 0; +- +-err_route_reply: +- nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_ORIGINAL); +- +- return err; + } + EXPORT_SYMBOL_GPL(flow_offload_route_init); + +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index 3d9f6dda5aeb2..7a8707632a815 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -250,9 +250,14 @@ static int nft_flow_route(const struct nft_pktinfo *pkt, + break; + } + ++ if (!dst_hold_safe(this_dst)) ++ return -ENOENT; ++ + nf_route(nft_net(pkt), &other_dst, &fl, false, nft_pf(pkt)); +- if (!other_dst) ++ if (!other_dst) { ++ dst_release(this_dst); + return -ENOENT; ++ } + + nft_default_forward_path(route, this_dst, dir); + nft_default_forward_path(route, other_dst, !dir); +@@ -349,8 +354,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, + if (!flow) + goto err_flow_alloc; + +- if (flow_offload_route_init(flow, &route) < 0) +- goto err_flow_add; ++ flow_offload_route_init(flow, &route); + + if (tcph) { + ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; +@@ -361,12 +365,12 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, + if (ret < 0) + goto err_flow_add; + +- dst_release(route.tuple[!dir].dst); + return; + + err_flow_add: + flow_offload_free(flow); + err_flow_alloc: ++ dst_release(route.tuple[dir].dst); + dst_release(route.tuple[!dir].dst); + err_flow_route: + clear_bit(IPS_OFFLOAD_BIT, &ct->status); +-- +2.43.0 + diff --git a/queue-6.1/netfilter-nf_tables-register-hooks-last-when-adding-.patch b/queue-6.1/netfilter-nf_tables-register-hooks-last-when-adding-.patch new file mode 100644 index 00000000000..2bb778224fb --- /dev/null +++ b/queue-6.1/netfilter-nf_tables-register-hooks-last-when-adding-.patch @@ -0,0 +1,191 @@ +From 795b8c0ab65fa3ae4ce101196d3793ded8052961 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Feb 2024 19:43:53 +0100 +Subject: netfilter: nf_tables: register hooks last when adding new + chain/flowtable + +From: Pablo Neira Ayuso + +[ Upstream commit d472e9853d7b46a6b094224d131d09ccd3a03daf ] + +Register hooks last when adding chain/flowtable to ensure that packets do +not walk over datastructure that is being released in the error path +without waiting for the rcu grace period. + +Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain") +Fixes: 3b49e2e94e6e ("netfilter: nf_tables: add flow table netlink frontend") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 78 ++++++++++++++++++----------------- + 1 file changed, 40 insertions(+), 38 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index c7b543d1a0516..a29313e0aaa4d 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -686,15 +686,16 @@ static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj) + return err; + } + +-static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, +- struct nft_flowtable *flowtable) ++static struct nft_trans * ++nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, ++ struct nft_flowtable *flowtable) + { + struct nft_trans *trans; + + trans = nft_trans_alloc(ctx, msg_type, + sizeof(struct nft_trans_flowtable)); + if (trans == NULL) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + + if (msg_type == NFT_MSG_NEWFLOWTABLE) + nft_activate_next(ctx->net, flowtable); +@@ -703,22 +704,22 @@ static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, + nft_trans_flowtable(trans) = flowtable; + nft_trans_commit_list_add_tail(ctx->net, trans); + +- return 0; ++ return trans; + } + + static int nft_delflowtable(struct nft_ctx *ctx, + struct nft_flowtable *flowtable) + { +- int err; ++ struct nft_trans *trans; + +- err = nft_trans_flowtable_add(ctx, NFT_MSG_DELFLOWTABLE, flowtable); +- if (err < 0) +- return err; ++ trans = nft_trans_flowtable_add(ctx, NFT_MSG_DELFLOWTABLE, flowtable); ++ if (IS_ERR(trans)) ++ return PTR_ERR(trans); + + nft_deactivate_next(ctx->net, flowtable); + nft_use_dec(&ctx->table->use); + +- return err; ++ return 0; + } + + static void __nft_reg_track_clobber(struct nft_regs_track *track, u8 dreg) +@@ -2459,19 +2460,15 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, + RCU_INIT_POINTER(chain->blob_gen_0, blob); + RCU_INIT_POINTER(chain->blob_gen_1, blob); + +- err = nf_tables_register_hook(net, table, chain); +- if (err < 0) +- goto err_destroy_chain; +- + if (!nft_use_inc(&table->use)) { + err = -EMFILE; +- goto err_use; ++ goto err_destroy_chain; + } + + trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN); + if (IS_ERR(trans)) { + err = PTR_ERR(trans); +- goto err_unregister_hook; ++ goto err_trans; + } + + nft_trans_chain_policy(trans) = NFT_CHAIN_POLICY_UNSET; +@@ -2479,17 +2476,22 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, + nft_trans_chain_policy(trans) = policy; + + err = nft_chain_add(table, chain); +- if (err < 0) { +- nft_trans_destroy(trans); +- goto err_unregister_hook; +- } ++ if (err < 0) ++ goto err_chain_add; ++ ++ /* This must be LAST to ensure no packets are walking over this chain. */ ++ err = nf_tables_register_hook(net, table, chain); ++ if (err < 0) ++ goto err_register_hook; + + return 0; + +-err_unregister_hook: ++err_register_hook: ++ nft_chain_del(chain); ++err_chain_add: ++ nft_trans_destroy(trans); ++err_trans: + nft_use_dec_restore(&table->use); +-err_use: +- nf_tables_unregister_hook(net, table, chain); + err_destroy_chain: + nf_tables_chain_destroy(ctx); + +@@ -8031,9 +8033,9 @@ static int nf_tables_newflowtable(struct sk_buff *skb, + u8 family = info->nfmsg->nfgen_family; + const struct nf_flowtable_type *type; + struct nft_flowtable *flowtable; +- struct nft_hook *hook, *next; + struct net *net = info->net; + struct nft_table *table; ++ struct nft_trans *trans; + struct nft_ctx ctx; + int err; + +@@ -8113,34 +8115,34 @@ static int nf_tables_newflowtable(struct sk_buff *skb, + err = nft_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], + &flowtable_hook, flowtable, true); + if (err < 0) +- goto err4; ++ goto err_flowtable_parse_hooks; + + list_splice(&flowtable_hook.list, &flowtable->hook_list); + flowtable->data.priority = flowtable_hook.priority; + flowtable->hooknum = flowtable_hook.num; + ++ trans = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable); ++ if (IS_ERR(trans)) { ++ err = PTR_ERR(trans); ++ goto err_flowtable_trans; ++ } ++ ++ /* This must be LAST to ensure no packets are walking over this flowtable. */ + err = nft_register_flowtable_net_hooks(ctx.net, table, + &flowtable->hook_list, + flowtable); +- if (err < 0) { +- nft_hooks_destroy(&flowtable->hook_list); +- goto err4; +- } +- +- err = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable); + if (err < 0) +- goto err5; ++ goto err_flowtable_hooks; + + list_add_tail_rcu(&flowtable->list, &table->flowtables); + + return 0; +-err5: +- list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { +- nft_unregister_flowtable_hook(net, flowtable, hook); +- list_del_rcu(&hook->list); +- kfree_rcu(hook, rcu); +- } +-err4: ++ ++err_flowtable_hooks: ++ nft_trans_destroy(trans); ++err_flowtable_trans: ++ nft_hooks_destroy(&flowtable->hook_list); ++err_flowtable_parse_hooks: + flowtable->data.type->free(&flowtable->data); + err3: + module_put(type->owner); +-- +2.43.0 + diff --git a/queue-6.1/netfilter-nf_tables-rename-function-to-destroy-hook-.patch b/queue-6.1/netfilter-nf_tables-rename-function-to-destroy-hook-.patch new file mode 100644 index 00000000000..82063f1ca51 --- /dev/null +++ b/queue-6.1/netfilter-nf_tables-rename-function-to-destroy-hook-.patch @@ -0,0 +1,62 @@ +From 1593cc918dde81d0111c2f4395641d8906524a2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Apr 2023 00:34:30 +0200 +Subject: netfilter: nf_tables: rename function to destroy hook list + +From: Pablo Neira Ayuso + +[ Upstream commit cdc32546632354305afdcf399a5431138a31c9e0 ] + +Rename nft_flowtable_hooks_destroy() by nft_hooks_destroy() to prepare +for netdev chain device updates. + +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: d472e9853d7b ("netfilter: nf_tables: register hooks last when adding new chain/flowtable") +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index f1a74b0949999..c7b543d1a0516 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -7938,7 +7938,7 @@ static int nft_register_flowtable_net_hooks(struct net *net, + return err; + } + +-static void nft_flowtable_hooks_destroy(struct list_head *hook_list) ++static void nft_hooks_destroy(struct list_head *hook_list) + { + struct nft_hook *hook, *next; + +@@ -8123,7 +8123,7 @@ static int nf_tables_newflowtable(struct sk_buff *skb, + &flowtable->hook_list, + flowtable); + if (err < 0) { +- nft_flowtable_hooks_destroy(&flowtable->hook_list); ++ nft_hooks_destroy(&flowtable->hook_list); + goto err4; + } + +@@ -8893,7 +8893,7 @@ static void nft_commit_release(struct nft_trans *trans) + break; + case NFT_MSG_DELFLOWTABLE: + if (nft_trans_flowtable_update(trans)) +- nft_flowtable_hooks_destroy(&nft_trans_flowtable_hooks(trans)); ++ nft_hooks_destroy(&nft_trans_flowtable_hooks(trans)); + else + nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); + break; +@@ -9850,7 +9850,7 @@ static void nf_tables_abort_release(struct nft_trans *trans) + break; + case NFT_MSG_NEWFLOWTABLE: + if (nft_trans_flowtable_update(trans)) +- nft_flowtable_hooks_destroy(&nft_trans_flowtable_hooks(trans)); ++ nft_hooks_destroy(&nft_trans_flowtable_hooks(trans)); + else + nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); + break; +-- +2.43.0 + diff --git a/queue-6.1/netfilter-nf_tables-set-dormant-flag-on-hook-registe.patch b/queue-6.1/netfilter-nf_tables-set-dormant-flag-on-hook-registe.patch new file mode 100644 index 00000000000..0b090f7d5a0 --- /dev/null +++ b/queue-6.1/netfilter-nf_tables-set-dormant-flag-on-hook-registe.patch @@ -0,0 +1,42 @@ +From 09be199d01a383d0b60fa2e30a2f9b853c97f9f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Feb 2024 16:58:04 +0100 +Subject: netfilter: nf_tables: set dormant flag on hook register failure + +From: Florian Westphal + +[ Upstream commit bccebf64701735533c8db37773eeacc6566cc8ec ] + +We need to set the dormant flag again if we fail to register +the hooks. + +During memory pressure hook registration can fail and we end up +with a table marked as active but no registered hooks. + +On table/base chain deletion, nf_tables will attempt to unregister +the hook again which yields a warn splat from the nftables core. + +Reported-and-tested-by: syzbot+de4025c006ec68ac56fc@syzkaller.appspotmail.com +Fixes: 179d9ba5559a ("netfilter: nf_tables: fix table flag updates") +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 49acb89ba9c56..f1a74b0949999 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -1245,6 +1245,7 @@ static int nf_tables_updtable(struct nft_ctx *ctx) + return 0; + + err_register_hooks: ++ ctx->table->flags |= NFT_TABLE_F_DORMANT; + nft_trans_destroy(trans); + return ret; + } +-- +2.43.0 + diff --git a/queue-6.1/netfilter-nf_tables-use-kzalloc-for-hook-allocation.patch b/queue-6.1/netfilter-nf_tables-use-kzalloc-for-hook-allocation.patch new file mode 100644 index 00000000000..838913d74d5 --- /dev/null +++ b/queue-6.1/netfilter-nf_tables-use-kzalloc-for-hook-allocation.patch @@ -0,0 +1,40 @@ +From 33db609121871f789aa7af3574b7b5f132508b9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Feb 2024 18:38:45 +0100 +Subject: netfilter: nf_tables: use kzalloc for hook allocation + +From: Florian Westphal + +[ Upstream commit 195e5f88c2e48330ba5483e0bad2de3b3fad484f ] + +KMSAN reports unitialized variable when registering the hook, + reg->hook_ops_type == NF_HOOK_OP_BPF) + ~~~~~~~~~~~ undefined + +This is a small structure, just use kzalloc to make sure this +won't happen again when new fields get added to nf_hook_ops. + +Fixes: 7b4b2fa37587 ("netfilter: annotate nf_tables base hook ops") +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index a29313e0aaa4d..e21ec3ad80939 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2059,7 +2059,7 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net, + struct nft_hook *hook; + int err; + +- hook = kmalloc(sizeof(struct nft_hook), GFP_KERNEL_ACCOUNT); ++ hook = kzalloc(sizeof(struct nft_hook), GFP_KERNEL_ACCOUNT); + if (!hook) { + err = -ENOMEM; + goto err_hook_alloc; +-- +2.43.0 + diff --git a/queue-6.1/netfilter-nft_flow_offload-release-dst-in-case-direc.patch b/queue-6.1/netfilter-nft_flow_offload-release-dst-in-case-direc.patch new file mode 100644 index 00000000000..a706e4f6b1a --- /dev/null +++ b/queue-6.1/netfilter-nft_flow_offload-release-dst-in-case-direc.patch @@ -0,0 +1,61 @@ +From 48a0ad02aa81bbb1f08891b8f2b873a3b954fa47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Feb 2024 21:36:39 +0100 +Subject: netfilter: nft_flow_offload: release dst in case direct xmit path is + used + +From: Pablo Neira Ayuso + +[ Upstream commit 8762785f459be1cfe6fcf7285c123aad6a3703f0 ] + +Direct xmit does not use it since it calls dev_queue_xmit() to send +packets, hence it calls dst_release(). + +kmemleak reports: + +unreferenced object 0xffff88814f440900 (size 184): + comm "softirq", pid 0, jiffies 4294951896 + hex dump (first 32 bytes): + 00 60 5b 04 81 88 ff ff 00 e6 e8 82 ff ff ff ff .`[............. + 21 0b 50 82 ff ff ff ff 00 00 00 00 00 00 00 00 !.P............. + backtrace (crc cb2bf5d6): + [<000000003ee17107>] kmem_cache_alloc+0x286/0x340 + [<0000000021a5de2c>] dst_alloc+0x43/0xb0 + [<00000000f0671159>] rt_dst_alloc+0x2e/0x190 + [<00000000fe5092c9>] __mkroute_output+0x244/0x980 + [<000000005fb96fb0>] ip_route_output_flow+0xc0/0x160 + [<0000000045367433>] nf_ip_route+0xf/0x30 + [<0000000085da1d8e>] nf_route+0x2d/0x60 + [<00000000d1ecd1cb>] nft_flow_route+0x171/0x6a0 [nft_flow_offload] + [<00000000d9b2fb60>] nft_flow_offload_eval+0x4e8/0x700 [nft_flow_offload] + [<000000009f447dbb>] expr_call_ops_eval+0x53/0x330 [nf_tables] + [<00000000072e1be6>] nft_do_chain+0x17c/0x840 [nf_tables] + [<00000000d0551029>] nft_do_chain_inet+0xa1/0x210 [nf_tables] + [<0000000097c9d5c6>] nf_hook_slow+0x5b/0x160 + [<0000000005eccab1>] ip_forward+0x8b6/0x9b0 + [<00000000553a269b>] ip_rcv+0x221/0x230 + [<00000000412872e5>] __netif_receive_skb_one_core+0xfe/0x110 + +Fixes: fa502c865666 ("netfilter: flowtable: simplify route logic") +Reported-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_flow_table_core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c +index 2036c7a27075b..99195cf6b2657 100644 +--- a/net/netfilter/nf_flow_table_core.c ++++ b/net/netfilter/nf_flow_table_core.c +@@ -132,6 +132,7 @@ static int flow_offload_fill_route(struct flow_offload *flow, + ETH_ALEN); + flow_tuple->out.ifidx = route->tuple[dir].out.ifindex; + flow_tuple->out.hw_ifidx = route->tuple[dir].out.hw_ifindex; ++ dst_release(dst); + break; + case FLOW_OFFLOAD_XMIT_XFRM: + case FLOW_OFFLOAD_XMIT_NEIGH: +-- +2.43.0 + diff --git a/queue-6.1/netfilter-nft_flow_offload-reset-dst-in-route-object.patch b/queue-6.1/netfilter-nft_flow_offload-reset-dst-in-route-object.patch new file mode 100644 index 00000000000..5acb79d841e --- /dev/null +++ b/queue-6.1/netfilter-nft_flow_offload-reset-dst-in-route-object.patch @@ -0,0 +1,76 @@ +From 0fd162379ba0c91a4dcf5e1309a208acb894043d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Feb 2024 12:32:58 +0100 +Subject: netfilter: nft_flow_offload: reset dst in route object after setting + up flow + +From: Pablo Neira Ayuso + +[ Upstream commit 9e0f0430389be7696396c62f037be4bf72cf93e3 ] + +dst is transferred to the flow object, route object does not own it +anymore. Reset dst in route object, otherwise if flow_offload_add() +fails, error path releases dst twice, leading to a refcount underflow. + +Fixes: a3c90f7a2323 ("netfilter: nf_tables: flow offload expression") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_flow_table.h | 2 +- + net/netfilter/nf_flow_table_core.c | 16 +++++++++++++--- + 2 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h +index 692d5955911c7..4a767b3d20b9d 100644 +--- a/include/net/netfilter/nf_flow_table.h ++++ b/include/net/netfilter/nf_flow_table.h +@@ -275,7 +275,7 @@ nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table, + } + + void flow_offload_route_init(struct flow_offload *flow, +- const struct nf_flow_route *route); ++ struct nf_flow_route *route); + + int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); + void flow_offload_refresh(struct nf_flowtable *flow_table, +diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c +index 78e4aba52b22a..2036c7a27075b 100644 +--- a/net/netfilter/nf_flow_table_core.c ++++ b/net/netfilter/nf_flow_table_core.c +@@ -87,12 +87,22 @@ static u32 flow_offload_dst_cookie(struct flow_offload_tuple *flow_tuple) + return 0; + } + ++static struct dst_entry *nft_route_dst_fetch(struct nf_flow_route *route, ++ enum flow_offload_tuple_dir dir) ++{ ++ struct dst_entry *dst = route->tuple[dir].dst; ++ ++ route->tuple[dir].dst = NULL; ++ ++ return dst; ++} ++ + static int flow_offload_fill_route(struct flow_offload *flow, +- const struct nf_flow_route *route, ++ struct nf_flow_route *route, + enum flow_offload_tuple_dir dir) + { + struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; +- struct dst_entry *dst = route->tuple[dir].dst; ++ struct dst_entry *dst = nft_route_dst_fetch(route, dir); + int i, j = 0; + + switch (flow_tuple->l3proto) { +@@ -146,7 +156,7 @@ static void nft_flow_dst_release(struct flow_offload *flow, + } + + void flow_offload_route_init(struct flow_offload *flow, +- const struct nf_flow_route *route) ++ struct nf_flow_route *route) + { + flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_ORIGINAL); + flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_REPLY); +-- +2.43.0 + diff --git a/queue-6.1/nouveau-fix-function-cast-warnings.patch b/queue-6.1/nouveau-fix-function-cast-warnings.patch new file mode 100644 index 00000000000..8480ed3cff3 --- /dev/null +++ b/queue-6.1/nouveau-fix-function-cast-warnings.patch @@ -0,0 +1,54 @@ +From 40e6df1db011eb416bcabb72f9532b60557db2c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 10:57:37 +0100 +Subject: nouveau: fix function cast warnings + +From: Arnd Bergmann + +[ Upstream commit 0affdba22aca5573f9d989bcb1d71d32a6a03efe ] + +clang-16 warns about casting between incompatible function types: + +drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c:161:10: error: cast from 'void (*)(const struct firmware *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict] + 161 | .fini = (void(*)(void *))release_firmware, + +This one was done to use the generic shadow_fw_release() function as a +callback for struct nvbios_source. Change it to use the same prototype +as the other five instances, with a trivial helper function that actually +calls release_firmware. + +Fixes: 70c0f263cc2e ("drm/nouveau/bios: pull in basic vbios subdev, more to come later") +Signed-off-by: Arnd Bergmann +Signed-off-by: Danilo Krummrich +Link: https://patchwork.freedesktop.org/patch/msgid/20240213095753.455062-1-arnd@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c +index 19188683c8fca..8c2bf1c16f2a9 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c +@@ -154,11 +154,17 @@ shadow_fw_init(struct nvkm_bios *bios, const char *name) + return (void *)fw; + } + ++static void ++shadow_fw_release(void *fw) ++{ ++ release_firmware(fw); ++} ++ + static const struct nvbios_source + shadow_fw = { + .name = "firmware", + .init = shadow_fw_init, +- .fini = (void(*)(void *))release_firmware, ++ .fini = shadow_fw_release, + .read = shadow_fw_read, + .rw = false, + }; +-- +2.43.0 + diff --git a/queue-6.1/octeontx2-af-consider-the-action-set-by-pf.patch b/queue-6.1/octeontx2-af-consider-the-action-set-by-pf.patch new file mode 100644 index 00000000000..60d69928119 --- /dev/null +++ b/queue-6.1/octeontx2-af-consider-the-action-set-by-pf.patch @@ -0,0 +1,46 @@ +From 9071c7009209488722f5da4de852c83908097fa0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Feb 2024 18:25:14 +0530 +Subject: octeontx2-af: Consider the action set by PF + +From: Subbaraya Sundeep + +[ Upstream commit 3b1ae9b71c2a97f848b00fb085a2bd29bddbe8d9 ] + +AF reserves MCAM entries for each PF, VF present in the +system and populates the entry with DMAC and action with +default RSS so that basic packet I/O works. Since PF/VF is +not aware of the RSS action installed by AF, AF only fixup +the actions of the rules installed by PF/VF with corresponding +default RSS action. This worked well for rules installed by +PF/VF for features like RX VLAN offload and DMAC filters but +rules involving action like drop/forward to queue are also +getting modified by AF. Hence fix it by setting the default +RSS action only if requested by PF/VF. + +Fixes: 967db3529eca ("octeontx2-af: add support for multicast/promisc packet replication feature") +Signed-off-by: Subbaraya Sundeep +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 3784347b6fd88..55639c133dd02 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -437,6 +437,10 @@ static void npc_fixup_vf_rule(struct rvu *rvu, struct npc_mcam *mcam, + return; + } + ++ /* AF modifies given action iff PF/VF has requested for it */ ++ if ((entry->action & 0xFULL) != NIX_RX_ACTION_DEFAULT) ++ return; ++ + /* copy VF default entry action to the VF mcam entry */ + rx_action = npc_get_default_entry_action(rvu, mcam, blkaddr, + target_func); +-- +2.43.0 + diff --git a/queue-6.1/phonet-pep-fix-racy-skb_queue_empty-use.patch b/queue-6.1/phonet-pep-fix-racy-skb_queue_empty-use.patch new file mode 100644 index 00000000000..7152549d075 --- /dev/null +++ b/queue-6.1/phonet-pep-fix-racy-skb_queue_empty-use.patch @@ -0,0 +1,87 @@ +From 6dc94850c4e644c3186f1b1dbd8b577769ea3b4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 18 Feb 2024 10:12:14 +0200 +Subject: phonet/pep: fix racy skb_queue_empty() use +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rémi Denis-Courmont + +[ Upstream commit 7d2a894d7f487dcb894df023e9d3014cf5b93fe5 ] + +The receive queues are protected by their respective spin-lock, not +the socket lock. This could lead to skb_peek() unexpectedly +returning NULL or a pointer to an already dequeued socket buffer. + +Fixes: 9641458d3ec4 ("Phonet: Pipe End Point for Phonet Pipes protocol") +Signed-off-by: Rémi Denis-Courmont +Link: https://lore.kernel.org/r/20240218081214.4806-2-remi@remlab.net +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/phonet/pep.c | 41 ++++++++++++++++++++++++++++++++--------- + 1 file changed, 32 insertions(+), 9 deletions(-) + +diff --git a/net/phonet/pep.c b/net/phonet/pep.c +index faba31f2eff29..3dd5f52bc1b58 100644 +--- a/net/phonet/pep.c ++++ b/net/phonet/pep.c +@@ -917,6 +917,37 @@ static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len) + return 0; + } + ++static unsigned int pep_first_packet_length(struct sock *sk) ++{ ++ struct pep_sock *pn = pep_sk(sk); ++ struct sk_buff_head *q; ++ struct sk_buff *skb; ++ unsigned int len = 0; ++ bool found = false; ++ ++ if (sock_flag(sk, SOCK_URGINLINE)) { ++ q = &pn->ctrlreq_queue; ++ spin_lock_bh(&q->lock); ++ skb = skb_peek(q); ++ if (skb) { ++ len = skb->len; ++ found = true; ++ } ++ spin_unlock_bh(&q->lock); ++ } ++ ++ if (likely(!found)) { ++ q = &sk->sk_receive_queue; ++ spin_lock_bh(&q->lock); ++ skb = skb_peek(q); ++ if (skb) ++ len = skb->len; ++ spin_unlock_bh(&q->lock); ++ } ++ ++ return len; ++} ++ + static int pep_ioctl(struct sock *sk, int cmd, int *karg) + { + struct pep_sock *pn = pep_sk(sk); +@@ -929,15 +960,7 @@ static int pep_ioctl(struct sock *sk, int cmd, int *karg) + break; + } + +- lock_sock(sk); +- if (sock_flag(sk, SOCK_URGINLINE) && +- !skb_queue_empty(&pn->ctrlreq_queue)) +- *karg = skb_peek(&pn->ctrlreq_queue)->len; +- else if (!skb_queue_empty(&sk->sk_receive_queue)) +- *karg = skb_peek(&sk->sk_receive_queue)->len; +- else +- *karg = 0; +- release_sock(sk); ++ *karg = pep_first_packet_length(sk); + ret = 0; + break; + +-- +2.43.0 + diff --git a/queue-6.1/phonet-take-correct-lock-to-peek-at-the-rx-queue.patch b/queue-6.1/phonet-take-correct-lock-to-peek-at-the-rx-queue.patch new file mode 100644 index 00000000000..711d9e3495f --- /dev/null +++ b/queue-6.1/phonet-take-correct-lock-to-peek-at-the-rx-queue.patch @@ -0,0 +1,46 @@ +From 1f5a44d59b1b5de08871b7c222043aa6fe0c382a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 18 Feb 2024 10:12:13 +0200 +Subject: phonet: take correct lock to peek at the RX queue +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rémi Denis-Courmont + +[ Upstream commit 3b2d9bc4d4acdf15a876eae2c0d83149250e85ba ] + +The receive queue is protected by its embedded spin-lock, not the +socket lock, so we need the former lock here (and only that one). + +Fixes: 107d0d9b8d9a ("Phonet: Phonet datagram transport protocol") +Reported-by: Luosili +Signed-off-by: Rémi Denis-Courmont +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20240218081214.4806-1-remi@remlab.net +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/phonet/datagram.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c +index 3aa50dc7535b7..976fe250b5095 100644 +--- a/net/phonet/datagram.c ++++ b/net/phonet/datagram.c +@@ -34,10 +34,10 @@ static int pn_ioctl(struct sock *sk, int cmd, int *karg) + + switch (cmd) { + case SIOCINQ: +- lock_sock(sk); ++ spin_lock_bh(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); + *karg = skb ? skb->len : 0; +- release_sock(sk); ++ spin_unlock_bh(&sk->sk_receive_queue.lock); + return 0; + + case SIOCPNADDRESOURCE: +-- +2.43.0 + diff --git a/queue-6.1/platform-x86-thinkpad_acpi-only-update-profile-if-su.patch b/queue-6.1/platform-x86-thinkpad_acpi-only-update-profile-if-su.patch new file mode 100644 index 00000000000..a2d053fd66c --- /dev/null +++ b/queue-6.1/platform-x86-thinkpad_acpi-only-update-profile-if-su.patch @@ -0,0 +1,61 @@ +From 3bc92822a99dc339035146d658250db282eb2243 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Feb 2024 20:23:11 -0600 +Subject: platform/x86: thinkpad_acpi: Only update profile if successfully + converted + +From: Mario Limonciello + +[ Upstream commit 427c70dec738318b7f71e1b9d829ff0e9771d493 ] + +Randomly a Lenovo Z13 will trigger a kernel warning traceback from this +condition: + +``` +if (WARN_ON((profile < 0) || (profile >= ARRAY_SIZE(profile_names)))) +``` + +This happens because thinkpad-acpi always assumes that +convert_dytc_to_profile() successfully updated the profile. On the +contrary a condition can occur that when dytc_profile_refresh() is called +the profile doesn't get updated as there is a -EOPNOTSUPP branch. + +Catch this situation and avoid updating the profile. Also log this into +dynamic debugging in case any other modes should be added in the future. + +Fixes: c3bfcd4c6762 ("platform/x86: thinkpad_acpi: Add platform profile support") +Signed-off-by: Mario Limonciello +Link: https://lore.kernel.org/r/20240217022311.113879-1-mario.limonciello@amd.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/thinkpad_acpi.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 6edd2e294750e..c2fb19af10705 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -10511,6 +10511,7 @@ static int convert_dytc_to_profile(int funcmode, int dytcmode, + return 0; + default: + /* Unknown function */ ++ pr_debug("unknown function 0x%x\n", funcmode); + return -EOPNOTSUPP; + } + return 0; +@@ -10696,8 +10697,8 @@ static void dytc_profile_refresh(void) + return; + + perfmode = (output >> DYTC_GET_MODE_BIT) & 0xF; +- convert_dytc_to_profile(funcmode, perfmode, &profile); +- if (profile != dytc_current_profile) { ++ err = convert_dytc_to_profile(funcmode, perfmode, &profile); ++ if (!err && profile != dytc_current_profile) { + dytc_current_profile = profile; + platform_profile_notify(); + } +-- +2.43.0 + diff --git a/queue-6.1/rdma-bnxt_re-return-error-for-srq-resize.patch b/queue-6.1/rdma-bnxt_re-return-error-for-srq-resize.patch new file mode 100644 index 00000000000..53b08a33245 --- /dev/null +++ b/queue-6.1/rdma-bnxt_re-return-error-for-srq-resize.patch @@ -0,0 +1,53 @@ +From 20828f272a533db4970c971e51edf00cb49835c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Jan 2024 20:54:36 -0800 +Subject: RDMA/bnxt_re: Return error for SRQ resize + +From: Kalesh AP + +[ Upstream commit 3687b450c5f32e80f179ce4b09e0454da1449eac ] + +SRQ resize is not supported in the driver. But driver is not +returning error from bnxt_re_modify_srq() for SRQ resize. + +Fixes: 37cb11acf1f7 ("RDMA/bnxt_re: Add SRQ support for Broadcom adapters") +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://lore.kernel.org/r/1705985677-15551-5-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index 4ed8814efde6f..6ed0568747eaa 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -1710,7 +1710,7 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr, + switch (srq_attr_mask) { + case IB_SRQ_MAX_WR: + /* SRQ resize is not supported */ +- break; ++ return -EINVAL; + case IB_SRQ_LIMIT: + /* Change the SRQ threshold */ + if (srq_attr->srq_limit > srq->qplib_srq.max_wqe) +@@ -1725,13 +1725,12 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr, + /* On success, update the shadow */ + srq->srq_limit = srq_attr->srq_limit; + /* No need to Build and send response back to udata */ +- break; ++ return 0; + default: + ibdev_err(&rdev->ibdev, + "Unsupported srq_attr_mask 0x%x", srq_attr_mask); + return -EINVAL; + } +- return 0; + } + + int bnxt_re_query_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr) +-- +2.43.0 + diff --git a/queue-6.1/rdma-irdma-add-ae-for-too-many-rnrs.patch b/queue-6.1/rdma-irdma-add-ae-for-too-many-rnrs.patch new file mode 100644 index 00000000000..27ab9b4cf85 --- /dev/null +++ b/queue-6.1/rdma-irdma-add-ae-for-too-many-rnrs.patch @@ -0,0 +1,51 @@ +From 8b2aab68d1c40b38beed9264faaea1564d210dfd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 17:38:49 -0600 +Subject: RDMA/irdma: Add AE for too many RNRS + +From: Mustafa Ismail + +[ Upstream commit 630bdb6f28ca9e5ff79e244030170ac788478332 ] + +Add IRDMA_AE_LLP_TOO_MANY_RNRS to the list of AE's processed as an +abnormal asyncronous event. + +Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs") +Signed-off-by: Mustafa Ismail +Signed-off-by: Shiraz Saleem +Signed-off-by: Sindhu Devale +Link: https://lore.kernel.org/r/20240131233849.400285-5-sindhu.devale@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/defs.h | 1 + + drivers/infiniband/hw/irdma/hw.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/defs.h b/drivers/infiniband/hw/irdma/defs.h +index ad54260cb58c9..ebe98fa2b1cd2 100644 +--- a/drivers/infiniband/hw/irdma/defs.h ++++ b/drivers/infiniband/hw/irdma/defs.h +@@ -345,6 +345,7 @@ enum irdma_cqp_op_type { + #define IRDMA_AE_LLP_TOO_MANY_KEEPALIVE_RETRIES 0x050b + #define IRDMA_AE_LLP_DOUBT_REACHABILITY 0x050c + #define IRDMA_AE_LLP_CONNECTION_ESTABLISHED 0x050e ++#define IRDMA_AE_LLP_TOO_MANY_RNRS 0x050f + #define IRDMA_AE_RESOURCE_EXHAUSTION 0x0520 + #define IRDMA_AE_RESET_SENT 0x0601 + #define IRDMA_AE_TERMINATE_SENT 0x0602 +diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c +index 12bd38b1e2c15..918a2d783141f 100644 +--- a/drivers/infiniband/hw/irdma/hw.c ++++ b/drivers/infiniband/hw/irdma/hw.c +@@ -379,6 +379,7 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) + case IRDMA_AE_LLP_TOO_MANY_RETRIES: + case IRDMA_AE_LCE_QP_CATASTROPHIC: + case IRDMA_AE_LCE_FUNCTION_CATASTROPHIC: ++ case IRDMA_AE_LLP_TOO_MANY_RNRS: + case IRDMA_AE_LCE_CQ_CATASTROPHIC: + case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG: + default: +-- +2.43.0 + diff --git a/queue-6.1/rdma-irdma-fix-kasan-issue-with-tasklet.patch b/queue-6.1/rdma-irdma-fix-kasan-issue-with-tasklet.patch new file mode 100644 index 00000000000..7ddab749acd --- /dev/null +++ b/queue-6.1/rdma-irdma-fix-kasan-issue-with-tasklet.patch @@ -0,0 +1,69 @@ +From 9268c24bff8072ca5744676c05748cc60903e33d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 17:38:46 -0600 +Subject: RDMA/irdma: Fix KASAN issue with tasklet + +From: Mike Marciniszyn + +[ Upstream commit bd97cea7b18a0a553773af806dfbfac27a7c4acb ] + +KASAN testing revealed the following issue assocated with freeing an IRQ. + +[50006.466686] Call Trace: +[50006.466691] +[50006.489538] dump_stack+0x5c/0x80 +[50006.493475] print_address_description.constprop.6+0x1a/0x150 +[50006.499872] ? irdma_sc_process_ceq+0x483/0x790 [irdma] +[50006.505742] ? irdma_sc_process_ceq+0x483/0x790 [irdma] +[50006.511644] kasan_report.cold.11+0x7f/0x118 +[50006.516572] ? irdma_sc_process_ceq+0x483/0x790 [irdma] +[50006.522473] irdma_sc_process_ceq+0x483/0x790 [irdma] +[50006.528232] irdma_process_ceq+0xb2/0x400 [irdma] +[50006.533601] ? irdma_hw_flush_wqes_callback+0x370/0x370 [irdma] +[50006.540298] irdma_ceq_dpc+0x44/0x100 [irdma] +[50006.545306] tasklet_action_common.isra.14+0x148/0x2c0 +[50006.551096] __do_softirq+0x1d0/0xaf8 +[50006.555396] irq_exit_rcu+0x219/0x260 +[50006.559670] irq_exit+0xa/0x20 +[50006.563320] smp_apic_timer_interrupt+0x1bf/0x690 +[50006.568645] apic_timer_interrupt+0xf/0x20 +[50006.573341] + +The issue is that a tasklet could be pending on another core racing +the delete of the irq. + +Fix by insuring any scheduled tasklet is killed after deleting the +irq. + +Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions") +Signed-off-by: Mike Marciniszyn +Signed-off-by: Shiraz Saleem +Signed-off-by: Sindhu Devale +Link: https://lore.kernel.org/r/20240131233849.400285-2-sindhu.devale@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/hw.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c +index 311a1138e838d..12bd38b1e2c15 100644 +--- a/drivers/infiniband/hw/irdma/hw.c ++++ b/drivers/infiniband/hw/irdma/hw.c +@@ -562,6 +562,13 @@ static void irdma_destroy_irq(struct irdma_pci_f *rf, + dev->irq_ops->irdma_dis_irq(dev, msix_vec->idx); + irq_update_affinity_hint(msix_vec->irq, NULL); + free_irq(msix_vec->irq, dev_id); ++ if (rf == dev_id) { ++ tasklet_kill(&rf->dpc_tasklet); ++ } else { ++ struct irdma_ceq *iwceq = (struct irdma_ceq *)dev_id; ++ ++ tasklet_kill(&iwceq->dpc_tasklet); ++ } + } + + /** +-- +2.43.0 + diff --git a/queue-6.1/rdma-irdma-set-the-cq-read-threshold-for-gen-1.patch b/queue-6.1/rdma-irdma-set-the-cq-read-threshold-for-gen-1.patch new file mode 100644 index 00000000000..a1a7aebb8ae --- /dev/null +++ b/queue-6.1/rdma-irdma-set-the-cq-read-threshold-for-gen-1.patch @@ -0,0 +1,43 @@ +From d3ee42ec947f951c1040ccb91859f08ec9641923 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 17:38:48 -0600 +Subject: RDMA/irdma: Set the CQ read threshold for GEN 1 + +From: Mustafa Ismail + +[ Upstream commit 666047f3ece9f991774c1fe9b223139a9ef8908d ] + +The CQ shadow read threshold is currently not set for GEN 2. This could +cause an invalid CQ overflow condition, so remove the GEN check that +exclused GEN 1. + +Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs") +Signed-off-by: Mustafa Ismail +Signed-off-by: Shiraz Saleem +Signed-off-by: Sindhu Devale +Link: https://lore.kernel.org/r/20240131233849.400285-4-sindhu.devale@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/verbs.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index 0fbc39df1e7d4..42c671f209233 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -2121,9 +2121,8 @@ static int irdma_create_cq(struct ib_cq *ibcq, + info.cq_base_pa = iwcq->kmem.pa; + } + +- if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) +- info.shadow_read_threshold = min(info.cq_uk_init_info.cq_size / 2, +- (u32)IRDMA_MAX_CQ_READ_THRESH); ++ info.shadow_read_threshold = min(info.cq_uk_init_info.cq_size / 2, ++ (u32)IRDMA_MAX_CQ_READ_THRESH); + + if (irdma_sc_cq_init(cq, &info)) { + ibdev_dbg(&iwdev->ibdev, "VERBS: init cq fail\n"); +-- +2.43.0 + diff --git a/queue-6.1/rdma-irdma-validate-max_send_wr-and-max_recv_wr.patch b/queue-6.1/rdma-irdma-validate-max_send_wr-and-max_recv_wr.patch new file mode 100644 index 00000000000..8f55a7ecd53 --- /dev/null +++ b/queue-6.1/rdma-irdma-validate-max_send_wr-and-max_recv_wr.patch @@ -0,0 +1,41 @@ +From e2785e1bca91ac0b4f3bc17258c3f8bb2bbb9566 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 17:38:47 -0600 +Subject: RDMA/irdma: Validate max_send_wr and max_recv_wr + +From: Shiraz Saleem + +[ Upstream commit ee107186bcfd25d7873258f3f75440e20f5e6416 ] + +Validate that max_send_wr and max_recv_wr is within the +supported range. + +Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs") +Change-Id: I2fc8b10292b641fddd20b36986a9dae90a93f4be +Signed-off-by: Shiraz Saleem +Signed-off-by: Sindhu Devale +Link: https://lore.kernel.org/r/20240131233849.400285-3-sindhu.devale@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/verbs.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index 01faec6ea5285..0fbc39df1e7d4 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -762,7 +762,9 @@ static int irdma_validate_qp_attrs(struct ib_qp_init_attr *init_attr, + + if (init_attr->cap.max_inline_data > uk_attrs->max_hw_inline || + init_attr->cap.max_send_sge > uk_attrs->max_hw_wq_frags || +- init_attr->cap.max_recv_sge > uk_attrs->max_hw_wq_frags) ++ init_attr->cap.max_recv_sge > uk_attrs->max_hw_wq_frags || ++ init_attr->cap.max_send_wr > uk_attrs->max_hw_wq_quanta || ++ init_attr->cap.max_recv_wr > uk_attrs->max_hw_rq_quanta) + return -EINVAL; + + if (rdma_protocol_roce(&iwdev->ibdev, 1)) { +-- +2.43.0 + diff --git a/queue-6.1/rdma-qedr-fix-qedr_create_user_qp-error-flow.patch b/queue-6.1/rdma-qedr-fix-qedr_create_user_qp-error-flow.patch new file mode 100644 index 00000000000..0dfaf72dc5f --- /dev/null +++ b/queue-6.1/rdma-qedr-fix-qedr_create_user_qp-error-flow.patch @@ -0,0 +1,109 @@ +From 973c9a2e9a723a8e8f7eb8454f67b124325686c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Feb 2024 17:36:28 -0500 +Subject: RDMA/qedr: Fix qedr_create_user_qp error flow + +From: Kamal Heib + +[ Upstream commit 5ba4e6d5863c53e937f49932dee0ecb004c65928 ] + +Avoid the following warning by making sure to free the allocated +resources in case that qedr_init_user_queue() fail. + +-----------[ cut here ]----------- +WARNING: CPU: 0 PID: 143192 at drivers/infiniband/core/rdma_core.c:874 uverbs_destroy_ufile_hw+0xcf/0xf0 [ib_uverbs] +Modules linked in: tls target_core_user uio target_core_pscsi target_core_file target_core_iblock ib_srpt ib_srp scsi_transport_srp nfsd nfs_acl rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache netfs 8021q garp mrp stp llc ext4 mbcache jbd2 opa_vnic ib_umad ib_ipoib sunrpc rdma_ucm ib_isert iscsi_target_mod target_core_mod ib_iser libiscsi scsi_transport_iscsi rdma_cm iw_cm ib_cm hfi1 intel_rapl_msr intel_rapl_common mgag200 qedr sb_edac drm_shmem_helper rdmavt x86_pkg_temp_thermal drm_kms_helper intel_powerclamp ib_uverbs coretemp i2c_algo_bit kvm_intel dell_wmi_descriptor ipmi_ssif sparse_keymap kvm ib_core rfkill syscopyarea sysfillrect video sysimgblt irqbypass ipmi_si ipmi_devintf fb_sys_fops rapl iTCO_wdt mxm_wmi iTCO_vendor_support intel_cstate pcspkr dcdbas intel_uncore ipmi_msghandler lpc_ich acpi_power_meter mei_me mei fuse drm xfs libcrc32c qede sd_mod ahci libahci t10_pi sg crct10dif_pclmul crc32_pclmul crc32c_intel qed libata tg3 +ghash_clmulni_intel megaraid_sas crc8 wmi [last unloaded: ib_srpt] +CPU: 0 PID: 143192 Comm: fi_rdm_tagged_p Kdump: loaded Not tainted 5.14.0-408.el9.x86_64 #1 +Hardware name: Dell Inc. PowerEdge R430/03XKDV, BIOS 2.14.0 01/25/2022 +RIP: 0010:uverbs_destroy_ufile_hw+0xcf/0xf0 [ib_uverbs] +Code: 5d 41 5c 41 5d 41 5e e9 0f 26 1b dd 48 89 df e8 67 6a ff ff 49 8b 86 10 01 00 00 48 85 c0 74 9c 4c 89 e7 e8 83 c0 cb dd eb 92 <0f> 0b eb be 0f 0b be 04 00 00 00 48 89 df e8 8e f5 ff ff e9 6d ff +RSP: 0018:ffffb7c6cadfbc60 EFLAGS: 00010286 +RAX: ffff8f0889ee3f60 RBX: ffff8f088c1a5200 RCX: 00000000802a0016 +RDX: 00000000802a0017 RSI: 0000000000000001 RDI: ffff8f0880042600 +RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000000 +R10: ffff8f11fffd5000 R11: 0000000000039000 R12: ffff8f0d5b36cd80 +R13: ffff8f088c1a5250 R14: ffff8f1206d91000 R15: 0000000000000000 +FS: 0000000000000000(0000) GS:ffff8f11d7c00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000147069200e20 CR3: 00000001c7210002 CR4: 00000000001706f0 +Call Trace: + +? show_trace_log_lvl+0x1c4/0x2df +? show_trace_log_lvl+0x1c4/0x2df +? ib_uverbs_close+0x1f/0xb0 [ib_uverbs] +? uverbs_destroy_ufile_hw+0xcf/0xf0 [ib_uverbs] +? __warn+0x81/0x110 +? uverbs_destroy_ufile_hw+0xcf/0xf0 [ib_uverbs] +? report_bug+0x10a/0x140 +? handle_bug+0x3c/0x70 +? exc_invalid_op+0x14/0x70 +? asm_exc_invalid_op+0x16/0x20 +? uverbs_destroy_ufile_hw+0xcf/0xf0 [ib_uverbs] +ib_uverbs_close+0x1f/0xb0 [ib_uverbs] +__fput+0x94/0x250 +task_work_run+0x5c/0x90 +do_exit+0x270/0x4a0 +do_group_exit+0x2d/0x90 +get_signal+0x87c/0x8c0 +arch_do_signal_or_restart+0x25/0x100 +? ib_uverbs_ioctl+0xc2/0x110 [ib_uverbs] +exit_to_user_mode_loop+0x9c/0x130 +exit_to_user_mode_prepare+0xb6/0x100 +syscall_exit_to_user_mode+0x12/0x40 +do_syscall_64+0x69/0x90 +? syscall_exit_work+0x103/0x130 +? syscall_exit_to_user_mode+0x22/0x40 +? do_syscall_64+0x69/0x90 +? syscall_exit_work+0x103/0x130 +? syscall_exit_to_user_mode+0x22/0x40 +? do_syscall_64+0x69/0x90 +? do_syscall_64+0x69/0x90 +? common_interrupt+0x43/0xa0 +entry_SYSCALL_64_after_hwframe+0x72/0xdc +RIP: 0033:0x1470abe3ec6b +Code: Unable to access opcode bytes at RIP 0x1470abe3ec41. +RSP: 002b:00007fff13ce9108 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 +RAX: fffffffffffffffc RBX: 00007fff13ce9218 RCX: 00001470abe3ec6b +RDX: 00007fff13ce9200 RSI: 00000000c0181b01 RDI: 0000000000000004 +RBP: 00007fff13ce91e0 R08: 0000558d9655da10 R09: 0000558d9655dd00 +R10: 00007fff13ce95c0 R11: 0000000000000246 R12: 00007fff13ce9358 +R13: 0000000000000013 R14: 0000558d9655db50 R15: 00007fff13ce9470 + +--[ end trace 888a9b92e04c5c97 ]-- + +Fixes: df15856132bc ("RDMA/qedr: restructure functions that create/destroy QPs") +Signed-off-by: Kamal Heib +Link: https://lore.kernel.org/r/20240208223628.2040841-1-kheib@redhat.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/qedr/verbs.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c +index d745ce9dc88aa..61755b5f3e20d 100644 +--- a/drivers/infiniband/hw/qedr/verbs.c ++++ b/drivers/infiniband/hw/qedr/verbs.c +@@ -1879,8 +1879,17 @@ static int qedr_create_user_qp(struct qedr_dev *dev, + /* RQ - read access only (0) */ + rc = qedr_init_user_queue(udata, dev, &qp->urq, ureq.rq_addr, + ureq.rq_len, true, 0, alloc_and_init); +- if (rc) ++ if (rc) { ++ ib_umem_release(qp->usq.umem); ++ qp->usq.umem = NULL; ++ if (rdma_protocol_roce(&dev->ibdev, 1)) { ++ qedr_free_pbl(dev, &qp->usq.pbl_info, ++ qp->usq.pbl_tbl); ++ } else { ++ kfree(qp->usq.pbl_tbl); ++ } + return rc; ++ } + } + + memset(&in_params, 0, sizeof(in_params)); +-- +2.43.0 + diff --git a/queue-6.1/rdma-srpt-fix-function-pointer-cast-warnings.patch b/queue-6.1/rdma-srpt-fix-function-pointer-cast-warnings.patch new file mode 100644 index 00000000000..e54dd5d43a4 --- /dev/null +++ b/queue-6.1/rdma-srpt-fix-function-pointer-cast-warnings.patch @@ -0,0 +1,60 @@ +From debbee18717ce55815e8ec7468b35dd895670698 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 11:07:13 +0100 +Subject: RDMA/srpt: fix function pointer cast warnings + +From: Arnd Bergmann + +[ Upstream commit eb5c7465c3240151cd42a55c7ace9da0026308a1 ] + +clang-16 notices that srpt_qp_event() gets called through an incompatible +pointer here: + +drivers/infiniband/ulp/srpt/ib_srpt.c:1815:5: error: cast from 'void (*)(struct ib_event *, struct srpt_rdma_ch *)' to 'void (*)(struct ib_event *, void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict] + 1815 | = (void(*)(struct ib_event *, void*))srpt_qp_event; + +Change srpt_qp_event() to use the correct prototype and adjust the +argument inside of it. + +Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") +Signed-off-by: Arnd Bergmann +Link: https://lore.kernel.org/r/20240213100728.458348-1-arnd@kernel.org +Reviewed-by: Bart Van Assche +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/srpt/ib_srpt.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c +index 4607d37b9224a..cffa93f114a73 100644 +--- a/drivers/infiniband/ulp/srpt/ib_srpt.c ++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c +@@ -214,10 +214,12 @@ static const char *get_ch_state_name(enum rdma_ch_state s) + /** + * srpt_qp_event - QP event callback function + * @event: Description of the event that occurred. +- * @ch: SRPT RDMA channel. ++ * @ptr: SRPT RDMA channel. + */ +-static void srpt_qp_event(struct ib_event *event, struct srpt_rdma_ch *ch) ++static void srpt_qp_event(struct ib_event *event, void *ptr) + { ++ struct srpt_rdma_ch *ch = ptr; ++ + pr_debug("QP event %d on ch=%p sess_name=%s-%d state=%s\n", + event->event, ch, ch->sess_name, ch->qp->qp_num, + get_ch_state_name(ch->state)); +@@ -1811,8 +1813,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) + ch->cq_size = ch->rq_size + sq_size; + + qp_init->qp_context = (void *)ch; +- qp_init->event_handler +- = (void(*)(struct ib_event *, void*))srpt_qp_event; ++ qp_init->event_handler = srpt_qp_event; + qp_init->send_cq = ch->cq; + qp_init->recv_cq = ch->cq; + qp_init->sq_sig_type = IB_SIGNAL_REQ_WR; +-- +2.43.0 + diff --git a/queue-6.1/rdma-srpt-support-specifying-the-srpt_service_guid-p.patch b/queue-6.1/rdma-srpt-support-specifying-the-srpt_service_guid-p.patch new file mode 100644 index 00000000000..3e52c1277bd --- /dev/null +++ b/queue-6.1/rdma-srpt-support-specifying-the-srpt_service_guid-p.patch @@ -0,0 +1,62 @@ +From c44742b7bfb555d7c7e8cb7a2bd3ed4e0c727d21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 4 Feb 2024 16:42:07 -0800 +Subject: RDMA/srpt: Support specifying the srpt_service_guid parameter + +From: Bart Van Assche + +[ Upstream commit fdfa083549de5d50ebf7f6811f33757781e838c0 ] + +Make loading ib_srpt with this parameter set work. The current behavior is +that setting that parameter while loading the ib_srpt kernel module +triggers the following kernel crash: + +BUG: kernel NULL pointer dereference, address: 0000000000000000 +Call Trace: + + parse_one+0x18c/0x1d0 + parse_args+0xe1/0x230 + load_module+0x8de/0xa60 + init_module_from_file+0x8b/0xd0 + idempotent_init_module+0x181/0x240 + __x64_sys_finit_module+0x5a/0xb0 + do_syscall_64+0x5f/0xe0 + entry_SYSCALL_64_after_hwframe+0x6e/0x76 + +Cc: LiHonggang +Reported-by: LiHonggang +Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") +Signed-off-by: Bart Van Assche +Link: https://lore.kernel.org/r/20240205004207.17031-1-bvanassche@acm.org +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/srpt/ib_srpt.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c +index 25e799dba999e..4607d37b9224a 100644 +--- a/drivers/infiniband/ulp/srpt/ib_srpt.c ++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c +@@ -79,12 +79,16 @@ module_param(srpt_srq_size, int, 0444); + MODULE_PARM_DESC(srpt_srq_size, + "Shared receive queue (SRQ) size."); + ++static int srpt_set_u64_x(const char *buffer, const struct kernel_param *kp) ++{ ++ return kstrtou64(buffer, 16, (u64 *)kp->arg); ++} + static int srpt_get_u64_x(char *buffer, const struct kernel_param *kp) + { + return sprintf(buffer, "0x%016llx\n", *(u64 *)kp->arg); + } +-module_param_call(srpt_service_guid, NULL, srpt_get_u64_x, &srpt_service_guid, +- 0444); ++module_param_call(srpt_service_guid, srpt_set_u64_x, srpt_get_u64_x, ++ &srpt_service_guid, 0444); + MODULE_PARM_DESC(srpt_service_guid, + "Using this value for ioc_guid, id_ext, and cm_listen_id instead of using the node_guid of the first HCA."); + +-- +2.43.0 + diff --git a/queue-6.1/s390-use-the-correct-count-for-__iowrite64_copy.patch b/queue-6.1/s390-use-the-correct-count-for-__iowrite64_copy.patch new file mode 100644 index 00000000000..3ec4488b2b1 --- /dev/null +++ b/queue-6.1/s390-use-the-correct-count-for-__iowrite64_copy.patch @@ -0,0 +1,39 @@ +From 6b7cbe507c83dd22f5b5d6b314b67b796371115b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Feb 2024 20:48:14 -0400 +Subject: s390: use the correct count for __iowrite64_copy() + +From: Jason Gunthorpe + +[ Upstream commit 723a2cc8d69d4342b47dfddbfe6c19f1b135f09b ] + +The signature for __iowrite64_copy() requires the number of 64 bit +quantities, not bytes. Multiple by 8 to get to a byte length before +invoking zpci_memcpy_toio() + +Fixes: 87bc359b9822 ("s390/pci: speed up __iowrite64_copy by using pci store block insn") +Acked-by: Niklas Schnelle +Signed-off-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/0-v1-9223d11a7662+1d7785-s390_iowrite64_jgg@nvidia.com +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/pci/pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c +index 2c99f9552b2f5..394c69fda399e 100644 +--- a/arch/s390/pci/pci.c ++++ b/arch/s390/pci/pci.c +@@ -241,7 +241,7 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, + /* combine single writes by using store-block insn */ + void __iowrite64_copy(void __iomem *to, const void *from, size_t count) + { +- zpci_memcpy_toio(to, from, count); ++ zpci_memcpy_toio(to, from, count * 8); + } + + static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot) +-- +2.43.0 + diff --git a/queue-6.1/scsi-jazz_esp-only-build-if-scsi-core-is-builtin.patch b/queue-6.1/scsi-jazz_esp-only-build-if-scsi-core-is-builtin.patch new file mode 100644 index 00000000000..e8a8d5a1747 --- /dev/null +++ b/queue-6.1/scsi-jazz_esp-only-build-if-scsi-core-is-builtin.patch @@ -0,0 +1,54 @@ +From 9c870ca9d068c8a3fc17a1b7481646c2247abdb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 21:59:53 -0800 +Subject: scsi: jazz_esp: Only build if SCSI core is builtin + +From: Randy Dunlap + +[ Upstream commit 9ddf190a7df77b77817f955fdb9c2ae9d1c9c9a3 ] + +JAZZ_ESP is a bool kconfig symbol that selects SCSI_SPI_ATTRS. When +CONFIG_SCSI=m, this results in SCSI_SPI_ATTRS=m while JAZZ_ESP=y, which +causes many undefined symbol linker errors. + +Fix this by only offering to build this driver when CONFIG_SCSI=y. + +[mkp: JAZZ_ESP is unique in that it does not support being compiled as a +module unlike the remaining SPI SCSI HBA drivers] + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Randy Dunlap +Link: https://lore.kernel.org/r/20240214055953.9612-1-rdunlap@infradead.org +Cc: Thomas Bogendoerfer +Cc: linux-mips@vger.kernel.org +Cc: Arnd Bergmann +Cc: Masahiro Yamada +Cc: Nicolas Schier +Cc: James E.J. Bottomley +Cc: Martin K. Petersen +Cc: linux-scsi@vger.kernel.org +Cc: Geert Uytterhoeven +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202402112222.Gl0udKyU-lkp@intel.com/ +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig +index 03e71e3d5e5b3..3b990cf2c1954 100644 +--- a/drivers/scsi/Kconfig ++++ b/drivers/scsi/Kconfig +@@ -1285,7 +1285,7 @@ source "drivers/scsi/arm/Kconfig" + + config JAZZ_ESP + bool "MIPS JAZZ FAS216 SCSI support" +- depends on MACH_JAZZ && SCSI ++ depends on MACH_JAZZ && SCSI=y + select SCSI_SPI_ATTRS + help + This is the driver for the onboard SCSI host adapter of MIPS Magnum +-- +2.43.0 + diff --git a/queue-6.1/scsi-smartpqi-fix-disable_managed_interrupts.patch b/queue-6.1/scsi-smartpqi-fix-disable_managed_interrupts.patch new file mode 100644 index 00000000000..b0324f64c4a --- /dev/null +++ b/queue-6.1/scsi-smartpqi-fix-disable_managed_interrupts.patch @@ -0,0 +1,92 @@ +From 15c5fdea1f3548ffc1c5af0015f4dc8fb9be3cf0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 10:22:00 -0600 +Subject: scsi: smartpqi: Fix disable_managed_interrupts + +From: Don Brace + +[ Upstream commit 5761eb9761d2d5fe8248a9b719efc4d8baf1f24a ] + +Correct blk-mq registration issue with module parameter +disable_managed_interrupts enabled. + +When we turn off the default PCI_IRQ_AFFINITY flag, the driver needs to +register with blk-mq using blk_mq_map_queues(). The driver is currently +calling blk_mq_pci_map_queues() which results in a stack trace and possibly +undefined behavior. + +Stack Trace: +[ 7.860089] scsi host2: smartpqi +[ 7.871934] WARNING: CPU: 0 PID: 238 at block/blk-mq-pci.c:52 blk_mq_pci_map_queues+0xca/0xd0 +[ 7.889231] Modules linked in: sd_mod t10_pi sg uas smartpqi(+) crc32c_intel scsi_transport_sas usb_storage dm_mirror dm_region_hash dm_log dm_mod ipmi_devintf ipmi_msghandler fuse +[ 7.924755] CPU: 0 PID: 238 Comm: kworker/0:3 Not tainted 4.18.0-372.88.1.el8_6_smartpqi_test.x86_64 #1 +[ 7.944336] Hardware name: HPE ProLiant DL380 Gen10/ProLiant DL380 Gen10, BIOS U30 03/08/2022 +[ 7.963026] Workqueue: events work_for_cpu_fn +[ 7.978275] RIP: 0010:blk_mq_pci_map_queues+0xca/0xd0 +[ 7.978278] Code: 48 89 de 89 c7 e8 f6 0f 4f 00 3b 05 c4 b7 8e 01 72 e1 5b 31 c0 5d 41 5c 41 5d 41 5e 41 5f e9 7d df 73 00 31 c0 e9 76 df 73 00 <0f> 0b eb bc 90 90 0f 1f 44 00 00 41 57 49 89 ff 41 56 41 55 41 54 +[ 7.978280] RSP: 0018:ffffa95fc3707d50 EFLAGS: 00010216 +[ 7.978283] RAX: 00000000ffffffff RBX: 0000000000000000 RCX: 0000000000000010 +[ 7.978284] RDX: 0000000000000004 RSI: 0000000000000000 RDI: ffff9190c32d4310 +[ 7.978286] RBP: 0000000000000000 R08: ffffa95fc3707d38 R09: ffff91929b81ac00 +[ 7.978287] R10: 0000000000000001 R11: ffffa95fc3707ac0 R12: 0000000000000000 +[ 7.978288] R13: ffff9190c32d4000 R14: 00000000ffffffff R15: ffff9190c4c950a8 +[ 7.978290] FS: 0000000000000000(0000) GS:ffff9193efc00000(0000) knlGS:0000000000000000 +[ 7.978292] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 8.172814] CR2: 000055d11166c000 CR3: 00000002dae10002 CR4: 00000000007706f0 +[ 8.172816] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 8.172817] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[ 8.172818] PKRU: 55555554 +[ 8.172819] Call Trace: +[ 8.172823] blk_mq_alloc_tag_set+0x12e/0x310 +[ 8.264339] scsi_add_host_with_dma.cold.9+0x30/0x245 +[ 8.279302] pqi_ctrl_init+0xacf/0xc8e [smartpqi] +[ 8.294085] ? pqi_pci_probe+0x480/0x4c8 [smartpqi] +[ 8.309015] pqi_pci_probe+0x480/0x4c8 [smartpqi] +[ 8.323286] local_pci_probe+0x42/0x80 +[ 8.337855] work_for_cpu_fn+0x16/0x20 +[ 8.351193] process_one_work+0x1a7/0x360 +[ 8.364462] ? create_worker+0x1a0/0x1a0 +[ 8.379252] worker_thread+0x1ce/0x390 +[ 8.392623] ? create_worker+0x1a0/0x1a0 +[ 8.406295] kthread+0x10a/0x120 +[ 8.418428] ? set_kthread_struct+0x50/0x50 +[ 8.431532] ret_from_fork+0x1f/0x40 +[ 8.444137] ---[ end trace 1bf0173d39354506 ]--- + +Fixes: cf15c3e734e8 ("scsi: smartpqi: Add module param to disable managed ints") +Tested-by: Yogesh Chandra Pandey +Reviewed-by: Scott Benesh +Reviewed-by: Scott Teel +Reviewed-by: Mahesh Rajashekhara +Reviewed-by: Mike McGowen +Reviewed-by: Kevin Barnett +Signed-off-by: Don Brace +Link: https://lore.kernel.org/r/20240213162200.1875970-2-don.brace@microchip.com +Reviewed-by: Tomas Henzl +Reviewed-by: Ewan D. Milne +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi_init.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 47d487729635c..e44f6bb25a8ea 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -6449,8 +6449,11 @@ static void pqi_map_queues(struct Scsi_Host *shost) + { + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + +- blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], ++ if (!ctrl_info->disable_managed_interrupts) ++ return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], + ctrl_info->pci_dev, 0); ++ else ++ return blk_mq_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT]); + } + + static inline bool pqi_is_tape_changer_device(struct pqi_scsi_dev *device) +-- +2.43.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 423867762ab..aca620dbf6b 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -127,3 +127,59 @@ mptcp-make-userspace_pm_append_new_local_addr-static.patch mptcp-add-needs_id-for-userspace-appending-addr.patch mptcp-fix-lockless-access-in-subflow-ulp-diag.patch revert-drm-amd-display-increased-min_dcfclk_mhz-and-min_fclk_mhz.patch +ib-hfi1-fix-a-memleak-in-init_credit_return.patch +rdma-bnxt_re-return-error-for-srq-resize.patch +rdma-irdma-fix-kasan-issue-with-tasklet.patch +rdma-irdma-validate-max_send_wr-and-max_recv_wr.patch +rdma-irdma-set-the-cq-read-threshold-for-gen-1.patch +rdma-irdma-add-ae-for-too-many-rnrs.patch +rdma-srpt-support-specifying-the-srpt_service_guid-p.patch +iommufd-iova_bitmap-bounds-check-mapped-pages-access.patch +iommufd-iova_bitmap-switch-iova_bitmap-bitmap-to-an-.patch +iommufd-iova_bitmap-consider-page-offset-for-the-pag.patch +rdma-qedr-fix-qedr_create_user_qp-error-flow.patch +arm64-dts-rockchip-set-num-cs-property-for-spi-on-px.patch +rdma-srpt-fix-function-pointer-cast-warnings.patch +bpf-scripts-correct-gpl-license-name.patch +scsi-smartpqi-fix-disable_managed_interrupts.patch +scsi-jazz_esp-only-build-if-scsi-core-is-builtin.patch +net-bridge-switchdev-skip-mdb-replays-of-deferred-ev.patch +net-bridge-switchdev-ensure-deferred-event-delivery-.patch +dccp-tcp-unhash-sk-from-ehash-for-tb2-alloc-failure-.patch +net-ethernet-adi-requires-phylib-support.patch +nouveau-fix-function-cast-warnings.patch +x86-numa-fix-the-address-overlap-check-in-numa_fill_.patch +x86-numa-fix-the-sort-compare-func-used-in-numa_fill.patch +net-stmmac-fix-incorrect-dereference-in-interrupt-ha.patch +ipv4-properly-combine-dev_base_seq-and-ipv4.dev_addr.patch +ipv6-properly-combine-dev_base_seq-and-ipv6.dev_addr.patch +ata-ahci_ceva-fix-error-handling-for-xilinx-gt-phy-s.patch +bpf-fix-racing-between-bpf_timer_cancel_and_free-and.patch +afs-increase-buffer-size-in-afs_update_volume_status.patch +ipv6-sr-fix-possible-use-after-free-and-null-ptr-der.patch +net-dev-convert-sa_data-to-flexible-array-in-struct-.patch +arm64-sme-restore-sme-registers-on-exit-from-suspend.patch +platform-x86-thinkpad_acpi-only-update-profile-if-su.patch +octeontx2-af-consider-the-action-set-by-pf.patch +s390-use-the-correct-count-for-__iowrite64_copy.patch +bpf-sockmap-fix-null-pointer-dereference-in-sk_psock.patch +tls-break-out-of-main-loop-when-peek-gets-a-non-data.patch +tls-stop-recv-if-initial-process_rx_list-gave-us-non.patch +tls-don-t-skip-over-different-type-records-from-the-.patch +netfilter-nf_tables-set-dormant-flag-on-hook-registe.patch +netfilter-flowtable-simplify-route-logic.patch +netfilter-nft_flow_offload-reset-dst-in-route-object.patch +netfilter-nft_flow_offload-release-dst-in-case-direc.patch +netfilter-nf_tables-rename-function-to-destroy-hook-.patch +netfilter-nf_tables-register-hooks-last-when-adding-.patch +netfilter-nf_tables-use-kzalloc-for-hook-allocation.patch +net-mctp-put-sock-on-tag-allocation-failure.patch +net-sparx5-add-spinlock-for-frame-transmission-from-.patch +net-ioctl-use-kernel-memory-on-protocol-ioctl-callba.patch +phonet-take-correct-lock-to-peek-at-the-rx-queue.patch +phonet-pep-fix-racy-skb_queue_empty-use.patch +fix-write-to-cloned-skb-in-ipv6_hop_ioam.patch +net-phy-realtek-fix-rtl8211f_config_init-for-rtl8211.patch +drm-syncobj-call-drm_syncobj_fence_add_wait-when-wai.patch +drm-amd-display-fix-memory-leak-in-dm_sw_fini.patch +i2c-imx-when-being-a-target-mark-the-last-read-as-pr.patch diff --git a/queue-6.1/tls-break-out-of-main-loop-when-peek-gets-a-non-data.patch b/queue-6.1/tls-break-out-of-main-loop-when-peek-gets-a-non-data.patch new file mode 100644 index 00000000000..8878e858c29 --- /dev/null +++ b/queue-6.1/tls-break-out-of-main-loop-when-peek-gets-a-non-data.patch @@ -0,0 +1,47 @@ +From 1aebbfe29d93e34d6de2bb7837a6e4566515a3b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 17:17:29 +0100 +Subject: tls: break out of main loop when PEEK gets a non-data record + +From: Sabrina Dubroca + +[ Upstream commit 10f41d0710fc81b7af93fa6106678d57b1ff24a7 ] + +PEEK needs to leave decrypted records on the rx_list so that we can +receive them later on, so it jumps back into the async code that +queues the skb. Unfortunately that makes us skip the +TLS_RECORD_TYPE_DATA check at the bottom of the main loop, so if two +records of the same (non-DATA) type are queued, we end up merging +them. + +Add the same record type check, and make it unlikely to not penalize +the async fastpath. Async decrypt only applies to data record, so this +check is only needed for PEEK. + +process_rx_list also has similar issues. + +Fixes: 692d7b5d1f91 ("tls: Fix recvmsg() to be able to peek across multiple records") +Signed-off-by: Sabrina Dubroca +Link: https://lore.kernel.org/r/3df2eef4fdae720c55e69472b5bea668772b45a2.1708007371.git.sd@queasysnail.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/tls/tls_sw.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index c8cbdd02a784e..cd86c271c1348 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -2137,6 +2137,8 @@ int tls_sw_recvmsg(struct sock *sk, + decrypted += chunk; + len -= chunk; + __skb_queue_tail(&ctx->rx_list, skb); ++ if (unlikely(control != TLS_RECORD_TYPE_DATA)) ++ break; + continue; + } + +-- +2.43.0 + diff --git a/queue-6.1/tls-don-t-skip-over-different-type-records-from-the-.patch b/queue-6.1/tls-don-t-skip-over-different-type-records-from-the-.patch new file mode 100644 index 00000000000..76410bf9479 --- /dev/null +++ b/queue-6.1/tls-don-t-skip-over-different-type-records-from-the-.patch @@ -0,0 +1,123 @@ +From 521606a692335737ba2c321996295b106e2c16b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 17:17:31 +0100 +Subject: tls: don't skip over different type records from the rx_list + +From: Sabrina Dubroca + +[ Upstream commit ec823bf3a479d42c589dc0f28ef4951c49cd2d2a ] + +If we queue 3 records: + - record 1, type DATA + - record 2, some other type + - record 3, type DATA +and do a recv(PEEK), the rx_list will contain the first two records. + +The next large recv will walk through the rx_list and copy data from +record 1, then stop because record 2 is a different type. Since we +haven't filled up our buffer, we will process the next available +record. It's also DATA, so we can merge it with the current read. + +We shouldn't do that, since there was a record in between that we +ignored. + +Add a flag to let process_rx_list inform tls_sw_recvmsg that it had +more data available. + +Fixes: 692d7b5d1f91 ("tls: Fix recvmsg() to be able to peek across multiple records") +Signed-off-by: Sabrina Dubroca +Link: https://lore.kernel.org/r/f00c0c0afa080c60f016df1471158c1caf983c34.1708007371.git.sd@queasysnail.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/tls/tls_sw.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index 20d2877bf22ad..93e1bfa72d791 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -1845,7 +1845,8 @@ static int process_rx_list(struct tls_sw_context_rx *ctx, + u8 *control, + size_t skip, + size_t len, +- bool is_peek) ++ bool is_peek, ++ bool *more) + { + struct sk_buff *skb = skb_peek(&ctx->rx_list); + struct tls_msg *tlm; +@@ -1858,7 +1859,7 @@ static int process_rx_list(struct tls_sw_context_rx *ctx, + + err = tls_record_content_type(msg, tlm, control); + if (err <= 0) +- goto out; ++ goto more; + + if (skip < rxm->full_len) + break; +@@ -1876,12 +1877,12 @@ static int process_rx_list(struct tls_sw_context_rx *ctx, + + err = tls_record_content_type(msg, tlm, control); + if (err <= 0) +- goto out; ++ goto more; + + err = skb_copy_datagram_msg(skb, rxm->offset + skip, + msg, chunk); + if (err < 0) +- goto out; ++ goto more; + + len = len - chunk; + copied = copied + chunk; +@@ -1917,6 +1918,10 @@ static int process_rx_list(struct tls_sw_context_rx *ctx, + + out: + return copied ? : err; ++more: ++ if (more) ++ *more = true; ++ goto out; + } + + static bool +@@ -2020,6 +2025,7 @@ int tls_sw_recvmsg(struct sock *sk, + int target, err; + bool is_kvec = iov_iter_is_kvec(&msg->msg_iter); + bool is_peek = flags & MSG_PEEK; ++ bool rx_more = false; + bool released = true; + bool bpf_strp_enabled; + bool zc_capable; +@@ -2039,12 +2045,12 @@ int tls_sw_recvmsg(struct sock *sk, + goto end; + + /* Process pending decrypted records. It must be non-zero-copy */ +- err = process_rx_list(ctx, msg, &control, 0, len, is_peek); ++ err = process_rx_list(ctx, msg, &control, 0, len, is_peek, &rx_more); + if (err < 0) + goto end; + + copied = err; +- if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA)) ++ if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA) || rx_more) + goto end; + + target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); +@@ -2203,10 +2209,10 @@ int tls_sw_recvmsg(struct sock *sk, + /* Drain records from the rx_list & copy if required */ + if (is_peek || is_kvec) + err = process_rx_list(ctx, msg, &control, copied, +- decrypted, is_peek); ++ decrypted, is_peek, NULL); + else + err = process_rx_list(ctx, msg, &control, 0, +- async_copy_bytes, is_peek); ++ async_copy_bytes, is_peek, NULL); + } + + copied += decrypted; +-- +2.43.0 + diff --git a/queue-6.1/tls-stop-recv-if-initial-process_rx_list-gave-us-non.patch b/queue-6.1/tls-stop-recv-if-initial-process_rx_list-gave-us-non.patch new file mode 100644 index 00000000000..110c35d3b28 --- /dev/null +++ b/queue-6.1/tls-stop-recv-if-initial-process_rx_list-gave-us-non.patch @@ -0,0 +1,44 @@ +From ff5e02b70841c13a45978f83d5a44bcb69690ef1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 17:17:30 +0100 +Subject: tls: stop recv() if initial process_rx_list gave us non-DATA + +From: Sabrina Dubroca + +[ Upstream commit fdfbaec5923d9359698cbb286bc0deadbb717504 ] + +If we have a non-DATA record on the rx_list and another record of the +same type still on the queue, we will end up merging them: + - process_rx_list copies the non-DATA record + - we start the loop and process the first available record since it's + of the same type + - we break out of the loop since the record was not DATA + +Just check the record type and jump to the end in case process_rx_list +did some work. + +Fixes: 692d7b5d1f91 ("tls: Fix recvmsg() to be able to peek across multiple records") +Signed-off-by: Sabrina Dubroca +Link: https://lore.kernel.org/r/bd31449e43bd4b6ff546f5c51cf958c31c511deb.1708007371.git.sd@queasysnail.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/tls/tls_sw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index cd86c271c1348..20d2877bf22ad 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -2044,7 +2044,7 @@ int tls_sw_recvmsg(struct sock *sk, + goto end; + + copied = err; +- if (len <= copied) ++ if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA)) + goto end; + + target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); +-- +2.43.0 + diff --git a/queue-6.1/x86-numa-fix-the-address-overlap-check-in-numa_fill_.patch b/queue-6.1/x86-numa-fix-the-address-overlap-check-in-numa_fill_.patch new file mode 100644 index 00000000000..7e7897304f2 --- /dev/null +++ b/queue-6.1/x86-numa-fix-the-address-overlap-check-in-numa_fill_.patch @@ -0,0 +1,116 @@ +From b0fe0fe31344c6a50e9d142051516d268a6e6501 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Jan 2024 12:09:50 -0800 +Subject: x86/numa: Fix the address overlap check in numa_fill_memblks() + +From: Alison Schofield + +[ Upstream commit 9b99c17f7510bed2adbe17751fb8abddba5620bc ] + +numa_fill_memblks() fills in the gaps in numa_meminfo memblks over a +physical address range. To do so, it first creates a list of existing +memblks that overlap that address range. The issue is that it is off +by one when comparing to the end of the address range, so memblks +that do not overlap are selected. + +The impact of selecting a memblk that does not actually overlap is +that an existing memblk may be filled when the expected action is to +do nothing and return NUMA_NO_MEMBLK to the caller. The caller can +then add a new NUMA node and memblk. + +Replace the broken open-coded search for address overlap with the +memblock helper memblock_addrs_overlap(). Update the kernel doc +and in code comments. + +Suggested by: "Huang, Ying" + +Fixes: 8f012db27c95 ("x86/numa: Introduce numa_fill_memblks()") +Signed-off-by: Alison Schofield +Acked-by: Mike Rapoport (IBM) +Acked-by: Dave Hansen +Reviewed-by: Dan Williams +Link: https://lore.kernel.org/r/10a3e6109c34c21a8dd4c513cf63df63481a2b07.1705085543.git.alison.schofield@intel.com +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + arch/x86/mm/numa.c | 19 +++++++------------ + include/linux/memblock.h | 2 ++ + mm/memblock.c | 5 +++-- + 3 files changed, 12 insertions(+), 14 deletions(-) + +diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c +index aa39d678fe81d..e60c61b8bbc61 100644 +--- a/arch/x86/mm/numa.c ++++ b/arch/x86/mm/numa.c +@@ -971,14 +971,12 @@ static struct numa_memblk *numa_memblk_list[NR_NODE_MEMBLKS] __initdata; + * @start: address to begin fill + * @end: address to end fill + * +- * Find and extend numa_meminfo memblks to cover the @start-@end +- * physical address range, such that the first memblk includes +- * @start, the last memblk includes @end, and any gaps in between +- * are filled. ++ * Find and extend numa_meminfo memblks to cover the physical ++ * address range @start-@end + * + * RETURNS: + * 0 : Success +- * NUMA_NO_MEMBLK : No memblk exists in @start-@end range ++ * NUMA_NO_MEMBLK : No memblks exist in address range @start-@end + */ + + int __init numa_fill_memblks(u64 start, u64 end) +@@ -990,17 +988,14 @@ int __init numa_fill_memblks(u64 start, u64 end) + + /* + * Create a list of pointers to numa_meminfo memblks that +- * overlap start, end. Exclude (start == bi->end) since +- * end addresses in both a CFMWS range and a memblk range +- * are exclusive. +- * +- * This list of pointers is used to make in-place changes +- * that fill out the numa_meminfo memblks. ++ * overlap start, end. The list is used to make in-place ++ * changes that fill out the numa_meminfo memblks. + */ + for (int i = 0; i < mi->nr_blks; i++) { + struct numa_memblk *bi = &mi->blk[i]; + +- if (start < bi->end && end >= bi->start) { ++ if (memblock_addrs_overlap(start, end - start, bi->start, ++ bi->end - bi->start)) { + blk[count] = &mi->blk[i]; + count++; + } +diff --git a/include/linux/memblock.h b/include/linux/memblock.h +index 50ad19662a322..6790f08066b72 100644 +--- a/include/linux/memblock.h ++++ b/include/linux/memblock.h +@@ -118,6 +118,8 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size); + int memblock_physmem_add(phys_addr_t base, phys_addr_t size); + #endif + void memblock_trim_memory(phys_addr_t align); ++unsigned long memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, ++ phys_addr_t base2, phys_addr_t size2); + bool memblock_overlaps_region(struct memblock_type *type, + phys_addr_t base, phys_addr_t size); + int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); +diff --git a/mm/memblock.c b/mm/memblock.c +index 511d4783dcf1d..516efec80851a 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -175,8 +175,9 @@ static inline phys_addr_t memblock_cap_size(phys_addr_t base, phys_addr_t *size) + /* + * Address comparison utilities + */ +-static unsigned long __init_memblock memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, +- phys_addr_t base2, phys_addr_t size2) ++unsigned long __init_memblock ++memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, phys_addr_t base2, ++ phys_addr_t size2) + { + return ((base1 < (base2 + size2)) && (base2 < (base1 + size1))); + } +-- +2.43.0 + diff --git a/queue-6.1/x86-numa-fix-the-sort-compare-func-used-in-numa_fill.patch b/queue-6.1/x86-numa-fix-the-sort-compare-func-used-in-numa_fill.patch new file mode 100644 index 00000000000..fa481802001 --- /dev/null +++ b/queue-6.1/x86-numa-fix-the-sort-compare-func-used-in-numa_fill.patch @@ -0,0 +1,50 @@ +From 84fc11188dd8675294a8592af9bd4a4d45642ff8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Jan 2024 12:09:51 -0800 +Subject: x86/numa: Fix the sort compare func used in numa_fill_memblks() + +From: Alison Schofield + +[ Upstream commit b626070ffc14acca5b87a2aa5f581db98617584c ] + +The compare function used to sort memblks into starting address +order fails when the result of its u64 address subtraction gets +truncated to an int upon return. + +The impact of the bad sort is that memblks will be filled out +incorrectly. Depending on the set of memblks, a user may see no +errors at all but still have a bad fill, or see messages reporting +a node overlap that leads to numa init failure: + +[] node 0 [mem: ] overlaps with node 1 [mem: ] +[] No NUMA configuration found + +Replace with a comparison that can only result in: 1, 0, -1. + +Fixes: 8f012db27c95 ("x86/numa: Introduce numa_fill_memblks()") +Signed-off-by: Alison Schofield +Acked-by: Dave Hansen +Reviewed-by: Dan Williams +Link: https://lore.kernel.org/r/99dcb3ae87e04995e9f293f6158dc8fa0749a487.1705085543.git.alison.schofield@intel.com +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + arch/x86/mm/numa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c +index e60c61b8bbc61..dae5c952735c7 100644 +--- a/arch/x86/mm/numa.c ++++ b/arch/x86/mm/numa.c +@@ -961,7 +961,7 @@ static int __init cmp_memblk(const void *a, const void *b) + const struct numa_memblk *ma = *(const struct numa_memblk **)a; + const struct numa_memblk *mb = *(const struct numa_memblk **)b; + +- return ma->start - mb->start; ++ return (ma->start > mb->start) - (ma->start < mb->start); + } + + static struct numa_memblk *numa_memblk_list[NR_NODE_MEMBLKS] __initdata; +-- +2.43.0 +