diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c index b619c42c..58761d3a 100644 --- a/drivers/crypto/tegra/tegra-se-aes.c +++ b/drivers/crypto/tegra/tegra-se-aes.c @@ -44,7 +44,6 @@ struct tegra_aes_reqctx { u32 *iv; u32 key1_id; u32 key2_id; - u32 *cmdbuf; }; struct tegra_aead_ctx { @@ -75,7 +74,6 @@ struct tegra_aead_reqctx { u32 key_id; u32 iv[4]; u8 authdata[16]; - u32 *cmdbuf; }; struct tegra_cmac_ctx { @@ -102,7 +100,6 @@ struct tegra_cmac_reqctx { u32 key_id; u32 *iv; u32 result[CMAC_RESULT_REG_COUNT]; - u32 *cmdbuf; }; /* increment counter (128-bit int) */ @@ -228,7 +225,7 @@ static int tegra234_aes_cfg(u32 alg, bool encrypt) static unsigned int tegra_aes_prep_cmd(struct tegra_se *se, struct tegra_aes_reqctx *rctx) { unsigned int data_count, res_bits, i = 0, j; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; dma_addr_t addr = rctx->datbuf.addr; data_count = rctx->len / AES_BLOCK_SIZE; @@ -332,14 +329,14 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq) /* Prepare the command and submit for execution */ cmdlen = tegra_aes_prep_cmd(se, rctx); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); + ret = tegra_se_host1x_submit(se, cmdlen); /* Copy the result */ tegra_aes_update_iv(req, ctx); scatterwalk_map_and_copy(rctx->datbuf.buf, req->dst, 0, req->cryptlen, 1); /* Free the buffer */ - dma_free_coherent(se->dev, rctx->datbuf.size, + dma_free_coherent(ctx->se->dev, rctx->datbuf.size, rctx->datbuf.buf, rctx->datbuf.addr); key2_free: @@ -349,8 +346,6 @@ key1_free: if (rctx->key1_id != ctx->key1_id) tegra_key_invalidate(ctx->se, rctx->key1_id, ctx->alg); out: - kfree(rctx->cmdbuf); - crypto_finalize_skcipher_request(se->engine, req, ret); return 0; @@ -643,13 +638,6 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt) if (!req->cryptlen) return 0; - if (ctx->alg == SE_ALG_ECB) - req->iv = NULL; - - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - return -ENOMEM; - rctx->encrypt = encrypt; rctx->config = se->regcfg->cfg(ctx->alg, encrypt); rctx->crypto_config = se->regcfg->crypto_cfg(ctx->alg, encrypt); @@ -803,7 +791,7 @@ static void tegra_aes_set_regcfg(struct tegra_se *se) static unsigned int tegra_gmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) { unsigned int data_count, res_bits, i = 0, j; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; data_count = (rctx->assoclen / AES_BLOCK_SIZE); res_bits = (rctx->assoclen % AES_BLOCK_SIZE) * 8; @@ -849,7 +837,7 @@ static unsigned int tegra_gmac_prep_cmd(struct tegra_se *se, struct tegra_aead_r static unsigned int tegra_gcm_crypt_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) { unsigned int data_count, res_bits, i = 0, j; - u32 *cpuvaddr = rctx->cmdbuf, op; + u32 *cpuvaddr = se->cmdbuf->addr, op; data_count = (rctx->cryptlen / AES_BLOCK_SIZE); res_bits = (rctx->cryptlen % AES_BLOCK_SIZE) * 8; @@ -971,7 +959,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct cmdlen = tegra_gmac_prep_cmd(se, rctx); - return tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); + return tegra_se_host1x_submit(se, cmdlen); } static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx) @@ -988,7 +976,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc /* Prepare command and submit */ cmdlen = tegra_gcm_crypt_prep_cmd(se, rctx); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); + ret = tegra_se_host1x_submit(se, cmdlen); if (ret) return ret; @@ -1002,7 +990,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx) { struct tegra_se *se = ctx->se; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; int cmdlen, ret, offset; rctx->config = se->regcfg->cfg(ctx->final_alg, rctx->encrypt); @@ -1011,7 +999,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc /* Prepare command and submit */ cmdlen = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); + ret = tegra_se_host1x_submit(se, cmdlen); if (ret) return ret; @@ -1028,7 +1016,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc static int tegra_gcm_hw_verify(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx, u8 *mac) { struct tegra_se *se = ctx->se; - u32 result, *cpuvaddr = rctx->cmdbuf; + u32 result, *cpuvaddr = se->cmdbuf->addr; int size, ret; memcpy(rctx->inbuf.buf, mac, rctx->authsize); @@ -1040,7 +1028,7 @@ static int tegra_gcm_hw_verify(struct tegra_aead_ctx *ctx, struct tegra_aead_req /* Prepare command and submit */ size = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx); - ret = tegra_se_host1x_submit(se, cpuvaddr, size); + ret = tegra_se_host1x_submit(se, size); if (ret) return ret; @@ -1089,7 +1077,7 @@ static inline int tegra_ccm_check_iv(const u8 *iv) static unsigned int tegra_cbcmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) { unsigned int data_count, i = 0; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; data_count = (rctx->inbuf.size / AES_BLOCK_SIZE) - 1; @@ -1123,7 +1111,7 @@ static unsigned int tegra_cbcmac_prep_cmd(struct tegra_se *se, struct tegra_aead static unsigned int tegra_ctr_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) { unsigned int i = 0, j; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; cpuvaddr[i++] = host1x_opcode_setpayload(SE_CRYPTO_CTR_REG_COUNT); cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->linear_ctr); @@ -1171,7 +1159,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_se *se, struct tegra_aead_reqctx *rc /* Prepare command and submit */ cmdlen = tegra_cbcmac_prep_cmd(se, rctx); - return tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); + return tegra_se_host1x_submit(se, cmdlen); } static int tegra_ccm_set_msg_len(u8 *block, unsigned int msglen, int csize) @@ -1376,7 +1364,7 @@ static int tegra_ccm_do_ctr(struct tegra_se *se, struct tegra_aead_reqctx *rctx) /* Prepare command and submit */ cmdlen = tegra_ctr_prep_cmd(se, rctx); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); + ret = tegra_se_host1x_submit(se, cmdlen); if (ret) return ret; @@ -1487,9 +1475,7 @@ key_free: /* Free the keyslot if it is cloned for this request */ if (rctx->key_id != ctx->key_id) tegra_key_invalidate(ctx->se, rctx->key_id, ctx->alg); - out: - kfree(rctx->cmdbuf); crypto_finalize_aead_request(ctx->se->engine, req, ret); return 0; @@ -1575,7 +1561,6 @@ outbuf_err: rctx->inbuf.buf, rctx->inbuf.addr); /* Finalize the request if there are no errors */ - kfree(rctx->cmdbuf); crypto_finalize_aead_request(ctx->se->engine, req, ret); return 0; @@ -1699,10 +1684,6 @@ static int tegra_aead_crypt(struct aead_request *req, bool encrypt) struct tegra_aead_ctx *ctx = crypto_aead_ctx(tfm); struct tegra_aead_reqctx *rctx = aead_request_ctx(req); - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - return -ENOMEM; - rctx->encrypt = encrypt; return crypto_transfer_aead_request_to_engine(ctx->se->engine, req); @@ -1734,7 +1715,7 @@ static int tegra_aead_setkey(struct crypto_aead *tfm, static unsigned int tegra_cmac_prep_cmd(struct tegra_se *se, struct tegra_cmac_reqctx *rctx) { unsigned int data_count, res_bits = 0, i = 0, j; - u32 *cpuvaddr = rctx->cmdbuf, op; + u32 *cpuvaddr = se->cmdbuf->addr, op; data_count = (rctx->datbuf.size / AES_BLOCK_SIZE); @@ -1881,7 +1862,7 @@ static int tegra_cmac_do_update(struct ahash_request *req) cmdlen = tegra_cmac_prep_cmd(se, rctx); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); + ret = tegra_se_host1x_submit(se, cmdlen); /* * If this is not the final update, copy the intermediate results * from the registers so that it can be used in the next 'update' @@ -1925,7 +1906,7 @@ static int tegra_cmac_do_final(struct ahash_request *req) /* Prepare command and submit */ cmdlen = tegra_cmac_prep_cmd(se, rctx); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, cmdlen); + ret = tegra_se_host1x_submit(se, cmdlen); if (ret) goto out; @@ -1946,7 +1927,6 @@ out_free: rctx->residue.buf, rctx->residue.addr); dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf, rctx->digest.addr); - kfree(rctx->cmdbuf); return ret; } @@ -2061,19 +2041,15 @@ static int tegra_cmac_init(struct ahash_request *req) return -ENOMEM; } - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - goto key_free; - rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size, &rctx->digest.addr, GFP_KERNEL); if (!rctx->digest.buf) - goto cmdbuf_free; + goto digbuf_fail; rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2, &rctx->residue.addr, GFP_KERNEL); if (!rctx->residue.buf) - goto digbuf_free; + goto resbuf_fail; rctx->residue.size = 0; rctx->datbuf.size = 0; @@ -2084,12 +2060,10 @@ static int tegra_cmac_init(struct ahash_request *req) return 0; -digbuf_free: +resbuf_fail: dma_free_coherent(se->dev, rctx->blk_size, rctx->digest.buf, rctx->digest.addr); -cmdbuf_free: - kfree(rctx->cmdbuf); -key_free: +digbuf_fail: if (rctx->key_id != ctx->key_id) tegra_key_invalidate(ctx->se, rctx->key_id, ctx->alg); diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c index 870e1795..2ad081c1 100644 --- a/drivers/crypto/tegra/tegra-se-hash.c +++ b/drivers/crypto/tegra/tegra-se-hash.c @@ -45,7 +45,6 @@ struct tegra_sha_reqctx { unsigned int blk_size; unsigned int task; u32 key_id; - u32 *cmdbuf; u32 result[HASH_RESULT_REG_COUNT]; struct ahash_request fallback_req; }; @@ -312,7 +311,7 @@ static int tegra_sha_do_update(struct ahash_request *req) struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); struct tegra_sha_reqctx *rctx = ahash_request_ctx(req); unsigned int nblks, nresidue, size, ret; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = ctx->se->cmdbuf->addr; nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size; nblks = (req->nbytes + rctx->residue.size) / rctx->blk_size; @@ -373,7 +372,7 @@ static int tegra_sha_do_update(struct ahash_request *req) size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx); - ret = tegra_se_host1x_submit(ctx->se, rctx->cmdbuf, size); + ret = tegra_se_host1x_submit(ctx->se, size); /* * If this is not the final update, copy the intermediate results @@ -395,7 +394,7 @@ static int tegra_sha_do_final(struct ahash_request *req) struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm); struct tegra_se *se = ctx->se; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; int size, ret = 0; rctx->datbuf.size = rctx->residue.size; @@ -416,7 +415,7 @@ static int tegra_sha_do_final(struct ahash_request *req) } size = tegra_sha_prep_cmd(se, cpuvaddr, rctx); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, size); + ret = tegra_se_host1x_submit(se, size); if (ret) goto out; @@ -432,8 +431,6 @@ out_free: rctx->residue.buf, rctx->residue.addr); dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf, rctx->digest.addr); - kfree(rctx->cmdbuf); - return ret; } @@ -568,28 +565,22 @@ static int tegra_sha_init(struct ahash_request *req) return -ENOMEM; } - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - goto key_free; - rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size, &rctx->digest.addr, GFP_KERNEL); if (!rctx->digest.buf) - goto cmdbuf_free; + goto digbuf_fail; rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size, &rctx->residue.addr, GFP_KERNEL); if (!rctx->residue.buf) - goto digbuf_free; + goto resbuf_fail; return 0; -digbuf_free: +resbuf_fail: dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf, rctx->digest.addr); -cmdbuf_free: - kfree(rctx->cmdbuf); -key_free: +digbuf_fail: if (rctx->key_id != ctx->key_id) tegra_key_invalidate(ctx->se, rctx->key_id, ctx->alg); diff --git a/drivers/crypto/tegra/tegra-se-key.c b/drivers/crypto/tegra/tegra-se-key.c index e2b09ce2..91ea9e24 100644 --- a/drivers/crypto/tegra/tegra-se-key.c +++ b/drivers/crypto/tegra/tegra-se-key.c @@ -177,22 +177,22 @@ static int tegra_key_insert(struct tegra_se *se, const u8 *key, u32 keylen, u16 slot, u32 alg) { const u32 *keyval = (u32 *)key; - u32 cmdbuf[100], size; + u32 *addr = se->cmdbuf->addr, size; - size = tegra_key_prep_ins_cmd(se, cmdbuf, keyval, keylen, slot, alg); + size = tegra_key_prep_ins_cmd(se, addr, keyval, keylen, slot, alg); - return tegra_se_host1x_submit(se, cmdbuf, size); + return tegra_se_host1x_submit(se, size); } static int tegra_key_move_to_kds(struct tegra_se *se, u32 slot, u32 kds_id) { - u32 src_keyid, size, cmdbuf[100]; + u32 src_keyid, size; int ret; src_keyid = SE_KSLT_REGION_ID_SYM | slot; - size = tegra_key_prep_mov_cmd(se, cmdbuf, src_keyid, kds_id); + size = tegra_key_prep_mov_cmd(se, se->cmdbuf->addr, src_keyid, kds_id); - ret = tegra_se_host1x_submit(se, cmdbuf, size); + ret = tegra_se_host1x_submit(se, size); if (ret) return ret; @@ -201,13 +201,13 @@ static int tegra_key_move_to_kds(struct tegra_se *se, u32 slot, u32 kds_id) static unsigned int tegra_kac_get_from_kds(struct tegra_se *se, u32 keyid, u16 slot) { - u32 tgt_keyid, size, cmdbuf[100]; + u32 tgt_keyid, size; int ret; tgt_keyid = SE_KSLT_REGION_ID_SYM | slot; - size = tegra_key_prep_mov_cmd(se, cmdbuf, keyid, tgt_keyid); + size = tegra_key_prep_mov_cmd(se, se->cmdbuf->addr, keyid, tgt_keyid); - ret = tegra_se_host1x_submit(se, cmdbuf, size); + ret = tegra_se_host1x_submit(se, size); if (ret) tegra_keyslot_free(slot); @@ -216,10 +216,10 @@ static unsigned int tegra_kac_get_from_kds(struct tegra_se *se, u32 keyid, u16 s static void tegra_key_kds_invalidate(struct tegra_se *se, u32 keyid) { - unsigned int size, cmdbuf[100]; + unsigned int size; - size = tegra_key_prep_invld_cmd(se, cmdbuf, keyid); - tegra_se_host1x_submit(se, cmdbuf, size); + size = tegra_key_prep_invld_cmd(se, se->cmdbuf->addr, keyid); + tegra_se_host1x_submit(se, size); tegra_kds_free_id(keyid); } diff --git a/drivers/crypto/tegra/tegra-se-main.c b/drivers/crypto/tegra/tegra-se-main.c index 1379c0f6..7006da85 100644 --- a/drivers/crypto/tegra/tegra-se-main.c +++ b/drivers/crypto/tegra/tegra-se-main.c @@ -143,10 +143,9 @@ static struct tegra_se_cmdbuf *tegra_se_host1x_bo_alloc(struct tegra_se *se, ssi return cmdbuf; } -int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size) +int tegra_se_host1x_submit(struct tegra_se *se, u32 size) { struct host1x_job *job; - struct tegra_se_cmdbuf *cmdbuf; int ret; job = host1x_job_alloc(se->channel, 1, 0, true); @@ -155,12 +154,6 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size) return -ENOMEM; } - cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K); - if (!cmdbuf) - goto job_put; - - memcpy(cmdbuf->addr, cpuvaddr, size * 4); - job->syncpt = host1x_syncpt_get(se->syncpt); job->syncpt_incrs = 1; job->client = &se->client; @@ -169,14 +162,14 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size) job->engine_fallback_streamid = se->stream_id; job->engine_streamid_offset = SE_STREAM_ID; - cmdbuf->words = size; + se->cmdbuf->words = size; - host1x_job_add_gather(job, &cmdbuf->bo, size, 0); + host1x_job_add_gather(job, &se->cmdbuf->bo, size, 0); ret = host1x_job_pin(job, se->dev); if (ret) { dev_err(se->dev, "failed to pin host1x job\n"); - goto cmdbuf_put; + goto job_put; } ret = host1x_job_submit(job); @@ -193,14 +186,10 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size) } host1x_job_put(job); - tegra_se_cmdbuf_put(&cmdbuf->bo); - return 0; job_unpin: host1x_job_unpin(job); -cmdbuf_put: - tegra_se_cmdbuf_put(&cmdbuf->bo); job_put: host1x_job_put(job); @@ -227,14 +216,22 @@ static int tegra_se_client_init(struct host1x_client *client) se->syncpt_id = host1x_syncpt_id(se->syncpt); + se->cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K); + if (!se->cmdbuf) { + ret = -ENOMEM; + goto syncpt_put; + } + ret = se->hw->init_alg(se); if (ret) { dev_err(se->dev, "failed to register algorithms\n"); - goto syncpt_put; + goto cmdbuf_put; } return 0; +cmdbuf_put: + tegra_se_cmdbuf_put(&se->cmdbuf->bo); syncpt_put: host1x_syncpt_put(se->syncpt); channel_put: @@ -248,6 +245,7 @@ static int tegra_se_client_deinit(struct host1x_client *client) struct tegra_se *se = container_of(client, struct tegra_se, client); se->hw->deinit_alg(se); + tegra_se_cmdbuf_put(&se->cmdbuf->bo); host1x_syncpt_put(se->syncpt); host1x_channel_put(se->channel); diff --git a/drivers/crypto/tegra/tegra-se-sm4.c b/drivers/crypto/tegra/tegra-se-sm4.c index 9216f660..ca9f2afd 100644 --- a/drivers/crypto/tegra/tegra-se-sm4.c +++ b/drivers/crypto/tegra/tegra-se-sm4.c @@ -2,7 +2,7 @@ /* * Crypto driver for NVIDIA Security Engine for block cipher operations. * - * Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. */ #include @@ -45,7 +45,6 @@ struct tegra_sm4_reqctx { u32 crypto_cfg; u32 key1_id; u32 key2_id; - u32 *cmdbuf; }; struct tegra_sm4_gcm_ctx { @@ -60,7 +59,6 @@ struct tegra_sm4_gcm_ctx { u32 verify_alg; u32 keylen; u32 key_id; - u32 *cmdbuf; }; struct tegra_sm4_gcm_reqctx { @@ -75,7 +73,6 @@ struct tegra_sm4_gcm_reqctx { u32 config; u32 crypto_config; u32 key_id; - u32 *cmdbuf; u32 iv[4]; u8 authdata[16]; }; @@ -103,7 +100,6 @@ struct tegra_sm4_cmac_reqctx { u32 crypto_config; u32 key_id; u32 result[CMAC_RESULT_REG_COUNT]; - u32 *cmdbuf; u32 *iv; }; @@ -229,7 +225,7 @@ static int tegra_sm4_do_one_req(struct crypto_engine *engine, void *areq) goto key2_free; } - cpuvaddr = rctx->cmdbuf; + cpuvaddr = se->cmdbuf->addr; len = req->cryptlen; /* Pad input to AES block size */ @@ -249,7 +245,7 @@ static int tegra_sm4_do_one_req(struct crypto_engine *engine, void *areq) size = tegra_sm4_prep_cmd(se, cpuvaddr, iv, len, rctx->datbuf.addr, config, crypto_config); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, size); + ret = tegra_se_host1x_submit(se, size); /* Copy the result */ dst_nents = sg_nents(req->dst); @@ -267,7 +263,6 @@ key1_free: if (rctx->key1_id != ctx->key1_id) tegra_key_invalidate(ctx->se, rctx->key1_id, ctx->alg); out: - kfree(rctx->cmdbuf); crypto_finalize_skcipher_request(se->engine, req, ret); return ret; @@ -506,10 +501,6 @@ static int tegra_sm4_encrypt(struct skcipher_request *req) rctx = skcipher_request_ctx(req); rctx->encrypt = true; - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - return -ENOMEM; - return crypto_transfer_skcipher_request_to_engine(ctx->se->engine, req); } @@ -522,10 +513,6 @@ static int tegra_sm4_decrypt(struct skcipher_request *req) rctx = skcipher_request_ctx(req); rctx->encrypt = false; - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - return -ENOMEM; - return crypto_transfer_skcipher_request_to_engine(ctx->se->engine, req); } @@ -842,7 +829,7 @@ static int tegra_sm4_gcm_prep_final_cmd(struct tegra_se *se, u32 *cpuvaddr, static int tegra_sm4_gcm_do_gmac(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm4_gcm_reqctx *rctx) { struct tegra_se *se = ctx->se; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; unsigned int nents, size; nents = sg_nents(rctx->src_sg); @@ -855,13 +842,13 @@ static int tegra_sm4_gcm_do_gmac(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm4 size = tegra_sm4_gmac_prep_cmd(se, cpuvaddr, rctx); - return tegra_se_host1x_submit(se, cpuvaddr, size); + return tegra_se_host1x_submit(se, size); } static int tegra_sm4_gcm_do_crypt(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm4_gcm_reqctx *rctx) { struct tegra_se *se = ctx->se; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; int size, ret; scatterwalk_map_and_copy(rctx->inbuf.buf, rctx->src_sg, @@ -873,7 +860,7 @@ static int tegra_sm4_gcm_do_crypt(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm /* Prepare command and submit */ size = tegra_sm4_gcm_crypt_prep_cmd(se, cpuvaddr, rctx); - ret = tegra_se_host1x_submit(se, cpuvaddr, size); + ret = tegra_se_host1x_submit(se, size); if (ret) return ret; @@ -887,7 +874,7 @@ static int tegra_sm4_gcm_do_crypt(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm static int tegra_sm4_gcm_do_final(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm4_gcm_reqctx *rctx) { struct tegra_se *se = ctx->se; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; int size, ret, off; rctx->config = se->regcfg->cfg(ctx->final_alg, rctx->encrypt); @@ -896,7 +883,7 @@ static int tegra_sm4_gcm_do_final(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm /* Prepare command and submit */ size = tegra_sm4_gcm_prep_final_cmd(se, cpuvaddr, rctx); - ret = tegra_se_host1x_submit(se, cpuvaddr, size); + ret = tegra_se_host1x_submit(se, size); if (ret) return ret; @@ -913,7 +900,7 @@ static int tegra_sm4_gcm_do_final(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm static int tegra_sm4_gcm_hw_verify(struct tegra_sm4_gcm_ctx *ctx, struct tegra_sm4_gcm_reqctx *rctx, u8 *mac) { struct tegra_se *se = ctx->se; - u32 result, *cpuvaddr = rctx->cmdbuf; + u32 result, *cpuvaddr = se->cmdbuf->addr; int size, ret; memcpy(rctx->inbuf.buf, mac, rctx->authsize); @@ -925,7 +912,7 @@ static int tegra_sm4_gcm_hw_verify(struct tegra_sm4_gcm_ctx *ctx, struct tegra_s /* Prepare command and submit */ size = tegra_sm4_gcm_prep_final_cmd(se, cpuvaddr, rctx); - ret = tegra_se_host1x_submit(se, cpuvaddr, size); + ret = tegra_se_host1x_submit(se, size); if (ret) return ret; @@ -1035,7 +1022,6 @@ key_free: tegra_key_invalidate(ctx->se, rctx->key_id, ctx->alg); out: - kfree(rctx->cmdbuf); crypto_finalize_aead_request(se->engine, req, ret); return 0; @@ -1099,10 +1085,6 @@ static int tegra_sm4_gcm_crypt(struct aead_request *req, bool encrypt) rctx->encrypt = encrypt; - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - return -ENOMEM; - return crypto_transfer_aead_request_to_engine(ctx->se->engine, req); } @@ -1244,9 +1226,9 @@ static int tegra_sm4_cmac_do_update(struct ahash_request *req) /* Update residue value with the residue after current block */ rctx->residue.size = nresidue; - size = tegra_sm4_cmac_prep_cmd(se, rctx->cmdbuf, rctx); + size = tegra_sm4_cmac_prep_cmd(se, se->cmdbuf->addr, rctx); - return tegra_se_host1x_submit(se, rctx->cmdbuf, size); + return tegra_se_host1x_submit(se, size); } static int tegra_sm4_cmac_do_final(struct ahash_request *req) @@ -1273,8 +1255,8 @@ static int tegra_sm4_cmac_do_final(struct ahash_request *req) } /* Prepare command and submit */ - size = tegra_sm4_cmac_prep_cmd(se, rctx->cmdbuf, rctx); - ret = tegra_se_host1x_submit(se, rctx->cmdbuf, size); + size = tegra_sm4_cmac_prep_cmd(se, se->cmdbuf->addr, rctx); + ret = tegra_se_host1x_submit(se, size); if (ret) goto out; @@ -1297,8 +1279,6 @@ out_free: dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf, rctx->digest.addr); - kfree(rctx->cmdbuf); - return ret; } @@ -1386,19 +1366,15 @@ static int tegra_sm4_cmac_init(struct ahash_request *req) return -ENOMEM; } - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - goto key_free; - rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size, &rctx->digest.addr, GFP_KERNEL); if (!rctx->digest.buf) - goto cmdbuf_free; + goto digbuf_fail; rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2, &rctx->residue.addr, GFP_KERNEL); if (!rctx->residue.buf) - goto digbuf_free; + goto resbuf_fail; rctx->residue.size = 0; rctx->datbuf.size = 0; @@ -1409,12 +1385,10 @@ static int tegra_sm4_cmac_init(struct ahash_request *req) return 0; -digbuf_free: +resbuf_fail: dma_free_coherent(se->dev, rctx->blk_size, rctx->digest.buf, rctx->digest.addr); -cmdbuf_free: - kfree(rctx->cmdbuf); -key_free: +digbuf_fail: if (rctx->key_id != ctx->key_id) tegra_key_invalidate(ctx->se, rctx->key_id, ctx->alg); diff --git a/drivers/crypto/tegra/tegra-se.h b/drivers/crypto/tegra/tegra-se.h index 961b6e41..56b29495 100644 --- a/drivers/crypto/tegra/tegra-se.h +++ b/drivers/crypto/tegra/tegra-se.h @@ -23,7 +23,6 @@ #define SE_OWNERSHIP_UID(x) FIELD_GET(GENMASK(7, 0), x) #define TEGRA_GPSE_ID 3 -#define SE_MAX_CMDLEN (100 * 4) /* max 100 commands of 4 bytes each */ #define SE_STREAM_ID 0x90 #define SE_SHA_CFG 0x4004 @@ -656,6 +655,7 @@ struct tegra_se { struct host1x_client client; struct host1x_channel *channel; struct tegra_se_regcfg *regcfg; + struct tegra_se_cmdbuf *cmdbuf; struct crypto_engine *engine; struct host1x_syncpt *syncpt; struct device *dev; @@ -770,7 +770,7 @@ int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u32 *keyid); void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg); unsigned int tegra_key_get_idx(struct tegra_se *se, u32 keyid); -int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size); +int tegra_se_host1x_submit(struct tegra_se *se, u32 size); u32 tegra_kds_get_id(void); void tegra_kds_free_id(u32 keyid);