* [PATCH AUTOSEL 6.12 13/69] remoteproc: imx_rproc: skip clock enable when M-core is managed by the SCU
[not found] <20250804003119.3620476-1-sashal@kernel.org>
@ 2025-08-04 0:30 ` Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 19/69] ARM: rockchip: fix kernel hang during smp initialization Sasha Levin
` (4 subsequent siblings)
5 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2025-08-04 0:30 UTC (permalink / raw)
To: patches, stable
Cc: Hiago De Franco, Peng Fan, Ulf Hansson, Mathieu Poirier,
Sasha Levin, andersson, shawnguo, linux-remoteproc, imx,
linux-arm-kernel
From: Hiago De Franco <hiago.franco@toradex.com>
[ Upstream commit 496deecb020d14ba89ba7084fbc3024f91687023 ]
For the i.MX8X and i.MX8 family SoCs, when the Cortex-M core is powered
up and started by the Cortex-A core using the bootloader (e.g., via the
U-Boot bootaux command), both M-core and Linux run within the same SCFW
(System Controller Firmware) partition. With that, Linux has permission
to control the M-core.
But once the M-core is started by the bootloader, the SCFW automatically
enables its clock and sets the clock rate. If Linux later attempts to
enable the same clock via clk_prepare_enable(), the SCFW returns a
'LOCKED' error, as the clock is already configured by the SCFW. This
causes the probe function in imx_rproc.c to fail, leading to the M-core
power domain being shut down while the core is still running. This
results in a fault from the SCU (System Controller Unit) and triggers a
system reset.
To address this issue, ignore handling the clk for i.MX8X and i.MX8
M-core, as SCFW already takes care of enabling and configuring the
clock.
Suggested-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Hiago De Franco <hiago.franco@toradex.com>
Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20250629172512.14857-3-hiagofranco@gmail.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Based on my analysis, I can now provide a definitive answer:
**Backport Status: YES**
This commit should be backported to stable kernel trees for the
following reasons:
1. **Critical bug fix preventing system reset**: The commit fixes a
serious issue where the probe function failure causes the M-core
power domain to be shut down while the core is still running,
resulting in a fault from the SCU and triggering a system reset. This
is a severe user-impacting bug that can cause unexpected system
reboots.
2. **Minimal and contained change**: The fix is very simple - it just
adds `|| dcfg->method == IMX_RPROC_SCU_API` to an existing condition
in the `imx_rproc_clk_enable()` function. This is a one-line change
that only affects the clock handling logic for i.MX8X and i.MX8
family SoCs when using SCU API method.
3. **Clear root cause**: The commit message clearly explains the issue -
when the M-core is started by the bootloader, the SCFW automatically
enables its clock. If Linux later attempts to enable the same clock,
SCFW returns a 'LOCKED' error, causing probe failure and subsequent
power domain shutdown while the core is running.
4. **No architectural changes**: This is purely a bug fix that doesn't
introduce new features or change the driver architecture. It simply
skips clock operations for a specific configuration where the clock
is already managed by the SCFW.
5. **Platform-specific fix with no regression risk**: The change only
affects i.MX8X and i.MX8 platforms using the SCU API method
(`IMX_RPROC_SCU_API`). Other platforms and methods are unaffected,
minimizing the risk of regression.
6. **Prevents data corruption/loss**: System resets caused by this bug
could potentially lead to data loss or corruption, making this fix
important for system stability.
The specific code change in `imx_rproc_clk_enable()` at line 1033 simply
extends the existing check from:
```c
if (dcfg->method == IMX_RPROC_NONE)
```
to:
```c
if (dcfg->method == IMX_RPROC_NONE || dcfg->method == IMX_RPROC_SCU_API)
```
This ensures that for SCU-managed cores, Linux doesn't attempt to enable
clocks that are already controlled by the SCFW, preventing the probe
failure and subsequent system reset.
drivers/remoteproc/imx_rproc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 800015ff7ff9..cc3f5b7fe9dd 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -1029,8 +1029,8 @@ static int imx_rproc_clk_enable(struct imx_rproc *priv)
struct device *dev = priv->dev;
int ret;
- /* Remote core is not under control of Linux */
- if (dcfg->method == IMX_RPROC_NONE)
+ /* Remote core is not under control of Linux or it is managed by SCU API */
+ if (dcfg->method == IMX_RPROC_NONE || dcfg->method == IMX_RPROC_SCU_API)
return 0;
priv->clk = devm_clk_get(dev, NULL);
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH AUTOSEL 6.12 19/69] ARM: rockchip: fix kernel hang during smp initialization
[not found] <20250804003119.3620476-1-sashal@kernel.org>
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 13/69] remoteproc: imx_rproc: skip clock enable when M-core is managed by the SCU Sasha Levin
@ 2025-08-04 0:30 ` Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 21/69] EDAC/synopsys: Clear the ECC counters on init Sasha Levin
` (3 subsequent siblings)
5 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2025-08-04 0:30 UTC (permalink / raw)
To: patches, stable
Cc: Alexander Kochetkov, Heiko Stuebner, Sasha Levin,
linux-arm-kernel, linux-rockchip
From: Alexander Kochetkov <al.kochet@gmail.com>
[ Upstream commit 7cdb433bb44cdc87dc5260cdf15bf03cc1cd1814 ]
In order to bring up secondary CPUs main CPU write trampoline
code to SRAM. The trampoline code is written while secondary
CPUs are powered on (at least that true for RK3188 CPU).
Sometimes that leads to kernel hang. Probably because secondary
CPU execute trampoline code while kernel doesn't expect.
The patch moves SRAM initialization step to the point where all
secondary CPUs are powered down.
That fixes rarely hangs on RK3188:
[ 0.091568] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[ 0.091996] rockchip_smp_prepare_cpus: ncores 4
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
Link: https://lore.kernel.org/r/20250703140453.1273027-1-al.kochet@gmail.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Based on my analysis of the commit and the code context, here's my
determination:
**Backport Status: YES**
This commit should be backported to stable kernel trees for the
following reasons:
1. **Fixes a real bug affecting users**: The commit explicitly mentions
that it "fixes rarely hangs on RK3188" during SMP initialization.
This is a critical boot-time issue that prevents the system from
functioning properly.
2. **Small and contained fix**: The change is minimal - it only moves
the SRAM initialization code (`rockchip_smp_prepare_sram()`) to
execute after all secondary CPUs are powered down. The code movement
is straightforward:
- Lines 281-285 (old location) are moved to lines 321-325 (new
location)
- The fix is contained within a single function
(`rockchip_smp_prepare_cpus()`)
3. **Clear root cause**: The commit message explains the race condition
clearly - secondary CPUs may execute trampoline code while it's being
written to SRAM, causing unpredictable behavior and hangs.
4. **No architectural changes**: This is purely a timing/ordering fix
that doesn't introduce new features or change the architecture of the
code.
5. **Critical subsystem**: SMP initialization is a critical kernel
subsystem. A hang during boot makes the system unusable, which is a
severe issue for affected users.
6. **Platform-specific fix**: The change only affects Rockchip ARM
platforms (specifically those with Cortex-A9 CPUs like RK3188),
limiting the scope of potential regressions.
7. **Follows stable tree rules**: The fix addresses an important bug
(boot hang), is small and self-contained, has minimal risk of
regression, and doesn't introduce new features.
The key insight from the code analysis is that the original code had a
clear race condition where:
1. Secondary CPUs were powered on (lines 287-288 in the original)
2. Trampoline code was written to SRAM (line 282 in the original)
3. Secondary CPUs could potentially execute incomplete/corrupted
trampoline code
The fix ensures all secondary CPUs are powered down (lines 321-323)
before writing the trampoline code to SRAM (lines 321-325 in the new
version), eliminating the race condition.
arch/arm/mach-rockchip/platsmp.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
index 36915a073c23..f432d22bfed8 100644
--- a/arch/arm/mach-rockchip/platsmp.c
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -279,11 +279,6 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
}
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
- if (rockchip_smp_prepare_sram(node)) {
- of_node_put(node);
- return;
- }
-
/* enable the SCU power domain */
pmu_set_power_domain(PMU_PWRDN_SCU, true);
@@ -316,11 +311,19 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
asm ("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
ncores = ((l2ctlr >> 24) & 0x3) + 1;
}
- of_node_put(node);
/* Make sure that all cores except the first are really off */
for (i = 1; i < ncores; i++)
pmu_set_power_domain(0 + i, false);
+
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
+ if (rockchip_smp_prepare_sram(node)) {
+ of_node_put(node);
+ return;
+ }
+ }
+
+ of_node_put(node);
}
static void __init rk3036_smp_prepare_cpus(unsigned int max_cpus)
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH AUTOSEL 6.12 21/69] EDAC/synopsys: Clear the ECC counters on init
[not found] <20250804003119.3620476-1-sashal@kernel.org>
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 13/69] remoteproc: imx_rproc: skip clock enable when M-core is managed by the SCU Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 19/69] ARM: rockchip: fix kernel hang during smp initialization Sasha Levin
@ 2025-08-04 0:30 ` Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 28/69] ARM: tegra: Use I/O memcpy to write to IRAM Sasha Levin
` (2 subsequent siblings)
5 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2025-08-04 0:30 UTC (permalink / raw)
To: patches, stable
Cc: Shubhrajyoti Datta, Borislav Petkov, Sasha Levin, michal.simek,
linux-arm-kernel, linux-edac
From: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
[ Upstream commit b1dc7f097b78eb8d25b071ead2384b07a549692b ]
Clear the ECC error and counter registers during initialization/probe to avoid
reporting stale errors that may have occurred before EDAC registration.
For that, unify the Zynq and ZynqMP ECC state reading paths and simplify the
code.
[ bp: Massage commit message.
Fix an -Wsometimes-uninitialized warning as reported by
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202507141048.obUv3ZUm-lkp@intel.com ]
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/20250713050753.7042-1-shubhrajyoti.datta@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
**Backport Status: YES**
This commit is suitable for backporting to stable kernel trees based on
the following analysis:
## Bug Fix Nature
The commit fixes a clear bug where the EDAC driver could report stale
ECC errors from before the driver was initialized. This is evident from
the commit message: "Clear the ECC error and counter registers during
initialization/probe to avoid reporting stale errors that may have
occurred before EDAC registration."
## Code Changes Analysis
1. **Problem Being Fixed**:
- The driver wasn't clearing ECC error counters during initialization
- This could lead to false error reports from pre-boot or pre-driver-
load errors
- Users could see incorrect ECC error counts that don't reflect
actual runtime errors
2. **Solution Implementation**:
- The patch consolidates the ECC state checking into a single
`get_ecc_state()` function
- Adds counter clearing logic for both Zynq and ZynqMP platforms:
```c
// For Zynq:
clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_UE_ERR;
writel(clearval, priv->baseaddr + ECC_CTRL_OFST);
writel(0x0, priv->baseaddr + ECC_CTRL_OFST);
// For ZynqMP:
clearval = readl(priv->baseaddr + ECC_CLR_OFST) |
ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
writel(clearval, priv->baseaddr + ECC_CLR_OFST);
```
3. **Scope and Risk Assessment**:
- Changes are confined to the synopsys_edac driver
- No API changes or interface modifications
- The refactoring simplifies code by removing duplicate
`zynq_get_ecc_state()` and `zynqmp_get_ecc_state()` functions
- Adds platform type enum for cleaner platform identification
- Risk is minimal as it only affects initialization path
4. **Stable Tree Criteria Compliance**:
- ✓ Fixes a real bug (stale error reporting)
- ✓ Small and contained changes (~150 lines)
- ✓ No new features added
- ✓ No architectural changes
- ✓ Low regression risk
- ✓ Clear fix for a specific problem
5. **Additional Evidence**:
- The maintainer (Borislav Petkov) accepted and massaged the patch
- Fixed a compiler warning caught by kernel test robot
- The bug could affect production systems by showing false ECC errors
This is a textbook example of a stable-worthy patch: it fixes a specific
bug (stale ECC error reporting) with minimal, focused changes that don't
introduce new functionality or risk.
drivers/edac/synopsys_edac.c | 97 +++++++++++++++++-------------------
1 file changed, 46 insertions(+), 51 deletions(-)
diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index d7416166fd8a..ec3ed5e2b2d7 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -332,20 +332,26 @@ struct synps_edac_priv {
#endif
};
+enum synps_platform_type {
+ ZYNQ,
+ ZYNQMP,
+ SYNPS,
+};
+
/**
* struct synps_platform_data - synps platform data structure.
+ * @platform: Identifies the target hardware platform
* @get_error_info: Get EDAC error info.
* @get_mtype: Get mtype.
* @get_dtype: Get dtype.
- * @get_ecc_state: Get ECC state.
* @get_mem_info: Get EDAC memory info
* @quirks: To differentiate IPs.
*/
struct synps_platform_data {
+ enum synps_platform_type platform;
int (*get_error_info)(struct synps_edac_priv *priv);
enum mem_type (*get_mtype)(const void __iomem *base);
enum dev_type (*get_dtype)(const void __iomem *base);
- bool (*get_ecc_state)(void __iomem *base);
#ifdef CONFIG_EDAC_DEBUG
u64 (*get_mem_info)(struct synps_edac_priv *priv);
#endif
@@ -720,51 +726,38 @@ static enum dev_type zynqmp_get_dtype(const void __iomem *base)
return dt;
}
-/**
- * zynq_get_ecc_state - Return the controller ECC enable/disable status.
- * @base: DDR memory controller base address.
- *
- * Get the ECC enable/disable status of the controller.
- *
- * Return: true if enabled, otherwise false.
- */
-static bool zynq_get_ecc_state(void __iomem *base)
+static bool get_ecc_state(struct synps_edac_priv *priv)
{
+ u32 ecctype, clearval;
enum dev_type dt;
- u32 ecctype;
-
- dt = zynq_get_dtype(base);
- if (dt == DEV_UNKNOWN)
- return false;
- ecctype = readl(base + SCRUB_OFST) & SCRUB_MODE_MASK;
- if ((ecctype == SCRUB_MODE_SECDED) && (dt == DEV_X2))
- return true;
-
- return false;
-}
-
-/**
- * zynqmp_get_ecc_state - Return the controller ECC enable/disable status.
- * @base: DDR memory controller base address.
- *
- * Get the ECC enable/disable status for the controller.
- *
- * Return: a ECC status boolean i.e true/false - enabled/disabled.
- */
-static bool zynqmp_get_ecc_state(void __iomem *base)
-{
- enum dev_type dt;
- u32 ecctype;
-
- dt = zynqmp_get_dtype(base);
- if (dt == DEV_UNKNOWN)
- return false;
-
- ecctype = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
- if ((ecctype == SCRUB_MODE_SECDED) &&
- ((dt == DEV_X2) || (dt == DEV_X4) || (dt == DEV_X8)))
- return true;
+ if (priv->p_data->platform == ZYNQ) {
+ dt = zynq_get_dtype(priv->baseaddr);
+ if (dt == DEV_UNKNOWN)
+ return false;
+
+ ecctype = readl(priv->baseaddr + SCRUB_OFST) & SCRUB_MODE_MASK;
+ if (ecctype == SCRUB_MODE_SECDED && dt == DEV_X2) {
+ clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_UE_ERR;
+ writel(clearval, priv->baseaddr + ECC_CTRL_OFST);
+ writel(0x0, priv->baseaddr + ECC_CTRL_OFST);
+ return true;
+ }
+ } else {
+ dt = zynqmp_get_dtype(priv->baseaddr);
+ if (dt == DEV_UNKNOWN)
+ return false;
+
+ ecctype = readl(priv->baseaddr + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
+ if (ecctype == SCRUB_MODE_SECDED &&
+ (dt == DEV_X2 || dt == DEV_X4 || dt == DEV_X8)) {
+ clearval = readl(priv->baseaddr + ECC_CLR_OFST) |
+ ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
+ ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
+ writel(clearval, priv->baseaddr + ECC_CLR_OFST);
+ return true;
+ }
+ }
return false;
}
@@ -934,18 +927,18 @@ static int setup_irq(struct mem_ctl_info *mci,
}
static const struct synps_platform_data zynq_edac_def = {
+ .platform = ZYNQ,
.get_error_info = zynq_get_error_info,
.get_mtype = zynq_get_mtype,
.get_dtype = zynq_get_dtype,
- .get_ecc_state = zynq_get_ecc_state,
.quirks = 0,
};
static const struct synps_platform_data zynqmp_edac_def = {
+ .platform = ZYNQMP,
.get_error_info = zynqmp_get_error_info,
.get_mtype = zynqmp_get_mtype,
.get_dtype = zynqmp_get_dtype,
- .get_ecc_state = zynqmp_get_ecc_state,
#ifdef CONFIG_EDAC_DEBUG
.get_mem_info = zynqmp_get_mem_info,
#endif
@@ -957,10 +950,10 @@ static const struct synps_platform_data zynqmp_edac_def = {
};
static const struct synps_platform_data synopsys_edac_def = {
+ .platform = SYNPS,
.get_error_info = zynqmp_get_error_info,
.get_mtype = zynqmp_get_mtype,
.get_dtype = zynqmp_get_dtype,
- .get_ecc_state = zynqmp_get_ecc_state,
.quirks = (DDR_ECC_INTR_SUPPORT | DDR_ECC_INTR_SELF_CLEAR
#ifdef CONFIG_EDAC_DEBUG
| DDR_ECC_DATA_POISON_SUPPORT
@@ -1390,10 +1383,6 @@ static int mc_probe(struct platform_device *pdev)
if (!p_data)
return -ENODEV;
- if (!p_data->get_ecc_state(baseaddr)) {
- edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
- return -ENXIO;
- }
layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
layers[0].size = SYNPS_EDAC_NR_CSROWS;
@@ -1413,6 +1402,12 @@ static int mc_probe(struct platform_device *pdev)
priv = mci->pvt_info;
priv->baseaddr = baseaddr;
priv->p_data = p_data;
+ if (!get_ecc_state(priv)) {
+ edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
+ rc = -ENODEV;
+ goto free_edac_mc;
+ }
+
spin_lock_init(&priv->reglock);
mc_init(mci, pdev);
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH AUTOSEL 6.12 28/69] ARM: tegra: Use I/O memcpy to write to IRAM
[not found] <20250804003119.3620476-1-sashal@kernel.org>
` (2 preceding siblings ...)
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 21/69] EDAC/synopsys: Clear the ECC counters on init Sasha Levin
@ 2025-08-04 0:30 ` Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 32/69] firmware: arm_scmi: power_control: Ensure SCMI_SYSPOWER_IDLE is set early during resume Sasha Levin
2025-08-04 0:31 ` [PATCH AUTOSEL 6.12 60/69] imx8m-blk-ctrl: set ISI panic write hurry level Sasha Levin
5 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2025-08-04 0:30 UTC (permalink / raw)
To: patches, stable
Cc: Aaron Kling, Thierry Reding, Sasha Levin, thierry.reding,
jonathanh, linux-arm-kernel, linux-tegra
From: Aaron Kling <webgeek1234@gmail.com>
[ Upstream commit 398e67e0f5ae04b29bcc9cbf342e339fe9d3f6f1 ]
Kasan crashes the kernel trying to check boundaries when using the
normal memcpy.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
Link: https://lore.kernel.org/r/20250522-mach-tegra-kasan-v1-1-419041b8addb@gmail.com
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Based on my analysis of this commit, here's my determination:
**Backport Status: YES**
This commit should be backported to stable kernel trees for the
following reasons:
1. **Fixes a real crash/bug**: The commit fixes a KASAN (Kernel Address
Sanitizer) crash that occurs when using regular `memcpy()` to write
to IRAM (Internal RAM). This is a functional bug that causes kernel
crashes when KASAN is enabled.
2. **Small and contained fix**: The change is minimal - it simply
replaces `memcpy()` with `memcpy_toio()` on line 66 of arch/arm/mach-
tegra/reset.c. This is a one-line change that doesn't alter any logic
or introduce new features.
3. **Follows proper I/O memory access patterns**: The fix is technically
correct. According to the kernel documentation in
Documentation/driver-api/device-io.rst, I/O memory regions (which
IRAM is mapped as via `IO_ADDRESS()`) should be accessed using
I/O-specific functions like `memcpy_toio()` rather than regular
`memcpy()`. The documentation explicitly states: "Do not use memset
or memcpy on IO addresses; they are not guaranteed to copy data in
order."
4. **No architectural changes**: The commit doesn't introduce any
architectural changes or new functionality. It's purely a bug fix
that corrects improper memory access.
5. **Minimal risk of regression**: Since this change only affects how
data is copied to IRAM during the Tegra CPU reset handler
initialization, and uses the proper kernel API for I/O memory access,
the risk of introducing new issues is very low.
6. **Platform-specific but important**: While this fix is specific to
ARM Tegra platforms, it fixes a crash that would affect any Tegra
system running with KASAN enabled. This is important for developers
and users who rely on KASAN for debugging.
The fact that `iram_base` is obtained through `IO_ADDRESS()` macro
clearly indicates this is I/O mapped memory that requires I/O-specific
accessors. KASAN correctly identified this misuse and crashed to prevent
potential issues. The fix properly uses `memcpy_toio()` which is
designed for copying to I/O memory regions and won't trigger KASAN
checks for regular memory access.
arch/arm/mach-tegra/reset.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index d5c805adf7a8..ea706fac6358 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -63,7 +63,7 @@ static void __init tegra_cpu_reset_handler_enable(void)
BUG_ON(is_enabled);
BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
- memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
+ memcpy_toio(iram_base, (void *)__tegra_cpu_reset_handler_start,
tegra_cpu_reset_handler_size);
err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH AUTOSEL 6.12 32/69] firmware: arm_scmi: power_control: Ensure SCMI_SYSPOWER_IDLE is set early during resume
[not found] <20250804003119.3620476-1-sashal@kernel.org>
` (3 preceding siblings ...)
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 28/69] ARM: tegra: Use I/O memcpy to write to IRAM Sasha Levin
@ 2025-08-04 0:30 ` Sasha Levin
2025-08-04 0:31 ` [PATCH AUTOSEL 6.12 60/69] imx8m-blk-ctrl: set ISI panic write hurry level Sasha Levin
5 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2025-08-04 0:30 UTC (permalink / raw)
To: patches, stable
Cc: Peng Fan, Sudeep Holla, Sasha Levin, arm-scmi, linux-arm-kernel
From: Peng Fan <peng.fan@nxp.com>
[ Upstream commit 9a0658d3991e6c82df87584b253454842f22f965 ]
Fix a race condition where a second suspend notification from another
SCMI agent wakes the system before SCMI_SYSPOWER_IDLE is set, leading
to ignored suspend requests. This is due to interrupts triggering early
execution of `scmi_userspace_notifier()` before the SCMI state is updated.
To resolve this, set SCMI_SYSPOWER_IDLE earlier in the device resume
path, prior to `thaw_processes()`. This ensures the SCMI state is
correct when the notifier runs, allowing the system to suspend again
as expected.
On some platforms using SCMI, SCP cannot distinguish between CPU idle
and suspend since both result in cluster power-off. By explicitly setting
the idle state early, the Linux SCMI agent can correctly re-suspend in
response to external notifications.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Message-Id: <20250704-scmi-pm-v2-2-9316cec2f9cc@nxp.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
**Backport Status: YES**
This commit should be backported to stable kernel trees. Here's my
extensive analysis:
## 1. Bug Fix Nature
The commit fixes a clear race condition bug that affects system
suspend/resume functionality on SCMI-based platforms. Looking at the
code changes:
- **Original bug** (lines 325-333 in original code): The
`scmi_suspend_work_func` sets `sc->state = SCMI_SYSPOWER_IDLE` AFTER
`pm_suspend()` returns
- **Race condition**: If another SCMI agent sends a suspend notification
while the system is resuming (after `pm_suspend()` returns but before
`SCMI_SYSPOWER_IDLE` is set), the `scmi_userspace_notifier` (line 305)
will see the state is still `SCMI_SYSPOWER_IN_PROGRESS` and ignore the
new suspend request
- **Impact**: The system fails to re-suspend when it should, breaking
power management functionality
## 2. Fix is Small and Contained
The fix is minimal and well-contained:
- Adds PM ops structure with only a resume callback
- Moves the state reset from work function to PM resume callback
- Total change is about 20 lines of code
- No API changes or architectural modifications
## 3. Clear User Impact
The commit message explicitly states this affects real platforms: "On
some platforms using SCMI, SCP cannot distinguish between CPU idle and
suspend since both result in cluster power-off." This indicates actual
hardware is affected by this bug.
## 4. Low Risk of Regression
The changes are:
- Limited to the SCMI power control driver
- Only modifies the timing of when `SCMI_SYSPOWER_IDLE` is set
- Uses standard PM callbacks (`dev_pm_ops`)
- No changes to core logic or protocol handling
## 5. Follows Stable Criteria
The fix meets stable kernel criteria:
- Fixes a real bug (race condition in suspend/resume)
- Small, focused change (~20 lines)
- Already tested and merged upstream
- Clear explanation of the problem and solution
- No new features added
## 6. Technical Correctness
The fix is technically sound:
- Setting `SCMI_SYSPOWER_IDLE` in the PM resume callback ensures it
happens before `thaw_processes()` completes
- This guarantees the state is correct when interrupts are re-enabled
and the notifier can run
- The use of `dev_set_drvdata()` and `dev_get_drvdata()` properly passes
the context to the PM callback
This is a textbook example of a stable-worthy commit: it fixes a
specific race condition bug with minimal code changes and clear impact
on affected systems.
.../firmware/arm_scmi/scmi_power_control.c | 22 ++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/arm_scmi/scmi_power_control.c b/drivers/firmware/arm_scmi/scmi_power_control.c
index 21f467a92942..ab0cee0d4bec 100644
--- a/drivers/firmware/arm_scmi/scmi_power_control.c
+++ b/drivers/firmware/arm_scmi/scmi_power_control.c
@@ -46,6 +46,7 @@
#include <linux/math.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/pm.h>
#include <linux/printk.h>
#include <linux/reboot.h>
#include <linux/scmi_protocol.h>
@@ -324,12 +325,7 @@ static int scmi_userspace_notifier(struct notifier_block *nb,
static void scmi_suspend_work_func(struct work_struct *work)
{
- struct scmi_syspower_conf *sc =
- container_of(work, struct scmi_syspower_conf, suspend_work);
-
pm_suspend(PM_SUSPEND_MEM);
-
- sc->state = SCMI_SYSPOWER_IDLE;
}
static int scmi_syspower_probe(struct scmi_device *sdev)
@@ -354,6 +350,7 @@ static int scmi_syspower_probe(struct scmi_device *sdev)
sc->required_transition = SCMI_SYSTEM_MAX;
sc->userspace_nb.notifier_call = &scmi_userspace_notifier;
sc->dev = &sdev->dev;
+ dev_set_drvdata(&sdev->dev, sc);
INIT_WORK(&sc->suspend_work, scmi_suspend_work_func);
@@ -363,6 +360,18 @@ static int scmi_syspower_probe(struct scmi_device *sdev)
NULL, &sc->userspace_nb);
}
+static int scmi_system_power_resume(struct device *dev)
+{
+ struct scmi_syspower_conf *sc = dev_get_drvdata(dev);
+
+ sc->state = SCMI_SYSPOWER_IDLE;
+ return 0;
+}
+
+static const struct dev_pm_ops scmi_system_power_pmops = {
+ SET_SYSTEM_SLEEP_PM_OPS(NULL, scmi_system_power_resume)
+};
+
static const struct scmi_device_id scmi_id_table[] = {
{ SCMI_PROTOCOL_SYSTEM, "syspower" },
{ },
@@ -370,6 +379,9 @@ static const struct scmi_device_id scmi_id_table[] = {
MODULE_DEVICE_TABLE(scmi, scmi_id_table);
static struct scmi_driver scmi_system_power_driver = {
+ .driver = {
+ .pm = &scmi_system_power_pmops,
+ },
.name = "scmi-system-power",
.probe = scmi_syspower_probe,
.id_table = scmi_id_table,
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH AUTOSEL 6.12 60/69] imx8m-blk-ctrl: set ISI panic write hurry level
[not found] <20250804003119.3620476-1-sashal@kernel.org>
` (4 preceding siblings ...)
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 32/69] firmware: arm_scmi: power_control: Ensure SCMI_SYSPOWER_IDLE is set early during resume Sasha Levin
@ 2025-08-04 0:31 ` Sasha Levin
5 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2025-08-04 0:31 UTC (permalink / raw)
To: patches, stable
Cc: Krzysztof Hałasa, Ulf Hansson, Sasha Levin, shawnguo,
peng.fan, imx, linux-arm-kernel
From: Krzysztof Hałasa <khalasa@piap.pl>
[ Upstream commit c01fba0b4869cada5403fffff416cd1675dba078 ]
Apparently, ISI needs cache settings similar to LCDIF.
Otherwise we get artefacts in the image.
Tested on i.MX8MP.
Signed-off-by: Krzysztof Hałasa <khalasa@piap.pl>
Link: https://lore.kernel.org/r/m3ldr69lsw.fsf@t19.piap.pl
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Based on my analysis of the commit and the surrounding code:
**Backport Status: YES**
This commit should be backported to stable kernel trees for the
following reasons:
1. **Fixes a real user-visible bug**: The commit fixes image artifacts
in the ISI (Image Sensor Interface) on i.MX8MP. This is a functional
bug that affects users of camera/image capture functionality.
2. **Small and contained change**: The fix adds only 10 lines of code
that set ISI panic write hurry levels in the
`imx8mp_media_power_notifier` function. It's a minimal change
confined to the i.MX8MP media block controller.
3. **Follows established pattern**: The fix mirrors the existing LCDIF
panic read hurry level fix (commit 06a9a229b159) that was already
applied for display FIFO underflow issues. The ISI needs similar
cache settings to prevent artifacts.
4. **Hardware-specific fix**: The change only affects i.MX8MP hardware
and is guarded by the platform-specific power notifier function,
minimizing risk to other platforms.
5. **Clear problem and solution**: The commit message clearly states the
problem (image artifacts) and the solution (setting ISI panic write
hurry levels similar to LCDIF), making it a straightforward hardware
configuration fix.
6. **No architectural changes**: This is purely a hardware register
configuration change during power-on sequences, not introducing new
features or changing kernel architecture.
The fix addresses a hardware-specific issue where the ISI (Image Sensor
Interface) needs proper cache/priority settings to avoid image
artifacts, similar to how the LCDIF (display interface) needs such
settings to avoid display FIFO underflow. This is an important fix for
anyone using camera functionality on i.MX8MP platforms.
drivers/pmdomain/imx/imx8m-blk-ctrl.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
index ca942d7929c2..8b7b175f5896 100644
--- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
@@ -665,6 +665,11 @@ static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
#define LCDIF_1_RD_HURRY GENMASK(15, 13)
#define LCDIF_0_RD_HURRY GENMASK(12, 10)
+#define ISI_CACHE_CTRL 0x50
+#define ISI_V_WR_HURRY GENMASK(28, 26)
+#define ISI_U_WR_HURRY GENMASK(25, 23)
+#define ISI_Y_WR_HURRY GENMASK(22, 20)
+
static int imx8mp_media_power_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -694,6 +699,11 @@ static int imx8mp_media_power_notifier(struct notifier_block *nb,
regmap_set_bits(bc->regmap, LCDIF_ARCACHE_CTRL,
FIELD_PREP(LCDIF_1_RD_HURRY, 7) |
FIELD_PREP(LCDIF_0_RD_HURRY, 7));
+ /* Same here for ISI */
+ regmap_set_bits(bc->regmap, ISI_CACHE_CTRL,
+ FIELD_PREP(ISI_V_WR_HURRY, 7) |
+ FIELD_PREP(ISI_U_WR_HURRY, 7) |
+ FIELD_PREP(ISI_Y_WR_HURRY, 7));
}
return NOTIFY_OK;
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-08-04 1:20 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20250804003119.3620476-1-sashal@kernel.org>
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 13/69] remoteproc: imx_rproc: skip clock enable when M-core is managed by the SCU Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 19/69] ARM: rockchip: fix kernel hang during smp initialization Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 21/69] EDAC/synopsys: Clear the ECC counters on init Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 28/69] ARM: tegra: Use I/O memcpy to write to IRAM Sasha Levin
2025-08-04 0:30 ` [PATCH AUTOSEL 6.12 32/69] firmware: arm_scmi: power_control: Ensure SCMI_SYSPOWER_IDLE is set early during resume Sasha Levin
2025-08-04 0:31 ` [PATCH AUTOSEL 6.12 60/69] imx8m-blk-ctrl: set ISI panic write hurry level Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).