| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | From 1286c9b10f76b122ad1b328cc1bec17ac4d5908e Mon Sep 17 00:00:00 2001 | 
 | 2 | From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com> | 
 | 3 | Date: Wed, 13 Nov 2019 09:42:34 +0200 | 
 | 4 | Subject: [PATCH] LFV-26 crypto: caam - fix Secure Memory driver init | 
 | 5 | MIME-Version: 1.0 | 
 | 6 | Content-Type: text/plain; charset=UTF-8 | 
 | 7 | Content-Transfer-Encoding: 8bit | 
 | 8 |  | 
 | 9 | SM driver is buggy, since it runs irrespective of the presence of | 
 | 10 | the caam-sm DT node. | 
 | 11 | This causes issues on SoCs that have caam HW, but without support | 
 | 12 | for secure memory. | 
 | 13 |  | 
 | 14 | Let's transform the module in a library, in the same way (and for | 
 | 15 | the same reasons) we did for the other job ring-dependent drivers | 
 | 16 | (caamalg, caamhash etc.) in | 
 | 17 | commit 1b46c90c8e00 ("crypto: caam - convert top level drivers to libraries") | 
 | 18 |  | 
 | 19 | SM test module is also updated, to run only when needed. | 
 | 20 |  | 
 | 21 | Fixes: 54e3fcf89f97 ("MLKU-25-3 crypto: caam - add Secure Memory support") | 
 | 22 | Signed-off-by: Horia Geantă <horia.geanta@nxp.com> | 
 | 23 | Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com> | 
 | 24 | --- | 
 | 25 |  drivers/crypto/caam/Kconfig    |  2 +- | 
 | 26 |  drivers/crypto/caam/ctrl.c     |  2 ++ | 
 | 27 |  drivers/crypto/caam/intern.h   | 19 ++++++++++ | 
 | 28 |  drivers/crypto/caam/jr.c       |  6 ++-- | 
 | 29 |  drivers/crypto/caam/sm.h       |  1 - | 
 | 30 |  drivers/crypto/caam/sm_store.c | 80 +++++------------------------------------- | 
 | 31 |  drivers/crypto/caam/sm_test.c  |  7 ++++ | 
 | 32 |  7 files changed, 42 insertions(+), 75 deletions(-) | 
 | 33 |  | 
 | 34 | --- a/drivers/crypto/caam/Kconfig | 
 | 35 | +++ b/drivers/crypto/caam/Kconfig | 
 | 36 | @@ -167,7 +167,7 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST | 
 | 37 |  	  just before the RNG is registered with the hw_random API. | 
 | 38 |   | 
 | 39 |  config CRYPTO_DEV_FSL_CAAM_SM | 
 | 40 | -	tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" | 
 | 41 | +	bool "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" | 
 | 42 |  	help | 
 | 43 |  	  Enables use of a prototype kernel-level Keystore API with CAAM | 
 | 44 |  	  Secure Memory for insertion/extraction of bus-protected secrets. | 
 | 45 | --- a/drivers/crypto/caam/ctrl.c | 
 | 46 | +++ b/drivers/crypto/caam/ctrl.c | 
 | 47 | @@ -763,6 +763,8 @@ iomap_ctrl: | 
 | 48 |  		ctrlpriv->sm_size = resource_size(&res_regs); | 
 | 49 |  	else | 
 | 50 |  		ctrlpriv->sm_size = PG_SIZE_64K; | 
 | 51 | + | 
 | 52 | +	ctrlpriv->sm_present = 1; | 
 | 53 |  	of_node_put(np); | 
 | 54 |   | 
 | 55 |  	if (!reg_access) | 
 | 56 | --- a/drivers/crypto/caam/intern.h | 
 | 57 | +++ b/drivers/crypto/caam/intern.h | 
 | 58 | @@ -86,6 +86,7 @@ struct caam_drv_private { | 
 | 59 |  	 */ | 
 | 60 |  	u8 total_jobrs;		/* Total Job Rings in device */ | 
 | 61 |  	u8 qi_present;		/* Nonzero if QI present in device */ | 
 | 62 | +	u8 sm_present;		/* Nonzero if Secure Memory is supported */ | 
 | 63 |  	u8 mc_en;		/* Nonzero if MC f/w is active */ | 
 | 64 |  	u8 scu_en;		/* Nonzero if SCU f/w is active */ | 
 | 65 |  	u8 optee_en;		/* Nonzero if OP-TEE f/w is active */ | 
 | 66 | @@ -200,6 +201,24 @@ static inline void caam_qi_algapi_exit(v | 
 | 67 |   | 
 | 68 |  #endif /* CONFIG_CAAM_QI */ | 
 | 69 |   | 
 | 70 | +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_SM | 
 | 71 | + | 
 | 72 | +int caam_sm_startup(struct device *dev); | 
 | 73 | +void caam_sm_shutdown(struct device *dev); | 
 | 74 | + | 
 | 75 | +#else | 
 | 76 | + | 
 | 77 | +static inline int caam_sm_startup(struct device *dev) | 
 | 78 | +{ | 
 | 79 | +	return 0; | 
 | 80 | +} | 
 | 81 | + | 
 | 82 | +static inline void caam_sm_shutdown(struct device *dev) | 
 | 83 | +{ | 
 | 84 | +} | 
 | 85 | + | 
 | 86 | +#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_SM */ | 
 | 87 | + | 
 | 88 |  #ifdef CONFIG_DEBUG_FS | 
 | 89 |  static int caam_debugfs_u64_get(void *data, u64 *val) | 
 | 90 |  { | 
 | 91 | --- a/drivers/crypto/caam/jr.c | 
 | 92 | +++ b/drivers/crypto/caam/jr.c | 
 | 93 | @@ -34,6 +34,7 @@ static void register_algs(struct device | 
 | 94 |  	if (++active_devs != 1) | 
 | 95 |  		goto algs_unlock; | 
 | 96 |   | 
 | 97 | +	caam_sm_startup(dev); | 
 | 98 |  	caam_algapi_init(dev); | 
 | 99 |  	caam_algapi_hash_init(dev); | 
 | 100 |  	caam_pkc_init(dev); | 
 | 101 | @@ -44,7 +45,7 @@ algs_unlock: | 
 | 102 |  	mutex_unlock(&algs_lock); | 
 | 103 |  } | 
 | 104 |   | 
 | 105 | -static void unregister_algs(void) | 
 | 106 | +static void unregister_algs(struct device *dev) | 
 | 107 |  { | 
 | 108 |  	mutex_lock(&algs_lock); | 
 | 109 |   | 
 | 110 | @@ -57,6 +58,7 @@ static void unregister_algs(void) | 
 | 111 |  	caam_pkc_exit(); | 
 | 112 |  	caam_algapi_hash_exit(); | 
 | 113 |  	caam_algapi_exit(); | 
 | 114 | +	caam_sm_shutdown(dev); | 
 | 115 |   | 
 | 116 |  algs_unlock: | 
 | 117 |  	mutex_unlock(&algs_lock); | 
 | 118 | @@ -143,7 +145,7 @@ static int caam_jr_remove(struct platfor | 
 | 119 |  	} | 
 | 120 |   | 
 | 121 |  	/* Unregister JR-based RNG & crypto algorithms */ | 
 | 122 | -	unregister_algs(); | 
 | 123 | +	unregister_algs(jrdev->parent); | 
 | 124 |   | 
 | 125 |  	/* Remove the node from Physical JobR list maintained by driver */ | 
 | 126 |  	spin_lock(&driver_data.jr_alloc_lock); | 
 | 127 | --- a/drivers/crypto/caam/sm.h | 
 | 128 | +++ b/drivers/crypto/caam/sm.h | 
 | 129 | @@ -41,7 +41,6 @@ void sm_init_keystore(struct device *dev | 
 | 130 |  u32 sm_detect_keystore_units(struct device *dev); | 
 | 131 |  int sm_establish_keystore(struct device *dev, u32 unit); | 
 | 132 |  void sm_release_keystore(struct device *dev, u32 unit); | 
 | 133 | -void caam_sm_shutdown(struct platform_device *pdev); | 
 | 134 |  int caam_sm_example_init(struct platform_device *pdev); | 
 | 135 |   | 
 | 136 |  /* Keystore accessor functions */ | 
 | 137 | --- a/drivers/crypto/caam/sm_store.c | 
 | 138 | +++ b/drivers/crypto/caam/sm_store.c | 
 | 139 | @@ -1053,9 +1053,9 @@ EXPORT_SYMBOL(sm_keystore_slot_import); | 
 | 140 |   * Also, simply uses ring 0 for execution at the present | 
 | 141 |   */ | 
 | 142 |   | 
 | 143 | -int caam_sm_startup(struct platform_device *pdev) | 
 | 144 | +int caam_sm_startup(struct device *ctrldev) | 
 | 145 |  { | 
 | 146 | -	struct device *ctrldev, *smdev; | 
 | 147 | +	struct device *smdev; | 
 | 148 |  	struct caam_drv_private *ctrlpriv; | 
 | 149 |  	struct caam_drv_private_sm *smpriv; | 
 | 150 |  	struct caam_drv_private_jr *jrpriv;	/* need this for reg page */ | 
 | 151 | @@ -1065,17 +1065,10 @@ int caam_sm_startup(struct platform_devi | 
 | 152 |  	int ret = 0; | 
 | 153 |   | 
 | 154 |  	struct device_node *np; | 
 | 155 | -	ctrldev = &pdev->dev; | 
 | 156 |  	ctrlpriv = dev_get_drvdata(ctrldev); | 
 | 157 |   | 
 | 158 | -	/* | 
 | 159 | -	 * If ctrlpriv is NULL, it's probably because the caam driver wasn't | 
 | 160 | -	 * properly initialized (e.g. RNG4 init failed). Thus, bail out here. | 
 | 161 | -	 */ | 
 | 162 | -	if (!ctrlpriv) { | 
 | 163 | -		ret = -ENODEV; | 
 | 164 | -		goto exit; | 
 | 165 | -	} | 
 | 166 | +	if (!ctrlpriv->sm_present) | 
 | 167 | +		return 0; | 
 | 168 |   | 
 | 169 |  	/* | 
 | 170 |  	 * Set up the private block for secure memory | 
 | 171 | @@ -1248,14 +1241,16 @@ exit: | 
 | 172 |  	return ret; | 
 | 173 |  } | 
 | 174 |   | 
 | 175 | -void caam_sm_shutdown(struct platform_device *pdev) | 
 | 176 | +void caam_sm_shutdown(struct device *ctrldev) | 
 | 177 |  { | 
 | 178 | -	struct device *ctrldev, *smdev; | 
 | 179 | +	struct device *smdev; | 
 | 180 |  	struct caam_drv_private *priv; | 
 | 181 |  	struct caam_drv_private_sm *smpriv; | 
 | 182 |   | 
 | 183 | -	ctrldev = &pdev->dev; | 
 | 184 |  	priv = dev_get_drvdata(ctrldev); | 
 | 185 | +	if (!priv->sm_present) | 
 | 186 | +		return; | 
 | 187 | + | 
 | 188 |  	smdev = priv->smdev; | 
 | 189 |   | 
 | 190 |  	/* Return if resource not initialized by startup */ | 
 | 191 | @@ -1273,60 +1268,3 @@ void caam_sm_shutdown(struct platform_de | 
 | 192 |  	kfree(smpriv); | 
 | 193 |  } | 
 | 194 |  EXPORT_SYMBOL(caam_sm_shutdown); | 
 | 195 | - | 
 | 196 | -static void  __exit caam_sm_exit(void) | 
 | 197 | -{ | 
 | 198 | -	struct device_node *dev_node; | 
 | 199 | -	struct platform_device *pdev; | 
 | 200 | - | 
 | 201 | -	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); | 
 | 202 | -	if (!dev_node) { | 
 | 203 | -		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); | 
 | 204 | -		if (!dev_node) | 
 | 205 | -			return; | 
 | 206 | -	} | 
 | 207 | - | 
 | 208 | -	pdev = of_find_device_by_node(dev_node); | 
 | 209 | -	if (!pdev) | 
 | 210 | -		return; | 
 | 211 | - | 
 | 212 | -	of_node_put(dev_node); | 
 | 213 | - | 
 | 214 | -	caam_sm_shutdown(pdev); | 
 | 215 | - | 
 | 216 | -	return; | 
 | 217 | -} | 
 | 218 | - | 
 | 219 | -static int __init caam_sm_init(void) | 
 | 220 | -{ | 
 | 221 | -	struct device_node *dev_node; | 
 | 222 | -	struct platform_device *pdev; | 
 | 223 | - | 
 | 224 | -	/* | 
 | 225 | -	 * Do of_find_compatible_node() then of_find_device_by_node() | 
 | 226 | -	 * once a functional device tree is available | 
 | 227 | -	 */ | 
 | 228 | -	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); | 
 | 229 | -	if (!dev_node) { | 
 | 230 | -		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); | 
 | 231 | -		if (!dev_node) | 
 | 232 | -			return -ENODEV; | 
 | 233 | -	} | 
 | 234 | - | 
 | 235 | -	pdev = of_find_device_by_node(dev_node); | 
 | 236 | -	if (!pdev) | 
 | 237 | -		return -ENODEV; | 
 | 238 | - | 
 | 239 | -	of_node_get(dev_node); | 
 | 240 | - | 
 | 241 | -	caam_sm_startup(pdev); | 
 | 242 | - | 
 | 243 | -	return 0; | 
 | 244 | -} | 
 | 245 | - | 
 | 246 | -module_init(caam_sm_init); | 
 | 247 | -module_exit(caam_sm_exit); | 
 | 248 | - | 
 | 249 | -MODULE_LICENSE("Dual BSD/GPL"); | 
 | 250 | -MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore"); | 
 | 251 | -MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD"); | 
 | 252 | --- a/drivers/crypto/caam/sm_test.c | 
 | 253 | +++ b/drivers/crypto/caam/sm_test.c | 
 | 254 | @@ -531,6 +531,7 @@ static int __init caam_sm_test_init(void | 
 | 255 |  { | 
 | 256 |  	struct device_node *dev_node; | 
 | 257 |  	struct platform_device *pdev; | 
 | 258 | +	struct caam_drv_private *priv; | 
 | 259 |  	int ret; | 
 | 260 |   | 
 | 261 |  	/* | 
 | 262 | @@ -550,6 +551,12 @@ static int __init caam_sm_test_init(void | 
 | 263 |   | 
 | 264 |  	of_node_put(dev_node); | 
 | 265 |   | 
 | 266 | +	priv = dev_get_drvdata(&pdev->dev); | 
 | 267 | +	if (!priv->sm_present) { | 
 | 268 | +		dev_info(&pdev->dev, "No SM support, skipping tests\n"); | 
 | 269 | +		return -ENODEV; | 
 | 270 | +	} | 
 | 271 | + | 
 | 272 |  	ret = caam_sm_example_init(pdev); | 
 | 273 |  	if (ret) | 
 | 274 |  		dev_err(&pdev->dev, "SM test failed: %d\n", ret); |