[PATCH v3 1/4] crypto: caam - Prevent crash on suspend with iMX8QM / iMX8ULP
Frank Li
Frank.li at nxp.com
Wed May 28 07:52:59 PDT 2025
On Wed, May 28, 2025 at 02:43:07PM +0000, John Ernberg wrote:
> Since the CAAM on these SoCs is managed by another ARM core, called the
> SECO (Security Controller) on iMX8QM and Secure Enclave on iMX8ULP, which
> also reserves access to register page 0 suspend operations cannot touch
> this page.
>
> This is similar to when running OPTEE, where OPTEE will reserve page 0.
>
> Track this situation using a new state variable no_page0, reflecting if
> page 0 is reserved elsewhere, either by other management cores in SoC or
> by OPTEE.
>
> Replace the optee_en check in suspend/resume with the new check.
>
> optee_en cannot go away as it's needed elsewhere to gate OPTEE specific
> situations.
>
> Fixes the following splat at suspend:
>
> Internal error: synchronous external abort: 0000000096000010 [#1] SMP
> Hardware name: Freescale i.MX8QXP ACU6C (DT)
> pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : readl+0x0/0x18
> lr : rd_reg32+0x18/0x3c
> sp : ffffffc08192ba20
> x29: ffffffc08192ba20 x28: ffffff8025190000 x27: 0000000000000000
> x26: ffffffc0808ae808 x25: ffffffc080922338 x24: ffffff8020e89090
> x23: 0000000000000000 x22: ffffffc080922000 x21: ffffff8020e89010
> x20: ffffffc080387ef8 x19: ffffff8020e89010 x18: 000000005d8000d5
> x17: 0000000030f35963 x16: 000000008f785f3f x15: 000000003b8ef57c
> x14: 00000000c418aef8 x13: 00000000f5fea526 x12: 0000000000000001
> x11: 0000000000000002 x10: 0000000000000001 x9 : 0000000000000000
> x8 : ffffff8025190870 x7 : ffffff8021726880 x6 : 0000000000000002
> x5 : ffffff80217268f0 x4 : ffffff8021726880 x3 : ffffffc081200000
> x2 : 0000000000000001 x1 : ffffff8020e89010 x0 : ffffffc081200004
> Call trace:
> readl+0x0/0x18
> caam_ctrl_suspend+0x30/0xdc
> dpm_run_callback.constprop.0+0x24/0x5c
> device_suspend+0x170/0x2e8
> dpm_suspend+0xa0/0x104
> dpm_suspend_start+0x48/0x50
> suspend_devices_and_enter+0x7c/0x45c
> pm_suspend+0x148/0x160
> state_store+0xb4/0xf8
> kobj_attr_store+0x14/0x24
> sysfs_kf_write+0x38/0x48
> kernfs_fop_write_iter+0xb4/0x178
> vfs_write+0x118/0x178
> ksys_write+0x6c/0xd0
> __arm64_sys_write+0x14/0x1c
> invoke_syscall.constprop.0+0x64/0xb0
> do_el0_svc+0x90/0xb0
> el0_svc+0x18/0x44
> el0t_64_sync_handler+0x88/0x124
> el0t_64_sync+0x150/0x154
> Code: 88dffc21 88dffc21 5ac00800 d65f03c0 (b9400000)
>
> Fixes: d2835701d93c ("crypto: caam - i.MX8ULP donot have CAAM page0 access")
> Fixes: 61bb8db6f682 ("crypto: caam - Add support for i.MX8QM")
Why need two fixes tags? It should be enough to keep oldest one.
Frank
> Cc: stable at kernel.org # v6.10+
> Signed-off-by: John Ernberg <john.ernberg at actia.se>
>
> ---
>
> I noticed this when enabling the iMX8QXP support (next patch), hence the
> iMX8QXP backtrace, but the iMX8QM CAAM integration works exactly the same
> and according to the NXP tree [1] the iMX8ULP suffers the same issue.
>
> [1]: https://github.com/nxp-imx/linux-imx/commit/653712ffe52dd59f407af1b781ce318f3d9e17bb
>
> ---
>
> v3:
> - no changes
>
> v2:
> - Adjust commit message to make it clearer what is happening around no_page0 (Frank Li)
> ---
> drivers/crypto/caam/ctrl.c | 5 +++--
> drivers/crypto/caam/intern.h | 1 +
> 2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
> index 38ff931059b4..766c447c9cfb 100644
> --- a/drivers/crypto/caam/ctrl.c
> +++ b/drivers/crypto/caam/ctrl.c
> @@ -831,7 +831,7 @@ static int caam_ctrl_suspend(struct device *dev)
> {
> const struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
>
> - if (ctrlpriv->caam_off_during_pm && !ctrlpriv->optee_en)
> + if (ctrlpriv->caam_off_during_pm && !ctrlpriv->no_page0)
> caam_state_save(dev);
>
> return 0;
> @@ -842,7 +842,7 @@ static int caam_ctrl_resume(struct device *dev)
> struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
> int ret = 0;
>
> - if (ctrlpriv->caam_off_during_pm && !ctrlpriv->optee_en) {
> + if (ctrlpriv->caam_off_during_pm && !ctrlpriv->no_page0) {
> caam_state_restore(dev);
>
> /* HW and rng will be reset so deinstantiation can be removed */
> @@ -908,6 +908,7 @@ static int caam_probe(struct platform_device *pdev)
>
> imx_soc_data = imx_soc_match->data;
> reg_access = reg_access && imx_soc_data->page0_access;
> + ctrlpriv->no_page0 = !reg_access;
> /*
> * CAAM clocks cannot be controlled from kernel.
> */
> diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
> index e51320150872..51c90d17a40d 100644
> --- a/drivers/crypto/caam/intern.h
> +++ b/drivers/crypto/caam/intern.h
> @@ -115,6 +115,7 @@ struct caam_drv_private {
> u8 blob_present; /* Nonzero if BLOB support present in device */
> u8 mc_en; /* Nonzero if MC f/w is active */
> u8 optee_en; /* Nonzero if OP-TEE f/w is active */
> + u8 no_page0; /* Nonzero if register page 0 is not controlled by Linux */
> bool pr_support; /* RNG prediction resistance available */
> int secvio_irq; /* Security violation interrupt number */
> int virt_en; /* Virtualization enabled in CAAM */
> --
> 2.49.0
More information about the linux-arm-kernel
mailing list