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 1b46c90c8e ("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>
This commit is contained in:
Horia Geantă 2019-11-13 09:42:34 +02:00 committed by Dong Aisheng
parent 4458e5f8bb
commit 4d3a0772bf
7 changed files with 42 additions and 75 deletions

View File

@ -166,7 +166,7 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST
just before the RNG is registered with the hw_random API. just before the RNG is registered with the hw_random API.
config CRYPTO_DEV_FSL_CAAM_SM config CRYPTO_DEV_FSL_CAAM_SM
tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" bool "CAAM Secure Memory / Keystore API (EXPERIMENTAL)"
help help
Enables use of a prototype kernel-level Keystore API with CAAM Enables use of a prototype kernel-level Keystore API with CAAM
Secure Memory for insertion/extraction of bus-protected secrets. Secure Memory for insertion/extraction of bus-protected secrets.

View File

@ -763,6 +763,8 @@ iomap_ctrl:
ctrlpriv->sm_size = resource_size(&res_regs); ctrlpriv->sm_size = resource_size(&res_regs);
else else
ctrlpriv->sm_size = PG_SIZE_64K; ctrlpriv->sm_size = PG_SIZE_64K;
ctrlpriv->sm_present = 1;
of_node_put(np); of_node_put(np);
if (!reg_access) if (!reg_access)

View File

@ -86,6 +86,7 @@ struct caam_drv_private {
*/ */
u8 total_jobrs; /* Total Job Rings in device */ u8 total_jobrs; /* Total Job Rings in device */
u8 qi_present; /* Nonzero if QI present 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 mc_en; /* Nonzero if MC f/w is active */
u8 scu_en; /* Nonzero if SCU 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 */ 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 */ #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 #ifdef CONFIG_DEBUG_FS
static int caam_debugfs_u64_get(void *data, u64 *val) static int caam_debugfs_u64_get(void *data, u64 *val)
{ {

View File

@ -34,6 +34,7 @@ static void register_algs(struct device *dev)
if (++active_devs != 1) if (++active_devs != 1)
goto algs_unlock; goto algs_unlock;
caam_sm_startup(dev);
caam_algapi_init(dev); caam_algapi_init(dev);
caam_algapi_hash_init(dev); caam_algapi_hash_init(dev);
caam_pkc_init(dev); caam_pkc_init(dev);
@ -44,7 +45,7 @@ algs_unlock:
mutex_unlock(&algs_lock); mutex_unlock(&algs_lock);
} }
static void unregister_algs(void) static void unregister_algs(struct device *dev)
{ {
mutex_lock(&algs_lock); mutex_lock(&algs_lock);
@ -57,6 +58,7 @@ static void unregister_algs(void)
caam_pkc_exit(); caam_pkc_exit();
caam_algapi_hash_exit(); caam_algapi_hash_exit();
caam_algapi_exit(); caam_algapi_exit();
caam_sm_shutdown(dev);
algs_unlock: algs_unlock:
mutex_unlock(&algs_lock); mutex_unlock(&algs_lock);
@ -143,7 +145,7 @@ static int caam_jr_remove(struct platform_device *pdev)
} }
/* Unregister JR-based RNG & crypto algorithms */ /* Unregister JR-based RNG & crypto algorithms */
unregister_algs(); unregister_algs(jrdev->parent);
/* Remove the node from Physical JobR list maintained by driver */ /* Remove the node from Physical JobR list maintained by driver */
spin_lock(&driver_data.jr_alloc_lock); spin_lock(&driver_data.jr_alloc_lock);

View File

@ -41,7 +41,6 @@ void sm_init_keystore(struct device *dev);
u32 sm_detect_keystore_units(struct device *dev); u32 sm_detect_keystore_units(struct device *dev);
int sm_establish_keystore(struct device *dev, u32 unit); int sm_establish_keystore(struct device *dev, u32 unit);
void sm_release_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); int caam_sm_example_init(struct platform_device *pdev);
/* Keystore accessor functions */ /* Keystore accessor functions */

View File

@ -1053,9 +1053,9 @@ EXPORT_SYMBOL(sm_keystore_slot_import);
* Also, simply uses ring 0 for execution at the present * 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 *ctrlpriv;
struct caam_drv_private_sm *smpriv; struct caam_drv_private_sm *smpriv;
struct caam_drv_private_jr *jrpriv; /* need this for reg page */ 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; int ret = 0;
struct device_node *np; struct device_node *np;
ctrldev = &pdev->dev;
ctrlpriv = dev_get_drvdata(ctrldev); ctrlpriv = dev_get_drvdata(ctrldev);
/* if (!ctrlpriv->sm_present)
* If ctrlpriv is NULL, it's probably because the caam driver wasn't return 0;
* properly initialized (e.g. RNG4 init failed). Thus, bail out here.
*/
if (!ctrlpriv) {
ret = -ENODEV;
goto exit;
}
/* /*
* Set up the private block for secure memory * Set up the private block for secure memory
@ -1248,14 +1241,16 @@ exit:
return ret; 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 *priv;
struct caam_drv_private_sm *smpriv; struct caam_drv_private_sm *smpriv;
ctrldev = &pdev->dev;
priv = dev_get_drvdata(ctrldev); priv = dev_get_drvdata(ctrldev);
if (!priv->sm_present)
return;
smdev = priv->smdev; smdev = priv->smdev;
/* Return if resource not initialized by startup */ /* Return if resource not initialized by startup */
@ -1273,60 +1268,3 @@ void caam_sm_shutdown(struct platform_device *pdev)
kfree(smpriv); kfree(smpriv);
} }
EXPORT_SYMBOL(caam_sm_shutdown); 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");

View File

@ -531,6 +531,7 @@ static int __init caam_sm_test_init(void)
{ {
struct device_node *dev_node; struct device_node *dev_node;
struct platform_device *pdev; struct platform_device *pdev;
struct caam_drv_private *priv;
int ret; int ret;
/* /*
@ -550,6 +551,12 @@ static int __init caam_sm_test_init(void)
of_node_put(dev_node); 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); ret = caam_sm_example_init(pdev);
if (ret) if (ret)
dev_err(&pdev->dev, "SM test failed: %d\n", ret); dev_err(&pdev->dev, "SM test failed: %d\n", ret);