From: Greg Kroah-Hartman Date: Tue, 21 Jul 2026 09:48:49 +0000 (+0200) Subject: 7.1-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99e616e0eb7e1f030e2f34c7f123c6c478cf1b2a;p=thirdparty%2Fkernel%2Fstable-queue.git 7.1-stable patches added patches: mmc-block-fix-rpmb-device-unregister-ordering.patch mmc-mmc_test-fix-__counted_by-handling-after-kzalloc_flex-conversion.patch mmc-sdhci-esdhc-imx-disable-irq-during-suspend-to-fix-unhandled-interrupt.patch mmc-sdhci-esdhc-imx-fix-esdhc_change_pinstate-to-allow-default-state-restore.patch mmc-sdhci-esdhc-imx-fix-resume-error-handling.patch mmc-sdhci-esdhc-imx-make-non-fatal-errors-non-blocking-in-suspend.patch mmc-sdhci-esdhc-imx-remove-unnecessary-mmc_card_wake_sdio_irq-check-for-tuning-save-restore.patch mmc-sdhci-esdhc-imx-restore-dll-override-for-ddr-modes-on-resume.patch mmc-sdhci-esdhc-imx-use-pm_runtime_resume_and_get-in-suspend.patch mmc-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch mmc-vub300-defer-reset-until-cmd_mutex-is-unlocked.patch mtd-mchp23k256-use-spi-match-data-for-chip-caps.patch mtd-onenand-samsung-report-dma-completion-timeouts.patch mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch mtd-virt-concat-free-duplicate-generated-name.patch powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch powerpc-uaccess-correct-check-for-config_ppc_e500-in-mask_user_address.patch wifi-cfg80211-validate-eht-mle-before-mld-id-read.patch wifi-ieee80211-validate-mle-common-info-length.patch wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch wifi-mac80211-validate-extension-frame-layout-before-rx.patch wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch --- diff --git a/queue-7.1/mmc-block-fix-rpmb-device-unregister-ordering.patch b/queue-7.1/mmc-block-fix-rpmb-device-unregister-ordering.patch new file mode 100644 index 0000000000..184d5bb960 --- /dev/null +++ b/queue-7.1/mmc-block-fix-rpmb-device-unregister-ordering.patch @@ -0,0 +1,58 @@ +From 86152fef52cac15cd662ed3bfc7604fbfef378f0 Mon Sep 17 00:00:00 2001 +From: Ao Sun +Date: Mon, 6 Jul 2026 11:43:00 +0000 +Subject: mmc: block: fix RPMB device unregister ordering + +From: Ao Sun + +commit 86152fef52cac15cd662ed3bfc7604fbfef378f0 upstream. + +Since commit 7852028a35f0 ("mmc: block: register RPMB partition with +the RPMB subsystem"), each mmc RPMB partition is represented by two +device objects: + - the mmc-owned device (`rpmb->dev`, backing the legacy /dev/mmcblkXrpmb + char device) and + - the rpmb-core device (`rdev`, backing /dev/rpmbN). + +The child RPMB device holds a reference to its parent, so the +parent's release callback cannot be invoked if the child device +is still registered. + +Remove rpmb_dev_unregister() from the parent release handler and +unregister the child RPMB device in the remove path before tearing +down the parent device. + +Also delete the extra blank line between mmc_blk_remove_rpmb_part() +and {. + +Fixes: 7852028a35f0 ("mmc: block: register RPMB partition with the RPMB subsystem") +Cc: stable@vger.kernel.org +Signed-off-by: Jiazi Li +Signed-off-by: Ao Sun +Reviewed-by: Avri Altman +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/core/block.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -2715,7 +2715,6 @@ static void mmc_blk_rpmb_device_release( + { + struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev); + +- rpmb_dev_unregister(rpmb->rdev); + mmc_blk_put(rpmb->md); + ida_free(&mmc_rpmb_ida, rpmb->id); + kfree(rpmb); +@@ -2930,8 +2929,8 @@ out_put_device: + } + + static void mmc_blk_remove_rpmb_part(struct mmc_rpmb_data *rpmb) +- + { ++ rpmb_dev_unregister(rpmb->rdev); + cdev_device_del(&rpmb->chrdev, &rpmb->dev); + put_device(&rpmb->dev); + } diff --git a/queue-7.1/mmc-mmc_test-fix-__counted_by-handling-after-kzalloc_flex-conversion.patch b/queue-7.1/mmc-mmc_test-fix-__counted_by-handling-after-kzalloc_flex-conversion.patch new file mode 100644 index 0000000000..053d409924 --- /dev/null +++ b/queue-7.1/mmc-mmc_test-fix-__counted_by-handling-after-kzalloc_flex-conversion.patch @@ -0,0 +1,97 @@ +From c35fac6481a1dbb2d114dd337b54a40799437546 Mon Sep 17 00:00:00 2001 +From: Lad Prabhakar +Date: Tue, 2 Jun 2026 21:13:44 +0100 +Subject: mmc: mmc_test: Fix __counted_by handling after kzalloc_flex() conversion + +From: Lad Prabhakar + +commit c35fac6481a1dbb2d114dd337b54a40799437546 upstream. + +Fix logic issues introduced by the kzalloc_flex() conversion in +mmc_test_alloc_mem() due to interaction with the __counted_by +annotation on the flexible array. + +Bounds-checking sanitizers rely on the counter field reflecting the +allocated array size before any array access occurs. However, use +mem->cnt both as the allocation size and as the runtime insertion +index, causing incorrect indexing and potentially invalid bounds +tracking. + +Initialize mem->cnt to the maximum allocated number of segments +immediately after kzalloc_flex(), then use a separate local index +variable to track successfully allocated entries. Update mem->cnt to +the actual number of initialized elements before returning or entering +the cleanup path. + +Also rewrite mmc_test_free_mem() to use a forward for-loop, improving +readability and ensuring only initialized entries are freed. + +Fixes: c3126dccfd7b ("mmc: mmc_test: use kzalloc_flex") +Signed-off-by: Lad Prabhakar +Reviewed-by: Geert Uytterhoeven +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/core/mmc_test.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c +index ab38e4c45a8d..4dc16649e61d 100644 +--- a/drivers/mmc/core/mmc_test.c ++++ b/drivers/mmc/core/mmc_test.c +@@ -318,9 +318,9 @@ static void mmc_test_free_mem(struct mmc_test_mem *mem) + { + if (!mem) + return; +- while (mem->cnt--) +- __free_pages(mem->arr[mem->cnt].page, +- mem->arr[mem->cnt].order); ++ for (unsigned int i = 0; i < mem->cnt; i++) ++ __free_pages(mem->arr[i].page, ++ mem->arr[i].order); + kfree(mem); + } + +@@ -341,6 +341,7 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz, + unsigned long page_cnt = 0; + unsigned long limit = nr_free_buffer_pages() >> 4; + struct mmc_test_mem *mem; ++ unsigned int idx = 0; + + if (max_page_cnt > limit) + max_page_cnt = limit; +@@ -375,23 +376,26 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz, + goto out_free; + break; + } +- mem->arr[mem->cnt].page = page; +- mem->arr[mem->cnt].order = order; +- mem->cnt += 1; ++ mem->arr[idx].page = page; ++ mem->arr[idx].order = order; ++ idx += 1; + if (max_page_cnt <= (1UL << order)) + break; + max_page_cnt -= 1UL << order; + page_cnt += 1UL << order; +- if (mem->cnt >= max_segs) { ++ if (idx >= mem->cnt) { + if (page_cnt < min_page_cnt) + goto out_free; + break; + } + } + ++ mem->cnt = idx; ++ + return mem; + + out_free: ++ mem->cnt = idx; + mmc_test_free_mem(mem); + return NULL; + } +-- +2.55.0 + diff --git a/queue-7.1/mmc-sdhci-esdhc-imx-disable-irq-during-suspend-to-fix-unhandled-interrupt.patch b/queue-7.1/mmc-sdhci-esdhc-imx-disable-irq-during-suspend-to-fix-unhandled-interrupt.patch new file mode 100644 index 0000000000..65e10b47db --- /dev/null +++ b/queue-7.1/mmc-sdhci-esdhc-imx-disable-irq-during-suspend-to-fix-unhandled-interrupt.patch @@ -0,0 +1,67 @@ +From 9d87eaf985cef9581b6ed99b461b38e8cd666480 Mon Sep 17 00:00:00 2001 +From: Luke Wang +Date: Wed, 15 Jul 2026 15:18:15 +0800 +Subject: mmc: sdhci-esdhc-imx: disable irq during suspend to fix unhandled interrupt + +From: Luke Wang + +commit 9d87eaf985cef9581b6ed99b461b38e8cd666480 upstream. + +When using WIFI out-of-band wakeup, an "irq xxx: nobody cared" warning +occurs. This happens because the usdhc interrupt is not disabled during +system suspend when device_may_wakeup() returns false. + +The sequence of events leading to this issue: +1. System enters suspend without disabling usdhc interrupt +(because device_may_wakeup() returns false for usdhc device) +2. WIFI out-of-band wakeup triggers system resume via GPIO interrupt +3. WIFI sends a Card interrupt before usdhc has fully resumed +4. usdhc is still in runtime suspend state and cannot handle the +interrupt properly +5. The unhandled interrupt triggers "nobody cared" warning + +Fix this by unconditionally disabling the usdhc interrupt during suspend +and re-enabling it during resume, regardless of the wakeup capability. +This ensures no interrupts are processed during the suspend/resume +transition. + +Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic") +Acked-by: Adrian Hunter +Reviewed-by: Haibo Chen +Signed-off-by: Luke Wang +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-esdhc-imx.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -2077,9 +2077,10 @@ static int sdhci_esdhc_suspend(struct de + if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data)) + sdhc_esdhc_tuning_save(host); + ++ /* The irqs of imx are not shared. It is safe to disable */ ++ disable_irq(host->irq); ++ + if (device_may_wakeup(dev)) { +- /* The irqs of imx are not shared. It is safe to disable */ +- disable_irq(host->irq); + ret = sdhci_enable_irq_wakeups(host); + if (!ret) + dev_warn(dev, "Failed to enable irq wakeup\n"); +@@ -2130,10 +2131,10 @@ static int sdhci_esdhc_resume(struct dev + /* re-initialize hw state in case it's lost in low power mode */ + sdhci_esdhc_imx_hwinit(host); + +- if (host->irq_wake_enabled) { ++ if (host->irq_wake_enabled) + sdhci_disable_irq_wakeups(host); +- enable_irq(host->irq); +- } ++ ++ enable_irq(host->irq); + + /* + * restore the saved tuning delay value for the device which keep diff --git a/queue-7.1/mmc-sdhci-esdhc-imx-fix-esdhc_change_pinstate-to-allow-default-state-restore.patch b/queue-7.1/mmc-sdhci-esdhc-imx-fix-esdhc_change_pinstate-to-allow-default-state-restore.patch new file mode 100644 index 0000000000..2f1330f948 --- /dev/null +++ b/queue-7.1/mmc-sdhci-esdhc-imx-fix-esdhc_change_pinstate-to-allow-default-state-restore.patch @@ -0,0 +1,56 @@ +From 5adc14cd4b905629d5b9163b3a416dcab24c7ce2 Mon Sep 17 00:00:00 2001 +From: Luke Wang +Date: Wed, 15 Jul 2026 15:18:13 +0800 +Subject: mmc: sdhci-esdhc-imx: fix esdhc_change_pinstate() to allow default state restore + +From: Luke Wang + +commit 5adc14cd4b905629d5b9163b3a416dcab24c7ce2 upstream. + +esdhc_change_pinstate() checks for pins_100mhz and pins_200mhz at the +top of the function and returns -EINVAL if either is not defined. This +prevents the default case from ever being reached, which means devices +with a sleep pinctrl state but without high-speed pin states (100mhz/ +200mhz) can never restore their default pin configuration. + +Move the IS_ERR checks for pins_100mhz and pins_200mhz into their +respective switch cases. + +Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic") +Acked-by: Adrian Hunter +Reviewed-by: Frank Li +Signed-off-by: Luke Wang +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-esdhc-imx.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -1326,19 +1326,21 @@ static int esdhc_change_pinstate(struct + + dev_dbg(mmc_dev(host->mmc), "change pinctrl state for uhs %d\n", uhs); + +- if (IS_ERR(imx_data->pinctrl) || +- IS_ERR(imx_data->pins_100mhz) || +- IS_ERR(imx_data->pins_200mhz)) ++ if (IS_ERR(imx_data->pinctrl)) + return -EINVAL; + + switch (uhs) { + case MMC_TIMING_UHS_SDR50: + case MMC_TIMING_UHS_DDR50: ++ if (IS_ERR(imx_data->pins_100mhz)) ++ return -EINVAL; + pinctrl = imx_data->pins_100mhz; + break; + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_MMC_HS200: + case MMC_TIMING_MMC_HS400: ++ if (IS_ERR(imx_data->pins_200mhz)) ++ return -EINVAL; + pinctrl = imx_data->pins_200mhz; + break; + default: diff --git a/queue-7.1/mmc-sdhci-esdhc-imx-fix-resume-error-handling.patch b/queue-7.1/mmc-sdhci-esdhc-imx-fix-resume-error-handling.patch new file mode 100644 index 0000000000..95400218f7 --- /dev/null +++ b/queue-7.1/mmc-sdhci-esdhc-imx-fix-resume-error-handling.patch @@ -0,0 +1,63 @@ +From e27c946b589c53520409a0956b33d52ef7a0898f Mon Sep 17 00:00:00 2001 +From: Luke Wang +Date: Wed, 15 Jul 2026 15:18:18 +0800 +Subject: mmc: sdhci-esdhc-imx: fix resume error handling + +From: Luke Wang + +commit e27c946b589c53520409a0956b33d52ef7a0898f upstream. + +Check pm_runtime_force_resume() return value in resume. If it fails +(clock enable failure), return immediately since accessing hardware +registers on an unclocked device would cause a kernel panic. + +The early return intentionally skips enable_irq() and +sdhci_disable_irq_wakeups() because the IRQ handler reads +SDHCI_INT_STATUS, which would also fault without clocks. The PM runtime +usage counter leak only affects this already-broken device instance and +is an acceptable tradeoff to preserve system stability. + +Remove the return value check for mmc_gpio_set_cd_wake(host->mmc, false) +since disable_irq_wake() called internally always returns 0. + +Also return 0 explicitly on the success path instead of propagating +stale return values. + +Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic") +Acked-by: Adrian Hunter +Reviewed-by: Frank Li +Signed-off-by: Luke Wang +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-esdhc-imx.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -2123,12 +2123,12 @@ static int sdhci_esdhc_resume(struct dev + dev_warn(dev, "Failed to restore pinctrl state\n"); + } + +- pm_runtime_force_resume(dev); +- +- ret = mmc_gpio_set_cd_wake(host->mmc, false); ++ ret = pm_runtime_force_resume(dev); + if (ret) + return ret; + ++ mmc_gpio_set_cd_wake(host->mmc, false); ++ + /* re-initialize hw state in case it's lost in low power mode */ + sdhci_esdhc_imx_hwinit(host); + +@@ -2155,7 +2155,7 @@ static int sdhci_esdhc_resume(struct dev + + pm_runtime_put_autosuspend(dev); + +- return ret; ++ return 0; + } + + static int sdhci_esdhc_runtime_suspend(struct device *dev) diff --git a/queue-7.1/mmc-sdhci-esdhc-imx-make-non-fatal-errors-non-blocking-in-suspend.patch b/queue-7.1/mmc-sdhci-esdhc-imx-make-non-fatal-errors-non-blocking-in-suspend.patch new file mode 100644 index 0000000000..c2df4125f6 --- /dev/null +++ b/queue-7.1/mmc-sdhci-esdhc-imx-make-non-fatal-errors-non-blocking-in-suspend.patch @@ -0,0 +1,65 @@ +From 6aa00a43bbd3d994558a55586351757cebbff236 Mon Sep 17 00:00:00 2001 +From: Luke Wang +Date: Wed, 15 Jul 2026 15:18:17 +0800 +Subject: mmc: sdhci-esdhc-imx: make non-fatal errors non-blocking in suspend + +From: Luke Wang + +commit 6aa00a43bbd3d994558a55586351757cebbff236 upstream. + +Make pinctrl_pm_select_sleep_state() and mmc_gpio_set_cd_wake() failures +non-fatal in the suspend path. These failures only mean slightly higher +power consumption or missing CD wakeup capability, but should not block +system suspend. + +Also change the function to always return 0 on the success path instead +of propagating non-fatal warning return values. + +Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic") +Acked-by: Adrian Hunter +Signed-off-by: Luke Wang +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-esdhc-imx.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -2083,8 +2083,7 @@ static int sdhci_esdhc_suspend(struct de + disable_irq(host->irq); + + if (device_may_wakeup(dev)) { +- ret = sdhci_enable_irq_wakeups(host); +- if (!ret) ++ if (!sdhci_enable_irq_wakeups(host)) + dev_warn(dev, "Failed to enable irq wakeup\n"); + } else { + /* +@@ -2095,12 +2094,12 @@ static int sdhci_esdhc_suspend(struct de + * other function like GPIO function to save power in PM, + * which finally block the SDIO wakeup function. + */ +- ret = pinctrl_pm_select_sleep_state(dev); +- if (ret) +- return ret; ++ if (pinctrl_pm_select_sleep_state(dev)) ++ dev_warn(dev, "Failed to select sleep pinctrl state\n"); + } + +- ret = mmc_gpio_set_cd_wake(host->mmc, true); ++ if (mmc_gpio_set_cd_wake(host->mmc, true)) ++ dev_warn(dev, "Failed to enable cd wake\n"); + + /* + * Make sure invoke runtime_suspend to gate off clock. +@@ -2108,7 +2107,7 @@ static int sdhci_esdhc_suspend(struct de + */ + pm_runtime_force_suspend(dev); + +- return ret; ++ return 0; + } + + static int sdhci_esdhc_resume(struct device *dev) diff --git a/queue-7.1/mmc-sdhci-esdhc-imx-remove-unnecessary-mmc_card_wake_sdio_irq-check-for-tuning-save-restore.patch b/queue-7.1/mmc-sdhci-esdhc-imx-remove-unnecessary-mmc_card_wake_sdio_irq-check-for-tuning-save-restore.patch new file mode 100644 index 0000000000..5ad7c2b912 --- /dev/null +++ b/queue-7.1/mmc-sdhci-esdhc-imx-remove-unnecessary-mmc_card_wake_sdio_irq-check-for-tuning-save-restore.patch @@ -0,0 +1,55 @@ +From 899160e2774d9952e9f2770b38f701ff1906c0b2 Mon Sep 17 00:00:00 2001 +From: Luke Wang +Date: Wed, 15 Jul 2026 15:18:11 +0800 +Subject: mmc: sdhci-esdhc-imx: remove unnecessary mmc_card_wake_sdio_irq check for tuning save/restore + +From: Luke Wang + +commit 899160e2774d9952e9f2770b38f701ff1906c0b2 upstream. + +The tuning save/restore during system PM is conditioned on +mmc_card_wake_sdio_irq(), but this check is unrelated to whether +tuning values need to be preserved. The actual requirement is that +the card keeps power during suspend and the controller is a uSDHC. + +SDIO devices using out-of-band GPIO wakeup maintain power during +suspend but do not set the SDIO IRQ wake flag. In this case the +tuning delay values are not saved/restored. + +Remove the unnecessary mmc_card_wake_sdio_irq() condition from both +the suspend save and resume restore paths. + +Fixes: c63d25cdc59a ("mmc: sdhci-esdhc-imx: Save tuning value when card stays powered in suspend") +Acked-by: Adrian Hunter +Reviewed-by: Frank Li +Reviewed-by: Haibo Chen +Signed-off-by: Luke Wang +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-esdhc-imx.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -2064,8 +2064,7 @@ static int sdhci_esdhc_suspend(struct de + * to save the tuning delay value just in case the usdhc + * lost power during system PM. + */ +- if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) && +- esdhc_is_usdhc(imx_data)) ++ if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data)) + sdhc_esdhc_tuning_save(host); + + if (device_may_wakeup(dev)) { +@@ -2130,8 +2129,7 @@ static int sdhci_esdhc_resume(struct dev + * restore the saved tuning delay value for the device which keep + * power during system PM. + */ +- if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) && +- esdhc_is_usdhc(imx_data)) ++ if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data)) + sdhc_esdhc_tuning_restore(host); + + pm_runtime_put_autosuspend(dev); diff --git a/queue-7.1/mmc-sdhci-esdhc-imx-restore-dll-override-for-ddr-modes-on-resume.patch b/queue-7.1/mmc-sdhci-esdhc-imx-restore-dll-override-for-ddr-modes-on-resume.patch new file mode 100644 index 0000000000..95ebb4c0da --- /dev/null +++ b/queue-7.1/mmc-sdhci-esdhc-imx-restore-dll-override-for-ddr-modes-on-resume.patch @@ -0,0 +1,101 @@ +From 2439becd91bad6883b135044f85f83a0538b96a6 Mon Sep 17 00:00:00 2001 +From: Luke Wang +Date: Wed, 15 Jul 2026 15:18:12 +0800 +Subject: mmc: sdhci-esdhc-imx: restore DLL override for DDR modes on resume + +From: Luke Wang + +commit 2439becd91bad6883b135044f85f83a0538b96a6 upstream. + +sdhci_esdhc_imx_hwinit() unconditionally clears ESDHC_DLL_CTRL by +writing zero. For SDIO devices that keep power during system suspend +and operate in DDR mode, the card remains in DDR timing while the host +DLL override configuration is lost. + +Extract the DLL override setup from esdhc_set_uhs_signaling() into +a helper esdhc_set_dll_override(), and call it on the resume path +when the card kept power and is using a DDR timing mode. + +Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic") +Acked-by: Adrian Hunter +Reviewed-by: Frank Li +Reviewed-by: Haibo Chen +Signed-off-by: Luke Wang +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-esdhc-imx.c | 39 ++++++++++++++++++++++++++----------- + 1 file changed, 28 insertions(+), 11 deletions(-) + +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -1349,6 +1349,23 @@ static int esdhc_change_pinstate(struct + return pinctrl_select_state(imx_data->pinctrl, pinctrl); + } + ++static void esdhc_set_dll_override(struct sdhci_host *host) ++{ ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); ++ struct esdhc_platform_data *boarddata = &imx_data->boarddata; ++ u32 v; ++ ++ if (!boarddata->delay_line) ++ return; ++ ++ v = boarddata->delay_line << ESDHC_DLL_OVERRIDE_VAL_SHIFT | ++ (1 << ESDHC_DLL_OVERRIDE_EN_SHIFT); ++ if (is_imx53_esdhc(imx_data)) ++ v <<= 1; ++ writel(v, host->ioaddr + ESDHC_DLL_CTRL); ++} ++ + /* + * For HS400 eMMC, there is a data_strobe line. This signal is generated + * by the device and used for data output and CRC status response output +@@ -1404,7 +1421,6 @@ static void esdhc_set_uhs_signaling(stru + u32 m; + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); +- struct esdhc_platform_data *boarddata = &imx_data->boarddata; + + /* disable ddr mode and disable HS400 mode */ + m = readl(host->ioaddr + ESDHC_MIX_CTRL); +@@ -1425,15 +1441,7 @@ static void esdhc_set_uhs_signaling(stru + m |= ESDHC_MIX_CTRL_DDREN; + writel(m, host->ioaddr + ESDHC_MIX_CTRL); + imx_data->is_ddr = 1; +- if (boarddata->delay_line) { +- u32 v; +- v = boarddata->delay_line << +- ESDHC_DLL_OVERRIDE_VAL_SHIFT | +- (1 << ESDHC_DLL_OVERRIDE_EN_SHIFT); +- if (is_imx53_esdhc(imx_data)) +- v <<= 1; +- writel(v, host->ioaddr + ESDHC_DLL_CTRL); +- } ++ esdhc_set_dll_override(host); + break; + case MMC_TIMING_MMC_HS400: + m |= ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN; +@@ -2129,9 +2137,18 @@ static int sdhci_esdhc_resume(struct dev + * restore the saved tuning delay value for the device which keep + * power during system PM. + */ +- if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data)) ++ if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data)) { + sdhc_esdhc_tuning_restore(host); + ++ /* ++ * Restore DLL override for DDR modes. hwinit unconditionally ++ * clears ESDHC_DLL_CTRL, but the card is still in DDR mode. ++ */ ++ if (host->timing == MMC_TIMING_UHS_DDR50 || ++ host->timing == MMC_TIMING_MMC_DDR52) ++ esdhc_set_dll_override(host); ++ } ++ + pm_runtime_put_autosuspend(dev); + + return ret; diff --git a/queue-7.1/mmc-sdhci-esdhc-imx-use-pm_runtime_resume_and_get-in-suspend.patch b/queue-7.1/mmc-sdhci-esdhc-imx-use-pm_runtime_resume_and_get-in-suspend.patch new file mode 100644 index 0000000000..eb56960626 --- /dev/null +++ b/queue-7.1/mmc-sdhci-esdhc-imx-use-pm_runtime_resume_and_get-in-suspend.patch @@ -0,0 +1,39 @@ +From 8da5930144712412d85e7f868693d96ec5c2018c Mon Sep 17 00:00:00 2001 +From: Luke Wang +Date: Wed, 15 Jul 2026 15:18:16 +0800 +Subject: mmc: sdhci-esdhc-imx: use pm_runtime_resume_and_get() in suspend + +From: Luke Wang + +commit 8da5930144712412d85e7f868693d96ec5c2018c upstream. + +Replace pm_runtime_get_sync() with pm_runtime_resume_and_get() to +simplify error handling. pm_runtime_resume_and_get() automatically +drops the usage counter on failure, avoiding the need for a separate +pm_runtime_put_noidle() call. If it fails, the device is unclocked and +accessing hardware registers would cause a kernel panic, so return the +error immediately. + +Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic") +Acked-by: Adrian Hunter +Signed-off-by: Luke Wang +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-esdhc-imx.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -2061,7 +2061,9 @@ static int sdhci_esdhc_suspend(struct de + * 2, make sure the pm_runtime_force_resume() in sdhci_esdhc_resume() really + * invoke its ->runtime_resume callback (needs_force_resume = 1). + */ +- pm_runtime_get_sync(dev); ++ ret = pm_runtime_resume_and_get(dev); ++ if (ret) ++ return ret; + + if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) && + (host->tuning_mode != SDHCI_TUNING_MODE_1)) { diff --git a/queue-7.1/mmc-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch b/queue-7.1/mmc-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch new file mode 100644 index 0000000000..055891f2f3 --- /dev/null +++ b/queue-7.1/mmc-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch @@ -0,0 +1,77 @@ +From 521f39ca93cc43ce1b3eae8d44201f8f55dd9151 Mon Sep 17 00:00:00 2001 +From: Sergey Shtylyov +Date: Mon, 1 Jun 2026 17:49:01 +0300 +Subject: mmc: sdhci-of-dwcmshc: check bus clock enable result in the probe() method + +From: Sergey Shtylyov + +commit 521f39ca93cc43ce1b3eae8d44201f8f55dd9151 upstream. + +In the driver's probe() method, clk_disable_unprepare() for the bus clock +is called on the error path even if the prior clk_prepare_enable() call has +failed (and the same thing happens in the remove() method as well) -- that +would cause the prepare/enable counter imbalance. Also, the same problem +can happen in the driver's suspend() method; note that the resume() method +does check the clk_prepare_enable()'s result -- let's be consistent and do +that in probe() method as well. BTW, I don't know for sure what does the +bus clock control -- if it affects the register accesses, the driver will +likely cause (e.g. on ARM) a kernel oops if it fails to prepare/enable the +bus clock in the probe() method... + +Found by Linux Verification Center (linuxtesting.org) with the Svace static +analysis tool. + +Fixes: e438cf49b305 ("mmc: sdhci-of-dwcmshc: add SDHCI OF Synopsys DWC MSHC driver") +Fixes: bccce2ec7790 ("mmc: sdhci-of-dwcmshc: add suspend/resume support") +Signed-off-by: Sergey Shtylyov +Acked-by: Adrian Hunter +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-of-dwcmshc.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -2441,13 +2441,16 @@ static int dwcmshc_probe(struct platform + return err; + + priv->bus_clk = devm_clk_get(dev, "bus"); +- if (!IS_ERR(priv->bus_clk)) +- clk_prepare_enable(priv->bus_clk); ++ if (!IS_ERR(priv->bus_clk)) { ++ err = clk_prepare_enable(priv->bus_clk); ++ if (err) ++ goto err_clk; ++ } + } + + err = mmc_of_parse(host->mmc); + if (err) +- goto err_clk; ++ goto err_bus_clk; + + sdhci_get_of_property(pdev); + +@@ -2461,7 +2464,7 @@ static int dwcmshc_probe(struct platform + if (pltfm_data->init) { + err = pltfm_data->init(&pdev->dev, host, priv); + if (err) +- goto err_clk; ++ goto err_bus_clk; + } + + #ifdef CONFIG_ACPI +@@ -2507,9 +2510,10 @@ err_setup_host: + err_rpm: + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); ++err_bus_clk: ++ clk_disable_unprepare(priv->bus_clk); + err_clk: + clk_disable_unprepare(pltfm_host->clk); +- clk_disable_unprepare(priv->bus_clk); + clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); + return err; + } diff --git a/queue-7.1/mmc-vub300-defer-reset-until-cmd_mutex-is-unlocked.patch b/queue-7.1/mmc-vub300-defer-reset-until-cmd_mutex-is-unlocked.patch new file mode 100644 index 0000000000..f1f4a973d5 --- /dev/null +++ b/queue-7.1/mmc-vub300-defer-reset-until-cmd_mutex-is-unlocked.patch @@ -0,0 +1,126 @@ +From ee5fb641c4ccac8406c668d3e947eb20ce44f233 Mon Sep 17 00:00:00 2001 +From: Runyu Xiao +Date: Wed, 17 Jun 2026 23:23:19 +0800 +Subject: mmc: vub300: defer reset until cmd_mutex is unlocked + +From: Runyu Xiao + +commit ee5fb641c4ccac8406c668d3e947eb20ce44f233 upstream. + +vub300_cmndwork_thread() holds cmd_mutex while it sends a command and +waits for the command response. If the response wait times out, +__vub300_command_response() kills the command URBs and then synchronously +resets the USB device through usb_reset_device(). + +That reset path re-enters the driver through vub300_pre_reset(), which +also takes cmd_mutex. The worker therefore tries to acquire the same +mutex recursively while it is still holding it from the command path. + +This issue was found by our static analysis tool and then manually +reviewed against the current tree. + +The grounded PoC kept the real worker and timeout/reset carrier: + + vub300_cmndwork_thread() + __vub300_command_response() + usb_lock_device_for_reset() + usb_reset_device() + vub300_pre_reset() + +Lockdep reported the same-task recursive acquisition on cmd_mutex: + + WARNING: possible recursive locking detected + ... (&test_vub300.cmd_mutex) ... at: usb_reset_device... [vuln_msv] + ... (&test_vub300.cmd_mutex) ... at: vub300_cmndwork_thread+0x12/0x20 [vuln_msv] + Workqueue: vub300_cmd_wq vub300_cmndwork_thread [vuln_msv] + *** DEADLOCK *** + +Return a flag from __vub300_command_response() when the timeout path needs +a device reset, then perform the reset after vub300_cmndwork_thread() has +cleared the in-flight command state and dropped cmd_mutex. The reset is +still attempted before mmc_request_done(), preserving the existing request +completion ordering while avoiding the recursive lock. + +Fixes: 88095e7b473a ("mmc: Add new VUB300 USB-to-SD/SDIO/MMC driver") +Cc: stable@vger.kernel.org +Signed-off-by: Runyu Xiao +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/vub300.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +--- a/drivers/mmc/host/vub300.c ++++ b/drivers/mmc/host/vub300.c +@@ -1586,7 +1586,7 @@ static int __command_write_data(struct v + return linear_length; + } + +-static void __vub300_command_response(struct vub300_mmc_host *vub300, ++static bool __vub300_command_response(struct vub300_mmc_host *vub300, + struct mmc_command *cmd, + struct mmc_data *data, int data_length) + { +@@ -1598,17 +1598,11 @@ static void __vub300_command_response(st + msecs_to_jiffies(msec_timeout)); + if (respretval == 0) { /* TIMED OUT */ + /* we don't know which of "out" and "res" if any failed */ +- int result; + vub300->usb_timed_out = 1; + usb_kill_urb(vub300->command_out_urb); + usb_kill_urb(vub300->command_res_urb); + cmd->error = -ETIMEDOUT; +- result = usb_lock_device_for_reset(vub300->udev, +- vub300->interface); +- if (result == 0) { +- result = usb_reset_device(vub300->udev); +- usb_unlock_device(vub300->udev); +- } ++ return true; + } else if (respretval < 0) { + /* we don't know which of "out" and "res" if any failed */ + usb_kill_urb(vub300->command_out_urb); +@@ -1704,6 +1698,8 @@ static void __vub300_command_response(st + } else { + cmd->error = -EINVAL; + } ++ ++ return false; + } + + static void construct_request_response(struct vub300_mmc_host *vub300, +@@ -1749,6 +1745,7 @@ static void vub300_cmndwork_thread(struc + struct mmc_request *req = vub300->req; + struct mmc_command *cmd = vub300->cmd; + struct mmc_data *data = vub300->data; ++ bool reset_device; + int data_length; + mutex_lock(&vub300->cmd_mutex); + init_completion(&vub300->command_complete); +@@ -1771,7 +1768,8 @@ static void vub300_cmndwork_thread(struc + data_length = __command_read_data(vub300, cmd, data); + else + data_length = __command_write_data(vub300, cmd, data); +- __vub300_command_response(vub300, cmd, data, data_length); ++ reset_device = __vub300_command_response(vub300, cmd, ++ data, data_length); + vub300->req = NULL; + vub300->cmd = NULL; + vub300->data = NULL; +@@ -1779,6 +1777,16 @@ static void vub300_cmndwork_thread(struc + if (cmd->error == -ENOMEDIUM) + check_vub300_port_status(vub300); + mutex_unlock(&vub300->cmd_mutex); ++ if (reset_device) { ++ int result; ++ ++ result = usb_lock_device_for_reset(vub300->udev, ++ vub300->interface); ++ if (result == 0) { ++ result = usb_reset_device(vub300->udev); ++ usb_unlock_device(vub300->udev); ++ } ++ } + mmc_request_done(vub300->mmc, req); + kref_put(&vub300->kref, vub300_delete); + return; diff --git a/queue-7.1/mtd-mchp23k256-use-spi-match-data-for-chip-caps.patch b/queue-7.1/mtd-mchp23k256-use-spi-match-data-for-chip-caps.patch new file mode 100644 index 0000000000..cd2cfa4fdf --- /dev/null +++ b/queue-7.1/mtd-mchp23k256-use-spi-match-data-for-chip-caps.patch @@ -0,0 +1,38 @@ +From d322e40f4edf92bf0ca329e5aa4ae1c0316feb38 Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Fri, 3 Jul 2026 15:40:52 +0800 +Subject: mtd: mchp23k256: use SPI match data for chip caps + +From: Pengpeng Hou + +commit d322e40f4edf92bf0ca329e5aa4ae1c0316feb38 upstream. + +The driver stores chip capacity information in both the OF match table +and the SPI id table. Probe currently uses of_device_get_match_data(), +so a non-OF SPI modalias match falls back to mchp23k256_caps even when +the SPI id table selected a different part. + +Use spi_get_device_match_data() so SPI id-table driver_data is consumed +when OF match data is absent. This keeps the existing default fallback +while avoiding the wrong MTD geometry for id-table-only matches. + +Fixes: 4379075a870b ("mtd: mchp23k256: Add support for mchp23lcv1024") +Cc: stable@vger.kernel.org +Signed-off-by: Pengpeng Hou +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/devices/mchp23k256.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mtd/devices/mchp23k256.c ++++ b/drivers/mtd/devices/mchp23k256.c +@@ -188,7 +188,7 @@ static int mchp23k256_probe(struct spi_d + + data = dev_get_platdata(&spi->dev); + +- flash->caps = of_device_get_match_data(&spi->dev); ++ flash->caps = spi_get_device_match_data(spi); + if (!flash->caps) + flash->caps = &mchp23k256_caps; + diff --git a/queue-7.1/mtd-onenand-samsung-report-dma-completion-timeouts.patch b/queue-7.1/mtd-onenand-samsung-report-dma-completion-timeouts.patch new file mode 100644 index 0000000000..94652beb0f --- /dev/null +++ b/queue-7.1/mtd-onenand-samsung-report-dma-completion-timeouts.patch @@ -0,0 +1,49 @@ +From d03a19bd6c7f86b99ca8fb61a6ec2345cee1d9d6 Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Fri, 3 Jul 2026 15:43:50 +0800 +Subject: mtd: onenand: samsung: report DMA completion timeouts + +From: Pengpeng Hou + +commit d03a19bd6c7f86b99ca8fb61a6ec2345cee1d9d6 upstream. + +The S5PC110 OneNAND DMA helpers have bounded waits for transfer +completion. The polling helper falls out of its timeout loop and returns +success, and the IRQ helper ignores wait_for_completion_timeout(). + +Return -ETIMEDOUT when the DMA transfer-done bit or completion does not +arrive before the timeout so callers can treat the buffer transfer as +failed. + +Fixes: e23abf4b7743 ("mtd: OneNAND: S5PC110: Implement DMA interrupt method") +Cc: stable@vger.kernel.org +Signed-off-by: Pengpeng Hou +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/onenand/onenand_samsung.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/nand/onenand/onenand_samsung.c ++++ b/drivers/mtd/nand/onenand/onenand_samsung.c +@@ -554,6 +554,9 @@ static int s5pc110_dma_poll(dma_addr_t d + } while (!(status & S5PC110_DMA_TRANS_STATUS_TD) && + time_before(jiffies, timeout)); + ++ if (!(status & S5PC110_DMA_TRANS_STATUS_TD)) ++ return -ETIMEDOUT; ++ + writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD); + + return 0; +@@ -608,7 +611,9 @@ static int s5pc110_dma_irq(dma_addr_t ds + + writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD); + +- wait_for_completion_timeout(&onenand->complete, msecs_to_jiffies(20)); ++ if (!wait_for_completion_timeout(&onenand->complete, ++ msecs_to_jiffies(20))) ++ return -ETIMEDOUT; + + return 0; + } diff --git a/queue-7.1/mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch b/queue-7.1/mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch new file mode 100644 index 0000000000..1a02047e03 --- /dev/null +++ b/queue-7.1/mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch @@ -0,0 +1,46 @@ +From f9a13e05a327080c3a1c8165adf9e678fb68fef2 Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Fri, 3 Jul 2026 15:42:33 +0800 +Subject: mtd: rawnand: fsl_ifc: return errors for failed page reads + +From: Pengpeng Hou + +commit f9a13e05a327080c3a1c8165adf9e678fb68fef2 upstream. + +fsl_ifc_run_command() logs controller timeout and other non-OPC +completion states in ctrl->nand_stat. fsl_ifc_read_page() then only +increments the ECC failure counter for non-OPC status and still returns +max_bitflips, which can be zero. + +Return -ETIMEDOUT when the command did not complete at all and -EIO for +other non-OPC read completions so the NAND core does not treat a failed +page read as a clean page. + +Fixes: 82771882d960 ("NAND Machine support for Integrated Flash Controller") +Cc: stable@vger.kernel.org +Signed-off-by: Pengpeng Hou +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/fsl_ifc_nand.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c ++++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c +@@ -684,8 +684,15 @@ static int fsl_ifc_read_page(struct nand + return check_erased_page(chip, buf); + } + +- if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) ++ if (!ctrl->nand_stat) { + mtd->ecc_stats.failed++; ++ return -ETIMEDOUT; ++ } ++ ++ if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) { ++ mtd->ecc_stats.failed++; ++ return -EIO; ++ } + + return nctrl->max_bitflips; + } diff --git a/queue-7.1/mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch b/queue-7.1/mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch new file mode 100644 index 0000000000..ecaf399f73 --- /dev/null +++ b/queue-7.1/mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch @@ -0,0 +1,74 @@ +From dbf590b662695b16fbf5917ef129697be4410ea9 Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Fri, 3 Jul 2026 15:37:59 +0800 +Subject: mtd: rawnand: lpc32xx_mlc: fail DMA transfers on timeout + +From: Pengpeng Hou + +commit dbf590b662695b16fbf5917ef129697be4410ea9 upstream. + +lpc32xx_xmit_dma() starts a DMA transfer and waits up to one second +for its completion, but it ignores the wait result and returns success +after unmapping the buffer. + +A timed out read can therefore return success with incomplete data, and +a timed out write can continue the NAND operation without proof that the +DMA payload reached the controller. + +Terminate the DMA channel on timeout, unmap the scatterlist through the +existing cleanup path, and return -ETIMEDOUT to the NAND read/write +callers. Initialize the shared cleanup-path result before using it for +dmaengine_prep_slave_sg() failures. + +Fixes: 70f7cb78ec53 ("mtd: add LPC32xx MLC NAND driver") +Cc: stable@vger.kernel.org +Reviewed-by: Vladimir Zapolskiy +Signed-off-by: Pengpeng Hou +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/lpc32xx_mlc.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/nand/raw/lpc32xx_mlc.c ++++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c +@@ -396,6 +396,7 @@ static int lpc32xx_xmit_dma(struct mtd_i + struct lpc32xx_nand_host *host = nand_get_controller_data(chip); + struct dma_async_tx_descriptor *desc; + int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; ++ unsigned long time_left; + int res; + + sg_init_one(&host->sgl, mem, len); +@@ -410,6 +411,7 @@ static int lpc32xx_xmit_dma(struct mtd_i + flags); + if (!desc) { + dev_err(mtd->dev.parent, "Failed to prepare slave sg\n"); ++ res = -ENXIO; + goto out1; + } + +@@ -420,7 +422,13 @@ static int lpc32xx_xmit_dma(struct mtd_i + dmaengine_submit(desc); + dma_async_issue_pending(host->dma_chan); + +- wait_for_completion_timeout(&host->comp_dma, msecs_to_jiffies(1000)); ++ time_left = wait_for_completion_timeout(&host->comp_dma, ++ msecs_to_jiffies(1000)); ++ if (!time_left) { ++ dmaengine_terminate_sync(host->dma_chan); ++ res = -ETIMEDOUT; ++ goto out1; ++ } + + dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1, + DMA_BIDIRECTIONAL); +@@ -428,7 +436,7 @@ static int lpc32xx_xmit_dma(struct mtd_i + out1: + dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1, + DMA_BIDIRECTIONAL); +- return -ENXIO; ++ return res; + } + + static int lpc32xx_read_page(struct nand_chip *chip, uint8_t *buf, diff --git a/queue-7.1/mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch b/queue-7.1/mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch new file mode 100644 index 0000000000..4728ae57b3 --- /dev/null +++ b/queue-7.1/mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch @@ -0,0 +1,59 @@ +From 17a8ce84964f243c8f89dc7353ac7e8d3137bc74 Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Fri, 3 Jul 2026 15:39:43 +0800 +Subject: mtd: rawnand: lpc32xx_slc: fail DMA transfer on completion timeout + +From: Pengpeng Hou + +commit 17a8ce84964f243c8f89dc7353ac7e8d3137bc74 upstream. + +lpc32xx_xmit_dma() waits for the DMA completion callback but ignores +wait_for_completion_timeout(). A timed out DMA transfer is therefore +unmapped and reported as successful to the NAND read/write path. + +Return -ETIMEDOUT when the completion wait expires. Terminate the DMA +channel before unmapping the scatterlist so the timed out transfer cannot +continue to access the buffer after the error is returned. + +Fixes: 2944a44da09e ("mtd: add LPC32xx SLC NAND driver") +Cc: stable@vger.kernel.org +Reviewed-by: Vladimir Zapolskiy +Signed-off-by: Pengpeng Hou +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/lpc32xx_slc.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/nand/raw/lpc32xx_slc.c ++++ b/drivers/mtd/nand/raw/lpc32xx_slc.c +@@ -430,6 +430,7 @@ static int lpc32xx_xmit_dma(struct mtd_i + struct dma_async_tx_descriptor *desc; + int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; + int res; ++ unsigned long time_left; + + host->dma_slave_config.direction = dir; + host->dma_slave_config.src_addr = dma; +@@ -467,12 +468,19 @@ static int lpc32xx_xmit_dma(struct mtd_i + dmaengine_submit(desc); + dma_async_issue_pending(host->dma_chan); + +- wait_for_completion_timeout(&host->comp, msecs_to_jiffies(1000)); ++ time_left = wait_for_completion_timeout(&host->comp, ++ msecs_to_jiffies(1000)); ++ if (!time_left) { ++ dmaengine_terminate_sync(host->dma_chan); ++ res = -ETIMEDOUT; ++ } else { ++ res = 0; ++ } + + dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1, + DMA_BIDIRECTIONAL); + +- return 0; ++ return res; + out1: + dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1, + DMA_BIDIRECTIONAL); diff --git a/queue-7.1/mtd-virt-concat-free-duplicate-generated-name.patch b/queue-7.1/mtd-virt-concat-free-duplicate-generated-name.patch new file mode 100644 index 0000000000..e69aae6af3 --- /dev/null +++ b/queue-7.1/mtd-virt-concat-free-duplicate-generated-name.patch @@ -0,0 +1,44 @@ +From caa0ecbeff4f7fbf70f22bd8ca598918bffb1b78 Mon Sep 17 00:00:00 2001 +From: Xu Rao +Date: Fri, 26 Jun 2026 10:13:38 +0800 +Subject: mtd: virt-concat: free duplicate generated name + +From: Xu Rao + +commit caa0ecbeff4f7fbf70f22bd8ca598918bffb1b78 upstream. + +Every MTD registration runs mtd_virt_concat_create_join(). Once a +virtual concat has already been registered, the function builds the same +name again and takes the equal-name branch. That branch skips to the +next item without freeing the newly allocated string. + +Free the temporary name before continuing. + +Fixes: 43db6366fc2d ("mtd: Add driver for concatenating devices") +Cc: stable@vger.kernel.org +Signed-off-by: Xu Rao +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/mtd_virt_concat.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/mtd_virt_concat.c b/drivers/mtd/mtd_virt_concat.c +index c872a8827718..da4277ced4d6 100644 +--- a/drivers/mtd/mtd_virt_concat.c ++++ b/drivers/mtd/mtd_virt_concat.c +@@ -321,8 +321,10 @@ int mtd_virt_concat_create_join(void) + + if (concat->mtd.name) { + ret = memcmp(concat->mtd.name, name, name_sz); +- if (ret == 0) ++ if (ret == 0) { ++ kfree(name); + continue; ++ } + } + mtd = mtd_concat_create(concat->subdev, concat->num_subdev, name); + if (!mtd) { +-- +2.55.0 + diff --git a/queue-7.1/powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch b/queue-7.1/powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch new file mode 100644 index 0000000000..c5b2810818 --- /dev/null +++ b/queue-7.1/powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch @@ -0,0 +1,47 @@ +From 47b87f469a35b5ffc81c16eee6b13a9b6c8d55c6 Mon Sep 17 00:00:00 2001 +From: Junrui Luo +Date: Mon, 1 Jun 2026 15:50:00 +0800 +Subject: powerpc/spufs: fix out-of-bounds access in spufs_mem_mmap_access() + +From: Junrui Luo + +commit 47b87f469a35b5ffc81c16eee6b13a9b6c8d55c6 upstream. + +spufs_mem_mmap_access() computes the local store offset as +address - vma->vm_start, but bounds-checks it against vma->vm_end +instead of the local store size. On 64-bit, offset is always well +below vma->vm_end, so the clamp never fires and len stays unbounded +against the LS_SIZE buffer returned by ctx->ops->get_ls(). + +Reject offsets at or beyond LS_SIZE and clamp len to the remaining +space, mirroring the guard already used by spufs_mem_mmap_fault() and +spufs_ps_fault(). + +Fixes: a352894d0705 ("spufs: use new vm_ops->access to allow local state access from gdb") +Reported-by: Yuhao Jiang +Cc: stable@vger.kernel.org +Signed-off-by: Junrui Luo +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/SYBPR01MB7881EE775E8B51C09F5A29E7AF152@SYBPR01MB7881.ausprd01.prod.outlook.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/platforms/cell/spufs/file.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/platforms/cell/spufs/file.c ++++ b/arch/powerpc/platforms/cell/spufs/file.c +@@ -268,10 +268,12 @@ static int spufs_mem_mmap_access(struct + + if (write && !(vma->vm_flags & VM_WRITE)) + return -EACCES; ++ if (offset >= LS_SIZE) ++ return -EFAULT; + if (spu_acquire(ctx)) + return -EINTR; +- if ((offset + len) > vma->vm_end) +- len = vma->vm_end - offset; ++ if ((offset + len) > LS_SIZE) ++ len = LS_SIZE - offset; + local_store = ctx->ops->get_ls(ctx); + if (write) + memcpy_toio(local_store + offset, buf, len); diff --git a/queue-7.1/powerpc-uaccess-correct-check-for-config_ppc_e500-in-mask_user_address.patch b/queue-7.1/powerpc-uaccess-correct-check-for-config_ppc_e500-in-mask_user_address.patch new file mode 100644 index 0000000000..9a99a1cd5e --- /dev/null +++ b/queue-7.1/powerpc-uaccess-correct-check-for-config_ppc_e500-in-mask_user_address.patch @@ -0,0 +1,36 @@ +From d610d3ab18197d87618da11ec5fe8b3cebf32208 Mon Sep 17 00:00:00 2001 +From: Ethan Nelson-Moore +Date: Mon, 15 Jun 2026 16:37:26 -0700 +Subject: powerpc/uaccess: correct check for CONFIG_PPC_E500 in mask_user_address() + +From: Ethan Nelson-Moore + +commit d610d3ab18197d87618da11ec5fe8b3cebf32208 upstream. + +mask_user_address() incorrectly checks for CONFIG_E500 instead of +CONFIG_PPC_E500, causing mask_user_address_isel() to not be used on +E500 hardware. Fix the check to use the correct name. + +Fixes: 861574d51bbd ("powerpc/uaccess: Implement masked user access") +Cc: stable@vger.kernel.org # 7.0+ +Signed-off-by: Ethan Nelson-Moore +Fixes: 861574d51bbd ("powerpc/uaccess: Implement masked user access") +Reviewed-by: Christophe Leroy (CS GROUP) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20260615233729.29386-1-enelsonmoore@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/include/asm/uaccess.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/include/asm/uaccess.h ++++ b/arch/powerpc/include/asm/uaccess.h +@@ -511,7 +511,7 @@ static inline void __user *mask_user_add + + if (IS_ENABLED(CONFIG_PPC64)) + return mask_user_address_simple(ptr); +- if (IS_ENABLED(CONFIG_E500)) ++ if (IS_ENABLED(CONFIG_PPC_E500)) + return mask_user_address_isel(ptr); + if (TASK_SIZE <= UL(SZ_2G) && border >= UL(SZ_2G)) + return mask_user_address_simple(ptr); diff --git a/queue-7.1/series b/queue-7.1/series index cd51135ba8..cc8e2f4624 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -2029,3 +2029,27 @@ ipvs-fix-more-places-with-wrong-ipv6-transport-offsets.patch ipvs-reload-ip-header-after-head-reallocation.patch reset-imx7-correct-polarity-of-mipi-csi-resets-on-i.mx8mq.patch reset-sunxi-fix-memory-region-leak-on-ioremap-failure.patch +powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch +powerpc-uaccess-correct-check-for-config_ppc_e500-in-mask_user_address.patch +wifi-cfg80211-validate-eht-mle-before-mld-id-read.patch +wifi-ieee80211-validate-mle-common-info-length.patch +wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch +wifi-mac80211-validate-extension-frame-layout-before-rx.patch +wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch +mtd-virt-concat-free-duplicate-generated-name.patch +mtd-onenand-samsung-report-dma-completion-timeouts.patch +mtd-mchp23k256-use-spi-match-data-for-chip-caps.patch +mmc-vub300-defer-reset-until-cmd_mutex-is-unlocked.patch +mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch +mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch +mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch +mmc-block-fix-rpmb-device-unregister-ordering.patch +mmc-mmc_test-fix-__counted_by-handling-after-kzalloc_flex-conversion.patch +mmc-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch +mmc-sdhci-esdhc-imx-remove-unnecessary-mmc_card_wake_sdio_irq-check-for-tuning-save-restore.patch +mmc-sdhci-esdhc-imx-restore-dll-override-for-ddr-modes-on-resume.patch +mmc-sdhci-esdhc-imx-fix-esdhc_change_pinstate-to-allow-default-state-restore.patch +mmc-sdhci-esdhc-imx-disable-irq-during-suspend-to-fix-unhandled-interrupt.patch +mmc-sdhci-esdhc-imx-use-pm_runtime_resume_and_get-in-suspend.patch +mmc-sdhci-esdhc-imx-make-non-fatal-errors-non-blocking-in-suspend.patch +mmc-sdhci-esdhc-imx-fix-resume-error-handling.patch diff --git a/queue-7.1/wifi-cfg80211-validate-eht-mle-before-mld-id-read.patch b/queue-7.1/wifi-cfg80211-validate-eht-mle-before-mld-id-read.patch new file mode 100644 index 0000000000..9eb19407c7 --- /dev/null +++ b/queue-7.1/wifi-cfg80211-validate-eht-mle-before-mld-id-read.patch @@ -0,0 +1,54 @@ +From 74e27cd1d98b546fdb276008a83708d062339661 Mon Sep 17 00:00:00 2001 +From: Haofeng Li +Date: Wed, 1 Jul 2026 17:33:27 +0800 +Subject: wifi: cfg80211: validate EHT MLE before MLD ID read + +From: Haofeng Li + +commit 74e27cd1d98b546fdb276008a83708d062339661 upstream. + +cfg80211_gen_new_ie() copies ML probe response elements from +the parent frame when the parent EHT multi-link element has an +MLD ID matching the nontransmitted BSSID index. + +The code only checked that the extension element had more than +one byte before calling ieee80211_mle_get_mld_id(). That helper +assumes a BASIC MLE with enough common info and documents that +callers must first use ieee80211_mle_type_ok(). + +Attack chain: +malicious AP sends a short EHT MLE in an MBSSID beacon. +cfg80211_inform_bss_frame_data() stores the copied IE buffer. +cfg80211_parse_mbssid_data() builds the nontransmitted BSS IE. +cfg80211_gen_new_ie() sees the EHT MLE in the parent frame. +ieee80211_mle_get_mld_id() then reads past the IE boundary. + +Validate the MLE type and size before reading the MLD ID. This +matches the contract required by the MLE helper and rejects the +short element before any internal MLE fields are accessed. + +Cc: stable@vger.kernel.org +Fixes: 61dcfa8c2a8f ("wifi: cfg80211: copy multi-link element from the multi-link probe request's frame body to the generated elements") +Signed-off-by: Haofeng Li +Link: https://patch.msgid.link/20260701093327.2680709-1-lihaofeng@kylinos.cn +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/wireless/scan.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -326,8 +326,11 @@ cfg80211_gen_new_ie(const u8 *ie, size_t + /* For ML probe response, match the MLE in the frame body with + * MLD id being 'bssid_index' + */ +- if (parent->id == WLAN_EID_EXTENSION && parent->datalen > 1 && ++ if (parent->id == WLAN_EID_EXTENSION && + parent->data[0] == WLAN_EID_EXT_EHT_MULTI_LINK && ++ ieee80211_mle_type_ok(parent->data + 1, ++ IEEE80211_ML_CONTROL_TYPE_BASIC, ++ parent->datalen - 1) && + bssid_index == ieee80211_mle_get_mld_id(parent->data + 1)) { + if (!cfg80211_copy_elem_with_frags(parent, + ie, ielen, diff --git a/queue-7.1/wifi-ieee80211-validate-mle-common-info-length.patch b/queue-7.1/wifi-ieee80211-validate-mle-common-info-length.patch new file mode 100644 index 0000000000..3355217707 --- /dev/null +++ b/queue-7.1/wifi-ieee80211-validate-mle-common-info-length.patch @@ -0,0 +1,85 @@ +From 293baeae9b2434a3e432629d7720b5603db2d77e Mon Sep 17 00:00:00 2001 +From: Zhao Li +Date: Fri, 12 Jun 2026 01:35:07 +0800 +Subject: wifi: ieee80211: validate MLE common info length + +From: Zhao Li + +commit 293baeae9b2434a3e432629d7720b5603db2d77e upstream. + +ieee80211_mle_common_size() uses the first common-info octet as the +common information length for all known MLE types. However, +ieee80211_mle_size_ok() only validates that octet for Basic, Probe +Request, and TDLS MLEs. + +Reconfiguration MLEs also skipped the length octet when calculating the +minimum common size, and Priority Access MLEs skipped validation of the +advertised common information length. + +Account for the Reconfiguration common-info length octet and validate +the advertised common information length for all known MLE types. Keep +unknown-type handling unchanged. + +Fixes: 0f48b8b88aa9 ("wifi: ieee80211: add definitions for multi-link element") +Cc: stable@vger.kernel.org +Signed-off-by: Zhao Li +Link: https://patch.msgid.link/20260611173506.36838-2-enderaoelyther@gmail.com +[remove now misleading comment] +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/ieee80211-eht.h | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +--- a/include/linux/ieee80211-eht.h ++++ b/include/linux/ieee80211-eht.h +@@ -844,7 +844,7 @@ static inline bool ieee80211_mle_size_ok + const struct ieee80211_multi_link_elem *mle = (const void *)data; + u8 fixed = sizeof(*mle); + u8 common = 0; +- bool check_common_len = false; ++ u8 common_len; + u16 control; + + if (!data || len < fixed) +@@ -855,7 +855,6 @@ static inline bool ieee80211_mle_size_ok + switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { + case IEEE80211_ML_CONTROL_TYPE_BASIC: + common += sizeof(struct ieee80211_mle_basic_common_info); +- check_common_len = true; + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) +@@ -875,9 +874,9 @@ static inline bool ieee80211_mle_size_ok + common += sizeof(struct ieee80211_mle_preq_common_info); + if (control & IEEE80211_MLC_PREQ_PRES_MLD_ID) + common += 1; +- check_common_len = true; + break; + case IEEE80211_ML_CONTROL_TYPE_RECONF: ++ common += 1; + if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR) + common += ETH_ALEN; + if (control & IEEE80211_MLC_RECONF_PRES_EML_CAPA) +@@ -889,7 +888,6 @@ static inline bool ieee80211_mle_size_ok + break; + case IEEE80211_ML_CONTROL_TYPE_TDLS: + common += sizeof(struct ieee80211_mle_tdls_common_info); +- check_common_len = true; + break; + case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: + common = ETH_ALEN + 1; +@@ -902,11 +900,9 @@ static inline bool ieee80211_mle_size_ok + if (len < fixed + common) + return false; + +- if (!check_common_len) +- return true; ++ common_len = mle->variable[0]; + +- /* if present, common length is the first octet there */ +- return mle->variable[0] >= common; ++ return common_len >= common && common_len <= len - fixed; + } + + /** diff --git a/queue-7.1/wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch b/queue-7.1/wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch new file mode 100644 index 0000000000..619f4bd059 --- /dev/null +++ b/queue-7.1/wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch @@ -0,0 +1,78 @@ +From 2c51457d930f723e5f2903af90f5847f7df53f42 Mon Sep 17 00:00:00 2001 +From: Zhiling Zou +Date: Sat, 27 Jun 2026 00:58:30 +0800 +Subject: wifi: mac80211: free ack status frame on TX header build failure + +From: Zhiling Zou + +commit 2c51457d930f723e5f2903af90f5847f7df53f42 upstream. + +ieee80211_build_hdr() stores an ACK status frame before it has +finished all validation and header construction. If a later error path +is taken, the transmit skb is freed but the stored ACK status frame +remains in local->ack_status_frames. + +This can happen for control port frames when the requested MLO link ID +does not match the link selected for a non-MLO station. Repeated +failures can fill the ACK status IDR and leave pending ACK frames until +hardware teardown. + +Remove any stored ACK status frame before returning an error after it +has been inserted into the IDR. + +Fixes: a729cff8ad51 ("mac80211: implement wifi TX status") +Cc: stable@vger.kernel.org +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Assisted-by: Codex:gpt-5.4 +Signed-off-by: Zhiling Zou +Signed-off-by: Ren Wei +Link: https://patch.msgid.link/9de0423da840e92084915b8f92e66a421245c4b8.1782462409.git.roxy520tt@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/tx.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -2597,6 +2597,18 @@ static u16 ieee80211_store_ack_skb(struc + return info_id; + } + ++static void ieee80211_remove_ack_skb(struct ieee80211_local *local, u16 info_id) ++{ ++ struct sk_buff *ack_skb; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&local->ack_status_lock, flags); ++ ack_skb = idr_remove(&local->ack_status_frames, info_id); ++ spin_unlock_irqrestore(&local->ack_status_lock, flags); ++ ++ kfree_skb(ack_skb); ++} ++ + /** + * ieee80211_build_hdr - build 802.11 header in the given frame + * @sdata: virtual interface to build the header for +@@ -2972,7 +2984,8 @@ static struct sk_buff *ieee80211_build_h + if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) { + ieee80211_free_txskb(&local->hw, skb); + skb = NULL; +- return ERR_PTR(-ENOMEM); ++ ret = -ENOMEM; ++ goto free; + } + } + +@@ -3040,6 +3053,8 @@ static struct sk_buff *ieee80211_build_h + + return skb; + free: ++ if (info_id) ++ ieee80211_remove_ack_skb(local, info_id); + kfree_skb(skb); + return ERR_PTR(ret); + } diff --git a/queue-7.1/wifi-mac80211-validate-extension-frame-layout-before-rx.patch b/queue-7.1/wifi-mac80211-validate-extension-frame-layout-before-rx.patch new file mode 100644 index 0000000000..441b234bc4 --- /dev/null +++ b/queue-7.1/wifi-mac80211-validate-extension-frame-layout-before-rx.patch @@ -0,0 +1,127 @@ +From 57d503ce32eccfa7650065ca4c560f7e29a2e676 Mon Sep 17 00:00:00 2001 +From: Zhao Li +Date: Fri, 12 Jun 2026 00:19:45 +0800 +Subject: wifi: mac80211: validate extension-frame layout before RX + +From: Zhao Li + +commit 57d503ce32eccfa7650065ca4c560f7e29a2e676 upstream. + +Extension frames only have the extension header at the regular 802.11 +header offset. The generic RX path can still reach helpers and interface +dispatch code that read regular header address fields before unsupported +extension subtypes are dropped. + +mac80211 currently only handles S1G beacon extension frames. Drop other +extension subtypes before they can reach regular-header RX processing. +For S1G beacons, linearize the SKB with the management-frame path and +require the fixed S1G beacon header, including optional fixed fields +indicated by frame control, before generic RX dispatch. + +Route S1G beacons through the station/default-link RX path without +regular-header station lookup. Avoid regular-header address reads in the +mac80211 RX paths that process S1G extension beacons, including +accept-frame, duplicate-detection, address-copy, and MLO +address-translation paths. + +Also make ieee80211_get_bssid() length-safe before returning the S1G +source-address pointer. + +Fixes: 09a740ce352e ("mac80211: receive and process S1G beacons") +Cc: stable@vger.kernel.org +Signed-off-by: Zhao Li +Link: https://patch.msgid.link/20260611161943.91069-5-enderaoelyther@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/rx.c | 34 ++++++++++++++++++++++++++++++++-- + net/mac80211/util.c | 3 +++ + 2 files changed, 35 insertions(+), 2 deletions(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1526,6 +1526,9 @@ ieee80211_rx_h_check_dup(struct ieee8021 + if (status->flag & RX_FLAG_DUP_VALIDATED) + return RX_CONTINUE; + ++ if (ieee80211_is_ext(hdr->frame_control)) ++ return RX_CONTINUE; ++ + /* + * Drop duplicate 802.11 retransmissions + * (IEEE 802.11-2012: 9.3.2.10 "Duplicate detection and recovery") +@@ -4487,12 +4490,16 @@ static bool ieee80211_accept_frame(struc + struct ieee80211_hdr *hdr = (void *)skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); +- bool multicast = is_multicast_ether_addr(hdr->addr1) || +- ieee80211_is_s1g_beacon(hdr->frame_control); ++ bool multicast; + static const u8 nan_network_id[ETH_ALEN] __aligned(2) = { + 0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00 + }; + ++ if (ieee80211_is_s1g_beacon(hdr->frame_control)) ++ return sdata->vif.type == NL80211_IFTYPE_STATION && bssid; ++ ++ multicast = is_multicast_ether_addr(hdr->addr1); ++ + switch (sdata->vif.type) { + case NL80211_IFTYPE_STATION: + if (!bssid && !sdata->u.mgd.use_4addr) +@@ -5174,6 +5181,11 @@ static bool ieee80211_prepare_and_rx_han + hdr = (struct ieee80211_hdr *)rx->skb->data; + } + ++ if (ieee80211_is_s1g_beacon(hdr->frame_control)) { ++ ieee80211_invoke_rx_handlers(rx); ++ return true; ++ } ++ + /* Store a copy of the pre-translated link addresses for SW crypto */ + if (unlikely(is_unicast_ether_addr(hdr->addr1) && + !ieee80211_is_data(hdr->frame_control))) +@@ -5263,6 +5275,13 @@ static bool ieee80211_rx_for_interface(s + struct sta_info *sta; + int link_id = -1; + ++ if (ieee80211_is_s1g_beacon(hdr->frame_control)) { ++ if (!ieee80211_rx_data_set_sta(rx, NULL, -1)) ++ return false; ++ ++ return ieee80211_prepare_and_rx_handle(rx, skb, consume); ++ } ++ + /* + * Look up link station first, in case there's a + * chance that they might have a link address that +@@ -5338,6 +5357,17 @@ static void __ieee80211_rx_handle_packet + err = -ENOBUFS; + else + err = skb_linearize(skb); ++ } else if (ieee80211_is_s1g_beacon(fc)) { ++ size_t s1g_hdr_len = offsetof(struct ieee80211_ext, ++ u.s1g_beacon.variable) + ++ ieee80211_s1g_optional_len(fc); ++ ++ if (skb->len < s1g_hdr_len) ++ err = -ENOBUFS; ++ else ++ err = skb_linearize(skb); ++ } else if (ieee80211_is_ext(fc)) { ++ err = -EINVAL; + } else { + err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); + } +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -73,6 +73,9 @@ u8 *ieee80211_get_bssid(struct ieee80211 + if (ieee80211_is_s1g_beacon(fc)) { + struct ieee80211_ext *ext = (void *) hdr; + ++ if (len < offsetofend(struct ieee80211_ext, u.s1g_beacon.sa)) ++ return NULL; ++ + return ext->u.s1g_beacon.sa; + } + diff --git a/queue-7.1/wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch b/queue-7.1/wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch new file mode 100644 index 0000000000..39db8e160f --- /dev/null +++ b/queue-7.1/wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch @@ -0,0 +1,87 @@ +From d78a407bad6f500884a8606aea1a5a9207be4030 Mon Sep 17 00:00:00 2001 +From: Rafael Beims +Date: Fri, 12 Jun 2026 09:25:46 -0300 +Subject: wifi: mwifiex: fix permanently busy scans after multiple roam iterations + +From: Rafael Beims + +commit d78a407bad6f500884a8606aea1a5a9207be4030 upstream. + +In order for the firmware to sleep, the driver has to confirm a +previously received sleep request. The normal sequence of evets goes +like this: +EVENT_SLEEP -> adapter->ps_state = PS_STATE_PRE_SLEEP -> sleep-confirm +-> SLEEP -> EVENT_AWAKE -> AWAKE. +Before sending the sleep-confirm command, the driver must make sure +there are no commands either running or waiting to be completed. + +mwifiex_ret_802_11_associate() unconditionally sets +ps_state = PS_STATE_AWAKE when it processes the association command +response, outside of the normal powersave management flow. If +EVENT_SLEEP arrives while the association command is in flight, +ps_state is PRE_SLEEP when the association command response is parsed, +and the forced AWAKE overwrites it. The deferred sleep-confirm is +never sent. + +A subsequent scan_start command is correctly acknowledged, but the +firmware doesn't generate scan_result events. The scan request never +finishes, and additional requests from userspace fail with -EBUSY. + +After testing on both IW412 and W8997, I could only trigger the bug on +the IW412 and observed the firmwares behave differently. On the IW412 +the firmware still sends EVENT_SLEEP while the authentication / +association process is ongoing. A W8997 under the same +conditions seems to suppress power-save for the duration of the +association, so PRE_SLEEP never coincided with the association response +even after extended periods of testing using the loops +described below (>12hours). + +On the IW412, the delay between commands that triggers an EVENT_SLEEP +was empirically determined to be ~20ms. This delay can naturally occur +when the driver is outputting debugging information +(debug_mask = 0x00000037), in which situation the busy scans issue is +repeatable while running "test 1)" as described below. If the delay +between commands is less than ~20ms, the firmware stays awake and +the issue was not reproducible running the same test. + +The host_mlme=false path also behaves differently. In this case, the +entire authentication / association transaction is executed by one +command (HostCmd_CMD_802_11_ASSOCIATE), and the firmware doesn't emit +EVENT_SLEEP while the command is running. + +Remove the assignment so the ps_state is only manipulated in the paths +that are related to powersave event handling and on the main workqueue +for correct sleep confirmation. + +The following loop tests were performed (with debugging output enabled): +1) force roaming between two AP's, one 5GHz and one 2.4GHz, same +SSID. Use wpa_cli to trigger the roaming behavior, sleep 2s +between iterations. +2) force a disconnection to AP 1 and a connection to AP 2, test +scan. Use wpa_cli to trigger the connection changes, sleep 2s +between iterations. + +Each test ran in each device for at least 3 hours. + +Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-7 +Signed-off-by: Rafael Beims +Reviewed-by: Jeff Chen +Link: https://patch.msgid.link/20260612122547.1586872-2-rafael@beims.me +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/marvell/mwifiex/join.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/wireless/marvell/mwifiex/join.c ++++ b/drivers/net/wireless/marvell/mwifiex/join.c +@@ -736,7 +736,6 @@ int mwifiex_ret_802_11_associate(struct + /* Send a Media Connected event, according to the Spec */ + priv->media_connected = true; + +- priv->adapter->ps_state = PS_STATE_AWAKE; + priv->adapter->pps_uapsd_mode = false; + priv->adapter->tx_lock_flag = false; +