| From 1286c9b10f76b122ad1b328cc1bec17ac4d5908e Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com> |
| Date: Wed, 13 Nov 2019 09:42:34 +0200 |
| Subject: [PATCH] LFV-26 crypto: caam - fix Secure Memory driver init |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| 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> |
| --- |
| drivers/crypto/caam/Kconfig | 2 +- |
| drivers/crypto/caam/ctrl.c | 2 ++ |
| drivers/crypto/caam/intern.h | 19 ++++++++++ |
| drivers/crypto/caam/jr.c | 6 ++-- |
| drivers/crypto/caam/sm.h | 1 - |
| drivers/crypto/caam/sm_store.c | 80 +++++------------------------------------- |
| drivers/crypto/caam/sm_test.c | 7 ++++ |
| 7 files changed, 42 insertions(+), 75 deletions(-) |
| |
| --- a/drivers/crypto/caam/Kconfig |
| +++ b/drivers/crypto/caam/Kconfig |
| @@ -167,7 +167,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. |
| --- 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) |
| --- 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(v |
| |
| #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) |
| { |
| --- a/drivers/crypto/caam/jr.c |
| +++ b/drivers/crypto/caam/jr.c |
| @@ -34,6 +34,7 @@ static void register_algs(struct device |
| 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 platfor |
| } |
| |
| /* 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); |
| --- 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 */ |
| --- 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_devi |
| 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_de |
| 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"); |
| --- 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); |