mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
Bug Fix: Fix AESRNG performance on Thor
Bug 5095525 Change-Id: I4de355ea6a53b4dcc5654cb67d50c128efd8e06b Signed-off-by: Khushi <khushi@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3348752 (cherry picked from commit 28f1ad0ad6ec3fe69a7f551a24accb526c23e410) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3361960 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Leo Chiu <lchiu@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Sandeep Trasi <strasi@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
@@ -3775,13 +3775,16 @@ static int tegra_hv_vse_safety_get_random(struct tegra_virtual_se_rng_context *r
|
|||||||
struct tegra_virtual_se_dev *se_dev =
|
struct tegra_virtual_se_dev *se_dev =
|
||||||
g_crypto_to_ivc_map[rng_ctx->node_id].se_dev;
|
g_crypto_to_ivc_map[rng_ctx->node_id].se_dev;
|
||||||
u8 *rdata_addr;
|
u8 *rdata_addr;
|
||||||
int err = 0, j, num_blocks, data_len = 0;
|
int err = 0;
|
||||||
struct tegra_virtual_se_ivc_tx_msg_t *ivc_tx;
|
struct tegra_virtual_se_ivc_tx_msg_t *ivc_tx;
|
||||||
struct tegra_hv_ivc_cookie *pivck = g_crypto_to_ivc_map[rng_ctx->node_id].ivck;
|
struct tegra_hv_ivc_cookie *pivck = g_crypto_to_ivc_map[rng_ctx->node_id].ivck;
|
||||||
struct tegra_virtual_se_ivc_msg_t *ivc_req_msg;
|
struct tegra_virtual_se_ivc_msg_t *ivc_req_msg;
|
||||||
struct tegra_virtual_se_ivc_hdr_t *ivc_hdr = NULL;
|
struct tegra_virtual_se_ivc_hdr_t *ivc_hdr = NULL;
|
||||||
struct tegra_vse_priv_data *priv = NULL;
|
struct tegra_vse_priv_data *priv = NULL;
|
||||||
const struct tegra_vse_dma_buf *src;
|
const struct tegra_vse_dma_buf *src;
|
||||||
|
unsigned int chunk_size, aligned_size, copy_size;
|
||||||
|
unsigned int bytes_remaining;
|
||||||
|
unsigned int offset = 0;
|
||||||
|
|
||||||
if (atomic_read(&se_dev->se_suspended)) {
|
if (atomic_read(&se_dev->se_suspended)) {
|
||||||
VSE_ERR("%s: Engine is in suspended state\n", __func__);
|
VSE_ERR("%s: Engine is in suspended state\n", __func__);
|
||||||
@@ -3793,11 +3796,6 @@ static int tegra_hv_vse_safety_get_random(struct tegra_virtual_se_rng_context *r
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_blocks = (dlen / TEGRA_VIRTUAL_SE_RNG_DT_SIZE);
|
|
||||||
data_len = (dlen % TEGRA_VIRTUAL_SE_RNG_DT_SIZE);
|
|
||||||
if (data_len == 0)
|
|
||||||
num_blocks = num_blocks - 1;
|
|
||||||
|
|
||||||
ivc_req_msg = devm_kzalloc(se_dev->dev,
|
ivc_req_msg = devm_kzalloc(se_dev->dev,
|
||||||
sizeof(*ivc_req_msg),
|
sizeof(*ivc_req_msg),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@@ -3805,12 +3803,25 @@ static int tegra_hv_vse_safety_get_random(struct tegra_virtual_se_rng_context *r
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (is_hw_req == CRYPTODEV_RNG) {
|
if (is_hw_req == CRYPTODEV_RNG) {
|
||||||
src = tegra_hv_vse_get_dma_buf(rng_ctx->node_id, AES_SRC_BUF_IDX,
|
if ((dlen % TEGRA_VIRTUAL_SE_RNG_DT_SIZE) == 0)
|
||||||
TEGRA_VIRTUAL_SE_RNG_DT_SIZE);
|
aligned_size = dlen;
|
||||||
|
else
|
||||||
|
aligned_size = dlen - (dlen % TEGRA_VIRTUAL_SE_RNG_DT_SIZE) +
|
||||||
|
TEGRA_VIRTUAL_SE_RNG_DT_SIZE;
|
||||||
|
/* calculate aligned size to the next multiple of TEGRA_VIRTUAL_SE_RNG_DT_SIZE */
|
||||||
|
src = tegra_hv_vse_get_dma_buf(rng_ctx->node_id, AES_SRC_BUF_IDX, aligned_size);
|
||||||
|
if (!src) {
|
||||||
|
aligned_size -= TEGRA_VIRTUAL_SE_RNG_DT_SIZE;
|
||||||
|
/* If the aligned size is greater than the max dma_buf,
|
||||||
|
* decrease the aligned size by one alignment unit.
|
||||||
|
*/
|
||||||
|
src = tegra_hv_vse_get_dma_buf(rng_ctx->node_id,
|
||||||
|
AES_SRC_BUF_IDX, aligned_size);
|
||||||
if (!src) {
|
if (!src) {
|
||||||
dev_err(se_dev->dev, "%s src is NULL\n", __func__);
|
dev_err(se_dev->dev, "%s src is NULL\n", __func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
priv = g_crypto_to_ivc_map[rng_ctx->node_id].priv;
|
priv = g_crypto_to_ivc_map[rng_ctx->node_id].priv;
|
||||||
} else {
|
} else {
|
||||||
src = &rng_ctx->hwrng_dma_buf;
|
src = &rng_ctx->hwrng_dma_buf;
|
||||||
@@ -3828,13 +3839,23 @@ static int tegra_hv_vse_safety_get_random(struct tegra_virtual_se_rng_context *r
|
|||||||
ivc_hdr->tag.priv_data = priv;
|
ivc_hdr->tag.priv_data = priv;
|
||||||
priv->cmd = VIRTUAL_SE_PROCESS;
|
priv->cmd = VIRTUAL_SE_PROCESS;
|
||||||
priv->se_dev = se_dev;
|
priv->se_dev = se_dev;
|
||||||
|
|
||||||
ivc_tx->cmd = TEGRA_VIRTUAL_SE_CMD_AES_RNG_DBRG;
|
ivc_tx->cmd = TEGRA_VIRTUAL_SE_CMD_AES_RNG_DBRG;
|
||||||
|
|
||||||
for (j = 0; j <= num_blocks; j++) {
|
bytes_remaining = dlen;
|
||||||
|
|
||||||
|
while (bytes_remaining > 0) {
|
||||||
|
if (is_hw_req == CRYPTODEV_RNG)
|
||||||
|
chunk_size = bytes_remaining;
|
||||||
|
else
|
||||||
|
chunk_size = min(bytes_remaining, rng_ctx->hwrng_dma_buf.buf_len);
|
||||||
|
|
||||||
|
aligned_size = chunk_size & ~(TEGRA_VIRTUAL_SE_RNG_DT_SIZE - 1);
|
||||||
|
|
||||||
|
if (aligned_size < TEGRA_VIRTUAL_SE_RNG_DT_SIZE)
|
||||||
|
aligned_size = TEGRA_VIRTUAL_SE_RNG_DT_SIZE;
|
||||||
|
|
||||||
ivc_tx->aes.op_rng.dst_addr.lo = src->buf_iova & 0xFFFFFFFF;
|
ivc_tx->aes.op_rng.dst_addr.lo = src->buf_iova & 0xFFFFFFFF;
|
||||||
ivc_tx->aes.op_rng.dst_addr.hi = (src->buf_iova >> 32)
|
ivc_tx->aes.op_rng.dst_addr.hi = (src->buf_iova >> 32) | aligned_size;
|
||||||
| TEGRA_VIRTUAL_SE_RNG_DT_SIZE;
|
|
||||||
init_completion(&priv->alg_complete);
|
init_completion(&priv->alg_complete);
|
||||||
g_crypto_to_ivc_map[rng_ctx->node_id].vse_thread_start = true;
|
g_crypto_to_ivc_map[rng_ctx->node_id].vse_thread_start = true;
|
||||||
|
|
||||||
@@ -3845,15 +3866,13 @@ static int tegra_hv_vse_safety_get_random(struct tegra_virtual_se_rng_context *r
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdata_addr =
|
copy_size = min(bytes_remaining, aligned_size);
|
||||||
(rdata + (j * TEGRA_VIRTUAL_SE_RNG_DT_SIZE));
|
rdata_addr = (rdata + offset);
|
||||||
if (data_len && num_blocks == j) {
|
memcpy(rdata_addr, src->buf_ptr, copy_size);
|
||||||
memcpy(rdata_addr, src->buf_ptr, data_len);
|
bytes_remaining -= copy_size;
|
||||||
} else {
|
offset += copy_size;
|
||||||
memcpy(rdata_addr, src->buf_ptr,
|
|
||||||
TEGRA_VIRTUAL_SE_RNG_DT_SIZE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
devm_kfree(se_dev->dev, ivc_req_msg);
|
devm_kfree(se_dev->dev, ivc_req_msg);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user