From: Sasha Levin Date: Sun, 15 Jun 2025 13:01:12 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v6.6.94~61 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0de958ce231b02343a8b9a772df1abc0c06e9ada;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/ath10k-snoc-fix-unbalanced-irq-enable-in-crash-recov.patch b/queue-5.15/ath10k-snoc-fix-unbalanced-irq-enable-in-crash-recov.patch new file mode 100644 index 0000000000..8b7d05d296 --- /dev/null +++ b/queue-5.15/ath10k-snoc-fix-unbalanced-irq-enable-in-crash-recov.patch @@ -0,0 +1,49 @@ +From 159c738378ec8436a06680af17a2db0223b140dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Mar 2025 20:50:27 +0000 +Subject: ath10k: snoc: fix unbalanced IRQ enable in crash recovery + +From: Caleb Connolly + +[ Upstream commit 1650d32b92b01db03a1a95d69ee74fcbc34d4b00 ] + +In ath10k_snoc_hif_stop() we skip disabling the IRQs in the crash +recovery flow, but we still unconditionally call enable again in +ath10k_snoc_hif_start(). + +We can't check the ATH10K_FLAG_CRASH_FLUSH bit since it is cleared +before hif_start() is called, so instead check the +ATH10K_SNOC_FLAG_RECOVERY flag and skip enabling the IRQs during crash +recovery. + +This fixes unbalanced IRQ enable splats that happen after recovering from +a crash. + +Fixes: 0e622f67e041 ("ath10k: add support for WCN3990 firmware crash recovery") +Signed-off-by: Caleb Connolly +Tested-by: Loic Poulain +Link: https://patch.msgid.link/20250318205043.1043148-1-caleb.connolly@linaro.org +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/snoc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c +index 439df8a404d86..b091e5187dbe5 100644 +--- a/drivers/net/wireless/ath/ath10k/snoc.c ++++ b/drivers/net/wireless/ath/ath10k/snoc.c +@@ -936,7 +936,9 @@ static int ath10k_snoc_hif_start(struct ath10k *ar) + bitmap_clear(ar_snoc->pending_ce_irqs, 0, CE_COUNT_MAX); + + ath10k_core_napi_enable(ar); +- ath10k_snoc_irq_enable(ar); ++ /* IRQs are left enabled when we restart due to a firmware crash */ ++ if (!test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags)) ++ ath10k_snoc_irq_enable(ar); + ath10k_snoc_rx_post(ar); + + clear_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags); +-- +2.39.5 + diff --git a/queue-5.15/drm-meson-fix-debug-log-statement-when-setting-the-h.patch b/queue-5.15/drm-meson-fix-debug-log-statement-when-setting-the-h.patch new file mode 100644 index 0000000000..6d4908f63d --- /dev/null +++ b/queue-5.15/drm-meson-fix-debug-log-statement-when-setting-the-h.patch @@ -0,0 +1,39 @@ +From 678c5cce6ed465438482186e1afb419098f4d884 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jun 2025 22:37:29 +0200 +Subject: drm/meson: fix debug log statement when setting the HDMI clocks + +From: Martin Blumenstingl + +[ Upstream commit d17e61ab63fb7747b340d6a66bf1408cd5c6562b ] + +The "phy" and "vclk" frequency labels were swapped, making it more +difficult to debug driver errors. Swap the label order to make them +match with the actual frequencies printed to correct this. + +Fixes: e5fab2ec9ca4 ("drm/meson: vclk: add support for YUV420 setup") +Signed-off-by: Martin Blumenstingl +Reviewed-by: Neil Armstrong +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250606203729.3311592-1-martin.blumenstingl@googlemail.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/meson/meson_encoder_hdmi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c +index 95137c2d3c56d..1fd17de93fc34 100644 +--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c ++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c +@@ -106,7 +106,7 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, + venc_freq /= 2; + + dev_dbg(priv->dev, +- "vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n", ++ "phy:%lluHz vclk=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n", + phy_freq, vclk_freq, venc_freq, hdmi_freq, + priv->venc.hdmi_use_enci); + +-- +2.39.5 + diff --git a/queue-5.15/drm-meson-fix-more-rounding-issues-with-59.94hz-mode.patch b/queue-5.15/drm-meson-fix-more-rounding-issues-with-59.94hz-mode.patch new file mode 100644 index 0000000000..adbd33cad1 --- /dev/null +++ b/queue-5.15/drm-meson-fix-more-rounding-issues-with-59.94hz-mode.patch @@ -0,0 +1,134 @@ +From 6ee6cd4d8c40947c93ebf06bd6a659dd365743da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jun 2025 22:27:51 +0200 +Subject: drm/meson: fix more rounding issues with 59.94Hz modes + +From: Martin Blumenstingl + +[ Upstream commit 0cee6c4d3518b2e757aedae78771f17149f57653 ] + +Commit 1017560164b6 ("drm/meson: use unsigned long long / Hz for +frequency types") attempts to resolve video playback using 59.94Hz. + using YUV420 by changing the clock calculation to use +Hz instead of kHz (thus yielding more precision). + +The basic calculation itself is correct, however the comparisions in +meson_vclk_vic_supported_freq() and meson_vclk_setup() don't work +anymore for 59.94Hz modes (using the freq * 1000 / 1001 logic). For +example, drm/edid specifies a 593407kHz clock for 3840x2160@59.94Hz. +With the mentioend commit we convert this to Hz. Then meson_vclk +tries to find a matchig "params" entry (as the clock setup code +currently only supports specific frequencies) by taking the venc_freq +from the params and calculating the "alt frequency" (used for the +59.94Hz modes) from it, which is: + (594000000Hz * 1000) / 1001 = 593406593Hz + +Similar calculation is applied to the phy_freq (TMDS clock), which is 10 +times the pixel clock. + +Implement a new meson_vclk_freqs_are_matching_param() function whose +purpose is to compare if the requested and calculated frequencies. They +may not match exactly (for the reasons mentioned above). Allow the +clocks to deviate slightly to make the 59.94Hz modes again. + +Fixes: 1017560164b6 ("drm/meson: use unsigned long long / Hz for frequency types") +Reported-by: Christian Hewitt +Signed-off-by: Martin Blumenstingl +Reviewed-by: Neil Armstrong +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250609202751.962208-1-martin.blumenstingl@googlemail.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/meson/meson_vclk.c | 55 ++++++++++++++++++------------ + 1 file changed, 34 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +index c4123bb958e4c..dfe0c28a0f054 100644 +--- a/drivers/gpu/drm/meson/meson_vclk.c ++++ b/drivers/gpu/drm/meson/meson_vclk.c +@@ -110,10 +110,7 @@ + #define HDMI_PLL_LOCK BIT(31) + #define HDMI_PLL_LOCK_G12A (3 << 30) + +-#define PIXEL_FREQ_1000_1001(_freq) \ +- DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL) +-#define PHY_FREQ_1000_1001(_freq) \ +- (PIXEL_FREQ_1000_1001(DIV_ROUND_DOWN_ULL(_freq, 10ULL)) * 10) ++#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL) + + /* VID PLL Dividers */ + enum { +@@ -772,6 +769,36 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, + pll_freq); + } + ++static bool meson_vclk_freqs_are_matching_param(unsigned int idx, ++ unsigned long long phy_freq, ++ unsigned long long vclk_freq) ++{ ++ DRM_DEBUG_DRIVER("i = %d vclk_freq = %lluHz alt = %lluHz\n", ++ idx, params[idx].vclk_freq, ++ FREQ_1000_1001(params[idx].vclk_freq)); ++ DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", ++ idx, params[idx].phy_freq, ++ FREQ_1000_1001(params[idx].phy_freq)); ++ ++ /* Match strict frequency */ ++ if (phy_freq == params[idx].phy_freq && ++ vclk_freq == params[idx].vclk_freq) ++ return true; ++ ++ /* Match 1000/1001 variant: vclk deviation has to be less than 1kHz ++ * (drm EDID is defined in 1kHz steps, so everything smaller must be ++ * rounding error) and the PHY freq deviation has to be less than ++ * 10kHz (as the TMDS clock is 10 times the pixel clock, so anything ++ * smaller must be rounding error as well). ++ */ ++ if (abs(vclk_freq - FREQ_1000_1001(params[idx].vclk_freq)) < 1000 && ++ abs(phy_freq - FREQ_1000_1001(params[idx].phy_freq)) < 10000) ++ return true; ++ ++ /* no match */ ++ return false; ++} ++ + enum drm_mode_status + meson_vclk_vic_supported_freq(struct meson_drm *priv, + unsigned long long phy_freq, +@@ -790,19 +817,7 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, + } + + for (i = 0 ; params[i].pixel_freq ; ++i) { +- DRM_DEBUG_DRIVER("i = %d vclk_freq = %lluHz alt = %lluHz\n", +- i, params[i].vclk_freq, +- PIXEL_FREQ_1000_1001(params[i].vclk_freq)); +- DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", +- i, params[i].phy_freq, +- PHY_FREQ_1000_1001(params[i].phy_freq)); +- /* Match strict frequency */ +- if (phy_freq == params[i].phy_freq && +- vclk_freq == params[i].vclk_freq) +- return MODE_OK; +- /* Match 1000/1001 variant */ +- if (phy_freq == PHY_FREQ_1000_1001(params[i].phy_freq) && +- vclk_freq == PIXEL_FREQ_1000_1001(params[i].vclk_freq)) ++ if (meson_vclk_freqs_are_matching_param(i, phy_freq, vclk_freq)) + return MODE_OK; + } + +@@ -1075,10 +1090,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + } + + for (freq = 0 ; params[freq].pixel_freq ; ++freq) { +- if ((phy_freq == params[freq].phy_freq || +- phy_freq == PHY_FREQ_1000_1001(params[freq].phy_freq)) && +- (vclk_freq == params[freq].vclk_freq || +- vclk_freq == PIXEL_FREQ_1000_1001(params[freq].vclk_freq))) { ++ if (meson_vclk_freqs_are_matching_param(freq, phy_freq, ++ vclk_freq)) { + if (vclk_freq != params[freq].vclk_freq) + vic_alternate_clock = true; + else +-- +2.39.5 + diff --git a/queue-5.15/drm-meson-use-unsigned-long-long-hz-for-frequency-ty.patch b/queue-5.15/drm-meson-use-unsigned-long-long-hz-for-frequency-ty.patch new file mode 100644 index 0000000000..5852af651c --- /dev/null +++ b/queue-5.15/drm-meson-use-unsigned-long-long-hz-for-frequency-ty.patch @@ -0,0 +1,650 @@ +From 590f8745d9ff55ac5576789eb34a96c28ea0d1df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Apr 2025 22:13:00 +0200 +Subject: drm/meson: use unsigned long long / Hz for frequency types + +From: Martin Blumenstingl + +[ Upstream commit 1017560164b6bbcbc93579266926e6e96675262a ] + +Christian reports that 4K output using YUV420 encoding fails with the +following error: + Fatal Error, invalid HDMI vclk freq 593406 + +Modetest shows the following: + 3840x2160 59.94 3840 4016 4104 4400 2160 2168 2178 2250 593407 flags: xxxx, xxxx, + drm calculated value -------------------------------------^ + +This indicates that there's a (1kHz) mismatch between the clock +calculated by the drm framework and the meson driver. + +Relevant function call stack: +(drm framework) + -> meson_encoder_hdmi_atomic_enable() + -> meson_encoder_hdmi_set_vclk() + -> meson_vclk_setup() + +The video clock requested by the drm framework is 593407kHz. This is +passed by meson_encoder_hdmi_atomic_enable() to +meson_encoder_hdmi_set_vclk() and the following formula is applied: +- the frequency is halved (which would be 296703.5kHz) and rounded down + to the next full integer, which is 296703kHz +- TMDS clock is calculated (296703kHz * 10) +- video encoder clock is calculated - this needs to match a table from + meson_vclk.c and so it doubles the previously halved value again + (resulting in 593406kHz) +- meson_vclk_setup() can't find (either directly, or by deriving it from + 594000kHz * 1000 / 1001 and rounding to the closest integer value - + which is 593407kHz as originally requested by the drm framework) a + matching clock in it's internal table and errors out with "invalid + HDMI vclk freq" + +Fix the division precision by switching the whole meson driver to use +unsigned long long (64-bit) Hz values for clock frequencies instead of +unsigned int (32-bit) kHz to fix the rouding error. + +Fixes: e5fab2ec9ca4 ("drm/meson: vclk: add support for YUV420 setup") +Reported-by: Christian Hewitt +Signed-off-by: Martin Blumenstingl +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250421201300.778955-3-martin.blumenstingl@googlemail.com +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250421201300.778955-3-martin.blumenstingl@googlemail.com +Stable-dep-of: d17e61ab63fb ("drm/meson: fix debug log statement when setting the HDMI clocks") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/meson/meson_drv.c | 2 +- + drivers/gpu/drm/meson/meson_drv.h | 2 +- + drivers/gpu/drm/meson/meson_encoder_hdmi.c | 29 +-- + drivers/gpu/drm/meson/meson_vclk.c | 195 +++++++++++---------- + drivers/gpu/drm/meson/meson_vclk.h | 13 +- + 5 files changed, 126 insertions(+), 115 deletions(-) + +diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c +index 829aadc1258a1..2df2315b09755 100644 +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -166,7 +166,7 @@ static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = { + /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */ + { + .limits = { +- .max_hdmi_phy_freq = 1650000, ++ .max_hdmi_phy_freq = 1650000000, + }, + .attrs = (const struct soc_device_attribute []) { + { .soc_id = "GXL (S805*)", }, +diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h +index 177dac3ca3bea..2e4d7740974f5 100644 +--- a/drivers/gpu/drm/meson/meson_drv.h ++++ b/drivers/gpu/drm/meson/meson_drv.h +@@ -31,7 +31,7 @@ struct meson_drm_match_data { + }; + + struct meson_drm_soc_limits { +- unsigned int max_hdmi_phy_freq; ++ unsigned long long max_hdmi_phy_freq; + }; + + struct meson_drm { +diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c +index b075c9bc3a500..95137c2d3c56d 100644 +--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c ++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c +@@ -68,12 +68,12 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, + { + struct meson_drm *priv = encoder_hdmi->priv; + int vic = drm_match_cea_mode(mode); +- unsigned int phy_freq; +- unsigned int vclk_freq; +- unsigned int venc_freq; +- unsigned int hdmi_freq; ++ unsigned long long phy_freq; ++ unsigned long long vclk_freq; ++ unsigned long long venc_freq; ++ unsigned long long hdmi_freq; + +- vclk_freq = mode->clock; ++ vclk_freq = mode->clock * 1000; + + /* For 420, pixel clock is half unlike venc clock */ + if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) +@@ -105,7 +105,8 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + venc_freq /= 2; + +- dev_dbg(priv->dev, "vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", ++ dev_dbg(priv->dev, ++ "vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n", + phy_freq, vclk_freq, venc_freq, hdmi_freq, + priv->venc.hdmi_use_enci); + +@@ -120,10 +121,11 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri + struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); + struct meson_drm *priv = encoder_hdmi->priv; + bool is_hdmi2_sink = display_info->hdmi.scdc.supported; +- unsigned int phy_freq; +- unsigned int vclk_freq; +- unsigned int venc_freq; +- unsigned int hdmi_freq; ++ unsigned long long clock = mode->clock * 1000; ++ unsigned long long phy_freq; ++ unsigned long long vclk_freq; ++ unsigned long long venc_freq; ++ unsigned long long hdmi_freq; + int vic = drm_match_cea_mode(mode); + enum drm_mode_status status; + +@@ -142,12 +144,12 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri + if (status != MODE_OK) + return status; + +- return meson_vclk_dmt_supported_freq(priv, mode->clock); ++ return meson_vclk_dmt_supported_freq(priv, clock); + /* Check against supported VIC modes */ + } else if (!meson_venc_hdmi_supported_vic(vic)) + return MODE_BAD; + +- vclk_freq = mode->clock; ++ vclk_freq = clock; + + /* For 420, pixel clock is half unlike venc clock */ + if (drm_mode_is_420_only(display_info, mode) || +@@ -177,7 +179,8 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + venc_freq /= 2; + +- dev_dbg(priv->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", ++ dev_dbg(priv->dev, ++ "%s: vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz\n", + __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); + + return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq); +diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +index 2a82119eb58ed..3325580d885d0 100644 +--- a/drivers/gpu/drm/meson/meson_vclk.c ++++ b/drivers/gpu/drm/meson/meson_vclk.c +@@ -110,7 +110,10 @@ + #define HDMI_PLL_LOCK BIT(31) + #define HDMI_PLL_LOCK_G12A (3 << 30) + +-#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001) ++#define PIXEL_FREQ_1000_1001(_freq) \ ++ DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL) ++#define PHY_FREQ_1000_1001(_freq) \ ++ (PIXEL_FREQ_1000_1001(DIV_ROUND_DOWN_ULL(_freq, 10ULL)) * 10) + + /* VID PLL Dividers */ + enum { +@@ -360,11 +363,11 @@ enum { + }; + + struct meson_vclk_params { +- unsigned int pll_freq; +- unsigned int phy_freq; +- unsigned int vclk_freq; +- unsigned int venc_freq; +- unsigned int pixel_freq; ++ unsigned long long pll_freq; ++ unsigned long long phy_freq; ++ unsigned long long vclk_freq; ++ unsigned long long venc_freq; ++ unsigned long long pixel_freq; + unsigned int pll_od1; + unsigned int pll_od2; + unsigned int pll_od3; +@@ -372,11 +375,11 @@ struct meson_vclk_params { + unsigned int vclk_div; + } params[] = { + [MESON_VCLK_HDMI_ENCI_54000] = { +- .pll_freq = 4320000, +- .phy_freq = 270000, +- .vclk_freq = 54000, +- .venc_freq = 54000, +- .pixel_freq = 54000, ++ .pll_freq = 4320000000, ++ .phy_freq = 270000000, ++ .vclk_freq = 54000000, ++ .venc_freq = 54000000, ++ .pixel_freq = 54000000, + .pll_od1 = 4, + .pll_od2 = 4, + .pll_od3 = 1, +@@ -384,11 +387,11 @@ struct meson_vclk_params { + .vclk_div = 1, + }, + [MESON_VCLK_HDMI_DDR_54000] = { +- .pll_freq = 4320000, +- .phy_freq = 270000, +- .vclk_freq = 54000, +- .venc_freq = 54000, +- .pixel_freq = 27000, ++ .pll_freq = 4320000000, ++ .phy_freq = 270000000, ++ .vclk_freq = 54000000, ++ .venc_freq = 54000000, ++ .pixel_freq = 27000000, + .pll_od1 = 4, + .pll_od2 = 4, + .pll_od3 = 1, +@@ -396,11 +399,11 @@ struct meson_vclk_params { + .vclk_div = 1, + }, + [MESON_VCLK_HDMI_DDR_148500] = { +- .pll_freq = 2970000, +- .phy_freq = 742500, +- .vclk_freq = 148500, +- .venc_freq = 148500, +- .pixel_freq = 74250, ++ .pll_freq = 2970000000, ++ .phy_freq = 742500000, ++ .vclk_freq = 148500000, ++ .venc_freq = 148500000, ++ .pixel_freq = 74250000, + .pll_od1 = 4, + .pll_od2 = 1, + .pll_od3 = 1, +@@ -408,11 +411,11 @@ struct meson_vclk_params { + .vclk_div = 1, + }, + [MESON_VCLK_HDMI_74250] = { +- .pll_freq = 2970000, +- .phy_freq = 742500, +- .vclk_freq = 74250, +- .venc_freq = 74250, +- .pixel_freq = 74250, ++ .pll_freq = 2970000000, ++ .phy_freq = 742500000, ++ .vclk_freq = 74250000, ++ .venc_freq = 74250000, ++ .pixel_freq = 74250000, + .pll_od1 = 2, + .pll_od2 = 2, + .pll_od3 = 2, +@@ -420,11 +423,11 @@ struct meson_vclk_params { + .vclk_div = 1, + }, + [MESON_VCLK_HDMI_148500] = { +- .pll_freq = 2970000, +- .phy_freq = 1485000, +- .vclk_freq = 148500, +- .venc_freq = 148500, +- .pixel_freq = 148500, ++ .pll_freq = 2970000000, ++ .phy_freq = 1485000000, ++ .vclk_freq = 148500000, ++ .venc_freq = 148500000, ++ .pixel_freq = 148500000, + .pll_od1 = 1, + .pll_od2 = 2, + .pll_od3 = 2, +@@ -432,11 +435,11 @@ struct meson_vclk_params { + .vclk_div = 1, + }, + [MESON_VCLK_HDMI_297000] = { +- .pll_freq = 5940000, +- .phy_freq = 2970000, +- .venc_freq = 297000, +- .vclk_freq = 297000, +- .pixel_freq = 297000, ++ .pll_freq = 5940000000, ++ .phy_freq = 2970000000, ++ .venc_freq = 297000000, ++ .vclk_freq = 297000000, ++ .pixel_freq = 297000000, + .pll_od1 = 2, + .pll_od2 = 1, + .pll_od3 = 1, +@@ -444,11 +447,11 @@ struct meson_vclk_params { + .vclk_div = 2, + }, + [MESON_VCLK_HDMI_594000] = { +- .pll_freq = 5940000, +- .phy_freq = 5940000, +- .venc_freq = 594000, +- .vclk_freq = 594000, +- .pixel_freq = 594000, ++ .pll_freq = 5940000000, ++ .phy_freq = 5940000000, ++ .venc_freq = 594000000, ++ .vclk_freq = 594000000, ++ .pixel_freq = 594000000, + .pll_od1 = 1, + .pll_od2 = 1, + .pll_od3 = 2, +@@ -456,11 +459,11 @@ struct meson_vclk_params { + .vclk_div = 1, + }, + [MESON_VCLK_HDMI_594000_YUV420] = { +- .pll_freq = 5940000, +- .phy_freq = 2970000, +- .venc_freq = 594000, +- .vclk_freq = 594000, +- .pixel_freq = 297000, ++ .pll_freq = 5940000000, ++ .phy_freq = 2970000000, ++ .venc_freq = 594000000, ++ .vclk_freq = 594000000, ++ .pixel_freq = 297000000, + .pll_od1 = 2, + .pll_od2 = 1, + .pll_od3 = 1, +@@ -617,16 +620,16 @@ static void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m, + 3 << 20, pll_od_to_reg(od3) << 20); + } + +-#define XTAL_FREQ 24000 ++#define XTAL_FREQ (24 * 1000 * 1000) + + static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv, +- unsigned int pll_freq) ++ unsigned long long pll_freq) + { + /* The GXBB PLL has a /2 pre-multiplier */ + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) +- pll_freq /= 2; ++ pll_freq = DIV_ROUND_DOWN_ULL(pll_freq, 2); + +- return pll_freq / XTAL_FREQ; ++ return DIV_ROUND_DOWN_ULL(pll_freq, XTAL_FREQ); + } + + #define HDMI_FRAC_MAX_GXBB 4096 +@@ -635,12 +638,13 @@ static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv, + + static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, + unsigned int m, +- unsigned int pll_freq) ++ unsigned long long pll_freq) + { +- unsigned int parent_freq = XTAL_FREQ; ++ unsigned long long parent_freq = XTAL_FREQ; + unsigned int frac_max = HDMI_FRAC_MAX_GXL; + unsigned int frac_m; + unsigned int frac; ++ u32 remainder; + + /* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */ + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { +@@ -652,11 +656,11 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, + frac_max = HDMI_FRAC_MAX_G12A; + + /* We can have a perfect match !*/ +- if (pll_freq / m == parent_freq && +- pll_freq % m == 0) ++ if (div_u64_rem(pll_freq, m, &remainder) == parent_freq && ++ remainder == 0) + return 0; + +- frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq); ++ frac = mul_u64_u64_div_u64(pll_freq, frac_max, parent_freq); + frac_m = m * frac_max; + if (frac_m > frac) + return frac_max; +@@ -666,7 +670,7 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, + } + + static bool meson_hdmi_pll_validate_params(struct meson_drm *priv, +- unsigned int m, ++ unsigned long long m, + unsigned int frac) + { + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { +@@ -694,7 +698,7 @@ static bool meson_hdmi_pll_validate_params(struct meson_drm *priv, + } + + static bool meson_hdmi_pll_find_params(struct meson_drm *priv, +- unsigned int freq, ++ unsigned long long freq, + unsigned int *m, + unsigned int *frac, + unsigned int *od) +@@ -706,7 +710,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv, + continue; + *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od); + +- DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n", ++ DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d\n", + freq, *m, *frac, *od); + + if (meson_hdmi_pll_validate_params(priv, *m, *frac)) +@@ -718,7 +722,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv, + + /* pll_freq is the frequency after the OD dividers */ + enum drm_mode_status +-meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq) ++meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq) + { + unsigned int od, m, frac; + +@@ -741,7 +745,7 @@ EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq); + + /* pll_freq is the frequency after the OD dividers */ + static void meson_hdmi_pll_generic_set(struct meson_drm *priv, +- unsigned int pll_freq) ++ unsigned long long pll_freq) + { + unsigned int od, m, frac, od1, od2, od3; + +@@ -756,7 +760,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, + od1 = od / od2; + } + +- DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n", ++ DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d/%d/%d\n", + pll_freq, m, frac, od1, od2, od3); + + meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); +@@ -764,17 +768,18 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, + return; + } + +- DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n", ++ DRM_ERROR("Fatal, unable to find parameters for PLL freq %lluHz\n", + pll_freq); + } + + enum drm_mode_status +-meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, +- unsigned int vclk_freq) ++meson_vclk_vic_supported_freq(struct meson_drm *priv, ++ unsigned long long phy_freq, ++ unsigned long long vclk_freq) + { + int i; + +- DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n", ++ DRM_DEBUG_DRIVER("phy_freq = %lluHz vclk_freq = %lluHz\n", + phy_freq, vclk_freq); + + /* Check against soc revision/package limits */ +@@ -785,19 +790,19 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, + } + + for (i = 0 ; params[i].pixel_freq ; ++i) { +- DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n", ++ DRM_DEBUG_DRIVER("i = %d pixel_freq = %lluHz alt = %lluHz\n", + i, params[i].pixel_freq, +- FREQ_1000_1001(params[i].pixel_freq)); +- DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n", ++ PIXEL_FREQ_1000_1001(params[i].pixel_freq)); ++ DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", + i, params[i].phy_freq, +- FREQ_1000_1001(params[i].phy_freq/10)*10); ++ PHY_FREQ_1000_1001(params[i].phy_freq)); + /* Match strict frequency */ + if (phy_freq == params[i].phy_freq && + vclk_freq == params[i].vclk_freq) + return MODE_OK; + /* Match 1000/1001 variant */ +- if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) && +- vclk_freq == FREQ_1000_1001(params[i].vclk_freq)) ++ if (phy_freq == PHY_FREQ_1000_1001(params[i].phy_freq) && ++ vclk_freq == PIXEL_FREQ_1000_1001(params[i].vclk_freq)) + return MODE_OK; + } + +@@ -805,8 +810,9 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, + } + EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq); + +-static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, +- unsigned int od1, unsigned int od2, unsigned int od3, ++static void meson_vclk_set(struct meson_drm *priv, ++ unsigned long long pll_base_freq, unsigned int od1, ++ unsigned int od2, unsigned int od3, + unsigned int vid_pll_div, unsigned int vclk_div, + unsigned int hdmi_tx_div, unsigned int venc_div, + bool hdmi_use_enci, bool vic_alternate_clock) +@@ -826,15 +832,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, + meson_hdmi_pll_generic_set(priv, pll_base_freq); + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { + switch (pll_base_freq) { +- case 2970000: ++ case 2970000000: + m = 0x3d; + frac = vic_alternate_clock ? 0xd02 : 0xe00; + break; +- case 4320000: ++ case 4320000000: + m = vic_alternate_clock ? 0x59 : 0x5a; + frac = vic_alternate_clock ? 0xe8f : 0; + break; +- case 5940000: ++ case 5940000000: + m = 0x7b; + frac = vic_alternate_clock ? 0xa05 : 0xc00; + break; +@@ -844,15 +850,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || + meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { + switch (pll_base_freq) { +- case 2970000: ++ case 2970000000: + m = 0x7b; + frac = vic_alternate_clock ? 0x281 : 0x300; + break; +- case 4320000: ++ case 4320000000: + m = vic_alternate_clock ? 0xb3 : 0xb4; + frac = vic_alternate_clock ? 0x347 : 0; + break; +- case 5940000: ++ case 5940000000: + m = 0xf7; + frac = vic_alternate_clock ? 0x102 : 0x200; + break; +@@ -861,15 +867,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, + meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + switch (pll_base_freq) { +- case 2970000: ++ case 2970000000: + m = 0x7b; + frac = vic_alternate_clock ? 0x140b4 : 0x18000; + break; +- case 4320000: ++ case 4320000000: + m = vic_alternate_clock ? 0xb3 : 0xb4; + frac = vic_alternate_clock ? 0x1a3ee : 0; + break; +- case 5940000: ++ case 5940000000: + m = 0xf7; + frac = vic_alternate_clock ? 0x8148 : 0x10000; + break; +@@ -1025,14 +1031,14 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, + } + + void meson_vclk_setup(struct meson_drm *priv, unsigned int target, +- unsigned int phy_freq, unsigned int vclk_freq, +- unsigned int venc_freq, unsigned int dac_freq, ++ unsigned long long phy_freq, unsigned long long vclk_freq, ++ unsigned long long venc_freq, unsigned long long dac_freq, + bool hdmi_use_enci) + { + bool vic_alternate_clock = false; +- unsigned int freq; +- unsigned int hdmi_tx_div; +- unsigned int venc_div; ++ unsigned long long freq; ++ unsigned long long hdmi_tx_div; ++ unsigned long long venc_div; + + if (target == MESON_VCLK_TARGET_CVBS) { + meson_venci_cvbs_clock_config(priv); +@@ -1052,27 +1058,27 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + return; + } + +- hdmi_tx_div = vclk_freq / dac_freq; ++ hdmi_tx_div = DIV_ROUND_DOWN_ULL(vclk_freq, dac_freq); + + if (hdmi_tx_div == 0) { +- pr_err("Fatal Error, invalid HDMI-TX freq %d\n", ++ pr_err("Fatal Error, invalid HDMI-TX freq %lluHz\n", + dac_freq); + return; + } + +- venc_div = vclk_freq / venc_freq; ++ venc_div = DIV_ROUND_DOWN_ULL(vclk_freq, venc_freq); + + if (venc_div == 0) { +- pr_err("Fatal Error, invalid HDMI venc freq %d\n", ++ pr_err("Fatal Error, invalid HDMI venc freq %lluHz\n", + venc_freq); + return; + } + + for (freq = 0 ; params[freq].pixel_freq ; ++freq) { + if ((phy_freq == params[freq].phy_freq || +- phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) && ++ phy_freq == PHY_FREQ_1000_1001(params[freq].phy_freq)) && + (vclk_freq == params[freq].vclk_freq || +- vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) { ++ vclk_freq == PIXEL_FREQ_1000_1001(params[freq].vclk_freq))) { + if (vclk_freq != params[freq].vclk_freq) + vic_alternate_clock = true; + else +@@ -1098,7 +1104,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, + } + + if (!params[freq].pixel_freq) { +- pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq); ++ pr_err("Fatal Error, invalid HDMI vclk freq %lluHz\n", ++ vclk_freq); + return; + } + +diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h +index 60617aaf18dd1..7ac55744e5749 100644 +--- a/drivers/gpu/drm/meson/meson_vclk.h ++++ b/drivers/gpu/drm/meson/meson_vclk.h +@@ -20,17 +20,18 @@ enum { + }; + + /* 27MHz is the CVBS Pixel Clock */ +-#define MESON_VCLK_CVBS 27000 ++#define MESON_VCLK_CVBS (27 * 1000 * 1000) + + enum drm_mode_status +-meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq); ++meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq); + enum drm_mode_status +-meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, +- unsigned int vclk_freq); ++meson_vclk_vic_supported_freq(struct meson_drm *priv, ++ unsigned long long phy_freq, ++ unsigned long long vclk_freq); + + void meson_vclk_setup(struct meson_drm *priv, unsigned int target, +- unsigned int phy_freq, unsigned int vclk_freq, +- unsigned int venc_freq, unsigned int dac_freq, ++ unsigned long long phy_freq, unsigned long long vclk_freq, ++ unsigned long long venc_freq, unsigned long long dac_freq, + bool hdmi_use_enci); + + #endif /* __MESON_VCLK_H */ +-- +2.39.5 + diff --git a/queue-5.15/drm-meson-use-vclk_freq-instead-of-pixel_freq-in-deb.patch b/queue-5.15/drm-meson-use-vclk_freq-instead-of-pixel_freq-in-deb.patch new file mode 100644 index 0000000000..7aa00d92a3 --- /dev/null +++ b/queue-5.15/drm-meson-use-vclk_freq-instead-of-pixel_freq-in-deb.patch @@ -0,0 +1,46 @@ +From 670f7e4f07f34dbc0fbb8d38433f6bde61a7fb85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Jun 2025 00:10:31 +0200 +Subject: drm/meson: use vclk_freq instead of pixel_freq in debug print + +From: Martin Blumenstingl + +[ Upstream commit faf2f8382088e8c74bd6eeb236c8c9190e61615e ] + +meson_vclk_vic_supported_freq() has a debug print which includes the +pixel freq. However, within the whole function the pixel freq is +irrelevant, other than checking the end of the params array. Switch to +printing the vclk_freq which is being compared / matched against the +inputs to the function to avoid confusion when analyzing error reports +from users. + +Fixes: e5fab2ec9ca4 ("drm/meson: vclk: add support for YUV420 setup") +Signed-off-by: Martin Blumenstingl +Reviewed-by: Neil Armstrong +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250606221031.3419353-1-martin.blumenstingl@googlemail.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/meson/meson_vclk.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c +index 3325580d885d0..c4123bb958e4c 100644 +--- a/drivers/gpu/drm/meson/meson_vclk.c ++++ b/drivers/gpu/drm/meson/meson_vclk.c +@@ -790,9 +790,9 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, + } + + for (i = 0 ; params[i].pixel_freq ; ++i) { +- DRM_DEBUG_DRIVER("i = %d pixel_freq = %lluHz alt = %lluHz\n", +- i, params[i].pixel_freq, +- PIXEL_FREQ_1000_1001(params[i].pixel_freq)); ++ DRM_DEBUG_DRIVER("i = %d vclk_freq = %lluHz alt = %lluHz\n", ++ i, params[i].vclk_freq, ++ PIXEL_FREQ_1000_1001(params[i].vclk_freq)); + DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", + i, params[i].phy_freq, + PHY_FREQ_1000_1001(params[i].phy_freq)); +-- +2.39.5 + diff --git a/queue-5.15/i40e-retry-vflr-handling-if-there-is-ongoing-vf-rese.patch b/queue-5.15/i40e-retry-vflr-handling-if-there-is-ongoing-vf-rese.patch new file mode 100644 index 0000000000..f59d5ce324 --- /dev/null +++ b/queue-5.15/i40e-retry-vflr-handling-if-there-is-ongoing-vf-rese.patch @@ -0,0 +1,44 @@ +From 944cbbefbbd108c9555933c8a2c3226da2cc7824 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 May 2025 10:31:52 +0200 +Subject: i40e: retry VFLR handling if there is ongoing VF reset + +From: Robert Malz + +[ Upstream commit fb4e9239e029954a37a00818b21e837cebf2aa10 ] + +When a VFLR interrupt is received during a VF reset initiated from a +different source, the VFLR may be not fully handled. This can +leave the VF in an undefined state. +To address this, set the I40E_VFLR_EVENT_PENDING bit again during VFLR +handling if the reset is not yet complete. This ensures the driver +will properly complete the VF reset in such scenarios. + +Fixes: 52424f974bc5 ("i40e: Fix VF hang when reset is triggered on another VF") +Signed-off-by: Robert Malz +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index a5265b1a7184a..d5b8462aa3eae 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -4212,7 +4212,10 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf) + reg = rd32(hw, I40E_GLGEN_VFLRSTAT(reg_idx)); + if (reg & BIT(bit_idx)) + /* i40e_reset_vf will clear the bit in GLGEN_VFLRSTAT */ +- i40e_reset_vf(vf, true); ++ if (!i40e_reset_vf(vf, true)) { ++ /* At least one VF did not finish resetting, retry next time */ ++ set_bit(__I40E_VFLR_EVENT_PENDING, pf->state); ++ } + } + + return 0; +-- +2.39.5 + diff --git a/queue-5.15/i40e-return-false-from-i40e_reset_vf-if-reset-is-in-.patch b/queue-5.15/i40e-return-false-from-i40e_reset_vf-if-reset-is-in-.patch new file mode 100644 index 0000000000..098dff6dd6 --- /dev/null +++ b/queue-5.15/i40e-return-false-from-i40e_reset_vf-if-reset-is-in-.patch @@ -0,0 +1,55 @@ +From 74b93cdc9b96406045575968fd343a9104bccecf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 May 2025 10:31:51 +0200 +Subject: i40e: return false from i40e_reset_vf if reset is in progress + +From: Robert Malz + +[ Upstream commit a2c90d63b71223d69a813333c1abf4fdacddbbe5 ] + +The function i40e_vc_reset_vf attempts, up to 20 times, to handle a +VF reset request, using the return value of i40e_reset_vf as an indicator +of whether the reset was successfully triggered. Currently, i40e_reset_vf +always returns true, which causes new reset requests to be ignored if a +different VF reset is already in progress. + +This patch updates the return value of i40e_reset_vf to reflect when +another VF reset is in progress, allowing the caller to properly use +the retry mechanism. + +Fixes: 52424f974bc5 ("i40e: Fix VF hang when reset is triggered on another VF") +Signed-off-by: Robert Malz +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 65a29f955d9c4..a5265b1a7184a 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -1548,8 +1548,8 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf) + * @vf: pointer to the VF structure + * @flr: VFLR was issued or not + * +- * Returns true if the VF is in reset, resets successfully, or resets +- * are disabled and false otherwise. ++ * Return: True if reset was performed successfully or if resets are disabled. ++ * False if reset is already in progress. + **/ + bool i40e_reset_vf(struct i40e_vf *vf, bool flr) + { +@@ -1568,7 +1568,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr) + + /* If VF is being reset already we don't need to continue. */ + if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) +- return true; ++ return false; + + i40e_trigger_vf_reset(vf, flr); + +-- +2.39.5 + diff --git a/queue-5.15/macsec-macsec-sci-assignment-for-es-0.patch b/queue-5.15/macsec-macsec-sci-assignment-for-es-0.patch new file mode 100644 index 0000000000..ee5dde9b22 --- /dev/null +++ b/queue-5.15/macsec-macsec-sci-assignment-for-es-0.patch @@ -0,0 +1,128 @@ +From 41186784348e3f0fa0d1ec26af1cc60587bc4d22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jun 2025 09:26:26 +0200 +Subject: macsec: MACsec SCI assignment for ES = 0 + +From: Carlos Fernandez + +[ Upstream commit d9816ec74e6d6aa29219d010bba3f780ba1d9d75 ] + +According to 802.1AE standard, when ES and SC flags in TCI are zero, +used SCI should be the current active SC_RX. Current code uses the +header MAC address. Without this patch, when ES flag is 0 (using a +bridge or switch), header MAC will not fit the SCI and MACSec frames +will be discarted. + +In order to test this issue, MACsec link should be stablished between +two interfaces, setting SC and ES flags to zero and a port identifier +different than one. For example, using ip macsec tools: + +ip link add link $ETH0 macsec0 type macsec port 11 send_sci off +end_station off +ip macsec add macsec0 tx sa 0 pn 2 on key 01 $ETH1_KEY +ip macsec add macsec0 rx port 11 address $ETH1_MAC +ip macsec add macsec0 rx port 11 address $ETH1_MAC sa 0 pn 2 on key 02 +ip link set dev macsec0 up + +ip link add link $ETH1 macsec1 type macsec port 11 send_sci off +end_station off +ip macsec add macsec1 tx sa 0 pn 2 on key 01 $ETH0_KEY +ip macsec add macsec1 rx port 11 address $ETH0_MAC +ip macsec add macsec1 rx port 11 address $ETH0_MAC sa 0 pn 2 on key 02 +ip link set dev macsec1 up + +Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") +Co-developed-by: Andreu Montiel +Signed-off-by: Andreu Montiel +Signed-off-by: Carlos Fernandez +Reviewed-by: Subbaraya Sundeep +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/macsec.c | 40 ++++++++++++++++++++++++++++++++++------ + 1 file changed, 34 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index a91c409958ff2..79ce61a78644e 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -261,15 +261,39 @@ static sci_t make_sci(u8 *addr, __be16 port) + return sci; + } + +-static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present) ++static sci_t macsec_active_sci(struct macsec_secy *secy) + { +- sci_t sci; ++ struct macsec_rx_sc *rx_sc = rcu_dereference_bh(secy->rx_sc); ++ ++ /* Case single RX SC */ ++ if (rx_sc && !rcu_dereference_bh(rx_sc->next)) ++ return (rx_sc->active) ? rx_sc->sci : 0; ++ /* Case no RX SC or multiple */ ++ else ++ return 0; ++} ++ ++static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present, ++ struct macsec_rxh_data *rxd) ++{ ++ struct macsec_dev *macsec; ++ sci_t sci = 0; + +- if (sci_present) ++ /* SC = 1 */ ++ if (sci_present) { + memcpy(&sci, hdr->secure_channel_id, + sizeof(hdr->secure_channel_id)); +- else ++ /* SC = 0; ES = 0 */ ++ } else if ((!(hdr->tci_an & (MACSEC_TCI_ES | MACSEC_TCI_SC))) && ++ (list_is_singular(&rxd->secys))) { ++ /* Only one SECY should exist on this scenario */ ++ macsec = list_first_or_null_rcu(&rxd->secys, struct macsec_dev, ++ secys); ++ if (macsec) ++ return macsec_active_sci(&macsec->secy); ++ } else { + sci = make_sci(hdr->eth.h_source, MACSEC_PORT_ES); ++ } + + return sci; + } +@@ -1092,7 +1116,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) + struct macsec_rxh_data *rxd; + struct macsec_dev *macsec; + unsigned int len; +- sci_t sci; ++ sci_t sci = 0; + u32 hdr_pn; + bool cbit; + struct pcpu_rx_sc_stats *rxsc_stats; +@@ -1139,11 +1163,14 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) + + macsec_skb_cb(skb)->has_sci = !!(hdr->tci_an & MACSEC_TCI_SC); + macsec_skb_cb(skb)->assoc_num = hdr->tci_an & MACSEC_AN_MASK; +- sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci); + + rcu_read_lock(); + rxd = macsec_data_rcu(skb->dev); + ++ sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci, rxd); ++ if (!sci) ++ goto drop_nosc; ++ + list_for_each_entry_rcu(macsec, &rxd->secys, secys) { + struct macsec_rx_sc *sc = find_rx_sc(&macsec->secy, sci); + +@@ -1266,6 +1293,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) + macsec_rxsa_put(rx_sa); + drop_nosa: + macsec_rxsc_put(rx_sc); ++drop_nosc: + rcu_read_unlock(); + drop_direct: + kfree_skb(skb); +-- +2.39.5 + diff --git a/queue-5.15/net-fix-toctou-issue-in-sk_is_readable.patch b/queue-5.15/net-fix-toctou-issue-in-sk_is_readable.patch new file mode 100644 index 0000000000..c6831fd573 --- /dev/null +++ b/queue-5.15/net-fix-toctou-issue-in-sk_is_readable.patch @@ -0,0 +1,52 @@ +From 9b00c07d892251241cb49aef2ceca2a08cea80dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jun 2025 19:08:03 +0200 +Subject: net: Fix TOCTOU issue in sk_is_readable() + +From: Michal Luczaj + +[ Upstream commit 2660a544fdc0940bba15f70508a46cf9a6491230 ] + +sk->sk_prot->sock_is_readable is a valid function pointer when sk resides +in a sockmap. After the last sk_psock_put() (which usually happens when +socket is removed from sockmap), sk->sk_prot gets restored and +sk->sk_prot->sock_is_readable becomes NULL. + +This makes sk_is_readable() racy, if the value of sk->sk_prot is reloaded +after the initial check. Which in turn may lead to a null pointer +dereference. + +Ensure the function pointer does not turn NULL after the check. + +Fixes: 8934ce2fd081 ("bpf: sockmap redirect ingress support") +Suggested-by: Jakub Sitnicki +Signed-off-by: Michal Luczaj +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20250609-skisreadable-toctou-v1-1-d0dfb2d62c37@rbox.co +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index 0461890f10ae7..fd68fd0adae7f 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2935,8 +2935,11 @@ int sock_bind_add(struct sock *sk, struct sockaddr *addr, int addr_len); + + static inline bool sk_is_readable(struct sock *sk) + { +- if (sk->sk_prot->sock_is_readable) +- return sk->sk_prot->sock_is_readable(sk); ++ const struct proto *prot = READ_ONCE(sk->sk_prot); ++ ++ if (prot->sock_is_readable) ++ return prot->sock_is_readable(sk); ++ + return false; + } + #endif /* _SOCK_H */ +-- +2.39.5 + diff --git a/queue-5.15/net-mdio-c22-is-now-optional-eopnotsupp-if-not-provi.patch b/queue-5.15/net-mdio-c22-is-now-optional-eopnotsupp-if-not-provi.patch new file mode 100644 index 0000000000..87837f7555 --- /dev/null +++ b/queue-5.15/net-mdio-c22-is-now-optional-eopnotsupp-if-not-provi.patch @@ -0,0 +1,53 @@ +From 80a404213e3236f2e5e14ca8b6cb09b327d27ab7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 16:30:44 +0100 +Subject: net: mdio: C22 is now optional, EOPNOTSUPP if not provided + +From: Andrew Lunn + +[ Upstream commit b063b1924fd9bf0bc157cf644764dc2151d04ccc ] + +When performing a C22 operation, check that the bus driver actually +provides the methods, and return -EOPNOTSUPP if not. C45 only busses +do exist, and in future their C22 methods will be NULL. + +Signed-off-by: Andrew Lunn +Signed-off-by: Michael Walle +Signed-off-by: Jakub Kicinski +Stable-dep-of: 0e629694126c ("net/mdiobus: Fix potential out-of-bounds read/write access") +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mdio_bus.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c +index 5f89828fd9f17..c26f46c06a1b2 100644 +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -757,7 +757,10 @@ int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum) + + lockdep_assert_held_once(&bus->mdio_lock); + +- retval = bus->read(bus, addr, regnum); ++ if (bus->read) ++ retval = bus->read(bus, addr, regnum); ++ else ++ retval = -EOPNOTSUPP; + + trace_mdio_access(bus, 1, addr, regnum, retval, retval); + mdiobus_stats_acct(&bus->stats[addr], true, retval); +@@ -783,7 +786,10 @@ int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val) + + lockdep_assert_held_once(&bus->mdio_lock); + +- err = bus->write(bus, addr, regnum, val); ++ if (bus->write) ++ err = bus->write(bus, addr, regnum, val); ++ else ++ err = -EOPNOTSUPP; + + trace_mdio_access(bus, 0, addr, regnum, val, err); + mdiobus_stats_acct(&bus->stats[addr], false, err); +-- +2.39.5 + diff --git a/queue-5.15/net-mdiobus-fix-potential-out-of-bounds-read-write-a.patch b/queue-5.15/net-mdiobus-fix-potential-out-of-bounds-read-write-a.patch new file mode 100644 index 0000000000..5ec671b5bf --- /dev/null +++ b/queue-5.15/net-mdiobus-fix-potential-out-of-bounds-read-write-a.patch @@ -0,0 +1,58 @@ +From 08af38c563eedb9339b70de05042b467ed730dcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jun 2025 17:31:46 +0200 +Subject: net/mdiobus: Fix potential out-of-bounds read/write access + +From: Jakub Raczynski + +[ Upstream commit 0e629694126ca388916f059453a1c36adde219c4 ] + +When using publicly available tools like 'mdio-tools' to read/write data +from/to network interface and its PHY via mdiobus, there is no verification of +parameters passed to the ioctl and it accepts any mdio address. +Currently there is support for 32 addresses in kernel via PHY_MAX_ADDR define, +but it is possible to pass higher value than that via ioctl. +While read/write operation should generally fail in this case, +mdiobus provides stats array, where wrong address may allow out-of-bounds +read/write. + +Fix that by adding address verification before read/write operation. +While this excludes this access from any statistics, it improves security of +read/write operation. + +Fixes: 080bb352fad00 ("net: phy: Maintain MDIO device and bus statistics") +Signed-off-by: Jakub Raczynski +Reported-by: Wenjing Shan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mdio_bus.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c +index c26f46c06a1b2..95536c5e541da 100644 +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -757,6 +757,9 @@ int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum) + + lockdep_assert_held_once(&bus->mdio_lock); + ++ if (addr >= PHY_MAX_ADDR) ++ return -ENXIO; ++ + if (bus->read) + retval = bus->read(bus, addr, regnum); + else +@@ -786,6 +789,9 @@ int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val) + + lockdep_assert_held_once(&bus->mdio_lock); + ++ if (addr >= PHY_MAX_ADDR) ++ return -ENXIO; ++ + if (bus->write) + err = bus->write(bus, addr, regnum, val); + else +-- +2.39.5 + diff --git a/queue-5.15/net-mlx5-ensure-fw-pages-are-always-allocated-on-sam.patch b/queue-5.15/net-mlx5-ensure-fw-pages-are-always-allocated-on-sam.patch new file mode 100644 index 0000000000..c3c958a510 --- /dev/null +++ b/queue-5.15/net-mlx5-ensure-fw-pages-are-always-allocated-on-sam.patch @@ -0,0 +1,43 @@ +From 7b6e1fc619838f25abc016813a633295eb442d6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jun 2025 18:15:06 +0300 +Subject: net/mlx5: Ensure fw pages are always allocated on same NUMA + +From: Moshe Shemesh + +[ Upstream commit f37258133c1e95e61db532e14067e28b4881bf24 ] + +When firmware asks the driver to allocate more pages, using event of +give_pages, the driver should always allocate it from same NUMA, the +original device NUMA. Current code uses dev_to_node() which can result +in different NUMA as it is changed by other driver flows, such as +mlx5_dma_zalloc_coherent_node(). Instead, use saved numa node for +allocating firmware pages. + +Fixes: 311c7c71c9bb ("net/mlx5e: Allocate DMA coherent memory on reader NUMA node") +Signed-off-by: Moshe Shemesh +Reviewed-by: Tariq Toukan +Signed-off-by: Mark Bloch +Link: https://patch.msgid.link/20250610151514.1094735-2-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +index ae6ac51b8ab03..fadb94e9a4bf2 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +@@ -272,7 +272,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 function) + static int alloc_system_page(struct mlx5_core_dev *dev, u32 function) + { + struct device *device = mlx5_core_dma_dev(dev); +- int nid = dev_to_node(device); ++ int nid = dev->priv.numa_node; + struct page *page; + u64 zero_addr = 1; + u64 addr; +-- +2.39.5 + diff --git a/queue-5.15/net-mlx5-fix-return-value-when-searching-for-existin.patch b/queue-5.15/net-mlx5-fix-return-value-when-searching-for-existin.patch new file mode 100644 index 0000000000..800c441221 --- /dev/null +++ b/queue-5.15/net-mlx5-fix-return-value-when-searching-for-existin.patch @@ -0,0 +1,61 @@ +From 07073e70d378e0269eb89ccbde240221ac28a322 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jun 2025 18:15:08 +0300 +Subject: net/mlx5: Fix return value when searching for existing flow group + +From: Patrisious Haddad + +[ Upstream commit 8ec40e3f1f72bf8f8accf18020d487caa99f46a4 ] + +When attempting to add a rule to an existing flow group, if a matching +flow group exists but is not active, the error code returned should be +EAGAIN, so that the rule can be added to the matching flow group once +it is active, rather than ENOENT, which indicates that no matching +flow group was found. + +Fixes: bd71b08ec2ee ("net/mlx5: Support multiple updates of steering rules in parallel") +Signed-off-by: Gavi Teitz +Signed-off-by: Roi Dayan +Signed-off-by: Patrisious Haddad +Reviewed-by: Tariq Toukan +Signed-off-by: Mark Bloch +Link: https://patch.msgid.link/20250610151514.1094735-4-mbloch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +index 8ff2b81960de7..ef56a71e43d70 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -1876,6 +1876,7 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft, + struct mlx5_flow_handle *rule; + struct match_list *iter; + bool take_write = false; ++ bool try_again = false; + struct fs_fte *fte; + u64 version = 0; + int err; +@@ -1935,6 +1936,7 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft, + nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); + + if (!g->node.active) { ++ try_again = true; + up_write_ref_node(&g->node, false); + continue; + } +@@ -1956,7 +1958,8 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft, + tree_put_node(&fte->node, false); + return rule; + } +- rule = ERR_PTR(-ENOENT); ++ err = try_again ? -EAGAIN : -ENOENT; ++ rule = ERR_PTR(err); + out: + kmem_cache_free(steering->ftes_cache, fte); + return rule; +-- +2.39.5 + diff --git a/queue-5.15/net_sched-ets-fix-a-race-in-ets_qdisc_change.patch b/queue-5.15/net_sched-ets-fix-a-race-in-ets_qdisc_change.patch new file mode 100644 index 0000000000..fecb0f94c3 --- /dev/null +++ b/queue-5.15/net_sched-ets-fix-a-race-in-ets_qdisc_change.patch @@ -0,0 +1,58 @@ +From 671c674603c6e3013ad5cc33fe8b303fb6dfb13b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 11:15:14 +0000 +Subject: net_sched: ets: fix a race in ets_qdisc_change() + +From: Eric Dumazet + +[ Upstream commit d92adacdd8c2960be856e0b82acc5b7c5395fddb ] + +Gerrard Tai reported a race condition in ETS, whenever SFQ perturb timer +fires at the wrong time. + +The race is as follows: + +CPU 0 CPU 1 +[1]: lock root +[2]: qdisc_tree_flush_backlog() +[3]: unlock root + | + | [5]: lock root + | [6]: rehash + | [7]: qdisc_tree_reduce_backlog() + | +[4]: qdisc_put() + +This can be abused to underflow a parent's qlen. + +Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() +should fix the race, because all packets will be purged from the qdisc +before releasing the lock. + +Fixes: b05972f01e7d ("net: sched: tbf: don't call qdisc_put() while holding tree lock") +Reported-by: Gerrard Tai +Suggested-by: Gerrard Tai +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20250611111515.1983366-5-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_ets.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c +index a37979ec78f88..b49e1a9775865 100644 +--- a/net/sched/sch_ets.c ++++ b/net/sched/sch_ets.c +@@ -675,7 +675,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt, + for (i = q->nbands; i < oldbands; i++) { + if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) + list_del_init(&q->classes[i].alist); +- qdisc_tree_flush_backlog(q->classes[i].qdisc); ++ qdisc_purge_queue(q->classes[i].qdisc); + } + q->nstrict = nstrict; + memcpy(q->prio2band, priomap, sizeof(priomap)); +-- +2.39.5 + diff --git a/queue-5.15/net_sched-prio-fix-a-race-in-prio_tune.patch b/queue-5.15/net_sched-prio-fix-a-race-in-prio_tune.patch new file mode 100644 index 0000000000..f2fa09973d --- /dev/null +++ b/queue-5.15/net_sched-prio-fix-a-race-in-prio_tune.patch @@ -0,0 +1,58 @@ +From 2d453b7250a1fae696d9f55595edcaa4c3547e94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 11:15:11 +0000 +Subject: net_sched: prio: fix a race in prio_tune() + +From: Eric Dumazet + +[ Upstream commit d35acc1be3480505b5931f17e4ea9b7617fea4d3 ] + +Gerrard Tai reported a race condition in PRIO, whenever SFQ perturb timer +fires at the wrong time. + +The race is as follows: + +CPU 0 CPU 1 +[1]: lock root +[2]: qdisc_tree_flush_backlog() +[3]: unlock root + | + | [5]: lock root + | [6]: rehash + | [7]: qdisc_tree_reduce_backlog() + | +[4]: qdisc_put() + +This can be abused to underflow a parent's qlen. + +Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() +should fix the race, because all packets will be purged from the qdisc +before releasing the lock. + +Fixes: 7b8e0b6e6599 ("net: sched: prio: delay destroying child qdiscs on change") +Reported-by: Gerrard Tai +Suggested-by: Gerrard Tai +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20250611111515.1983366-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_prio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c +index 2e0b1e7f54668..b3defe09d9f7b 100644 +--- a/net/sched/sch_prio.c ++++ b/net/sched/sch_prio.c +@@ -211,7 +211,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt, + memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1); + + for (i = q->bands; i < oldbands; i++) +- qdisc_tree_flush_backlog(q->queues[i]); ++ qdisc_purge_queue(q->queues[i]); + + for (i = oldbands; i < q->bands; i++) { + q->queues[i] = queues[i]; +-- +2.39.5 + diff --git a/queue-5.15/net_sched-red-fix-a-race-in-__red_change.patch b/queue-5.15/net_sched-red-fix-a-race-in-__red_change.patch new file mode 100644 index 0000000000..b4b7c5b5de --- /dev/null +++ b/queue-5.15/net_sched-red-fix-a-race-in-__red_change.patch @@ -0,0 +1,58 @@ +From 88a7ca2976d25c43a4d1cce80700512070c68aa7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 11:15:12 +0000 +Subject: net_sched: red: fix a race in __red_change() + +From: Eric Dumazet + +[ Upstream commit 85a3e0ede38450ea3053b8c45d28cf55208409b8 ] + +Gerrard Tai reported a race condition in RED, whenever SFQ perturb timer +fires at the wrong time. + +The race is as follows: + +CPU 0 CPU 1 +[1]: lock root +[2]: qdisc_tree_flush_backlog() +[3]: unlock root + | + | [5]: lock root + | [6]: rehash + | [7]: qdisc_tree_reduce_backlog() + | +[4]: qdisc_put() + +This can be abused to underflow a parent's qlen. + +Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() +should fix the race, because all packets will be purged from the qdisc +before releasing the lock. + +Fixes: 0c8d13ac9607 ("net: sched: red: delay destroying child qdisc on replace") +Reported-by: Gerrard Tai +Suggested-by: Gerrard Tai +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20250611111515.1983366-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_red.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c +index 935d90874b1b7..1b69b7b90d858 100644 +--- a/net/sched/sch_red.c ++++ b/net/sched/sch_red.c +@@ -283,7 +283,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb, + q->userbits = userbits; + q->limit = ctl->limit; + if (child) { +- qdisc_tree_flush_backlog(q->qdisc); ++ qdisc_purge_queue(q->qdisc); + old_child = q->qdisc; + q->qdisc = child; + } +-- +2.39.5 + diff --git a/queue-5.15/net_sched-sch_sfq-fix-a-potential-crash-on-gso_skb-h.patch b/queue-5.15/net_sched-sch_sfq-fix-a-potential-crash-on-gso_skb-h.patch new file mode 100644 index 0000000000..ac79a5253d --- /dev/null +++ b/queue-5.15/net_sched-sch_sfq-fix-a-potential-crash-on-gso_skb-h.patch @@ -0,0 +1,70 @@ +From 58b82237dcce6fa0cfa70279b8c3454630667f63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jun 2025 16:51:27 +0000 +Subject: net_sched: sch_sfq: fix a potential crash on gso_skb handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric Dumazet + +[ Upstream commit 82ffbe7776d0ac084031f114167712269bf3d832 ] + +SFQ has an assumption of always being able to queue at least one packet. + +However, after the blamed commit, sch->q.len can be inflated by packets +in sch->gso_skb, and an enqueue() on an empty SFQ qdisc can be followed +by an immediate drop. + +Fix sfq_drop() to properly clear q->tail in this situation. + +Tested: + +ip netns add lb +ip link add dev to-lb type veth peer name in-lb netns lb +ethtool -K to-lb tso off # force qdisc to requeue gso_skb +ip netns exec lb ethtool -K in-lb gro on # enable NAPI +ip link set dev to-lb up +ip -netns lb link set dev in-lb up +ip addr add dev to-lb 192.168.20.1/24 +ip -netns lb addr add dev in-lb 192.168.20.2/24 +tc qdisc replace dev to-lb root sfq limit 100 + +ip netns exec lb netserver + +netperf -H 192.168.20.2 -l 100 & +netperf -H 192.168.20.2 -l 100 & +netperf -H 192.168.20.2 -l 100 & +netperf -H 192.168.20.2 -l 100 & + +Fixes: a53851e2c321 ("net: sched: explicit locking in gso_cpu fallback") +Reported-by: Marcus Wichelmann +Closes: https://lore.kernel.org/netdev/9da42688-bfaa-4364-8797-e9271f3bdaef@hetzner-cloud.de/ +Signed-off-by: Eric Dumazet +Reviewed-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20250606165127.3629486-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_sfq.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c +index f8e569f79f136..8cd4e663575c6 100644 +--- a/net/sched/sch_sfq.c ++++ b/net/sched/sch_sfq.c +@@ -317,7 +317,10 @@ static unsigned int sfq_drop(struct Qdisc *sch, struct sk_buff **to_free) + /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ + x = q->tail->next; + slot = &q->slots[x]; +- q->tail->next = slot->next; ++ if (slot->next == x) ++ q->tail = NULL; /* no more active slots */ ++ else ++ q->tail->next = slot->next; + q->ht[slot->hash] = SFQ_EMPTY_SLOT; + goto drop; + } +-- +2.39.5 + diff --git a/queue-5.15/net_sched-tbf-fix-a-race-in-tbf_change.patch b/queue-5.15/net_sched-tbf-fix-a-race-in-tbf_change.patch new file mode 100644 index 0000000000..29b3dfab6e --- /dev/null +++ b/queue-5.15/net_sched-tbf-fix-a-race-in-tbf_change.patch @@ -0,0 +1,59 @@ +From 3963e41aa92cb130dfdaabf3a56c19182f5d9235 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 11:15:13 +0000 +Subject: net_sched: tbf: fix a race in tbf_change() + +From: Eric Dumazet + +[ Upstream commit 43eb466041216d25dedaef1c383ad7bd89929cbc ] + +Gerrard Tai reported a race condition in TBF, whenever SFQ perturb timer +fires at the wrong time. + +The race is as follows: + +CPU 0 CPU 1 +[1]: lock root +[2]: qdisc_tree_flush_backlog() +[3]: unlock root + | + | [5]: lock root + | [6]: rehash + | [7]: qdisc_tree_reduce_backlog() + | +[4]: qdisc_put() + +This can be abused to underflow a parent's qlen. + +Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() +should fix the race, because all packets will be purged from the qdisc +before releasing the lock. + +Fixes: b05972f01e7d ("net: sched: tbf: don't call qdisc_put() while holding tree lock") +Reported-by: Gerrard Tai +Suggested-by: Gerrard Tai +Signed-off-by: Eric Dumazet +Cc: Zhengchao Shao +Link: https://patch.msgid.link/20250611111515.1983366-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_tbf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c +index 5f50fdeaafa8d..411970dc07f74 100644 +--- a/net/sched/sch_tbf.c ++++ b/net/sched/sch_tbf.c +@@ -437,7 +437,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt, + + sch_tree_lock(sch); + if (child) { +- qdisc_tree_flush_backlog(q->qdisc); ++ qdisc_purge_queue(q->qdisc); + old = q->qdisc; + q->qdisc = child; + } +-- +2.39.5 + diff --git a/queue-5.15/powerpc-powernv-memtrace-fix-out-of-bounds-issue-in-.patch b/queue-5.15/powerpc-powernv-memtrace-fix-out-of-bounds-issue-in-.patch new file mode 100644 index 0000000000..7131d579f6 --- /dev/null +++ b/queue-5.15/powerpc-powernv-memtrace-fix-out-of-bounds-issue-in-.patch @@ -0,0 +1,48 @@ +From 6f6fefd574d5c7652fb0984ddcfd8b37473a52d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jun 2025 07:42:26 +0530 +Subject: powerpc/powernv/memtrace: Fix out of bounds issue in memtrace mmap + +From: Ritesh Harjani (IBM) + +[ Upstream commit cd097df4596f3a1e9d75eb8520162de1eb8485b2 ] + +memtrace mmap issue has an out of bounds issue. This patch fixes the by +checking that the requested mapping region size should stay within the +allocated region size. + +Reported-by: Jonathan Greental +Fixes: 08a022ad3dfa ("powerpc/powernv/memtrace: Allow mmaping trace buffers") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250610021227.361980-1-maddy@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/platforms/powernv/memtrace.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c +index 877720c645151..35471b679638a 100644 +--- a/arch/powerpc/platforms/powernv/memtrace.c ++++ b/arch/powerpc/platforms/powernv/memtrace.c +@@ -48,11 +48,15 @@ static ssize_t memtrace_read(struct file *filp, char __user *ubuf, + static int memtrace_mmap(struct file *filp, struct vm_area_struct *vma) + { + struct memtrace_entry *ent = filp->private_data; ++ unsigned long ent_nrpages = ent->size >> PAGE_SHIFT; ++ unsigned long vma_nrpages = vma_pages(vma); + +- if (ent->size < vma->vm_end - vma->vm_start) ++ /* The requested page offset should be within object's page count */ ++ if (vma->vm_pgoff >= ent_nrpages) + return -EINVAL; + +- if (vma->vm_pgoff << PAGE_SHIFT >= ent->size) ++ /* The requested mapping range should remain within the bounds */ ++ if (vma_nrpages > ent_nrpages - vma->vm_pgoff) + return -EINVAL; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +-- +2.39.5 + diff --git a/queue-5.15/powerpc-vas-return-einval-if-the-offset-is-non-zero-.patch b/queue-5.15/powerpc-vas-return-einval-if-the-offset-is-non-zero-.patch new file mode 100644 index 0000000000..b3784bdcfc --- /dev/null +++ b/queue-5.15/powerpc-vas-return-einval-if-the-offset-is-non-zero-.patch @@ -0,0 +1,52 @@ +From eaed3e3f90b188b77f3d226032e608f0daedec05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jun 2025 07:42:27 +0530 +Subject: powerpc/vas: Return -EINVAL if the offset is non-zero in mmap() + +From: Haren Myneni + +[ Upstream commit 0d67f0dee6c9176bc09a5482dd7346e3a0f14d0b ] + +The user space calls mmap() to map VAS window paste address +and the kernel returns the complete mapped page for each +window. So return -EINVAL if non-zero is passed for offset +parameter to mmap(). + +See Documentation/arch/powerpc/vas-api.rst for mmap() +restrictions. + +Co-developed-by: Jonathan Greental +Signed-off-by: Jonathan Greental +Reported-by: Jonathan Greental +Fixes: dda44eb29c23 ("powerpc/vas: Add VAS user space API") +Signed-off-by: Haren Myneni +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250610021227.361980-2-maddy@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/platforms/book3s/vas-api.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c +index 4d82c92ddd523..bfe52af0719eb 100644 +--- a/arch/powerpc/platforms/book3s/vas-api.c ++++ b/arch/powerpc/platforms/book3s/vas-api.c +@@ -367,6 +367,15 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) + return -EINVAL; + } + ++ /* ++ * Map complete page to the paste address. So the user ++ * space should pass 0ULL to the offset parameter. ++ */ ++ if (vma->vm_pgoff) { ++ pr_debug("Page offset unsupported to map paste address\n"); ++ return -EINVAL; ++ } ++ + /* Ensure instance has an open send window */ + if (!txwin) { + pr_err("%s(): No send window open?\n", __func__); +-- +2.39.5 + diff --git a/queue-5.15/ptp-remove-ptp-n_vclocks-check-logic-in-ptp_vclock_i.patch b/queue-5.15/ptp-remove-ptp-n_vclocks-check-logic-in-ptp_vclock_i.patch new file mode 100644 index 0000000000..9433db8ea2 --- /dev/null +++ b/queue-5.15/ptp-remove-ptp-n_vclocks-check-logic-in-ptp_vclock_i.patch @@ -0,0 +1,90 @@ +From 71e970ced8872e676965ec36a566d771ef693a28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 May 2025 01:07:17 +0900 +Subject: ptp: remove ptp->n_vclocks check logic in ptp_vclock_in_use() + +From: Jeongjun Park + +[ Upstream commit 87f7ce260a3c838b49e1dc1ceedf1006795157a2 ] + +There is no disagreement that we should check both ptp->is_virtual_clock +and ptp->n_vclocks to check if the ptp virtual clock is in use. + +However, when we acquire ptp->n_vclocks_mux to read ptp->n_vclocks in +ptp_vclock_in_use(), we observe a recursive lock in the call trace +starting from n_vclocks_store(). + +============================================ +WARNING: possible recursive locking detected +6.15.0-rc6 #1 Not tainted +-------------------------------------------- +syz.0.1540/13807 is trying to acquire lock: +ffff888035a24868 (&ptp->n_vclocks_mux){+.+.}-{4:4}, at: + ptp_vclock_in_use drivers/ptp/ptp_private.h:103 [inline] +ffff888035a24868 (&ptp->n_vclocks_mux){+.+.}-{4:4}, at: + ptp_clock_unregister+0x21/0x250 drivers/ptp/ptp_clock.c:415 + +but task is already holding lock: +ffff888030704868 (&ptp->n_vclocks_mux){+.+.}-{4:4}, at: + n_vclocks_store+0xf1/0x6d0 drivers/ptp/ptp_sysfs.c:215 + +other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(&ptp->n_vclocks_mux); + lock(&ptp->n_vclocks_mux); + + *** DEADLOCK *** +.... +============================================ + +The best way to solve this is to remove the logic that checks +ptp->n_vclocks in ptp_vclock_in_use(). + +The reason why this is appropriate is that any path that uses +ptp->n_vclocks must unconditionally check if ptp->n_vclocks is greater +than 0 before unregistering vclocks, and all functions are already +written this way. And in the function that uses ptp->n_vclocks, we +already get ptp->n_vclocks_mux before unregistering vclocks. + +Therefore, we need to remove the redundant check for ptp->n_vclocks in +ptp_vclock_in_use() to prevent recursive locking. + +Fixes: 73f37068d540 ("ptp: support ptp physical/virtual clocks conversion") +Signed-off-by: Jeongjun Park +Acked-by: Richard Cochran +Link: https://patch.msgid.link/20250520160717.7350-1-aha310510@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/ptp/ptp_private.h | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h +index b336c12bb6976..f57ed0dd0aa40 100644 +--- a/drivers/ptp/ptp_private.h ++++ b/drivers/ptp/ptp_private.h +@@ -87,17 +87,7 @@ static inline int queue_cnt(const struct timestamp_event_queue *q) + /* Check if ptp virtual clock is in use */ + static inline bool ptp_vclock_in_use(struct ptp_clock *ptp) + { +- bool in_use = false; +- +- if (mutex_lock_interruptible(&ptp->n_vclocks_mux)) +- return true; +- +- if (!ptp->is_virtual_clock && ptp->n_vclocks) +- in_use = true; +- +- mutex_unlock(&ptp->n_vclocks_mux); +- +- return in_use; ++ return !ptp->is_virtual_clock; + } + + extern struct class *ptp_class; +-- +2.39.5 + diff --git a/queue-5.15/sch_ets-make-est_qlen_notify-idempotent.patch b/queue-5.15/sch_ets-make-est_qlen_notify-idempotent.patch new file mode 100644 index 0000000000..4b40282f67 --- /dev/null +++ b/queue-5.15/sch_ets-make-est_qlen_notify-idempotent.patch @@ -0,0 +1,71 @@ +From 7d023a27861971977aab093b09686094ccaa4aed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Apr 2025 14:10:27 -0700 +Subject: sch_ets: make est_qlen_notify() idempotent + +From: Cong Wang + +[ Upstream commit a7a15f39c682ac4268624da2abdb9114bdde96d5 ] + +est_qlen_notify() deletes its class from its active list with +list_del() when qlen is 0, therefore, it is not idempotent and +not friendly to its callers, like fq_codel_dequeue(). + +Let's make it idempotent to ease qdisc_tree_reduce_backlog() callers' +life. Also change other list_del()'s to list_del_init() just to be +extra safe. + +Reported-by: Gerrard Tai +Signed-off-by: Cong Wang +Link: https://patch.msgid.link/20250403211033.166059-6-xiyou.wangcong@gmail.com +Acked-by: Jamal Hadi Salim +Signed-off-by: Paolo Abeni +Stable-dep-of: d92adacdd8c2 ("net_sched: ets: fix a race in ets_qdisc_change()") +Signed-off-by: Sasha Levin +--- + net/sched/sch_ets.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c +index 07fae45f58732..a37979ec78f88 100644 +--- a/net/sched/sch_ets.c ++++ b/net/sched/sch_ets.c +@@ -298,7 +298,7 @@ static void ets_class_qlen_notify(struct Qdisc *sch, unsigned long arg) + * to remove them. + */ + if (!ets_class_is_strict(q, cl) && sch->q.qlen) +- list_del(&cl->alist); ++ list_del_init(&cl->alist); + } + + static int ets_class_dump(struct Qdisc *sch, unsigned long arg, +@@ -499,7 +499,7 @@ static struct sk_buff *ets_qdisc_dequeue(struct Qdisc *sch) + if (unlikely(!skb)) + goto out; + if (cl->qdisc->q.qlen == 0) +- list_del(&cl->alist); ++ list_del_init(&cl->alist); + return ets_qdisc_dequeue_skb(sch, skb); + } + +@@ -674,7 +674,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt, + } + for (i = q->nbands; i < oldbands; i++) { + if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) +- list_del(&q->classes[i].alist); ++ list_del_init(&q->classes[i].alist); + qdisc_tree_flush_backlog(q->classes[i].qdisc); + } + q->nstrict = nstrict; +@@ -723,7 +723,7 @@ static void ets_qdisc_reset(struct Qdisc *sch) + + for (band = q->nstrict; band < q->nbands; band++) { + if (q->classes[band].qdisc->q.qlen) +- list_del(&q->classes[band].alist); ++ list_del_init(&q->classes[band].alist); + } + for (band = 0; band < q->nbands; band++) + qdisc_reset(q->classes[band].qdisc); +-- +2.39.5 + diff --git a/queue-5.15/scsi-core-ufs-fix-a-hang-in-the-error-handler.patch b/queue-5.15/scsi-core-ufs-fix-a-hang-in-the-error-handler.patch new file mode 100644 index 0000000000..63556e4fa7 --- /dev/null +++ b/queue-5.15/scsi-core-ufs-fix-a-hang-in-the-error-handler.patch @@ -0,0 +1,73 @@ +From 243bf0911fc890b7a8161da1c64996d574ac79de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 May 2025 13:14:01 -0700 +Subject: scsi: core: ufs: Fix a hang in the error handler + +From: Sanjeev Yadav + +[ Upstream commit 8a3514d348de87a9d5e2ac00fbac4faae0b97996 ] + +ufshcd_err_handling_prepare() calls ufshcd_rpm_get_sync(). The latter +function can only succeed if UFSHCD_EH_IN_PROGRESS is not set because +resuming involves submitting a SCSI command and ufshcd_queuecommand() +returns SCSI_MLQUEUE_HOST_BUSY if UFSHCD_EH_IN_PROGRESS is set. Fix this +hang by setting UFSHCD_EH_IN_PROGRESS after ufshcd_rpm_get_sync() has +been called instead of before. + +Backtrace: +__switch_to+0x174/0x338 +__schedule+0x600/0x9e4 +schedule+0x7c/0xe8 +schedule_timeout+0xa4/0x1c8 +io_schedule_timeout+0x48/0x70 +wait_for_common_io+0xa8/0x160 //waiting on START_STOP +wait_for_completion_io_timeout+0x10/0x20 +blk_execute_rq+0xe4/0x1e4 +scsi_execute_cmd+0x108/0x244 +ufshcd_set_dev_pwr_mode+0xe8/0x250 +__ufshcd_wl_resume+0x94/0x354 +ufshcd_wl_runtime_resume+0x3c/0x174 +scsi_runtime_resume+0x64/0xa4 +rpm_resume+0x15c/0xa1c +__pm_runtime_resume+0x4c/0x90 // Runtime resume ongoing +ufshcd_err_handler+0x1a0/0xd08 +process_one_work+0x174/0x808 +worker_thread+0x15c/0x490 +kthread+0xf4/0x1ec +ret_from_fork+0x10/0x20 + +Signed-off-by: Sanjeev Yadav +[ bvanassche: rewrote patch description ] +Fixes: 62694735ca95 ("[SCSI] ufs: Add runtime PM support for UFS host controller driver") +Signed-off-by: Bart Van Assche +Link: https://lore.kernel.org/r/20250523201409.1676055-1-bvanassche@acm.org +Reviewed-by: Peter Wang +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ufs/ufshcd.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index e199abc4e6176..2b78cc96ccef6 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -6073,9 +6073,14 @@ static void ufshcd_err_handler(struct work_struct *work) + up(&hba->host_sem); + return; + } +- ufshcd_set_eh_in_progress(hba); + spin_unlock_irqrestore(hba->host->host_lock, flags); ++ + ufshcd_err_handling_prepare(hba); ++ ++ spin_lock_irqsave(hba->host->host_lock, flags); ++ ufshcd_set_eh_in_progress(hba); ++ spin_unlock_irqrestore(hba->host->host_lock, flags); ++ + /* Complete requests that have door-bell cleared by h/w */ + ufshcd_complete_requests(hba); + spin_lock_irqsave(hba->host->host_lock, flags); +-- +2.39.5 + diff --git a/queue-5.15/scsi-iscsi-fix-incorrect-error-path-labels-for-flash.patch b/queue-5.15/scsi-iscsi-fix-incorrect-error-path-labels-for-flash.patch new file mode 100644 index 0000000000..d200fb0240 --- /dev/null +++ b/queue-5.15/scsi-iscsi-fix-incorrect-error-path-labels-for-flash.patch @@ -0,0 +1,99 @@ +From abc05cd6b9a07d8a53dc5f5a07af302fd409ede2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 May 2025 12:29:35 -0700 +Subject: scsi: iscsi: Fix incorrect error path labels for flashnode operations + +From: Alok Tiwari + +[ Upstream commit 9b17621366d210ffee83262a8754086ebbde5e55 ] + +Correct the error handling goto labels used when host lookup fails in +various flashnode-related event handlers: + + - iscsi_new_flashnode() + - iscsi_del_flashnode() + - iscsi_login_flashnode() + - iscsi_logout_flashnode() + - iscsi_logout_flashnode_sid() + +scsi_host_put() is not required when shost is NULL, so jumping to the +correct label avoids unnecessary operations. These functions previously +jumped to the wrong goto label (put_host), which did not match the +intended cleanup logic. + +Use the correct exit labels (exit_new_fnode, exit_del_fnode, etc.) to +ensure proper error handling. Also remove the unused put_host label +under iscsi_new_flashnode() as it is no longer needed. + +No functional changes beyond accurate error path correction. + +Fixes: c6a4bb2ef596 ("[SCSI] scsi_transport_iscsi: Add flash node mgmt support") +Signed-off-by: Alok Tiwari +Link: https://lore.kernel.org/r/20250530193012.3312911-1-alok.a.tiwari@oracle.com +Reviewed-by: Mike Christie +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_transport_iscsi.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c +index 8930acdff08c5..91998e1df94d3 100644 +--- a/drivers/scsi/scsi_transport_iscsi.c ++++ b/drivers/scsi/scsi_transport_iscsi.c +@@ -3545,7 +3545,7 @@ static int iscsi_new_flashnode(struct iscsi_transport *transport, + pr_err("%s could not find host no %u\n", + __func__, ev->u.new_flashnode.host_no); + err = -ENODEV; +- goto put_host; ++ goto exit_new_fnode; + } + + index = transport->new_flashnode(shost, data, len); +@@ -3555,7 +3555,6 @@ static int iscsi_new_flashnode(struct iscsi_transport *transport, + else + err = -EIO; + +-put_host: + scsi_host_put(shost); + + exit_new_fnode: +@@ -3580,7 +3579,7 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport, + pr_err("%s could not find host no %u\n", + __func__, ev->u.del_flashnode.host_no); + err = -ENODEV; +- goto put_host; ++ goto exit_del_fnode; + } + + idx = ev->u.del_flashnode.flashnode_idx; +@@ -3622,7 +3621,7 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport, + pr_err("%s could not find host no %u\n", + __func__, ev->u.login_flashnode.host_no); + err = -ENODEV; +- goto put_host; ++ goto exit_login_fnode; + } + + idx = ev->u.login_flashnode.flashnode_idx; +@@ -3674,7 +3673,7 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport, + pr_err("%s could not find host no %u\n", + __func__, ev->u.logout_flashnode.host_no); + err = -ENODEV; +- goto put_host; ++ goto exit_logout_fnode; + } + + idx = ev->u.logout_flashnode.flashnode_idx; +@@ -3724,7 +3723,7 @@ static int iscsi_logout_flashnode_sid(struct iscsi_transport *transport, + pr_err("%s could not find host no %u\n", + __func__, ev->u.logout_flashnode.host_no); + err = -ENODEV; +- goto put_host; ++ goto exit_logout_sid; + } + + session = iscsi_session_lookup(ev->u.logout_flashnode_sid.sid); +-- +2.39.5 + diff --git a/queue-5.15/series b/queue-5.15/series index af57ba85fc..6e0409b247 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -138,3 +138,27 @@ serial-sh-sci-check-if-tx-data-was-written-to-device.patch serial-sh-sci-move-runtime-pm-enable-to-sci_probe_si.patch serial-sh-sci-clean-sci_ports-0-after-at-earlycon-ex.patch serial-sh-sci-increment-the-runtime-usage-counter-fo.patch +scsi-core-ufs-fix-a-hang-in-the-error-handler.patch +ptp-remove-ptp-n_vclocks-check-logic-in-ptp_vclock_i.patch +ath10k-snoc-fix-unbalanced-irq-enable-in-crash-recov.patch +scsi-iscsi-fix-incorrect-error-path-labels-for-flash.patch +net_sched-sch_sfq-fix-a-potential-crash-on-gso_skb-h.patch +powerpc-powernv-memtrace-fix-out-of-bounds-issue-in-.patch +powerpc-vas-return-einval-if-the-offset-is-non-zero-.patch +drm-meson-use-unsigned-long-long-hz-for-frequency-ty.patch +drm-meson-fix-debug-log-statement-when-setting-the-h.patch +drm-meson-use-vclk_freq-instead-of-pixel_freq-in-deb.patch +drm-meson-fix-more-rounding-issues-with-59.94hz-mode.patch +i40e-return-false-from-i40e_reset_vf-if-reset-is-in-.patch +i40e-retry-vflr-handling-if-there-is-ongoing-vf-rese.patch +net-fix-toctou-issue-in-sk_is_readable.patch +macsec-macsec-sci-assignment-for-es-0.patch +net-mdio-c22-is-now-optional-eopnotsupp-if-not-provi.patch +net-mdiobus-fix-potential-out-of-bounds-read-write-a.patch +net-mlx5-ensure-fw-pages-are-always-allocated-on-sam.patch +net-mlx5-fix-return-value-when-searching-for-existin.patch +net_sched-prio-fix-a-race-in-prio_tune.patch +net_sched-red-fix-a-race-in-__red_change.patch +net_sched-tbf-fix-a-race-in-tbf_change.patch +sch_ets-make-est_qlen_notify-idempotent.patch +net_sched-ets-fix-a-race-in-ets_qdisc_change.patch