diff options
author | Horia Geantă <horia.geanta@nxp.com> | 2019-11-13 09:42:34 +0200 |
---|---|---|
committer | Dong Aisheng <aisheng.dong@nxp.com> | 2019-12-02 18:02:22 +0800 |
commit | 4d3a0772bf9912074034b3af2868b1a30baf2e42 (patch) | |
tree | b864ae726ddb8bb473d9abdde649c28eb9759e0d | |
parent | 4458e5f8bb3f864be6ce0a519351d5d730831285 (diff) |
LFV-26 crypto: caam - fix Secure Memory driver init
SM driver is buggy, since it runs irrespective of the presence of
the caam-sm DT node.
This causes issues on SoCs that have caam HW, but without support
for secure memory.
Let's transform the module in a library, in the same way (and for
the same reasons) we did for the other job ring-dependent drivers
(caamalg, caamhash etc.) in
commit 1b46c90c8e00 ("crypto: caam - convert top level drivers to libraries")
SM test module is also updated, to run only when needed.
Fixes: 54e3fcf89f97 ("MLKU-25-3 crypto: caam - add Secure Memory support")
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com>
-rw-r--r-- | drivers/crypto/caam/Kconfig | 2 | ||||
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 2 | ||||
-rw-r--r-- | drivers/crypto/caam/intern.h | 19 | ||||
-rw-r--r-- | drivers/crypto/caam/jr.c | 6 | ||||
-rw-r--r-- | drivers/crypto/caam/sm.h | 1 | ||||
-rw-r--r-- | drivers/crypto/caam/sm_store.c | 80 | ||||
-rw-r--r-- | drivers/crypto/caam/sm_test.c | 7 |
7 files changed, 42 insertions, 75 deletions
diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index 127561f372fc..81a218e5ba6b 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -166,7 +166,7 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST just before the RNG is registered with the hw_random API. config CRYPTO_DEV_FSL_CAAM_SM - tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" + bool "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" help Enables use of a prototype kernel-level Keystore API with CAAM Secure Memory for insertion/extraction of bus-protected secrets. diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index d87266256cff..b9dc6d92f94b 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -763,6 +763,8 @@ iomap_ctrl: ctrlpriv->sm_size = resource_size(&res_regs); else ctrlpriv->sm_size = PG_SIZE_64K; + + ctrlpriv->sm_present = 1; of_node_put(np); if (!reg_access) diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index e888d57aceae..70810c52aee6 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h @@ -86,6 +86,7 @@ struct caam_drv_private { */ u8 total_jobrs; /* Total Job Rings in device */ u8 qi_present; /* Nonzero if QI present in device */ + u8 sm_present; /* Nonzero if Secure Memory is supported */ u8 mc_en; /* Nonzero if MC f/w is active */ u8 scu_en; /* Nonzero if SCU f/w is active */ u8 optee_en; /* Nonzero if OP-TEE f/w is active */ @@ -200,6 +201,24 @@ static inline void caam_qi_algapi_exit(void) #endif /* CONFIG_CAAM_QI */ +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_SM + +int caam_sm_startup(struct device *dev); +void caam_sm_shutdown(struct device *dev); + +#else + +static inline int caam_sm_startup(struct device *dev) +{ + return 0; +} + +static inline void caam_sm_shutdown(struct device *dev) +{ +} + +#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_SM */ + #ifdef CONFIG_DEBUG_FS static int caam_debugfs_u64_get(void *data, u64 *val) { diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index fb91f8b33054..2ae792db4b90 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -34,6 +34,7 @@ static void register_algs(struct device *dev) if (++active_devs != 1) goto algs_unlock; + caam_sm_startup(dev); caam_algapi_init(dev); caam_algapi_hash_init(dev); caam_pkc_init(dev); @@ -44,7 +45,7 @@ algs_unlock: mutex_unlock(&algs_lock); } -static void unregister_algs(void) +static void unregister_algs(struct device *dev) { mutex_lock(&algs_lock); @@ -57,6 +58,7 @@ static void unregister_algs(void) caam_pkc_exit(); caam_algapi_hash_exit(); caam_algapi_exit(); + caam_sm_shutdown(dev); algs_unlock: mutex_unlock(&algs_lock); @@ -143,7 +145,7 @@ static int caam_jr_remove(struct platform_device *pdev) } /* Unregister JR-based RNG & crypto algorithms */ - unregister_algs(); + unregister_algs(jrdev->parent); /* Remove the node from Physical JobR list maintained by driver */ spin_lock(&driver_data.jr_alloc_lock); diff --git a/drivers/crypto/caam/sm.h b/drivers/crypto/caam/sm.h index 84863d6b09ca..614c9b4d373f 100644 --- a/drivers/crypto/caam/sm.h +++ b/drivers/crypto/caam/sm.h @@ -41,7 +41,6 @@ void sm_init_keystore(struct device *dev); u32 sm_detect_keystore_units(struct device *dev); int sm_establish_keystore(struct device *dev, u32 unit); void sm_release_keystore(struct device *dev, u32 unit); -void caam_sm_shutdown(struct platform_device *pdev); int caam_sm_example_init(struct platform_device *pdev); /* Keystore accessor functions */ diff --git a/drivers/crypto/caam/sm_store.c b/drivers/crypto/caam/sm_store.c index 2e23de3ce602..326edbd06ed5 100644 --- a/drivers/crypto/caam/sm_store.c +++ b/drivers/crypto/caam/sm_store.c @@ -1053,9 +1053,9 @@ EXPORT_SYMBOL(sm_keystore_slot_import); * Also, simply uses ring 0 for execution at the present */ -int caam_sm_startup(struct platform_device *pdev) +int caam_sm_startup(struct device *ctrldev) { - struct device *ctrldev, *smdev; + struct device *smdev; struct caam_drv_private *ctrlpriv; struct caam_drv_private_sm *smpriv; struct caam_drv_private_jr *jrpriv; /* need this for reg page */ @@ -1065,17 +1065,10 @@ int caam_sm_startup(struct platform_device *pdev) int ret = 0; struct device_node *np; - ctrldev = &pdev->dev; ctrlpriv = dev_get_drvdata(ctrldev); - /* - * If ctrlpriv is NULL, it's probably because the caam driver wasn't - * properly initialized (e.g. RNG4 init failed). Thus, bail out here. - */ - if (!ctrlpriv) { - ret = -ENODEV; - goto exit; - } + if (!ctrlpriv->sm_present) + return 0; /* * Set up the private block for secure memory @@ -1248,14 +1241,16 @@ exit: return ret; } -void caam_sm_shutdown(struct platform_device *pdev) +void caam_sm_shutdown(struct device *ctrldev) { - struct device *ctrldev, *smdev; + struct device *smdev; struct caam_drv_private *priv; struct caam_drv_private_sm *smpriv; - ctrldev = &pdev->dev; priv = dev_get_drvdata(ctrldev); + if (!priv->sm_present) + return; + smdev = priv->smdev; /* Return if resource not initialized by startup */ @@ -1273,60 +1268,3 @@ void caam_sm_shutdown(struct platform_device *pdev) kfree(smpriv); } EXPORT_SYMBOL(caam_sm_shutdown); - -static void __exit caam_sm_exit(void) -{ - struct device_node *dev_node; - struct platform_device *pdev; - - dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); - if (!dev_node) { - dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); - if (!dev_node) - return; - } - - pdev = of_find_device_by_node(dev_node); - if (!pdev) - return; - - of_node_put(dev_node); - - caam_sm_shutdown(pdev); - - return; -} - -static int __init caam_sm_init(void) -{ - struct device_node *dev_node; - struct platform_device *pdev; - - /* - * Do of_find_compatible_node() then of_find_device_by_node() - * once a functional device tree is available - */ - dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); - if (!dev_node) { - dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); - if (!dev_node) - return -ENODEV; - } - - pdev = of_find_device_by_node(dev_node); - if (!pdev) - return -ENODEV; - - of_node_get(dev_node); - - caam_sm_startup(pdev); - - return 0; -} - -module_init(caam_sm_init); -module_exit(caam_sm_exit); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore"); -MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD"); diff --git a/drivers/crypto/caam/sm_test.c b/drivers/crypto/caam/sm_test.c index 3910cfbd24de..c31beddcad15 100644 --- a/drivers/crypto/caam/sm_test.c +++ b/drivers/crypto/caam/sm_test.c @@ -531,6 +531,7 @@ static int __init caam_sm_test_init(void) { struct device_node *dev_node; struct platform_device *pdev; + struct caam_drv_private *priv; int ret; /* @@ -550,6 +551,12 @@ static int __init caam_sm_test_init(void) of_node_put(dev_node); + priv = dev_get_drvdata(&pdev->dev); + if (!priv->sm_present) { + dev_info(&pdev->dev, "No SM support, skipping tests\n"); + return -ENODEV; + } + ret = caam_sm_example_init(pdev); if (ret) dev_err(&pdev->dev, "SM test failed: %d\n", ret); |