--- /dev/null
+From 159c738378ec8436a06680af17a2db0223b140dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 20:50:27 +0000
+Subject: ath10k: snoc: fix unbalanced IRQ enable in crash recovery
+
+From: Caleb Connolly <caleb.connolly@linaro.org>
+
+[ 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 <caleb.connolly@linaro.org>
+Tested-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250318205043.1043148-1-caleb.connolly@linaro.org
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 678c5cce6ed465438482186e1afb419098f4d884 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jun 2025 22:37:29 +0200
+Subject: drm/meson: fix debug log statement when setting the HDMI clocks
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ 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 <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250606203729.3311592-1-martin.blumenstingl@googlemail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 6ee6cd4d8c40947c93ebf06bd6a659dd365743da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jun 2025 22:27:51 +0200
+Subject: drm/meson: fix more rounding issues with 59.94Hz modes
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ 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 <christianshewitt@gmail.com>
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250609202751.962208-1-martin.blumenstingl@googlemail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 590f8745d9ff55ac5576789eb34a96c28ea0d1df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 22:13:00 +0200
+Subject: drm/meson: use unsigned long long / Hz for frequency types
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ 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 <christianshewitt@gmail.com>
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250421201300.778955-3-martin.blumenstingl@googlemail.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+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 <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 670f7e4f07f34dbc0fbb8d38433f6bde61a7fb85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <martin.blumenstingl@googlemail.com>
+
+[ 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 <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250606221031.3419353-1-martin.blumenstingl@googlemail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 944cbbefbbd108c9555933c8a2c3226da2cc7824 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 10:31:52 +0200
+Subject: i40e: retry VFLR handling if there is ongoing VF reset
+
+From: Robert Malz <robert.malz@canonical.com>
+
+[ 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 <robert.malz@canonical.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 74b93cdc9b96406045575968fd343a9104bccecf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <robert.malz@canonical.com>
+
+[ 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 <robert.malz@canonical.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 41186784348e3f0fa0d1ec26af1cc60587bc4d22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jun 2025 09:26:26 +0200
+Subject: macsec: MACsec SCI assignment for ES = 0
+
+From: Carlos Fernandez <carlos.fernandez@technica-engineering.de>
+
+[ 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 <Andreu.Montiel@technica-engineering.de>
+Signed-off-by: Andreu Montiel <Andreu.Montiel@technica-engineering.de>
+Signed-off-by: Carlos Fernandez <carlos.fernandez@technica-engineering.de>
+Reviewed-by: Subbaraya Sundeep <sbhatta@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 9b00c07d892251241cb49aef2ceca2a08cea80dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jun 2025 19:08:03 +0200
+Subject: net: Fix TOCTOU issue in sk_is_readable()
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ 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 <jakub@cloudflare.com>
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250609-skisreadable-toctou-v1-1-d0dfb2d62c37@rbox.co
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 80a404213e3236f2e5e14ca8b6cb09b327d27ab7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 16:30:44 +0100
+Subject: net: mdio: C22 is now optional, EOPNOTSUPP if not provided
+
+From: Andrew Lunn <andrew@lunn.ch>
+
+[ 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 <andrew@lunn.ch>
+Signed-off-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 0e629694126c ("net/mdiobus: Fix potential out-of-bounds read/write access")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 08af38c563eedb9339b70de05042b467ed730dcd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jun 2025 17:31:46 +0200
+Subject: net/mdiobus: Fix potential out-of-bounds read/write access
+
+From: Jakub Raczynski <j.raczynski@samsung.com>
+
+[ 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 <j.raczynski@samsung.com>
+Reported-by: Wenjing Shan <wenjing.shan@samsung.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 7b6e1fc619838f25abc016813a633295eb442d6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jun 2025 18:15:06 +0300
+Subject: net/mlx5: Ensure fw pages are always allocated on same NUMA
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ 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 <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250610151514.1094735-2-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 07073e70d378e0269eb89ccbde240221ac28a322 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jun 2025 18:15:08 +0300
+Subject: net/mlx5: Fix return value when searching for existing flow group
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ 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 <gavi@nvidia.com>
+Signed-off-by: Roi Dayan <roid@nvidia.com>
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250610151514.1094735-4-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 671c674603c6e3013ad5cc33fe8b303fb6dfb13b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 11:15:14 +0000
+Subject: net_sched: ets: fix a race in ets_qdisc_change()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <gerrard.tai@starlabs.sg>
+Suggested-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250611111515.1983366-5-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 2d453b7250a1fae696d9f55595edcaa4c3547e94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 11:15:11 +0000
+Subject: net_sched: prio: fix a race in prio_tune()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <gerrard.tai@starlabs.sg>
+Suggested-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250611111515.1983366-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 88a7ca2976d25c43a4d1cce80700512070c68aa7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 11:15:12 +0000
+Subject: net_sched: red: fix a race in __red_change()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <gerrard.tai@starlabs.sg>
+Suggested-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250611111515.1983366-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 58b82237dcce6fa0cfa70279b8c3454630667f63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <edumazet@google.com>
+
+[ 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 <marcus.wichelmann@hetzner-cloud.de>
+Closes: https://lore.kernel.org/netdev/9da42688-bfaa-4364-8797-e9271f3bdaef@hetzner-cloud.de/
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Link: https://patch.msgid.link/20250606165127.3629486-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 3963e41aa92cb130dfdaabf3a56c19182f5d9235 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 11:15:13 +0000
+Subject: net_sched: tbf: fix a race in tbf_change()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <gerrard.tai@starlabs.sg>
+Suggested-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Zhengchao Shao <shaozhengchao@huawei.com>
+Link: https://patch.msgid.link/20250611111515.1983366-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 6f6fefd574d5c7652fb0984ddcfd8b37473a52d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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) <ritesh.list@gmail.com>
+
+[ 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 <yonatan02greental@gmail.com>
+Fixes: 08a022ad3dfa ("powerpc/powernv/memtrace: Allow mmaping trace buffers")
+Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250610021227.361980-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From eaed3e3f90b188b77f3d226032e608f0daedec05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <haren@linux.ibm.com>
+
+[ 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 <yonatan02greental@gmail.com>
+Signed-off-by: Jonathan Greental <yonatan02greental@gmail.com>
+Reported-by: Jonathan Greental <yonatan02greental@gmail.com>
+Fixes: dda44eb29c23 ("powerpc/vas: Add VAS user space API")
+Signed-off-by: Haren Myneni <haren@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250610021227.361980-2-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 71e970ced8872e676965ec36a566d771ef693a28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <aha310510@gmail.com>
+
+[ 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 <aha310510@gmail.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://patch.msgid.link/20250520160717.7350-1-aha310510@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 7d023a27861971977aab093b09686094ccaa4aed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 14:10:27 -0700
+Subject: sch_ets: make est_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+[ 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 <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Link: https://patch.msgid.link/20250403211033.166059-6-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: d92adacdd8c2 ("net_sched: ets: fix a race in ets_qdisc_change()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 243bf0911fc890b7a8161da1c64996d574ac79de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 13:14:01 -0700
+Subject: scsi: core: ufs: Fix a hang in the error handler
+
+From: Sanjeev Yadav <sanjeev.y@mediatek.com>
+
+[ 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 <sanjeev.y@mediatek.com>
+[ bvanassche: rewrote patch description ]
+Fixes: 62694735ca95 ("[SCSI] ufs: Add runtime PM support for UFS host controller driver")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20250523201409.1676055-1-bvanassche@acm.org
+Reviewed-by: Peter Wang <peter.wang@mediatek.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From abc05cd6b9a07d8a53dc5f5a07af302fd409ede2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 12:29:35 -0700
+Subject: scsi: iscsi: Fix incorrect error path labels for flashnode operations
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ 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 <alok.a.tiwari@oracle.com>
+Link: https://lore.kernel.org/r/20250530193012.3312911-1-alok.a.tiwari@oracle.com
+Reviewed-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
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