From: Greg Kroah-Hartman Date: Tue, 3 Feb 2026 15:04:17 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v5.10.249~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f02a13f94b4c88047fc599adf14442937085c44;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch arm64-fpsimd-signal-fix-restoration-of-sve-context.patch asoc-codecs-wsa881x-drop-unused-version-readout.patch asoc-codecs-wsa881x-fix-unnecessary-initialisation.patch asoc-codecs-wsa881x-simplify-pdev-dev-in-probe.patch asoc-codecs-wsa881x-use-proper-shutdown-gpio-polarity.patch asoc-codecs-wsa883x-fix-unnecessary-initialisation.patch dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch genirq-irq_sim-initialize-work-context-pointers-properly.patch iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch iio-chemical-scd4x-fix-reported-channel-endianness.patch ksmbd-smbd-fix-dma_unmap_sg-nents.patch mei-trace-treat-reg-parameter-as-string.patch mm-kmsan-fix-poisoning-of-high-order-non-compound-pages.patch mm-page_alloc-prevent-pcp-corruption-with-smp-n.patch mm-rmap-fix-two-comments-related-to-huge_pmd_unshare.patch mmc-sdhci-of-dwcmshc-prevent-illegal-clock-reduction-in-hs200-hs400-mode.patch mmc-sdhci-of-dwcmshc-update-dll-and-pre-change-delay-for-rockchip-platform.patch nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch nvme-fix-pcie-subsystem-reset-controller-state-transition.patch nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch phy-phy-rockchip-inno-usb2-simplify-phy-clock-handling.patch phy-phy-rockchip-inno-usb2-use-dev_err_probe-in-the-probe-path.patch phy-rockchip-inno-usb2-fix-a-double-free-bug-in-rockchip_usb2phy_probe.patch pmdomain-imx8m-blk-ctrl-remove-separate-rst-and-clk-mask-for-8mq-vpu.patch scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch team-move-team-device-type-change-at-the-end-of-team_port_add.patch wifi-mac80211-move-tdls-work-to-wiphy-work.patch wifi-mac80211-use-wiphy-work-for-sdata-work.patch x86-fpu-clear-xstate_bv-in-guest-xsave-state-whenever-xfd-1.patch xen-make-remove-callback-of-xen-driver-void-returned.patch xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch --- diff --git a/queue-6.1/alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch b/queue-6.1/alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch new file mode 100644 index 0000000000..563097551b --- /dev/null +++ b/queue-6.1/alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch @@ -0,0 +1,57 @@ +From stable+bounces-211905-greg=kroah.com@vger.kernel.org Wed Jan 28 01:56:49 2026 +From: Sasha Levin +Date: Tue, 27 Jan 2026 19:56:42 -0500 +Subject: ALSA: scarlett2: Fix buffer overflow in config retrieval +To: stable@vger.kernel.org +Cc: Samasth Norway Ananda , Takashi Iwai , Sasha Levin +Message-ID: <20260128005642.2300891-1-sashal@kernel.org> + +From: Samasth Norway Ananda + +[ Upstream commit 6f5c69f72e50d51be3a8c028ae7eda42c82902cb ] + +The scarlett2_usb_get_config() function has a logic error in the +endianness conversion code that can cause buffer overflows when +count > 1. + +The code checks `if (size == 2)` where `size` is the total buffer size in +bytes, then loops `count` times treating each element as u16 (2 bytes). +This causes the loop to access `count * 2` bytes when the buffer only +has `size` bytes allocated. + +Fix by checking the element size (config_item->size) instead of the +total buffer size. This ensures the endianness conversion matches the +actual element type. + +Fixes: ac34df733d2d ("ALSA: usb-audio: scarlett2: Update get_config to do endian conversion") +Cc: stable@vger.kernel.org +Signed-off-by: Samasth Norway Ananda +Link: https://patch.msgid.link/20260117012706.1715574-1-samasth.norway.ananda@oracle.com +Signed-off-by: Takashi Iwai +[ add 32-bit handling block ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer_scarlett2.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/sound/usb/mixer_scarlett2.c ++++ b/sound/usb/mixer_scarlett2.c +@@ -1408,11 +1408,16 @@ static int scarlett2_usb_get_config( + err = scarlett2_usb_get(mixer, config_item->offset, buf, size); + if (err < 0) + return err; +- if (size == 2) { ++ if (config_item->size == 16) { + u16 *buf_16 = buf; + + for (i = 0; i < count; i++, buf_16++) + *buf_16 = le16_to_cpu(*(__le16 *)buf_16); ++ } else if (config_item->size == 32) { ++ u32 *buf_32 = (u32 *)buf; ++ ++ for (i = 0; i < count; i++, buf_32++) ++ *buf_32 = le32_to_cpu(*(__le32 *)buf_32); + } + return 0; + } diff --git a/queue-6.1/arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch b/queue-6.1/arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch new file mode 100644 index 0000000000..6f7af83679 --- /dev/null +++ b/queue-6.1/arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch @@ -0,0 +1,40 @@ +From stable+bounces-211649-greg=kroah.com@vger.kernel.org Mon Jan 26 17:22:23 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 11:21:33 -0500 +Subject: arm64: dts: rockchip: remove redundant max-link-speed from nanopi-r4s +To: stable@vger.kernel.org +Cc: Geraldo Nascimento , Dragan Simic , Shawn Lin , Heiko Stuebner , Sasha Levin +Message-ID: <20260126162133.3376453-1-sashal@kernel.org> + +From: Geraldo Nascimento + +[ Upstream commit ce652c98a7bfa0b7c675ef5cd85c44c186db96af ] + +This is already the default in rk3399-base.dtsi, remove redundant +declaration from rk3399-nanopi-r4s.dtsi. + +Fixes: db792e9adbf8 ("rockchip: rk3399: Add support for FriendlyARM NanoPi R4S") +Cc: stable@vger.kernel.org +Reported-by: Dragan Simic +Reviewed-by: Dragan Simic +Signed-off-by: Geraldo Nascimento +Acked-by: Shawn Lin +Link: https://patch.msgid.link/6694456a735844177c897581f785cc00c064c7d1.1763415706.git.geraldogabriel@gmail.com +Signed-off-by: Heiko Stuebner +[ adapted file path from rk3399-nanopi-r4s.dtsi to rk3399-nanopi-r4s.dts ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts | 1 - + 1 file changed, 1 deletion(-) + +--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +@@ -73,7 +73,6 @@ + }; + + &pcie0 { +- max-link-speed = <1>; + num-lanes = <1>; + vpcie3v3-supply = <&vcc3v3_sys>; + }; diff --git a/queue-6.1/arm64-fpsimd-signal-fix-restoration-of-sve-context.patch b/queue-6.1/arm64-fpsimd-signal-fix-restoration-of-sve-context.patch new file mode 100644 index 0000000000..ecb75f6b07 --- /dev/null +++ b/queue-6.1/arm64-fpsimd-signal-fix-restoration-of-sve-context.patch @@ -0,0 +1,136 @@ +From stable+bounces-212680-greg=kroah.com@vger.kernel.org Wed Jan 28 22:37:23 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 16:37:16 -0500 +Subject: arm64/fpsimd: signal: Fix restoration of SVE context +To: stable@vger.kernel.org +Cc: Mark Rutland , Mark Brown , Will Deacon , Catalin Marinas , Sasha Levin +Message-ID: <20260128213716.2763076-1-sashal@kernel.org> + +From: Mark Rutland + +[ Upstream commit d2907cbe9ea0a54cbe078076f9d089240ee1e2d9 ] + +When SME is supported, Restoring SVE signal context can go wrong in a +few ways, including placing the task into an invalid state where the +kernel may read from out-of-bounds memory (and may potentially take a +fatal fault) and/or may kill the task with a SIGKILL. + +(1) Restoring a context with SVE_SIG_FLAG_SM set can place the task into + an invalid state where SVCR.SM is set (and sve_state is non-NULL) + but TIF_SME is clear, consequently resuting in out-of-bounds memory + reads and/or killing the task with SIGKILL. + + This can only occur in unusual (but legitimate) cases where the SVE + signal context has either been modified by userspace or was saved in + the context of another task (e.g. as with CRIU), as otherwise the + presence of an SVE signal context with SVE_SIG_FLAG_SM implies that + TIF_SME is already set. + + While in this state, task_fpsimd_load() will NOT configure SMCR_ELx + (leaving some arbitrary value configured in hardware) before + restoring SVCR and attempting to restore the streaming mode SVE + registers from memory via sve_load_state(). As the value of + SMCR_ELx.LEN may be larger than the task's streaming SVE vector + length, this may read memory outside of the task's allocated + sve_state, reading unrelated data and/or triggering a fault. + + While this can result in secrets being loaded into streaming SVE + registers, these values are never exposed. As TIF_SME is clear, + fpsimd_bind_task_to_cpu() will configure CPACR_ELx.SMEN to trap EL0 + accesses to streaming mode SVE registers, so these cannot be + accessed directly at EL0. As fpsimd_save_user_state() verifies the + live vector length before saving (S)SVE state to memory, no secret + values can be saved back to memory (and hence cannot be observed via + ptrace, signals, etc). + + When the live vector length doesn't match the expected vector length + for the task, fpsimd_save_user_state() will send a fatal SIGKILL + signal to the task. Hence the task may be killed after executing + userspace for some period of time. + +(2) Restoring a context with SVE_SIG_FLAG_SM clear does not clear the + task's SVCR.SM. If SVCR.SM was set prior to restoring the context, + then the task will be left in streaming mode unexpectedly, and some + register state will be combined inconsistently, though the task will + be left in legitimate state from the kernel's PoV. + + This can only occur in unusual (but legitimate) cases where ptrace + has been used to set SVCR.SM after entry to the sigreturn syscall, + as syscall entry clears SVCR.SM. + + In these cases, the the provided SVE register data will be loaded + into the task's sve_state using the non-streaming SVE vector length + and the FPSIMD registers will be merged into this using the + streaming SVE vector length. + +Fix (1) by setting TIF_SME when setting SVCR.SM. This also requires +ensuring that the task's sme_state has been allocated, but as this could +contain live ZA state, it should not be zeroed. Fix (2) by clearing +SVCR.SM when restoring a SVE signal context with SVE_SIG_FLAG_SM clear. + +For consistency, I've pulled the manipulation of SVCR, TIF_SVE, TIF_SME, +and fp_type earlier, immediately after the allocation of +sve_state/sme_state, before the restore of the actual register state. +This makes it easier to ensure that these are always modified +consistently, even if a fault is taken while reading the register data +from the signal context. I do not expect any software to depend on the +exact state restored when a fault is taken while reading the context. + +Fixes: 85ed24dad290 ("arm64/sme: Implement streaming SVE signal handling") +Signed-off-by: Mark Rutland +Cc: +Cc: Mark Brown +Cc: Will Deacon +Reviewed-by: Mark Brown +Signed-off-by: Catalin Marinas +[ adapted sme_state to za_state ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kernel/signal.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -317,12 +317,28 @@ static int restore_sve_fpsimd_context(st + fpsimd_flush_task_state(current); + /* From now, fpsimd_thread_switch() won't touch thread.sve_state */ + ++ if (sve.flags & SVE_SIG_FLAG_SM) { ++ sme_alloc(current, false); ++ if (!current->thread.za_state) ++ return -ENOMEM; ++ } ++ + sve_alloc(current, true); + if (!current->thread.sve_state) { + clear_thread_flag(TIF_SVE); + return -ENOMEM; + } + ++ if (sve.flags & SVE_SIG_FLAG_SM) { ++ current->thread.svcr |= SVCR_SM_MASK; ++ set_thread_flag(TIF_SME); ++ } else { ++ current->thread.svcr &= ~SVCR_SM_MASK; ++ set_thread_flag(TIF_SVE); ++ } ++ ++ current->thread.fp_type = FP_STATE_SVE; ++ + err = __copy_from_user(current->thread.sve_state, + (char __user const *)user->sve + + SVE_SIG_REGS_OFFSET, +@@ -330,12 +346,6 @@ static int restore_sve_fpsimd_context(st + if (err) + return -EFAULT; + +- if (sve.flags & SVE_SIG_FLAG_SM) +- current->thread.svcr |= SVCR_SM_MASK; +- else +- set_thread_flag(TIF_SVE); +- current->thread.fp_type = FP_STATE_SVE; +- + fpsimd_only: + /* copy the FP and status/control registers */ + /* restore_sigframe() already checked that user->fpsimd != NULL. */ diff --git a/queue-6.1/asoc-codecs-wsa881x-drop-unused-version-readout.patch b/queue-6.1/asoc-codecs-wsa881x-drop-unused-version-readout.patch new file mode 100644 index 0000000000..f0af43fdaa --- /dev/null +++ b/queue-6.1/asoc-codecs-wsa881x-drop-unused-version-readout.patch @@ -0,0 +1,43 @@ +From stable+bounces-210643-greg=kroah.com@vger.kernel.org Wed Jan 21 03:05:09 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:04:23 -0500 +Subject: ASoC: codecs: wsa881x: Drop unused version readout +To: stable@vger.kernel.org +Cc: Krzysztof Kozlowski , Mark Brown , Sasha Levin +Message-ID: <20260121020424.1123218-3-sashal@kernel.org> + +From: Krzysztof Kozlowski + +[ Upstream commit 3d2a69eb503d15171a7ba51cf0b562728ac396b7 ] + +Driver does not use the device version after reading it from the +registers, so simplify by dropping unneeded code. + +Signed-off-by: Krzysztof Kozlowski +Link: https://patch.msgid.link/20240710-asoc-wsa88xx-version-v1-1-f1c54966ccde@linaro.org +Signed-off-by: Mark Brown +Stable-dep-of: 29d71b8a5a40 ("ASoC: codecs: wsa881x: fix unnecessary initialisation") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/codecs/wsa881x.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/sound/soc/codecs/wsa881x.c ++++ b/sound/soc/codecs/wsa881x.c +@@ -683,7 +683,6 @@ struct wsa881x_priv { + * For backwards compatibility. + */ + unsigned int sd_n_val; +- int version; + int active_ports; + bool port_prepared[WSA881X_MAX_SWR_PORTS]; + bool port_enable[WSA881X_MAX_SWR_PORTS]; +@@ -694,7 +693,6 @@ static void wsa881x_init(struct wsa881x_ + struct regmap *rm = wsa881x->regmap; + unsigned int val = 0; + +- regmap_read(rm, WSA881X_CHIP_ID1, &wsa881x->version); + regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0, + ARRAY_SIZE(wsa881x_rev_2_0)); + diff --git a/queue-6.1/asoc-codecs-wsa881x-fix-unnecessary-initialisation.patch b/queue-6.1/asoc-codecs-wsa881x-fix-unnecessary-initialisation.patch new file mode 100644 index 0000000000..0fb7b394e5 --- /dev/null +++ b/queue-6.1/asoc-codecs-wsa881x-fix-unnecessary-initialisation.patch @@ -0,0 +1,69 @@ +From stable+bounces-210644-greg=kroah.com@vger.kernel.org Wed Jan 21 03:05:07 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:04:24 -0500 +Subject: ASoC: codecs: wsa881x: fix unnecessary initialisation +To: stable@vger.kernel.org +Cc: Johan Hovold , Srinivas Kandagatla , Krzysztof Kozlowski , Srinivas Kandagatla , Mark Brown , Sasha Levin +Message-ID: <20260121020424.1123218-4-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit 29d71b8a5a40708b3eed9ba4953bfc2312c9c776 ] + +The soundwire update_status() callback may be called multiple times with +the same ATTACHED status but initialisation should only be done when +transitioning from UNATTACHED to ATTACHED. + +Fixes: a0aab9e1404a ("ASoC: codecs: add wsa881x amplifier support") +Cc: stable@vger.kernel.org # 5.6 +Cc: Srinivas Kandagatla +Signed-off-by: Johan Hovold +Reviewed-by: Krzysztof Kozlowski +Reviewed-by: Srinivas Kandagatla +Link: https://patch.msgid.link/20260102111413.9605-3-johan@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/codecs/wsa881x.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/sound/soc/codecs/wsa881x.c ++++ b/sound/soc/codecs/wsa881x.c +@@ -684,6 +684,7 @@ struct wsa881x_priv { + */ + unsigned int sd_n_val; + int active_ports; ++ bool hw_init; + bool port_prepared[WSA881X_MAX_SWR_PORTS]; + bool port_enable[WSA881X_MAX_SWR_PORTS]; + }; +@@ -693,6 +694,9 @@ static void wsa881x_init(struct wsa881x_ + struct regmap *rm = wsa881x->regmap; + unsigned int val = 0; + ++ if (wsa881x->hw_init) ++ return; ++ + regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0, + ARRAY_SIZE(wsa881x_rev_2_0)); + +@@ -730,6 +734,8 @@ static void wsa881x_init(struct wsa881x_ + regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A); + regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2); + regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05); ++ ++ wsa881x->hw_init = true; + } + + static int wsa881x_component_probe(struct snd_soc_component *comp) +@@ -1074,6 +1080,9 @@ static int wsa881x_update_status(struct + { + struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev); + ++ if (status == SDW_SLAVE_UNATTACHED) ++ wsa881x->hw_init = false; ++ + if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0) + wsa881x_init(wsa881x); + diff --git a/queue-6.1/asoc-codecs-wsa881x-simplify-pdev-dev-in-probe.patch b/queue-6.1/asoc-codecs-wsa881x-simplify-pdev-dev-in-probe.patch new file mode 100644 index 0000000000..022b946db9 --- /dev/null +++ b/queue-6.1/asoc-codecs-wsa881x-simplify-pdev-dev-in-probe.patch @@ -0,0 +1,61 @@ +From stable+bounces-210641-greg=kroah.com@vger.kernel.org Wed Jan 21 03:07:04 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:04:21 -0500 +Subject: ASoC: codecs: wsa881x: Simplify &pdev->dev in probe +To: stable@vger.kernel.org +Cc: Krzysztof Kozlowski , Mark Brown , Sasha Levin +Message-ID: <20260121020424.1123218-1-sashal@kernel.org> + +From: Krzysztof Kozlowski + +[ Upstream commit c617c9e7024d152426acf9f1aaf01070b6852f13 ] + +The probe already stores pointer to &pdev->dev, so use it to make the +code a bit easier to read. + +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20230102114152.297305-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Mark Brown +Stable-dep-of: 29d71b8a5a40 ("ASoC: codecs: wsa881x: fix unnecessary initialisation") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/codecs/wsa881x.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/sound/soc/codecs/wsa881x.c ++++ b/sound/soc/codecs/wsa881x.c +@@ -1112,20 +1112,20 @@ static int wsa881x_probe(struct sdw_slav + struct wsa881x_priv *wsa881x; + struct device *dev = &pdev->dev; + +- wsa881x = devm_kzalloc(&pdev->dev, sizeof(*wsa881x), GFP_KERNEL); ++ wsa881x = devm_kzalloc(dev, sizeof(*wsa881x), GFP_KERNEL); + if (!wsa881x) + return -ENOMEM; + +- wsa881x->sd_n = devm_gpiod_get_optional(&pdev->dev, "powerdown", ++ wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown", + GPIOD_FLAGS_BIT_NONEXCLUSIVE); + if (IS_ERR(wsa881x->sd_n)) { + dev_err(&pdev->dev, "Shutdown Control GPIO not found\n"); + return PTR_ERR(wsa881x->sd_n); + } + +- dev_set_drvdata(&pdev->dev, wsa881x); ++ dev_set_drvdata(dev, wsa881x); + wsa881x->slave = pdev; +- wsa881x->dev = &pdev->dev; ++ wsa881x->dev = dev; + wsa881x->sconfig.ch_count = 1; + wsa881x->sconfig.bps = 1; + wsa881x->sconfig.frame_rate = 48000; +@@ -1148,7 +1148,7 @@ static int wsa881x_probe(struct sdw_slav + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + +- return devm_snd_soc_register_component(&pdev->dev, ++ return devm_snd_soc_register_component(dev, + &wsa881x_component_drv, + wsa881x_dais, + ARRAY_SIZE(wsa881x_dais)); diff --git a/queue-6.1/asoc-codecs-wsa881x-use-proper-shutdown-gpio-polarity.patch b/queue-6.1/asoc-codecs-wsa881x-use-proper-shutdown-gpio-polarity.patch new file mode 100644 index 0000000000..ff66e312b5 --- /dev/null +++ b/queue-6.1/asoc-codecs-wsa881x-use-proper-shutdown-gpio-polarity.patch @@ -0,0 +1,108 @@ +From stable+bounces-210642-greg=kroah.com@vger.kernel.org Wed Jan 21 03:07:16 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:04:22 -0500 +Subject: ASoC: codecs: wsa881x: Use proper shutdown GPIO polarity +To: stable@vger.kernel.org +Cc: Krzysztof Kozlowski , Mark Brown , Sasha Levin +Message-ID: <20260121020424.1123218-2-sashal@kernel.org> + +From: Krzysztof Kozlowski + +[ Upstream commit 738455858a2d21b769f673892546cf8300c9fd78 ] + +The shutdown GPIO is active low (SD_N), but this depends on actual board +layout. Linux drivers should only care about logical state, where high +(1) means shutdown and low (0) means do not shutdown. + +Invert the GPIO to match logical value while preserving backwards DTB +compatibility. It is not possible to detect whether ACTIVE_HIGH flag in +DTB is because it is an old DTB (using incorrect flag) or it is a new +DTB with a correct hardware pin polarity description. Therefore the +solution prioritizes backwards compatibility while relying on relevant +DTS being upstreamed. + +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20230102114152.297305-4-krzysztof.kozlowski@linaro.org +Signed-off-by: Mark Brown +Stable-dep-of: 29d71b8a5a40 ("ASoC: codecs: wsa881x: fix unnecessary initialisation") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/codecs/wsa881x.c | 33 +++++++++++++++++++++++++++++---- + 1 file changed, 29 insertions(+), 4 deletions(-) + +--- a/sound/soc/codecs/wsa881x.c ++++ b/sound/soc/codecs/wsa881x.c +@@ -678,6 +678,11 @@ struct wsa881x_priv { + struct sdw_stream_runtime *sruntime; + struct sdw_port_config port_config[WSA881X_MAX_SWR_PORTS]; + struct gpio_desc *sd_n; ++ /* ++ * Logical state for SD_N GPIO: high for shutdown, low for enable. ++ * For backwards compatibility. ++ */ ++ unsigned int sd_n_val; + int version; + int active_ports; + bool port_prepared[WSA881X_MAX_SWR_PORTS]; +@@ -1123,6 +1128,26 @@ static int wsa881x_probe(struct sdw_slav + return PTR_ERR(wsa881x->sd_n); + } + ++ /* ++ * Backwards compatibility work-around. ++ * ++ * The SD_N GPIO is active low, however upstream DTS used always active ++ * high. Changing the flag in driver and DTS will break backwards ++ * compatibility, so add a simple value inversion to work with both old ++ * and new DTS. ++ * ++ * This won't work properly with DTS using the flags properly in cases: ++ * 1. Old DTS with proper ACTIVE_LOW, however such case was broken ++ * before as the driver required the active high. ++ * 2. New DTS with proper ACTIVE_HIGH (intended), which is rare case ++ * (not existing upstream) but possible. This is the price of ++ * backwards compatibility, therefore this hack should be removed at ++ * some point. ++ */ ++ wsa881x->sd_n_val = gpiod_is_active_low(wsa881x->sd_n); ++ if (!wsa881x->sd_n_val) ++ dev_warn(dev, "Using ACTIVE_HIGH for shutdown GPIO. Your DTB might be outdated or you use unsupported configuration for the GPIO."); ++ + dev_set_drvdata(dev, wsa881x); + wsa881x->slave = pdev; + wsa881x->dev = dev; +@@ -1134,7 +1159,7 @@ static int wsa881x_probe(struct sdw_slav + pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS - 1, 0); + pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; + pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; +- gpiod_direction_output(wsa881x->sd_n, 1); ++ gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val); + + wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config); + if (IS_ERR(wsa881x->regmap)) { +@@ -1159,7 +1184,7 @@ static int __maybe_unused wsa881x_runtim + struct regmap *regmap = dev_get_regmap(dev, NULL); + struct wsa881x_priv *wsa881x = dev_get_drvdata(dev); + +- gpiod_direction_output(wsa881x->sd_n, 0); ++ gpiod_direction_output(wsa881x->sd_n, wsa881x->sd_n_val); + + regcache_cache_only(regmap, true); + regcache_mark_dirty(regmap); +@@ -1174,13 +1199,13 @@ static int __maybe_unused wsa881x_runtim + struct wsa881x_priv *wsa881x = dev_get_drvdata(dev); + unsigned long time; + +- gpiod_direction_output(wsa881x->sd_n, 1); ++ gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val); + + time = wait_for_completion_timeout(&slave->initialization_complete, + msecs_to_jiffies(WSA881X_PROBE_TIMEOUT)); + if (!time) { + dev_err(dev, "Initialization not complete, timed out\n"); +- gpiod_direction_output(wsa881x->sd_n, 0); ++ gpiod_direction_output(wsa881x->sd_n, wsa881x->sd_n_val); + return -ETIMEDOUT; + } + diff --git a/queue-6.1/asoc-codecs-wsa883x-fix-unnecessary-initialisation.patch b/queue-6.1/asoc-codecs-wsa883x-fix-unnecessary-initialisation.patch new file mode 100644 index 0000000000..26809cf65d --- /dev/null +++ b/queue-6.1/asoc-codecs-wsa883x-fix-unnecessary-initialisation.patch @@ -0,0 +1,80 @@ +From stable+bounces-210386-greg=kroah.com@vger.kernel.org Mon Jan 19 18:44:24 2026 +From: Sasha Levin +Date: Mon, 19 Jan 2026 12:20:22 -0500 +Subject: ASoC: codecs: wsa883x: fix unnecessary initialisation +To: stable@vger.kernel.org +Cc: Johan Hovold , Srinivas Kandagatla , Krzysztof Kozlowski , Srinivas Kandagatla , Mark Brown , Sasha Levin +Message-ID: <20260119172022.3580065-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit 49aadf830eb048134d33ad7329d92ecff45d8dbb ] + +The soundwire update_status() callback may be called multiple times with +the same ATTACHED status but initialisation should only be done when +transitioning from UNATTACHED to ATTACHED. + +This avoids repeated initialisation of the codecs during boot of +machines like the Lenovo ThinkPad X13s: + +[ 11.614523] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 +[ 11.618022] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 +[ 11.621377] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 +[ 11.624065] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 +[ 11.631382] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2 +[ 11.634424] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2 + +Fixes: 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support") +Cc: stable@vger.kernel.org # 6.0 +Cc: Srinivas Kandagatla +Signed-off-by: Johan Hovold +Reviewed-by: Krzysztof Kozlowski +Reviewed-by: Srinivas Kandagatla +Link: https://patch.msgid.link/20260102111413.9605-2-johan@kernel.org +Signed-off-by: Mark Brown +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/codecs/wsa883x.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/sound/soc/codecs/wsa883x.c ++++ b/sound/soc/codecs/wsa883x.c +@@ -448,6 +448,7 @@ struct wsa883x_priv { + int active_ports; + int dev_mode; + int comp_offset; ++ bool hw_init; + }; + + enum { +@@ -1007,6 +1008,9 @@ static int wsa883x_init(struct wsa883x_p + struct regmap *regmap = wsa883x->regmap; + int variant, version, ret; + ++ if (wsa883x->hw_init) ++ return 0; ++ + ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant); + if (ret) + return ret; +@@ -1050,6 +1054,8 @@ static int wsa883x_init(struct wsa883x_p + wsa883x->comp_offset); + } + ++ wsa883x->hw_init = true; ++ + return 0; + } + +@@ -1058,6 +1064,9 @@ static int wsa883x_update_status(struct + { + struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev); + ++ if (status == SDW_SLAVE_UNATTACHED) ++ wsa883x->hw_init = false; ++ + if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0) + return wsa883x_init(wsa883x); + diff --git a/queue-6.1/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch b/queue-6.1/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch new file mode 100644 index 0000000000..0e6433a50a --- /dev/null +++ b/queue-6.1/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch @@ -0,0 +1,91 @@ +From stable+bounces-210739-greg=kroah.com@vger.kernel.org Wed Jan 21 13:23:28 2026 +From: Sasha Levin +Date: Wed, 21 Jan 2026 07:20:38 -0500 +Subject: dmaengine: stm32: dmamux: fix device leak on route allocation +To: stable@vger.kernel.org +Cc: Johan Hovold , Pierre-Yves MORDRET , Amelie Delaunay , Vinod Koul , Sasha Levin +Message-ID: <20260121122038.1526229-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit dd6e4943889fb354efa3f700e42739da9bddb6ef ] + +Make sure to drop the reference taken when looking up the DMA mux +platform device during route allocation. + +Note that holding a reference to a device does not prevent its driver +data from going away so there is no point in keeping the reference. + +Fixes: df7e762db5f6 ("dmaengine: Add STM32 DMAMUX driver") +Cc: stable@vger.kernel.org # 4.15 +Cc: Pierre-Yves MORDRET +Signed-off-by: Johan Hovold +Reviewed-by: Amelie Delaunay +Link: https://patch.msgid.link/20251117161258.10679-11-johan@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/stm32-dmamux.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/drivers/dma/stm32-dmamux.c ++++ b/drivers/dma/stm32-dmamux.c +@@ -88,23 +88,25 @@ static void *stm32_dmamux_route_allocate + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev); + struct stm32_dmamux *mux; + u32 i, min, max; +- int ret; ++ int ret = -EINVAL; + unsigned long flags; + + if (dma_spec->args_count != 3) { + dev_err(&pdev->dev, "invalid number of dma mux args\n"); +- return ERR_PTR(-EINVAL); ++ goto err_put_pdev; + } + + if (dma_spec->args[0] > dmamux->dmamux_requests) { + dev_err(&pdev->dev, "invalid mux request number: %d\n", + dma_spec->args[0]); +- return ERR_PTR(-EINVAL); ++ goto err_put_pdev; + } + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); +- if (!mux) +- return ERR_PTR(-ENOMEM); ++ if (!mux) { ++ ret = -ENOMEM; ++ goto err_put_pdev; ++ } + + spin_lock_irqsave(&dmamux->lock, flags); + mux->chan_id = find_first_zero_bit(dmamux->dma_inuse, +@@ -131,7 +133,6 @@ static void *stm32_dmamux_route_allocate + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", i - 1); + if (!dma_spec->np) { + dev_err(&pdev->dev, "can't get dma master\n"); +- ret = -EINVAL; + goto error; + } + +@@ -158,6 +159,8 @@ static void *stm32_dmamux_route_allocate + dev_dbg(&pdev->dev, "Mapping DMAMUX(%u) to DMA%u(%u)\n", + mux->request, mux->master, mux->chan_id); + ++ put_device(&pdev->dev); ++ + return mux; + + err_put_dma_spec_np: +@@ -167,6 +170,9 @@ error: + + error_chan_id: + kfree(mux); ++err_put_pdev: ++ put_device(&pdev->dev); ++ + return ERR_PTR(ret); + } + diff --git a/queue-6.1/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch b/queue-6.1/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch new file mode 100644 index 0000000000..8eb0ce364c --- /dev/null +++ b/queue-6.1/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch @@ -0,0 +1,48 @@ +From stable+bounces-210742-greg=kroah.com@vger.kernel.org Wed Jan 21 13:30:52 2026 +From: Sasha Levin +Date: Wed, 21 Jan 2026 07:24:45 -0500 +Subject: dmaengine: stm32: dmamux: fix OF node leak on route allocation failure +To: stable@vger.kernel.org +Cc: Johan Hovold , Pierre-Yves MORDRET , Amelie Delaunay , Vinod Koul , Sasha Levin +Message-ID: <20260121122445.1527855-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit b1b590a590af13ded598e70f0b72bc1e515787a1 ] + +Make sure to drop the reference taken to the DMA master OF node also on +late route allocation failures. + +Fixes: df7e762db5f6 ("dmaengine: Add STM32 DMAMUX driver") +Cc: stable@vger.kernel.org # 4.15 +Cc: Pierre-Yves MORDRET +Signed-off-by: Johan Hovold +Reviewed-by: Amelie Delaunay +Link: https://patch.msgid.link/20251117161258.10679-12-johan@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/stm32-dmamux.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/dma/stm32-dmamux.c ++++ b/drivers/dma/stm32-dmamux.c +@@ -140,7 +140,7 @@ static void *stm32_dmamux_route_allocate + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) { + spin_unlock_irqrestore(&dmamux->lock, flags); +- goto error; ++ goto err_put_dma_spec_np; + } + spin_unlock_irqrestore(&dmamux->lock, flags); + +@@ -160,6 +160,8 @@ static void *stm32_dmamux_route_allocate + + return mux; + ++err_put_dma_spec_np: ++ of_node_put(dma_spec->np); + error: + clear_bit(mux->chan_id, dmamux->dma_inuse); + diff --git a/queue-6.1/genirq-irq_sim-initialize-work-context-pointers-properly.patch b/queue-6.1/genirq-irq_sim-initialize-work-context-pointers-properly.patch new file mode 100644 index 0000000000..2d7b3082c2 --- /dev/null +++ b/queue-6.1/genirq-irq_sim-initialize-work-context-pointers-properly.patch @@ -0,0 +1,39 @@ +From black.hawk@163.com Mon Feb 2 09:28:18 2026 +From: Rahul Sharma +Date: Mon, 2 Feb 2026 16:27:28 +0800 +Subject: genirq/irq_sim: Initialize work context pointers properly +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, Gyeyoung Baek , Thomas Gleixner , Rahul Sharma +Message-ID: <20260202082728.975184-1-black.hawk@163.com> + +From: Gyeyoung Baek + +[ Upstream commit 8a2277a3c9e4cc5398f80821afe7ecbe9bdf2819 ] + +Initialize `ops` member's pointers properly by using kzalloc() instead of +kmalloc() when allocating the simulation work context. Otherwise the +pointers contain random content leading to invalid dereferencing. + +Signed-off-by: Gyeyoung Baek +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/all/20250612124827.63259-1-gye976@gmail.com +[ The context change is due to the commit 011f583781fa +("genirq/irq_sim: add an extended irq_sim initializer") +which is irrelevant to the logic of this patch. ] +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + kernel/irq/irq_sim.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/irq/irq_sim.c ++++ b/kernel/irq/irq_sim.c +@@ -166,7 +166,7 @@ struct irq_domain *irq_domain_create_sim + { + struct irq_sim_work_ctx *work_ctx; + +- work_ctx = kmalloc(sizeof(*work_ctx), GFP_KERNEL); ++ work_ctx = kzalloc(sizeof(*work_ctx), GFP_KERNEL); + if (!work_ctx) + goto err_out; + diff --git a/queue-6.1/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch b/queue-6.1/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch new file mode 100644 index 0000000000..eeb45f1c74 --- /dev/null +++ b/queue-6.1/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch @@ -0,0 +1,69 @@ +From stable+bounces-211892-greg=kroah.com@vger.kernel.org Tue Jan 27 22:09:48 2026 +From: Sasha Levin +Date: Tue, 27 Jan 2026 16:07:04 -0500 +Subject: iio: adc: exynos_adc: fix OF populate on driver rebind +To: stable@vger.kernel.org +Cc: Johan Hovold , Krzysztof Kozlowski , Jonathan Cameron , Sasha Levin +Message-ID: <20260127210704.2163667-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit ea6b4feba85e996e840e0b661bc42793df6eb701 ] + +Since commit c6e126de43e7 ("of: Keep track of populated platform +devices") child devices will not be created by of_platform_populate() +if the devices had previously been deregistered individually so that the +OF_POPULATED flag is still set in the corresponding OF nodes. + +Switch to using of_platform_depopulate() instead of open coding so that +the child devices are created if the driver is rebound. + +Fixes: c6e126de43e7 ("of: Keep track of populated platform devices") +Cc: stable@vger.kernel.org # 3.16 +Signed-off-by: Johan Hovold +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Jonathan Cameron +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/exynos_adc.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +--- a/drivers/iio/adc/exynos_adc.c ++++ b/drivers/iio/adc/exynos_adc.c +@@ -721,14 +721,7 @@ static const struct iio_chan_spec exynos + ADC_CHANNEL(9, "adc9"), + }; + +-static int exynos_adc_remove_devices(struct device *dev, void *c) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- +- platform_device_unregister(pdev); + +- return 0; +-} + + static int exynos_adc_ts_open(struct input_dev *dev) + { +@@ -929,8 +922,7 @@ static int exynos_adc_probe(struct platf + return 0; + + err_of_populate: +- device_for_each_child(&indio_dev->dev, NULL, +- exynos_adc_remove_devices); ++ of_platform_depopulate(&indio_dev->dev); + if (has_ts) { + input_unregister_device(info->input); + free_irq(info->tsirq, info); +@@ -959,8 +951,7 @@ static int exynos_adc_remove(struct plat + free_irq(info->tsirq, info); + input_unregister_device(info->input); + } +- device_for_each_child(&indio_dev->dev, NULL, +- exynos_adc_remove_devices); ++ of_platform_depopulate(&indio_dev->dev); + iio_device_unregister(indio_dev); + free_irq(info->irq, info); + if (info->data->exit_hw) diff --git a/queue-6.1/iio-chemical-scd4x-fix-reported-channel-endianness.patch b/queue-6.1/iio-chemical-scd4x-fix-reported-channel-endianness.patch new file mode 100644 index 0000000000..919b8e043b --- /dev/null +++ b/queue-6.1/iio-chemical-scd4x-fix-reported-channel-endianness.patch @@ -0,0 +1,61 @@ +From stable+bounces-211851-greg=kroah.com@vger.kernel.org Tue Jan 27 16:52:08 2026 +From: Sasha Levin +Date: Tue, 27 Jan 2026 10:52:02 -0500 +Subject: iio: chemical: scd4x: fix reported channel endianness +To: stable@vger.kernel.org +Cc: Fiona Klute , David Lechner , Jonathan Cameron , Sasha Levin +Message-ID: <20260127155202.1927098-1-sashal@kernel.org> + +From: Fiona Klute + +[ Upstream commit 81d5a5366d3c20203fb9d7345e1aa46d668445a2 ] + +The driver converts values read from the sensor from BE to CPU +endianness in scd4x_read_meas(). The result is then pushed into the +buffer in scd4x_trigger_handler(), so on LE architectures parsing the +buffer using the reported BE type gave wrong results. + +scd4x_read_raw() which provides sysfs *_raw values is not affected, it +used the values returned by scd4x_read_meas() without further +conversion. + +Fixes: 49d22b695cbb6 ("drivers: iio: chemical: Add support for Sensirion SCD4x CO2 sensor") +Signed-off-by: Fiona Klute +Reviewed-by: David Lechner +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/chemical/scd4x.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/iio/chemical/scd4x.c ++++ b/drivers/iio/chemical/scd4x.c +@@ -518,7 +518,7 @@ static const struct iio_chan_spec scd4x_ + .sign = 'u', + .realbits = 16, + .storagebits = 16, +- .endianness = IIO_BE, ++ .endianness = IIO_CPU, + }, + }, + { +@@ -533,7 +533,7 @@ static const struct iio_chan_spec scd4x_ + .sign = 'u', + .realbits = 16, + .storagebits = 16, +- .endianness = IIO_BE, ++ .endianness = IIO_CPU, + }, + }, + { +@@ -546,7 +546,7 @@ static const struct iio_chan_spec scd4x_ + .sign = 'u', + .realbits = 16, + .storagebits = 16, +- .endianness = IIO_BE, ++ .endianness = IIO_CPU, + }, + }, + }; diff --git a/queue-6.1/ksmbd-smbd-fix-dma_unmap_sg-nents.patch b/queue-6.1/ksmbd-smbd-fix-dma_unmap_sg-nents.patch new file mode 100644 index 0000000000..428c4c0712 --- /dev/null +++ b/queue-6.1/ksmbd-smbd-fix-dma_unmap_sg-nents.patch @@ -0,0 +1,72 @@ +From stable+bounces-212683-greg=kroah.com@vger.kernel.org Wed Jan 28 23:21:36 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 17:20:21 -0500 +Subject: ksmbd: smbd: fix dma_unmap_sg() nents +To: stable@vger.kernel.org +Cc: Thomas Fourier , Namjae Jeon , Steve French , Sasha Levin +Message-ID: <20260128222021.2800060-1-sashal@kernel.org> + +From: Thomas Fourier + +[ Upstream commit 98e3e2b561bc88f4dd218d1c05890672874692f6 ] + +The dma_unmap_sg() functions should be called with the same nents as the +dma_map_sg(), not the value the map function returned. + +Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers") +Cc: +Signed-off-by: Thomas Fourier +Acked-by: Namjae Jeon +Signed-off-by: Steve French +[ Context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/server/transport_rdma.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +--- a/fs/smb/server/transport_rdma.c ++++ b/fs/smb/server/transport_rdma.c +@@ -1103,14 +1103,12 @@ static int get_sg_list(void *buf, int si + + static int get_mapped_sg_list(struct ib_device *device, void *buf, int size, + struct scatterlist *sg_list, int nentries, +- enum dma_data_direction dir) ++ enum dma_data_direction dir, int *npages) + { +- int npages; +- +- npages = get_sg_list(buf, size, sg_list, nentries); +- if (npages < 0) ++ *npages = get_sg_list(buf, size, sg_list, nentries); ++ if (*npages < 0) + return -EINVAL; +- return ib_dma_map_sg(device, sg_list, npages, dir); ++ return ib_dma_map_sg(device, sg_list, *npages, dir); + } + + static int post_sendmsg(struct smb_direct_transport *t, +@@ -1179,12 +1177,13 @@ static int smb_direct_post_send_data(str + for (i = 0; i < niov; i++) { + struct ib_sge *sge; + int sg_cnt; ++ int npages; + + sg_init_table(sg, SMB_DIRECT_MAX_SEND_SGES - 1); + sg_cnt = get_mapped_sg_list(t->cm_id->device, + iov[i].iov_base, iov[i].iov_len, + sg, SMB_DIRECT_MAX_SEND_SGES - 1, +- DMA_TO_DEVICE); ++ DMA_TO_DEVICE, &npages); + if (sg_cnt <= 0) { + pr_err("failed to map buffer\n"); + ret = -ENOMEM; +@@ -1192,7 +1191,7 @@ static int smb_direct_post_send_data(str + } else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES) { + pr_err("buffer not fitted into sges\n"); + ret = -E2BIG; +- ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt, ++ ib_dma_unmap_sg(t->cm_id->device, sg, npages, + DMA_TO_DEVICE); + goto err; + } diff --git a/queue-6.1/mei-trace-treat-reg-parameter-as-string.patch b/queue-6.1/mei-trace-treat-reg-parameter-as-string.patch new file mode 100644 index 0000000000..f04e008a8d --- /dev/null +++ b/queue-6.1/mei-trace-treat-reg-parameter-as-string.patch @@ -0,0 +1,104 @@ +From stable+bounces-212682-greg=kroah.com@vger.kernel.org Wed Jan 28 23:21:34 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 17:20:19 -0500 +Subject: mei: trace: treat reg parameter as string +To: stable@vger.kernel.org +Cc: Alexander Usyskin , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20260128222019.2800019-1-sashal@kernel.org> + +From: Alexander Usyskin + +[ Upstream commit 06d5a7afe1d0b47102936d8fba568572c2b4b941 ] + +The commit +afd2627f727b ("tracing: Check "%s" dereference via the field and not the TP_printk format") +forbids to emit event with a plain char* without a wrapper. + +The reg parameter always passed as static string and wrapper +is not strictly required, contrary to dev parameter. +Use the string wrapper anyway to check sanity of the reg parameters, +store it value independently and prevent internal kernel data leaks. + +Since some code refactoring has taken place, explicit backporting may +be needed for kernels older than 6.10. + +Cc: stable@vger.kernel.org # v6.11+ +Fixes: a0a927d06d79 ("mei: me: add io register tracing") +Signed-off-by: Alexander Usyskin +Link: https://patch.msgid.link/20260111145125.1754912-1-alexander.usyskin@intel.com +Signed-off-by: Greg Kroah-Hartman +[ adapted __assign_str() calls to use two arguments ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/mei/mei-trace.h | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/misc/mei/mei-trace.h ++++ b/drivers/misc/mei/mei-trace.h +@@ -21,18 +21,18 @@ TRACE_EVENT(mei_reg_read, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); +- __entry->reg = reg; ++ __assign_str(reg, reg); + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] read %s:[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + TRACE_EVENT(mei_reg_write, +@@ -40,18 +40,18 @@ TRACE_EVENT(mei_reg_write, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); +- __entry->reg = reg; ++ __assign_str(reg, reg); + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] write %s[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + TRACE_EVENT(mei_pci_cfg_read, +@@ -59,18 +59,18 @@ TRACE_EVENT(mei_pci_cfg_read, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); +- __entry->reg = reg; ++ __assign_str(reg, reg); + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] pci cfg read %s:[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + #endif /* _MEI_TRACE_H_ */ diff --git a/queue-6.1/mm-kmsan-fix-poisoning-of-high-order-non-compound-pages.patch b/queue-6.1/mm-kmsan-fix-poisoning-of-high-order-non-compound-pages.patch new file mode 100644 index 0000000000..00989aab2d --- /dev/null +++ b/queue-6.1/mm-kmsan-fix-poisoning-of-high-order-non-compound-pages.patch @@ -0,0 +1,55 @@ +From stable+bounces-210736-greg=kroah.com@vger.kernel.org Wed Jan 21 13:12:30 2026 +From: Sasha Levin +Date: Wed, 21 Jan 2026 07:05:13 -0500 +Subject: mm: kmsan: fix poisoning of high-order non-compound pages +To: stable@vger.kernel.org +Cc: Ryan Roberts , Alexander Potapenko , Dmitriy Vyukov , Marco Elver , Andrew Morton , Sasha Levin +Message-ID: <20260121120513.1505706-1-sashal@kernel.org> + +From: Ryan Roberts + +[ Upstream commit 4795d205d78690a46b60164f44b8bb7b3e800865 ] + +kmsan_free_page() is called by the page allocator's free_pages_prepare() +during page freeing. Its job is to poison all the memory covered by the +page. It can be called with an order-0 page, a compound high-order page +or a non-compound high-order page. But page_size() only works for order-0 +and compound pages. For a non-compound high-order page it will +incorrectly return PAGE_SIZE. + +The implication is that the tail pages of a high-order non-compound page +do not get poisoned at free, so any invalid access while they are free +could go unnoticed. It looks like the pages will be poisoned again at +allocation time, so that would bookend the window. + +Fix this by using the order parameter to calculate the size. + +Link: https://lkml.kernel.org/r/20260104134348.3544298-1-ryan.roberts@arm.com +Fixes: b073d7f8aee4 ("mm: kmsan: maintain KMSAN metadata for page operations") +Signed-off-by: Ryan Roberts +Reviewed-by: Alexander Potapenko +Tested-by: Alexander Potapenko +Cc: Dmitriy Vyukov +Cc: Dmitry Vyukov +Cc: Marco Elver +Cc: Ryan Roberts +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/kmsan/shadow.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/mm/kmsan/shadow.c ++++ b/mm/kmsan/shadow.c +@@ -209,8 +209,7 @@ void kmsan_free_page(struct page *page, + if (!kmsan_enabled || kmsan_in_runtime()) + return; + kmsan_enter_runtime(); +- kmsan_internal_poison_memory(page_address(page), +- PAGE_SIZE << compound_order(page), ++ kmsan_internal_poison_memory(page_address(page), PAGE_SIZE << order, + GFP_KERNEL, + KMSAN_POISON_CHECK | KMSAN_POISON_FREE); + kmsan_leave_runtime(); diff --git a/queue-6.1/mm-page_alloc-prevent-pcp-corruption-with-smp-n.patch b/queue-6.1/mm-page_alloc-prevent-pcp-corruption-with-smp-n.patch new file mode 100644 index 0000000000..80cd04364a --- /dev/null +++ b/queue-6.1/mm-page_alloc-prevent-pcp-corruption-with-smp-n.patch @@ -0,0 +1,171 @@ +From stable+bounces-210738-greg=kroah.com@vger.kernel.org Wed Jan 21 13:25:40 2026 +From: Sasha Levin +Date: Wed, 21 Jan 2026 07:15:54 -0500 +Subject: mm/page_alloc: prevent pcp corruption with SMP=n +To: stable@vger.kernel.org +Cc: Vlastimil Babka , kernel test robot , Matthew Wilcox , Mel Gorman , Brendan Jackman , Johannes Weiner , Michal Hocko , Sebastian Andrzej Siewior , Steven Rostedt , Suren Baghdasaryan , Zi Yan , Andrew Morton , Sasha Levin +Message-ID: <20260121121554.1523263-1-sashal@kernel.org> + +From: Vlastimil Babka + +[ Upstream commit 038a102535eb49e10e93eafac54352fcc5d78847 ] + +The kernel test robot has reported: + + BUG: spinlock trylock failure on UP on CPU#0, kcompactd0/28 + lock: 0xffff888807e35ef0, .magic: dead4ead, .owner: kcompactd0/28, .owner_cpu: 0 + CPU: 0 UID: 0 PID: 28 Comm: kcompactd0 Not tainted 6.18.0-rc5-00127-ga06157804399 #1 PREEMPT 8cc09ef94dcec767faa911515ce9e609c45db470 + Call Trace: + + __dump_stack (lib/dump_stack.c:95) + dump_stack_lvl (lib/dump_stack.c:123) + dump_stack (lib/dump_stack.c:130) + spin_dump (kernel/locking/spinlock_debug.c:71) + do_raw_spin_trylock (kernel/locking/spinlock_debug.c:?) + _raw_spin_trylock (include/linux/spinlock_api_smp.h:89 kernel/locking/spinlock.c:138) + __free_frozen_pages (mm/page_alloc.c:2973) + ___free_pages (mm/page_alloc.c:5295) + __free_pages (mm/page_alloc.c:5334) + tlb_remove_table_rcu (include/linux/mm.h:? include/linux/mm.h:3122 include/asm-generic/tlb.h:220 mm/mmu_gather.c:227 mm/mmu_gather.c:290) + ? __cfi_tlb_remove_table_rcu (mm/mmu_gather.c:289) + ? rcu_core (kernel/rcu/tree.c:?) + rcu_core (include/linux/rcupdate.h:341 kernel/rcu/tree.c:2607 kernel/rcu/tree.c:2861) + rcu_core_si (kernel/rcu/tree.c:2879) + handle_softirqs (arch/x86/include/asm/jump_label.h:36 include/trace/events/irq.h:142 kernel/softirq.c:623) + __irq_exit_rcu (arch/x86/include/asm/jump_label.h:36 kernel/softirq.c:725) + irq_exit_rcu (kernel/softirq.c:741) + sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1052) + + + RIP: 0010:_raw_spin_unlock_irqrestore (arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:152 kernel/locking/spinlock.c:194) + free_pcppages_bulk (mm/page_alloc.c:1494) + drain_pages_zone (include/linux/spinlock.h:391 mm/page_alloc.c:2632) + __drain_all_pages (mm/page_alloc.c:2731) + drain_all_pages (mm/page_alloc.c:2747) + kcompactd (mm/compaction.c:3115) + kthread (kernel/kthread.c:465) + ? __cfi_kcompactd (mm/compaction.c:3166) + ? __cfi_kthread (kernel/kthread.c:412) + ret_from_fork (arch/x86/kernel/process.c:164) + ? __cfi_kthread (kernel/kthread.c:412) + ret_from_fork_asm (arch/x86/entry/entry_64.S:255) + + +Matthew has analyzed the report and identified that in drain_page_zone() +we are in a section protected by spin_lock(&pcp->lock) and then get an +interrupt that attempts spin_trylock() on the same lock. The code is +designed to work this way without disabling IRQs and occasionally fail the +trylock with a fallback. However, the SMP=n spinlock implementation +assumes spin_trylock() will always succeed, and thus it's normally a +no-op. Here the enabled lock debugging catches the problem, but otherwise +it could cause a corruption of the pcp structure. + +The problem has been introduced by commit 574907741599 ("mm/page_alloc: +leave IRQs enabled for per-cpu page allocations"). The pcp locking scheme +recognizes the need for disabling IRQs to prevent nesting spin_trylock() +sections on SMP=n, but the need to prevent the nesting in spin_lock() has +not been recognized. Fix it by introducing local wrappers that change the +spin_lock() to spin_lock_iqsave() with SMP=n and use them in all places +that do spin_lock(&pcp->lock). + +[vbabka@suse.cz: add pcp_ prefix to the spin_lock_irqsave wrappers, per Steven] +Link: https://lkml.kernel.org/r/20260105-fix-pcp-up-v1-1-5579662d2071@suse.cz +Fixes: 574907741599 ("mm/page_alloc: leave IRQs enabled for per-cpu page allocations") +Signed-off-by: Vlastimil Babka +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-lkp/202512101320.e2f2dd6f-lkp@intel.com +Analyzed-by: Matthew Wilcox +Link: https://lore.kernel.org/all/aUW05pyc9nZkvY-1@casper.infradead.org/ +Acked-by: Mel Gorman +Cc: Brendan Jackman +Cc: Johannes Weiner +Cc: Michal Hocko +Cc: Sebastian Andrzej Siewior +Cc: Steven Rostedt +Cc: Suren Baghdasaryan +Cc: Zi Yan +Cc: +Signed-off-by: Andrew Morton +[ drop changes to decay_pcp_high() and zone_pcp_update_cacheinfo() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/page_alloc.c | 37 +++++++++++++++++++++++++++++++++---- + 1 file changed, 33 insertions(+), 4 deletions(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -198,6 +198,33 @@ static DEFINE_MUTEX(pcp_batch_high_lock) + #define pcp_spin_unlock(ptr) \ + pcpu_spin_unlock(lock, ptr) + ++/* ++ * With the UP spinlock implementation, when we spin_lock(&pcp->lock) (for i.e. ++ * a potentially remote cpu drain) and get interrupted by an operation that ++ * attempts pcp_spin_trylock(), we can't rely on the trylock failure due to UP ++ * spinlock assumptions making the trylock a no-op. So we have to turn that ++ * spin_lock() to a spin_lock_irqsave(). This works because on UP there are no ++ * remote cpu's so we can only be locking the only existing local one. ++ */ ++#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) ++static inline void __flags_noop(unsigned long *flags) { } ++#define pcp_spin_lock_maybe_irqsave(ptr, flags) \ ++({ \ ++ __flags_noop(&(flags)); \ ++ spin_lock(&(ptr)->lock); \ ++}) ++#define pcp_spin_unlock_maybe_irqrestore(ptr, flags) \ ++({ \ ++ spin_unlock(&(ptr)->lock); \ ++ __flags_noop(&(flags)); \ ++}) ++#else ++#define pcp_spin_lock_maybe_irqsave(ptr, flags) \ ++ spin_lock_irqsave(&(ptr)->lock, flags) ++#define pcp_spin_unlock_maybe_irqrestore(ptr, flags) \ ++ spin_unlock_irqrestore(&(ptr)->lock, flags) ++#endif ++ + #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID + DEFINE_PER_CPU(int, numa_node); + EXPORT_PER_CPU_SYMBOL(numa_node); +@@ -3174,14 +3201,15 @@ static int rmqueue_bulk(struct zone *zon + */ + void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) + { ++ unsigned long UP_flags; + int to_drain, batch; + + batch = READ_ONCE(pcp->batch); + to_drain = min(pcp->count, batch); + if (to_drain > 0) { +- spin_lock(&pcp->lock); ++ pcp_spin_lock_maybe_irqsave(pcp, UP_flags); + free_pcppages_bulk(zone, to_drain, pcp, 0); +- spin_unlock(&pcp->lock); ++ pcp_spin_unlock_maybe_irqrestore(pcp, UP_flags); + } + } + #endif +@@ -3192,10 +3220,11 @@ void drain_zone_pages(struct zone *zone, + static void drain_pages_zone(unsigned int cpu, struct zone *zone) + { + struct per_cpu_pages *pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu); ++ unsigned long UP_flags; + int count; + + do { +- spin_lock(&pcp->lock); ++ pcp_spin_lock_maybe_irqsave(pcp, UP_flags); + count = pcp->count; + if (count) { + int to_drain = min(count, +@@ -3204,7 +3233,7 @@ static void drain_pages_zone(unsigned in + free_pcppages_bulk(zone, to_drain, pcp, 0); + count -= to_drain; + } +- spin_unlock(&pcp->lock); ++ pcp_spin_unlock_maybe_irqrestore(pcp, UP_flags); + } while (count); + } + diff --git a/queue-6.1/mm-rmap-fix-two-comments-related-to-huge_pmd_unshare.patch b/queue-6.1/mm-rmap-fix-two-comments-related-to-huge_pmd_unshare.patch new file mode 100644 index 0000000000..fb7b866cf9 --- /dev/null +++ b/queue-6.1/mm-rmap-fix-two-comments-related-to-huge_pmd_unshare.patch @@ -0,0 +1,76 @@ +From stable+bounces-211671-greg=kroah.com@vger.kernel.org Mon Jan 26 19:02:25 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 13:02:11 -0500 +Subject: mm/rmap: fix two comments related to huge_pmd_unshare() +To: stable@vger.kernel.org +Cc: "David Hildenbrand (Red Hat)" , Rik van Riel , Laurence Oberman , Lorenzo Stoakes , Oscar Salvador , Liu Shixin , Harry Yoo , Lance Yang , "Uschakow, Stanislav" , Andrew Morton , Sasha Levin +Message-ID: <20260126180211.3511367-1-sashal@kernel.org> + +From: "David Hildenbrand (Red Hat)" + +[ Upstream commit a8682d500f691b6dfaa16ae1502d990aeb86e8be ] + +PMD page table unsharing no longer touches the refcount of a PMD page +table. Also, it is not about dropping the refcount of a "PMD page" but +the "PMD page table". + +Let's just simplify by saying that the PMD page table was unmapped, +consequently also unmapping the folio that was mapped into this page. + +This code should be deduplicated in the future. + +Link: https://lkml.kernel.org/r/20251223214037.580860-4-david@kernel.org +Fixes: 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count") +Signed-off-by: David Hildenbrand (Red Hat) +Reviewed-by: Rik van Riel +Tested-by: Laurence Oberman +Reviewed-by: Lorenzo Stoakes +Acked-by: Oscar Salvador +Cc: Liu Shixin +Cc: Harry Yoo +Cc: Lance Yang +Cc: "Uschakow, Stanislav" +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/rmap.c | 20 ++++---------------- + 1 file changed, 4 insertions(+), 16 deletions(-) + +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -1574,14 +1574,8 @@ static bool try_to_unmap_one(struct foli + mmu_notifier_invalidate_range(mm, + range.start, range.end); + /* +- * The ref count of the PMD page was +- * dropped which is part of the way map +- * counting is done for shared PMDs. +- * Return 'true' here. When there is +- * no other sharing, huge_pmd_unshare +- * returns false and we will unmap the +- * actual page and drop map count +- * to zero. ++ * The PMD table was unmapped, ++ * consequently unmapping the folio. + */ + page_vma_mapped_walk_done(&pvmw); + break; +@@ -1965,14 +1959,8 @@ static bool try_to_migrate_one(struct fo + range.start, range.end); + + /* +- * The ref count of the PMD page was +- * dropped which is part of the way map +- * counting is done for shared PMDs. +- * Return 'true' here. When there is +- * no other sharing, huge_pmd_unshare +- * returns false and we will unmap the +- * actual page and drop map count +- * to zero. ++ * The PMD table was unmapped, ++ * consequently unmapping the folio. + */ + page_vma_mapped_walk_done(&pvmw); + break; diff --git a/queue-6.1/mmc-sdhci-of-dwcmshc-prevent-illegal-clock-reduction-in-hs200-hs400-mode.patch b/queue-6.1/mmc-sdhci-of-dwcmshc-prevent-illegal-clock-reduction-in-hs200-hs400-mode.patch new file mode 100644 index 0000000000..5cd87d0a96 --- /dev/null +++ b/queue-6.1/mmc-sdhci-of-dwcmshc-prevent-illegal-clock-reduction-in-hs200-hs400-mode.patch @@ -0,0 +1,60 @@ +From stable+bounces-212658-greg=kroah.com@vger.kernel.org Wed Jan 28 19:26:23 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 13:26:15 -0500 +Subject: mmc: sdhci-of-dwcmshc: Prevent illegal clock reduction in HS200/HS400 mode +To: stable@vger.kernel.org +Cc: Shawn Lin , Sebastian Reichel , Yifeng Zhao , Ulf Hansson , Sasha Levin +Message-ID: <20260128182615.2660161-2-sashal@kernel.org> + +From: Shawn Lin + +[ Upstream commit 3009738a855cf938bbfc9078bec725031ae623a4 ] + +When operating in HS200 or HS400 timing modes, reducing the clock frequency +below 52MHz will lead to link broken as the Rockchip DWC MSHC controller +requires maintaining a minimum clock of 52MHz in these modes. + +Add a check to prevent illegal clock reduction through debugfs: + +root@debian:/# echo 50000000 > /sys/kernel/debug/mmc0/clock +root@debian:/# [ 30.090146] mmc0: running CQE recovery +mmc0: cqhci: Failed to halt +mmc0: cqhci: spurious TCN for tag 0 +WARNING: drivers/mmc/host/cqhci-core.c:797 at cqhci_irq+0x254/0x818, CPU#1: kworker/1:0H/24 +Modules linked in: +CPU: 1 UID: 0 PID: 24 Comm: kworker/1:0H Not tainted 6.19.0-rc1-00001-g09db0998649d-dirty #204 PREEMPT +Hardware name: Rockchip RK3588 EVB1 V10 Board (DT) +Workqueue: kblockd blk_mq_run_work_fn +pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : cqhci_irq+0x254/0x818 +lr : cqhci_irq+0x254/0x818 +... + +Fixes: c6f361cba51c ("mmc: sdhci-of-dwcmshc: add support for rk3588") +Cc: Sebastian Reichel +Cc: Yifeng Zhao +Signed-off-by: Shawn Lin +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-of-dwcmshc.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -236,6 +236,13 @@ static void dwcmshc_rk3568_set_clock(str + sdhci_writel(host, extra, reg); + + if (clock <= 52000000) { ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || ++ host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { ++ dev_err(mmc_dev(host->mmc), ++ "Can't reduce the clock below 52MHz in HS200/HS400 mode"); ++ return; ++ } ++ + /* + * Disable DLL and reset both of sample and drive clock. + * The bypass bit and start bit need to be set if DLL is not locked. diff --git a/queue-6.1/mmc-sdhci-of-dwcmshc-update-dll-and-pre-change-delay-for-rockchip-platform.patch b/queue-6.1/mmc-sdhci-of-dwcmshc-update-dll-and-pre-change-delay-for-rockchip-platform.patch new file mode 100644 index 0000000000..8b068dd692 --- /dev/null +++ b/queue-6.1/mmc-sdhci-of-dwcmshc-update-dll-and-pre-change-delay-for-rockchip-platform.patch @@ -0,0 +1,69 @@ +From stable+bounces-212657-greg=kroah.com@vger.kernel.org Wed Jan 28 19:29:28 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 13:26:14 -0500 +Subject: mmc: sdhci-of-dwcmshc: Update DLL and pre-change delay for rockchip platform +To: stable@vger.kernel.org +Cc: Shawn Lin , Ulf Hansson , Sasha Levin +Message-ID: <20260128182615.2660161-1-sashal@kernel.org> + +From: Shawn Lin + +[ Upstream commit b75a52b0dda353aeefb4830a320589a363f49579 ] + +For Rockchip platform, DLL bypass bit and start bit need to be set if +DLL is not locked. And adjust pre-change delay to 0x3 for better signal +test result. + +Signed-off-by: Shawn Lin +Link: https://lore.kernel.org/r/1675298118-64243-2-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Ulf Hansson +Stable-dep-of: 3009738a855c ("mmc: sdhci-of-dwcmshc: Prevent illegal clock reduction in HS200/HS400 mode") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-of-dwcmshc.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -48,6 +48,7 @@ + #define DWCMSHC_EMMC_DLL_RXCLK_SRCSEL 29 + #define DWCMSHC_EMMC_DLL_START_POINT 16 + #define DWCMSHC_EMMC_DLL_INC 8 ++#define DWCMSHC_EMMC_DLL_BYPASS BIT(24) + #define DWCMSHC_EMMC_DLL_DLYENA BIT(27) + #define DLL_TXCLK_TAPNUM_DEFAULT 0x10 + #define DLL_TXCLK_TAPNUM_90_DEGREES 0xA +@@ -60,6 +61,7 @@ + #define DLL_RXCLK_NO_INVERTER 1 + #define DLL_RXCLK_INVERTER 0 + #define DLL_CMDOUT_TAPNUM_90_DEGREES 0x8 ++#define DLL_RXCLK_ORI_GATE BIT(31) + #define DLL_CMDOUT_TAPNUM_FROM_SW BIT(24) + #define DLL_CMDOUT_SRC_CLK_NEG BIT(28) + #define DLL_CMDOUT_EN_SRC_CLK_NEG BIT(29) +@@ -234,9 +236,12 @@ static void dwcmshc_rk3568_set_clock(str + sdhci_writel(host, extra, reg); + + if (clock <= 52000000) { +- /* Disable DLL and reset both of sample and drive clock */ +- sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL); +- sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_RXCLK); ++ /* ++ * Disable DLL and reset both of sample and drive clock. ++ * The bypass bit and start bit need to be set if DLL is not locked. ++ */ ++ sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, DWCMSHC_EMMC_DLL_CTRL); ++ sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK); + sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK); + sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT); + /* +@@ -279,7 +284,7 @@ static void dwcmshc_rk3568_set_clock(str + } + + extra = 0x1 << 16 | /* tune clock stop en */ +- 0x2 << 17 | /* pre-change delay */ ++ 0x3 << 17 | /* pre-change delay */ + 0x3 << 19; /* post-change delay */ + sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); + diff --git a/queue-6.1/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch b/queue-6.1/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch new file mode 100644 index 0000000000..106a382680 --- /dev/null +++ b/queue-6.1/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch @@ -0,0 +1,47 @@ +From stable+bounces-210661-greg=kroah.com@vger.kernel.org Wed Jan 21 03:57:09 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:56:57 -0500 +Subject: nvme-fc: rename free_ctrl callback to match name pattern +To: stable@vger.kernel.org +Cc: Daniel Wagner , Christoph Hellwig , Sagi Grimberg , Hannes Reinecke , Keith Busch , Sasha Levin +Message-ID: <20260121025659.1157002-1-sashal@kernel.org> + +From: Daniel Wagner + +[ Upstream commit 205fb5fa6fde1b5b426015eb1ff69f2ff25ef5bb ] + +Rename nvme_fc_nvme_ctrl_freed to nvme_fc_free_ctrl to match the name +pattern for the callback. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Sagi Grimberg +Reviewed-by: Hannes Reinecke +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/fc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -2417,7 +2417,7 @@ nvme_fc_ctrl_get(struct nvme_fc_ctrl *ct + * controller. Called after last nvme_put_ctrl() call + */ + static void +-nvme_fc_nvme_ctrl_freed(struct nvme_ctrl *nctrl) ++nvme_fc_free_ctrl(struct nvme_ctrl *nctrl) + { + struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); + +@@ -3362,7 +3362,7 @@ static const struct nvme_ctrl_ops nvme_f + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, +- .free_ctrl = nvme_fc_nvme_ctrl_freed, ++ .free_ctrl = nvme_fc_free_ctrl, + .submit_async_event = nvme_fc_submit_async_event, + .delete_ctrl = nvme_fc_delete_ctrl, + .get_address = nvmf_get_address, diff --git a/queue-6.1/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch b/queue-6.1/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch new file mode 100644 index 0000000000..21d1bf5130 --- /dev/null +++ b/queue-6.1/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch @@ -0,0 +1,58 @@ +From stable+bounces-210663-greg=kroah.com@vger.kernel.org Wed Jan 21 03:57:51 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:56:59 -0500 +Subject: nvme: fix PCIe subsystem reset controller state transition +To: stable@vger.kernel.org +Cc: Nilay Shroff , Daniel Wagner , Keith Busch , Sasha Levin +Message-ID: <20260121025659.1157002-3-sashal@kernel.org> + +From: Nilay Shroff + +[ Upstream commit 0edb475ac0a7d153318a24d4dca175a270a5cc4f ] + +The commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING +state”) disallows controller state transitions directly from RESETTING +to LIVE. However, the NVMe PCIe subsystem reset path relies on this +transition to recover the controller on PowerPC (PPC) systems. + +On PPC systems, issuing a subsystem reset causes a temporary loss of +communication with the NVMe adapter. A subsequent PCIe MMIO read then +triggers EEH recovery, which restores the PCIe link and brings the +controller back online. For EEH recovery to proceed correctly, the +controller must transition back to the LIVE state. + +Due to the changes introduced by commit d2fe192348f9 (“nvme: only allow +entering LIVE from CONNECTING state”), the controller can no longer +transition directly from RESETTING to LIVE. As a result, EEH recovery +exits prematurely, leaving the controller stuck in the RESETTING state. + +Fix this by explicitly transitioning the controller state from RESETTING +to CONNECTING and then to LIVE. This satisfies the updated state +transition rules and allows the controller to be successfully recovered +on PPC systems following a PCIe subsystem reset. + +Cc: stable@vger.kernel.org +Fixes: d2fe192348f9 ("nvme: only allow entering LIVE from CONNECTING state") +Reviewed-by: Daniel Wagner +Signed-off-by: Nilay Shroff +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/pci.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1213,7 +1213,10 @@ static int nvme_pci_subsystem_reset(stru + } + + writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); +- nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); ++ ++ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) || ++ !nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE)) ++ goto unlock; + + /* + * Read controller status to flush the previous write and trigger a diff --git a/queue-6.1/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch b/queue-6.1/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch new file mode 100644 index 0000000000..c9a3a6c2b2 --- /dev/null +++ b/queue-6.1/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch @@ -0,0 +1,205 @@ +From stable+bounces-210662-greg=kroah.com@vger.kernel.org Wed Jan 21 03:57:48 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:56:58 -0500 +Subject: nvme-pci: do not directly handle subsys reset fallout +To: stable@vger.kernel.org +Cc: Keith Busch , Nilay Shroff , Christoph Hellwig , Sasha Levin +Message-ID: <20260121025659.1157002-2-sashal@kernel.org> + +From: Keith Busch + +[ Upstream commit 210b1f6576e8b367907e7ff51ef425062e1468e4 ] + +Scheduling reset_work after a nvme subsystem reset is expected to fail +on pcie, but this also prevents potential handling the platform's pcie +services may provide that might successfully recovering the link without +re-enumeration. Such examples include AER, DPC, and power's EEH. + +Provide a pci specific operation that safely initiates a subsystem +reset, and instead of scheduling reset work, read back the status +register to trigger a pcie read error. + +Since this only affects pci, the other fabrics drivers subscribe to a +generic nvmf subsystem reset that is exactly the same as before. The +loop fabric doesn't use it because nvmet doesn't support setting that +property anyway. + +And since we're using the magic NSSR value in two places now, provide a +symbolic define for it. + +Reported-by: Nilay Shroff +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/fabrics.c | 15 +++++++++++++++ + drivers/nvme/host/fabrics.h | 1 + + drivers/nvme/host/fc.c | 1 + + drivers/nvme/host/nvme.h | 14 +++----------- + drivers/nvme/host/pci.c | 36 ++++++++++++++++++++++++++++++++++++ + drivers/nvme/host/rdma.c | 1 + + drivers/nvme/host/tcp.c | 1 + + include/linux/nvme.h | 3 +++ + 8 files changed, 61 insertions(+), 11 deletions(-) + +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -253,6 +253,21 @@ int nvmf_reg_write32(struct nvme_ctrl *c + } + EXPORT_SYMBOL_GPL(nvmf_reg_write32); + ++int nvmf_subsystem_reset(struct nvme_ctrl *ctrl) ++{ ++ int ret; ++ ++ if (!nvme_wait_reset(ctrl)) ++ return -EBUSY; ++ ++ ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, NVME_SUBSYS_RESET); ++ if (ret) ++ return ret; ++ ++ return nvme_try_sched_reset(ctrl); ++} ++EXPORT_SYMBOL_GPL(nvmf_subsystem_reset); ++ + /** + * nvmf_log_connect_error() - Error-parsing-diagnostic print out function for + * connect() errors. +--- a/drivers/nvme/host/fabrics.h ++++ b/drivers/nvme/host/fabrics.h +@@ -199,6 +199,7 @@ static inline void nvmf_complete_timed_o + int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val); + int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val); + int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val); ++int nvmf_subsystem_reset(struct nvme_ctrl *ctrl); + int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl); + int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid); + int nvmf_register_transport(struct nvmf_transport_ops *ops); +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -3362,6 +3362,7 @@ static const struct nvme_ctrl_ops nvme_f + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_fc_free_ctrl, + .submit_async_event = nvme_fc_submit_async_event, + .delete_ctrl = nvme_fc_delete_ctrl, +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -538,6 +538,7 @@ struct nvme_ctrl_ops { + int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val); + void (*free_ctrl)(struct nvme_ctrl *ctrl); + void (*submit_async_event)(struct nvme_ctrl *ctrl); ++ int (*subsystem_reset)(struct nvme_ctrl *ctrl); + void (*delete_ctrl)(struct nvme_ctrl *ctrl); + void (*stop_ctrl)(struct nvme_ctrl *ctrl); + int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); +@@ -636,18 +637,9 @@ int nvme_try_sched_reset(struct nvme_ctr + + static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl) + { +- int ret; +- +- if (!ctrl->subsystem) ++ if (!ctrl->subsystem || !ctrl->ops->subsystem_reset) + return -ENOTTY; +- if (!nvme_wait_reset(ctrl)) +- return -EBUSY; +- +- ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); +- if (ret) +- return ret; +- +- return nvme_try_sched_reset(ctrl); ++ return ctrl->ops->subsystem_reset(ctrl); + } + + /* +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1190,6 +1190,41 @@ static void nvme_pci_submit_async_event( + spin_unlock(&nvmeq->sq_lock); + } + ++static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl) ++{ ++ struct nvme_dev *dev = to_nvme_dev(ctrl); ++ int ret = 0; ++ ++ /* ++ * Taking the shutdown_lock ensures the BAR mapping is not being ++ * altered by reset_work. Holding this lock before the RESETTING state ++ * change, if successful, also ensures nvme_remove won't be able to ++ * proceed to iounmap until we're done. ++ */ ++ mutex_lock(&dev->shutdown_lock); ++ if (!dev->bar_mapped_size) { ++ ret = -ENODEV; ++ goto unlock; ++ } ++ ++ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) { ++ ret = -EBUSY; ++ goto unlock; ++ } ++ ++ writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); ++ nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); ++ ++ /* ++ * Read controller status to flush the previous write and trigger a ++ * pcie read error. ++ */ ++ readl(dev->bar + NVME_REG_CSTS); ++unlock: ++ mutex_unlock(&dev->shutdown_lock); ++ return ret; ++} ++ + static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) + { + struct nvme_command c = { }; +@@ -3033,6 +3068,7 @@ static const struct nvme_ctrl_ops nvme_p + .reg_read64 = nvme_pci_reg_read64, + .free_ctrl = nvme_pci_free_ctrl, + .submit_async_event = nvme_pci_submit_async_event, ++ .subsystem_reset = nvme_pci_subsystem_reset, + .get_address = nvme_pci_get_address, + .print_device_info = nvme_pci_print_device_info, + .supports_pci_p2pdma = nvme_pci_supports_pci_p2pdma, +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -2256,6 +2256,7 @@ static const struct nvme_ctrl_ops nvme_r + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_rdma_free_ctrl, + .submit_async_event = nvme_rdma_submit_async_event, + .delete_ctrl = nvme_rdma_delete_ctrl, +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -2612,6 +2612,7 @@ static const struct nvme_ctrl_ops nvme_t + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_tcp_free_ctrl, + .submit_async_event = nvme_tcp_submit_async_event, + .delete_ctrl = nvme_tcp_delete_ctrl, +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -28,6 +28,9 @@ + + #define NVME_NSID_ALL 0xffffffff + ++/* Special NSSR value, 'NVMe' */ ++#define NVME_SUBSYS_RESET 0x4E564D65 ++ + enum nvme_subsys_type { + /* Referral to another discovery type target subsystem */ + NVME_NQN_DISC = 1, diff --git a/queue-6.1/phy-phy-rockchip-inno-usb2-simplify-phy-clock-handling.patch b/queue-6.1/phy-phy-rockchip-inno-usb2-simplify-phy-clock-handling.patch new file mode 100644 index 0000000000..7390bcc633 --- /dev/null +++ b/queue-6.1/phy-phy-rockchip-inno-usb2-simplify-phy-clock-handling.patch @@ -0,0 +1,64 @@ +From stable+bounces-210647-greg=kroah.com@vger.kernel.org Wed Jan 21 03:13:38 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:13:31 -0500 +Subject: phy: phy-rockchip-inno-usb2: simplify phy clock handling +To: stable@vger.kernel.org +Cc: Sebastian Reichel , Vinod Koul , Sasha Levin +Message-ID: <20260121021333.1126769-1-sashal@kernel.org> + +From: Sebastian Reichel + +[ Upstream commit b43511233c6e34b9c0d9a55e41b078d10e7d9ea6 ] + +Simplify phyclk handling by using devm_clk_get_optional_enabled to +acquire and enable the optional clock. This also fixes a resource +leak in driver remove path and adds proper error handling. + +Signed-off-by: Sebastian Reichel +Link: https://lore.kernel.org/r/20230522170324.61349-6-sebastian.reichel@collabora.com +Signed-off-by: Vinod Koul +Stable-dep-of: e07dea3de508 ("phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1273,18 +1273,16 @@ static int rockchip_usb2phy_probe(struct + return -EINVAL; + } + +- rphy->clk = of_clk_get_by_name(np, "phyclk"); +- if (!IS_ERR(rphy->clk)) { +- clk_prepare_enable(rphy->clk); +- } else { +- dev_info(&pdev->dev, "no phyclk specified\n"); +- rphy->clk = NULL; ++ rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk"); ++ if (IS_ERR(rphy->clk)) { ++ return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk), ++ "failed to get phyclk\n"); + } + + ret = rockchip_usb2phy_clk480m_register(rphy); + if (ret) { + dev_err(dev, "failed to register 480m output clock\n"); +- goto disable_clks; ++ return ret; + } + + index = 0; +@@ -1347,11 +1345,6 @@ next_child: + + put_child: + of_node_put(child_np); +-disable_clks: +- if (rphy->clk) { +- clk_disable_unprepare(rphy->clk); +- clk_put(rphy->clk); +- } + return ret; + } + diff --git a/queue-6.1/phy-phy-rockchip-inno-usb2-use-dev_err_probe-in-the-probe-path.patch b/queue-6.1/phy-phy-rockchip-inno-usb2-use-dev_err_probe-in-the-probe-path.patch new file mode 100644 index 0000000000..86a3c9c40f --- /dev/null +++ b/queue-6.1/phy-phy-rockchip-inno-usb2-use-dev_err_probe-in-the-probe-path.patch @@ -0,0 +1,90 @@ +From stable+bounces-210648-greg=kroah.com@vger.kernel.org Wed Jan 21 03:14:14 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:13:32 -0500 +Subject: phy: phy-rockchip-inno-usb2: Use dev_err_probe() in the probe path +To: stable@vger.kernel.org +Cc: Dragan Simic , Heiko Stuebner , Vinod Koul , Sasha Levin +Message-ID: <20260121021333.1126769-2-sashal@kernel.org> + +From: Dragan Simic + +[ Upstream commit 40452520850683f6771094ca218ff206d1fcb022 ] + +Improve error handling in the probe path by using function dev_err_probe() +instead of function dev_err(), where appropriate. + +Signed-off-by: Dragan Simic +Reviewed-by: Heiko Stuebner +Link: https://lore.kernel.org/r/d4ccd9fc278fb46ea868406bf77811ee507f0e4e.1725524803.git.dsimic@manjaro.org +Signed-off-by: Vinod Koul +Stable-dep-of: e07dea3de508 ("phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 27 +++++++++----------------- + 1 file changed, 10 insertions(+), 17 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -380,11 +380,9 @@ static int rockchip_usb2phy_extcon_regis + + if (of_property_read_bool(node, "extcon")) { + edev = extcon_get_edev_by_phandle(rphy->dev, 0); +- if (IS_ERR(edev)) { +- if (PTR_ERR(edev) != -EPROBE_DEFER) +- dev_err(rphy->dev, "Invalid or missing extcon\n"); +- return PTR_ERR(edev); +- } ++ if (IS_ERR(edev)) ++ return dev_err_probe(rphy->dev, PTR_ERR(edev), ++ "invalid or missing extcon\n"); + } else { + /* Initialize extcon device */ + edev = devm_extcon_dev_allocate(rphy->dev, +@@ -394,10 +392,9 @@ static int rockchip_usb2phy_extcon_regis + return -ENOMEM; + + ret = devm_extcon_dev_register(rphy->dev, edev); +- if (ret) { +- dev_err(rphy->dev, "failed to register extcon device\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(rphy->dev, ret, ++ "failed to register extcon device\n"); + } + + rphy->edev = edev; +@@ -1280,10 +1277,8 @@ static int rockchip_usb2phy_probe(struct + } + + ret = rockchip_usb2phy_clk480m_register(rphy); +- if (ret) { +- dev_err(dev, "failed to register 480m output clock\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to register 480m output clock\n"); + + index = 0; + for_each_available_child_of_node(np, child_np) { +@@ -1297,8 +1292,7 @@ static int rockchip_usb2phy_probe(struct + + phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops); + if (IS_ERR(phy)) { +- dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n"); +- ret = PTR_ERR(phy); ++ ret = dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n"); + goto put_child; + } + +@@ -1335,8 +1329,7 @@ next_child: + "rockchip_usb2phy", + rphy); + if (ret) { +- dev_err(rphy->dev, +- "failed to request usb2phy irq handle\n"); ++ dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n"); + goto put_child; + } + } diff --git a/queue-6.1/phy-rockchip-inno-usb2-fix-a-double-free-bug-in-rockchip_usb2phy_probe.patch b/queue-6.1/phy-rockchip-inno-usb2-fix-a-double-free-bug-in-rockchip_usb2phy_probe.patch new file mode 100644 index 0000000000..7be659d6da --- /dev/null +++ b/queue-6.1/phy-rockchip-inno-usb2-fix-a-double-free-bug-in-rockchip_usb2phy_probe.patch @@ -0,0 +1,43 @@ +From stable+bounces-210649-greg=kroah.com@vger.kernel.org Wed Jan 21 03:13:42 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:13:33 -0500 +Subject: phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe() +To: stable@vger.kernel.org +Cc: Wentao Liang , Neil Armstrong , Vinod Koul , Sasha Levin +Message-ID: <20260121021333.1126769-3-sashal@kernel.org> + +From: Wentao Liang + +[ Upstream commit e07dea3de508cd6950c937cec42de7603190e1ca ] + +The for_each_available_child_of_node() calls of_node_put() to +release child_np in each success loop. After breaking from the +loop with the child_np has been released, the code will jump to +the put_child label and will call the of_node_put() again if the +devm_request_threaded_irq() fails. These cause a double free bug. + +Fix by returning directly to avoid the duplicate of_node_put(). + +Fixes: ed2b5a8e6b98 ("phy: phy-rockchip-inno-usb2: support muxed interrupts") +Cc: stable@vger.kernel.org +Signed-off-by: Wentao Liang +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20260109154626.2452034-1-vulab@iscas.ac.cn +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1330,7 +1330,7 @@ next_child: + rphy); + if (ret) { + dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n"); +- goto put_child; ++ return ret; + } + } + diff --git a/queue-6.1/pmdomain-imx8m-blk-ctrl-remove-separate-rst-and-clk-mask-for-8mq-vpu.patch b/queue-6.1/pmdomain-imx8m-blk-ctrl-remove-separate-rst-and-clk-mask-for-8mq-vpu.patch new file mode 100644 index 0000000000..97d0707828 --- /dev/null +++ b/queue-6.1/pmdomain-imx8m-blk-ctrl-remove-separate-rst-and-clk-mask-for-8mq-vpu.patch @@ -0,0 +1,63 @@ +From stable+bounces-212684-greg=kroah.com@vger.kernel.org Wed Jan 28 23:21:38 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 17:20:33 -0500 +Subject: pmdomain: imx8m-blk-ctrl: Remove separate rst and clk mask for 8mq vpu +To: stable@vger.kernel.org +Cc: Ming Qian , Benjamin Gaignard , Peng Fan , Frank Li , Ulf Hansson , Sasha Levin +Message-ID: <20260128222033.2800495-1-sashal@kernel.org> + +From: Ming Qian + +[ Upstream commit 3de49966499634454fd59e0e6fecd50baab7febd ] + +For i.MX8MQ platform, the ADB in the VPUMIX domain has no separate reset +and clock enable bits, but is ungated and reset together with the VPUs. +So we can't reset G1 or G2 separately, it may led to the system hang. +Remove rst_mask and clk_mask of imx8mq_vpu_blk_ctl_domain_data. +Let imx8mq_vpu_power_notifier() do really vpu reset. + +Fixes: 608d7c325e85 ("soc: imx: imx8m-blk-ctrl: add i.MX8MQ VPU blk-ctrl") +Signed-off-by: Ming Qian +Reviewed-by: Benjamin Gaignard +Reviewed-by: Peng Fan +Reviewed-by: Frank Li +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/soc/imx/imx8m-blk-ctrl.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/soc/imx/imx8m-blk-ctrl.c ++++ b/drivers/soc/imx/imx8m-blk-ctrl.c +@@ -810,22 +810,25 @@ static int imx8mq_vpu_power_notifier(str + return NOTIFY_OK; + } + ++/* ++ * For i.MX8MQ, the ADB in the VPUMIX domain has no separate reset and clock ++ * enable bits, but is ungated and reset together with the VPUs. ++ * Resetting G1 or G2 separately may led to system hang. ++ * Remove the rst_mask and clk_mask from the domain data of G1 and G2, ++ * Let imx8mq_vpu_power_notifier() do really vpu reset. ++ */ + static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = { + [IMX8MQ_VPUBLK_PD_G1] = { + .name = "vpublk-g1", + .clk_names = (const char *[]){ "g1", }, + .num_clks = 1, + .gpc_name = "g1", +- .rst_mask = BIT(1), +- .clk_mask = BIT(1), + }, + [IMX8MQ_VPUBLK_PD_G2] = { + .name = "vpublk-g2", + .clk_names = (const char *[]){ "g2", }, + .num_clks = 1, + .gpc_name = "g2", +- .rst_mask = BIT(0), +- .clk_mask = BIT(0), + }, + }; + diff --git a/queue-6.1/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch b/queue-6.1/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch new file mode 100644 index 0000000000..1b36cea212 --- /dev/null +++ b/queue-6.1/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch @@ -0,0 +1,39 @@ +From stable+bounces-211642-greg=kroah.com@vger.kernel.org Mon Jan 26 16:51:27 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 10:51:19 -0500 +Subject: scsi: xen: scsiback: Fix potential memory leak in scsiback_remove() +To: stable@vger.kernel.org +Cc: Abdun Nihaal , Juergen Gross , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260126155119.3323199-2-sashal@kernel.org> + +From: Abdun Nihaal + +[ Upstream commit 901a5f309daba412e2a30364d7ec1492fa11c32c ] + +Memory allocated for struct vscsiblk_info in scsiback_probe() is not +freed in scsiback_remove() leading to potential memory leaks on remove, +as well as in the scsiback_probe() error paths. Fix that by freeing it +in scsiback_remove(). + +Cc: stable@vger.kernel.org +Fixes: d9d660f6e562 ("xen-scsiback: Add Xen PV SCSI backend driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20251223063012.119035-1-nihaal@cse.iitm.ac.in +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/xen/xen-scsiback.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/xen/xen-scsiback.c ++++ b/drivers/xen/xen-scsiback.c +@@ -1261,6 +1261,7 @@ static void scsiback_remove(struct xenbu + gnttab_page_cache_shrink(&info->free_pages, 0); + + dev_set_drvdata(&dev->dev, NULL); ++ kfree(info); + } + + static int scsiback_probe(struct xenbus_device *dev, diff --git a/queue-6.1/series b/queue-6.1/series index 7b197b2d13..4e2a87244f 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -217,3 +217,37 @@ drm-amdgpu-soc21-fix-xclk-for-apus.patch drm-amdgpu-gfx10-fix-wptr-reset-in-kgq-init.patch drm-amdgpu-gfx11-fix-wptr-reset-in-kgq-init.patch gpio-rockchip-stop-calling-pinctrl-for-set_direction.patch +mm-rmap-fix-two-comments-related-to-huge_pmd_unshare.patch +arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch +xen-make-remove-callback-of-xen-driver-void-returned.patch +scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch +dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch +mm-page_alloc-prevent-pcp-corruption-with-smp-n.patch +dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch +mm-kmsan-fix-poisoning-of-high-order-non-compound-pages.patch +xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch +pmdomain-imx8m-blk-ctrl-remove-separate-rst-and-clk-mask-for-8mq-vpu.patch +ksmbd-smbd-fix-dma_unmap_sg-nents.patch +mei-trace-treat-reg-parameter-as-string.patch +arm64-fpsimd-signal-fix-restoration-of-sve-context.patch +mmc-sdhci-of-dwcmshc-update-dll-and-pre-change-delay-for-rockchip-platform.patch +mmc-sdhci-of-dwcmshc-prevent-illegal-clock-reduction-in-hs200-hs400-mode.patch +alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch +iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch +iio-chemical-scd4x-fix-reported-channel-endianness.patch +nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch +nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch +nvme-fix-pcie-subsystem-reset-controller-state-transition.patch +phy-phy-rockchip-inno-usb2-simplify-phy-clock-handling.patch +phy-phy-rockchip-inno-usb2-use-dev_err_probe-in-the-probe-path.patch +phy-rockchip-inno-usb2-fix-a-double-free-bug-in-rockchip_usb2phy_probe.patch +asoc-codecs-wsa881x-simplify-pdev-dev-in-probe.patch +asoc-codecs-wsa881x-use-proper-shutdown-gpio-polarity.patch +asoc-codecs-wsa881x-drop-unused-version-readout.patch +asoc-codecs-wsa881x-fix-unnecessary-initialisation.patch +asoc-codecs-wsa883x-fix-unnecessary-initialisation.patch +x86-fpu-clear-xstate_bv-in-guest-xsave-state-whenever-xfd-1.patch +team-move-team-device-type-change-at-the-end-of-team_port_add.patch +wifi-mac80211-use-wiphy-work-for-sdata-work.patch +wifi-mac80211-move-tdls-work-to-wiphy-work.patch +genirq-irq_sim-initialize-work-context-pointers-properly.patch diff --git a/queue-6.1/team-move-team-device-type-change-at-the-end-of-team_port_add.patch b/queue-6.1/team-move-team-device-type-change-at-the-end-of-team_port_add.patch new file mode 100644 index 0000000000..9ef827b542 --- /dev/null +++ b/queue-6.1/team-move-team-device-type-change-at-the-end-of-team_port_add.patch @@ -0,0 +1,117 @@ +From black.hawk@163.com Tue Feb 3 07:09:19 2026 +From: Rahul Sharma +Date: Tue, 3 Feb 2026 14:08:48 +0800 +Subject: team: Move team device type change at the end of team_port_add +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, "Nikola Z. Ivanov" , syzbot+a2a3b519de727b0f7903@syzkaller.appspotmail.com, Jiri Pirko , Jakub Kicinski , Rahul Sharma +Message-ID: <20260203060848.1805797-1-black.hawk@163.com> + +From: "Nikola Z. Ivanov" + +[ Upstream commit 0ae9cfc454ea5ead5f3ddbdfe2e70270d8e2c8ef ] + +Attempting to add a port device that is already up will expectedly fail, +but not before modifying the team device header_ops. + +In the case of the syzbot reproducer the gre0 device is +already in state UP when it attempts to add it as a +port device of team0, this fails but before that +header_ops->create of team0 is changed from eth_header to ipgre_header +in the call to team_dev_type_check_change. + +Later when we end up in ipgre_header() struct ip_tunnel* points to nonsense +as the private data of the device still holds a struct team. + +Example sequence of iproute2 commands to reproduce the hang/BUG(): +ip link add dev team0 type team +ip link add dev gre0 type gre +ip link set dev gre0 up +ip link set dev gre0 master team0 +ip link set dev team0 up +ping -I team0 1.1.1.1 + +Move team_dev_type_check_change down where all other checks have passed +as it changes the dev type with no way to restore it in case +one of the checks that follow it fail. + +Also make sure to preserve the origial mtu assignment: + - If port_dev is not the same type as dev, dev takes mtu from port_dev + - If port_dev is the same type as dev, port_dev takes mtu from dev + +This is done by adding a conditional before the call to dev_set_mtu +to prevent it from assigning port_dev->mtu = dev->mtu and instead +letting team_dev_type_check_change assign dev->mtu = port_dev->mtu. +The conditional is needed because the patch moves the call to +team_dev_type_check_change past dev_set_mtu. + +Testing: + - team device driver in-tree selftests + - Add/remove various devices as slaves of team device + - syzbot + +Reported-by: syzbot+a2a3b519de727b0f7903@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=a2a3b519de727b0f7903 +Fixes: 1d76efe1577b ("team: add support for non-ethernet devices") +Signed-off-by: Nikola Z. Ivanov +Reviewed-by: Jiri Pirko +Link: https://patch.msgid.link/20251122002027.695151-1-zlatistiv@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/team/team.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -1186,10 +1186,6 @@ static int team_port_add(struct team *te + return -EPERM; + } + +- err = team_dev_type_check_change(dev, port_dev); +- if (err) +- return err; +- + if (port_dev->flags & IFF_UP) { + NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port"); + netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n", +@@ -1207,10 +1203,16 @@ static int team_port_add(struct team *te + INIT_LIST_HEAD(&port->qom_list); + + port->orig.mtu = port_dev->mtu; +- err = dev_set_mtu(port_dev, dev->mtu); +- if (err) { +- netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err); +- goto err_set_mtu; ++ /* ++ * MTU assignment will be handled in team_dev_type_check_change ++ * if dev and port_dev are of different types ++ */ ++ if (dev->type == port_dev->type) { ++ err = dev_set_mtu(port_dev, dev->mtu); ++ if (err) { ++ netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err); ++ goto err_set_mtu; ++ } + } + + memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len); +@@ -1285,6 +1287,10 @@ static int team_port_add(struct team *te + } + } + ++ err = team_dev_type_check_change(dev, port_dev); ++ if (err) ++ goto err_set_dev_type; ++ + if (dev->flags & IFF_UP) { + netif_addr_lock_bh(dev); + dev_uc_sync_multiple(port_dev, dev); +@@ -1303,6 +1309,7 @@ static int team_port_add(struct team *te + + return 0; + ++err_set_dev_type: + err_set_slave_promisc: + __team_option_inst_del_port(team, port); + diff --git a/queue-6.1/wifi-mac80211-move-tdls-work-to-wiphy-work.patch b/queue-6.1/wifi-mac80211-move-tdls-work-to-wiphy-work.patch new file mode 100644 index 0000000000..7543df45e0 --- /dev/null +++ b/queue-6.1/wifi-mac80211-move-tdls-work-to-wiphy-work.patch @@ -0,0 +1,104 @@ +From stable+bounces-213087-greg=kroah.com@vger.kernel.org Mon Feb 2 17:54:07 2026 +From: "Hanne-Lotta Mäenpää" +Date: Mon, 2 Feb 2026 18:49:24 +0200 +Subject: wifi: mac80211: move TDLS work to wiphy work +To: stable@vger.kernel.org +Cc: johannes@sipsolutions.net, linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, "Johannes Berg" , "Emmanuel Grumbach" , "Hanne-Lotta Mäenpää" +Message-ID: <20260202164924.215621-2-hannelotta@gmail.com> + +From: Johannes Berg + +[ Upstream commit 777b26002b73127e81643d9286fadf3d41e0e477 ] + +Again, to have the wiphy locked for it. + +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +[ Summary of conflict resolutions: + - In mlme.c, move only tdls_peer_del_work + to wiphy work, and none the other works ] +Signed-off-by: Hanne-Lotta Mäenpää +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/ieee80211_i.h | 4 ++-- + net/mac80211/mlme.c | 7 ++++--- + net/mac80211/tdls.c | 11 ++++++----- + 3 files changed, 12 insertions(+), 10 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -531,7 +531,7 @@ struct ieee80211_if_managed { + + /* TDLS support */ + u8 tdls_peer[ETH_ALEN] __aligned(2); +- struct delayed_work tdls_peer_del_work; ++ struct wiphy_delayed_work tdls_peer_del_work; + struct sk_buff *orig_teardown_skb; /* The original teardown skb */ + struct sk_buff *teardown_skb; /* A copy to send through the AP */ + spinlock_t teardown_lock; /* To lock changing teardown_skb */ +@@ -2525,7 +2525,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wi + size_t extra_ies_len); + int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, + const u8 *peer, enum nl80211_tdls_operation oper); +-void ieee80211_tdls_peer_del_work(struct work_struct *wk); ++void ieee80211_tdls_peer_del_work(struct wiphy *wiphy, struct wiphy_work *wk); + int ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr, u8 oper_class, + struct cfg80211_chan_def *chandef); +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -6517,8 +6517,8 @@ void ieee80211_sta_setup_sdata(struct ie + ieee80211_beacon_connection_loss_work); + INIT_WORK(&ifmgd->csa_connection_drop_work, + ieee80211_csa_connection_drop_work); +- INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work, +- ieee80211_tdls_peer_del_work); ++ wiphy_delayed_work_init(&ifmgd->tdls_peer_del_work, ++ ieee80211_tdls_peer_del_work); + timer_setup(&ifmgd->timer, ieee80211_sta_timer, 0); + timer_setup(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 0); + timer_setup(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, 0); +@@ -7524,7 +7524,8 @@ void ieee80211_mgd_stop(struct ieee80211 + cancel_work_sync(&ifmgd->monitor_work); + cancel_work_sync(&ifmgd->beacon_connection_loss_work); + cancel_work_sync(&ifmgd->csa_connection_drop_work); +- cancel_delayed_work_sync(&ifmgd->tdls_peer_del_work); ++ wiphy_delayed_work_cancel(sdata->local->hw.wiphy, ++ &ifmgd->tdls_peer_del_work); + + sdata_lock(sdata); + if (ifmgd->assoc_data) +--- a/net/mac80211/tdls.c ++++ b/net/mac80211/tdls.c +@@ -21,7 +21,7 @@ + /* give usermode some time for retries in setting up the TDLS session */ + #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) + +-void ieee80211_tdls_peer_del_work(struct work_struct *wk) ++void ieee80211_tdls_peer_del_work(struct wiphy *wiphy, struct wiphy_work *wk) + { + struct ieee80211_sub_if_data *sdata; + struct ieee80211_local *local; +@@ -1128,9 +1128,9 @@ ieee80211_tdls_mgmt_setup(struct wiphy * + return ret; + } + +- ieee80211_queue_delayed_work(&sdata->local->hw, +- &sdata->u.mgd.tdls_peer_del_work, +- TDLS_PEER_SETUP_TIMEOUT); ++ wiphy_delayed_work_queue(sdata->local->hw.wiphy, ++ &sdata->u.mgd.tdls_peer_del_work, ++ TDLS_PEER_SETUP_TIMEOUT); + return 0; + + out_unlock: +@@ -1427,7 +1427,8 @@ int ieee80211_tdls_oper(struct wiphy *wi + } + + if (ret == 0 && ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { +- cancel_delayed_work(&sdata->u.mgd.tdls_peer_del_work); ++ wiphy_delayed_work_cancel(sdata->local->hw.wiphy, ++ &sdata->u.mgd.tdls_peer_del_work); + eth_zero_addr(sdata->u.mgd.tdls_peer); + } + diff --git a/queue-6.1/wifi-mac80211-use-wiphy-work-for-sdata-work.patch b/queue-6.1/wifi-mac80211-use-wiphy-work-for-sdata-work.patch new file mode 100644 index 0000000000..2653a2b3a7 --- /dev/null +++ b/queue-6.1/wifi-mac80211-use-wiphy-work-for-sdata-work.patch @@ -0,0 +1,317 @@ +From stable+bounces-213086-greg=kroah.com@vger.kernel.org Mon Feb 2 17:52:48 2026 +From: "Hanne-Lotta Mäenpää" +Date: Mon, 2 Feb 2026 18:49:23 +0200 +Subject: wifi: mac80211: use wiphy work for sdata->work +To: stable@vger.kernel.org +Cc: johannes@sipsolutions.net, linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, "Johannes Berg" , "Hanne-Lotta Mäenpää" +Message-ID: <20260202164924.215621-1-hannelotta@gmail.com> + +From: Johannes Berg + +[ Upstream commit 16114496d684a3df4ce09f7c6b7557a8b2922795 ] + +We'll need this later to convert other works that might +be cancelled from here, so convert this one first. + +Signed-off-by: Johannes Berg +(cherry picked from commit 16114496d684a3df4ce09f7c6b7557a8b2922795) +Signed-off-by: Hanne-Lotta Mäenpää +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/ibss.c | 8 ++++---- + net/mac80211/ieee80211_i.h | 2 +- + net/mac80211/iface.c | 10 +++++----- + net/mac80211/mesh.c | 10 +++++----- + net/mac80211/mesh_hwmp.c | 6 +++--- + net/mac80211/mlme.c | 6 +++--- + net/mac80211/ocb.c | 6 +++--- + net/mac80211/rx.c | 2 +- + net/mac80211/scan.c | 2 +- + net/mac80211/status.c | 6 +++--- + net/mac80211/util.c | 2 +- + 11 files changed, 30 insertions(+), 30 deletions(-) + +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -741,7 +741,7 @@ static void ieee80211_csa_connection_dro + skb_queue_purge(&sdata->skb_queue); + + /* trigger a scan to find another IBSS network to join */ +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + + sdata_unlock(sdata); + } +@@ -1242,7 +1242,7 @@ void ieee80211_ibss_rx_no_sta(struct iee + spin_lock(&ifibss->incomplete_lock); + list_add(&sta->list, &ifibss->incomplete_stations); + spin_unlock(&ifibss->incomplete_lock); +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata) +@@ -1721,7 +1721,7 @@ static void ieee80211_ibss_timer(struct + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.ibss.timer); + +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) +@@ -1856,7 +1856,7 @@ int ieee80211_ibss_join(struct ieee80211 + sdata->deflink.needed_rx_chains = local->rx_chains; + sdata->control_port_over_nl80211 = params->control_port_over_nl80211; + +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + + return 0; + } +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1046,7 +1046,7 @@ struct ieee80211_sub_if_data { + /* used to reconfigure hardware SM PS */ + struct work_struct recalc_smps; + +- struct work_struct work; ++ struct wiphy_work work; + struct sk_buff_head skb_queue; + struct sk_buff_head status_queue; + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -43,7 +43,7 @@ + * by either the RTNL, the iflist_mtx or RCU. + */ + +-static void ieee80211_iface_work(struct work_struct *work); ++static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work); + + bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) + { +@@ -650,7 +650,7 @@ static void ieee80211_do_stop(struct iee + RCU_INIT_POINTER(local->p2p_sdata, NULL); + fallthrough; + default: +- cancel_work_sync(&sdata->work); ++ wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->work); + /* + * When we get here, the interface is marked down. + * Free the remaining keys, if there are any +@@ -1224,7 +1224,7 @@ int ieee80211_add_virtual_monitor(struct + + skb_queue_head_init(&sdata->skb_queue); + skb_queue_head_init(&sdata->status_queue); +- INIT_WORK(&sdata->work, ieee80211_iface_work); ++ wiphy_work_init(&sdata->work, ieee80211_iface_work); + + return 0; + } +@@ -1707,7 +1707,7 @@ static void ieee80211_iface_process_stat + } + } + +-static void ieee80211_iface_work(struct work_struct *work) ++static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work) + { + struct ieee80211_sub_if_data *sdata = + container_of(work, struct ieee80211_sub_if_data, work); +@@ -1819,7 +1819,7 @@ static void ieee80211_setup_sdata(struct + + skb_queue_head_init(&sdata->skb_queue); + skb_queue_head_init(&sdata->status_queue); +- INIT_WORK(&sdata->work, ieee80211_iface_work); ++ wiphy_work_init(&sdata->work, ieee80211_iface_work); + INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); + INIT_WORK(&sdata->activate_links_work, ieee80211_activate_links_work); + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -44,7 +44,7 @@ static void ieee80211_mesh_housekeeping_ + + set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); + +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + /** +@@ -643,7 +643,7 @@ static void ieee80211_mesh_path_timer(st + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.mesh.mesh_path_timer); + +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + static void ieee80211_mesh_path_root_timer(struct timer_list *t) +@@ -654,7 +654,7 @@ static void ieee80211_mesh_path_root_tim + + set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); + +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) +@@ -1018,7 +1018,7 @@ void ieee80211_mbss_info_change_notify(s + for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE) + set_bit(bit, &ifmsh->mbss_changed); + set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags); +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) +@@ -1043,7 +1043,7 @@ int ieee80211_start_mesh(struct ieee8021 + ifmsh->sync_offset_clockdrift_max = 0; + set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); + ieee80211_mesh_root_setup(ifmsh); +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + sdata->vif.bss_conf.ht_operation_mode = + ifmsh->mshcfg.ht_opmode; + sdata->vif.bss_conf.enable_beacon = true; +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2008, 2009 open80211s Ltd. +- * Copyright (C) 2019, 2021-2022 Intel Corporation ++ * Copyright (C) 2019, 2021-2023 Intel Corporation + * Author: Luis Carlos Cobo + */ + +@@ -1025,14 +1025,14 @@ static void mesh_queue_preq(struct mesh_ + spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); + + if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + + else if (time_before(jiffies, ifmsh->last_preq)) { + /* avoid long wait if did not send preqs for a long time + * and jiffies wrapped around + */ + ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } else + mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + + min_preq_int_jiff(sdata)); +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3168,7 +3168,7 @@ void ieee80211_sta_tx_notify(struct ieee + sdata->u.mgd.probe_send_count = 0; + else + sdata->u.mgd.nullfunc_failed = true; +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + static void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata, +@@ -6031,7 +6031,7 @@ static void ieee80211_sta_timer(struct t + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.mgd.timer); + +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, +@@ -6175,7 +6175,7 @@ void ieee80211_mgd_conn_tx_status(struct + sdata->u.mgd.status_acked = acked; + sdata->u.mgd.status_received = true; + +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) +--- a/net/mac80211/ocb.c ++++ b/net/mac80211/ocb.c +@@ -81,7 +81,7 @@ void ieee80211_ocb_rx_no_sta(struct ieee + spin_lock(&ifocb->incomplete_lock); + list_add(&sta->list, &ifocb->incomplete_stations); + spin_unlock(&ifocb->incomplete_lock); +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta) +@@ -157,7 +157,7 @@ static void ieee80211_ocb_housekeeping_t + + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); + +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata) +@@ -197,7 +197,7 @@ int ieee80211_ocb_join(struct ieee80211_ + ifocb->joined = true; + + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + + netif_carrier_on(sdata->dev); + return 0; +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -229,7 +229,7 @@ static void __ieee80211_queue_skb_to_ifa + } + + skb_queue_tail(&sdata->skb_queue, skb); +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + if (sta) + sta->deflink.rx_stats.packets++; + } +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -503,7 +503,7 @@ static void __ieee80211_scan_completed(s + */ + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (ieee80211_sdata_running(sdata)) +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + if (was_scanning) +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -5,7 +5,7 @@ + * Copyright 2006-2007 Jiri Benc + * Copyright 2008-2010 Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH +- * Copyright 2021-2022 Intel Corporation ++ * Copyright 2021-2023 Intel Corporation + */ + + #include +@@ -747,8 +747,8 @@ static void ieee80211_report_used_skb(st + if (qskb) { + skb_queue_tail(&sdata->status_queue, + qskb); +- ieee80211_queue_work(&local->hw, +- &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, ++ &sdata->work); + } + } + } else { +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2751,7 +2751,7 @@ int ieee80211_reconfig(struct ieee80211_ + + /* Requeue all works */ + list_for_each_entry(sdata, &local->interfaces, list) +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, diff --git a/queue-6.1/x86-fpu-clear-xstate_bv-in-guest-xsave-state-whenever-xfd-1.patch b/queue-6.1/x86-fpu-clear-xstate_bv-in-guest-xsave-state-whenever-xfd-1.patch new file mode 100644 index 0000000000..f16ce651db --- /dev/null +++ b/queue-6.1/x86-fpu-clear-xstate_bv-in-guest-xsave-state-whenever-xfd-1.patch @@ -0,0 +1,177 @@ +From stable+bounces-210370-greg=kroah.com@vger.kernel.org Mon Jan 19 17:01:11 2026 +From: Sasha Levin +Date: Mon, 19 Jan 2026 11:00:09 -0500 +Subject: x86/fpu: Clear XSTATE_BV[i] in guest XSAVE state whenever XFD[i]=1 +To: stable@vger.kernel.org +Cc: Sean Christopherson , Paolo Bonzini , Binbin Wu , Sasha Levin +Message-ID: <20260119160009.3069587-1-sashal@kernel.org> + +From: Sean Christopherson + +[ Upstream commit b45f721775947a84996deb5c661602254ce25ce6 ] + +When loading guest XSAVE state via KVM_SET_XSAVE, and when updating XFD in +response to a guest WRMSR, clear XFD-disabled features in the saved (or to +be restored) XSTATE_BV to ensure KVM doesn't attempt to load state for +features that are disabled via the guest's XFD. Because the kernel +executes XRSTOR with the guest's XFD, saving XSTATE_BV[i]=1 with XFD[i]=1 +will cause XRSTOR to #NM and panic the kernel. + +E.g. if fpu_update_guest_xfd() sets XFD without clearing XSTATE_BV: + + ------------[ cut here ]------------ + WARNING: arch/x86/kernel/traps.c:1524 at exc_device_not_available+0x101/0x110, CPU#29: amx_test/848 + Modules linked in: kvm_intel kvm irqbypass + CPU: 29 UID: 1000 PID: 848 Comm: amx_test Not tainted 6.19.0-rc2-ffa07f7fd437-x86_amx_nm_xfd_non_init-vm #171 NONE + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 + RIP: 0010:exc_device_not_available+0x101/0x110 + Call Trace: + + asm_exc_device_not_available+0x1a/0x20 + RIP: 0010:restore_fpregs_from_fpstate+0x36/0x90 + switch_fpu_return+0x4a/0xb0 + kvm_arch_vcpu_ioctl_run+0x1245/0x1e40 [kvm] + kvm_vcpu_ioctl+0x2c3/0x8f0 [kvm] + __x64_sys_ioctl+0x8f/0xd0 + do_syscall_64+0x62/0x940 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + + ---[ end trace 0000000000000000 ]--- + +This can happen if the guest executes WRMSR(MSR_IA32_XFD) to set XFD[18] = 1, +and a host IRQ triggers kernel_fpu_begin() prior to the vmexit handler's +call to fpu_update_guest_xfd(). + +and if userspace stuffs XSTATE_BV[i]=1 via KVM_SET_XSAVE: + + ------------[ cut here ]------------ + WARNING: arch/x86/kernel/traps.c:1524 at exc_device_not_available+0x101/0x110, CPU#14: amx_test/867 + Modules linked in: kvm_intel kvm irqbypass + CPU: 14 UID: 1000 PID: 867 Comm: amx_test Not tainted 6.19.0-rc2-2dace9faccd6-x86_amx_nm_xfd_non_init-vm #168 NONE + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 + RIP: 0010:exc_device_not_available+0x101/0x110 + Call Trace: + + asm_exc_device_not_available+0x1a/0x20 + RIP: 0010:restore_fpregs_from_fpstate+0x36/0x90 + fpu_swap_kvm_fpstate+0x6b/0x120 + kvm_load_guest_fpu+0x30/0x80 [kvm] + kvm_arch_vcpu_ioctl_run+0x85/0x1e40 [kvm] + kvm_vcpu_ioctl+0x2c3/0x8f0 [kvm] + __x64_sys_ioctl+0x8f/0xd0 + do_syscall_64+0x62/0x940 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + + ---[ end trace 0000000000000000 ]--- + +The new behavior is consistent with the AMX architecture. Per Intel's SDM, +XSAVE saves XSTATE_BV as '0' for components that are disabled via XFD +(and non-compacted XSAVE saves the initial configuration of the state +component): + + If XSAVE, XSAVEC, XSAVEOPT, or XSAVES is saving the state component i, + the instruction does not generate #NM when XCR0[i] = IA32_XFD[i] = 1; + instead, it operates as if XINUSE[i] = 0 (and the state component was + in its initial state): it saves bit i of XSTATE_BV field of the XSAVE + header as 0; in addition, XSAVE saves the initial configuration of the + state component (the other instructions do not save state component i). + +Alternatively, KVM could always do XRSTOR with XFD=0, e.g. by using +a constant XFD based on the set of enabled features when XSAVEing for +a struct fpu_guest. However, having XSTATE_BV[i]=1 for XFD-disabled +features can only happen in the above interrupt case, or in similar +scenarios involving preemption on preemptible kernels, because +fpu_swap_kvm_fpstate()'s call to save_fpregs_to_fpstate() saves the +outgoing FPU state with the current XFD; and that is (on all but the +first WRMSR to XFD) the guest XFD. + +Therefore, XFD can only go out of sync with XSTATE_BV in the above +interrupt case, or in similar scenarios involving preemption on +preemptible kernels, and it we can consider it (de facto) part of KVM +ABI that KVM_GET_XSAVE returns XSTATE_BV[i]=0 for XFD-disabled features. + +Reported-by: Paolo Bonzini +Cc: stable@vger.kernel.org +Fixes: 820a6ee944e7 ("kvm: x86: Add emulation for IA32_XFD", 2022-01-14) +Signed-off-by: Sean Christopherson +[Move clearing of XSTATE_BV from fpu_copy_uabi_to_guest_fpstate + to kvm_vcpu_ioctl_x86_set_xsave. - Paolo] +Reviewed-by: Binbin Wu +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/fpu/core.c | 32 +++++++++++++++++++++++++++++--- + arch/x86/kvm/x86.c | 9 +++++++++ + 2 files changed, 38 insertions(+), 3 deletions(-) + +--- a/arch/x86/kernel/fpu/core.c ++++ b/arch/x86/kernel/fpu/core.c +@@ -294,10 +294,29 @@ EXPORT_SYMBOL_GPL(fpu_enable_guest_xfd_f + #ifdef CONFIG_X86_64 + void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd) + { ++ struct fpstate *fpstate = guest_fpu->fpstate; ++ + fpregs_lock(); +- guest_fpu->fpstate->xfd = xfd; +- if (guest_fpu->fpstate->in_use) +- xfd_update_state(guest_fpu->fpstate); ++ ++ /* ++ * KVM's guest ABI is that setting XFD[i]=1 *can* immediately revert the ++ * save state to its initial configuration. Likewise, KVM_GET_XSAVE does ++ * the same as XSAVE and returns XSTATE_BV[i]=0 whenever XFD[i]=1. ++ * ++ * If the guest's FPU state is in hardware, just update XFD: the XSAVE ++ * in fpu_swap_kvm_fpstate will clear XSTATE_BV[i] whenever XFD[i]=1. ++ * ++ * If however the guest's FPU state is NOT resident in hardware, clear ++ * disabled components in XSTATE_BV now, or a subsequent XRSTOR will ++ * attempt to load disabled components and generate #NM _in the host_. ++ */ ++ if (xfd && test_thread_flag(TIF_NEED_FPU_LOAD)) ++ fpstate->regs.xsave.header.xfeatures &= ~xfd; ++ ++ fpstate->xfd = xfd; ++ if (fpstate->in_use) ++ xfd_update_state(fpstate); ++ + fpregs_unlock(); + } + EXPORT_SYMBOL_GPL(fpu_update_guest_xfd); +@@ -406,6 +425,13 @@ int fpu_copy_uabi_to_guest_fpstate(struc + return -EINVAL; + + /* ++ * Disabled features must be in their initial state, otherwise XRSTOR ++ * causes an exception. ++ */ ++ if (WARN_ON_ONCE(ustate->xsave.header.xfeatures & kstate->xfd)) ++ return -EINVAL; ++ ++ /* + * Nullify @vpkru to preserve its current value if PKRU's bit isn't set + * in the header. KVM's odd ABI is to leave PKRU untouched in this + * case (all other components are eventually re-initialized). +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -5341,9 +5341,18 @@ static void kvm_vcpu_ioctl_x86_get_xsave + static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, + struct kvm_xsave *guest_xsave) + { ++ union fpregs_state *xstate = (union fpregs_state *)guest_xsave->region; ++ + if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) + return 0; + ++ /* ++ * For backwards compatibility, do not expect disabled features to be in ++ * their initial state. XSTATE_BV[i] must still be cleared whenever ++ * XFD[i]=1, or XRSTOR would cause a #NM. ++ */ ++ xstate->xsave.header.xfeatures &= ~vcpu->arch.guest_fpu.fpstate->xfd; ++ + return fpu_copy_uabi_to_guest_fpstate(&vcpu->arch.guest_fpu, + guest_xsave->region, + kvm_caps.supported_xcr0, diff --git a/queue-6.1/xen-make-remove-callback-of-xen-driver-void-returned.patch b/queue-6.1/xen-make-remove-callback-of-xen-driver-void-returned.patch new file mode 100644 index 0000000000..867f84aa32 --- /dev/null +++ b/queue-6.1/xen-make-remove-callback-of-xen-driver-void-returned.patch @@ -0,0 +1,408 @@ +From stable+bounces-211641-greg=kroah.com@vger.kernel.org Mon Jan 26 16:51:25 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 10:51:18 -0500 +Subject: xen: make remove callback of xen driver void returned +To: stable@vger.kernel.org +Cc: Dawei Li , Juergen Gross , Sasha Levin +Message-ID: <20260126155119.3323199-1-sashal@kernel.org> + +From: Dawei Li + +[ Upstream commit 7cffcade57a429667447c4f41d8414bbcf1b3aaa ] + +Since commit fc7a6209d571 ("bus: Make remove callback return void") +forces bus_type::remove be void-returned, it doesn't make much sense for +any bus based driver implementing remove callbalk to return non-void to +its caller. + +This change is for xen bus based drivers. + +Acked-by: Juergen Gross +Signed-off-by: Dawei Li +Link: https://lore.kernel.org/r/TYCP286MB23238119AB4DF190997075C9CAE39@TYCP286MB2323.JPNP286.PROD.OUTLOOK.COM +Signed-off-by: Juergen Gross +Stable-dep-of: 901a5f309dab ("scsi: xen: scsiback: Fix potential memory leak in scsiback_remove()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/xen-blkback/xenbus.c | 4 +--- + drivers/block/xen-blkfront.c | 3 +-- + drivers/char/tpm/xen-tpmfront.c | 3 +-- + drivers/gpu/drm/xen/xen_drm_front.c | 3 +-- + drivers/input/misc/xen-kbdfront.c | 5 ++--- + drivers/net/xen-netback/xenbus.c | 3 +-- + drivers/net/xen-netfront.c | 4 +--- + drivers/pci/xen-pcifront.c | 4 +--- + drivers/scsi/xen-scsifront.c | 4 +--- + drivers/tty/hvc/hvc_xen.c | 4 ++-- + drivers/usb/host/xen-hcd.c | 4 +--- + drivers/video/fbdev/xen-fbfront.c | 6 ++---- + drivers/xen/pvcalls-back.c | 3 +-- + drivers/xen/pvcalls-front.c | 3 +-- + drivers/xen/xen-pciback/xenbus.c | 4 +--- + drivers/xen/xen-scsiback.c | 4 +--- + include/xen/xenbus.h | 2 +- + net/9p/trans_xen.c | 3 +-- + sound/xen/xen_snd_front.c | 3 +-- + 19 files changed, 22 insertions(+), 47 deletions(-) + +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -524,7 +524,7 @@ static int xen_vbd_create(struct xen_blk + return 0; + } + +-static int xen_blkbk_remove(struct xenbus_device *dev) ++static void xen_blkbk_remove(struct xenbus_device *dev) + { + struct backend_info *be = dev_get_drvdata(&dev->dev); + +@@ -547,8 +547,6 @@ static int xen_blkbk_remove(struct xenbu + /* Put the reference we set in xen_blkif_alloc(). */ + xen_blkif_put(be->blkif); + } +- +- return 0; + } + + int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -2469,7 +2469,7 @@ static void blkback_changed(struct xenbu + } + } + +-static int blkfront_remove(struct xenbus_device *xbdev) ++static void blkfront_remove(struct xenbus_device *xbdev) + { + struct blkfront_info *info = dev_get_drvdata(&xbdev->dev); + +@@ -2490,7 +2490,6 @@ static int blkfront_remove(struct xenbus + } + + kfree(info); +- return 0; + } + + static int blkfront_is_ready(struct xenbus_device *dev) +--- a/drivers/char/tpm/xen-tpmfront.c ++++ b/drivers/char/tpm/xen-tpmfront.c +@@ -360,14 +360,13 @@ static int tpmfront_probe(struct xenbus_ + return tpm_chip_register(priv->chip); + } + +-static int tpmfront_remove(struct xenbus_device *dev) ++static void tpmfront_remove(struct xenbus_device *dev) + { + struct tpm_chip *chip = dev_get_drvdata(&dev->dev); + struct tpm_private *priv = dev_get_drvdata(&chip->dev); + tpm_chip_unregister(chip); + ring_free(priv); + dev_set_drvdata(&chip->dev, NULL); +- return 0; + } + + static int tpmfront_resume(struct xenbus_device *dev) +--- a/drivers/gpu/drm/xen/xen_drm_front.c ++++ b/drivers/gpu/drm/xen/xen_drm_front.c +@@ -717,7 +717,7 @@ static int xen_drv_probe(struct xenbus_d + return xenbus_switch_state(xb_dev, XenbusStateInitialising); + } + +-static int xen_drv_remove(struct xenbus_device *dev) ++static void xen_drv_remove(struct xenbus_device *dev) + { + struct xen_drm_front_info *front_info = dev_get_drvdata(&dev->dev); + int to = 100; +@@ -751,7 +751,6 @@ static int xen_drv_remove(struct xenbus_ + + xen_drm_drv_fini(front_info); + xenbus_frontend_closed(dev); +- return 0; + } + + static const struct xenbus_device_id xen_driver_ids[] = { +--- a/drivers/input/misc/xen-kbdfront.c ++++ b/drivers/input/misc/xen-kbdfront.c +@@ -51,7 +51,7 @@ module_param_array(ptr_size, int, NULL, + MODULE_PARM_DESC(ptr_size, + "Pointing device width, height in pixels (default 800,600)"); + +-static int xenkbd_remove(struct xenbus_device *); ++static void xenkbd_remove(struct xenbus_device *); + static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *); + static void xenkbd_disconnect_backend(struct xenkbd_info *); + +@@ -404,7 +404,7 @@ static int xenkbd_resume(struct xenbus_d + return xenkbd_connect_backend(dev, info); + } + +-static int xenkbd_remove(struct xenbus_device *dev) ++static void xenkbd_remove(struct xenbus_device *dev) + { + struct xenkbd_info *info = dev_get_drvdata(&dev->dev); + +@@ -417,7 +417,6 @@ static int xenkbd_remove(struct xenbus_d + input_unregister_device(info->mtouch); + free_page((unsigned long)info->page); + kfree(info); +- return 0; + } + + static int xenkbd_connect_backend(struct xenbus_device *dev, +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -977,7 +977,7 @@ static int read_xenbus_vif_flags(struct + return 0; + } + +-static int netback_remove(struct xenbus_device *dev) ++static void netback_remove(struct xenbus_device *dev) + { + struct backend_info *be = dev_get_drvdata(&dev->dev); + +@@ -992,7 +992,6 @@ static int netback_remove(struct xenbus_ + kfree(be->hotplug_script); + kfree(be); + dev_set_drvdata(&dev->dev, NULL); +- return 0; + } + + /* +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -2652,7 +2652,7 @@ static void xennet_bus_close(struct xenb + } while (!ret); + } + +-static int xennet_remove(struct xenbus_device *dev) ++static void xennet_remove(struct xenbus_device *dev) + { + struct netfront_info *info = dev_get_drvdata(&dev->dev); + +@@ -2668,8 +2668,6 @@ static int xennet_remove(struct xenbus_d + rtnl_unlock(); + } + xennet_free_netdev(info->netdev); +- +- return 0; + } + + static const struct xenbus_device_id netfront_ids[] = { +--- a/drivers/pci/xen-pcifront.c ++++ b/drivers/pci/xen-pcifront.c +@@ -1055,14 +1055,12 @@ out: + return err; + } + +-static int pcifront_xenbus_remove(struct xenbus_device *xdev) ++static void pcifront_xenbus_remove(struct xenbus_device *xdev) + { + struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev); + + if (pdev) + free_pdev(pdev); +- +- return 0; + } + + static const struct xenbus_device_id xenpci_ids[] = { +--- a/drivers/scsi/xen-scsifront.c ++++ b/drivers/scsi/xen-scsifront.c +@@ -995,7 +995,7 @@ static int scsifront_suspend(struct xenb + return err; + } + +-static int scsifront_remove(struct xenbus_device *dev) ++static void scsifront_remove(struct xenbus_device *dev) + { + struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); + +@@ -1011,8 +1011,6 @@ static int scsifront_remove(struct xenbu + + scsifront_free_ring(info); + scsi_host_put(info->host); +- +- return 0; + } + + static void scsifront_disconnect(struct vscsifrnt_info *info) +--- a/drivers/tty/hvc/hvc_xen.c ++++ b/drivers/tty/hvc/hvc_xen.c +@@ -420,9 +420,9 @@ static int xen_console_remove(struct xen + return 0; + } + +-static int xencons_remove(struct xenbus_device *dev) ++static void xencons_remove(struct xenbus_device *dev) + { +- return xen_console_remove(dev_get_drvdata(&dev->dev)); ++ xen_console_remove(dev_get_drvdata(&dev->dev)); + } + + static int xencons_connect_backend(struct xenbus_device *dev, +--- a/drivers/usb/host/xen-hcd.c ++++ b/drivers/usb/host/xen-hcd.c +@@ -1530,15 +1530,13 @@ static void xenhcd_backend_changed(struc + } + } + +-static int xenhcd_remove(struct xenbus_device *dev) ++static void xenhcd_remove(struct xenbus_device *dev) + { + struct xenhcd_info *info = dev_get_drvdata(&dev->dev); + struct usb_hcd *hcd = xenhcd_info_to_hcd(info); + + xenhcd_destroy_rings(info); + usb_put_hcd(hcd); +- +- return 0; + } + + static int xenhcd_probe(struct xenbus_device *dev, +--- a/drivers/video/fbdev/xen-fbfront.c ++++ b/drivers/video/fbdev/xen-fbfront.c +@@ -67,7 +67,7 @@ MODULE_PARM_DESC(video, + "Video memory size in MB, width, height in pixels (default 2,800,600)"); + + static void xenfb_make_preferred_console(void); +-static int xenfb_remove(struct xenbus_device *); ++static void xenfb_remove(struct xenbus_device *); + static void xenfb_init_shared_page(struct xenfb_info *, struct fb_info *); + static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *); + static void xenfb_disconnect_backend(struct xenfb_info *); +@@ -527,7 +527,7 @@ static int xenfb_resume(struct xenbus_de + return xenfb_connect_backend(dev, info); + } + +-static int xenfb_remove(struct xenbus_device *dev) ++static void xenfb_remove(struct xenbus_device *dev) + { + struct xenfb_info *info = dev_get_drvdata(&dev->dev); + +@@ -542,8 +542,6 @@ static int xenfb_remove(struct xenbus_de + vfree(info->gfns); + vfree(info->fb); + kfree(info); +- +- return 0; + } + + static unsigned long vmalloc_to_gfn(void *address) +--- a/drivers/xen/pvcalls-back.c ++++ b/drivers/xen/pvcalls-back.c +@@ -1180,9 +1180,8 @@ static void pvcalls_back_changed(struct + } + } + +-static int pvcalls_back_remove(struct xenbus_device *dev) ++static void pvcalls_back_remove(struct xenbus_device *dev) + { +- return 0; + } + + static int pvcalls_back_uevent(struct xenbus_device *xdev, +--- a/drivers/xen/pvcalls-front.c ++++ b/drivers/xen/pvcalls-front.c +@@ -1087,7 +1087,7 @@ static const struct xenbus_device_id pvc + { "" } + }; + +-static int pvcalls_front_remove(struct xenbus_device *dev) ++static void pvcalls_front_remove(struct xenbus_device *dev) + { + struct pvcalls_bedata *bedata; + struct sock_mapping *map = NULL, *n; +@@ -1123,7 +1123,6 @@ static int pvcalls_front_remove(struct x + kfree(bedata->ring.sring); + kfree(bedata); + xenbus_switch_state(dev, XenbusStateClosed); +- return 0; + } + + static int pvcalls_front_probe(struct xenbus_device *dev, +--- a/drivers/xen/xen-pciback/xenbus.c ++++ b/drivers/xen/xen-pciback/xenbus.c +@@ -716,14 +716,12 @@ out: + return err; + } + +-static int xen_pcibk_xenbus_remove(struct xenbus_device *dev) ++static void xen_pcibk_xenbus_remove(struct xenbus_device *dev) + { + struct xen_pcibk_device *pdev = dev_get_drvdata(&dev->dev); + + if (pdev != NULL) + free_pdev(pdev); +- +- return 0; + } + + static const struct xenbus_device_id xen_pcibk_ids[] = { +--- a/drivers/xen/xen-scsiback.c ++++ b/drivers/xen/xen-scsiback.c +@@ -1249,7 +1249,7 @@ static void scsiback_release_translation + spin_unlock_irqrestore(&info->v2p_lock, flags); + } + +-static int scsiback_remove(struct xenbus_device *dev) ++static void scsiback_remove(struct xenbus_device *dev) + { + struct vscsibk_info *info = dev_get_drvdata(&dev->dev); + +@@ -1261,8 +1261,6 @@ static int scsiback_remove(struct xenbus + gnttab_page_cache_shrink(&info->free_pages, 0); + + dev_set_drvdata(&dev->dev, NULL); +- +- return 0; + } + + static int scsiback_probe(struct xenbus_device *dev, +--- a/include/xen/xenbus.h ++++ b/include/xen/xenbus.h +@@ -117,7 +117,7 @@ struct xenbus_driver { + const struct xenbus_device_id *id); + void (*otherend_changed)(struct xenbus_device *dev, + enum xenbus_state backend_state); +- int (*remove)(struct xenbus_device *dev); ++ void (*remove)(struct xenbus_device *dev); + int (*suspend)(struct xenbus_device *dev); + int (*resume)(struct xenbus_device *dev); + int (*uevent)(struct xenbus_device *, struct kobj_uevent_env *); +--- a/net/9p/trans_xen.c ++++ b/net/9p/trans_xen.c +@@ -307,13 +307,12 @@ static void xen_9pfs_front_free(struct x + kfree(priv); + } + +-static int xen_9pfs_front_remove(struct xenbus_device *dev) ++static void xen_9pfs_front_remove(struct xenbus_device *dev) + { + struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev); + + dev_set_drvdata(&dev->dev, NULL); + xen_9pfs_front_free(priv); +- return 0; + } + + static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev, +--- a/sound/xen/xen_snd_front.c ++++ b/sound/xen/xen_snd_front.c +@@ -311,7 +311,7 @@ static int xen_drv_probe(struct xenbus_d + return xenbus_switch_state(xb_dev, XenbusStateInitialising); + } + +-static int xen_drv_remove(struct xenbus_device *dev) ++static void xen_drv_remove(struct xenbus_device *dev) + { + struct xen_snd_front_info *front_info = dev_get_drvdata(&dev->dev); + int to = 100; +@@ -345,7 +345,6 @@ static int xen_drv_remove(struct xenbus_ + + xen_snd_drv_fini(front_info); + xenbus_frontend_closed(dev); +- return 0; + } + + static const struct xenbus_device_id xen_drv_ids[] = { diff --git a/queue-6.1/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch b/queue-6.1/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch new file mode 100644 index 0000000000..287f7459c9 --- /dev/null +++ b/queue-6.1/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch @@ -0,0 +1,85 @@ +From stable+bounces-210650-greg=kroah.com@vger.kernel.org Wed Jan 21 03:21:51 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:19:53 -0500 +Subject: xfs: set max_agbno to allow sparse alloc of last full inode chunk +To: stable@vger.kernel.org +Cc: Brian Foster , "Darrick J. Wong" , Carlos Maiolino , Sasha Levin +Message-ID: <20260121021953.1128404-1-sashal@kernel.org> + +From: Brian Foster + +[ Upstream commit c360004c0160dbe345870f59f24595519008926f ] + +Sparse inode cluster allocation sets min/max agbno values to avoid +allocating an inode cluster that might map to an invalid inode +chunk. For example, we can't have an inode record mapped to agbno 0 +or that extends past the end of a runt AG of misaligned size. + +The initial calculation of max_agbno is unnecessarily conservative, +however. This has triggered a corner case allocation failure where a +small runt AG (i.e. 2063 blocks) is mostly full save for an extent +to the EOFS boundary: [2050,13]. max_agbno is set to 2048 in this +case, which happens to be the offset of the last possible valid +inode chunk in the AG. In practice, we should be able to allocate +the 4-block cluster at agbno 2052 to map to the parent inode record +at agbno 2048, but the max_agbno value precludes it. + +Note that this can result in filesystem shutdown via dirty trans +cancel on stable kernels prior to commit 9eb775968b68 ("xfs: walk +all AGs if TRYLOCK passed to xfs_alloc_vextent_iterate_ags") because +the tail AG selection by the allocator sets t_highest_agno on the +transaction. If the inode allocator spins around and finds an inode +chunk with free inodes in an earlier AG, the subsequent dir name +creation path may still fail to allocate due to the AG restriction +and cancel. + +To avoid this problem, update the max_agbno calculation to the agbno +prior to the last chunk aligned agbno in the AG. This is not +necessarily the last valid allocation target for a sparse chunk, but +since inode chunks (i.e. records) are chunk aligned and sparse +allocs are cluster sized/aligned, this allows the sb_spino_align +alignment restriction to take over and round down the max effective +agbno to within the last valid inode chunk in the AG. + +Note that even though the allocator improvements in the +aforementioned commit seem to avoid this particular dirty trans +cancel situation, the max_agbno logic improvement still applies as +we should be able to allocate from an AG that has been appropriately +selected. The more important target for this patch however are +older/stable kernels prior to this allocator rework/improvement. + +Cc: stable@vger.kernel.org # v4.2 +Fixes: 56d1115c9bc7 ("xfs: allocate sparse inode chunks on full chunk allocation failure") +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +[ xfs_ag_block_count(args.mp, pag_agno(pag)) => args.mp->m_sb.sb_agblocks ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_ialloc.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/fs/xfs/libxfs/xfs_ialloc.c ++++ b/fs/xfs/libxfs/xfs_ialloc.c +@@ -772,14 +772,15 @@ sparse_alloc: + * invalid inode records, such as records that start at agbno 0 + * or extend beyond the AG. + * +- * Set min agbno to the first aligned, non-zero agbno and max to +- * the last aligned agbno that is at least one full chunk from +- * the end of the AG. ++ * Set min agbno to the first chunk aligned, non-zero agbno and ++ * max to one less than the last chunk aligned agbno from the ++ * end of the AG. We subtract 1 from max so that the cluster ++ * allocation alignment takes over and allows allocation within ++ * the last full inode chunk in the AG. + */ + args.min_agbno = args.mp->m_sb.sb_inoalignmt; + args.max_agbno = round_down(args.mp->m_sb.sb_agblocks, +- args.mp->m_sb.sb_inoalignmt) - +- igeo->ialloc_blks; ++ args.mp->m_sb.sb_inoalignmt) - 1; + + error = xfs_alloc_vextent(&args); + if (error)