From: Sasha Levin Date: Tue, 6 May 2025 11:50:06 +0000 (-0400) Subject: Fixes for 6.12 X-Git-Tag: v5.15.182~56 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c352464fd9bc1bc0f39c795ea66985d50e3202d7;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.12 Signed-off-by: Sasha Levin --- diff --git a/queue-6.12/accel-ivpu-correct-dct-interrupt-handling.patch b/queue-6.12/accel-ivpu-correct-dct-interrupt-handling.patch new file mode 100644 index 0000000000..4770eb809f --- /dev/null +++ b/queue-6.12/accel-ivpu-correct-dct-interrupt-handling.patch @@ -0,0 +1,97 @@ +From aa879c0688f4d5fe9eac1ee1fc00dc500fbccfce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 12:26:16 +0200 +Subject: accel/ivpu: Correct DCT interrupt handling + +From: Karol Wachowski + +[ Upstream commit e53e004e346062e15df9511bd4b5a19e34701384 ] + +Fix improper use of dct_active_percent field in DCT interrupt handler +causing DCT to never get enabled. Set dct_active_percent internally before +IPC to ensure correct driver value even if IPC fails. +Set default DCT value to 30 accordingly to HW architecture specification. + +Fixes: a19bffb10c46 ("accel/ivpu: Implement DCT handling") +Signed-off-by: Karol Wachowski +Signed-off-by: Maciej Falkowski +Reviewed-by: Jeff Hugo +Signed-off-by: Jacek Lawrynowicz +Link: https://lore.kernel.org/r/20250416102616.384577-1-maciej.falkowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_hw_btrs.h | 2 +- + drivers/accel/ivpu/ivpu_pm.c | 18 ++++++++++-------- + 2 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h +index 71792dab3c210..3855e2df1e0c8 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.h ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.h +@@ -14,7 +14,7 @@ + #define PLL_PROFILING_FREQ_DEFAULT 38400000 + #define PLL_PROFILING_FREQ_HIGH 400000000 + +-#define DCT_DEFAULT_ACTIVE_PERCENT 15u ++#define DCT_DEFAULT_ACTIVE_PERCENT 30u + #define DCT_PERIOD_US 35300u + + int ivpu_hw_btrs_info_init(struct ivpu_device *vdev); +diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c +index fbb61a2c3b19c..d1fbad78f61ba 100644 +--- a/drivers/accel/ivpu/ivpu_pm.c ++++ b/drivers/accel/ivpu/ivpu_pm.c +@@ -421,16 +421,17 @@ int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent) + active_us = (DCT_PERIOD_US * active_percent) / 100; + inactive_us = DCT_PERIOD_US - active_us; + ++ vdev->pm->dct_active_percent = active_percent; ++ ++ ivpu_dbg(vdev, PM, "DCT requested %u%% (D0: %uus, D0i2: %uus)\n", ++ active_percent, active_us, inactive_us); ++ + ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us); + if (ret) { + ivpu_err_ratelimited(vdev, "Filed to enable DCT: %d\n", ret); + return ret; + } + +- vdev->pm->dct_active_percent = active_percent; +- +- ivpu_dbg(vdev, PM, "DCT set to %u%% (D0: %uus, D0i2: %uus)\n", +- active_percent, active_us, inactive_us); + return 0; + } + +@@ -438,15 +439,16 @@ int ivpu_pm_dct_disable(struct ivpu_device *vdev) + { + int ret; + ++ vdev->pm->dct_active_percent = 0; ++ ++ ivpu_dbg(vdev, PM, "DCT requested to be disabled\n"); ++ + ret = ivpu_jsm_dct_disable(vdev); + if (ret) { + ivpu_err_ratelimited(vdev, "Filed to disable DCT: %d\n", ret); + return ret; + } + +- vdev->pm->dct_active_percent = 0; +- +- ivpu_dbg(vdev, PM, "DCT disabled\n"); + return 0; + } + +@@ -458,7 +460,7 @@ void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev) + if (ivpu_hw_btrs_dct_get_request(vdev, &enable)) + return; + +- if (vdev->pm->dct_active_percent) ++ if (enable) + ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT); + else + ret = ivpu_pm_dct_disable(vdev); +-- +2.39.5 + diff --git a/queue-6.12/alsa-hda-realtek-enable-speaker-for-hp-platform.patch b/queue-6.12/alsa-hda-realtek-enable-speaker-for-hp-platform.patch new file mode 100644 index 0000000000..5ee91a291c --- /dev/null +++ b/queue-6.12/alsa-hda-realtek-enable-speaker-for-hp-platform.patch @@ -0,0 +1,66 @@ +From 20187b5c6bf29cc75261fe4387d89b10f1b86fe8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 15:04:02 +0800 +Subject: ALSA: hda/realtek - Enable speaker for HP platform + +From: Kailang Yang + +[ Upstream commit 494d0939b1bda4d4ddca7d52a6ce6f808ff2c9a5 ] + +The speaker doesn't mute when plugged headphone. +This platform support 4ch speakers. +The speaker pin 0x14 wasn't fill verb table. +After assigned model ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX. +The speaker can mute when headphone was plugged. + +Fixes: aa8e3ef4fe53 ("ALSA: hda/realtek: Add quirks for various HP ENVY models") +Signed-off-by: Kailang Yang +Link: https://lore.kernel.org/eb4c14a4d85740069c909e756bbacb0e@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 4171aa22747c3..5a36cb2969b08 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -440,6 +440,10 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) + alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); + fallthrough; + case 0x10ec0215: ++ case 0x10ec0236: ++ case 0x10ec0245: ++ case 0x10ec0256: ++ case 0x10ec0257: + case 0x10ec0285: + case 0x10ec0289: + alc_update_coef_idx(codec, 0x36, 1<<13, 0); +@@ -447,12 +451,8 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) + case 0x10ec0230: + case 0x10ec0233: + case 0x10ec0235: +- case 0x10ec0236: +- case 0x10ec0245: + case 0x10ec0255: +- case 0x10ec0256: + case 0x19e58326: +- case 0x10ec0257: + case 0x10ec0282: + case 0x10ec0283: + case 0x10ec0286: +@@ -10687,8 +10687,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8caf, "HP Elite mt645 G8 Mobile Thin Client", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8cbd, "HP Pavilion Aero Laptop 13-bg0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), +- SND_PCI_QUIRK(0x103c, 0x8cdd, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2), +- SND_PCI_QUIRK(0x103c, 0x8cde, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8cdd, "HP Spectre", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX), ++ SND_PCI_QUIRK(0x103c, 0x8cde, "HP OmniBook Ultra Flip Laptop 14t", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX), + SND_PCI_QUIRK(0x103c, 0x8cdf, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ce0, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), +-- +2.39.5 + diff --git a/queue-6.12/alsa-hda-realtek-fix-built-mic-regression-on-other-a.patch b/queue-6.12/alsa-hda-realtek-fix-built-mic-regression-on-other-a.patch new file mode 100644 index 0000000000..f32b382d49 --- /dev/null +++ b/queue-6.12/alsa-hda-realtek-fix-built-mic-regression-on-other-a.patch @@ -0,0 +1,62 @@ +From 1722e0315a626fb5edb70f4fe92b803f4cf85c02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 07:31:41 +0200 +Subject: ALSA: hda/realtek: Fix built-mic regression on other ASUS models + +From: Takashi Iwai + +[ Upstream commit 4d5b71b487291da9f92e352c0a7e39f256d60db8 ] + +A few ASUS models use the ALC256_FIXUP_ASUS_HEADSET_MODE although they +have no built-in mic pin on NID 0x13, as found in the commit +c1732ede5e80 ("ALSA: hda/realtek - Fix headset and mic on several Asus +laptops with ALC256"). This was relatively harmless in the past as +NID 0x13 was assigned as the secondary mic. But since the fix for the +pin sort order, this pin became the primary one, hence user started +noticing the broken input, and we've fixed already for a few ASUS +models to switch to ALC256_FIXUP_ASUS_MIC_NO_PRESENCE. + +This patch corrects the other ASUS models to use the right quirk entry +for fixing the built-in mic regression. Here we cover X541SA +(1043:12e0), X541UV (1043:12f0), Z550SA (1043:13bf0) and X555UB +(1043:1ccd). + +Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220058 +Link: https://patch.msgid.link/20250430053210.31776-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 5a36cb2969b08..db72c5fce9d18 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10723,10 +10723,10 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x12a3, "Asus N7691ZM", ALC269_FIXUP_ASUS_N7601ZM), + SND_PCI_QUIRK(0x1043, 0x12af, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x12b4, "ASUS B3405CCA / P3405CCA", ALC294_FIXUP_ASUS_CS35L41_SPI_2), +- SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), +- SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), ++ SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE), +- SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), ++ SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), + SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1460, "Asus VivoBook 15", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), +@@ -10780,7 +10780,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS), + SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JU/JV/JI", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JY/JZ/JI/JG", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS), +- SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1ccf, "ASUS G814JU/JV/JI", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1cdf, "ASUS G814JY/JZ/JG", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1cef, "ASUS G834JY/JZ/JI/JG", ALC285_FIXUP_ASUS_HEADSET_MIC), +-- +2.39.5 + diff --git a/queue-6.12/alsa-ump-fix-buffer-overflow-at-ump-sysex-message-co.patch b/queue-6.12/alsa-ump-fix-buffer-overflow-at-ump-sysex-message-co.patch new file mode 100644 index 0000000000..8622a6eed1 --- /dev/null +++ b/queue-6.12/alsa-ump-fix-buffer-overflow-at-ump-sysex-message-co.patch @@ -0,0 +1,45 @@ +From eaed3af695f6b88f78d8f7cb7109b586bf61707b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 14:48:41 +0200 +Subject: ALSA: ump: Fix buffer overflow at UMP SysEx message conversion + +From: Takashi Iwai + +[ Upstream commit 56f1f30e6795b890463d9b20b11e576adf5a2f77 ] + +The conversion function from MIDI 1.0 to UMP packet contains an +internal buffer to keep the incoming MIDI bytes, and its size is 4, as +it was supposed to be the max size for a MIDI1 UMP packet data. +However, the implementation overlooked that SysEx is handled in a +different format, and it can be up to 6 bytes, as found in +do_convert_to_ump(). It leads eventually to a buffer overflow, and +may corrupt the memory when a longer SysEx message is received. + +The fix is simply to extend the buffer size to 6 to fit with the SysEx +UMP message. + +Fixes: 0b5288f5fe63 ("ALSA: ump: Add legacy raw MIDI support") +Reported-by: Argusee +Link: https://patch.msgid.link/20250429124845.25128-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + include/sound/ump_convert.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/sound/ump_convert.h b/include/sound/ump_convert.h +index d099ae27f8491..682499b871eac 100644 +--- a/include/sound/ump_convert.h ++++ b/include/sound/ump_convert.h +@@ -19,7 +19,7 @@ struct ump_cvt_to_ump_bank { + /* context for converting from MIDI1 byte stream to UMP packet */ + struct ump_cvt_to_ump { + /* MIDI1 intermediate buffer */ +- unsigned char buf[4]; ++ unsigned char buf[6]; /* up to 6 bytes for SysEx */ + int len; + int cmd_bytes; + +-- +2.39.5 + diff --git a/queue-6.12/asoc-amd-acp-fix-null-pointer-deref-in-acp_i2s_set_t.patch b/queue-6.12/asoc-amd-acp-fix-null-pointer-deref-in-acp_i2s_set_t.patch new file mode 100644 index 0000000000..fd9e88ec6b --- /dev/null +++ b/queue-6.12/asoc-amd-acp-fix-null-pointer-deref-in-acp_i2s_set_t.patch @@ -0,0 +1,38 @@ +From 09ac4f15e39e9430c672a922c833c6c025488419 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 11:31:40 +0530 +Subject: ASoC: amd: acp: Fix NULL pointer deref in acp_i2s_set_tdm_slot + +From: Venkata Prasad Potturu + +[ Upstream commit 6d9b64156d849e358cb49b6b899fb0b7d262bda8 ] + +Update chip data using dev_get_drvdata(dev->parent) to fix +NULL pointer deref in acp_i2s_set_tdm_slot. + +Fixes: cd60dec8994c ("ASoC: amd: acp: Refactor TDM slots selction based on acp revision id") + +Signed-off-by: Venkata Prasad Potturu +Link: https://patch.msgid.link/20250425060144.1773265-2-venkataprasad.potturu@amd.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/amd/acp/acp-i2s.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c +index 92c5ff0deea2c..607a3eaeb6da8 100644 +--- a/sound/soc/amd/acp/acp-i2s.c ++++ b/sound/soc/amd/acp/acp-i2s.c +@@ -101,7 +101,7 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas + struct acp_stream *stream; + int slot_len, no_of_slots; + +- chip = dev_get_platdata(dev); ++ chip = dev_get_drvdata(dev->parent); + switch (slot_width) { + case SLOT_WIDTH_8: + slot_len = 8; +-- +2.39.5 + diff --git a/queue-6.12/asoc-cs-amp-lib-test-don-t-select-snd_soc_cs_amp_lib.patch b/queue-6.12/asoc-cs-amp-lib-test-don-t-select-snd_soc_cs_amp_lib.patch new file mode 100644 index 0000000000..9db65736a5 --- /dev/null +++ b/queue-6.12/asoc-cs-amp-lib-test-don-t-select-snd_soc_cs_amp_lib.patch @@ -0,0 +1,45 @@ +From 4107766348b6d01e8c67cf920e157692d8177894 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Apr 2025 13:36:07 +0100 +Subject: ASoC: cs-amp-lib-test: Don't select SND_SOC_CS_AMP_LIB + +From: Richard Fitzgerald + +[ Upstream commit 96014d91cffb335d3b396771524ff2aba3549865 ] + +Depend on SND_SOC_CS_AMP_LIB instead of selecting it. + +KUNIT_ALL_TESTS should only build tests for components that are +already being built, it should not cause other stuff to be added +to the build. + +Fixes: 177862317a98 ("ASoC: cs-amp-lib: Add KUnit test for calibration helpers") +Signed-off-by: Richard Fitzgerald +Link: https://patch.msgid.link/20250411123608.1676462-3-rf@opensource.cirrus.com +Reviewed-by: David Gow +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/Kconfig | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 0d9d1d250f2b5..6a72561c4189b 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -746,10 +746,9 @@ config SND_SOC_CS_AMP_LIB + tristate + + config SND_SOC_CS_AMP_LIB_TEST +- tristate "KUnit test for Cirrus Logic cs-amp-lib" +- depends on KUNIT ++ tristate "KUnit test for Cirrus Logic cs-amp-lib" if !KUNIT_ALL_TESTS ++ depends on SND_SOC_CS_AMP_LIB && KUNIT + default KUNIT_ALL_TESTS +- select SND_SOC_CS_AMP_LIB + help + This builds KUnit tests for the Cirrus Logic common + amplifier library. +-- +2.39.5 + diff --git a/queue-6.12/asoc-intel-sof_sdw-add-null-check-in-asoc_sdw_rt_dmi.patch b/queue-6.12/asoc-intel-sof_sdw-add-null-check-in-asoc_sdw_rt_dmi.patch new file mode 100644 index 0000000000..3c018c50ee --- /dev/null +++ b/queue-6.12/asoc-intel-sof_sdw-add-null-check-in-asoc_sdw_rt_dmi.patch @@ -0,0 +1,37 @@ +From 5ba96b8cb01f3c533007a5ca10069903bf9f6e0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Apr 2025 14:41:34 -0500 +Subject: ASoC: Intel: sof_sdw: Add NULL check in asoc_sdw_rt_dmic_rtd_init() + +From: Chenyuan Yang + +[ Upstream commit 68715cb5c0e00284d93f976c6368809f64131b0b ] + +mic_name returned by devm_kasprintf() could be NULL. +Add a check for it. + +Signed-off-by: Chenyuan Yang +Fixes: bee2fe44679f ("ASoC: Intel: sof_sdw: use generic rtd_init function for Realtek SDW DMICs") +Link: https://patch.msgid.link/20250415194134.292830-1-chenyuan0y@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sdw_utils/soc_sdw_rt_dmic.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/sdw_utils/soc_sdw_rt_dmic.c b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c +index 7f24806d809d9..74bca3d04e4f1 100644 +--- a/sound/soc/sdw_utils/soc_sdw_rt_dmic.c ++++ b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c +@@ -29,6 +29,8 @@ int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da + mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "rt715-sdca"); + else + mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s", component->name_prefix); ++ if (!mic_name) ++ return -ENOMEM; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s mic:%s", card->components, +-- +2.39.5 + diff --git a/queue-6.12/asoc-simple-card-utils-fix-pointer-check-in-graph_ut.patch b/queue-6.12/asoc-simple-card-utils-fix-pointer-check-in-graph_ut.patch new file mode 100644 index 0000000000..73e87c36e7 --- /dev/null +++ b/queue-6.12/asoc-simple-card-utils-fix-pointer-check-in-graph_ut.patch @@ -0,0 +1,46 @@ +From 1ae0e5bb9852574c4dffc354930afa68ad2ba4b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 11:49:10 +0200 +Subject: ASoC: simple-card-utils: Fix pointer check in + graph_util_parse_link_direction + +From: Alexander Stein + +[ Upstream commit 3cc393d2232ec770b5f79bf0673d67702a3536c3 ] + +Actually check if the passed pointers are valid, before writing to them. +This also fixes a USBAN warning: +UBSAN: invalid-load in ../sound/soc/fsl/imx-card.c:687:25 +load of value 255 is not a valid value for type '_Bool' + +This is because playback_only is uninitialized and is not written to, as +the playback-only property is absent. + +Fixes: 844de7eebe97 ("ASoC: audio-graph-card2: expand dai_link property part") +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20250429094910.1150970-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/generic/simple-card-utils.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c +index 975ffd2cad292..809dbb9ded365 100644 +--- a/sound/soc/generic/simple-card-utils.c ++++ b/sound/soc/generic/simple-card-utils.c +@@ -1150,9 +1150,9 @@ void graph_util_parse_link_direction(struct device_node *np, + bool is_playback_only = of_property_read_bool(np, "playback-only"); + bool is_capture_only = of_property_read_bool(np, "capture-only"); + +- if (is_playback_only) ++ if (playback_only) + *playback_only = is_playback_only; +- if (is_capture_only) ++ if (capture_only) + *capture_only = is_capture_only; + } + EXPORT_SYMBOL_GPL(graph_util_parse_link_direction); +-- +2.39.5 + diff --git a/queue-6.12/asoc-soc-pcm-fix-hw_params-and-dapm-widget-sequence.patch b/queue-6.12/asoc-soc-pcm-fix-hw_params-and-dapm-widget-sequence.patch new file mode 100644 index 0000000000..665f7993b4 --- /dev/null +++ b/queue-6.12/asoc-soc-pcm-fix-hw_params-and-dapm-widget-sequence.patch @@ -0,0 +1,69 @@ +From 25a96008ddf6cfdcf4133f6c4c8bd9d07a1ba93b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Apr 2025 10:59:53 +0000 +Subject: ASoC: soc-pcm: Fix hw_params() and DAPM widget sequence + +From: Sheetal + +[ Upstream commit 9aff2e8df240e84a36f2607f98a0a9924a24e65d ] + +Issue: + When multiple audio streams share a common BE DAI, the BE DAI + widget can be powered up before its hardware parameters are configured. + This incorrect sequence leads to intermittent pcm_write errors. + + For example, the below Tegra use-case throws an error: + aplay(2 streams) -> AMX(mux) -> ADX(demux) -> arecord(2 streams), + here, 'AMX TX' and 'ADX RX' are common BE DAIs. + +For above usecase when failure happens below sequence is observed: + aplay(1) FE open() + - BE DAI callbacks added to the list + - BE DAI state = SND_SOC_DPCM_STATE_OPEN + aplay(2) FE open() + - BE DAI callbacks are not added to the list as the state is + already SND_SOC_DPCM_STATE_OPEN during aplay(1) FE open(). + aplay(2) FE hw_params() + - BE DAI hw_params() callback ignored + aplay(2) FE prepare() + - Widget is powered ON without BE DAI hw_params() call + aplay(1) FE hw_params() + - BE DAI hw_params() is now called + +Fix: + Add BE DAIs in the list if its state is either SND_SOC_DPCM_STATE_OPEN + or SND_SOC_DPCM_STATE_HW_PARAMS as well. + +It ensures the widget is powered ON after BE DAI hw_params() callback. + +Fixes: 0c25db3f7621 ("ASoC: soc-pcm: Don't reconnect an already active BE") +Signed-off-by: Sheetal +Link: https://patch.msgid.link/20250404105953.2784819-1-sheetal@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/soc-pcm.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index 1102599403c53..0e21ff9f7b74e 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -1633,10 +1633,13 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, + /* + * Filter for systems with 'component_chaining' enabled. + * This helps to avoid unnecessary re-configuration of an +- * already active BE on such systems. ++ * already active BE on such systems and ensures the BE DAI ++ * widget is powered ON after hw_params() BE DAI callback. + */ + if (fe->card->component_chaining && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) && ++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) && ++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) + continue; + +-- +2.39.5 + diff --git a/queue-6.12/bluetooth-btintel_pcie-add-additional-to-checks-to-c.patch b/queue-6.12/bluetooth-btintel_pcie-add-additional-to-checks-to-c.patch new file mode 100644 index 0000000000..5729c35a00 --- /dev/null +++ b/queue-6.12/bluetooth-btintel_pcie-add-additional-to-checks-to-c.patch @@ -0,0 +1,82 @@ +From 3da32cbda9eece37f7832e19ac5ea05532fea1a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Apr 2025 07:21:56 +0530 +Subject: Bluetooth: btintel_pcie: Add additional to checks to clear TX/RX + paths + +From: Kiran K + +[ Upstream commit 1c7664957e4edb234c69de2db4be1f740d2df564 ] + +Due to a hardware issue, there is a possibility that the driver may miss +an MSIx interrupt on the RX/TX data path. Since the TX and RX paths are +independent, when a TX MSIx interrupt occurs, the driver can check the +RX queue for any pending data and process it if present. The same +approach applies to the RX path. + +Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport") +Signed-off-by: Chandrashekar Devegowda +Signed-off-by: Kiran K +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btintel_pcie.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c +index 3d6067927f7ea..d225f0a37f985 100644 +--- a/drivers/bluetooth/btintel_pcie.c ++++ b/drivers/bluetooth/btintel_pcie.c +@@ -761,10 +761,8 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data) + bt_dev_dbg(hdev, "RXQ: cr_hia: %u cr_tia: %u", cr_hia, cr_tia); + + /* Check CR_TIA and CR_HIA for change */ +- if (cr_tia == cr_hia) { +- bt_dev_warn(hdev, "RXQ: no new CD found"); ++ if (cr_tia == cr_hia) + return; +- } + + rxq = &data->rxq; + +@@ -800,6 +798,16 @@ static irqreturn_t btintel_pcie_msix_isr(int irq, void *data) + return IRQ_WAKE_THREAD; + } + ++static inline bool btintel_pcie_is_rxq_empty(struct btintel_pcie_data *data) ++{ ++ return data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM] == data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM]; ++} ++ ++static inline bool btintel_pcie_is_txackq_empty(struct btintel_pcie_data *data) ++{ ++ return data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] == data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM]; ++} ++ + static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) + { + struct msix_entry *entry = dev_id; +@@ -827,12 +835,18 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) + btintel_pcie_msix_gp0_handler(data); + + /* For TX */ +- if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) ++ if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) { + btintel_pcie_msix_tx_handle(data); ++ if (!btintel_pcie_is_rxq_empty(data)) ++ btintel_pcie_msix_rx_handle(data); ++ } + + /* For RX */ +- if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) ++ if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) { + btintel_pcie_msix_rx_handle(data); ++ if (!btintel_pcie_is_txackq_empty(data)) ++ btintel_pcie_msix_tx_handle(data); ++ } + + /* + * Before sending the interrupt the HW disables it to prevent a nested +-- +2.39.5 + diff --git a/queue-6.12/bluetooth-btintel_pcie-avoid-redundant-buffer-alloca.patch b/queue-6.12/bluetooth-btintel_pcie-avoid-redundant-buffer-alloca.patch new file mode 100644 index 0000000000..4616fcabfe --- /dev/null +++ b/queue-6.12/bluetooth-btintel_pcie-avoid-redundant-buffer-alloca.patch @@ -0,0 +1,99 @@ +From b3994807c9f937df8c62a2faa8479a4f4200f451 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Apr 2025 09:18:42 +0530 +Subject: Bluetooth: btintel_pcie: Avoid redundant buffer allocation + +From: Kiran K + +[ Upstream commit d1af1f02ef8653dea4573e444136c8331189cd59 ] + +Reuse the skb buffer provided by the PCIe driver to pass it onto the +stack, instead of copying it to a new skb. + +Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport") +Signed-off-by: Kiran K +Reviewed-by: Paul Menzel +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btintel_pcie.c | 33 ++++++++++++-------------------- + 1 file changed, 12 insertions(+), 21 deletions(-) + +diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c +index ab465e13c1f60..3d6067927f7ea 100644 +--- a/drivers/bluetooth/btintel_pcie.c ++++ b/drivers/bluetooth/btintel_pcie.c +@@ -581,8 +581,10 @@ static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb) + /* This is a debug event that comes from IML and OP image when it + * starts execution. There is no need pass this event to stack. + */ +- if (skb->data[2] == 0x97) ++ if (skb->data[2] == 0x97) { ++ hci_recv_diag(hdev, skb); + return 0; ++ } + } + + return hci_recv_frame(hdev, skb); +@@ -598,7 +600,6 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data, + u8 pkt_type; + u16 plen; + u32 pcie_pkt_type; +- struct sk_buff *new_skb; + void *pdata; + struct hci_dev *hdev = data->hdev; + +@@ -675,24 +676,20 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data, + + bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen); + +- new_skb = bt_skb_alloc(plen, GFP_ATOMIC); +- if (!new_skb) { +- bt_dev_err(hdev, "Failed to allocate memory for skb of len: %u", +- skb->len); +- ret = -ENOMEM; +- goto exit_error; +- } +- +- hci_skb_pkt_type(new_skb) = pkt_type; +- skb_put_data(new_skb, skb->data, plen); ++ hci_skb_pkt_type(skb) = pkt_type; + hdev->stat.byte_rx += plen; ++ skb_trim(skb, plen); + + if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT) +- ret = btintel_pcie_recv_event(hdev, new_skb); ++ ret = btintel_pcie_recv_event(hdev, skb); + else +- ret = hci_recv_frame(hdev, new_skb); ++ ret = hci_recv_frame(hdev, skb); ++ skb = NULL; /* skb is freed in the callee */ + + exit_error: ++ if (skb) ++ kfree_skb(skb); ++ + if (ret) + hdev->stat.err_rx++; + +@@ -706,16 +703,10 @@ static void btintel_pcie_rx_work(struct work_struct *work) + struct btintel_pcie_data *data = container_of(work, + struct btintel_pcie_data, rx_work); + struct sk_buff *skb; +- int err; +- struct hci_dev *hdev = data->hdev; + + /* Process the sk_buf in queue and send to the HCI layer */ + while ((skb = skb_dequeue(&data->rx_skb_q))) { +- err = btintel_pcie_recv_frame(data, skb); +- if (err) +- bt_dev_err(hdev, "Failed to send received frame: %d", +- err); +- kfree_skb(skb); ++ btintel_pcie_recv_frame(data, skb); + } + } + +-- +2.39.5 + diff --git a/queue-6.12/bluetooth-btusb-avoid-null-pointer-dereference-in-sk.patch b/queue-6.12/bluetooth-btusb-avoid-null-pointer-dereference-in-sk.patch new file mode 100644 index 0000000000..6d30a9e2f2 --- /dev/null +++ b/queue-6.12/bluetooth-btusb-avoid-null-pointer-dereference-in-sk.patch @@ -0,0 +1,197 @@ +From 5492a86535ce478637cf9e2ba75264eacce0dd55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Apr 2025 21:00:37 +0800 +Subject: Bluetooth: btusb: avoid NULL pointer dereference in skb_dequeue() + +From: En-Wei Wu + +[ Upstream commit 0317b033abcd1d8dd2798f0e2de5e84543d0bd22 ] + +A NULL pointer dereference can occur in skb_dequeue() when processing a +QCA firmware crash dump on WCN7851 (0489:e0f3). + +[ 93.672166] Bluetooth: hci0: ACL memdump size(589824) + +[ 93.672475] BUG: kernel NULL pointer dereference, address: 0000000000000008 +[ 93.672517] Workqueue: hci0 hci_devcd_rx [bluetooth] +[ 93.672598] RIP: 0010:skb_dequeue+0x50/0x80 + +The issue stems from handle_dump_pkt_qca() returning 0 even when a dump +packet is successfully processed. This is because it incorrectly +forwards the return value of hci_devcd_init() (which returns 0 on +success). As a result, the caller (btusb_recv_acl_qca() or +btusb_recv_evt_qca()) assumes the packet was not handled and passes it +to hci_recv_frame(), leading to premature kfree() of the skb. + +Later, hci_devcd_rx() attempts to dequeue the same skb from the dump +queue, resulting in a NULL pointer dereference. + +Fix this by: +1. Making handle_dump_pkt_qca() return 0 on success and negative errno + on failure, consistent with kernel conventions. +2. Splitting dump packet detection into separate functions for ACL + and event packets for better structure and readability. + +This ensures dump packets are properly identified and consumed, avoiding +double handling and preventing NULL pointer access. + +Fixes: 20981ce2d5a5 ("Bluetooth: btusb: Add WCN6855 devcoredump support") +Signed-off-by: En-Wei Wu +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 101 +++++++++++++++++++++++++++----------- + 1 file changed, 73 insertions(+), 28 deletions(-) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index f784daaa6b528..7e1f03231b4c9 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -2975,22 +2975,16 @@ static void btusb_coredump_qca(struct hci_dev *hdev) + bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err); + } + +-/* +- * ==0: not a dump pkt. +- * < 0: fails to handle a dump pkt +- * > 0: otherwise. +- */ ++/* Return: 0 on success, negative errno on failure. */ + static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) + { +- int ret = 1; ++ int ret = 0; + u8 pkt_type; + u8 *sk_ptr; + unsigned int sk_len; + u16 seqno; + u32 dump_size; + +- struct hci_event_hdr *event_hdr; +- struct hci_acl_hdr *acl_hdr; + struct qca_dump_hdr *dump_hdr; + struct btusb_data *btdata = hci_get_drvdata(hdev); + struct usb_device *udev = btdata->udev; +@@ -3000,30 +2994,14 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) + sk_len = skb->len; + + if (pkt_type == HCI_ACLDATA_PKT) { +- acl_hdr = hci_acl_hdr(skb); +- if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE) +- return 0; + sk_ptr += HCI_ACL_HDR_SIZE; + sk_len -= HCI_ACL_HDR_SIZE; +- event_hdr = (struct hci_event_hdr *)sk_ptr; +- } else { +- event_hdr = hci_event_hdr(skb); + } + +- if ((event_hdr->evt != HCI_VENDOR_PKT) +- || (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE))) +- return 0; +- + sk_ptr += HCI_EVENT_HDR_SIZE; + sk_len -= HCI_EVENT_HDR_SIZE; + + dump_hdr = (struct qca_dump_hdr *)sk_ptr; +- if ((sk_len < offsetof(struct qca_dump_hdr, data)) +- || (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) +- || (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) +- return 0; +- +- /*it is dump pkt now*/ + seqno = le16_to_cpu(dump_hdr->seqno); + if (seqno == 0) { + set_bit(BTUSB_HW_SSR_ACTIVE, &btdata->flags); +@@ -3097,17 +3075,84 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) + return ret; + } + ++/* Return: true if the ACL packet is a dump packet, false otherwise. */ ++static bool acl_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb) ++{ ++ u8 *sk_ptr; ++ unsigned int sk_len; ++ ++ struct hci_event_hdr *event_hdr; ++ struct hci_acl_hdr *acl_hdr; ++ struct qca_dump_hdr *dump_hdr; ++ ++ sk_ptr = skb->data; ++ sk_len = skb->len; ++ ++ acl_hdr = hci_acl_hdr(skb); ++ if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE) ++ return false; ++ ++ sk_ptr += HCI_ACL_HDR_SIZE; ++ sk_len -= HCI_ACL_HDR_SIZE; ++ event_hdr = (struct hci_event_hdr *)sk_ptr; ++ ++ if ((event_hdr->evt != HCI_VENDOR_PKT) || ++ (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE))) ++ return false; ++ ++ sk_ptr += HCI_EVENT_HDR_SIZE; ++ sk_len -= HCI_EVENT_HDR_SIZE; ++ ++ dump_hdr = (struct qca_dump_hdr *)sk_ptr; ++ if ((sk_len < offsetof(struct qca_dump_hdr, data)) || ++ (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) || ++ (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) ++ return false; ++ ++ return true; ++} ++ ++/* Return: true if the event packet is a dump packet, false otherwise. */ ++static bool evt_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb) ++{ ++ u8 *sk_ptr; ++ unsigned int sk_len; ++ ++ struct hci_event_hdr *event_hdr; ++ struct qca_dump_hdr *dump_hdr; ++ ++ sk_ptr = skb->data; ++ sk_len = skb->len; ++ ++ event_hdr = hci_event_hdr(skb); ++ ++ if ((event_hdr->evt != HCI_VENDOR_PKT) ++ || (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE))) ++ return false; ++ ++ sk_ptr += HCI_EVENT_HDR_SIZE; ++ sk_len -= HCI_EVENT_HDR_SIZE; ++ ++ dump_hdr = (struct qca_dump_hdr *)sk_ptr; ++ if ((sk_len < offsetof(struct qca_dump_hdr, data)) || ++ (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) || ++ (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE)) ++ return false; ++ ++ return true; ++} ++ + static int btusb_recv_acl_qca(struct hci_dev *hdev, struct sk_buff *skb) + { +- if (handle_dump_pkt_qca(hdev, skb)) +- return 0; ++ if (acl_pkt_is_dump_qca(hdev, skb)) ++ return handle_dump_pkt_qca(hdev, skb); + return hci_recv_frame(hdev, skb); + } + + static int btusb_recv_evt_qca(struct hci_dev *hdev, struct sk_buff *skb) + { +- if (handle_dump_pkt_qca(hdev, skb)) +- return 0; ++ if (evt_pkt_is_dump_qca(hdev, skb)) ++ return handle_dump_pkt_qca(hdev, skb); + return hci_recv_frame(hdev, skb); + } + +-- +2.39.5 + diff --git a/queue-6.12/bluetooth-hci_conn-fix-not-setting-conn_timeout-for-.patch b/queue-6.12/bluetooth-hci_conn-fix-not-setting-conn_timeout-for-.patch new file mode 100644 index 0000000000..d9d0a04727 --- /dev/null +++ b/queue-6.12/bluetooth-hci_conn-fix-not-setting-conn_timeout-for-.patch @@ -0,0 +1,338 @@ +From 4ecde33cc7fbffb2d70017b4a4ea51307d1f3ebb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Apr 2025 16:08:48 -0400 +Subject: Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast + Receiver + +From: Luiz Augusto von Dentz + +[ Upstream commit 6d0417e4e1cf66fd917f06f0454958362714ef7d ] + +Broadcast Receiver requires creating PA sync but the command just +generates a status so this makes use of __hci_cmd_sync_status_sk to wait +for HCI_EV_LE_PA_SYNC_ESTABLISHED, also because of this chance it is not +longer necessary to use a custom method to serialize the process of +creating the PA sync since the cmd_work_sync itself ensures only one +command would be pending which now awaits for +HCI_EV_LE_PA_SYNC_ESTABLISHED before proceeding to next connection. + +Fixes: 4a5e0ba68676 ("Bluetooth: ISO: Do not emit LE PA Create Sync if previous is pending") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci.h | 2 + + include/net/bluetooth/hci_core.h | 13 +++-- + include/net/bluetooth/hci_sync.h | 2 + + net/bluetooth/hci_conn.c | 92 +------------------------------- + net/bluetooth/hci_event.c | 6 +-- + net/bluetooth/hci_sync.c | 87 ++++++++++++++++++++++++++++-- + 6 files changed, 95 insertions(+), 107 deletions(-) + +diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h +index 71d2432876406..3d1599cdbb8d0 100644 +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -1913,6 +1913,8 @@ struct hci_cp_le_pa_create_sync { + __u8 sync_cte_type; + } __packed; + ++#define HCI_OP_LE_PA_CREATE_SYNC_CANCEL 0x2045 ++ + #define HCI_OP_LE_PA_TERM_SYNC 0x2046 + struct hci_cp_le_pa_term_sync { + __le16 handle; +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 4245910ffc4a2..1753869000164 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1105,10 +1105,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev, + return NULL; + } + +-static inline struct hci_conn *hci_conn_hash_lookup_sid(struct hci_dev *hdev, +- __u8 sid, +- bdaddr_t *dst, +- __u8 dst_type) ++static inline struct hci_conn * ++hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev) + { + struct hci_conn_hash *h = &hdev->conn_hash; + struct hci_conn *c; +@@ -1116,8 +1114,10 @@ static inline struct hci_conn *hci_conn_hash_lookup_sid(struct hci_dev *hdev, + rcu_read_lock(); + + list_for_each_entry_rcu(c, &h->list, list) { +- if (c->type != ISO_LINK || bacmp(&c->dst, dst) || +- c->dst_type != dst_type || c->sid != sid) ++ if (c->type != ISO_LINK) ++ continue; ++ ++ if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags)) + continue; + + rcu_read_unlock(); +@@ -1506,7 +1506,6 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle); + void hci_sco_setup(struct hci_conn *conn, __u8 status); + bool hci_iso_setup_path(struct hci_conn *conn); + int hci_le_create_cis_pending(struct hci_dev *hdev); +-int hci_pa_create_sync_pending(struct hci_dev *hdev); + int hci_le_big_create_sync_pending(struct hci_dev *hdev); + int hci_conn_check_create_cis(struct hci_conn *conn); + +diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h +index f3052cb252efd..fbc4d753ef842 100644 +--- a/include/net/bluetooth/hci_sync.h ++++ b/include/net/bluetooth/hci_sync.h +@@ -186,3 +186,5 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn); + int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn); + int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn, + struct hci_conn_params *params); ++ ++int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn); +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index d097e308a7554..badaa6c199204 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -2061,95 +2061,6 @@ static int create_big_sync(struct hci_dev *hdev, void *data) + return hci_le_create_big(conn, &conn->iso_qos); + } + +-static void create_pa_complete(struct hci_dev *hdev, void *data, int err) +-{ +- bt_dev_dbg(hdev, ""); +- +- if (err) +- bt_dev_err(hdev, "Unable to create PA: %d", err); +-} +- +-static bool hci_conn_check_create_pa_sync(struct hci_conn *conn) +-{ +- if (conn->type != ISO_LINK || conn->sid == HCI_SID_INVALID) +- return false; +- +- return true; +-} +- +-static int create_pa_sync(struct hci_dev *hdev, void *data) +-{ +- struct hci_cp_le_pa_create_sync cp = {0}; +- struct hci_conn *conn; +- int err = 0; +- +- hci_dev_lock(hdev); +- +- rcu_read_lock(); +- +- /* The spec allows only one pending LE Periodic Advertising Create +- * Sync command at a time. If the command is pending now, don't do +- * anything. We check for pending connections after each PA Sync +- * Established event. +- * +- * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E +- * page 2493: +- * +- * If the Host issues this command when another HCI_LE_Periodic_ +- * Advertising_Create_Sync command is pending, the Controller shall +- * return the error code Command Disallowed (0x0C). +- */ +- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { +- if (test_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags)) +- goto unlock; +- } +- +- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { +- if (hci_conn_check_create_pa_sync(conn)) { +- struct bt_iso_qos *qos = &conn->iso_qos; +- +- cp.options = qos->bcast.options; +- cp.sid = conn->sid; +- cp.addr_type = conn->dst_type; +- bacpy(&cp.addr, &conn->dst); +- cp.skip = cpu_to_le16(qos->bcast.skip); +- cp.sync_timeout = cpu_to_le16(qos->bcast.sync_timeout); +- cp.sync_cte_type = qos->bcast.sync_cte_type; +- +- break; +- } +- } +- +-unlock: +- rcu_read_unlock(); +- +- hci_dev_unlock(hdev); +- +- if (bacmp(&cp.addr, BDADDR_ANY)) { +- hci_dev_set_flag(hdev, HCI_PA_SYNC); +- set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); +- +- err = __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC, +- sizeof(cp), &cp, HCI_CMD_TIMEOUT); +- if (!err) +- err = hci_update_passive_scan_sync(hdev); +- +- if (err) { +- hci_dev_clear_flag(hdev, HCI_PA_SYNC); +- clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); +- } +- } +- +- return err; +-} +- +-int hci_pa_create_sync_pending(struct hci_dev *hdev) +-{ +- /* Queue start pa_create_sync and scan */ +- return hci_cmd_sync_queue(hdev, create_pa_sync, +- NULL, create_pa_complete); +-} +- + struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, + __u8 dst_type, __u8 sid, + struct bt_iso_qos *qos) +@@ -2164,10 +2075,11 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, + conn->dst_type = dst_type; + conn->sid = sid; + conn->state = BT_LISTEN; ++ conn->conn_timeout = msecs_to_jiffies(qos->bcast.sync_timeout * 10); + + hci_conn_hold(conn); + +- hci_pa_create_sync_pending(hdev); ++ hci_connect_pa_sync(hdev, conn); + + return conn; + } +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index 96ad1b75d1c4d..bdf36ce06c68c 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -6368,8 +6368,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, + + hci_dev_clear_flag(hdev, HCI_PA_SYNC); + +- conn = hci_conn_hash_lookup_sid(hdev, ev->sid, &ev->bdaddr, +- ev->bdaddr_type); ++ conn = hci_conn_hash_lookup_create_pa_sync(hdev); + if (!conn) { + bt_dev_err(hdev, + "Unable to find connection for dst %pMR sid 0x%2.2x", +@@ -6408,9 +6407,6 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, + } + + unlock: +- /* Handle any other pending PA sync command */ +- hci_pa_create_sync_pending(hdev); +- + hci_dev_unlock(hdev); + } + +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index cb4d47ae129e8..d603810ccda99 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -2717,16 +2717,16 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) + + /* Force address filtering if PA Sync is in progress */ + if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) { +- struct hci_cp_le_pa_create_sync *sent; ++ struct hci_conn *conn; + +- sent = hci_sent_cmd_data(hdev, HCI_OP_LE_PA_CREATE_SYNC); +- if (sent) { ++ conn = hci_conn_hash_lookup_create_pa_sync(hdev); ++ if (conn) { + struct conn_params pa; + + memset(&pa, 0, sizeof(pa)); + +- bacpy(&pa.addr, &sent->addr); +- pa.addr_type = sent->addr_type; ++ bacpy(&pa.addr, &conn->dst); ++ pa.addr_type = conn->dst_type; + + /* Clear first since there could be addresses left + * behind. +@@ -6887,3 +6887,80 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn, + return __hci_cmd_sync_status(hdev, HCI_OP_LE_CONN_UPDATE, + sizeof(cp), &cp, HCI_CMD_TIMEOUT); + } ++ ++static void create_pa_complete(struct hci_dev *hdev, void *data, int err) ++{ ++ bt_dev_dbg(hdev, "err %d", err); ++ ++ if (!err) ++ return; ++ ++ hci_dev_clear_flag(hdev, HCI_PA_SYNC); ++ ++ if (err == -ECANCELED) ++ return; ++ ++ hci_dev_lock(hdev); ++ ++ hci_update_passive_scan_sync(hdev); ++ ++ hci_dev_unlock(hdev); ++} ++ ++static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data) ++{ ++ struct hci_cp_le_pa_create_sync cp; ++ struct hci_conn *conn = data; ++ struct bt_iso_qos *qos = &conn->iso_qos; ++ int err; ++ ++ if (!hci_conn_valid(hdev, conn)) ++ return -ECANCELED; ++ ++ if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC)) ++ return -EBUSY; ++ ++ /* Mark HCI_CONN_CREATE_PA_SYNC so hci_update_passive_scan_sync can ++ * program the address in the allow list so PA advertisements can be ++ * received. ++ */ ++ set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); ++ ++ hci_update_passive_scan_sync(hdev); ++ ++ memset(&cp, 0, sizeof(cp)); ++ cp.options = qos->bcast.options; ++ cp.sid = conn->sid; ++ cp.addr_type = conn->dst_type; ++ bacpy(&cp.addr, &conn->dst); ++ cp.skip = cpu_to_le16(qos->bcast.skip); ++ cp.sync_timeout = cpu_to_le16(qos->bcast.sync_timeout); ++ cp.sync_cte_type = qos->bcast.sync_cte_type; ++ ++ /* The spec allows only one pending LE Periodic Advertising Create ++ * Sync command at a time so we forcefully wait for PA Sync Established ++ * event since cmd_work can only schedule one command at a time. ++ * ++ * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E ++ * page 2493: ++ * ++ * If the Host issues this command when another HCI_LE_Periodic_ ++ * Advertising_Create_Sync command is pending, the Controller shall ++ * return the error code Command Disallowed (0x0C). ++ */ ++ err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_PA_CREATE_SYNC, ++ sizeof(cp), &cp, ++ HCI_EV_LE_PA_SYNC_ESTABLISHED, ++ conn->conn_timeout, NULL); ++ if (err == -ETIMEDOUT) ++ __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC_CANCEL, ++ 0, NULL, HCI_CMD_TIMEOUT); ++ ++ return err; ++} ++ ++int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn) ++{ ++ return hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync, conn, ++ create_pa_complete); ++} +-- +2.39.5 + diff --git a/queue-6.12/bluetooth-hci_conn-fix-not-setting-timeout-for-big-c.patch b/queue-6.12/bluetooth-hci_conn-fix-not-setting-timeout-for-big-c.patch new file mode 100644 index 0000000000..7e24f889a0 --- /dev/null +++ b/queue-6.12/bluetooth-hci_conn-fix-not-setting-timeout-for-big-c.patch @@ -0,0 +1,346 @@ +From 54b404b35cb51dc1d0022e6db7e0fe639a91e352 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 15:43:32 -0400 +Subject: Bluetooth: hci_conn: Fix not setting timeout for BIG Create Sync + +From: Luiz Augusto von Dentz + +[ Upstream commit 024421cf39923927ab2b5fe895d1d922b9abe67f ] + +BIG Create Sync requires the command to just generates a status so this +makes use of __hci_cmd_sync_status_sk to wait for +HCI_EVT_LE_BIG_SYNC_ESTABLISHED, also because of this chance it is not +longer necessary to use a custom method to serialize the process of +creating the BIG sync since the cmd_work_sync itself ensures only one +command would be pending which now awaits for +HCI_EVT_LE_BIG_SYNC_ESTABLISHED before proceeding to next connection. + +Fixes: 42ecf1947135 ("Bluetooth: ISO: Do not emit LE BIG Create Sync if previous is pending") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci.h | 2 +- + include/net/bluetooth/hci_core.h | 7 ++- + include/net/bluetooth/hci_sync.h | 1 + + net/bluetooth/hci_conn.c | 89 ++------------------------------ + net/bluetooth/hci_event.c | 9 ++-- + net/bluetooth/hci_sync.c | 63 ++++++++++++++++++++++ + net/bluetooth/iso.c | 26 +++++----- + 7 files changed, 88 insertions(+), 109 deletions(-) + +diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h +index 3d1599cdbb8d0..40fce4193cc1d 100644 +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -2814,7 +2814,7 @@ struct hci_evt_le_create_big_complete { + __le16 bis_handle[]; + } __packed; + +-#define HCI_EVT_LE_BIG_SYNC_ESTABILISHED 0x1d ++#define HCI_EVT_LE_BIG_SYNC_ESTABLISHED 0x1d + struct hci_evt_le_big_sync_estabilished { + __u8 status; + __u8 handle; +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 1753869000164..4f3b537476e10 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1506,7 +1506,6 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle); + void hci_sco_setup(struct hci_conn *conn, __u8 status); + bool hci_iso_setup_path(struct hci_conn *conn); + int hci_le_create_cis_pending(struct hci_dev *hdev); +-int hci_le_big_create_sync_pending(struct hci_dev *hdev); + int hci_conn_check_create_cis(struct hci_conn *conn); + + struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, +@@ -1547,9 +1546,9 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst, + __u8 data_len, __u8 *data); + struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, + __u8 dst_type, __u8 sid, struct bt_iso_qos *qos); +-int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, +- struct bt_iso_qos *qos, +- __u16 sync_handle, __u8 num_bis, __u8 bis[]); ++int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, ++ struct bt_iso_qos *qos, __u16 sync_handle, ++ __u8 num_bis, __u8 bis[]); + int hci_conn_check_link_mode(struct hci_conn *conn); + int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); + int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, +diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h +index fbc4d753ef842..dbabc17b30cdf 100644 +--- a/include/net/bluetooth/hci_sync.h ++++ b/include/net/bluetooth/hci_sync.h +@@ -188,3 +188,4 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn, + struct hci_conn_params *params); + + int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn); ++int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn); +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index badaa6c199204..ae66fa0a5fb58 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -2084,89 +2084,9 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, + return conn; + } + +-static bool hci_conn_check_create_big_sync(struct hci_conn *conn) +-{ +- if (!conn->num_bis) +- return false; +- +- return true; +-} +- +-static void big_create_sync_complete(struct hci_dev *hdev, void *data, int err) +-{ +- bt_dev_dbg(hdev, ""); +- +- if (err) +- bt_dev_err(hdev, "Unable to create BIG sync: %d", err); +-} +- +-static int big_create_sync(struct hci_dev *hdev, void *data) +-{ +- DEFINE_FLEX(struct hci_cp_le_big_create_sync, pdu, bis, num_bis, 0x11); +- struct hci_conn *conn; +- +- rcu_read_lock(); +- +- pdu->num_bis = 0; +- +- /* The spec allows only one pending LE BIG Create Sync command at +- * a time. If the command is pending now, don't do anything. We +- * check for pending connections after each BIG Sync Established +- * event. +- * +- * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E +- * page 2586: +- * +- * If the Host sends this command when the Controller is in the +- * process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_ +- * Established event has not been generated, the Controller shall +- * return the error code Command Disallowed (0x0C). +- */ +- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { +- if (test_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags)) +- goto unlock; +- } +- +- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { +- if (hci_conn_check_create_big_sync(conn)) { +- struct bt_iso_qos *qos = &conn->iso_qos; +- +- set_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags); +- +- pdu->handle = qos->bcast.big; +- pdu->sync_handle = cpu_to_le16(conn->sync_handle); +- pdu->encryption = qos->bcast.encryption; +- memcpy(pdu->bcode, qos->bcast.bcode, +- sizeof(pdu->bcode)); +- pdu->mse = qos->bcast.mse; +- pdu->timeout = cpu_to_le16(qos->bcast.timeout); +- pdu->num_bis = conn->num_bis; +- memcpy(pdu->bis, conn->bis, conn->num_bis); +- +- break; +- } +- } +- +-unlock: +- rcu_read_unlock(); +- +- if (!pdu->num_bis) +- return 0; +- +- return hci_send_cmd(hdev, HCI_OP_LE_BIG_CREATE_SYNC, +- struct_size(pdu, bis, pdu->num_bis), pdu); +-} +- +-int hci_le_big_create_sync_pending(struct hci_dev *hdev) +-{ +- /* Queue big_create_sync */ +- return hci_cmd_sync_queue_once(hdev, big_create_sync, +- NULL, big_create_sync_complete); +-} +- +-int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, +- struct bt_iso_qos *qos, +- __u16 sync_handle, __u8 num_bis, __u8 bis[]) ++int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, ++ struct bt_iso_qos *qos, __u16 sync_handle, ++ __u8 num_bis, __u8 bis[]) + { + int err; + +@@ -2183,9 +2103,10 @@ int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon, + + hcon->num_bis = num_bis; + memcpy(hcon->bis, bis, num_bis); ++ hcon->conn_timeout = msecs_to_jiffies(qos->bcast.timeout * 10); + } + +- return hci_le_big_create_sync_pending(hdev); ++ return hci_connect_big_sync(hdev, hcon); + } + + static void create_big_complete(struct hci_dev *hdev, void *data, int err) +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index bdf36ce06c68c..bc5b42fce2b80 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -6918,7 +6918,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, + + bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); + +- if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED, ++ if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABLISHED, + flex_array_size(ev, bis, ev->num_bis))) + return; + +@@ -6988,9 +6988,6 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, + } + + unlock: +- /* Handle any other pending BIG sync command */ +- hci_le_big_create_sync_pending(hdev); +- + hci_dev_unlock(hdev); + } + +@@ -7112,8 +7109,8 @@ static const struct hci_le_ev { + hci_le_create_big_complete_evt, + sizeof(struct hci_evt_le_create_big_complete), + HCI_MAX_EVENT_SIZE), +- /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */ +- HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED, ++ /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABLISHED] */ ++ HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABLISHED, + hci_le_big_sync_established_evt, + sizeof(struct hci_evt_le_big_sync_estabilished), + HCI_MAX_EVENT_SIZE), +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index d603810ccda99..6597936fbd51b 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -6964,3 +6964,66 @@ int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn) + return hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync, conn, + create_pa_complete); + } ++ ++static void create_big_complete(struct hci_dev *hdev, void *data, int err) ++{ ++ struct hci_conn *conn = data; ++ ++ bt_dev_dbg(hdev, "err %d", err); ++ ++ if (err == -ECANCELED) ++ return; ++ ++ if (hci_conn_valid(hdev, conn)) ++ clear_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags); ++} ++ ++static int hci_le_big_create_sync(struct hci_dev *hdev, void *data) ++{ ++ DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, 0x11); ++ struct hci_conn *conn = data; ++ struct bt_iso_qos *qos = &conn->iso_qos; ++ int err; ++ ++ if (!hci_conn_valid(hdev, conn)) ++ return -ECANCELED; ++ ++ set_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags); ++ ++ memset(cp, 0, sizeof(*cp)); ++ cp->handle = qos->bcast.big; ++ cp->sync_handle = cpu_to_le16(conn->sync_handle); ++ cp->encryption = qos->bcast.encryption; ++ memcpy(cp->bcode, qos->bcast.bcode, sizeof(cp->bcode)); ++ cp->mse = qos->bcast.mse; ++ cp->timeout = cpu_to_le16(qos->bcast.timeout); ++ cp->num_bis = conn->num_bis; ++ memcpy(cp->bis, conn->bis, conn->num_bis); ++ ++ /* The spec allows only one pending LE BIG Create Sync command at ++ * a time, so we forcefully wait for BIG Sync Established event since ++ * cmd_work can only schedule one command at a time. ++ * ++ * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E ++ * page 2586: ++ * ++ * If the Host sends this command when the Controller is in the ++ * process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_ ++ * Established event has not been generated, the Controller shall ++ * return the error code Command Disallowed (0x0C). ++ */ ++ err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_BIG_CREATE_SYNC, ++ struct_size(cp, bis, cp->num_bis), cp, ++ HCI_EVT_LE_BIG_SYNC_ESTABLISHED, ++ conn->conn_timeout, NULL); ++ if (err == -ETIMEDOUT) ++ hci_le_big_terminate_sync(hdev, cp->handle); ++ ++ return err; ++} ++ ++int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn) ++{ ++ return hci_cmd_sync_queue_once(hdev, hci_le_big_create_sync, conn, ++ create_big_complete); ++} +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index 644b606743e21..72bf9b1db2247 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -1414,14 +1414,13 @@ static void iso_conn_big_sync(struct sock *sk) + lock_sock(sk); + + if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) { +- err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon, +- &iso_pi(sk)->qos, +- iso_pi(sk)->sync_handle, +- iso_pi(sk)->bc_num_bis, +- iso_pi(sk)->bc_bis); ++ err = hci_conn_big_create_sync(hdev, iso_pi(sk)->conn->hcon, ++ &iso_pi(sk)->qos, ++ iso_pi(sk)->sync_handle, ++ iso_pi(sk)->bc_num_bis, ++ iso_pi(sk)->bc_bis); + if (err) +- bt_dev_err(hdev, "hci_le_big_create_sync: %d", +- err); ++ bt_dev_err(hdev, "hci_big_create_sync: %d", err); + } + + release_sock(sk); +@@ -1855,7 +1854,7 @@ static void iso_conn_ready(struct iso_conn *conn) + if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags) || + test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) { + ev = hci_recv_event_data(hcon->hdev, +- HCI_EVT_LE_BIG_SYNC_ESTABILISHED); ++ HCI_EVT_LE_BIG_SYNC_ESTABLISHED); + + /* Get reference to PA sync parent socket, if it exists */ + parent = iso_get_sock(&hcon->src, &hcon->dst, +@@ -2047,12 +2046,11 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) + + if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) && + !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) { +- err = hci_le_big_create_sync(hdev, +- hcon, +- &iso_pi(sk)->qos, +- iso_pi(sk)->sync_handle, +- iso_pi(sk)->bc_num_bis, +- iso_pi(sk)->bc_bis); ++ err = hci_conn_big_create_sync(hdev, hcon, ++ &iso_pi(sk)->qos, ++ iso_pi(sk)->sync_handle, ++ iso_pi(sk)->bc_num_bis, ++ iso_pi(sk)->bc_bis); + if (err) { + bt_dev_err(hdev, "hci_le_big_create_sync: %d", + err); +-- +2.39.5 + diff --git a/queue-6.12/bluetooth-hci_conn-remove-alloc-from-critical-sectio.patch b/queue-6.12/bluetooth-hci_conn-remove-alloc-from-critical-sectio.patch new file mode 100644 index 0000000000..b471e76333 --- /dev/null +++ b/queue-6.12/bluetooth-hci_conn-remove-alloc-from-critical-sectio.patch @@ -0,0 +1,87 @@ +From d067e4f6732fda38b9c2cc0ac3d6f9b379904a55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Nov 2024 13:47:07 +0200 +Subject: Bluetooth: hci_conn: Remove alloc from critical section + +From: Iulia Tanasescu + +[ Upstream commit 25ab2db3e60e0e84d7cdc740ea6ae3c10fe61eaa ] + +This removes the kzalloc memory allocation inside critical section in +create_pa_sync, fixing the following message that appears when the kernel +is compiled with CONFIG_DEBUG_ATOMIC_SLEEP enabled: + +BUG: sleeping function called from invalid context at +include/linux/sched/mm.h:321 + +Signed-off-by: Iulia Tanasescu +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: 6d0417e4e1cf ("Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver") +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_conn.c | 28 ++++++++++------------------ + 1 file changed, 10 insertions(+), 18 deletions(-) + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index e6591f487a511..d097e308a7554 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -2079,7 +2079,7 @@ static bool hci_conn_check_create_pa_sync(struct hci_conn *conn) + + static int create_pa_sync(struct hci_dev *hdev, void *data) + { +- struct hci_cp_le_pa_create_sync *cp = NULL; ++ struct hci_cp_le_pa_create_sync cp = {0}; + struct hci_conn *conn; + int err = 0; + +@@ -2108,19 +2108,13 @@ static int create_pa_sync(struct hci_dev *hdev, void *data) + if (hci_conn_check_create_pa_sync(conn)) { + struct bt_iso_qos *qos = &conn->iso_qos; + +- cp = kzalloc(sizeof(*cp), GFP_KERNEL); +- if (!cp) { +- err = -ENOMEM; +- goto unlock; +- } +- +- cp->options = qos->bcast.options; +- cp->sid = conn->sid; +- cp->addr_type = conn->dst_type; +- bacpy(&cp->addr, &conn->dst); +- cp->skip = cpu_to_le16(qos->bcast.skip); +- cp->sync_timeout = cpu_to_le16(qos->bcast.sync_timeout); +- cp->sync_cte_type = qos->bcast.sync_cte_type; ++ cp.options = qos->bcast.options; ++ cp.sid = conn->sid; ++ cp.addr_type = conn->dst_type; ++ bacpy(&cp.addr, &conn->dst); ++ cp.skip = cpu_to_le16(qos->bcast.skip); ++ cp.sync_timeout = cpu_to_le16(qos->bcast.sync_timeout); ++ cp.sync_cte_type = qos->bcast.sync_cte_type; + + break; + } +@@ -2131,17 +2125,15 @@ static int create_pa_sync(struct hci_dev *hdev, void *data) + + hci_dev_unlock(hdev); + +- if (cp) { ++ if (bacmp(&cp.addr, BDADDR_ANY)) { + hci_dev_set_flag(hdev, HCI_PA_SYNC); + set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); + + err = __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC, +- sizeof(*cp), cp, HCI_CMD_TIMEOUT); ++ sizeof(cp), &cp, HCI_CMD_TIMEOUT); + if (!err) + err = hci_update_passive_scan_sync(hdev); + +- kfree(cp); +- + if (err) { + hci_dev_clear_flag(hdev, HCI_PA_SYNC); + clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); +-- +2.39.5 + diff --git a/queue-6.12/bluetooth-l2cap-copy-rx-timestamp-to-new-fragments.patch b/queue-6.12/bluetooth-l2cap-copy-rx-timestamp-to-new-fragments.patch new file mode 100644 index 0000000000..ec35695ae8 --- /dev/null +++ b/queue-6.12/bluetooth-l2cap-copy-rx-timestamp-to-new-fragments.patch @@ -0,0 +1,37 @@ +From 8f7e0eae2b18aaf962c86e011549b428a83589f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 22:51:03 +0300 +Subject: Bluetooth: L2CAP: copy RX timestamp to new fragments + +From: Pauli Virtanen + +[ Upstream commit 3908feb1bd7f319a10e18d84369a48163264cc7d ] + +Copy timestamp too when allocating new skb for received fragment. +Fixes missing RX timestamps with fragmentation. + +Fixes: 4d7ea8ee90e4 ("Bluetooth: L2CAP: Fix handling fragmented length") +Signed-off-by: Pauli Virtanen +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index a55388fbf07c8..c219a8c596d3e 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -7380,6 +7380,9 @@ static int l2cap_recv_frag(struct l2cap_conn *conn, struct sk_buff *skb, + return -ENOMEM; + /* Init rx_len */ + conn->rx_len = len; ++ ++ skb_set_delivery_time(conn->rx_skb, skb->tstamp, ++ skb->tstamp_type); + } + + /* Copy as much as the rx_skb can hold */ +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-add-missing-skb_mark_for_recycle-in-bnxt_rx_.patch b/queue-6.12/bnxt_en-add-missing-skb_mark_for_recycle-in-bnxt_rx_.patch new file mode 100644 index 0000000000..75a07db855 --- /dev/null +++ b/queue-6.12/bnxt_en-add-missing-skb_mark_for_recycle-in-bnxt_rx_.patch @@ -0,0 +1,43 @@ +From 076f93ea26b66d62e717472655cd05ed312da696 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:58:58 -0700 +Subject: bnxt_en: Add missing skb_mark_for_recycle() in bnxt_rx_vlan() + +From: Somnath Kotur + +[ Upstream commit a63db07e4ecd45b027718168faf7d798bb47bf58 ] + +If bnxt_rx_vlan() fails because the VLAN protocol ID is invalid, +the SKB is freed but we're missing the call to recycle it. This +may cause the warning: + +"page_pool_release_retry() stalled pool shutdown" + +Add the missing skb_mark_for_recycle() in bnxt_rx_vlan(). + +Fixes: 86b05508f775 ("bnxt_en: Use the unified RX page pool buffers for XDP and non-XDP") +Reviewed-by: Kalesh AP +Reviewed-by: Pavan Chebbi +Signed-off-by: Somnath Kotur +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 026f0d7569e1c..74be0dd6f7a53 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -1986,6 +1986,7 @@ static struct sk_buff *bnxt_rx_vlan(struct sk_buff *skb, u8 cmp_type, + } + return skb; + vlan_err: ++ skb_mark_for_recycle(skb); + dev_kfree_skb(skb); + return NULL; + } +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-call-pci_alloc_irq_vectors-after-bnxt_reserv.patch b/queue-6.12/bnxt_en-call-pci_alloc_irq_vectors-after-bnxt_reserv.patch new file mode 100644 index 0000000000..71ce424fdf --- /dev/null +++ b/queue-6.12/bnxt_en-call-pci_alloc_irq_vectors-after-bnxt_reserv.patch @@ -0,0 +1,51 @@ +From 7fbe850705255375499fc7ac26121a674ea7d0c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:58:59 -0700 +Subject: bnxt_en: call pci_alloc_irq_vectors() after bnxt_reserve_rings() + +From: Kashyap Desai + +[ Upstream commit 1ae04e489dd757e1e61999362f33e7c554c3b9e3 ] + +On some architectures (e.g. ARM), calling pci_alloc_irq_vectors() +will immediately cause the MSIX table to be written. This will not +work if we haven't called bnxt_reserve_rings() to properly map +the MSIX table to the MSIX vectors reserved by FW. + +Fix the FW error recovery path to delay the bnxt_init_int_mode() -> +pci_alloc_irq_vectors() call by removing it from bnxt_hwrm_if_change(). +bnxt_request_irq() later in the code path will call it and by then the +MSIX table is properly mapped. + +Fixes: 4343838ca5eb ("bnxt_en: Replace deprecated PCI MSIX APIs") +Suggested-by: Michael Chan +Signed-off-by: Kashyap Desai +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 74be0dd6f7a53..e4d5bd30cf319 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -11851,13 +11851,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up) + set_bit(BNXT_STATE_ABORT_ERR, &bp->state); + return rc; + } ++ /* IRQ will be initialized later in bnxt_request_irq()*/ + bnxt_clear_int_mode(bp); +- rc = bnxt_init_int_mode(bp); +- if (rc) { +- clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state); +- netdev_err(bp->dev, "init int mode failed\n"); +- return rc; +- } + } + rc = bnxt_cancel_reservations(bp, fw_reset); + } +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-fix-coredump-logic-to-free-allocated-buffer.patch b/queue-6.12/bnxt_en-fix-coredump-logic-to-free-allocated-buffer.patch new file mode 100644 index 0000000000..4e5be440d5 --- /dev/null +++ b/queue-6.12/bnxt_en-fix-coredump-logic-to-free-allocated-buffer.patch @@ -0,0 +1,48 @@ +From 7b76abada55ff20e9798321f77db6d1bcb9df642 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:59:01 -0700 +Subject: bnxt_en: Fix coredump logic to free allocated buffer + +From: Shruti Parab + +[ Upstream commit ea9376cf68230e05492f22ca45d329f16e262c7b ] + +When handling HWRM_DBG_COREDUMP_LIST FW command in +bnxt_hwrm_dbg_dma_data(), the allocated buffer info->dest_buf is +not freed in the error path. In the normal path, info->dest_buf +is assigned to coredump->data and it will eventually be freed after +the coredump is collected. + +Free info->dest_buf immediately inside bnxt_hwrm_dbg_dma_data() in +the error path. + +Fixes: c74751f4c392 ("bnxt_en: Return error if FW returns more data than dump length") +Reported-by: Michael Chan +Reviewed-by: Kalesh AP +Signed-off-by: Shruti Parab +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c +index 4e2b938ed1f7e..651d3b1d153e0 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c +@@ -72,6 +72,11 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg, + memcpy(info->dest_buf + off, dma_buf, len); + } else { + rc = -ENOBUFS; ++ if (cmn_req->req_type == ++ cpu_to_le16(HWRM_DBG_COREDUMP_LIST)) { ++ kfree(info->dest_buf); ++ info->dest_buf = NULL; ++ } + break; + } + } +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-fix-error-handling-path-in-bnxt_init_chip.patch b/queue-6.12/bnxt_en-fix-error-handling-path-in-bnxt_init_chip.patch new file mode 100644 index 0000000000..f0ce5ccbe6 --- /dev/null +++ b/queue-6.12/bnxt_en-fix-error-handling-path-in-bnxt_init_chip.patch @@ -0,0 +1,50 @@ +From 5a3c2f73b3e6cca58c66a28aa92e2d7ea0e2a4a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:58:56 -0700 +Subject: bnxt_en: Fix error handling path in bnxt_init_chip() + +From: Shravya KN + +[ Upstream commit 9ab7a709c926c16b4433cf02d04fcbcf35aaab2b ] + +WARN_ON() is triggered in __flush_work() if bnxt_init_chip() fails +because we call cancel_work_sync() on dim work that has not been +initialized. + +WARNING: CPU: 37 PID: 5223 at kernel/workqueue.c:4201 __flush_work.isra.0+0x212/0x230 + +The driver relies on the BNXT_STATE_NAPI_DISABLED bit to check if dim +work has already been cancelled. But in the bnxt_open() path, +BNXT_STATE_NAPI_DISABLED is not set and this causes the error +path to think that it needs to cancel the uninitalized dim work. +Fix it by setting BNXT_STATE_NAPI_DISABLED during initialization. +The bit will be cleared when we enable NAPI and initialize dim work. + +Fixes: 40452969a506 ("bnxt_en: Fix DIM shutdown") +Suggested-by: Somnath Kotur +Reviewed-by: Somnath Kotur +Signed-off-by: Shravya KN +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 874a15f33bc5b..026f0d7569e1c 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -11079,6 +11079,9 @@ static void bnxt_init_napi(struct bnxt *bp) + poll_fn = bnxt_poll_p5; + else if (BNXT_CHIP_TYPE_NITRO_A0(bp)) + cp_nr_rings--; ++ ++ set_bit(BNXT_STATE_NAPI_DISABLED, &bp->state); ++ + for (i = 0; i < cp_nr_rings; i++) { + bnapi = bp->bnapi[i]; + netif_napi_add(bp->dev, &bnapi->napi, poll_fn); +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-fix-ethtool-d-byte-order-for-32-bit-values.patch b/queue-6.12/bnxt_en-fix-ethtool-d-byte-order-for-32-bit-values.patch new file mode 100644 index 0000000000..ba1ccdf9f2 --- /dev/null +++ b/queue-6.12/bnxt_en-fix-ethtool-d-byte-order-for-32-bit-values.patch @@ -0,0 +1,85 @@ +From d6a98b7f1a804d278add66eb7362885f641fadbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:59:03 -0700 +Subject: bnxt_en: Fix ethtool -d byte order for 32-bit values + +From: Michael Chan + +[ Upstream commit 02e8be5a032cae0f4ca33c6053c44d83cf4acc93 ] + +For version 1 register dump that includes the PCIe stats, the existing +code incorrectly assumes that all PCIe stats are 64-bit values. Fix it +by using an array containing the starting and ending index of the 32-bit +values. The loop in bnxt_get_regs() will use the array to do proper +endian swap for the 32-bit values. + +Fixes: b5d600b027eb ("bnxt_en: Add support for 'ethtool -d'") +Reviewed-by: Shruti Parab +Reviewed-by: Kalesh AP +Reviewed-by: Andy Gospodarek +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 38 ++++++++++++++++--- + 1 file changed, 32 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +index 36da52c0b9af6..54ae90526d8ff 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -2041,6 +2041,17 @@ static int bnxt_get_regs_len(struct net_device *dev) + return reg_len; + } + ++#define BNXT_PCIE_32B_ENTRY(start, end) \ ++ { offsetof(struct pcie_ctx_hw_stats, start), \ ++ offsetof(struct pcie_ctx_hw_stats, end) } ++ ++static const struct { ++ u16 start; ++ u16 end; ++} bnxt_pcie_32b_entries[] = { ++ BNXT_PCIE_32B_ENTRY(pcie_ltssm_histogram[0], pcie_ltssm_histogram[3]), ++}; ++ + static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *_p) + { +@@ -2072,12 +2083,27 @@ static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs, + req->pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr); + rc = hwrm_req_send(bp, req); + if (!rc) { +- __le64 *src = (__le64 *)hw_pcie_stats; +- u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN); +- int i; +- +- for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++) +- dst[i] = le64_to_cpu(src[i]); ++ u8 *dst = (u8 *)(_p + BNXT_PXP_REG_LEN); ++ u8 *src = (u8 *)hw_pcie_stats; ++ int i, j; ++ ++ for (i = 0, j = 0; i < sizeof(*hw_pcie_stats); ) { ++ if (i >= bnxt_pcie_32b_entries[j].start && ++ i <= bnxt_pcie_32b_entries[j].end) { ++ u32 *dst32 = (u32 *)(dst + i); ++ ++ *dst32 = le32_to_cpu(*(__le32 *)(src + i)); ++ i += 4; ++ if (i > bnxt_pcie_32b_entries[j].end && ++ j < ARRAY_SIZE(bnxt_pcie_32b_entries) - 1) ++ j++; ++ } else { ++ u64 *dst64 = (u64 *)(dst + i); ++ ++ *dst64 = le64_to_cpu(*(__le64 *)(src + i)); ++ i += 8; ++ } ++ } + } + hwrm_req_drop(bp, req); + } +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-fix-ethtool-selftest-output-in-one-of-the-fa.patch b/queue-6.12/bnxt_en-fix-ethtool-selftest-output-in-one-of-the-fa.patch new file mode 100644 index 0000000000..d473a3b2de --- /dev/null +++ b/queue-6.12/bnxt_en-fix-ethtool-selftest-output-in-one-of-the-fa.patch @@ -0,0 +1,49 @@ +From e5506718ea8ddf120d43ce2f34f669a6daf251d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:58:57 -0700 +Subject: bnxt_en: Fix ethtool selftest output in one of the failure cases + +From: Kalesh AP + +[ Upstream commit 8e6cc9045380f3f0c48ebda2bda5e1abe263388d ] + +When RDMA driver is loaded, running offline self test is not +supported and driver returns failure early. But it is not clearing +the input buffer and hence the application prints some junk +characters for individual test results. + +Fix it by clearing the buffer before returning. + +Fixes: 895621f1c816 ("bnxt_en: Don't support offline self test when RoCE driver is loaded") +Reviewed-by: Somnath Kotur +Signed-off-by: Kalesh AP +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +index b901ecb57f255..36da52c0b9af6 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -4848,6 +4848,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, + if (!bp->num_tests || !BNXT_PF(bp)) + return; + ++ memset(buf, 0, sizeof(u64) * bp->num_tests); + if (etest->flags & ETH_TEST_FL_OFFLINE && + bnxt_ulp_registered(bp->edev)) { + etest->flags |= ETH_TEST_FL_FAILED; +@@ -4855,7 +4856,6 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, + return; + } + +- memset(buf, 0, sizeof(u64) * bp->num_tests); + if (!netif_running(dev)) { + etest->flags |= ETH_TEST_FL_FAILED; + return; +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-fix-module-unload-sequence.patch b/queue-6.12/bnxt_en-fix-module-unload-sequence.patch new file mode 100644 index 0000000000..7065414bff --- /dev/null +++ b/queue-6.12/bnxt_en-fix-module-unload-sequence.patch @@ -0,0 +1,48 @@ +From be7742bf01a05add4c71256c211f53f777b507ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 10:03:43 -0700 +Subject: bnxt_en: fix module unload sequence + +From: Vadim Fedorenko + +[ Upstream commit 927069d5c40c1cfa7b2d13cfc6d7d58bc6f85c50 ] + +Recent updates to the PTP part of bnxt changed the way PTP FIFO is +cleared, skbs waiting for TX timestamps are now cleared during +ndo_close() call. To do clearing procedure, the ptp structure must +exist and point to a valid address. Module destroy sequence had ptp +clear code running before netdev close causing invalid memory access and +kernel crash. Change the sequence to destroy ptp structure after device +close. + +Fixes: 8f7ae5a85137 ("bnxt_en: improve TX timestamping FIFO configuration") +Reported-by: Taehee Yoo +Closes: https://lore.kernel.org/netdev/CAMArcTWDe2cd41=ub=zzvYifaYcYv-N-csxfqxUvejy_L0D6UQ@mail.gmail.com/ +Signed-off-by: Vadim Fedorenko +Reviewed-by: Jacob Keller +Reviewed-by: Michael Chan +Tested-by: Taehee Yoo +Link: https://patch.msgid.link/20250430170343.759126-1-vadfed@meta.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index e4d5bd30cf319..12b61a6fcda42 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -15421,8 +15421,8 @@ static void bnxt_remove_one(struct pci_dev *pdev) + + bnxt_rdma_aux_device_del(bp); + +- bnxt_ptp_clear(bp); + unregister_netdev(dev); ++ bnxt_ptp_clear(bp); + + bnxt_rdma_aux_device_uninit(bp); + +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-fix-out-of-bound-memcpy-during-ethtool-w.patch b/queue-6.12/bnxt_en-fix-out-of-bound-memcpy-during-ethtool-w.patch new file mode 100644 index 0000000000..7f1a9683e7 --- /dev/null +++ b/queue-6.12/bnxt_en-fix-out-of-bound-memcpy-during-ethtool-w.patch @@ -0,0 +1,95 @@ +From 50e6778993cc893eff708c3d4a657b7ecce9f01c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 15:59:02 -0700 +Subject: bnxt_en: Fix out-of-bound memcpy() during ethtool -w + +From: Shruti Parab + +[ Upstream commit 6b87bd94f34370bbf1dfa59352bed8efab5bf419 ] + +When retrieving the FW coredump using ethtool, it can sometimes cause +memory corruption: + +BUG: KFENCE: memory corruption in __bnxt_get_coredump+0x3ef/0x670 [bnxt_en] +Corrupted memory at 0x000000008f0f30e8 [ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] (in kfence-#45): +__bnxt_get_coredump+0x3ef/0x670 [bnxt_en] +ethtool_get_dump_data+0xdc/0x1a0 +__dev_ethtool+0xa1e/0x1af0 +dev_ethtool+0xa8/0x170 +dev_ioctl+0x1b5/0x580 +sock_do_ioctl+0xab/0xf0 +sock_ioctl+0x1ce/0x2e0 +__x64_sys_ioctl+0x87/0xc0 +do_syscall_64+0x5c/0xf0 +entry_SYSCALL_64_after_hwframe+0x78/0x80 + +... + +This happens when copying the coredump segment list in +bnxt_hwrm_dbg_dma_data() with the HWRM_DBG_COREDUMP_LIST FW command. +The info->dest_buf buffer is allocated based on the number of coredump +segments returned by the FW. The segment list is then DMA'ed by +the FW and the length of the DMA is returned by FW. The driver then +copies this DMA'ed segment list to info->dest_buf. + +In some cases, this DMA length may exceed the info->dest_buf length +and cause the above BUG condition. Fix it by capping the copy +length to not exceed the length of info->dest_buf. The extra +DMA data contains no useful information. + +This code path is shared for the HWRM_DBG_COREDUMP_LIST and the +HWRM_DBG_COREDUMP_RETRIEVE FW commands. The buffering is different +for these 2 FW commands. To simplify the logic, we need to move +the line to adjust the buffer length for HWRM_DBG_COREDUMP_RETRIEVE +up, so that the new check to cap the copy length will work for both +commands. + +Fixes: c74751f4c392 ("bnxt_en: Return error if FW returns more data than dump length") +Reviewed-by: Kalesh AP +Signed-off-by: Shruti Parab +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../net/ethernet/broadcom/bnxt/bnxt_coredump.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c +index 651d3b1d153e0..d80ce437435f0 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c +@@ -66,10 +66,19 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg, + } + } + ++ if (cmn_req->req_type == ++ cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE)) ++ info->dest_buf_size += len; ++ + if (info->dest_buf) { + if ((info->seg_start + off + len) <= + BNXT_COREDUMP_BUF_LEN(info->buf_len)) { +- memcpy(info->dest_buf + off, dma_buf, len); ++ u16 copylen = min_t(u16, len, ++ info->dest_buf_size - off); ++ ++ memcpy(info->dest_buf + off, dma_buf, copylen); ++ if (copylen < len) ++ break; + } else { + rc = -ENOBUFS; + if (cmn_req->req_type == +@@ -81,10 +90,6 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg, + } + } + +- if (cmn_req->req_type == +- cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE)) +- info->dest_buf_size += len; +- + if (!(cmn_resp->flags & HWRM_DBG_CMN_FLAGS_MORE)) + break; + +-- +2.39.5 + diff --git a/queue-6.12/bnxt_en-improve-tx-timestamping-fifo-configuration.patch b/queue-6.12/bnxt_en-improve-tx-timestamping-fifo-configuration.patch new file mode 100644 index 0000000000..ecb06c1bba --- /dev/null +++ b/queue-6.12/bnxt_en-improve-tx-timestamping-fifo-configuration.patch @@ -0,0 +1,121 @@ +From 493b0c038f938fd4ea0bb105722598c6e22db09b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 05:55:47 -0700 +Subject: bnxt_en: improve TX timestamping FIFO configuration + +From: Vadim Fedorenko + +[ Upstream commit 8f7ae5a85137b913cb97e2d24409d36548d0bab1 ] + +Reconfiguration of netdev may trigger close/open procedure which can +break FIFO status by adjusting the amount of empty slots for TX +timestamps. But it is not really needed because timestamps for the +packets sent over the wire still can be retrieved. On the other side, +during netdev close procedure any skbs waiting for TX timestamps can be +leaked because there is no cleaning procedure called. Free skbs waiting +for TX timestamps when closing netdev. + +Fixes: 8aa2a79e9b95 ("bnxt_en: Increase the max total outstanding PTP TX packets to 4") +Reviewed-by: Michael Chan +Reviewed-by: Pavan Chebbi +Signed-off-by: Vadim Fedorenko +Link: https://patch.msgid.link/20250424125547.460632-1-vadfed@meta.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 ++-- + drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 29 ++++++++++++++----- + drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h | 1 + + 3 files changed, 25 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 016dcfec8d496..874a15f33bc5b 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -3320,6 +3320,9 @@ static void bnxt_free_tx_skbs(struct bnxt *bp) + } + netdev_tx_reset_queue(netdev_get_tx_queue(bp->dev, i)); + } ++ ++ if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP)) ++ bnxt_ptp_free_txts_skbs(bp->ptp_cfg); + } + + static void bnxt_free_one_rx_ring(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) +@@ -12249,8 +12252,6 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) + /* VF-reps may need to be re-opened after the PF is re-opened */ + if (BNXT_PF(bp)) + bnxt_vf_reps_open(bp); +- if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP)) +- WRITE_ONCE(bp->ptp_cfg->tx_avail, BNXT_MAX_TX_TS); + bnxt_ptp_init_rtc(bp, true); + bnxt_ptp_cfg_tstamp_filters(bp); + if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +index 781225d3ba8ff..650034a4bb46d 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +@@ -777,6 +777,27 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) + return HZ; + } + ++void bnxt_ptp_free_txts_skbs(struct bnxt_ptp_cfg *ptp) ++{ ++ struct bnxt_ptp_tx_req *txts_req; ++ u16 cons = ptp->txts_cons; ++ ++ /* make sure ptp aux worker finished with ++ * possible BNXT_STATE_OPEN set ++ */ ++ ptp_cancel_worker_sync(ptp->ptp_clock); ++ ++ ptp->tx_avail = BNXT_MAX_TX_TS; ++ while (cons != ptp->txts_prod) { ++ txts_req = &ptp->txts_req[cons]; ++ if (!IS_ERR_OR_NULL(txts_req->tx_skb)) ++ dev_kfree_skb_any(txts_req->tx_skb); ++ cons = NEXT_TXTS(cons); ++ } ++ ptp->txts_cons = cons; ++ ptp_schedule_worker(ptp->ptp_clock, 0); ++} ++ + int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod) + { + spin_lock_bh(&ptp->ptp_tx_lock); +@@ -1095,7 +1116,6 @@ int bnxt_ptp_init(struct bnxt *bp) + void bnxt_ptp_clear(struct bnxt *bp) + { + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; +- int i; + + if (!ptp) + return; +@@ -1107,12 +1127,5 @@ void bnxt_ptp_clear(struct bnxt *bp) + kfree(ptp->ptp_info.pin_config); + ptp->ptp_info.pin_config = NULL; + +- for (i = 0; i < BNXT_MAX_TX_TS; i++) { +- if (ptp->txts_req[i].tx_skb) { +- dev_kfree_skb_any(ptp->txts_req[i].tx_skb); +- ptp->txts_req[i].tx_skb = NULL; +- } +- } +- + bnxt_unmap_ptp_regs(bp); + } +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h +index 61e89bb2d2690..999b497990bce 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h +@@ -174,6 +174,7 @@ int bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp); + void bnxt_ptp_reapply_pps(struct bnxt *bp); + int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr); + int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr); ++void bnxt_ptp_free_txts_skbs(struct bnxt_ptp_cfg *ptp); + int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod); + void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod); + int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts); +-- +2.39.5 + diff --git a/queue-6.12/book3s64-radix-align-section-vmemmap-start-address-t.patch b/queue-6.12/book3s64-radix-align-section-vmemmap-start-address-t.patch new file mode 100644 index 0000000000..c0138cd89b --- /dev/null +++ b/queue-6.12/book3s64-radix-align-section-vmemmap-start-address-t.patch @@ -0,0 +1,160 @@ +From 74e6e823f5cb5268c68249cbee572b2db539d4e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 07:44:10 -0500 +Subject: book3s64/radix : Align section vmemmap start address to PAGE_SIZE + +From: Donet Tom + +[ Upstream commit 9cf7e13fecbab0894f6986fc6986ab2eba8de52e ] + +A vmemmap altmap is a device-provided region used to provide +backing storage for struct pages. For each namespace, the altmap +should belong to that same namespace. If the namespaces are +created unaligned, there is a chance that the section vmemmap +start address could also be unaligned. If the section vmemmap +start address is unaligned, the altmap page allocated from the +current namespace might be used by the previous namespace also. +During the free operation, since the altmap is shared between two +namespaces, the previous namespace may detect that the page does +not belong to its altmap and incorrectly assume that the page is a +normal page. It then attempts to free the normal page, which leads +to a kernel crash. + +Kernel attempted to read user page (18) - exploit attempt? (uid: 0) +BUG: Kernel NULL pointer dereference on read at 0x00000018 +Faulting instruction address: 0xc000000000530c7c +Oops: Kernel access of bad area, sig: 11 [#1] +LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries +CPU: 32 PID: 2104 Comm: ndctl Kdump: loaded Tainted: G W +NIP: c000000000530c7c LR: c000000000530e00 CTR: 0000000000007ffe +REGS: c000000015e57040 TRAP: 0300 Tainted: G W +MSR: 800000000280b033 CR: 84482404 +CFAR: c000000000530dfc DAR: 0000000000000018 DSISR: 40000000 IRQMASK: 0 +GPR00: c000000000530e00 c000000015e572e0 c000000002c5cb00 c00c000101008040 +GPR04: 0000000000000000 0000000000000007 0000000000000001 000000000000001f +GPR08: 0000000000000005 0000000000000000 0000000000000018 0000000000002000 +GPR12: c0000000001d2fb0 c0000060de6b0080 0000000000000000 c0000060dbf90020 +GPR16: c00c000101008000 0000000000000001 0000000000000000 c000000125b20f00 +GPR20: 0000000000000001 0000000000000000 ffffffffffffffff c00c000101007fff +GPR24: 0000000000000001 0000000000000000 0000000000000000 0000000000000000 +GPR28: 0000000004040201 0000000000000001 0000000000000000 c00c000101008040 +NIP [c000000000530c7c] get_pfnblock_flags_mask+0x7c/0xd0 +LR [c000000000530e00] free_unref_page_prepare+0x130/0x4f0 +Call Trace: +free_unref_page+0x50/0x1e0 +free_reserved_page+0x40/0x68 +free_vmemmap_pages+0x98/0xe0 +remove_pte_table+0x164/0x1e8 +remove_pmd_table+0x204/0x2c8 +remove_pud_table+0x1c4/0x288 +remove_pagetable+0x1c8/0x310 +vmemmap_free+0x24/0x50 +section_deactivate+0x28c/0x2a0 +__remove_pages+0x84/0x110 +arch_remove_memory+0x38/0x60 +memunmap_pages+0x18c/0x3d0 +devm_action_release+0x30/0x50 +release_nodes+0x68/0x140 +devres_release_group+0x100/0x190 +dax_pmem_compat_release+0x44/0x80 [dax_pmem_compat] +device_for_each_child+0x8c/0x100 +[dax_pmem_compat_remove+0x2c/0x50 [dax_pmem_compat] +nvdimm_bus_remove+0x78/0x140 [libnvdimm] +device_remove+0x70/0xd0 + +Another issue is that if there is no altmap, a PMD-sized vmemmap +page will be allocated from RAM, regardless of the alignment of +the section start address. If the section start address is not +aligned to the PMD size, a VM_BUG_ON will be triggered when +setting the PMD-sized page to page table. + +In this patch, we are aligning the section vmemmap start address +to PAGE_SIZE. After alignment, the start address will not be +part of the current namespace, and a normal page will be allocated +for the vmemmap mapping of the current section. For the remaining +sections, altmaps will be allocated. During the free operation, +the normal page will be correctly freed. + +In the same way, a PMD_SIZE vmemmap page will be allocated only if +the section start address is PMD_SIZE-aligned; otherwise, it will +fall back to a PAGE-sized vmemmap allocation. + +Without this patch +================== +NS1 start NS2 start + _________________________________________________________ +| NS1 | NS2 | + --------------------------------------------------------- +| Altmap| Altmap | .....|Altmap| Altmap | ........... +| NS1 | NS1 | | NS2 | NS2 | + +In the above scenario, NS1 and NS2 are two namespaces. The vmemmap +for NS1 comes from Altmap NS1, which belongs to NS1, and the +vmemmap for NS2 comes from Altmap NS2, which belongs to NS2. + +The vmemmap start for NS2 is not aligned, so Altmap NS2 is shared +by both NS1 and NS2. During the free operation in NS1, Altmap NS2 +is not part of NS1's altmap, causing it to attempt to free an +invalid page. + +With this patch +=============== +NS1 start NS2 start + _________________________________________________________ +| NS1 | NS2 | + --------------------------------------------------------- +| Altmap| Altmap | .....| Normal | Altmap | Altmap |....... +| NS1 | NS1 | | Page | NS2 | NS2 | + +If the vmemmap start for NS2 is not aligned then we are allocating +a normal page. NS1 and NS2 vmemmap will be freed correctly. + +Fixes: 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use a different vmemmap handling function") +Co-developed-by: Ritesh Harjani (IBM) +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Donet Tom +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/8f98ec2b442977c618f7256cec88eb17dde3f2b9.1741609795.git.donettom@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/book3s64/radix_pgtable.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c +index b0d927009af83..04189689c127e 100644 +--- a/arch/powerpc/mm/book3s64/radix_pgtable.c ++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c +@@ -1132,6 +1132,19 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in + pmd_t *pmd; + pte_t *pte; + ++ /* ++ * Make sure we align the start vmemmap addr so that we calculate ++ * the correct start_pfn in altmap boundary check to decided whether ++ * we should use altmap or RAM based backing memory allocation. Also ++ * the address need to be aligned for set_pte operation. ++ ++ * If the start addr is already PMD_SIZE aligned we will try to use ++ * a pmd mapping. We don't want to be too aggressive here beacause ++ * that will cause more allocations in RAM. So only if the namespace ++ * vmemmap start addr is PMD_SIZE aligned we will use PMD mapping. ++ */ ++ ++ start = ALIGN_DOWN(start, PAGE_SIZE); + for (addr = start; addr < end; addr = next) { + next = pmd_addr_end(addr, end); + +@@ -1157,8 +1170,8 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in + * in altmap block allocation failures, in which case + * we fallback to RAM for vmemmap allocation. + */ +- if (altmap && (!IS_ALIGNED(addr, PMD_SIZE) || +- altmap_cross_boundary(altmap, addr, PMD_SIZE))) { ++ if (!IS_ALIGNED(addr, PMD_SIZE) || (altmap && ++ altmap_cross_boundary(altmap, addr, PMD_SIZE))) { + /* + * make sure we don't create altmap mappings + * covering things outside the device. +-- +2.39.5 + diff --git a/queue-6.12/drm-i915-pxp-fix-undefined-reference-to-intel_pxp_gs.patch b/queue-6.12/drm-i915-pxp-fix-undefined-reference-to-intel_pxp_gs.patch new file mode 100644 index 0000000000..9eb9942eb0 --- /dev/null +++ b/queue-6.12/drm-i915-pxp-fix-undefined-reference-to-intel_pxp_gs.patch @@ -0,0 +1,67 @@ +From 17e624f42fc3f8e53a6b32837fed4741eb26cb28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Apr 2025 12:06:16 +0300 +Subject: drm/i915/pxp: fix undefined reference to + `intel_pxp_gsccs_is_ready_for_sessions' + +From: Chen Linxuan + +[ Upstream commit 7e21ea8149a0e41c3666ee52cc063a6f797a7a2a ] + +On x86_64 with gcc version 13.3.0, I compile kernel with: + + make defconfig + ./scripts/kconfig/merge_config.sh .config <( + echo CONFIG_COMPILE_TEST=y + ) + make KCFLAGS="-fno-inline-functions -fno-inline-small-functions -fno-inline-functions-called-once" + +Then I get a linker error: + + ld: vmlinux.o: in function `pxp_fw_dependencies_completed': + kintel_pxp.c:(.text+0x95728f): undefined reference to `intel_pxp_gsccs_is_ready_for_sessions' + +This is caused by not having a intel_pxp_gsccs_is_ready_for_sessions() +header stub for CONFIG_DRM_I915_PXP=n. Add it. + +Signed-off-by: Chen Linxuan +Fixes: 99afb7cc8c44 ("drm/i915/pxp: Add ARB session creation and cleanup") +Reviewed-by: Jani Nikula +Link: https://lore.kernel.org/r/20250415090616.2649889-1-jani.nikula@intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit b484c1e225a6a582fc78c4d7af7b286408bb7d41) +Signed-off-by: Jani Nikula +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h +index 9aae779c4da31..4969d3de2bac3 100644 +--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h ++++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h +@@ -23,6 +23,7 @@ int intel_pxp_gsccs_init(struct intel_pxp *pxp); + + int intel_pxp_gsccs_create_session(struct intel_pxp *pxp, int arb_session_id); + void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id); ++bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp); + + #else + static inline void intel_pxp_gsccs_fini(struct intel_pxp *pxp) +@@ -34,8 +35,11 @@ static inline int intel_pxp_gsccs_init(struct intel_pxp *pxp) + return 0; + } + +-#endif ++static inline bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp) ++{ ++ return false; ++} + +-bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp); ++#endif + + #endif /*__INTEL_PXP_GSCCS_H__ */ +-- +2.39.5 + diff --git a/queue-6.12/drm-mipi-dbi-fix-blanking-for-non-16-bit-formats.patch b/queue-6.12/drm-mipi-dbi-fix-blanking-for-non-16-bit-formats.patch new file mode 100644 index 0000000000..1fad959c7f --- /dev/null +++ b/queue-6.12/drm-mipi-dbi-fix-blanking-for-non-16-bit-formats.patch @@ -0,0 +1,53 @@ +From aa0b67b44f6bdd2c2b8eb0e089598c064196956f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Apr 2025 22:32:59 -0700 +Subject: drm/mipi-dbi: Fix blanking for non-16 bit formats + +From: Russell Cloran + +[ Upstream commit 1a8bc0fe8039e1e57f68c4a588f0403d98bfeb1f ] + +On r6x2b6x2g6x2 displays not enough blank data is sent to blank the +entire screen. When support for these displays was added, the dirty +function was updated to handle the different amount of data, but +blanking was not, and remained hardcoded as 2 bytes per pixel. + +This change applies almost the same algorithm used in the dirty function +to the blank function, but there is no fb available at that point, and +no concern about having to transform any data, so the dbidev pixel +format is always used for calculating the length. + +Fixes: 4aebb79021f3 ("drm/mipi-dbi: Add support for DRM_FORMAT_RGB888") +Signed-off-by: Russell Cloran +Link: https://lore.kernel.org/r/20250415053259.79572-1-rcloran@gmail.com +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_mipi_dbi.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c +index 34bca75675766..3ea9f23b4f67a 100644 +--- a/drivers/gpu/drm/drm_mipi_dbi.c ++++ b/drivers/gpu/drm/drm_mipi_dbi.c +@@ -404,12 +404,16 @@ static void mipi_dbi_blank(struct mipi_dbi_dev *dbidev) + u16 height = drm->mode_config.min_height; + u16 width = drm->mode_config.min_width; + struct mipi_dbi *dbi = &dbidev->dbi; +- size_t len = width * height * 2; ++ const struct drm_format_info *dst_format; ++ size_t len; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + ++ dst_format = drm_format_info(dbidev->pixel_format); ++ len = drm_format_info_min_pitch(dst_format, 0, width) * height; ++ + memset(dbidev->tx_buf, 0, len); + + mipi_dbi_set_window_address(dbidev, 0, width - 1, 0, height - 1); +-- +2.39.5 + diff --git a/queue-6.12/drm-tests-shmem-fix-memleak.patch b/queue-6.12/drm-tests-shmem-fix-memleak.patch new file mode 100644 index 0000000000..171d1c4c6c --- /dev/null +++ b/queue-6.12/drm-tests-shmem-fix-memleak.patch @@ -0,0 +1,45 @@ +From c929b1cba6c2837dff132f83cb7bdb581457094a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Apr 2025 16:07:58 +0200 +Subject: drm/tests: shmem: Fix memleak + +From: Maxime Ripard + +[ Upstream commit 48ccf21fa8dc595c8aa4f1d347b593dcae0727d0 ] + +The drm_gem_shmem_test_get_pages_sgt() gets a scatter-gather table using +the drm_gem_shmem_get_sg_table() function and rightfully calls +sg_free_table() on it. However, it's also supposed to kfree() the +returned sg_table, but doesn't. + +This leads to a memory leak, reported by kmemleak. Fix it by adding a +kunit action to kfree the sgt when the test ends. + +Reported-by: Philipp Stanner +Closes: https://lore.kernel.org/dri-devel/a7655158a6367ac46194d57f4b7433ef0772a73e.camel@mailbox.org/ +Fixes: 93032ae634d4 ("drm/test: add a test suite for GEM objects backed by shmem") +Reviewed-by: Javier Martinez Canillas +Link: https://lore.kernel.org/r/20250408140758.1831333-1-mripard@kernel.org +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/tests/drm_gem_shmem_test.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/tests/drm_gem_shmem_test.c b/drivers/gpu/drm/tests/drm_gem_shmem_test.c +index fd4215e2f982d..925fbc2cda700 100644 +--- a/drivers/gpu/drm/tests/drm_gem_shmem_test.c ++++ b/drivers/gpu/drm/tests/drm_gem_shmem_test.c +@@ -216,6 +216,9 @@ static void drm_gem_shmem_test_get_pages_sgt(struct kunit *test) + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt); + KUNIT_EXPECT_NULL(test, shmem->sgt); + ++ ret = kunit_add_action_or_reset(test, kfree_wrapper, sgt); ++ KUNIT_ASSERT_EQ(test, ret, 0); ++ + ret = kunit_add_action_or_reset(test, sg_free_table_wrapper, sgt); + KUNIT_ASSERT_EQ(test, ret, 0); + +-- +2.39.5 + diff --git a/queue-6.12/ice-check-vf-vsi-pointer-value-in-ice_vc_add_fdir_fl.patch b/queue-6.12/ice-check-vf-vsi-pointer-value-in-ice_vc_add_fdir_fl.patch new file mode 100644 index 0000000000..f6d62cf9de --- /dev/null +++ b/queue-6.12/ice-check-vf-vsi-pointer-value-in-ice_vc_add_fdir_fl.patch @@ -0,0 +1,44 @@ +From 602965aac5bf16363128fee28704d77c9338a112 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 15:26:32 -0700 +Subject: ice: Check VF VSI Pointer Value in ice_vc_add_fdir_fltr() + +From: Xuanqiang Luo + +[ Upstream commit 425c5f266b2edeee0ce16fedd8466410cdcfcfe3 ] + +As mentioned in the commit baeb705fd6a7 ("ice: always check VF VSI +pointer values"), we need to perform a null pointer check on the return +value of ice_get_vf_vsi() before using it. + +Fixes: 6ebbe97a4881 ("ice: Add a per-VF limit on number of FDIR filters") +Signed-off-by: Xuanqiang Luo +Reviewed-by: Przemek Kitszel +Reviewed-by: Simon Horman +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20250425222636.3188441-3-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +index 14e3f0f89c78d..ef755cee64ca9 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +@@ -2091,6 +2091,11 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) + pf = vf->pf; + dev = ice_pf_to_dev(pf); + vf_vsi = ice_get_vf_vsi(vf); ++ if (!vf_vsi) { ++ dev_err(dev, "Can not get FDIR vf_vsi for VF %u\n", vf->vf_id); ++ v_ret = VIRTCHNL_STATUS_ERR_PARAM; ++ goto err_exit; ++ } + + #define ICE_VF_MAX_FDIR_FILTERS 128 + if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) || +-- +2.39.5 + diff --git a/queue-6.12/idpf-fix-offloads-support-for-encapsulated-packets.patch b/queue-6.12/idpf-fix-offloads-support-for-encapsulated-packets.patch new file mode 100644 index 0000000000..89230fa959 --- /dev/null +++ b/queue-6.12/idpf-fix-offloads-support-for-encapsulated-packets.patch @@ -0,0 +1,162 @@ +From e4e4358f1704b4dfcff448dbfe609ea47e7f015e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 15:26:33 -0700 +Subject: idpf: fix offloads support for encapsulated packets + +From: Madhu Chittim + +[ Upstream commit 713dd6c2deca88cba0596b1e2576f7b7a8e5c59e ] + +Split offloads into csum, tso and other offloads so that tunneled +packets do not by default have all the offloads enabled. + +Stateless offloads for encapsulated packets are not yet supported in +firmware/software but in the driver we were setting the features same as +non encapsulated features. + +Fixed naming to clarify CSUM bits are being checked for Tx. + +Inherit netdev features to VLAN interfaces as well. + +Fixes: 0fe45467a104 ("idpf: add create vport and netdev configuration") +Reviewed-by: Sridhar Samudrala +Signed-off-by: Madhu Chittim +Tested-by: Zachary Goldstein +Tested-by: Samuel Salin +Signed-off-by: Tony Nguyen +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20250425222636.3188441-4-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/idpf/idpf.h | 18 +++---- + drivers/net/ethernet/intel/idpf/idpf_lib.c | 57 ++++++++-------------- + 2 files changed, 27 insertions(+), 48 deletions(-) + +diff --git a/drivers/net/ethernet/intel/idpf/idpf.h b/drivers/net/ethernet/intel/idpf/idpf.h +index 66544faab710a..aef0e9775a330 100644 +--- a/drivers/net/ethernet/intel/idpf/idpf.h ++++ b/drivers/net/ethernet/intel/idpf/idpf.h +@@ -629,13 +629,13 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all, + VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V4 |\ + VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V6) + +-#define IDPF_CAP_RX_CSUM_L4V4 (\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP |\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP) ++#define IDPF_CAP_TX_CSUM_L4V4 (\ ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP |\ ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP) + +-#define IDPF_CAP_RX_CSUM_L4V6 (\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP) ++#define IDPF_CAP_TX_CSUM_L4V6 (\ ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP |\ ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP) + + #define IDPF_CAP_RX_CSUM (\ + VIRTCHNL2_CAP_RX_CSUM_L3_IPV4 |\ +@@ -644,11 +644,9 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all, + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\ + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP) + +-#define IDPF_CAP_SCTP_CSUM (\ ++#define IDPF_CAP_TX_SCTP_CSUM (\ + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP |\ +- VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP |\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP |\ +- VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP) ++ VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP) + + #define IDPF_CAP_TUNNEL_TX_CSUM (\ + VIRTCHNL2_CAP_TX_CSUM_L3_SINGLE_TUNNEL |\ +diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c +index a3d6b8f198a86..1c345a0e885b7 100644 +--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c ++++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c +@@ -703,8 +703,10 @@ static int idpf_cfg_netdev(struct idpf_vport *vport) + { + struct idpf_adapter *adapter = vport->adapter; + struct idpf_vport_config *vport_config; ++ netdev_features_t other_offloads = 0; ++ netdev_features_t csum_offloads = 0; ++ netdev_features_t tso_offloads = 0; + netdev_features_t dflt_features; +- netdev_features_t offloads = 0; + struct idpf_netdev_priv *np; + struct net_device *netdev; + u16 idx = vport->idx; +@@ -766,53 +768,32 @@ static int idpf_cfg_netdev(struct idpf_vport *vport) + + if (idpf_is_cap_ena_all(adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS)) + dflt_features |= NETIF_F_RXHASH; +- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM_L4V4)) +- dflt_features |= NETIF_F_IP_CSUM; +- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM_L4V6)) +- dflt_features |= NETIF_F_IPV6_CSUM; ++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_CSUM_L4V4)) ++ csum_offloads |= NETIF_F_IP_CSUM; ++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_CSUM_L4V6)) ++ csum_offloads |= NETIF_F_IPV6_CSUM; + if (idpf_is_cap_ena(adapter, IDPF_CSUM_CAPS, IDPF_CAP_RX_CSUM)) +- dflt_features |= NETIF_F_RXCSUM; +- if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_SCTP_CSUM)) +- dflt_features |= NETIF_F_SCTP_CRC; ++ csum_offloads |= NETIF_F_RXCSUM; ++ if (idpf_is_cap_ena_all(adapter, IDPF_CSUM_CAPS, IDPF_CAP_TX_SCTP_CSUM)) ++ csum_offloads |= NETIF_F_SCTP_CRC; + + if (idpf_is_cap_ena(adapter, IDPF_SEG_CAPS, VIRTCHNL2_CAP_SEG_IPV4_TCP)) +- dflt_features |= NETIF_F_TSO; ++ tso_offloads |= NETIF_F_TSO; + if (idpf_is_cap_ena(adapter, IDPF_SEG_CAPS, VIRTCHNL2_CAP_SEG_IPV6_TCP)) +- dflt_features |= NETIF_F_TSO6; ++ tso_offloads |= NETIF_F_TSO6; + if (idpf_is_cap_ena_all(adapter, IDPF_SEG_CAPS, + VIRTCHNL2_CAP_SEG_IPV4_UDP | + VIRTCHNL2_CAP_SEG_IPV6_UDP)) +- dflt_features |= NETIF_F_GSO_UDP_L4; ++ tso_offloads |= NETIF_F_GSO_UDP_L4; + if (idpf_is_cap_ena_all(adapter, IDPF_RSC_CAPS, IDPF_CAP_RSC)) +- offloads |= NETIF_F_GRO_HW; +- /* advertise to stack only if offloads for encapsulated packets is +- * supported +- */ +- if (idpf_is_cap_ena(vport->adapter, IDPF_SEG_CAPS, +- VIRTCHNL2_CAP_SEG_TX_SINGLE_TUNNEL)) { +- offloads |= NETIF_F_GSO_UDP_TUNNEL | +- NETIF_F_GSO_GRE | +- NETIF_F_GSO_GRE_CSUM | +- NETIF_F_GSO_PARTIAL | +- NETIF_F_GSO_UDP_TUNNEL_CSUM | +- NETIF_F_GSO_IPXIP4 | +- NETIF_F_GSO_IPXIP6 | +- 0; +- +- if (!idpf_is_cap_ena_all(vport->adapter, IDPF_CSUM_CAPS, +- IDPF_CAP_TUNNEL_TX_CSUM)) +- netdev->gso_partial_features |= +- NETIF_F_GSO_UDP_TUNNEL_CSUM; +- +- netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM; +- offloads |= NETIF_F_TSO_MANGLEID; +- } ++ other_offloads |= NETIF_F_GRO_HW; + if (idpf_is_cap_ena(adapter, IDPF_OTHER_CAPS, VIRTCHNL2_CAP_LOOPBACK)) +- offloads |= NETIF_F_LOOPBACK; ++ other_offloads |= NETIF_F_LOOPBACK; + +- netdev->features |= dflt_features; +- netdev->hw_features |= dflt_features | offloads; +- netdev->hw_enc_features |= dflt_features | offloads; ++ netdev->features |= dflt_features | csum_offloads | tso_offloads; ++ netdev->hw_features |= netdev->features | other_offloads; ++ netdev->vlan_features |= netdev->features | other_offloads; ++ netdev->hw_enc_features |= dflt_features | other_offloads; + idpf_set_ethtool_ops(netdev); + SET_NETDEV_DEV(netdev, &adapter->pdev->dev); + +-- +2.39.5 + diff --git a/queue-6.12/idpf-fix-potential-memory-leak-on-kcalloc-failure.patch b/queue-6.12/idpf-fix-potential-memory-leak-on-kcalloc-failure.patch new file mode 100644 index 0000000000..b945a4779b --- /dev/null +++ b/queue-6.12/idpf-fix-potential-memory-leak-on-kcalloc-failure.patch @@ -0,0 +1,76 @@ +From 830dedf35dfeadceb7345c39b49d77cc27694bfb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Apr 2025 12:54:21 +0200 +Subject: idpf: fix potential memory leak on kcalloc() failure + +From: Michal Swiatkowski + +[ Upstream commit 8a558cbda51bef09773c72bf74a32047479110c7 ] + +In case of failing on rss_data->rss_key allocation the function is +freeing vport without freeing earlier allocated q_vector_idxs. Fix it. + +Move from freeing in error branch to goto scheme. + +Fixes: d4d558718266 ("idpf: initialize interrupts and enable vport") +Reviewed-by: Pavan Kumar Linga +Reviewed-by: Aleksandr Loktionov +Suggested-by: Pavan Kumar Linga +Signed-off-by: Michal Swiatkowski +Reviewed-by: Simon Horman +Tested-by: Samuel Salin +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/idpf/idpf_lib.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c +index 1c345a0e885b7..5ce663d04de00 100644 +--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c ++++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c +@@ -1108,11 +1108,9 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, + + num_max_q = max(max_q->max_txq, max_q->max_rxq); + vport->q_vector_idxs = kcalloc(num_max_q, sizeof(u16), GFP_KERNEL); +- if (!vport->q_vector_idxs) { +- kfree(vport); ++ if (!vport->q_vector_idxs) ++ goto free_vport; + +- return NULL; +- } + idpf_vport_init(vport, max_q); + + /* This alloc is done separate from the LUT because it's not strictly +@@ -1122,11 +1120,9 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, + */ + rss_data = &adapter->vport_config[idx]->user_config.rss_data; + rss_data->rss_key = kzalloc(rss_data->rss_key_size, GFP_KERNEL); +- if (!rss_data->rss_key) { +- kfree(vport); ++ if (!rss_data->rss_key) ++ goto free_vector_idxs; + +- return NULL; +- } + /* Initialize default rss key */ + netdev_rss_key_fill((void *)rss_data->rss_key, rss_data->rss_key_size); + +@@ -1139,6 +1135,13 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, + adapter->next_vport = idpf_get_free_slot(adapter); + + return vport; ++ ++free_vector_idxs: ++ kfree(vport->q_vector_idxs); ++free_vport: ++ kfree(vport); ++ ++ return NULL; + } + + /** +-- +2.39.5 + diff --git a/queue-6.12/idpf-protect-shutdown-from-reset.patch b/queue-6.12/idpf-protect-shutdown-from-reset.patch new file mode 100644 index 0000000000..9f0c4b8cbe --- /dev/null +++ b/queue-6.12/idpf-protect-shutdown-from-reset.patch @@ -0,0 +1,53 @@ +From 4611949deff10a9f627e0a0406d19a9f8e0bdaf5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Apr 2025 13:52:23 +0200 +Subject: idpf: protect shutdown from reset + +From: Larysa Zaremba + +[ Upstream commit ed375b182140eeb9c73609b17939c8a29b27489e ] + +Before the referenced commit, the shutdown just called idpf_remove(), +this way IDPF_REMOVE_IN_PROG was protecting us from the serv_task +rescheduling reset. Without this flag set the shutdown process is +vulnerable to HW reset or any other triggering conditions (such as +default mailbox being destroyed). + +When one of conditions checked in idpf_service_task becomes true, +vc_event_task can be rescheduled during shutdown, this leads to accessing +freed memory e.g. idpf_req_rel_vector_indexes() trying to read +vport->q_vector_idxs. This in turn causes the system to become defunct +during e.g. systemctl kexec. + +Considering using IDPF_REMOVE_IN_PROG would lead to more heavy shutdown +process, instead just cancel the serv_task before cancelling +adapter->serv_task before cancelling adapter->vc_event_task to ensure that +reset will not be scheduled while we are doing a shutdown. + +Fixes: 4c9106f4906a ("idpf: fix adapter NULL pointer dereference on reboot") +Reviewed-by: Michal Swiatkowski +Signed-off-by: Larysa Zaremba +Reviewed-by: Simon Horman +Reviewed-by: Emil Tantilov +Tested-by: Samuel Salin +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/idpf/idpf_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c +index 7557bb6694c09..734da1680c5a4 100644 +--- a/drivers/net/ethernet/intel/idpf/idpf_main.c ++++ b/drivers/net/ethernet/intel/idpf/idpf_main.c +@@ -89,6 +89,7 @@ static void idpf_shutdown(struct pci_dev *pdev) + { + struct idpf_adapter *adapter = pci_get_drvdata(pdev); + ++ cancel_delayed_work_sync(&adapter->serv_task); + cancel_delayed_work_sync(&adapter->vc_event_task); + idpf_vc_core_deinit(adapter); + idpf_deinit_dflt_mbx(adapter); +-- +2.39.5 + diff --git a/queue-6.12/igc-fix-lock-order-in-igc_ptp_reset.patch b/queue-6.12/igc-fix-lock-order-in-igc_ptp_reset.patch new file mode 100644 index 0000000000..74f330ae48 --- /dev/null +++ b/queue-6.12/igc-fix-lock-order-in-igc_ptp_reset.patch @@ -0,0 +1,82 @@ +From 5e882226ae385f8090faf75ae74055f188c9b463 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Apr 2025 14:03:09 -0700 +Subject: igc: fix lock order in igc_ptp_reset + +From: Jacob Keller + +[ Upstream commit c7d6cb96d5c33b5148f3dc76fcd30a9b8cd9e973 ] + +Commit 1a931c4f5e68 ("igc: add lock preventing multiple simultaneous PTM +transactions") added a new mutex to protect concurrent PTM transactions. +This lock is acquired in igc_ptp_reset() in order to ensure the PTM +registers are properly disabled after a device reset. + +The flow where the lock is acquired already holds a spinlock, so acquiring +a mutex leads to a sleep-while-locking bug, reported both by smatch, +and the kernel test robot. + +The critical section in igc_ptp_reset() does correctly use the +readx_poll_timeout_atomic variants, but the standard PTM flow uses regular +sleeping variants. This makes converting the mutex to a spinlock a bit +tricky. + +Instead, re-order the locking in igc_ptp_reset. Acquire the mutex first, +and then the tmreg_lock spinlock. This is safe because there is no other +ordering dependency on these locks, as this is the only place where both +locks were acquired simultaneously. Indeed, any other flow acquiring locks +in that order would be wrong regardless. + +Signed-off-by: Jacob Keller +Fixes: 1a931c4f5e68 ("igc: add lock preventing multiple simultaneous PTM transactions") +Link: https://lore.kernel.org/intel-wired-lan/Z_-P-Hc1yxcw0lTB@stanley.mountain/ +Link: https://lore.kernel.org/intel-wired-lan/202504211511.f7738f5d-lkp@intel.com/T/#u +Reviewed-by: Przemek Kitszel +Reviewed-by: Vitaly Lifshits +Tested-by: Mor Bar-Gabay +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/igc/igc_ptp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c +index 612ed26a29c5d..efc7b30e42113 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ptp.c ++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c +@@ -1290,6 +1290,8 @@ void igc_ptp_reset(struct igc_adapter *adapter) + /* reset the tstamp_config */ + igc_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); + ++ mutex_lock(&adapter->ptm_lock); ++ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + + switch (adapter->hw.mac.type) { +@@ -1308,7 +1310,6 @@ void igc_ptp_reset(struct igc_adapter *adapter) + if (!igc_is_crosststamp_supported(adapter)) + break; + +- mutex_lock(&adapter->ptm_lock); + wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT); + wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT); + +@@ -1332,7 +1333,6 @@ void igc_ptp_reset(struct igc_adapter *adapter) + netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n"); + + igc_ptm_reset(hw); +- mutex_unlock(&adapter->ptm_lock); + break; + default: + /* No work to do. */ +@@ -1349,5 +1349,7 @@ void igc_ptp_reset(struct igc_adapter *adapter) + out: + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + ++ mutex_unlock(&adapter->ptm_lock); ++ + wrfl(); + } +-- +2.39.5 + diff --git a/queue-6.12/net-dlink-correct-endianness-handling-of-led_mode.patch b/queue-6.12/net-dlink-correct-endianness-handling-of-led_mode.patch new file mode 100644 index 0000000000..a4d4b43e00 --- /dev/null +++ b/queue-6.12/net-dlink-correct-endianness-handling-of-led_mode.patch @@ -0,0 +1,80 @@ +From 46af08312b1119a45933422a8356b23755f4b84e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 16:50:47 +0100 +Subject: net: dlink: Correct endianness handling of led_mode + +From: Simon Horman + +[ Upstream commit e7e5ae71831c44d58627a991e603845a2fed2cab ] + +As it's name suggests, parse_eeprom() parses EEPROM data. + +This is done by reading data, 16 bits at a time as follows: + + for (i = 0; i < 128; i++) + ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom(np, i)); + +sromdata is at the same memory location as psrom. +And the type of psrom is a pointer to struct t_SROM. + +As can be seen in the loop above, data is stored in sromdata, and thus psrom, +as 16-bit little-endian values. + +However, the integer fields of t_SROM are host byte order integers. +And in the case of led_mode this leads to a little endian value +being incorrectly treated as host byte order. + +Looking at rio_set_led_mode, this does appear to be a bug as that code +masks led_mode with 0x1, 0x2 and 0x8. Logic that would be effected by a +reversed byte order. + +This problem would only manifest on big endian hosts. + +Found by inspection while investigating a sparse warning +regarding the crc field of t_SROM. + +I believe that warning is a false positive. And although I plan +to send a follow-up to use little-endian types for other the integer +fields of PSROM_t I do not believe that will involve any bug fixes. + +Compile tested only. + +Fixes: c3f45d322cbd ("dl2k: Add support for IP1000A-based cards") +Signed-off-by: Simon Horman +Link: https://patch.msgid.link/20250425-dlink-led-mode-v1-1-6bae3c36e736@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/dlink/dl2k.c | 2 +- + drivers/net/ethernet/dlink/dl2k.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c +index d0ea926078706..6bf8a7aeef908 100644 +--- a/drivers/net/ethernet/dlink/dl2k.c ++++ b/drivers/net/ethernet/dlink/dl2k.c +@@ -352,7 +352,7 @@ parse_eeprom (struct net_device *dev) + eth_hw_addr_set(dev, psrom->mac_addr); + + if (np->chip_id == CHIP_IP1000A) { +- np->led_mode = psrom->led_mode; ++ np->led_mode = le16_to_cpu(psrom->led_mode); + return 0; + } + +diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h +index 195dc6cfd8955..0e33e2eaae960 100644 +--- a/drivers/net/ethernet/dlink/dl2k.h ++++ b/drivers/net/ethernet/dlink/dl2k.h +@@ -335,7 +335,7 @@ typedef struct t_SROM { + u16 sub_system_id; /* 0x06 */ + u16 pci_base_1; /* 0x08 (IP1000A only) */ + u16 pci_base_2; /* 0x0a (IP1000A only) */ +- u16 led_mode; /* 0x0c (IP1000A only) */ ++ __le16 led_mode; /* 0x0c (IP1000A only) */ + u16 reserved1[9]; /* 0x0e-0x1f */ + u8 mac_addr[6]; /* 0x20-0x25 */ + u8 reserved2[10]; /* 0x26-0x2f */ +-- +2.39.5 + diff --git a/queue-6.12/net-dsa-felix-fix-broken-taprio-gate-states-after-cl.patch b/queue-6.12/net-dsa-felix-fix-broken-taprio-gate-states-after-cl.patch new file mode 100644 index 0000000000..0db4b0e8ee --- /dev/null +++ b/queue-6.12/net-dsa-felix-fix-broken-taprio-gate-states-after-cl.patch @@ -0,0 +1,197 @@ +From 78c3eefd00eafb20a13f888fba86cab9b301a54f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Apr 2025 17:48:55 +0300 +Subject: net: dsa: felix: fix broken taprio gate states after clock jump + +From: Vladimir Oltean + +[ Upstream commit 426d487bca38b34f39c483edfc6313a036446b33 ] + +Simplest setup to reproduce the issue: connect 2 ports of the +LS1028A-RDB together (eno0 with swp0) and run: + +$ ip link set eno0 up && ip link set swp0 up +$ tc qdisc replace dev swp0 parent root handle 100 taprio num_tc 8 \ + queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 map 0 1 2 3 4 5 6 7 \ + base-time 0 sched-entry S 20 300000 sched-entry S 10 200000 \ + sched-entry S 20 300000 sched-entry S 48 200000 \ + sched-entry S 20 300000 sched-entry S 83 200000 \ + sched-entry S 40 300000 sched-entry S 00 200000 flags 2 +$ ptp4l -i eno0 -f /etc/linuxptp/configs/gPTP.cfg -m & +$ ptp4l -i swp0 -f /etc/linuxptp/configs/gPTP.cfg -m + +One will observe that the PTP state machine on swp0 starts +synchronizing, then it attempts to do a clock step, and after that, it +never fails to recover from the condition below. + +ptp4l[82.427]: selected best master clock 00049f.fffe.05f627 +ptp4l[82.428]: port 1 (swp0): MASTER to UNCALIBRATED on RS_SLAVE +ptp4l[83.252]: port 1 (swp0): UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED +ptp4l[83.886]: rms 4537731277 max 9075462553 freq -18518 +/- 11467 delay 818 +/- 0 +ptp4l[84.170]: timed out while polling for tx timestamp +ptp4l[84.171]: increasing tx_timestamp_timeout or increasing kworker priority may correct this issue, but a driver bug likely causes it +ptp4l[84.172]: port 1 (swp0): send peer delay request failed +ptp4l[84.173]: port 1 (swp0): clearing fault immediately +ptp4l[84.269]: port 1 (swp0): SLAVE to LISTENING on INIT_COMPLETE +ptp4l[85.303]: timed out while polling for tx timestamp +ptp4l[84.171]: increasing tx_timestamp_timeout or increasing kworker priority may correct this issue, but a driver bug likely causes it +ptp4l[84.172]: port 1 (swp0): send peer delay request failed +ptp4l[84.173]: port 1 (swp0): clearing fault immediately +ptp4l[84.269]: port 1 (swp0): SLAVE to LISTENING on INIT_COMPLETE +ptp4l[85.303]: timed out while polling for tx timestamp +ptp4l[85.304]: increasing tx_timestamp_timeout or increasing kworker priority may correct this issue, but a driver bug likely causes it +ptp4l[85.305]: port 1 (swp0): send peer delay response failed +ptp4l[85.306]: port 1 (swp0): clearing fault immediately +ptp4l[86.304]: timed out while polling for tx timestamp + +A hint is given by the non-zero statistics for dropped packets which +were expecting hardware TX timestamps: + +$ ethtool --include-statistics -T swp0 +(...) +Statistics: + tx_pkts: 30 + tx_lost: 11 + tx_err: 0 + +We know that when PTP clock stepping takes place (from ocelot_ptp_settime64() +or from ocelot_ptp_adjtime()), vsc9959_tas_clock_adjust() is called. + +Another interesting hint is that placing an early return in +vsc9959_tas_clock_adjust(), so as to neutralize this function, fixes the +issue and TX timestamps are no longer dropped. + +The debugging function written by me and included below is intended to +read the GCL RAM, after the admin schedule became operational, through +the two status registers available for this purpose: +QSYS_GCL_STATUS_REG_1 and QSYS_GCL_STATUS_REG_2. + +static void vsc9959_print_tas_gcl(struct ocelot *ocelot) +{ + u32 val, list_length, interval, gate_state; + int i, err; + + err = read_poll_timeout(ocelot_read, val, + !(val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING), + 10, 100000, false, ocelot, QSYS_PARAM_STATUS_REG_8); + if (err) { + dev_err(ocelot->dev, + "Failed to wait for TAS config pending bit to clear: %pe\n", + ERR_PTR(err)); + return; + } + + val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_3); + list_length = QSYS_PARAM_STATUS_REG_3_LIST_LENGTH_X(val); + + dev_info(ocelot->dev, "GCL length: %u\n", list_length); + + for (i = 0; i < list_length; i++) { + ocelot_rmw(ocelot, + QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM(i), + QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM_M, + QSYS_GCL_STATUS_REG_1); + interval = ocelot_read(ocelot, QSYS_GCL_STATUS_REG_2); + val = ocelot_read(ocelot, QSYS_GCL_STATUS_REG_1); + gate_state = QSYS_GCL_STATUS_REG_1_GATE_STATE_X(val); + + dev_info(ocelot->dev, "GCL entry %d: states 0x%x interval %u\n", + i, gate_state, interval); + } +} + +Calling it from two places: after the initial QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE +performed by vsc9959_qos_port_tas_set(), and after the one done by +vsc9959_tas_clock_adjust(), I notice the following difference. + +From the tc-taprio process context, where the schedule was initially +configured, the GCL looks like this: + +mscc_felix 0000:00:00.5: GCL length: 8 +mscc_felix 0000:00:00.5: GCL entry 0: states 0x20 interval 300000 +mscc_felix 0000:00:00.5: GCL entry 1: states 0x10 interval 200000 +mscc_felix 0000:00:00.5: GCL entry 2: states 0x20 interval 300000 +mscc_felix 0000:00:00.5: GCL entry 3: states 0x48 interval 200000 +mscc_felix 0000:00:00.5: GCL entry 4: states 0x20 interval 300000 +mscc_felix 0000:00:00.5: GCL entry 5: states 0x83 interval 200000 +mscc_felix 0000:00:00.5: GCL entry 6: states 0x40 interval 300000 +mscc_felix 0000:00:00.5: GCL entry 7: states 0x0 interval 200000 + +But from the ptp4l clock stepping process context, when the +vsc9959_tas_clock_adjust() hook is called, the GCL RAM of the +operational schedule now looks like this: + +mscc_felix 0000:00:00.5: GCL length: 8 +mscc_felix 0000:00:00.5: GCL entry 0: states 0x0 interval 0 +mscc_felix 0000:00:00.5: GCL entry 1: states 0x0 interval 0 +mscc_felix 0000:00:00.5: GCL entry 2: states 0x0 interval 0 +mscc_felix 0000:00:00.5: GCL entry 3: states 0x0 interval 0 +mscc_felix 0000:00:00.5: GCL entry 4: states 0x0 interval 0 +mscc_felix 0000:00:00.5: GCL entry 5: states 0x0 interval 0 +mscc_felix 0000:00:00.5: GCL entry 6: states 0x0 interval 0 +mscc_felix 0000:00:00.5: GCL entry 7: states 0x0 interval 0 + +I do not have a formal explanation, just experimental conclusions. +It appears that after triggering QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE +for a port's TAS, the GCL entry RAM is updated anyway, despite what the +documentation claims: "Specify the time interval in +QSYS::GCL_CFG_REG_2.TIME_INTERVAL. This triggers the actual RAM +write with the gate state and the time interval for the entry number +specified". We don't touch that register (through vsc9959_tas_gcl_set()) +from vsc9959_tas_clock_adjust(), yet the GCL RAM is updated anyway. + +It seems to be updated with effectively stale memory, which in my +testing can hold a variety of things, including even pieces of the +previously applied schedule, for particular schedule lengths. + +As such, in most circumstances it is very difficult to pinpoint this +issue, because the newly updated schedule would "behave strangely", +but ultimately might still pass traffic to some extent, due to some +gate entries still being present in the stale GCL entry RAM. It is easy +to miss. + +With the particular schedule given at the beginning, the GCL RAM +"happens" to be reproducibly rewritten with all zeroes, and this is +consistent with what we see: when the time-aware shaper has gate entries +with all gates closed, traffic is dropped on TX, no wonder we can't +retrieve TX timestamps. + +Rewriting the GCL entry RAM when reapplying the new base time fixes the +observed issue. + +Fixes: 8670dc33f48b ("net: dsa: felix: update base time of time-aware shaper when adjusting PTP time") +Reported-by: Richie Pearn +Signed-off-by: Vladimir Oltean +Link: https://patch.msgid.link/20250426144859.3128352-2-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/ocelot/felix_vsc9959.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c +index 940f1b71226d6..7b35d24c38d76 100644 +--- a/drivers/net/dsa/ocelot/felix_vsc9959.c ++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c +@@ -1543,7 +1543,7 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot) + struct tc_taprio_qopt_offload *taprio; + struct ocelot_port *ocelot_port; + struct timespec64 base_ts; +- int port; ++ int i, port; + u32 val; + + mutex_lock(&ocelot->fwd_domain_lock); +@@ -1575,6 +1575,9 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot) + QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M, + QSYS_PARAM_CFG_REG_3); + ++ for (i = 0; i < taprio->num_entries; i++) ++ vsc9959_tas_gcl_set(ocelot, i, &taprio->entries[i]); ++ + ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE, + QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE, + QSYS_TAS_PARAM_CFG_CTRL); +-- +2.39.5 + diff --git a/queue-6.12/net-ethernet-mtk-star-emac-fix-spinlock-recursion-is.patch b/queue-6.12/net-ethernet-mtk-star-emac-fix-spinlock-recursion-is.patch new file mode 100644 index 0000000000..6090de6863 --- /dev/null +++ b/queue-6.12/net-ethernet-mtk-star-emac-fix-spinlock-recursion-is.patch @@ -0,0 +1,124 @@ +From 04e2068f8be5dfc32e450ac38550a4f82470c993 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 10:38:48 +0200 +Subject: net: ethernet: mtk-star-emac: fix spinlock recursion issues on rx/tx + poll + +From: Louis-Alexis Eyraud + +[ Upstream commit 6fe0866014486736cc3ba1c6fd4606d3dbe55c9c ] + +Use spin_lock_irqsave and spin_unlock_irqrestore instead of spin_lock +and spin_unlock in mtk_star_emac driver to avoid spinlock recursion +occurrence that can happen when enabling the DMA interrupts again in +rx/tx poll. + +``` +BUG: spinlock recursion on CPU#0, swapper/0/0 + lock: 0xffff00000db9cf20, .magic: dead4ead, .owner: swapper/0/0, + .owner_cpu: 0 +CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted + 6.15.0-rc2-next-20250417-00001-gf6a27738686c-dirty #28 PREEMPT +Hardware name: MediaTek MT8365 Open Platform EVK (DT) +Call trace: + show_stack+0x18/0x24 (C) + dump_stack_lvl+0x60/0x80 + dump_stack+0x18/0x24 + spin_dump+0x78/0x88 + do_raw_spin_lock+0x11c/0x120 + _raw_spin_lock+0x20/0x2c + mtk_star_handle_irq+0xc0/0x22c [mtk_star_emac] + __handle_irq_event_percpu+0x48/0x140 + handle_irq_event+0x4c/0xb0 + handle_fasteoi_irq+0xa0/0x1bc + handle_irq_desc+0x34/0x58 + generic_handle_domain_irq+0x1c/0x28 + gic_handle_irq+0x4c/0x120 + do_interrupt_handler+0x50/0x84 + el1_interrupt+0x34/0x68 + el1h_64_irq_handler+0x18/0x24 + el1h_64_irq+0x6c/0x70 + regmap_mmio_read32le+0xc/0x20 (P) + _regmap_bus_reg_read+0x6c/0xac + _regmap_read+0x60/0xdc + regmap_read+0x4c/0x80 + mtk_star_rx_poll+0x2f4/0x39c [mtk_star_emac] + __napi_poll+0x38/0x188 + net_rx_action+0x164/0x2c0 + handle_softirqs+0x100/0x244 + __do_softirq+0x14/0x20 + ____do_softirq+0x10/0x20 + call_on_irq_stack+0x24/0x64 + do_softirq_own_stack+0x1c/0x40 + __irq_exit_rcu+0xd4/0x10c + irq_exit_rcu+0x10/0x1c + el1_interrupt+0x38/0x68 + el1h_64_irq_handler+0x18/0x24 + el1h_64_irq+0x6c/0x70 + cpuidle_enter_state+0xac/0x320 (P) + cpuidle_enter+0x38/0x50 + do_idle+0x1e4/0x260 + cpu_startup_entry+0x34/0x3c + rest_init+0xdc/0xe0 + console_on_rootfs+0x0/0x6c + __primary_switched+0x88/0x90 +``` + +Fixes: 0a8bd81fd6aa ("net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs") +Signed-off-by: Louis-Alexis Eyraud +Reviewed-by: Maxime Chevallier +Acked-by: Bartosz Golaszewski +Link: https://patch.msgid.link/20250424-mtk_star_emac-fix-spinlock-recursion-issue-v2-1-f3fde2e529d8@collabora.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mediatek/mtk_star_emac.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c +index 25989c79c92e6..47a00e02365a2 100644 +--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c ++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c +@@ -1163,6 +1163,7 @@ static int mtk_star_tx_poll(struct napi_struct *napi, int budget) + struct net_device *ndev = priv->ndev; + unsigned int head = ring->head; + unsigned int entry = ring->tail; ++ unsigned long flags; + + while (entry != head && count < (MTK_STAR_RING_NUM_DESCS - 1)) { + ret = mtk_star_tx_complete_one(priv); +@@ -1182,9 +1183,9 @@ static int mtk_star_tx_poll(struct napi_struct *napi, int budget) + netif_wake_queue(ndev); + + if (napi_complete(napi)) { +- spin_lock(&priv->lock); ++ spin_lock_irqsave(&priv->lock, flags); + mtk_star_enable_dma_irq(priv, false, true); +- spin_unlock(&priv->lock); ++ spin_unlock_irqrestore(&priv->lock, flags); + } + + return 0; +@@ -1341,6 +1342,7 @@ static int mtk_star_rx(struct mtk_star_priv *priv, int budget) + static int mtk_star_rx_poll(struct napi_struct *napi, int budget) + { + struct mtk_star_priv *priv; ++ unsigned long flags; + int work_done = 0; + + priv = container_of(napi, struct mtk_star_priv, rx_napi); +@@ -1348,9 +1350,9 @@ static int mtk_star_rx_poll(struct napi_struct *napi, int budget) + work_done = mtk_star_rx(priv, budget); + if (work_done < budget) { + napi_complete_done(napi, work_done); +- spin_lock(&priv->lock); ++ spin_lock_irqsave(&priv->lock, flags); + mtk_star_enable_dma_irq(priv, true, false); +- spin_unlock(&priv->lock); ++ spin_unlock_irqrestore(&priv->lock, flags); + } + + return work_done; +-- +2.39.5 + diff --git a/queue-6.12/net-ethernet-mtk-star-emac-rearm-interrupts-in-rx_po.patch b/queue-6.12/net-ethernet-mtk-star-emac-rearm-interrupts-in-rx_po.patch new file mode 100644 index 0000000000..3fa4b4f03e --- /dev/null +++ b/queue-6.12/net-ethernet-mtk-star-emac-rearm-interrupts-in-rx_po.patch @@ -0,0 +1,43 @@ +From bcce375c66db9969e843c4b46d6ce002bc641471 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 10:38:49 +0200 +Subject: net: ethernet: mtk-star-emac: rearm interrupts in rx_poll only when + advised + +From: Louis-Alexis Eyraud + +[ Upstream commit e54b4db35e201a9173da9cb7abc8377e12abaf87 ] + +In mtk_star_rx_poll function, on event processing completion, the +mtk_star_emac driver calls napi_complete_done but ignores its return +code and enable RX DMA interrupts inconditionally. This return code +gives the info if a device should avoid rearming its interrupts or not, +so fix this behaviour by taking it into account. + +Fixes: 8c7bd5a454ff ("net: ethernet: mtk-star-emac: new driver") +Signed-off-by: Louis-Alexis Eyraud +Acked-by: Bartosz Golaszewski +Link: https://patch.msgid.link/20250424-mtk_star_emac-fix-spinlock-recursion-issue-v2-2-f3fde2e529d8@collabora.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mediatek/mtk_star_emac.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c +index 47a00e02365a2..c2ab87828d858 100644 +--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c ++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c +@@ -1348,8 +1348,7 @@ static int mtk_star_rx_poll(struct napi_struct *napi, int budget) + priv = container_of(napi, struct mtk_star_priv, rx_napi); + + work_done = mtk_star_rx(priv, budget); +- if (work_done < budget) { +- napi_complete_done(napi, work_done); ++ if (work_done < budget && napi_complete_done(napi, work_done)) { + spin_lock_irqsave(&priv->lock, flags); + mtk_star_enable_dma_irq(priv, true, false); + spin_unlock_irqrestore(&priv->lock, flags); +-- +2.39.5 + diff --git a/queue-6.12/net-ethernet-mtk_eth_soc-fix-ser-panic-with-4gb-ram.patch b/queue-6.12/net-ethernet-mtk_eth_soc-fix-ser-panic-with-4gb-ram.patch new file mode 100644 index 0000000000..0e78be8ab1 --- /dev/null +++ b/queue-6.12/net-ethernet-mtk_eth_soc-fix-ser-panic-with-4gb-ram.patch @@ -0,0 +1,57 @@ +From 5e7bd3f7eea70670bd8a60869848605ef6810a0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Apr 2025 02:05:44 +0100 +Subject: net: ethernet: mtk_eth_soc: fix SER panic with 4GB+ RAM + +From: Chad Monroe + +[ Upstream commit 6e0490fc36cdac696f96e57b61d93b9ae32e0f4c ] + +If the mtk_poll_rx() function detects the MTK_RESETTING flag, it will +jump to release_desc and refill the high word of the SDP on the 4GB RFB. +Subsequently, mtk_rx_clean will process an incorrect SDP, leading to a +panic. + +Add patch from MediaTek's SDK to resolve this. + +Fixes: 2d75891ebc09 ("net: ethernet: mtk_eth_soc: support 36-bit DMA addressing on MT7988") +Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/71f47ea785699c6aa3b922d66c2bdc1a43da25b1 +Signed-off-by: Chad Monroe +Link: https://patch.msgid.link/4adc2aaeb0fb1b9cdc56bf21cf8e7fa328daa345.1745715843.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 5e7280479ca1c..c5d5b9ff8bc42 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2202,14 +2202,18 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, + ring->data[idx] = new_data; + rxd->rxd1 = (unsigned int)dma_addr; + release_desc: ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { ++ if (unlikely(dma_addr == DMA_MAPPING_ERROR)) ++ addr64 = FIELD_GET(RX_DMA_ADDR64_MASK, ++ rxd->rxd2); ++ else ++ addr64 = RX_DMA_PREP_ADDR64(dma_addr); ++ } ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + rxd->rxd2 = RX_DMA_LSO; + else +- rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); +- +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) && +- likely(dma_addr != DMA_MAPPING_ERROR)) +- rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); ++ rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size) | addr64; + + ring->calc_idx = idx; + done++; +-- +2.39.5 + diff --git a/queue-6.12/net-ethernet-mtk_eth_soc-sync-mtk_clks_source_name-a.patch b/queue-6.12/net-ethernet-mtk_eth_soc-sync-mtk_clks_source_name-a.patch new file mode 100644 index 0000000000..b8db3b6268 --- /dev/null +++ b/queue-6.12/net-ethernet-mtk_eth_soc-sync-mtk_clks_source_name-a.patch @@ -0,0 +1,47 @@ +From 8be93eef7467ddca4db81bff74096e4c1ea4a189 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 05:29:53 +0100 +Subject: net: ethernet: mtk_eth_soc: sync mtk_clks_source_name array + +From: Daniel Golle + +[ Upstream commit 8c47d5753a119f1c986bc3ed92e9178d2624e1e8 ] + +When removing the clock bits for clocks which aren't used by the +Ethernet driver their names should also have been removed from the +mtk_clks_source_name array. + +Remove them now as enum mtk_clks_map needs to match the +mtk_clks_source_name array so the driver can make sure that all required +clocks are present and correctly name missing clocks. + +Fixes: 887b1d1adb2e ("net: ethernet: mtk_eth_soc: drop clocks unused by Ethernet driver") +Signed-off-by: Daniel Golle +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/d075e706ff1cebc07f9ec666736d0b32782fd487.1745555321.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 223aee1af4430..5e7280479ca1c 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -269,12 +269,8 @@ static const char * const mtk_clks_source_name[] = { + "ethwarp_wocpu2", + "ethwarp_wocpu1", + "ethwarp_wocpu0", +- "top_usxgmii0_sel", +- "top_usxgmii1_sel", + "top_sgm0_sel", + "top_sgm1_sel", +- "top_xfi_phy0_xtal_sel", +- "top_xfi_phy1_xtal_sel", + "top_eth_gmii_sel", + "top_eth_refck_50m_sel", + "top_eth_sys_200m_sel", +-- +2.39.5 + diff --git a/queue-6.12/net-fec-err007885-workaround-for-conventional-tx.patch b/queue-6.12/net-fec-err007885-workaround-for-conventional-tx.patch new file mode 100644 index 0000000000..be94951591 --- /dev/null +++ b/queue-6.12/net-fec-err007885-workaround-for-conventional-tx.patch @@ -0,0 +1,55 @@ +From 6c0e4725296be3a1d74887b8d3b08a6edf8ce8a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 11:08:26 +0200 +Subject: net: fec: ERR007885 Workaround for conventional TX + +From: Mattias Barthel + +[ Upstream commit a179aad12badc43201cbf45d1e8ed2c1383c76b9 ] + +Activate TX hang workaround also in +fec_enet_txq_submit_skb() when TSO is not enabled. + +Errata: ERR007885 + +Symptoms: NETDEV WATCHDOG: eth0 (fec): transmit queue 0 timed out + +commit 37d6017b84f7 ("net: fec: Workaround for imx6sx enet tx hang when enable three queues") +There is a TDAR race condition for mutliQ when the software sets TDAR +and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles). +This will cause the udma_tx and udma_tx_arbiter state machines to hang. + +So, the Workaround is checking TDAR status four time, if TDAR cleared by + hardware and then write TDAR, otherwise don't set TDAR. + +Fixes: 53bb20d1faba ("net: fec: add variable reg_desc_active to speed things up") +Signed-off-by: Mattias Barthel +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250429090826.3101258-1-mattiasbarthel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/fec_main.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 2b05d9c6c21a4..04906897615d8 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -714,7 +714,12 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq, + txq->bd.cur = bdp; + + /* Trigger transmission start */ +- writel(0, txq->bd.reg_desc_active); ++ if (!(fep->quirks & FEC_QUIRK_ERR007885) || ++ !readl(txq->bd.reg_desc_active) || ++ !readl(txq->bd.reg_desc_active) || ++ !readl(txq->bd.reg_desc_active) || ++ !readl(txq->bd.reg_desc_active)) ++ writel(0, txq->bd.reg_desc_active); + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.12/net-hns3-defer-calling-ptp_clock_register.patch b/queue-6.12/net-hns3-defer-calling-ptp_clock_register.patch new file mode 100644 index 0000000000..160671b119 --- /dev/null +++ b/queue-6.12/net-hns3-defer-calling-ptp_clock_register.patch @@ -0,0 +1,59 @@ +From 28ec9481ceb9d2544c38dee8c2e5e87308e0a7ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 17:30:52 +0800 +Subject: net: hns3: defer calling ptp_clock_register() + +From: Jian Shen + +[ Upstream commit 4971394d9d624f91689d766f31ce668d169d9959 ] + +Currently the ptp_clock_register() is called before relative +ptp resource ready. It may cause unexpected result when upper +layer called the ptp API during the timewindow. Fix it by +moving the ptp_clock_register() to the function end. + +Fixes: 0bf5eb788512 ("net: hns3: add support for PTP") +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Reviewed-by: Vadim Fedorenko +Link: https://patch.msgid.link/20250430093052.2400464-5-shaojijie@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +index 181af419b878d..0ffda5146bae5 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +@@ -439,6 +439,13 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev) + ptp->info.settime64 = hclge_ptp_settime; + + ptp->info.n_alarm = 0; ++ ++ spin_lock_init(&ptp->lock); ++ ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET; ++ ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE; ++ ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF; ++ hdev->ptp = ptp; ++ + ptp->clock = ptp_clock_register(&ptp->info, &hdev->pdev->dev); + if (IS_ERR(ptp->clock)) { + dev_err(&hdev->pdev->dev, +@@ -450,12 +457,6 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev) + return -ENODEV; + } + +- spin_lock_init(&ptp->lock); +- ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET; +- ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE; +- ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF; +- hdev->ptp = ptp; +- + return 0; + } + +-- +2.39.5 + diff --git a/queue-6.12/net-hns3-fix-an-interrupt-residual-problem.patch b/queue-6.12/net-hns3-fix-an-interrupt-residual-problem.patch new file mode 100644 index 0000000000..4fde7ddf14 --- /dev/null +++ b/queue-6.12/net-hns3-fix-an-interrupt-residual-problem.patch @@ -0,0 +1,192 @@ +From 7e06e684a8878698610ab33dd560a097ae3476f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 17:30:50 +0800 +Subject: net: hns3: fix an interrupt residual problem + +From: Yonglong Liu + +[ Upstream commit 8e6b9c6ea5a55045eed6526d8ee49e93192d1a58 ] + +When a VF is passthrough to a VM, and the VM is killed, the reported +interrupt may not been handled, it will remain, and won't be clear by +the nic engine even with a flr or tqp reset. When the VM restart, the +interrupt of the first vector may be dropped by the second enable_irq +in vfio, see the issue below: +https://gitlab.com/qemu-project/qemu/-/issues/2884#note_2423361621 + +We notice that the vfio has always behaved this way, and the interrupt +is a residue of the nic engine, so we fix the problem by moving the +vector enable process out of the enable_irq loop. + +Fixes: 08a100689d4b ("net: hns3: re-organize vector handle") +Signed-off-by: Yonglong Liu +Signed-off-by: Jijie Shao +Link: https://patch.msgid.link/20250430093052.2400464-3-shaojijie@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/hisilicon/hns3/hns3_enet.c | 82 +++++++++---------- + 1 file changed, 39 insertions(+), 43 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index dc60ac3bde7f2..24062a40a7793 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -473,20 +473,14 @@ static void hns3_mask_vector_irq(struct hns3_enet_tqp_vector *tqp_vector, + writel(mask_en, tqp_vector->mask_addr); + } + +-static void hns3_vector_enable(struct hns3_enet_tqp_vector *tqp_vector) ++static void hns3_irq_enable(struct hns3_enet_tqp_vector *tqp_vector) + { + napi_enable(&tqp_vector->napi); + enable_irq(tqp_vector->vector_irq); +- +- /* enable vector */ +- hns3_mask_vector_irq(tqp_vector, 1); + } + +-static void hns3_vector_disable(struct hns3_enet_tqp_vector *tqp_vector) ++static void hns3_irq_disable(struct hns3_enet_tqp_vector *tqp_vector) + { +- /* disable vector */ +- hns3_mask_vector_irq(tqp_vector, 0); +- + disable_irq(tqp_vector->vector_irq); + napi_disable(&tqp_vector->napi); + cancel_work_sync(&tqp_vector->rx_group.dim.work); +@@ -707,11 +701,42 @@ static int hns3_set_rx_cpu_rmap(struct net_device *netdev) + return 0; + } + ++static void hns3_enable_irqs_and_tqps(struct net_device *netdev) ++{ ++ struct hns3_nic_priv *priv = netdev_priv(netdev); ++ struct hnae3_handle *h = priv->ae_handle; ++ u16 i; ++ ++ for (i = 0; i < priv->vector_num; i++) ++ hns3_irq_enable(&priv->tqp_vector[i]); ++ ++ for (i = 0; i < priv->vector_num; i++) ++ hns3_mask_vector_irq(&priv->tqp_vector[i], 1); ++ ++ for (i = 0; i < h->kinfo.num_tqps; i++) ++ hns3_tqp_enable(h->kinfo.tqp[i]); ++} ++ ++static void hns3_disable_irqs_and_tqps(struct net_device *netdev) ++{ ++ struct hns3_nic_priv *priv = netdev_priv(netdev); ++ struct hnae3_handle *h = priv->ae_handle; ++ u16 i; ++ ++ for (i = 0; i < h->kinfo.num_tqps; i++) ++ hns3_tqp_disable(h->kinfo.tqp[i]); ++ ++ for (i = 0; i < priv->vector_num; i++) ++ hns3_mask_vector_irq(&priv->tqp_vector[i], 0); ++ ++ for (i = 0; i < priv->vector_num; i++) ++ hns3_irq_disable(&priv->tqp_vector[i]); ++} ++ + static int hns3_nic_net_up(struct net_device *netdev) + { + struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = priv->ae_handle; +- int i, j; + int ret; + + ret = hns3_nic_reset_all_ring(h); +@@ -720,23 +745,13 @@ static int hns3_nic_net_up(struct net_device *netdev) + + clear_bit(HNS3_NIC_STATE_DOWN, &priv->state); + +- /* enable the vectors */ +- for (i = 0; i < priv->vector_num; i++) +- hns3_vector_enable(&priv->tqp_vector[i]); +- +- /* enable rcb */ +- for (j = 0; j < h->kinfo.num_tqps; j++) +- hns3_tqp_enable(h->kinfo.tqp[j]); ++ hns3_enable_irqs_and_tqps(netdev); + + /* start the ae_dev */ + ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0; + if (ret) { + set_bit(HNS3_NIC_STATE_DOWN, &priv->state); +- while (j--) +- hns3_tqp_disable(h->kinfo.tqp[j]); +- +- for (j = i - 1; j >= 0; j--) +- hns3_vector_disable(&priv->tqp_vector[j]); ++ hns3_disable_irqs_and_tqps(netdev); + } + + return ret; +@@ -823,17 +838,9 @@ static void hns3_reset_tx_queue(struct hnae3_handle *h) + static void hns3_nic_net_down(struct net_device *netdev) + { + struct hns3_nic_priv *priv = netdev_priv(netdev); +- struct hnae3_handle *h = hns3_get_handle(netdev); + const struct hnae3_ae_ops *ops; +- int i; + +- /* disable vectors */ +- for (i = 0; i < priv->vector_num; i++) +- hns3_vector_disable(&priv->tqp_vector[i]); +- +- /* disable rcb */ +- for (i = 0; i < h->kinfo.num_tqps; i++) +- hns3_tqp_disable(h->kinfo.tqp[i]); ++ hns3_disable_irqs_and_tqps(netdev); + + /* stop ae_dev */ + ops = priv->ae_handle->ae_algo->ops; +@@ -5864,8 +5871,6 @@ int hns3_set_channels(struct net_device *netdev, + void hns3_external_lb_prepare(struct net_device *ndev, bool if_running) + { + struct hns3_nic_priv *priv = netdev_priv(ndev); +- struct hnae3_handle *h = priv->ae_handle; +- int i; + + if (!if_running) + return; +@@ -5876,11 +5881,7 @@ void hns3_external_lb_prepare(struct net_device *ndev, bool if_running) + netif_carrier_off(ndev); + netif_tx_disable(ndev); + +- for (i = 0; i < priv->vector_num; i++) +- hns3_vector_disable(&priv->tqp_vector[i]); +- +- for (i = 0; i < h->kinfo.num_tqps; i++) +- hns3_tqp_disable(h->kinfo.tqp[i]); ++ hns3_disable_irqs_and_tqps(ndev); + + /* delay ring buffer clearing to hns3_reset_notify_uninit_enet + * during reset process, because driver may not be able +@@ -5896,7 +5897,6 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running) + { + struct hns3_nic_priv *priv = netdev_priv(ndev); + struct hnae3_handle *h = priv->ae_handle; +- int i; + + if (!if_running) + return; +@@ -5912,11 +5912,7 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running) + + clear_bit(HNS3_NIC_STATE_DOWN, &priv->state); + +- for (i = 0; i < priv->vector_num; i++) +- hns3_vector_enable(&priv->tqp_vector[i]); +- +- for (i = 0; i < h->kinfo.num_tqps; i++) +- hns3_tqp_enable(h->kinfo.tqp[i]); ++ hns3_enable_irqs_and_tqps(ndev); + + netif_tx_wake_all_queues(ndev); + +-- +2.39.5 + diff --git a/queue-6.12/net-hns3-fixed-debugfs-tm_qset-size.patch b/queue-6.12/net-hns3-fixed-debugfs-tm_qset-size.patch new file mode 100644 index 0000000000..8478b835bc --- /dev/null +++ b/queue-6.12/net-hns3-fixed-debugfs-tm_qset-size.patch @@ -0,0 +1,40 @@ +From 86416a6bc14ab4a50937d0b078f5f1358070575f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 17:30:51 +0800 +Subject: net: hns3: fixed debugfs tm_qset size + +From: Hao Lan + +[ Upstream commit e317aebeefcb3b0c71f2305af3c22871ca6b3833 ] + +The size of the tm_qset file of debugfs is limited to 64 KB, +which is too small in the scenario with 1280 qsets. +The size needs to be expanded to 1 MB. + +Fixes: 5e69ea7ee2a6 ("net: hns3: refactor the debugfs process") +Signed-off-by: Hao Lan +Signed-off-by: Peiyang Wang +Signed-off-by: Jijie Shao +Link: https://patch.msgid.link/20250430093052.2400464-4-shaojijie@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +index 9bbece25552b1..3d70c97a0bedf 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +@@ -60,7 +60,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = { + .name = "tm_qset", + .cmd = HNAE3_DBG_CMD_TM_QSET, + .dentry = HNS3_DBG_DENTRY_TM, +- .buf_len = HNS3_DBG_READ_LEN, ++ .buf_len = HNS3_DBG_READ_LEN_1MB, + .init = hns3_dbg_common_file_init, + }, + { +-- +2.39.5 + diff --git a/queue-6.12/net-hns3-store-rx-vlan-tag-offload-state-for-vf.patch b/queue-6.12/net-hns3-store-rx-vlan-tag-offload-state-for-vf.patch new file mode 100644 index 0000000000..3f8fcd3c41 --- /dev/null +++ b/queue-6.12/net-hns3-store-rx-vlan-tag-offload-state-for-vf.patch @@ -0,0 +1,113 @@ +From 83f96d773b10b455e1a6ada36d96d955f3e181fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 17:30:49 +0800 +Subject: net: hns3: store rx VLAN tag offload state for VF + +From: Jian Shen + +[ Upstream commit ef2383d078edcbe3055032436b16cdf206f26de2 ] + +The VF driver missed to store the rx VLAN tag strip state when +user change the rx VLAN tag offload state. And it will default +to enable the rx vlan tag strip when re-init VF device after +reset. So if user disable rx VLAN tag offload, and trig reset, +then the HW will still strip the VLAN tag from packet nad fill +into RX BD, but the VF driver will ignore it for rx VLAN tag +offload disabled. It may cause the rx VLAN tag dropped. + +Fixes: b2641e2ad456 ("net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver") +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250430093052.2400464-2-shaojijie@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../hisilicon/hns3/hns3vf/hclgevf_main.c | 25 ++++++++++++++----- + .../hisilicon/hns3/hns3vf/hclgevf_main.h | 1 + + 2 files changed, 20 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index fd5992164846b..8f5a85b97ac0c 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -1294,9 +1294,8 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) + rtnl_unlock(); + } + +-static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) ++static int hclgevf_en_hw_strip_rxvtag_cmd(struct hclgevf_dev *hdev, bool enable) + { +- struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclge_vf_to_pf_msg send_msg; + + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, +@@ -1305,6 +1304,19 @@ static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) + return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); + } + ++static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) ++{ ++ struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); ++ int ret; ++ ++ ret = hclgevf_en_hw_strip_rxvtag_cmd(hdev, enable); ++ if (ret) ++ return ret; ++ ++ hdev->rxvtag_strip_en = enable; ++ return 0; ++} ++ + static int hclgevf_reset_tqp(struct hnae3_handle *handle) + { + #define HCLGEVF_RESET_ALL_QUEUE_DONE 1U +@@ -2206,12 +2218,13 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) + tc_valid, tc_size); + } + +-static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) ++static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev, ++ bool rxvtag_strip_en) + { + struct hnae3_handle *nic = &hdev->nic; + int ret; + +- ret = hclgevf_en_hw_strip_rxvtag(nic, true); ++ ret = hclgevf_en_hw_strip_rxvtag(nic, rxvtag_strip_en); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to enable rx vlan offload, ret = %d\n", ret); +@@ -2881,7 +2894,7 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) + if (ret) + return ret; + +- ret = hclgevf_init_vlan_config(hdev); ++ ret = hclgevf_init_vlan_config(hdev, hdev->rxvtag_strip_en); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed(%d) to initialize VLAN config\n", ret); +@@ -2996,7 +3009,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) + goto err_config; + } + +- ret = hclgevf_init_vlan_config(hdev); ++ ret = hclgevf_init_vlan_config(hdev, true); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed(%d) to initialize VLAN config\n", ret); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +index cccef32284616..0208425ab594f 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +@@ -253,6 +253,7 @@ struct hclgevf_dev { + int *vector_irq; + + bool gro_en; ++ bool rxvtag_strip_en; + + unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)]; + +-- +2.39.5 + diff --git a/queue-6.12/net-ipv6-fix-udpv6-gso-segmentation-with-nat.patch b/queue-6.12/net-ipv6-fix-udpv6-gso-segmentation-with-nat.patch new file mode 100644 index 0000000000..4120e9ec5b --- /dev/null +++ b/queue-6.12/net-ipv6-fix-udpv6-gso-segmentation-with-nat.patch @@ -0,0 +1,104 @@ +From c77c3efa2ff87c2af9c69b583d27cc9370ffa8fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Apr 2025 17:32:09 +0200 +Subject: net: ipv6: fix UDPv6 GSO segmentation with NAT + +From: Felix Fietkau + +[ Upstream commit b936a9b8d4a585ccb6d454921c36286bfe63e01d ] + +If any address or port is changed, update it in all packets and recalculate +checksum. + +Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.") +Signed-off-by: Felix Fietkau +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20250426153210.14044-1-nbd@nbd.name +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/udp_offload.c | 61 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 60 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index ecfca59f31f13..da5d4aea1b591 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -247,6 +247,62 @@ static struct sk_buff *__udpv4_gso_segment_list_csum(struct sk_buff *segs) + return segs; + } + ++static void __udpv6_gso_segment_csum(struct sk_buff *seg, ++ struct in6_addr *oldip, ++ const struct in6_addr *newip, ++ __be16 *oldport, __be16 newport) ++{ ++ struct udphdr *uh = udp_hdr(seg); ++ ++ if (ipv6_addr_equal(oldip, newip) && *oldport == newport) ++ return; ++ ++ if (uh->check) { ++ inet_proto_csum_replace16(&uh->check, seg, oldip->s6_addr32, ++ newip->s6_addr32, true); ++ ++ inet_proto_csum_replace2(&uh->check, seg, *oldport, newport, ++ false); ++ if (!uh->check) ++ uh->check = CSUM_MANGLED_0; ++ } ++ ++ *oldip = *newip; ++ *oldport = newport; ++} ++ ++static struct sk_buff *__udpv6_gso_segment_list_csum(struct sk_buff *segs) ++{ ++ const struct ipv6hdr *iph; ++ const struct udphdr *uh; ++ struct ipv6hdr *iph2; ++ struct sk_buff *seg; ++ struct udphdr *uh2; ++ ++ seg = segs; ++ uh = udp_hdr(seg); ++ iph = ipv6_hdr(seg); ++ uh2 = udp_hdr(seg->next); ++ iph2 = ipv6_hdr(seg->next); ++ ++ if (!(*(const u32 *)&uh->source ^ *(const u32 *)&uh2->source) && ++ ipv6_addr_equal(&iph->saddr, &iph2->saddr) && ++ ipv6_addr_equal(&iph->daddr, &iph2->daddr)) ++ return segs; ++ ++ while ((seg = seg->next)) { ++ uh2 = udp_hdr(seg); ++ iph2 = ipv6_hdr(seg); ++ ++ __udpv6_gso_segment_csum(seg, &iph2->saddr, &iph->saddr, ++ &uh2->source, uh->source); ++ __udpv6_gso_segment_csum(seg, &iph2->daddr, &iph->daddr, ++ &uh2->dest, uh->dest); ++ } ++ ++ return segs; ++} ++ + static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb, + netdev_features_t features, + bool is_ipv6) +@@ -259,7 +315,10 @@ static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb, + + udp_hdr(skb)->len = htons(sizeof(struct udphdr) + mss); + +- return is_ipv6 ? skb : __udpv4_gso_segment_list_csum(skb); ++ if (is_ipv6) ++ return __udpv6_gso_segment_list_csum(skb); ++ else ++ return __udpv4_gso_segment_list_csum(skb); + } + + struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, +-- +2.39.5 + diff --git a/queue-6.12/net-lan743x-fix-memleak-issue-when-gso-enabled.patch b/queue-6.12/net-lan743x-fix-memleak-issue-when-gso-enabled.patch new file mode 100644 index 0000000000..13eaf66be0 --- /dev/null +++ b/queue-6.12/net-lan743x-fix-memleak-issue-when-gso-enabled.patch @@ -0,0 +1,81 @@ +From ab137dc6703f1c71824c2cac4380e5c5bcb02bea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 10:55:27 +0530 +Subject: net: lan743x: Fix memleak issue when GSO enabled + +From: Thangaraj Samynathan + +[ Upstream commit 2d52e2e38b85c8b7bc00dca55c2499f46f8c8198 ] + +Always map the `skb` to the LS descriptor. Previously skb was +mapped to EXT descriptor when the number of fragments is zero with +GSO enabled. Mapping the skb to EXT descriptor prevents it from +being freed, leading to a memory leak + +Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver") +Signed-off-by: Thangaraj Samynathan +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20250429052527.10031-1-thangaraj.s@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/lan743x_main.c | 8 ++++++-- + drivers/net/ethernet/microchip/lan743x_main.h | 1 + + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 4dc5adcda6a38..547255ca1c4ef 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -1815,6 +1815,7 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx, + if (nr_frags <= 0) { + tx->frame_data0 |= TX_DESC_DATA0_LS_; + tx->frame_data0 |= TX_DESC_DATA0_IOC_; ++ tx->frame_last = tx->frame_first; + } + tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; + tx_descriptor->data0 = cpu_to_le32(tx->frame_data0); +@@ -1884,6 +1885,7 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx, + tx->frame_first = 0; + tx->frame_data0 = 0; + tx->frame_tail = 0; ++ tx->frame_last = 0; + return -ENOMEM; + } + +@@ -1924,16 +1926,18 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx, + TX_DESC_DATA0_DTYPE_DATA_) { + tx->frame_data0 |= TX_DESC_DATA0_LS_; + tx->frame_data0 |= TX_DESC_DATA0_IOC_; ++ tx->frame_last = tx->frame_tail; + } + +- tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; +- buffer_info = &tx->buffer_info[tx->frame_tail]; ++ tx_descriptor = &tx->ring_cpu_ptr[tx->frame_last]; ++ buffer_info = &tx->buffer_info[tx->frame_last]; + buffer_info->skb = skb; + if (time_stamp) + buffer_info->flags |= TX_BUFFER_INFO_FLAG_TIMESTAMP_REQUESTED; + if (ignore_sync) + buffer_info->flags |= TX_BUFFER_INFO_FLAG_IGNORE_SYNC; + ++ tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; + tx_descriptor->data0 = cpu_to_le32(tx->frame_data0); + tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail); + tx->last_tail = tx->frame_tail; +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index 8ef897c114d3c..2f0cab0c85e1d 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -980,6 +980,7 @@ struct lan743x_tx { + u32 frame_first; + u32 frame_data0; + u32 frame_tail; ++ u32 frame_last; + + struct lan743x_tx_buffer_info *buffer_info; + +-- +2.39.5 + diff --git a/queue-6.12/net-mdio-mux-meson-gxl-set-reversed-bit-when-using-i.patch b/queue-6.12/net-mdio-mux-meson-gxl-set-reversed-bit-when-using-i.patch new file mode 100644 index 0000000000..c46d0f8508 --- /dev/null +++ b/queue-6.12/net-mdio-mux-meson-gxl-set-reversed-bit-when-using-i.patch @@ -0,0 +1,51 @@ +From 9c14b90c1874a8d8f55ee8f64a0be03073be961d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 15:20:09 -0400 +Subject: net: mdio: mux-meson-gxl: set reversed bit when using internal phy + +From: Da Xue + +[ Upstream commit b23285e93bef729e67519a5209d5b7fde3b4af50 ] + +This bit is necessary to receive packets from the internal PHY. +Without this bit set, no activity occurs on the interface. + +Normally u-boot sets this bit, but if u-boot is compiled without +net support, the interface will be up but without any activity. +If bit is set once, it will work until the IP is powered down or reset. + +The vendor SDK sets this bit along with the PHY_ID bits. + +Signed-off-by: Da Xue +Fixes: 9a24e1ff4326 ("net: mdio: add amlogic gxl mdio mux support") +Link: https://patch.msgid.link/20250425192009.1439508-1-da@libre.computer +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/mdio/mdio-mux-meson-gxl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/mdio/mdio-mux-meson-gxl.c b/drivers/net/mdio/mdio-mux-meson-gxl.c +index 89554021b5ccc..f9f02d3136492 100644 +--- a/drivers/net/mdio/mdio-mux-meson-gxl.c ++++ b/drivers/net/mdio/mdio-mux-meson-gxl.c +@@ -17,6 +17,7 @@ + #define REG2_LEDACT GENMASK(23, 22) + #define REG2_LEDLINK GENMASK(25, 24) + #define REG2_DIV4SEL BIT(27) ++#define REG2_REVERSED BIT(28) + #define REG2_ADCBYPASS BIT(30) + #define REG2_CLKINSEL BIT(31) + #define ETH_REG3 0x4 +@@ -65,7 +66,7 @@ static void gxl_enable_internal_mdio(struct gxl_mdio_mux *priv) + * The only constraint is that it must match the one in + * drivers/net/phy/meson-gxl.c to properly match the PHY. + */ +- writel(FIELD_PREP(REG2_PHYID, EPHY_GXL_ID), ++ writel(REG2_REVERSED | FIELD_PREP(REG2_PHYID, EPHY_GXL_ID), + priv->regs + ETH_REG2); + + /* Enable the internal phy */ +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5-e-switch-fix-error-handling-for-enabling-ro.patch b/queue-6.12/net-mlx5-e-switch-fix-error-handling-for-enabling-ro.patch new file mode 100644 index 0000000000..d75b6dfa78 --- /dev/null +++ b/queue-6.12/net-mlx5-e-switch-fix-error-handling-for-enabling-ro.patch @@ -0,0 +1,110 @@ +From f0bc99df4eefebc9ce73c456c9cfa957ad45b582 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 11:36:11 +0300 +Subject: net/mlx5: E-switch, Fix error handling for enabling roce + +From: Chris Mi + +[ Upstream commit 90538d23278a981e344d364e923162fce752afeb ] + +The cited commit assumes enabling roce always succeeds. But it is +not true. Add error handling for it. + +Fixes: 80f09dfc237f ("net/mlx5: Eswitch, enable RoCE loopback traffic") +Signed-off-by: Chris Mi +Reviewed-by: Roi Dayan +Reviewed-by: Maor Gottlieb +Signed-off-by: Mark Bloch +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250423083611.324567-6-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 5 ++++- + drivers/net/ethernet/mellanox/mlx5/core/rdma.c | 9 +++++---- + drivers/net/ethernet/mellanox/mlx5/core/rdma.h | 4 ++-- + 3 files changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 3950b1d4b3d8e..988df7047b01d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -3514,7 +3514,9 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) + int err; + + mutex_init(&esw->offloads.termtbl_mutex); +- mlx5_rdma_enable_roce(esw->dev); ++ err = mlx5_rdma_enable_roce(esw->dev); ++ if (err) ++ goto err_roce; + + err = mlx5_esw_host_number_init(esw); + if (err) +@@ -3575,6 +3577,7 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) + esw_offloads_metadata_uninit(esw); + err_metadata: + mlx5_rdma_disable_roce(esw->dev); ++err_roce: + mutex_destroy(&esw->offloads.termtbl_mutex); + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +index f585ef5a34243..5c552b71e371c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +@@ -140,17 +140,17 @@ void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev) + mlx5_nic_vport_disable_roce(dev); + } + +-void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) ++int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) + { + int err; + + if (!MLX5_CAP_GEN(dev, roce)) +- return; ++ return 0; + + err = mlx5_nic_vport_enable_roce(dev); + if (err) { + mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err); +- return; ++ return err; + } + + err = mlx5_rdma_add_roce_addr(dev); +@@ -165,10 +165,11 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) + goto del_roce_addr; + } + +- return; ++ return err; + + del_roce_addr: + mlx5_rdma_del_roce_addr(dev); + disable_roce: + mlx5_nic_vport_disable_roce(dev); ++ return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.h b/drivers/net/ethernet/mellanox/mlx5/core/rdma.h +index 750cff2a71a4b..3d9e76c3d42fb 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.h +@@ -8,12 +8,12 @@ + + #ifdef CONFIG_MLX5_ESWITCH + +-void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev); ++int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev); + void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev); + + #else /* CONFIG_MLX5_ESWITCH */ + +-static inline void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) {} ++static inline int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) { return 0; } + static inline void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev) {} + + #endif /* CONFIG_MLX5_ESWITCH */ +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5-e-switch-initialize-mac-address-for-default.patch b/queue-6.12/net-mlx5-e-switch-initialize-mac-address-for-default.patch new file mode 100644 index 0000000000..420faf2fb5 --- /dev/null +++ b/queue-6.12/net-mlx5-e-switch-initialize-mac-address-for-default.patch @@ -0,0 +1,48 @@ +From 994f4537dab8f63ab8bbbfc4234fba86f4439720 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 11:36:08 +0300 +Subject: net/mlx5: E-Switch, Initialize MAC Address for Default GID + +From: Maor Gottlieb + +[ Upstream commit 5d1a04f347e6cbf5ffe74da409a5d71fbe8c5f19 ] + +Initialize the source MAC address when creating the default GID entry. +Since this entry is used only for loopback traffic, it only needs to +be a unicast address. A zeroed-out MAC address is sufficient for this +purpose. +Without this fix, random bits would be assigned as the source address. +If these bits formed a multicast address, the firmware would return an +error, preventing the user from switching to switchdev mode: + +Error: mlx5_core: Failed setting eswitch to offloads. +kernel answers: Invalid argument + +Fixes: 80f09dfc237f ("net/mlx5: Eswitch, enable RoCE loopback traffic") +Signed-off-by: Maor Gottlieb +Signed-off-by: Mark Bloch +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250423083611.324567-3-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/rdma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +index a42f6cd99b744..f585ef5a34243 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +@@ -118,8 +118,8 @@ static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid * + + static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev) + { ++ u8 mac[ETH_ALEN] = {}; + union ib_gid gid; +- u8 mac[ETH_ALEN]; + + mlx5_rdma_make_default_gid(dev, &gid); + return mlx5_core_roce_gid_set(dev, 0, +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-fix-lock-order-in-mlx5e_tx_reporter_ptpsq_.patch b/queue-6.12/net-mlx5e-fix-lock-order-in-mlx5e_tx_reporter_ptpsq_.patch new file mode 100644 index 0000000000..1ea8e6757c --- /dev/null +++ b/queue-6.12/net-mlx5e-fix-lock-order-in-mlx5e_tx_reporter_ptpsq_.patch @@ -0,0 +1,62 @@ +From bd03816090df80ec8eee058e84b3d3e075330da3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 11:36:10 +0300 +Subject: net/mlx5e: Fix lock order in + mlx5e_tx_reporter_ptpsq_unhealthy_recover + +From: Cosmin Ratiu + +[ Upstream commit 1c2940ec0ddf51c689ee9ab85ead85c11b77809d ] + +RTNL needs to be acquired before state_lock. + +Fixes: fdce06bda7e5 ("net/mlx5e: Acquire RTNL lock before RQs/SQs activation/deactivation") +Signed-off-by: Cosmin Ratiu +Reviewed-by: Dragos Tatulea +Signed-off-by: Mark Bloch +Link: https://patch.msgid.link/20250423083611.324567-5-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +index 09433b91be176..c8adf309ecad0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +@@ -177,6 +177,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) + + priv = ptpsq->txqsq.priv; + ++ rtnl_lock(); + mutex_lock(&priv->state_lock); + chs = &priv->channels; + netdev = priv->netdev; +@@ -184,22 +185,19 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) + carrier_ok = netif_carrier_ok(netdev); + netif_carrier_off(netdev); + +- rtnl_lock(); + mlx5e_deactivate_priv_channels(priv); +- rtnl_unlock(); + + mlx5e_ptp_close(chs->ptp); + err = mlx5e_ptp_open(priv, &chs->params, chs->c[0]->lag_port, &chs->ptp); + +- rtnl_lock(); + mlx5e_activate_priv_channels(priv); +- rtnl_unlock(); + + /* return carrier back if needed */ + if (carrier_ok) + netif_carrier_on(netdev); + + mutex_unlock(&priv->state_lock); ++ rtnl_unlock(); + + return err; + } +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-tc-continue-the-attr-process-even-if-encap.patch b/queue-6.12/net-mlx5e-tc-continue-the-attr-process-even-if-encap.patch new file mode 100644 index 0000000000..f90de97d71 --- /dev/null +++ b/queue-6.12/net-mlx5e-tc-continue-the-attr-process-even-if-encap.patch @@ -0,0 +1,56 @@ +From 5240ffc26d5911dfadf880e504f39bfe1622bace Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 11:36:09 +0300 +Subject: net/mlx5e: TC, Continue the attr process even if encap entry is + invalid + +From: Jianbo Liu + +[ Upstream commit 172c034264c894518c012387f2de2f9d6443505d ] + +Previously the offload of the rule with header rewrite and mirror to +both internal and external destinations is skipped if the encap entry +is not valid. But it shouldn't because driver will try to offload it +again if neighbor is updated and encap entry is valid, to replace the +old FTE added for slow path. But the extra split attr doesn't exist at +that time as the process is skipped, driver then fails to offload it. +To fix this issue, remove the checking and continue the attr process +if encap entry is invalid. + +Fixes: b11bde56246e ("net/mlx5e: TC, Offload rewrite and mirror to both internal and external dests") +Signed-off-by: Jianbo Liu +Reviewed-by: Cosmin Ratiu +Signed-off-by: Mark Bloch +Link: https://patch.msgid.link/20250423083611.324567-4-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 6b3b1afe83121..218d5402cd1a6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -1750,9 +1750,6 @@ extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr + !list_is_first(&attr->list, &flow->attrs)) + return 0; + +- if (flow_flag_test(flow, SLOW)) +- return 0; +- + esw_attr = attr->esw_attr; + if (!esw_attr->split_count || + esw_attr->split_count == esw_attr->out_count - 1) +@@ -1766,7 +1763,7 @@ extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr + for (i = esw_attr->split_count; i < esw_attr->out_count; i++) { + /* external dest with encap is considered as internal by firmware */ + if (esw_attr->dests[i].vport == MLX5_VPORT_UPLINK && +- !(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP_VALID)) ++ !(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP)) + ext_dest = true; + else + int_dest = true; +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-use-custom-tunnel-header-for-vxlan-gbp.patch b/queue-6.12/net-mlx5e-use-custom-tunnel-header-for-vxlan-gbp.patch new file mode 100644 index 0000000000..cc61547266 --- /dev/null +++ b/queue-6.12/net-mlx5e-use-custom-tunnel-header-for-vxlan-gbp.patch @@ -0,0 +1,91 @@ +From df9b81578c65eba47bdb49aa1e6b739b23617c7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 11:36:07 +0300 +Subject: net/mlx5e: Use custom tunnel header for vxlan gbp + +From: Vlad Dogaru + +[ Upstream commit eacc77a73275895eca0e3655dc6c671853500e2e ] + +Symbolic (e.g. "vxlan") and custom (e.g. "tunnel_header_0") tunnels +cannot be combined, but the match params interface does not have fields +for matching on vxlan gbp. To match vxlan bgp, the tc_tun layer uses +tunnel_header_0. + +Allow matching on both VNI and GBP by matching the VNI with a custom +tunnel header instead of the symbolic field name. + +Matching solely on the VNI continues to use the symbolic field name. + +Fixes: 74a778b4a63f ("net/mlx5: HWS, added definers handling") +Signed-off-by: Vlad Dogaru +Reviewed-by: Yevgeny Kliteynik +Signed-off-by: Mark Bloch +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250423083611.324567-2-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../mellanox/mlx5/core/en/tc_tun_vxlan.c | 32 +++++++++++++++++-- + 1 file changed, 29 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c +index e4e487c8431b8..b9cf79e271244 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c +@@ -165,9 +165,6 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv, + struct flow_match_enc_keyid enc_keyid; + void *misc_c, *misc_v; + +- misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters); +- misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters); +- + if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) + return 0; + +@@ -182,6 +179,30 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv, + err = mlx5e_tc_tun_parse_vxlan_gbp_option(priv, spec, f); + if (err) + return err; ++ ++ /* We can't mix custom tunnel headers with symbolic ones and we ++ * don't have a symbolic field name for GBP, so we use custom ++ * tunnel headers in this case. We need hardware support to ++ * match on custom tunnel headers, but we already know it's ++ * supported because the previous call successfully checked for ++ * that. ++ */ ++ misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, ++ misc_parameters_5); ++ misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, ++ misc_parameters_5); ++ ++ /* Shift by 8 to account for the reserved bits in the vxlan ++ * header after the VNI. ++ */ ++ MLX5_SET(fte_match_set_misc5, misc_c, tunnel_header_1, ++ be32_to_cpu(enc_keyid.mask->keyid) << 8); ++ MLX5_SET(fte_match_set_misc5, misc_v, tunnel_header_1, ++ be32_to_cpu(enc_keyid.key->keyid) << 8); ++ ++ spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_5; ++ ++ return 0; + } + + /* match on VNI is required */ +@@ -195,6 +216,11 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv, + return -EOPNOTSUPP; + } + ++ misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, ++ misc_parameters); ++ misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, ++ misc_parameters); ++ + MLX5_SET(fte_match_set_misc, misc_c, vxlan_vni, + be32_to_cpu(enc_keyid.mask->keyid)); + MLX5_SET(fte_match_set_misc, misc_v, vxlan_vni, +-- +2.39.5 + diff --git a/queue-6.12/net-mscc-ocelot-delete-pvid-vlan-when-readding-it-as.patch b/queue-6.12/net-mscc-ocelot-delete-pvid-vlan-when-readding-it-as.patch new file mode 100644 index 0000000000..d1bc091f71 --- /dev/null +++ b/queue-6.12/net-mscc-ocelot-delete-pvid-vlan-when-readding-it-as.patch @@ -0,0 +1,72 @@ +From 7eb975f915482378f48604931979acda1e4ea16d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 01:37:33 +0300 +Subject: net: mscc: ocelot: delete PVID VLAN when readding it as non-PVID + +From: Vladimir Oltean + +[ Upstream commit 5ec6d7d737a491256cd37e33910f7ac1978db591 ] + +The following set of commands: + +ip link add br0 type bridge vlan_filtering 1 # vlan_default_pvid 1 is implicit +ip link set swp0 master br0 +bridge vlan add dev swp0 vid 1 + +should result in the dropping of untagged and 802.1p-tagged traffic, but +we see that it continues to be accepted. Whereas, had we deleted VID 1 +instead, the aforementioned dropping would have worked + +This is because the ANA_PORT_DROP_CFG update logic doesn't run, because +ocelot_vlan_add() only calls ocelot_port_set_pvid() if the new VLAN has +the BRIDGE_VLAN_INFO_PVID flag. + +Similar to other drivers like mt7530_port_vlan_add() which handle this +case correctly, we need to test whether the VLAN we're changing used to +have the BRIDGE_VLAN_INFO_PVID flag, but lost it now. That amounts to a +PVID deletion and should be treated as such. + +Regarding blame attribution: this never worked properly since the +introduction of bridge VLAN filtering in commit 7142529f1688 ("net: +mscc: ocelot: add VLAN filtering"). However, there was a significant +paradigm shift which aligned the ANA_PORT_DROP_CFG register with the +PVID concept rather than with the native VLAN concept, and that change +wasn't targeted for 'stable'. Realistically, that is as far as this fix +needs to be propagated to. + +Fixes: be0576fed6d3 ("net: mscc: ocelot: move the logic to drop 802.1p traffic to the pvid deletion") +Signed-off-by: Vladimir Oltean +Link: https://patch.msgid.link/20250424223734.3096202-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c +index ef93df5208871..08bee56aea35f 100644 +--- a/drivers/net/ethernet/mscc/ocelot.c ++++ b/drivers/net/ethernet/mscc/ocelot.c +@@ -830,6 +830,7 @@ EXPORT_SYMBOL(ocelot_vlan_prepare); + int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, + bool untagged) + { ++ struct ocelot_port *ocelot_port = ocelot->ports[port]; + int err; + + /* Ignore VID 0 added to our RX filter by the 8021q module, since +@@ -849,6 +850,11 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, + ocelot_bridge_vlan_find(ocelot, vid)); + if (err) + return err; ++ } else if (ocelot_port->pvid_vlan && ++ ocelot_bridge_vlan_find(ocelot, vid) == ocelot_port->pvid_vlan) { ++ err = ocelot_port_set_pvid(ocelot, port, NULL); ++ if (err) ++ return err; + } + + /* Untagged egress vlan clasification */ +-- +2.39.5 + diff --git a/queue-6.12/net-use-sock_gen_put-when-sk_state-is-tcp_time_wait.patch b/queue-6.12/net-use-sock_gen_put-when-sk_state-is-tcp_time_wait.patch new file mode 100644 index 0000000000..187545ae74 --- /dev/null +++ b/queue-6.12/net-use-sock_gen_put-when-sk_state-is-tcp_time_wait.patch @@ -0,0 +1,100 @@ +From 1c902e49988e25dc69b961800d8d3158da80d243 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 09:59:48 +0800 +Subject: net: use sock_gen_put() when sk_state is TCP_TIME_WAIT + +From: Jibin Zhang + +[ Upstream commit f920436a44295ca791ebb6dae3f4190142eec703 ] + +It is possible for a pointer of type struct inet_timewait_sock to be +returned from the functions __inet_lookup_established() and +__inet6_lookup_established(). This can cause a crash when the +returned pointer is of type struct inet_timewait_sock and +sock_put() is called on it. The following is a crash call stack that +shows sk->sk_wmem_alloc being accessed in sk_free() during the call to +sock_put() on a struct inet_timewait_sock pointer. To avoid this issue, +use sock_gen_put() instead of sock_put() when sk->sk_state +is TCP_TIME_WAIT. + +mrdump.ko ipanic() + 120 +vmlinux notifier_call_chain(nr_to_call=-1, nr_calls=0) + 132 +vmlinux atomic_notifier_call_chain(val=0) + 56 +vmlinux panic() + 344 +vmlinux add_taint() + 164 +vmlinux end_report() + 136 +vmlinux kasan_report(size=0) + 236 +vmlinux report_tag_fault() + 16 +vmlinux do_tag_recovery() + 16 +vmlinux __do_kernel_fault() + 88 +vmlinux do_bad_area() + 28 +vmlinux do_tag_check_fault() + 60 +vmlinux do_mem_abort() + 80 +vmlinux el1_abort() + 56 +vmlinux el1h_64_sync_handler() + 124 +vmlinux > 0xFFFFFFC080011294() +vmlinux __lse_atomic_fetch_add_release(v=0xF2FFFF82A896087C) +vmlinux __lse_atomic_fetch_sub_release(v=0xF2FFFF82A896087C) +vmlinux arch_atomic_fetch_sub_release(i=1, v=0xF2FFFF82A896087C) ++ 8 +vmlinux raw_atomic_fetch_sub_release(i=1, v=0xF2FFFF82A896087C) ++ 8 +vmlinux atomic_fetch_sub_release(i=1, v=0xF2FFFF82A896087C) + 8 +vmlinux __refcount_sub_and_test(i=1, r=0xF2FFFF82A896087C, +oldp=0) + 8 +vmlinux __refcount_dec_and_test(r=0xF2FFFF82A896087C, oldp=0) + 8 +vmlinux refcount_dec_and_test(r=0xF2FFFF82A896087C) + 8 +vmlinux sk_free(sk=0xF2FFFF82A8960700) + 28 +vmlinux sock_put() + 48 +vmlinux tcp6_check_fraglist_gro() + 236 +vmlinux tcp6_gro_receive() + 624 +vmlinux ipv6_gro_receive() + 912 +vmlinux dev_gro_receive() + 1116 +vmlinux napi_gro_receive() + 196 +ccmni.ko ccmni_rx_callback() + 208 +ccmni.ko ccmni_queue_recv_skb() + 388 +ccci_dpmaif.ko dpmaif_rxq_push_thread() + 1088 +vmlinux kthread() + 268 +vmlinux 0xFFFFFFC08001F30C() + +Fixes: c9d1d23e5239 ("net: add heuristic for enabling TCP fraglist GRO") +Signed-off-by: Jibin Zhang +Signed-off-by: Shiming Cheng +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20250429020412.14163-1-shiming.cheng@mediatek.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_offload.c | 2 +- + net/ipv6/tcpv6_offload.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c +index 2dfac79dc78b8..e04ebe651c334 100644 +--- a/net/ipv4/tcp_offload.c ++++ b/net/ipv4/tcp_offload.c +@@ -435,7 +435,7 @@ static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, + iif, sdif); + NAPI_GRO_CB(skb)->is_flist = !sk; + if (sk) +- sock_put(sk); ++ sock_gen_put(sk); + } + + INDIRECT_CALLABLE_SCOPE +diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c +index ae2da28f9dfb1..5ab509a5fbdfc 100644 +--- a/net/ipv6/tcpv6_offload.c ++++ b/net/ipv6/tcpv6_offload.c +@@ -42,7 +42,7 @@ static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, + iif, sdif); + NAPI_GRO_CB(skb)->is_flist = !sk; + if (sk) +- sock_put(sk); ++ sock_gen_put(sk); + #endif /* IS_ENABLED(CONFIG_IPV6) */ + } + +-- +2.39.5 + diff --git a/queue-6.12/net-vertexcom-mse102x-add-range-check-for-cmd_rts.patch b/queue-6.12/net-vertexcom-mse102x-add-range-check-for-cmd_rts.patch new file mode 100644 index 0000000000..b5d4793923 --- /dev/null +++ b/queue-6.12/net-vertexcom-mse102x-add-range-check-for-cmd_rts.patch @@ -0,0 +1,50 @@ +From da21628d11ab85ab974a63e247e589a71d86c2e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 15:30:42 +0200 +Subject: net: vertexcom: mse102x: Add range check for CMD_RTS + +From: Stefan Wahren + +[ Upstream commit d4dda902dac194e3231a1ed0f76c6c3b6340ba8a ] + +Since there is no protection in the SPI protocol against electrical +interferences, the driver shouldn't blindly trust the length payload +of CMD_RTS. So introduce a bounds check for incoming frames. + +Fixes: 2f207cbf0dd4 ("net: vertexcom: Add MSE102x SPI support") +Signed-off-by: Stefan Wahren +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250430133043.7722-4-wahrenst@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/vertexcom/mse102x.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c +index 3edf2c3753f0e..2c06d1d05164f 100644 +--- a/drivers/net/ethernet/vertexcom/mse102x.c ++++ b/drivers/net/ethernet/vertexcom/mse102x.c +@@ -6,6 +6,7 @@ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + ++#include + #include + #include + #include +@@ -337,8 +338,9 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + } + + rxlen = cmd_resp & LEN_MASK; +- if (!rxlen) { +- net_dbg_ratelimited("%s: No frame length defined\n", __func__); ++ if (rxlen < ETH_ZLEN || rxlen > VLAN_ETH_FRAME_LEN) { ++ net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__, ++ rxlen); + mse->stats.invalid_len++; + return; + } +-- +2.39.5 + diff --git a/queue-6.12/net-vertexcom-mse102x-fix-len_mask.patch b/queue-6.12/net-vertexcom-mse102x-fix-len_mask.patch new file mode 100644 index 0000000000..b4a7c60a21 --- /dev/null +++ b/queue-6.12/net-vertexcom-mse102x-fix-len_mask.patch @@ -0,0 +1,38 @@ +From 6573e093691180f59b5e8aa1bc77e77c38514111 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 15:30:41 +0200 +Subject: net: vertexcom: mse102x: Fix LEN_MASK + +From: Stefan Wahren + +[ Upstream commit 74987089ec678b4018dba0a609e9f4bf6ef7f4ad ] + +The LEN_MASK for CMD_RTS doesn't cover the whole parameter mask. +The Bit 11 is reserved, so adjust LEN_MASK accordingly. + +Fixes: 2f207cbf0dd4 ("net: vertexcom: Add MSE102x SPI support") +Signed-off-by: Stefan Wahren +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250430133043.7722-3-wahrenst@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/vertexcom/mse102x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c +index 92ebf16331598..3edf2c3753f0e 100644 +--- a/drivers/net/ethernet/vertexcom/mse102x.c ++++ b/drivers/net/ethernet/vertexcom/mse102x.c +@@ -33,7 +33,7 @@ + #define CMD_CTR (0x2 << CMD_SHIFT) + + #define CMD_MASK GENMASK(15, CMD_SHIFT) +-#define LEN_MASK GENMASK(CMD_SHIFT - 1, 0) ++#define LEN_MASK GENMASK(CMD_SHIFT - 2, 0) + + #define DET_CMD_LEN 4 + #define DET_SOF_LEN 2 +-- +2.39.5 + diff --git a/queue-6.12/net-vertexcom-mse102x-fix-possible-stuck-of-spi-inte.patch b/queue-6.12/net-vertexcom-mse102x-fix-possible-stuck-of-spi-inte.patch new file mode 100644 index 0000000000..4e980505f7 --- /dev/null +++ b/queue-6.12/net-vertexcom-mse102x-fix-possible-stuck-of-spi-inte.patch @@ -0,0 +1,53 @@ +From ebee06c8276d5fa00726589411b2227893934deb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 15:30:40 +0200 +Subject: net: vertexcom: mse102x: Fix possible stuck of SPI interrupt + +From: Stefan Wahren + +[ Upstream commit 55f362885951b2d00fd7fbb02ef0227deea572c2 ] + +The MSE102x doesn't provide any SPI commands for interrupt handling. +So in case the interrupt fired before the driver requests the IRQ, +the interrupt will never fire again. In order to fix this always poll +for pending packets after opening the interface. + +Fixes: 2f207cbf0dd4 ("net: vertexcom: Add MSE102x SPI support") +Signed-off-by: Stefan Wahren +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250430133043.7722-2-wahrenst@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/vertexcom/mse102x.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c +index 89dc4c401a8de..92ebf16331598 100644 +--- a/drivers/net/ethernet/vertexcom/mse102x.c ++++ b/drivers/net/ethernet/vertexcom/mse102x.c +@@ -509,6 +509,7 @@ static irqreturn_t mse102x_irq(int irq, void *_mse) + static int mse102x_net_open(struct net_device *ndev) + { + struct mse102x_net *mse = netdev_priv(ndev); ++ struct mse102x_net_spi *mses = to_mse102x_spi(mse); + int ret; + + ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT, +@@ -524,6 +525,13 @@ static int mse102x_net_open(struct net_device *ndev) + + netif_carrier_on(ndev); + ++ /* The SPI interrupt can stuck in case of pending packet(s). ++ * So poll for possible packet(s) to re-arm the interrupt. ++ */ ++ mutex_lock(&mses->lock); ++ mse102x_rx_pkt_spi(mse); ++ mutex_unlock(&mses->lock); ++ + netif_dbg(mse, ifup, ndev, "network device up\n"); + + return 0; +-- +2.39.5 + diff --git a/queue-6.12/net-vertexcom-mse102x-fix-rx-error-handling.patch b/queue-6.12/net-vertexcom-mse102x-fix-rx-error-handling.patch new file mode 100644 index 0000000000..83dbd1e58f --- /dev/null +++ b/queue-6.12/net-vertexcom-mse102x-fix-rx-error-handling.patch @@ -0,0 +1,95 @@ +From 7975f515d68c4582a7e7ed5ba37d7222635d7021 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 15:30:43 +0200 +Subject: net: vertexcom: mse102x: Fix RX error handling + +From: Stefan Wahren + +[ Upstream commit ee512922ddd7d64afe2b28830a88f19063217649 ] + +In case the CMD_RTS got corrupted by interferences, the MSE102x +doesn't allow a retransmission of the command. Instead the Ethernet +frame must be shifted out of the SPI FIFO. Since the actual length is +unknown, assume the maximum possible value. + +Fixes: 2f207cbf0dd4 ("net: vertexcom: Add MSE102x SPI support") +Signed-off-by: Stefan Wahren +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250430133043.7722-5-wahrenst@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/vertexcom/mse102x.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c +index 2c06d1d05164f..e4d993f313740 100644 +--- a/drivers/net/ethernet/vertexcom/mse102x.c ++++ b/drivers/net/ethernet/vertexcom/mse102x.c +@@ -263,7 +263,7 @@ static int mse102x_tx_frame_spi(struct mse102x_net *mse, struct sk_buff *txp, + } + + static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff, +- unsigned int frame_len) ++ unsigned int frame_len, bool drop) + { + struct mse102x_net_spi *mses = to_mse102x_spi(mse); + struct spi_transfer *xfer = &mses->spi_xfer; +@@ -281,6 +281,9 @@ static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff, + netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n", + __func__, ret); + mse->stats.xfer_err++; ++ } else if (drop) { ++ netdev_dbg(mse->ndev, "%s: Drop frame\n", __func__); ++ ret = -EINVAL; + } else if (*sof != cpu_to_be16(DET_SOF)) { + netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n", + __func__, *sof); +@@ -308,6 +311,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + struct sk_buff *skb; + unsigned int rxalign; + unsigned int rxlen; ++ bool drop = false; + __be16 rx = 0; + u16 cmd_resp; + u8 *rxpkt; +@@ -330,7 +334,8 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n", + __func__, cmd_resp); + mse->stats.invalid_rts++; +- return; ++ drop = true; ++ goto drop; + } + + net_dbg_ratelimited("%s: Unexpected response to first CMD\n", +@@ -342,9 +347,16 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__, + rxlen); + mse->stats.invalid_len++; +- return; ++ drop = true; + } + ++ /* In case of a invalid CMD_RTS, the frame must be consumed anyway. ++ * So assume the maximum possible frame length. ++ */ ++drop: ++ if (drop) ++ rxlen = VLAN_ETH_FRAME_LEN; ++ + rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4); + skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign); + if (!skb) +@@ -355,7 +367,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) + * They are copied, but ignored. + */ + rxpkt = skb_put(skb, rxlen) - DET_SOF_LEN; +- if (mse102x_rx_frame_spi(mse, rxpkt, rxlen)) { ++ if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) { + mse->ndev->stats.rx_errors++; + dev_kfree_skb(skb); + return; +-- +2.39.5 + diff --git a/queue-6.12/net_sched-drr-fix-double-list-add-in-class-with-nete.patch b/queue-6.12/net_sched-drr-fix-double-list-add-in-class-with-nete.patch new file mode 100644 index 0000000000..7b0a62715b --- /dev/null +++ b/queue-6.12/net_sched-drr-fix-double-list-add-in-class-with-nete.patch @@ -0,0 +1,75 @@ +From 9514300d90db4732bf2d0862aa081bdd881be598 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 19:07:05 -0300 +Subject: net_sched: drr: Fix double list add in class with netem as child + qdisc + +From: Victor Nogueira + +[ Upstream commit f99a3fbf023e20b626be4b0f042463d598050c9a ] + +As described in Gerrard's report [1], there are use cases where a netem +child qdisc will make the parent qdisc's enqueue callback reentrant. +In the case of drr, there won't be a UAF, but the code will add the same +classifier to the list twice, which will cause memory corruption. + +In addition to checking for qlen being zero, this patch checks whether the +class was already added to the active_list (cl_is_active) before adding +to the list to cover for the reentrant case. + +[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/ + +Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs") +Acked-by: Jamal Hadi Salim +Signed-off-by: Victor Nogueira +Link: https://patch.msgid.link/20250425220710.3964791-2-victor@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_drr.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c +index c69b999fae171..25b77ed0c1f28 100644 +--- a/net/sched/sch_drr.c ++++ b/net/sched/sch_drr.c +@@ -35,6 +35,11 @@ struct drr_sched { + struct Qdisc_class_hash clhash; + }; + ++static bool cl_is_active(struct drr_class *cl) ++{ ++ return !list_empty(&cl->alist); ++} ++ + static struct drr_class *drr_find_class(struct Qdisc *sch, u32 classid) + { + struct drr_sched *q = qdisc_priv(sch); +@@ -336,7 +341,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct drr_sched *q = qdisc_priv(sch); + struct drr_class *cl; + int err = 0; +- bool first; + + cl = drr_classify(skb, sch, &err); + if (cl == NULL) { +@@ -346,7 +350,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return err; + } + +- first = !cl->qdisc->q.qlen; + err = qdisc_enqueue(skb, cl->qdisc, to_free); + if (unlikely(err != NET_XMIT_SUCCESS)) { + if (net_xmit_drop_count(err)) { +@@ -356,7 +359,7 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return err; + } + +- if (first) { ++ if (!cl_is_active(cl)) { + list_add_tail(&cl->alist, &q->active); + cl->deficit = cl->quantum; + } +-- +2.39.5 + diff --git a/queue-6.12/net_sched-ets-fix-double-list-add-in-class-with-nete.patch b/queue-6.12/net_sched-ets-fix-double-list-add-in-class-with-nete.patch new file mode 100644 index 0000000000..c5ef25d64f --- /dev/null +++ b/queue-6.12/net_sched-ets-fix-double-list-add-in-class-with-nete.patch @@ -0,0 +1,75 @@ +From b81f1221720f55ae5f84f0cb61253da4aa31cc04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 19:07:07 -0300 +Subject: net_sched: ets: Fix double list add in class with netem as child + qdisc + +From: Victor Nogueira + +[ Upstream commit 1a6d0c00fa07972384b0c308c72db091d49988b6 ] + +As described in Gerrard's report [1], there are use cases where a netem +child qdisc will make the parent qdisc's enqueue callback reentrant. +In the case of ets, there won't be a UAF, but the code will add the same +classifier to the list twice, which will cause memory corruption. + +In addition to checking for qlen being zero, this patch checks whether +the class was already added to the active_list (cl_is_active) before +doing the addition to cater for the reentrant case. + +[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/ + +Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs") +Acked-by: Jamal Hadi Salim +Signed-off-by: Victor Nogueira +Link: https://patch.msgid.link/20250425220710.3964791-4-victor@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_ets.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c +index 516038a441638..9e4cd2cefa8c6 100644 +--- a/net/sched/sch_ets.c ++++ b/net/sched/sch_ets.c +@@ -74,6 +74,11 @@ static const struct nla_policy ets_class_policy[TCA_ETS_MAX + 1] = { + [TCA_ETS_QUANTA_BAND] = { .type = NLA_U32 }, + }; + ++static bool cl_is_active(struct ets_class *cl) ++{ ++ return !list_empty(&cl->alist); ++} ++ + static int ets_quantum_parse(struct Qdisc *sch, const struct nlattr *attr, + unsigned int *quantum, + struct netlink_ext_ack *extack) +@@ -416,7 +421,6 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct ets_sched *q = qdisc_priv(sch); + struct ets_class *cl; + int err = 0; +- bool first; + + cl = ets_classify(skb, sch, &err); + if (!cl) { +@@ -426,7 +430,6 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return err; + } + +- first = !cl->qdisc->q.qlen; + err = qdisc_enqueue(skb, cl->qdisc, to_free); + if (unlikely(err != NET_XMIT_SUCCESS)) { + if (net_xmit_drop_count(err)) { +@@ -436,7 +439,7 @@ static int ets_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, + return err; + } + +- if (first && !ets_class_is_strict(q, cl)) { ++ if (!cl_is_active(cl) && !ets_class_is_strict(q, cl)) { + list_add_tail(&cl->alist, &q->active); + cl->deficit = cl->quantum; + } +-- +2.39.5 + diff --git a/queue-6.12/net_sched-hfsc-fix-a-uaf-vulnerability-in-class-with.patch b/queue-6.12/net_sched-hfsc-fix-a-uaf-vulnerability-in-class-with.patch new file mode 100644 index 0000000000..cd74ec6064 --- /dev/null +++ b/queue-6.12/net_sched-hfsc-fix-a-uaf-vulnerability-in-class-with.patch @@ -0,0 +1,49 @@ +From d51fefc92b5020fb7f59bad008ccc44b146be5ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 19:07:06 -0300 +Subject: net_sched: hfsc: Fix a UAF vulnerability in class with netem as child + qdisc + +From: Victor Nogueira + +[ Upstream commit 141d34391abbb315d68556b7c67ad97885407547 ] + +As described in Gerrard's report [1], we have a UAF case when an hfsc class +has a netem child qdisc. The crux of the issue is that hfsc is assuming +that checking for cl->qdisc->q.qlen == 0 guarantees that it hasn't inserted +the class in the vttree or eltree (which is not true for the netem +duplicate case). + +This patch checks the n_active class variable to make sure that the code +won't insert the class in the vttree or eltree twice, catering for the +reentrant case. + +[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/ + +Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs") +Reported-by: Gerrard Tai +Acked-by: Jamal Hadi Salim +Signed-off-by: Victor Nogueira +Link: https://patch.msgid.link/20250425220710.3964791-3-victor@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_hfsc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c +index 5bb4ab9941d6e..1c857dc95e4f3 100644 +--- a/net/sched/sch_hfsc.c ++++ b/net/sched/sch_hfsc.c +@@ -1565,7 +1565,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + return err; + } + +- if (first) { ++ if (first && !cl->cl_nactive) { + if (cl->cl_flags & HFSC_RSC) + init_ed(cl, len); + if (cl->cl_flags & HFSC_FSC) +-- +2.39.5 + diff --git a/queue-6.12/net_sched-qfq-fix-double-list-add-in-class-with-nete.patch b/queue-6.12/net_sched-qfq-fix-double-list-add-in-class-with-nete.patch new file mode 100644 index 0000000000..21e7e82faf --- /dev/null +++ b/queue-6.12/net_sched-qfq-fix-double-list-add-in-class-with-nete.patch @@ -0,0 +1,77 @@ +From 6114129738fff902148749fefd499458b3c70b30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 19:07:08 -0300 +Subject: net_sched: qfq: Fix double list add in class with netem as child + qdisc + +From: Victor Nogueira + +[ Upstream commit f139f37dcdf34b67f5bf92bc8e0f7f6b3ac63aa4 ] + +As described in Gerrard's report [1], there are use cases where a netem +child qdisc will make the parent qdisc's enqueue callback reentrant. +In the case of qfq, there won't be a UAF, but the code will add the same +classifier to the list twice, which will cause memory corruption. + +This patch checks whether the class was already added to the agg->active +list (cl_is_active) before doing the addition to cater for the reentrant +case. + +[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/ + +Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs") +Acked-by: Jamal Hadi Salim +Signed-off-by: Victor Nogueira +Link: https://patch.msgid.link/20250425220710.3964791-5-victor@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_qfq.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c +index d584c0c25899c..0a1f5ebfdd412 100644 +--- a/net/sched/sch_qfq.c ++++ b/net/sched/sch_qfq.c +@@ -202,6 +202,11 @@ struct qfq_sched { + */ + enum update_reason {enqueue, requeue}; + ++static bool cl_is_active(struct qfq_class *cl) ++{ ++ return !list_empty(&cl->alist); ++} ++ + static struct qfq_class *qfq_find_class(struct Qdisc *sch, u32 classid) + { + struct qfq_sched *q = qdisc_priv(sch); +@@ -1217,7 +1222,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct qfq_class *cl; + struct qfq_aggregate *agg; + int err = 0; +- bool first; + + cl = qfq_classify(skb, sch, &err); + if (cl == NULL) { +@@ -1239,7 +1243,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, + } + + gso_segs = skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; +- first = !cl->qdisc->q.qlen; + err = qdisc_enqueue(skb, cl->qdisc, to_free); + if (unlikely(err != NET_XMIT_SUCCESS)) { + pr_debug("qfq_enqueue: enqueue failed %d\n", err); +@@ -1255,8 +1258,8 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, + ++sch->q.qlen; + + agg = cl->agg; +- /* if the queue was not empty, then done here */ +- if (!first) { ++ /* if the class is active, then done here */ ++ if (cl_is_active(cl)) { + if (unlikely(skb == cl->qdisc->ops->peek(cl->qdisc)) && + list_first_entry(&agg->active, struct qfq_class, alist) + == cl && cl->deficit < len) +-- +2.39.5 + diff --git a/queue-6.12/nvme-pci-fix-queue-unquiesce-check-on-slot_reset.patch b/queue-6.12/nvme-pci-fix-queue-unquiesce-check-on-slot_reset.patch new file mode 100644 index 0000000000..0e4cc7efe1 --- /dev/null +++ b/queue-6.12/nvme-pci-fix-queue-unquiesce-check-on-slot_reset.patch @@ -0,0 +1,38 @@ +From ff36dd725f44ae95a61184386f57eadab4bbddbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 10:18:01 -0700 +Subject: nvme-pci: fix queue unquiesce check on slot_reset + +From: Keith Busch + +[ Upstream commit a75401227eeb827b1a162df1aa9d5b33da921c43 ] + +A zero return means the reset was successfully scheduled. We don't want +to unquiesce the queues while the reset_work is pending, as that will +just flush out requeued requests to a failed completion. + +Fixes: 71a5bb153be104 ("nvme: ensure disabling pairs with unquiesce") +Reported-by: Dhankaran Singh Ajravat +Signed-off-by: Keith Busch +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index e70618e8d35eb..83ee433b69415 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3535,7 +3535,7 @@ static pci_ers_result_t nvme_slot_reset(struct pci_dev *pdev) + + dev_info(dev->ctrl.device, "restart after slot reset\n"); + pci_restore_state(pdev); +- if (!nvme_try_sched_reset(&dev->ctrl)) ++ if (nvme_try_sched_reset(&dev->ctrl)) + nvme_unquiesce_io_queues(&dev->ctrl); + return PCI_ERS_RESULT_RECOVERED; + } +-- +2.39.5 + diff --git a/queue-6.12/nvme-tcp-fix-premature-queue-removal-and-i-o-failove.patch b/queue-6.12/nvme-tcp-fix-premature-queue-removal-and-i-o-failove.patch new file mode 100644 index 0000000000..0147a6bf43 --- /dev/null +++ b/queue-6.12/nvme-tcp-fix-premature-queue-removal-and-i-o-failove.patch @@ -0,0 +1,112 @@ +From 0e8b5c329fd6546d40a60c0992f4ea403099e572 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 10:42:01 -0600 +Subject: nvme-tcp: fix premature queue removal and I/O failover +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michael Liang + +[ Upstream commit 77e40bbce93059658aee02786a32c5c98a240a8a ] + +This patch addresses a data corruption issue observed in nvme-tcp during +testing. + +In an NVMe native multipath setup, when an I/O timeout occurs, all +inflight I/Os are canceled almost immediately after the kernel socket is +shut down. These canceled I/Os are reported as host path errors, +triggering a failover that succeeds on a different path. + +However, at this point, the original I/O may still be outstanding in the +host's network transmission path (e.g., the NIC’s TX queue). From the +user-space app's perspective, the buffer associated with the I/O is +considered completed since they're acked on the different path and may +be reused for new I/O requests. + +Because nvme-tcp enables zero-copy by default in the transmission path, +this can lead to corrupted data being sent to the original target, +ultimately causing data corruption. + +We can reproduce this data corruption by injecting delay on one path and +triggering i/o timeout. + +To prevent this issue, this change ensures that all inflight +transmissions are fully completed from host's perspective before +returning from queue stop. To handle concurrent I/O timeout from multiple +namespaces under the same controller, always wait in queue stop +regardless of queue's state. + +This aligns with the behavior of queue stopping in other NVMe fabric +transports. + +Fixes: 3f2304f8c6d6 ("nvme-tcp: add NVMe over TCP host driver") +Signed-off-by: Michael Liang +Reviewed-by: Mohamed Khalfella +Reviewed-by: Randy Jennings +Reviewed-by: Sagi Grimberg +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/tcp.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c +index 854aa6a070ca8..4cc72be28c731 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -1944,7 +1944,7 @@ static void __nvme_tcp_stop_queue(struct nvme_tcp_queue *queue) + cancel_work_sync(&queue->io_work); + } + +-static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid) ++static void nvme_tcp_stop_queue_nowait(struct nvme_ctrl *nctrl, int qid) + { + struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); + struct nvme_tcp_queue *queue = &ctrl->queues[qid]; +@@ -1963,6 +1963,31 @@ static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid) + mutex_unlock(&queue->queue_lock); + } + ++static void nvme_tcp_wait_queue(struct nvme_ctrl *nctrl, int qid) ++{ ++ struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); ++ struct nvme_tcp_queue *queue = &ctrl->queues[qid]; ++ int timeout = 100; ++ ++ while (timeout > 0) { ++ if (!test_bit(NVME_TCP_Q_ALLOCATED, &queue->flags) || ++ !sk_wmem_alloc_get(queue->sock->sk)) ++ return; ++ msleep(2); ++ timeout -= 2; ++ } ++ dev_warn(nctrl->device, ++ "qid %d: timeout draining sock wmem allocation expired\n", ++ qid); ++} ++ ++static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid) ++{ ++ nvme_tcp_stop_queue_nowait(nctrl, qid); ++ nvme_tcp_wait_queue(nctrl, qid); ++} ++ ++ + static void nvme_tcp_setup_sock_ops(struct nvme_tcp_queue *queue) + { + write_lock_bh(&queue->sock->sk->sk_callback_lock); +@@ -2030,7 +2055,9 @@ static void nvme_tcp_stop_io_queues(struct nvme_ctrl *ctrl) + int i; + + for (i = 1; i < ctrl->queue_count; i++) +- nvme_tcp_stop_queue(ctrl, i); ++ nvme_tcp_stop_queue_nowait(ctrl, i); ++ for (i = 1; i < ctrl->queue_count; i++) ++ nvme_tcp_wait_queue(ctrl, i); + } + + static int nvme_tcp_start_io_queues(struct nvme_ctrl *ctrl, +-- +2.39.5 + diff --git a/queue-6.12/nvme-tcp-select-config_tls-from-config_nvme_tcp_tls.patch b/queue-6.12/nvme-tcp-select-config_tls-from-config_nvme_tcp_tls.patch new file mode 100644 index 0000000000..8ff61b5691 --- /dev/null +++ b/queue-6.12/nvme-tcp-select-config_tls-from-config_nvme_tcp_tls.patch @@ -0,0 +1,38 @@ +From 83a0bcc51736ae6fa6418ae94a3bad7e0f35633f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 08:40:25 +1000 +Subject: nvme-tcp: select CONFIG_TLS from CONFIG_NVME_TCP_TLS + +From: Alistair Francis + +[ Upstream commit 521987940ad4fd37fe3d0340ec6f39c4e8e91e36 ] + +Ensure that TLS support is enabled in the kernel when +CONFIG_NVME_TCP_TLS is enabled. Without this the code compiles, but does +not actually work unless something else enables CONFIG_TLS. + +Fixes: be8e82caa68 ("nvme-tcp: enable TLS handshake upcall") +Signed-off-by: Alistair Francis +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig +index 486afe5981845..09ed1f61c9a85 100644 +--- a/drivers/nvme/host/Kconfig ++++ b/drivers/nvme/host/Kconfig +@@ -97,6 +97,7 @@ config NVME_TCP_TLS + depends on NVME_TCP + select NET_HANDSHAKE + select KEYS ++ select TLS + help + Enables TLS encryption for NVMe TCP using the netlink handshake API. + +-- +2.39.5 + diff --git a/queue-6.12/nvmet-tcp-select-config_tls-from-config_nvme_target_.patch b/queue-6.12/nvmet-tcp-select-config_tls-from-config_nvme_target_.patch new file mode 100644 index 0000000000..914de402e1 --- /dev/null +++ b/queue-6.12/nvmet-tcp-select-config_tls-from-config_nvme_target_.patch @@ -0,0 +1,38 @@ +From 4b8417148c94d78432808b3a094b11aea8dd6a79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 08:23:47 +1000 +Subject: nvmet-tcp: select CONFIG_TLS from CONFIG_NVME_TARGET_TCP_TLS + +From: Alistair Francis + +[ Upstream commit ac38b7ef704c0659568fd4b2c7e6c1255fc51798 ] + +Ensure that TLS support is enabled in the kernel when +CONFIG_NVME_TARGET_TCP_TLS is enabled. Without this the code compiles, +but does not actually work unless something else enables CONFIG_TLS. + +Fixes: 675b453e0241 ("nvmet-tcp: enable TLS handshake upcall") +Signed-off-by: Alistair Francis +Reviewed-by: Hannes Reinecke +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig +index 46be031f91b43..34438cec32b90 100644 +--- a/drivers/nvme/target/Kconfig ++++ b/drivers/nvme/target/Kconfig +@@ -98,6 +98,7 @@ config NVME_TARGET_TCP_TLS + bool "NVMe over Fabrics TCP target TLS encryption support" + depends on NVME_TARGET_TCP + select NET_HANDSHAKE ++ select TLS + help + Enables TLS encryption for the NVMe TCP target using the netlink handshake API. + +-- +2.39.5 + diff --git a/queue-6.12/octeon_ep-fix-host-hang-issue-during-device-reboot.patch b/queue-6.12/octeon_ep-fix-host-hang-issue-during-device-reboot.patch new file mode 100644 index 0000000000..49bca6141d --- /dev/null +++ b/queue-6.12/octeon_ep-fix-host-hang-issue-during-device-reboot.patch @@ -0,0 +1,47 @@ +From e2b542c6789bae445be10616317838488a7a6855 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 04:46:24 -0700 +Subject: octeon_ep: Fix host hang issue during device reboot + +From: Sathesh B Edara + +[ Upstream commit 34f42736b325287a7b2ce37e415838f539767bda ] + +When the host loses heartbeat messages from the device, +the driver calls the device-specific ndo_stop function, +which frees the resources. If the driver is unloaded in +this scenario, it calls ndo_stop again, attempting to free +resources that have already been freed, leading to a host +hang issue. To resolve this, dev_close should be called +instead of the device-specific stop function.dev_close +internally calls ndo_stop to stop the network interface +and performs additional cleanup tasks. During the driver +unload process, if the device is already down, ndo_stop +is not called. + +Fixes: 5cb96c29aa0e ("octeon_ep: add heartbeat monitor") +Signed-off-by: Sathesh B Edara +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250429114624.19104-1-sedara@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeon_ep/octep_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +index a89f80bac39b8..1b2f5cae06449 100644 +--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c ++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +@@ -1184,7 +1184,7 @@ static void octep_hb_timeout_task(struct work_struct *work) + miss_cnt); + rtnl_lock(); + if (netif_running(oct->netdev)) +- octep_stop(oct->netdev); ++ dev_close(oct->netdev); + rtnl_unlock(); + } + +-- +2.39.5 + diff --git a/queue-6.12/octeon_ep_vf-resolve-netdevice-usage-count-issue.patch b/queue-6.12/octeon_ep_vf-resolve-netdevice-usage-count-issue.patch new file mode 100644 index 0000000000..1cbce1dcb5 --- /dev/null +++ b/queue-6.12/octeon_ep_vf-resolve-netdevice-usage-count-issue.patch @@ -0,0 +1,43 @@ +From 477f51fe561b53be6d1b22c7c362841cb6598ce1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 06:39:44 -0700 +Subject: octeon_ep_vf: Resolve netdevice usage count issue + +From: Sathesh B Edara + +[ Upstream commit 8548c84c004be3da4ffbe35ed0589041a4050c03 ] + +The netdevice usage count increases during transmit queue timeouts +because netdev_hold is called in ndo_tx_timeout, scheduling a task +to reinitialize the card. Although netdev_put is called at the end +of the scheduled work, rtnl_unlock checks the reference count during +cleanup. This could cause issues if transmit timeout is called on +multiple queues. + +Fixes: cb7dd712189f ("octeon_ep_vf: Add driver framework and device initialization") +Signed-off-by: Sathesh B Edara +Link: https://patch.msgid.link/20250424133944.28128-1-sedara@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c +index 18c922dd5fc64..ccb69bc5c9529 100644 +--- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c ++++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c +@@ -835,7 +835,9 @@ static void octep_vf_tx_timeout(struct net_device *netdev, unsigned int txqueue) + struct octep_vf_device *oct = netdev_priv(netdev); + + netdev_hold(netdev, NULL, GFP_ATOMIC); +- schedule_work(&oct->tx_timeout_task); ++ if (!schedule_work(&oct->tx_timeout_task)) ++ netdev_put(netdev, NULL); ++ + } + + static int octep_vf_set_mac(struct net_device *netdev, void *p) +-- +2.39.5 + diff --git a/queue-6.12/pds_core-make-pdsc_auxbus_dev_del-void.patch b/queue-6.12/pds_core-make-pdsc_auxbus_dev_del-void.patch new file mode 100644 index 0000000000..331396afd1 --- /dev/null +++ b/queue-6.12/pds_core-make-pdsc_auxbus_dev_del-void.patch @@ -0,0 +1,87 @@ +From 0fdd1b2083bfb6992b295674d79ec1472b4307ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Mar 2025 12:44:07 -0700 +Subject: pds_core: make pdsc_auxbus_dev_del() void + +From: Shannon Nelson + +[ Upstream commit e8562da829432d04a0de1830146984c89844f35e ] + +Since there really is no useful return, advertising a return value +is rather misleading. Make pdsc_auxbus_dev_del() a void function. + +Link: https://patch.msgid.link/r/20250320194412.67983-2-shannon.nelson@amd.com +Reviewed-by: Leon Romanovsky +Reviewed-by: Jonathan Cameron +Reviewed-by: Kalesh AP +Reviewed-by: Dave Jiang +Signed-off-by: Shannon Nelson +Signed-off-by: Jason Gunthorpe +Stable-dep-of: dfd76010f8e8 ("pds_core: remove write-after-free of client_id") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/amd/pds_core/auxbus.c | 7 +------ + drivers/net/ethernet/amd/pds_core/core.h | 2 +- + drivers/net/ethernet/amd/pds_core/devlink.c | 6 ++++-- + 3 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c +index b76a9b7e0aed6..d53b2124b1498 100644 +--- a/drivers/net/ethernet/amd/pds_core/auxbus.c ++++ b/drivers/net/ethernet/amd/pds_core/auxbus.c +@@ -172,13 +172,9 @@ static struct pds_auxiliary_dev *pdsc_auxbus_dev_register(struct pdsc *cf, + return padev; + } + +-int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf) ++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf) + { + struct pds_auxiliary_dev *padev; +- int err = 0; +- +- if (!cf) +- return -ENODEV; + + mutex_lock(&pf->config_lock); + +@@ -192,7 +188,6 @@ int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf) + pf->vfs[cf->vf_id].padev = NULL; + + mutex_unlock(&pf->config_lock); +- return err; + } + + int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) +diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h +index ec637dc4327a5..08b8280437dcf 100644 +--- a/drivers/net/ethernet/amd/pds_core/core.h ++++ b/drivers/net/ethernet/amd/pds_core/core.h +@@ -304,7 +304,7 @@ int pdsc_register_notify(struct notifier_block *nb); + void pdsc_unregister_notify(struct notifier_block *nb); + void pdsc_notify(unsigned long event, void *data); + int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf); +-int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf); ++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf); + + void pdsc_process_adminq(struct pdsc_qcq *qcq); + void pdsc_work_thread(struct work_struct *work); +diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c +index ca23cde385e67..48a7c22fe3320 100644 +--- a/drivers/net/ethernet/amd/pds_core/devlink.c ++++ b/drivers/net/ethernet/amd/pds_core/devlink.c +@@ -56,8 +56,10 @@ int pdsc_dl_enable_set(struct devlink *dl, u32 id, + for (vf_id = 0; vf_id < pdsc->num_vfs; vf_id++) { + struct pdsc *vf = pdsc->vfs[vf_id].vf; + +- err = ctx->val.vbool ? pdsc_auxbus_dev_add(vf, pdsc) : +- pdsc_auxbus_dev_del(vf, pdsc); ++ if (ctx->val.vbool) ++ err = pdsc_auxbus_dev_add(vf, pdsc); ++ else ++ pdsc_auxbus_dev_del(vf, pdsc); + } + + return err; +-- +2.39.5 + diff --git a/queue-6.12/pds_core-remove-write-after-free-of-client_id.patch b/queue-6.12/pds_core-remove-write-after-free-of-client_id.patch new file mode 100644 index 0000000000..5b86577579 --- /dev/null +++ b/queue-6.12/pds_core-remove-write-after-free-of-client_id.patch @@ -0,0 +1,52 @@ +From 90c2a08e5b038b52857fca1b56d70575301d31c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 13:38:57 -0700 +Subject: pds_core: remove write-after-free of client_id + +From: Shannon Nelson + +[ Upstream commit dfd76010f8e821b66116dec3c7d90dd2403d1396 ] + +A use-after-free error popped up in stress testing: + +[Mon Apr 21 21:21:33 2025] BUG: KFENCE: use-after-free write in pdsc_auxbus_dev_del+0xef/0x160 [pds_core] +[Mon Apr 21 21:21:33 2025] Use-after-free write at 0x000000007013ecd1 (in kfence-#47): +[Mon Apr 21 21:21:33 2025] pdsc_auxbus_dev_del+0xef/0x160 [pds_core] +[Mon Apr 21 21:21:33 2025] pdsc_remove+0xc0/0x1b0 [pds_core] +[Mon Apr 21 21:21:33 2025] pci_device_remove+0x24/0x70 +[Mon Apr 21 21:21:33 2025] device_release_driver_internal+0x11f/0x180 +[Mon Apr 21 21:21:33 2025] driver_detach+0x45/0x80 +[Mon Apr 21 21:21:33 2025] bus_remove_driver+0x83/0xe0 +[Mon Apr 21 21:21:33 2025] pci_unregister_driver+0x1a/0x80 + +The actual device uninit usually happens on a separate thread +scheduled after this code runs, but there is no guarantee of order +of thread execution, so this could be a problem. There's no +actual need to clear the client_id at this point, so simply +remove the offending code. + +Fixes: 10659034c622 ("pds_core: add the aux client API") +Signed-off-by: Shannon Nelson +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250425203857.71547-1-shannon.nelson@amd.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/amd/pds_core/auxbus.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c +index 4d3387bebe6a4..889a18962270a 100644 +--- a/drivers/net/ethernet/amd/pds_core/auxbus.c ++++ b/drivers/net/ethernet/amd/pds_core/auxbus.c +@@ -186,7 +186,6 @@ void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf, + pds_client_unregister(pf, padev->client_id); + auxiliary_device_delete(&padev->aux_dev); + auxiliary_device_uninit(&padev->aux_dev); +- padev->client_id = 0; + *pd_ptr = NULL; + + mutex_unlock(&pf->config_lock); +-- +2.39.5 + diff --git a/queue-6.12/pds_core-specify-auxiliary_device-to-be-created.patch b/queue-6.12/pds_core-specify-auxiliary_device-to-be-created.patch new file mode 100644 index 0000000000..8b384c8326 --- /dev/null +++ b/queue-6.12/pds_core-specify-auxiliary_device-to-be-created.patch @@ -0,0 +1,195 @@ +From 01911431386e672f2abf1f686d0dbb5682f362ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Mar 2025 12:44:08 -0700 +Subject: pds_core: specify auxiliary_device to be created + +From: Shannon Nelson + +[ Upstream commit b699bdc720c0255d1bb76cecba7382c1f2107af5 ] + +In preparation for adding a new auxiliary_device for the PF, +make the vif type an argument to pdsc_auxbus_dev_add(). Pass in +the address of the padev pointer so that the caller can specify +where to save it and keep the mutex usage within the function. + +Link: https://patch.msgid.link/r/20250320194412.67983-3-shannon.nelson@amd.com +Reviewed-by: Leon Romanovsky +Reviewed-by: Jonathan Cameron +Reviewed-by: Dave Jiang +Signed-off-by: Shannon Nelson +Signed-off-by: Jason Gunthorpe +Stable-dep-of: dfd76010f8e8 ("pds_core: remove write-after-free of client_id") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/amd/pds_core/auxbus.c | 37 ++++++++++----------- + drivers/net/ethernet/amd/pds_core/core.h | 7 ++-- + drivers/net/ethernet/amd/pds_core/devlink.c | 5 +-- + drivers/net/ethernet/amd/pds_core/main.c | 11 +++--- + 4 files changed, 33 insertions(+), 27 deletions(-) + +diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c +index d53b2124b1498..4d3387bebe6a4 100644 +--- a/drivers/net/ethernet/amd/pds_core/auxbus.c ++++ b/drivers/net/ethernet/amd/pds_core/auxbus.c +@@ -172,29 +172,32 @@ static struct pds_auxiliary_dev *pdsc_auxbus_dev_register(struct pdsc *cf, + return padev; + } + +-void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf) ++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf, ++ struct pds_auxiliary_dev **pd_ptr) + { + struct pds_auxiliary_dev *padev; + ++ if (!*pd_ptr) ++ return; ++ + mutex_lock(&pf->config_lock); + +- padev = pf->vfs[cf->vf_id].padev; +- if (padev) { +- pds_client_unregister(pf, padev->client_id); +- auxiliary_device_delete(&padev->aux_dev); +- auxiliary_device_uninit(&padev->aux_dev); +- padev->client_id = 0; +- } +- pf->vfs[cf->vf_id].padev = NULL; ++ padev = *pd_ptr; ++ pds_client_unregister(pf, padev->client_id); ++ auxiliary_device_delete(&padev->aux_dev); ++ auxiliary_device_uninit(&padev->aux_dev); ++ padev->client_id = 0; ++ *pd_ptr = NULL; + + mutex_unlock(&pf->config_lock); + } + +-int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) ++int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf, ++ enum pds_core_vif_types vt, ++ struct pds_auxiliary_dev **pd_ptr) + { + struct pds_auxiliary_dev *padev; + char devname[PDS_DEVNAME_LEN]; +- enum pds_core_vif_types vt; + unsigned long mask; + u16 vt_support; + int client_id; +@@ -203,6 +206,9 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) + if (!cf) + return -ENODEV; + ++ if (vt >= PDS_DEV_TYPE_MAX) ++ return -EINVAL; ++ + mutex_lock(&pf->config_lock); + + mask = BIT_ULL(PDSC_S_FW_DEAD) | +@@ -214,17 +220,10 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) + goto out_unlock; + } + +- /* We only support vDPA so far, so it is the only one to +- * be verified that it is available in the Core device and +- * enabled in the devlink param. In the future this might +- * become a loop for several VIF types. +- */ +- + /* Verify that the type is supported and enabled. It is not + * an error if there is no auxbus device support for this + * VF, it just means something else needs to happen with it. + */ +- vt = PDS_DEV_TYPE_VDPA; + vt_support = !!le16_to_cpu(pf->dev_ident.vif_types[vt]); + if (!(vt_support && + pf->viftype_status[vt].supported && +@@ -250,7 +249,7 @@ int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf) + err = PTR_ERR(padev); + goto out_unlock; + } +- pf->vfs[cf->vf_id].padev = padev; ++ *pd_ptr = padev; + + out_unlock: + mutex_unlock(&pf->config_lock); +diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h +index 08b8280437dcf..becd3104473c2 100644 +--- a/drivers/net/ethernet/amd/pds_core/core.h ++++ b/drivers/net/ethernet/amd/pds_core/core.h +@@ -303,8 +303,11 @@ void pdsc_health_thread(struct work_struct *work); + int pdsc_register_notify(struct notifier_block *nb); + void pdsc_unregister_notify(struct notifier_block *nb); + void pdsc_notify(unsigned long event, void *data); +-int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf); +-void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf); ++int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf, ++ enum pds_core_vif_types vt, ++ struct pds_auxiliary_dev **pd_ptr); ++void pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf, ++ struct pds_auxiliary_dev **pd_ptr); + + void pdsc_process_adminq(struct pdsc_qcq *qcq); + void pdsc_work_thread(struct work_struct *work); +diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c +index 48a7c22fe3320..d8dc39da4161f 100644 +--- a/drivers/net/ethernet/amd/pds_core/devlink.c ++++ b/drivers/net/ethernet/amd/pds_core/devlink.c +@@ -57,9 +57,10 @@ int pdsc_dl_enable_set(struct devlink *dl, u32 id, + struct pdsc *vf = pdsc->vfs[vf_id].vf; + + if (ctx->val.vbool) +- err = pdsc_auxbus_dev_add(vf, pdsc); ++ err = pdsc_auxbus_dev_add(vf, pdsc, vt_entry->vif_id, ++ &pdsc->vfs[vf_id].padev); + else +- pdsc_auxbus_dev_del(vf, pdsc); ++ pdsc_auxbus_dev_del(vf, pdsc, &pdsc->vfs[vf_id].padev); + } + + return err; +diff --git a/drivers/net/ethernet/amd/pds_core/main.c b/drivers/net/ethernet/amd/pds_core/main.c +index 660268ff95623..a3a68889137b6 100644 +--- a/drivers/net/ethernet/amd/pds_core/main.c ++++ b/drivers/net/ethernet/amd/pds_core/main.c +@@ -190,7 +190,8 @@ static int pdsc_init_vf(struct pdsc *vf) + devl_unlock(dl); + + pf->vfs[vf->vf_id].vf = vf; +- err = pdsc_auxbus_dev_add(vf, pf); ++ err = pdsc_auxbus_dev_add(vf, pf, PDS_DEV_TYPE_VDPA, ++ &pf->vfs[vf->vf_id].padev); + if (err) { + devl_lock(dl); + devl_unregister(dl); +@@ -417,7 +418,7 @@ static void pdsc_remove(struct pci_dev *pdev) + + pf = pdsc_get_pf_struct(pdsc->pdev); + if (!IS_ERR(pf)) { +- pdsc_auxbus_dev_del(pdsc, pf); ++ pdsc_auxbus_dev_del(pdsc, pf, &pf->vfs[pdsc->vf_id].padev); + pf->vfs[pdsc->vf_id].vf = NULL; + } + } else { +@@ -482,7 +483,8 @@ static void pdsc_reset_prepare(struct pci_dev *pdev) + + pf = pdsc_get_pf_struct(pdsc->pdev); + if (!IS_ERR(pf)) +- pdsc_auxbus_dev_del(pdsc, pf); ++ pdsc_auxbus_dev_del(pdsc, pf, ++ &pf->vfs[pdsc->vf_id].padev); + } + + pdsc_unmap_bars(pdsc); +@@ -527,7 +529,8 @@ static void pdsc_reset_done(struct pci_dev *pdev) + + pf = pdsc_get_pf_struct(pdsc->pdev); + if (!IS_ERR(pf)) +- pdsc_auxbus_dev_add(pdsc, pf); ++ pdsc_auxbus_dev_add(pdsc, pf, PDS_DEV_TYPE_VDPA, ++ &pf->vfs[pdsc->vf_id].padev); + } + } + +-- +2.39.5 + diff --git a/queue-6.12/pinctrl-imx-return-null-if-no-group-is-matched-and-f.patch b/queue-6.12/pinctrl-imx-return-null-if-no-group-is-matched-and-f.patch new file mode 100644 index 0000000000..36ff0ef773 --- /dev/null +++ b/queue-6.12/pinctrl-imx-return-null-if-no-group-is-matched-and-f.patch @@ -0,0 +1,50 @@ +From 8969a08726ff0b8638606895e458399996fd2752 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Mar 2025 11:16:00 +0800 +Subject: pinctrl: imx: Return NULL if no group is matched and found + +From: Hui Wang + +[ Upstream commit e64c0ff0d5d85791fbcd126ee558100a06a24a97 ] + +Currently if no group is matched and found, this function will return +the last grp to the caller, this is not expected, it is supposed to +return NULL in this case. + +Fixes: e566fc11ea76 ("pinctrl: imx: use generic pinctrl helpers for managing groups") +Signed-off-by: Hui Wang +Reviewed-by: Frank Li +Link: https://lore.kernel.org/20250327031600.99723-1-hui.wang@canonical.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/freescale/pinctrl-imx.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c +index d05c2c478e795..4e1fe457a608a 100644 +--- a/drivers/pinctrl/freescale/pinctrl-imx.c ++++ b/drivers/pinctrl/freescale/pinctrl-imx.c +@@ -37,16 +37,16 @@ static inline const struct group_desc *imx_pinctrl_find_group_by_name( + struct pinctrl_dev *pctldev, + const char *name) + { +- const struct group_desc *grp = NULL; ++ const struct group_desc *grp; + int i; + + for (i = 0; i < pctldev->num_groups; i++) { + grp = pinctrl_generic_get_group(pctldev, i); + if (grp && !strcmp(grp->grp.name, name)) +- break; ++ return grp; + } + +- return grp; ++ return NULL; + } + + static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, +-- +2.39.5 + diff --git a/queue-6.12/powerpc-boot-check-for-ld-option-support.patch b/queue-6.12/powerpc-boot-check-for-ld-option-support.patch new file mode 100644 index 0000000000..efeb88df11 --- /dev/null +++ b/queue-6.12/powerpc-boot-check-for-ld-option-support.patch @@ -0,0 +1,53 @@ +From 25d3064a32109df99e4adb749acd12d4e4654e19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 06:12:18 +0530 +Subject: powerpc/boot: Check for ld-option support + +From: Madhavan Srinivasan + +[ Upstream commit b2accfe7ca5bc9f9af28e603b79bdd5ad8df5c0b ] + +Commit 579aee9fc594 ("powerpc: suppress some linker warnings in recent linker versions") +enabled support to add linker option "--no-warn-rwx-segments", +if the version is greater than 2.39. Similar build warning were +reported recently from linker version 2.35.2. + +ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions +ld: warning: arch/powerpc/boot/zImage.pseries has a LOAD segment with RWX permissions + +Fix the warning by checking for "--no-warn-rwx-segments" +option support in linker to enable it, instead of checking +for the version range. + +Fixes: 579aee9fc594 ("powerpc: suppress some linker warnings in recent linker versions") +Reported-by: Venkat Rao Bagalkote +Suggested-by: Christophe Leroy +Tested-by: Venkat Rao Bagalkote +Closes: https://lore.kernel.org/linuxppc-dev/61cf556c-4947-4bd6-af63-892fc0966dad@linux.ibm.com/ +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250401004218.24869-1-maddy@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/boot/wrapper | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper +index b1f5549a3c9c4..08f7a1386e8e0 100755 +--- a/arch/powerpc/boot/wrapper ++++ b/arch/powerpc/boot/wrapper +@@ -234,10 +234,8 @@ fi + + # suppress some warnings in recent ld versions + nowarn="-z noexecstack" +-if ! ld_is_lld; then +- if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then +- nowarn="$nowarn --no-warn-rwx-segments" +- fi ++if [ $(${CROSS}ld -v --no-warn-rwx-segments &>/dev/null; echo $?) -eq 0 ]; then ++ nowarn="$nowarn --no-warn-rwx-segments" + fi + + platformo=$object/"$platform".o +-- +2.39.5 + diff --git a/queue-6.12/powerpc-boot-fix-dash-warning.patch b/queue-6.12/powerpc-boot-fix-dash-warning.patch new file mode 100644 index 0000000000..652b77770a --- /dev/null +++ b/queue-6.12/powerpc-boot-fix-dash-warning.patch @@ -0,0 +1,53 @@ +From 638aea36133c7b6791069adec3097779ca1e3227 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 13:51:54 +0530 +Subject: powerpc/boot: Fix dash warning + +From: Madhavan Srinivasan + +[ Upstream commit e3f506b78d921e48a00d005bea5c45ec36a99240 ] + +'commit b2accfe7ca5b ("powerpc/boot: Check for ld-option support")' suppressed +linker warnings, but the expressed used did not go well with POSIX shell (dash) +resulting with this warning + +arch/powerpc/boot/wrapper: 237: [: 0: unexpected operator +ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions + +Fix the check to handle the reported warning. Patch also fixes +couple of shellcheck reported errors for the same line. + +In arch/powerpc/boot/wrapper line 237: +if [ $(${CROSS}ld -v --no-warn-rwx-segments &>/dev/null; echo $?) -eq 0 ]; then + ^-- SC2046 (warning): Quote this to prevent word splitting. + ^------^ SC2086 (info): Double quote to prevent globbing and word splitting. + ^---------^ SC3020 (warning): In POSIX sh, &> is undefined. + +Fixes: b2accfe7ca5b ("powerpc/boot: Check for ld-option support") +Reported-by: Stephen Rothwell +Suggested-by: Stephen Rothwell +Tested-by: Venkat Rao Bagalkote +Reviewed-by: Stephen Rothwell +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250423082154.30625-1-maddy@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/boot/wrapper | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper +index 08f7a1386e8e0..fd6db10ef9e65 100755 +--- a/arch/powerpc/boot/wrapper ++++ b/arch/powerpc/boot/wrapper +@@ -234,7 +234,7 @@ fi + + # suppress some warnings in recent ld versions + nowarn="-z noexecstack" +-if [ $(${CROSS}ld -v --no-warn-rwx-segments &>/dev/null; echo $?) -eq 0 ]; then ++if "${CROSS}ld" -v --no-warn-rwx-segments >/dev/null 2>&1; then + nowarn="$nowarn --no-warn-rwx-segments" + fi + +-- +2.39.5 + diff --git a/queue-6.12/ptp-ocp-fix-null-dereference-in-adva-board-sma-sysfs.patch b/queue-6.12/ptp-ocp-fix-null-dereference-in-adva-board-sma-sysfs.patch new file mode 100644 index 0000000000..93262d2817 --- /dev/null +++ b/queue-6.12/ptp-ocp-fix-null-dereference-in-adva-board-sma-sysfs.patch @@ -0,0 +1,97 @@ +From 60e63342c4588e088707a6e5f42c3d2377859c49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 10:33:20 +0300 +Subject: ptp: ocp: Fix NULL dereference in Adva board SMA sysfs operations + +From: Sagi Maimon + +[ Upstream commit e98386d79a23c57cf179fe4138322e277aa3aa74 ] + +On Adva boards, SMA sysfs store/get operations can call +__handle_signal_outputs() or __handle_signal_inputs() while the `irig` +and `dcf` pointers are uninitialized, leading to a NULL pointer +dereference in __handle_signal() and causing a kernel crash. Adva boards +don't use `irig` or `dcf` functionality, so add Adva-specific callbacks +`ptp_ocp_sma_adva_set_outputs()` and `ptp_ocp_sma_adva_set_inputs()` that +avoid invoking `irig` or `dcf` input/output routines. + +Fixes: ef61f5528fca ("ptp: ocp: add Adva timecard support") +Signed-off-by: Sagi Maimon +Reviewed-by: Vadim Fedorenko +Link: https://patch.msgid.link/20250429073320.33277-1-maimon.sagi@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/ptp/ptp_ocp.c | 52 +++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 50 insertions(+), 2 deletions(-) + +diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c +index 0eeb503e06c23..1a936829975e1 100644 +--- a/drivers/ptp/ptp_ocp.c ++++ b/drivers/ptp/ptp_ocp.c +@@ -2574,12 +2574,60 @@ static const struct ocp_sma_op ocp_fb_sma_op = { + .set_output = ptp_ocp_sma_fb_set_output, + }; + ++static int ++ptp_ocp_sma_adva_set_output(struct ptp_ocp *bp, int sma_nr, u32 val) ++{ ++ u32 reg, mask, shift; ++ unsigned long flags; ++ u32 __iomem *gpio; ++ ++ gpio = sma_nr > 2 ? &bp->sma_map1->gpio2 : &bp->sma_map2->gpio2; ++ shift = sma_nr & 1 ? 0 : 16; ++ ++ mask = 0xffff << (16 - shift); ++ ++ spin_lock_irqsave(&bp->lock, flags); ++ ++ reg = ioread32(gpio); ++ reg = (reg & mask) | (val << shift); ++ ++ iowrite32(reg, gpio); ++ ++ spin_unlock_irqrestore(&bp->lock, flags); ++ ++ return 0; ++} ++ ++static int ++ptp_ocp_sma_adva_set_inputs(struct ptp_ocp *bp, int sma_nr, u32 val) ++{ ++ u32 reg, mask, shift; ++ unsigned long flags; ++ u32 __iomem *gpio; ++ ++ gpio = sma_nr > 2 ? &bp->sma_map2->gpio1 : &bp->sma_map1->gpio1; ++ shift = sma_nr & 1 ? 0 : 16; ++ ++ mask = 0xffff << (16 - shift); ++ ++ spin_lock_irqsave(&bp->lock, flags); ++ ++ reg = ioread32(gpio); ++ reg = (reg & mask) | (val << shift); ++ ++ iowrite32(reg, gpio); ++ ++ spin_unlock_irqrestore(&bp->lock, flags); ++ ++ return 0; ++} ++ + static const struct ocp_sma_op ocp_adva_sma_op = { + .tbl = { ptp_ocp_adva_sma_in, ptp_ocp_adva_sma_out }, + .init = ptp_ocp_sma_fb_init, + .get = ptp_ocp_sma_fb_get, +- .set_inputs = ptp_ocp_sma_fb_set_inputs, +- .set_output = ptp_ocp_sma_fb_set_output, ++ .set_inputs = ptp_ocp_sma_adva_set_inputs, ++ .set_output = ptp_ocp_sma_adva_set_output, + }; + + static int +-- +2.39.5 + diff --git a/queue-6.12/rtase-modify-the-condition-used-to-detect-overflow-i.patch b/queue-6.12/rtase-modify-the-condition-used-to-detect-overflow-i.patch new file mode 100644 index 0000000000..448e6c1292 --- /dev/null +++ b/queue-6.12/rtase-modify-the-condition-used-to-detect-overflow-i.patch @@ -0,0 +1,66 @@ +From 122d571fdb437e47eefaab4ada6ae1420ef40820 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 12:04:44 +0800 +Subject: rtase: Modify the condition used to detect overflow in + rtase_calc_time_mitigation + +From: Justin Lai + +[ Upstream commit 68f9d8974b545668e1be2422240b25a92e304b14 ] + +Fix the following compile error reported by the kernel test +robot by modifying the condition used to detect overflow in +rtase_calc_time_mitigation. + +In file included from include/linux/mdio.h:10:0, + from drivers/net/ethernet/realtek/rtase/rtase_main.c:58: + In function 'u16_encode_bits', + inlined from 'rtase_calc_time_mitigation.constprop' at drivers/net/ + ethernet/realtek/rtase/rtase_main.c:1915:13, + inlined from 'rtase_init_software_variable.isra.41' at drivers/net/ + ethernet/realtek/rtase/rtase_main.c:1961:13, + inlined from 'rtase_init_one' at drivers/net/ethernet/realtek/ + rtase/rtase_main.c:2111:2: +>> include/linux/bitfield.h:178:3: error: call to '__field_overflow' + declared with attribute error: value doesn't fit into mask + __field_overflow(); \ + ^~~~~~~~~~~~~~~~~~ + include/linux/bitfield.h:198:2: note: in expansion of macro + '____MAKE_OP' + ____MAKE_OP(u##size,u##size,,) + ^~~~~~~~~~~ + include/linux/bitfield.h:200:1: note: in expansion of macro + '__MAKE_OP' + __MAKE_OP(16) + ^~~~~~~~~ + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202503182158.nkAlbJWX-lkp@intel.com/ +Fixes: a36e9f5cfe9e ("rtase: Add support for a pci table in this module") +Signed-off-by: Justin Lai +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250424040444.5530-1-justinlai0215@realtek.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/realtek/rtase/rtase_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/realtek/rtase/rtase_main.c b/drivers/net/ethernet/realtek/rtase/rtase_main.c +index 86dd034fdddc5..3a588aaa89c58 100644 +--- a/drivers/net/ethernet/realtek/rtase/rtase_main.c ++++ b/drivers/net/ethernet/realtek/rtase/rtase_main.c +@@ -1924,8 +1924,8 @@ static u16 rtase_calc_time_mitigation(u32 time_us) + + time_us = min_t(int, time_us, RTASE_MITI_MAX_TIME); + +- msb = fls(time_us); +- if (msb >= RTASE_MITI_COUNT_BIT_NUM) { ++ if (time_us > RTASE_MITI_TIME_COUNT_MASK) { ++ msb = fls(time_us); + time_unit = msb - RTASE_MITI_COUNT_BIT_NUM; + time_count = time_us >> (msb - RTASE_MITI_COUNT_BIT_NUM); + } else { +-- +2.39.5 + diff --git a/queue-6.12/scsi-ufs-core-remove-redundant-query_complete-trace.patch b/queue-6.12/scsi-ufs-core-remove-redundant-query_complete-trace.patch new file mode 100644 index 0000000000..49d93e66a1 --- /dev/null +++ b/queue-6.12/scsi-ufs-core-remove-redundant-query_complete-trace.patch @@ -0,0 +1,46 @@ +From 7dcecc7bf096a68b3041d8fd7334760452e4ac4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 10:06:05 +0900 +Subject: scsi: ufs: core: Remove redundant query_complete trace + +From: Keoseong Park + +[ Upstream commit 0e9693b97a0eee1df7bae33aec207c975fbcbdb8 ] + +The query_complete trace was not removed after ufshcd_issue_dev_cmd() was +called from the bsg path, resulting in duplicate output. + +Below is an example of the trace: + + ufs-utils-773 [000] ..... 218.176933: ufshcd_upiu: query_send: 0000:00:04.0: HDR:16 00 00 1f 00 01 00 00 00 00 00 00, OSF:03 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ufs-utils-773 [000] ..... 218.177145: ufshcd_upiu: query_complete: 0000:00:04.0: HDR:36 00 00 1f 00 01 00 00 00 00 00 00, OSF:03 07 00 00 00 00 00 00 00 00 00 08 00 00 00 00 + ufs-utils-773 [000] ..... 218.177146: ufshcd_upiu: query_complete: 0000:00:04.0: HDR:36 00 00 1f 00 01 00 00 00 00 00 00, OSF:03 07 00 00 00 00 00 00 00 00 00 08 00 00 00 00 + +Remove the redundant trace call in the bsg path, preventing duplication. + +Signed-off-by: Keoseong Park +Link: https://lore.kernel.org/r/20250425010605epcms2p67e89b351398832fe0fd547404d3afc65@epcms2p6 +Fixes: 71aabb747d5f ("scsi: ufs: core: Reuse exec_dev_cmd") +Reviewed-by: Avri Altman +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 8d4a5b8371b63..a9b032d2f4a8d 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -7256,8 +7256,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, + err = -EINVAL; + } + } +- ufshcd_add_query_upiu_trace(hba, err ? UFS_QUERY_ERR : UFS_QUERY_COMP, +- (struct utp_upiu_req *)lrbp->ucd_rsp_ptr); + + return err; + } +-- +2.39.5 + diff --git a/queue-6.12/series b/queue-6.12/series index 754444f9e5..76fec37831 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -50,3 +50,86 @@ cpufreq-fix-setting-policy-limits-when-frequency-tables-are-used.patch tracing-fix-oob-write-in-trace_seq_to_buffer.patch drm-amd-display-default-ips-to-rcg_in_active_ips2_in_off.patch asoc-soc-core-stop-using-of_property_read_bool-for-non-boolean-properties.patch +asoc-cs-amp-lib-test-don-t-select-snd_soc_cs_amp_lib.patch +asoc-soc-pcm-fix-hw_params-and-dapm-widget-sequence.patch +book3s64-radix-align-section-vmemmap-start-address-t.patch +pinctrl-imx-return-null-if-no-group-is-matched-and-f.patch +powerpc-boot-check-for-ld-option-support.patch +asoc-intel-sof_sdw-add-null-check-in-asoc_sdw_rt_dmi.patch +alsa-hda-realtek-enable-speaker-for-hp-platform.patch +drm-i915-pxp-fix-undefined-reference-to-intel_pxp_gs.patch +wifi-iwlwifi-don-t-warn-if-the-nic-is-gone-in-resume.patch +wifi-iwlwifi-fix-the-check-for-the-scratch-register-.patch +wifi-plfxlc-remove-erroneous-assert-in-plfxlc_mac_re.patch +powerpc-boot-fix-dash-warning.patch +vxlan-vnifilter-fix-unlocked-deletion-of-default-fdb.patch +xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch +net-mlx5e-use-custom-tunnel-header-for-vxlan-gbp.patch +net-mlx5-e-switch-initialize-mac-address-for-default.patch +net-mlx5e-tc-continue-the-attr-process-even-if-encap.patch +net-mlx5e-fix-lock-order-in-mlx5e_tx_reporter_ptpsq_.patch +net-mlx5-e-switch-fix-error-handling-for-enabling-ro.patch +accel-ivpu-correct-dct-interrupt-handling.patch +asoc-amd-acp-fix-null-pointer-deref-in-acp_i2s_set_t.patch +bluetooth-hci_conn-remove-alloc-from-critical-sectio.patch +bluetooth-hci_conn-fix-not-setting-conn_timeout-for-.patch +bluetooth-hci_conn-fix-not-setting-timeout-for-big-c.patch +bluetooth-btintel_pcie-avoid-redundant-buffer-alloca.patch +bluetooth-btusb-avoid-null-pointer-dereference-in-sk.patch +bluetooth-btintel_pcie-add-additional-to-checks-to-c.patch +bluetooth-l2cap-copy-rx-timestamp-to-new-fragments.patch +net-mscc-ocelot-delete-pvid-vlan-when-readding-it-as.patch +octeon_ep_vf-resolve-netdevice-usage-count-issue.patch +bnxt_en-improve-tx-timestamping-fifo-configuration.patch +rtase-modify-the-condition-used-to-detect-overflow-i.patch +net-ethernet-mtk-star-emac-fix-spinlock-recursion-is.patch +net-ethernet-mtk-star-emac-rearm-interrupts-in-rx_po.patch +net-ethernet-mtk_eth_soc-sync-mtk_clks_source_name-a.patch +pds_core-make-pdsc_auxbus_dev_del-void.patch +pds_core-specify-auxiliary_device-to-be-created.patch +pds_core-remove-write-after-free-of-client_id.patch +net_sched-drr-fix-double-list-add-in-class-with-nete.patch +net_sched-hfsc-fix-a-uaf-vulnerability-in-class-with.patch +net_sched-ets-fix-double-list-add-in-class-with-nete.patch +net_sched-qfq-fix-double-list-add-in-class-with-nete.patch +ice-check-vf-vsi-pointer-value-in-ice_vc_add_fdir_fl.patch +idpf-fix-offloads-support-for-encapsulated-packets.patch +scsi-ufs-core-remove-redundant-query_complete-trace.patch +alsa-ump-fix-buffer-overflow-at-ump-sysex-message-co.patch +nvme-pci-fix-queue-unquiesce-check-on-slot_reset.patch +drm-tests-shmem-fix-memleak.patch +drm-mipi-dbi-fix-blanking-for-non-16-bit-formats.patch +net-dlink-correct-endianness-handling-of-led_mode.patch +net-mdio-mux-meson-gxl-set-reversed-bit-when-using-i.patch +idpf-fix-potential-memory-leak-on-kcalloc-failure.patch +idpf-protect-shutdown-from-reset.patch +igc-fix-lock-order-in-igc_ptp_reset.patch +net-ethernet-mtk_eth_soc-fix-ser-panic-with-4gb-ram.patch +net-dsa-felix-fix-broken-taprio-gate-states-after-cl.patch +net-ipv6-fix-udpv6-gso-segmentation-with-nat.patch +alsa-hda-realtek-fix-built-mic-regression-on-other-a.patch +bnxt_en-fix-error-handling-path-in-bnxt_init_chip.patch +bnxt_en-fix-ethtool-selftest-output-in-one-of-the-fa.patch +bnxt_en-add-missing-skb_mark_for_recycle-in-bnxt_rx_.patch +bnxt_en-call-pci_alloc_irq_vectors-after-bnxt_reserv.patch +bnxt_en-fix-coredump-logic-to-free-allocated-buffer.patch +bnxt_en-fix-out-of-bound-memcpy-during-ethtool-w.patch +bnxt_en-fix-ethtool-d-byte-order-for-32-bit-values.patch +nvme-tcp-fix-premature-queue-removal-and-i-o-failove.patch +nvme-tcp-select-config_tls-from-config_nvme_tcp_tls.patch +nvmet-tcp-select-config_tls-from-config_nvme_target_.patch +asoc-simple-card-utils-fix-pointer-check-in-graph_ut.patch +bnxt_en-fix-module-unload-sequence.patch +net-use-sock_gen_put-when-sk_state-is-tcp_time_wait.patch +ptp-ocp-fix-null-dereference-in-adva-board-sma-sysfs.patch +net-lan743x-fix-memleak-issue-when-gso-enabled.patch +net-fec-err007885-workaround-for-conventional-tx.patch +octeon_ep-fix-host-hang-issue-during-device-reboot.patch +net-hns3-store-rx-vlan-tag-offload-state-for-vf.patch +net-hns3-fix-an-interrupt-residual-problem.patch +net-hns3-fixed-debugfs-tm_qset-size.patch +net-hns3-defer-calling-ptp_clock_register.patch +net-vertexcom-mse102x-fix-possible-stuck-of-spi-inte.patch +net-vertexcom-mse102x-fix-len_mask.patch +net-vertexcom-mse102x-add-range-check-for-cmd_rts.patch +net-vertexcom-mse102x-fix-rx-error-handling.patch diff --git a/queue-6.12/vxlan-vnifilter-fix-unlocked-deletion-of-default-fdb.patch b/queue-6.12/vxlan-vnifilter-fix-unlocked-deletion-of-default-fdb.patch new file mode 100644 index 0000000000..6aa44b4367 --- /dev/null +++ b/queue-6.12/vxlan-vnifilter-fix-unlocked-deletion-of-default-fdb.patch @@ -0,0 +1,87 @@ +From 1f3bf87eb17d53c6115b2b3c7958d3985d47cc2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 17:51:31 +0300 +Subject: vxlan: vnifilter: Fix unlocked deletion of default FDB entry + +From: Ido Schimmel + +[ Upstream commit 087a9eb9e5978e3ba362e1163691e41097e8ca20 ] + +When a VNI is deleted from a VXLAN device in 'vnifilter' mode, the FDB +entry associated with the default remote (assuming one was configured) +is deleted without holding the hash lock. This is wrong and will result +in a warning [1] being generated by the lockdep annotation that was +added by commit ebe642067455 ("vxlan: Create wrappers for FDB lookup"). + +Reproducer: + + # ip link add vx0 up type vxlan dstport 4789 external vnifilter local 192.0.2.1 + # bridge vni add vni 10010 remote 198.51.100.1 dev vx0 + # bridge vni del vni 10010 dev vx0 + +Fix by acquiring the hash lock before the deletion and releasing it +afterwards. Blame the original commit that introduced the issue rather +than the one that exposed it. + +[1] +WARNING: CPU: 3 PID: 392 at drivers/net/vxlan/vxlan_core.c:417 vxlan_find_mac+0x17f/0x1a0 +[...] +RIP: 0010:vxlan_find_mac+0x17f/0x1a0 +[...] +Call Trace: + + __vxlan_fdb_delete+0xbe/0x560 + vxlan_vni_delete_group+0x2ba/0x940 + vxlan_vni_del.isra.0+0x15f/0x580 + vxlan_process_vni_filter+0x38b/0x7b0 + vxlan_vnifilter_process+0x3bb/0x510 + rtnetlink_rcv_msg+0x2f7/0xb70 + netlink_rcv_skb+0x131/0x360 + netlink_unicast+0x426/0x710 + netlink_sendmsg+0x75a/0xc20 + __sock_sendmsg+0xc1/0x150 + ____sys_sendmsg+0x5aa/0x7b0 + ___sys_sendmsg+0xfc/0x180 + __sys_sendmsg+0x121/0x1b0 + do_syscall_64+0xbb/0x1d0 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + +Fixes: f9c4bb0b245c ("vxlan: vni filtering support on collect metadata device") +Signed-off-by: Ido Schimmel +Reviewed-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20250423145131.513029-1-idosch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan/vxlan_vnifilter.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c +index 6e6e9f05509ab..06d19e90eadb5 100644 +--- a/drivers/net/vxlan/vxlan_vnifilter.c ++++ b/drivers/net/vxlan/vxlan_vnifilter.c +@@ -627,7 +627,11 @@ static void vxlan_vni_delete_group(struct vxlan_dev *vxlan, + * default dst remote_ip previously added for this vni + */ + if (!vxlan_addr_any(&vninode->remote_ip) || +- !vxlan_addr_any(&dst->remote_ip)) ++ !vxlan_addr_any(&dst->remote_ip)) { ++ u32 hash_index = fdb_head_index(vxlan, all_zeros_mac, ++ vninode->vni); ++ ++ spin_lock_bh(&vxlan->hash_lock[hash_index]); + __vxlan_fdb_delete(vxlan, all_zeros_mac, + (vxlan_addr_any(&vninode->remote_ip) ? + dst->remote_ip : vninode->remote_ip), +@@ -635,6 +639,8 @@ static void vxlan_vni_delete_group(struct vxlan_dev *vxlan, + vninode->vni, vninode->vni, + dst->remote_ifindex, + true); ++ spin_unlock_bh(&vxlan->hash_lock[hash_index]); ++ } + + if (vxlan->dev->flags & IFF_UP) { + if (vxlan_addr_multicast(&vninode->remote_ip) && +-- +2.39.5 + diff --git a/queue-6.12/wifi-iwlwifi-don-t-warn-if-the-nic-is-gone-in-resume.patch b/queue-6.12/wifi-iwlwifi-don-t-warn-if-the-nic-is-gone-in-resume.patch new file mode 100644 index 0000000000..9bf3d5eebc --- /dev/null +++ b/queue-6.12/wifi-iwlwifi-don-t-warn-if-the-nic-is-gone-in-resume.patch @@ -0,0 +1,171 @@ +From 32c7609fde03aae5384156f6645ad61ef5b4d9cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Apr 2025 10:00:00 +0300 +Subject: wifi: iwlwifi: don't warn if the NIC is gone in resume + +From: Emmanuel Grumbach + +[ Upstream commit 15220a257319ffe3bf95796326dfe0aacdbeb1c4 ] + +Some BIOSes decide to power gate the WLAN device during S3. Since +iwlwifi doesn't expect this, it gets very noisy reporting that the +device is no longer available. Wifi is still available because iwlwifi +recovers, but it spews scary prints in the log. + +Fix that by failing gracefully. + +Fixes: e8bb19c1d590 ("wifi: iwlwifi: support fast resume") +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219597 +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20250420095642.d8d58146c829.I569ca15eaaa774d633038a749cc6ec7448419714@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../net/wireless/intel/iwlwifi/iwl-trans.c | 1 - + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 20 ++++++++++++++++--- + .../wireless/intel/iwlwifi/pcie/internal.h | 9 +++++---- + .../net/wireless/intel/iwlwifi/pcie/trans.c | 13 +++++++++--- + drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 2 +- + 5 files changed, 33 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +index 3c9d91496c826..3b3dcaf33c9d9 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +@@ -347,7 +347,6 @@ void __releases(nic_access) + iwl_trans_release_nic_access(struct iwl_trans *trans) + { + iwl_trans_pcie_release_nic_access(trans); +- __release(nic_access); + } + IWL_EXPORT_SYMBOL(iwl_trans_release_nic_access); + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index 9dd0e0a51ce5c..a3cabee35d471 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -1652,10 +1652,24 @@ static int _iwl_pci_resume(struct device *device, bool restore) + * need to reset it completely. + * Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan, + * so assume that any bits there mean that the device is usable. ++ * For older devices, just try silently to grab the NIC. + */ +- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ && +- !iwl_read32(trans, CSR_FUNC_SCRATCH)) +- device_was_powered_off = true; ++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { ++ if (!iwl_read32(trans, CSR_FUNC_SCRATCH)) ++ device_was_powered_off = true; ++ } else { ++ /* ++ * bh are re-enabled by iwl_trans_pcie_release_nic_access, ++ * so re-enable them if _iwl_trans_pcie_grab_nic_access fails. ++ */ ++ local_bh_disable(); ++ if (_iwl_trans_pcie_grab_nic_access(trans, true)) { ++ iwl_trans_pcie_release_nic_access(trans); ++ } else { ++ device_was_powered_off = true; ++ local_bh_enable(); ++ } ++ } + + if (restore || device_was_powered_off) { + trans->state = IWL_TRANS_NO_FW; +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +index ebe9b25cc53a9..6019114a5d1aa 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +@@ -558,10 +558,10 @@ void iwl_trans_pcie_free(struct iwl_trans *trans); + void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions, + struct device *dev); + +-bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans); +-#define _iwl_trans_pcie_grab_nic_access(trans) \ ++bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent); ++#define _iwl_trans_pcie_grab_nic_access(trans, silent) \ + __cond_lock(nic_access_nobh, \ +- likely(__iwl_trans_pcie_grab_nic_access(trans))) ++ likely(__iwl_trans_pcie_grab_nic_access(trans, silent))) + + /***************************************************** + * RX +@@ -1102,7 +1102,8 @@ void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg, + int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs, + u32 *val); + bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans); +-void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans); ++void __releases(nic_access_nobh) ++iwl_trans_pcie_release_nic_access(struct iwl_trans *trans); + + /* transport gen 1 exported functions */ + void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr); +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index d19b3bd0866bd..18d7d59ae5814 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -2191,7 +2191,7 @@ EXPORT_SYMBOL(iwl_trans_pcie_remove); + * This version doesn't disable BHs but rather assumes they're + * already disabled. + */ +-bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans) ++bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) + { + int ret; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); +@@ -2243,6 +2243,11 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans) + if (unlikely(ret < 0)) { + u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL); + ++ if (silent) { ++ spin_unlock(&trans_pcie->reg_lock); ++ return false; ++ } ++ + WARN_ONCE(1, + "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", + cntrl); +@@ -2273,7 +2278,7 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans) + bool ret; + + local_bh_disable(); +- ret = __iwl_trans_pcie_grab_nic_access(trans); ++ ret = __iwl_trans_pcie_grab_nic_access(trans, false); + if (ret) { + /* keep BHs disabled until iwl_trans_pcie_release_nic_access */ + return ret; +@@ -2282,7 +2287,8 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans) + return false; + } + +-void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) ++void __releases(nic_access_nobh) ++iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + +@@ -2309,6 +2315,7 @@ void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) + * scheduled on different CPUs (after we drop reg_lock). + */ + out: ++ __release(nic_access_nobh); + spin_unlock_bh(&trans_pcie->reg_lock); + } + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +index 9fcdd06e126ae..f0213a6b8cf53 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +@@ -1021,7 +1021,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, + * returned. This needs to be done only on NICs that have + * apmg_wake_up_wa set (see above.) + */ +- if (!_iwl_trans_pcie_grab_nic_access(trans)) ++ if (!_iwl_trans_pcie_grab_nic_access(trans, false)) + return -EIO; + + /* +-- +2.39.5 + diff --git a/queue-6.12/wifi-iwlwifi-fix-the-check-for-the-scratch-register-.patch b/queue-6.12/wifi-iwlwifi-fix-the-check-for-the-scratch-register-.patch new file mode 100644 index 0000000000..d0cf1cc575 --- /dev/null +++ b/queue-6.12/wifi-iwlwifi-fix-the-check-for-the-scratch-register-.patch @@ -0,0 +1,63 @@ +From 2fdb7eb67f965bf457cf7280d141980e02573e3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Apr 2025 10:00:01 +0300 +Subject: wifi: iwlwifi: fix the check for the SCRATCH register upon resume + +From: Emmanuel Grumbach + +[ Upstream commit a17821321a9b42f26e77335cd525fee72dc1cd63 ] + +We can't rely on the SCRATCH register being 0 on platform that power +gate the NIC in S3. Even in those platforms, the SCRATCH register is +still returning 0x1010000. + +Make sure that we understand that those platforms have powered off the +device. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219597 +Fixes: cb347bd29d0d ("wifi: iwlwifi: mvm: fix hibernation") +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20250420095642.a7e082ee785c.I9418d76f860f54261cfa89e1f7ac10300904ba40@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 1 + + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +index 98563757ce2c9..405bba199fe7f 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +@@ -148,6 +148,7 @@ + * during a error FW error. + */ + #define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101) ++#define CSR_FUNC_SCRATCH_POWER_OFF_MASK 0xFFFF + + /* Bits for CSR_HW_IF_CONFIG_REG */ + #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH (0x0000000F) +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index a3cabee35d471..9141ea57abfce 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -1651,11 +1651,13 @@ static int _iwl_pci_resume(struct device *device, bool restore) + * Scratch value was altered, this means the device was powered off, we + * need to reset it completely. + * Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan, +- * so assume that any bits there mean that the device is usable. ++ * but not bits [15:8]. So if we have bits set in lower word, assume ++ * the device is alive. + * For older devices, just try silently to grab the NIC. + */ + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { +- if (!iwl_read32(trans, CSR_FUNC_SCRATCH)) ++ if (!(iwl_read32(trans, CSR_FUNC_SCRATCH) & ++ CSR_FUNC_SCRATCH_POWER_OFF_MASK)) + device_was_powered_off = true; + } else { + /* +-- +2.39.5 + diff --git a/queue-6.12/wifi-plfxlc-remove-erroneous-assert-in-plfxlc_mac_re.patch b/queue-6.12/wifi-plfxlc-remove-erroneous-assert-in-plfxlc_mac_re.patch new file mode 100644 index 0000000000..8e81665cbb --- /dev/null +++ b/queue-6.12/wifi-plfxlc-remove-erroneous-assert-in-plfxlc_mac_re.patch @@ -0,0 +1,89 @@ +From 4eb75fd180e3896fbcea44a4ab591c0c66cbd28e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Mar 2025 21:52:25 +0300 +Subject: wifi: plfxlc: Remove erroneous assert in plfxlc_mac_release + +From: Murad Masimov + +[ Upstream commit 0fb15ae3b0a9221be01715dac0335647c79f3362 ] + +plfxlc_mac_release() asserts that mac->lock is held. This assertion is +incorrect, because even if it was possible, it would not be the valid +behaviour. The function is used when probe fails or after the device is +disconnected. In both cases mac->lock can not be held as the driver is +not working with the device at the moment. All functions that use mac->lock +unlock it just after it was held. There is also no need to hold mac->lock +for plfxlc_mac_release() itself, as mac data is not affected, except for +mac->flags, which is modified atomically. + +This bug leads to the following warning: +================================================================ +WARNING: CPU: 0 PID: 127 at drivers/net/wireless/purelifi/plfxlc/mac.c:106 plfxlc_mac_release+0x7d/0xa0 +Modules linked in: +CPU: 0 PID: 127 Comm: kworker/0:2 Not tainted 6.1.124-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 +Workqueue: usb_hub_wq hub_event +RIP: 0010:plfxlc_mac_release+0x7d/0xa0 drivers/net/wireless/purelifi/plfxlc/mac.c:106 +Call Trace: + + probe+0x941/0xbd0 drivers/net/wireless/purelifi/plfxlc/usb.c:694 + usb_probe_interface+0x5c0/0xaf0 drivers/usb/core/driver.c:396 + really_probe+0x2ab/0xcb0 drivers/base/dd.c:639 + __driver_probe_device+0x1a2/0x3d0 drivers/base/dd.c:785 + driver_probe_device+0x50/0x420 drivers/base/dd.c:815 + __device_attach_driver+0x2cf/0x510 drivers/base/dd.c:943 + bus_for_each_drv+0x183/0x200 drivers/base/bus.c:429 + __device_attach+0x359/0x570 drivers/base/dd.c:1015 + bus_probe_device+0xba/0x1e0 drivers/base/bus.c:489 + device_add+0xb48/0xfd0 drivers/base/core.c:3696 + usb_set_configuration+0x19dd/0x2020 drivers/usb/core/message.c:2165 + usb_generic_driver_probe+0x84/0x140 drivers/usb/core/generic.c:238 + usb_probe_device+0x130/0x260 drivers/usb/core/driver.c:293 + really_probe+0x2ab/0xcb0 drivers/base/dd.c:639 + __driver_probe_device+0x1a2/0x3d0 drivers/base/dd.c:785 + driver_probe_device+0x50/0x420 drivers/base/dd.c:815 + __device_attach_driver+0x2cf/0x510 drivers/base/dd.c:943 + bus_for_each_drv+0x183/0x200 drivers/base/bus.c:429 + __device_attach+0x359/0x570 drivers/base/dd.c:1015 + bus_probe_device+0xba/0x1e0 drivers/base/bus.c:489 + device_add+0xb48/0xfd0 drivers/base/core.c:3696 + usb_new_device+0xbdd/0x18f0 drivers/usb/core/hub.c:2620 + hub_port_connect drivers/usb/core/hub.c:5477 [inline] + hub_port_connect_change drivers/usb/core/hub.c:5617 [inline] + port_event drivers/usb/core/hub.c:5773 [inline] + hub_event+0x2efe/0x5730 drivers/usb/core/hub.c:5855 + process_one_work+0x8a9/0x11d0 kernel/workqueue.c:2292 + worker_thread+0xa47/0x1200 kernel/workqueue.c:2439 + kthread+0x28d/0x320 kernel/kthread.c:376 + ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 + +================================================================ + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: 68d57a07bfe5 ("wireless: add plfxlc driver for pureLiFi X, XL, XC devices") +Reported-by: syzbot+7d4f142f6c288de8abfe@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7d4f142f6c288de8abfe +Signed-off-by: Murad Masimov +Link: https://patch.msgid.link/20250321185226.71-2-m.masimov@mt-integration.ru +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/purelifi/plfxlc/mac.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/wireless/purelifi/plfxlc/mac.c b/drivers/net/wireless/purelifi/plfxlc/mac.c +index eae93efa61504..82d1bf7edba20 100644 +--- a/drivers/net/wireless/purelifi/plfxlc/mac.c ++++ b/drivers/net/wireless/purelifi/plfxlc/mac.c +@@ -102,7 +102,6 @@ int plfxlc_mac_init_hw(struct ieee80211_hw *hw) + void plfxlc_mac_release(struct plfxlc_mac *mac) + { + plfxlc_chip_release(&mac->chip); +- lockdep_assert_held(&mac->lock); + } + + int plfxlc_op_start(struct ieee80211_hw *hw) +-- +2.39.5 + diff --git a/queue-6.12/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch b/queue-6.12/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch new file mode 100644 index 0000000000..14bc8c436d --- /dev/null +++ b/queue-6.12/xsk-fix-race-condition-in-af_xdp-generic-rx-path.patch @@ -0,0 +1,122 @@ +From f01fd6eb48cdf843afc372d8d69ea8ce500b4a03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 12:19:08 +0200 +Subject: xsk: Fix race condition in AF_XDP generic RX path + +From: e.kubanski + +[ Upstream commit a1356ac7749cafc4e27aa62c0c4604b5dca4983e ] + +Move rx_lock from xsk_socket to xsk_buff_pool. +Fix synchronization for shared umem mode in +generic RX path where multiple sockets share +single xsk_buff_pool. + +RX queue is exclusive to xsk_socket, while FILL +queue can be shared between multiple sockets. +This could result in race condition where two +CPU cores access RX path of two different sockets +sharing the same umem. + +Protect both queues by acquiring spinlock in shared +xsk_buff_pool. + +Lock contention may be minimized in the future by some +per-thread FQ buffering. + +It's safe and necessary to move spin_lock_bh(rx_lock) +after xsk_rcv_check(): +* xs->pool and spinlock_init is synchronized by + xsk_bind() -> xsk_is_bound() memory barriers. +* xsk_rcv_check() may return true at the moment + of xsk_release() or xsk_unbind_dev(), + however this will not cause any data races or + race conditions. xsk_unbind_dev() removes xdp + socket from all maps and waits for completion + of all outstanding rx operations. Packets in + RX path will either complete safely or drop. + +Signed-off-by: Eryk Kubanski +Fixes: bf0bdd1343efb ("xdp: fix race on generic receive path") +Acked-by: Magnus Karlsson +Link: https://patch.msgid.link/20250416101908.10919-1-e.kubanski@partner.samsung.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/xdp_sock.h | 3 --- + include/net/xsk_buff_pool.h | 2 ++ + net/xdp/xsk.c | 6 +++--- + net/xdp/xsk_buff_pool.c | 1 + + 4 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h +index bfe625b55d55d..df3f5f07bc7c2 100644 +--- a/include/net/xdp_sock.h ++++ b/include/net/xdp_sock.h +@@ -71,9 +71,6 @@ struct xdp_sock { + */ + u32 tx_budget_spent; + +- /* Protects generic receive. */ +- spinlock_t rx_lock; +- + /* Statistics */ + u64 rx_dropped; + u64 rx_queue_full; +diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h +index bacb33f1e3e58..823fd5c7a3b18 100644 +--- a/include/net/xsk_buff_pool.h ++++ b/include/net/xsk_buff_pool.h +@@ -55,6 +55,8 @@ struct xsk_buff_pool { + refcount_t users; + struct xdp_umem *umem; + struct work_struct work; ++ /* Protects generic receive in shared and non-shared umem mode. */ ++ spinlock_t rx_lock; + struct list_head free_list; + struct list_head xskb_list; + u32 heads_cnt; +diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c +index b57d5d2904eb4..f031b07baa57a 100644 +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -338,13 +338,14 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp) + u32 len = xdp_get_buff_len(xdp); + int err; + +- spin_lock_bh(&xs->rx_lock); + err = xsk_rcv_check(xs, xdp, len); + if (!err) { ++ spin_lock_bh(&xs->pool->rx_lock); + err = __xsk_rcv(xs, xdp, len); + xsk_flush(xs); ++ spin_unlock_bh(&xs->pool->rx_lock); + } +- spin_unlock_bh(&xs->rx_lock); ++ + return err; + } + +@@ -1720,7 +1721,6 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol, + xs = xdp_sk(sk); + xs->state = XSK_READY; + mutex_init(&xs->mutex); +- spin_lock_init(&xs->rx_lock); + + INIT_LIST_HEAD(&xs->map_list); + spin_lock_init(&xs->map_list_lock); +diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c +index 87e865b9b83af..b69dbd8615fc4 100644 +--- a/net/xdp/xsk_buff_pool.c ++++ b/net/xdp/xsk_buff_pool.c +@@ -87,6 +87,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, + pool->addrs = umem->addrs; + pool->tx_metadata_len = umem->tx_metadata_len; + pool->tx_sw_csum = umem->flags & XDP_UMEM_TX_SW_CSUM; ++ spin_lock_init(&pool->rx_lock); + INIT_LIST_HEAD(&pool->free_list); + INIT_LIST_HEAD(&pool->xskb_list); + INIT_LIST_HEAD(&pool->xsk_tx_list); +-- +2.39.5 +