| From 5ffc47feddcf8eb4d8ac7b42111a02c8e8146512 Mon Sep 17 00:00:00 2001 |
| From: John Ernberg <john.ernberg@actia.se> |
| Date: Wed, 11 Jun 2025 11:38:08 +0000 |
| Subject: crypto: caam - Prevent crash on suspend with iMX8QM / iMX8ULP |
| |
| From: John Ernberg <john.ernberg@actia.se> |
| |
| commit 5ffc47feddcf8eb4d8ac7b42111a02c8e8146512 upstream. |
| |
| 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") |
| Cc: stable@kernel.org # v6.10+ |
| Signed-off-by: John Ernberg <john.ernberg@actia.se> |
| Reviewed-by: Peng Fan <peng.fan@nxp.com> |
| Reviewed-by: Frank Li <Frank.Li@nxp.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/crypto/caam/ctrl.c | 5 +++-- |
| drivers/crypto/caam/intern.h | 1 + |
| 2 files changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/crypto/caam/ctrl.c |
| +++ b/drivers/crypto/caam/ctrl.c |
| @@ -830,7 +830,7 @@ static int caam_ctrl_suspend(struct devi |
| { |
| 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; |
| @@ -841,7 +841,7 @@ static int caam_ctrl_resume(struct devic |
| 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 */ |
| @@ -907,6 +907,7 @@ static int caam_probe(struct platform_de |
| |
| 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. |
| */ |
| --- 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 */ |