Commit a7cd942b authored by Horia Geantă's avatar Horia Geantă Committed by Herbert Xu
Browse files

crypto: caam/qi - DMA map keys using proper device



Currently there is a mismatch b/w the ICID (Isolation Context ID) used
for DMA mapping keys and ICID used for accessing them.
-keys are DMA mapped using a job ring device, thus a job ring ICID
-keys are accessed from descriptors enqueued via Queue Interface,
thus using QI ICID

[Note: ICIDs of JRs, QI are configured by U-boot / other entity by:
-fixing up the corresponding job ring and controller DT nodes
-setting up corresponding caam ICID registers]

In order to avoid IOMMU faults, DMA map the key using the controller
device instead of a job ring device.

Signed-off-by: default avatarHoria Geantă <horia.geanta@nxp.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent b2b2ee35
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -237,7 +237,7 @@ static int aead_setkey(struct crypto_aead *aead, const u8 *key,
		memcpy(ctx->key, keys.authkey, keys.authkeylen);
		memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
		       keys.enckeylen);
		dma_sync_single_for_device(jrdev, ctx->key_dma,
		dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
					   ctx->adata.keylen_pad +
					   keys.enckeylen, ctx->dir);
		goto skip_split_key;
@@ -251,8 +251,9 @@ static int aead_setkey(struct crypto_aead *aead, const u8 *key,

	/* postpend encryption key to auth split key */
	memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
				   keys.enckeylen, ctx->dir);
	dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
				   ctx->adata.keylen_pad + keys.enckeylen,
				   ctx->dir);
#ifdef DEBUG
	print_hex_dump(KERN_ERR, "ctx.key@" __stringify(__LINE__)": ",
		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
@@ -392,7 +393,8 @@ static int gcm_setkey(struct crypto_aead *aead,
#endif

	memcpy(ctx->key, key, keylen);
	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
	dma_sync_single_for_device(jrdev->parent, ctx->key_dma, keylen,
				   ctx->dir);
	ctx->cdata.keylen = keylen;

	ret = gcm_set_sh_desc(aead);
@@ -496,8 +498,8 @@ static int rfc4106_setkey(struct crypto_aead *aead,
	 * in the nonce. Update the AES key length.
	 */
	ctx->cdata.keylen = keylen - 4;
	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
				   ctx->dir);
	dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
				   ctx->cdata.keylen, ctx->dir);

	ret = rfc4106_set_sh_desc(aead);
	if (ret)
@@ -600,8 +602,8 @@ static int rfc4543_setkey(struct crypto_aead *aead,
	 * in the nonce. Update the AES key length.
	 */
	ctx->cdata.keylen = keylen - 4;
	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
				   ctx->dir);
	dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
				   ctx->cdata.keylen, ctx->dir);

	ret = rfc4543_set_sh_desc(aead);
	if (ret)
@@ -2414,6 +2416,7 @@ static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
			    bool uses_dkp)
{
	struct caam_drv_private *priv;
	struct device *dev;

	/*
	 * distribute tfms across job rings to ensure in-order
@@ -2425,16 +2428,17 @@ static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
		return PTR_ERR(ctx->jrdev);
	}

	priv = dev_get_drvdata(ctx->jrdev->parent);
	dev = ctx->jrdev->parent;
	priv = dev_get_drvdata(dev);
	if (priv->era >= 6 && uses_dkp)
		ctx->dir = DMA_BIDIRECTIONAL;
	else
		ctx->dir = DMA_TO_DEVICE;

	ctx->key_dma = dma_map_single(ctx->jrdev, ctx->key, sizeof(ctx->key),
	ctx->key_dma = dma_map_single(dev, ctx->key, sizeof(ctx->key),
				      ctx->dir);
	if (dma_mapping_error(ctx->jrdev, ctx->key_dma)) {
		dev_err(ctx->jrdev, "unable to map key\n");
	if (dma_mapping_error(dev, ctx->key_dma)) {
		dev_err(dev, "unable to map key\n");
		caam_jr_free(ctx->jrdev);
		return -ENOMEM;
	}
@@ -2443,7 +2447,7 @@ static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
	ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;

	ctx->qidev = ctx->jrdev->parent;
	ctx->qidev = dev;

	spin_lock_init(&ctx->lock);
	ctx->drv_ctx[ENCRYPT] = NULL;
@@ -2477,7 +2481,8 @@ static void caam_exit_common(struct caam_ctx *ctx)
	caam_drv_ctx_rel(ctx->drv_ctx[ENCRYPT]);
	caam_drv_ctx_rel(ctx->drv_ctx[DECRYPT]);

	dma_unmap_single(ctx->jrdev, ctx->key_dma, sizeof(ctx->key), ctx->dir);
	dma_unmap_single(ctx->jrdev->parent, ctx->key_dma, sizeof(ctx->key),
			 ctx->dir);

	caam_jr_free(ctx->jrdev);
}