diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c index db4fba9b..a7c972bd 100644 --- a/drivers/crypto/tegra/tegra-se-aes.c +++ b/drivers/crypto/tegra/tegra-se-aes.c @@ -42,7 +42,6 @@ struct tegra_aes_reqctx { u32 crypto_config; u32 len; u32 *iv; - u32 *cmdbuf; }; struct tegra_aead_ctx { @@ -70,7 +69,6 @@ struct tegra_aead_reqctx { u32 key_id; u32 iv[4]; u8 authdata[16]; - u32 *cmdbuf; }; struct tegra_cmac_ctx { @@ -95,7 +93,6 @@ struct tegra_cmac_reqctx { u32 key_id; u32 *iv; u32 result[CMAC_RESULT_REG_COUNT]; - u32 *cmdbuf; }; /* increment counter (128-bit int) */ @@ -216,7 +213,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; @@ -295,17 +292,16 @@ 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); - kfree(rctx->cmdbuf); crypto_finalize_skcipher_request(se->engine, req, ret); return 0; @@ -463,13 +459,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 = tegra234_aes_cfg(ctx->alg, encrypt); rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, encrypt); @@ -608,7 +597,7 @@ static struct tegra_se_alg tegra_aes_algs[] = { static unsigned int tegra_gmac_prep_cmd(struct tegra_se *se, struct tegra_aead_reqctx *rctx) { unsigned int data_count, res_bits, i = 0; - u32 *cpuvaddr = rctx->cmdbuf; + u32 *cpuvaddr = se->cmdbuf->addr; data_count = (rctx->assoclen / AES_BLOCK_SIZE); res_bits = (rctx->assoclen % AES_BLOCK_SIZE) * 8; @@ -646,7 +635,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; @@ -766,7 +755,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) @@ -783,7 +772,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; @@ -797,7 +786,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 = tegra234_aes_cfg(SE_ALG_GCM_FINAL, rctx->encrypt); @@ -806,7 +795,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; @@ -851,7 +840,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; @@ -884,7 +873,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); @@ -934,7 +923,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req /* 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) @@ -1141,7 +1130,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx /* 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; @@ -1242,7 +1231,6 @@ outbuf_err: dma_free_coherent(ctx->se->dev, rctx->inbuf.size, rctx->inbuf.buf, rctx->inbuf.addr); - kfree(rctx->cmdbuf); crypto_finalize_aead_request(ctx->se->engine, req, ret); return 0; @@ -1316,7 +1304,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; @@ -1447,10 +1434,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); @@ -1482,7 +1465,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); @@ -1617,7 +1600,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' @@ -1662,7 +1645,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; @@ -1680,8 +1663,6 @@ out: out_free: dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm) * 2, rctx->residue.buf, rctx->residue.addr); - kfree(rctx->cmdbuf); - return ret; } @@ -1792,14 +1773,10 @@ static int tegra_cmac_init(struct ahash_request *req) rctx->task = SHA_FIRST; rctx->blk_size = crypto_ahash_blocksize(tfm); - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - return -ENOMEM; - rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2, &rctx->residue.addr, GFP_KERNEL); if (!rctx->residue.buf) - goto cmdbuf_free; + return -ENOMEM; rctx->residue.size = 0; rctx->datbuf.size = 0; @@ -1809,11 +1786,6 @@ static int tegra_cmac_init(struct ahash_request *req) writel(0, se->base + se->hw->regs->result + (i * 4)); return 0; - -cmdbuf_free: - kfree(rctx->cmdbuf); - - return -ENOMEM; } static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c index 62fca037..bdcc3239 100644 --- a/drivers/crypto/tegra/tegra-se-hash.c +++ b/drivers/crypto/tegra/tegra-se-hash.c @@ -44,7 +44,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; }; @@ -306,7 +305,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; @@ -367,7 +366,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 @@ -389,7 +388,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; @@ -410,7 +409,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; @@ -426,8 +425,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; } @@ -552,10 +549,6 @@ static int tegra_sha_init(struct ahash_request *req) rctx->blk_size = crypto_ahash_blocksize(tfm); rctx->digest.size = crypto_ahash_digestsize(tfm); - rctx->cmdbuf = kzalloc(SE_MAX_CMDLEN, GFP_KERNEL); - if (!rctx->cmdbuf) - return -ENOMEM; - rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size, &rctx->digest.addr, GFP_KERNEL); if (!rctx->digest.buf) @@ -572,8 +565,6 @@ resbuf_fail: dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf, rctx->digest.addr); digbuf_fail: - kfree(rctx->cmdbuf); - return -ENOMEM; } diff --git a/drivers/crypto/tegra/tegra-se-key.c b/drivers/crypto/tegra/tegra-se-key.c index afcd5317..e3b97ec7 100644 --- a/drivers/crypto/tegra/tegra-se-key.c +++ b/drivers/crypto/tegra/tegra-se-key.c @@ -115,11 +115,11 @@ static int tegra_key_insert(struct tegra_se *se, const u8 *key, u32 keylen, u16 slot, u32 alg) { const u32 *keyval = (u32 *)key; - u32 addr[100], size; + u32 *addr = se->cmdbuf->addr, size; size = tegra_key_prep_ins_cmd(se, addr, keyval, keylen, slot, alg); - return tegra_se_host1x_submit(se, addr, size); + return tegra_se_host1x_submit(se, size); } void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg) diff --git a/drivers/crypto/tegra/tegra-se-main.c b/drivers/crypto/tegra/tegra-se-main.c index 819b995b..470f34c6 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.h b/drivers/crypto/tegra/tegra-se.h index b06750bb..900d6bfc 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 @@ -442,6 +441,7 @@ struct tegra_se { const struct tegra_se_hw *hw; struct host1x_client client; struct host1x_channel *channel; + struct tegra_se_cmdbuf *cmdbuf; struct crypto_engine *engine; struct host1x_syncpt *syncpt; struct device *dev; @@ -524,7 +524,7 @@ void tegra_deinit_hash(struct tegra_se *se); 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); -int tegra_se_host1x_submit(struct tegra_se *se, u32 *cpuvaddr, u32 size); +int tegra_se_host1x_submit(struct tegra_se *se, u32 size); /* HOST1x OPCODES */ static inline u32 host1x_opcode_setpayload(unsigned int payload)