From: Greg Kroah-Hartman Date: Tue, 21 Jul 2026 09:50:06 +0000 (+0200) Subject: 6.12-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ca6e0d112bdeb5b08e351da7b7ee0b30cb199af3;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: mmc-block-fix-rpmb-device-unregister-ordering.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 powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch --- diff --git a/queue-6.12/mmc-block-fix-rpmb-device-unregister-ordering.patch b/queue-6.12/mmc-block-fix-rpmb-device-unregister-ordering.patch new file mode 100644 index 0000000000..562811e575 --- /dev/null +++ b/queue-6.12/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 +@@ -2768,7 +2768,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); +@@ -2989,8 +2988,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-6.12/mmc-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch b/queue-6.12/mmc-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch new file mode 100644 index 0000000000..98f242b84e --- /dev/null +++ b/queue-6.12/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 +@@ -1464,13 +1464,16 @@ static int dwcmshc_probe(struct platform + goto free_pltfm; + + 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); + +@@ -1484,7 +1487,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 +@@ -1530,9 +1533,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); + free_pltfm: + sdhci_pltfm_free(pdev); diff --git a/queue-6.12/mmc-vub300-defer-reset-until-cmd_mutex-is-unlocked.patch b/queue-6.12/mmc-vub300-defer-reset-until-cmd_mutex-is-unlocked.patch new file mode 100644 index 0000000000..50cc109316 --- /dev/null +++ b/queue-6.12/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 +@@ -1585,7 +1585,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) + { +@@ -1597,17 +1597,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); +@@ -1703,6 +1697,8 @@ static void __vub300_command_response(st + } else { + cmd->error = -EINVAL; + } ++ ++ return false; + } + + static void construct_request_response(struct vub300_mmc_host *vub300, +@@ -1748,6 +1744,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); +@@ -1770,7 +1767,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; +@@ -1778,6 +1776,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-6.12/mtd-mchp23k256-use-spi-match-data-for-chip-caps.patch b/queue-6.12/mtd-mchp23k256-use-spi-match-data-for-chip-caps.patch new file mode 100644 index 0000000000..cd2cfa4fdf --- /dev/null +++ b/queue-6.12/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-6.12/mtd-onenand-samsung-report-dma-completion-timeouts.patch b/queue-6.12/mtd-onenand-samsung-report-dma-completion-timeouts.patch new file mode 100644 index 0000000000..94652beb0f --- /dev/null +++ b/queue-6.12/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-6.12/mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch b/queue-6.12/mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch new file mode 100644 index 0000000000..b573a127ed --- /dev/null +++ b/queue-6.12/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 +@@ -683,8 +683,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-6.12/mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch b/queue-6.12/mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch new file mode 100644 index 0000000000..ecaf399f73 --- /dev/null +++ b/queue-6.12/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-6.12/mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch b/queue-6.12/mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch new file mode 100644 index 0000000000..4728ae57b3 --- /dev/null +++ b/queue-6.12/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-6.12/powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch b/queue-6.12/powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch new file mode 100644 index 0000000000..c5b2810818 --- /dev/null +++ b/queue-6.12/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-6.12/series b/queue-6.12/series index 9fcd7e5195..1dc9abd46c 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -1120,3 +1120,14 @@ 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 +wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch +wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.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-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch diff --git a/queue-6.12/wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch b/queue-6.12/wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch new file mode 100644 index 0000000000..fb4fa80e63 --- /dev/null +++ b/queue-6.12/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 +@@ -2578,6 +2578,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 +@@ -2935,7 +2947,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; + } + } + +@@ -3003,6 +3016,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-6.12/wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch b/queue-6.12/wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch new file mode 100644 index 0000000000..7a6b5b7342 --- /dev/null +++ b/queue-6.12/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 +@@ -737,7 +737,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; +