Currently, the RSA algorithm calls qm_crypto_bin_to_hpre_bin() to transfer the key when sending request. However, the key needs to be transferred only once, repeated transfer may cause data inconsistency with original user's data, resulting in incorrect calculation results.
Therefore, after the key is transferred, the 'dsize' is changed to the 'bsize', When 'disze' and 'bsize' are equal, no transfer is performed.
Signed-off-by: Weili Qian qianweili@huawei.com --- v1/drv/hisi_hpre_udrv.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/v1/drv/hisi_hpre_udrv.c b/v1/drv/hisi_hpre_udrv.c index 193ba56..0d0c3b4 100644 --- a/v1/drv/hisi_hpre_udrv.c +++ b/v1/drv/hisi_hpre_udrv.c @@ -136,27 +136,32 @@ static int qm_fill_rsa_crt_prikey2(struct wcrypto_rsa_prikey *prikey, wd_dq->bsize, wd_dq->dsize, "rsa crt dq"); if (unlikely(ret)) return ret; + wd_dq->dsize = wd_dq->bsize;
ret = qm_crypto_bin_to_hpre_bin(wd_dp->data, (const char *)wd_dp->data, wd_dp->bsize, wd_dp->dsize, "rsa crt dp"); if (unlikely(ret)) return ret; + wd_dp->dsize = wd_dp->bsize;
ret = qm_crypto_bin_to_hpre_bin(wd_q->data, (const char *)wd_q->data, wd_q->bsize, wd_q->dsize, "rsa crt q"); if (unlikely(ret)) return ret; + wd_q->dsize = wd_q->bsize;
ret = qm_crypto_bin_to_hpre_bin(wd_p->data, (const char *)wd_p->data, wd_p->bsize, wd_p->dsize, "rsa crt p"); if (unlikely(ret)) return ret; + wd_p->dsize = wd_p->bsize;
ret = qm_crypto_bin_to_hpre_bin(wd_qinv->data, (const char *)wd_qinv->data, wd_qinv->bsize, wd_qinv->dsize, "rsa crt qinv"); if (unlikely(ret)) return ret; + wd_qinv->dsize = wd_qinv->bsize;
*data = wd_dq->data; return (int)(wd_dq->bsize + wd_qinv->bsize + wd_p->bsize + @@ -179,11 +184,13 @@ static int qm_fill_rsa_prikey1(struct wcrypto_rsa_prikey *prikey, void **data) wd_d->bsize, wd_d->dsize, "rsa prikey1 d"); if (unlikely(ret)) return ret; + wd_d->dsize = wd_d->bsize;
ret = qm_crypto_bin_to_hpre_bin(wd_n->data, (const char *)wd_n->data, wd_n->bsize, wd_n->dsize, "rsa prikey1 n"); if (unlikely(ret)) return ret; + wd_n->dsize = wd_n->bsize;
*data = wd_d->data; return (int)(wd_n->bsize + wd_d->bsize); @@ -200,11 +207,13 @@ static int qm_fill_rsa_pubkey(struct wcrypto_rsa_pubkey *pubkey, void **data) wd_e->bsize, wd_e->dsize, "rsa pubkey e"); if (unlikely(ret)) return ret; + wd_e->dsize = wd_e->dsize;
ret = qm_crypto_bin_to_hpre_bin(wd_n->data, (const char *)wd_n->data, wd_n->bsize, wd_n->dsize, "rsa pubkey n"); if (unlikely(ret)) return ret; + wd_n->dsize = wd_n->dsize;
*data = wd_e->data; return (int)(wd_n->bsize + wd_e->bsize);
Currently, the RSA algorithm calls crypto_bin_to_hpre_bin() to transfer the key when sending request. However, the key needs to be transferred only once, repeated transfer may cause data inconsistency with original user's data, resulting in incorrect calculation results.
Therefore, after the key is transferred, the 'dsize' is changed to the 'bsize', When 'disze' and 'bsize' are equal, no transfer is performed.
Signed-off-by: Weili Qian qianweili@huawei.com --- drv/hisi_hpre.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index c7bb70e..61c7855 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -212,27 +212,32 @@ static int fill_rsa_crt_prikey2(struct wd_rsa_prikey *prikey, wd_dq->bsize, wd_dq->dsize, "rsa crt dq"); if (ret) return ret; + wd_dq->dsize = wd_dq->bsize;
ret = crypto_bin_to_hpre_bin(wd_dp->data, (const char *)wd_dp->data, wd_dp->bsize, wd_dp->dsize, "rsa crt dp"); if (ret) return ret; + wd_dp->dsize = wd_dp->bsize;
ret = crypto_bin_to_hpre_bin(wd_q->data, (const char *)wd_q->data, wd_q->bsize, wd_q->dsize, "rsa crt q"); if (ret) return ret; + wd_q->dsize = wd_q->bsize;
ret = crypto_bin_to_hpre_bin(wd_p->data, (const char *)wd_p->data, wd_p->bsize, wd_p->dsize, "rsa crt p"); if (ret) return ret; + wd_p->dsize = wd_p->bsize;
ret = crypto_bin_to_hpre_bin(wd_qinv->data, (const char *)wd_qinv->data, wd_qinv->bsize, wd_qinv->dsize, "rsa crt qinv"); if (ret) return ret; + wd_qinv->dsize = wd_qinv->bsize;
*data = wd_dq->data;
@@ -249,11 +254,13 @@ static int fill_rsa_prikey1(struct wd_rsa_prikey *prikey, void **data) wd_d->bsize, wd_d->dsize, "rsa d"); if (ret) return ret; + wd_d->dsize = wd_d->bsize;
ret = crypto_bin_to_hpre_bin(wd_n->data, (const char *)wd_n->data, wd_n->bsize, wd_n->dsize, "rsa n"); if (ret) return ret; + wd_n->dsize = wd_n->bsize;
*data = wd_d->data;
@@ -270,11 +277,13 @@ static int fill_rsa_pubkey(struct wd_rsa_pubkey *pubkey, void **data) wd_e->bsize, wd_e->dsize, "rsa e"); if (ret) return ret; + wd_e->dsize = wd_e->bsize;
ret = crypto_bin_to_hpre_bin(wd_n->data, (const char *)wd_n->data, wd_n->bsize, wd_n->dsize, "rsa n"); if (ret) return ret; + wd_n->dsize = wd_n->bsize;
*data = wd_e->data;
Some of the header files are already included in wd.h, and hisi_rng_udrv.h already includes wd.h. Therefore, the hisi_rng_udrv.c file does not need to include these header files repeatedly.
Signed-off-by: Weili Qian qianweili@huawei.com --- v1/drv/hisi_rng_udrv.c | 6 ------ v1/drv/hisi_rng_udrv.h | 1 - 2 files changed, 7 deletions(-)
diff --git a/v1/drv/hisi_rng_udrv.c b/v1/drv/hisi_rng_udrv.c index 09fa2c3..86a20cb 100644 --- a/v1/drv/hisi_rng_udrv.c +++ b/v1/drv/hisi_rng_udrv.c @@ -18,18 +18,12 @@ #include <unistd.h> #include <stdio.h> #include <sys/mman.h> -#include <assert.h> #include <string.h> #include <stdint.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/ioctl.h> #include <sys/epoll.h> #include <sys/eventfd.h> #include <sys/types.h> -#include <unistd.h>
-#include "config.h" #include "hisi_rng_udrv.h"
#define HISI_RNG_BYTES 4 diff --git a/v1/drv/hisi_rng_udrv.h b/v1/drv/hisi_rng_udrv.h index 93f2f91..56814a4 100644 --- a/v1/drv/hisi_rng_udrv.h +++ b/v1/drv/hisi_rng_udrv.h @@ -18,7 +18,6 @@ #define __HISI_RNG_UDRV_H__
#include <linux/types.h> -#include "config.h" #include "v1/wd.h" #include "v1/wd_util.h" #include "v1/wd_rng.h"
From: Qi Tao taoqi10@huawei.com
After the memory is applied for, the memory must be initialized before being written.
Signed-off-by: Qi Tao taoqi10@huawei.com --- drv/hisi_qm_udrv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c index 13db3f0..0baa85c 100644 --- a/drv/hisi_qm_udrv.c +++ b/drv/hisi_qm_udrv.c @@ -252,11 +252,10 @@ static int hisi_qm_setup_db(handle_t h_ctx, struct hisi_qm_queue_info *q_info) static int his_qm_set_qp_ctx(handle_t h_ctx, struct hisi_qm_priv *config, struct hisi_qm_queue_info *q_info) { - struct hisi_qp_info qp_cfg; - struct hisi_qp_ctx qp_ctx; + struct hisi_qp_info qp_cfg = {0}; + struct hisi_qp_ctx qp_ctx = {0}; int ret;
- memset(&qp_ctx, 0, sizeof(struct hisi_qp_ctx)); qp_ctx.qc_type = config->op_type; q_info->qc_type = qp_ctx.qc_type; ret = wd_ctx_set_io_cmd(h_ctx, UACCE_CMD_QM_SET_QP_CTX, &qp_ctx); @@ -264,6 +263,7 @@ static int his_qm_set_qp_ctx(handle_t h_ctx, struct hisi_qm_priv *config, WD_DEV_ERR(h_ctx, "failed to set qc_type!\n"); return ret; } + q_info->sqn = qp_ctx.id; config->sqn = qp_ctx.id;
From: Hao Fang fanghao11@huawei.com
The spin_lock need to destroy and mem region need to unmap, hisi_qm_clear_info() can do this.
Signed-off-by: Hao Fang fanghao11@huawei.com --- drv/hisi_qm_udrv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c index 0baa85c..4c80959 100644 --- a/drv/hisi_qm_udrv.c +++ b/drv/hisi_qm_udrv.c @@ -449,10 +449,10 @@ void hisi_qm_free_qp(handle_t h_qp) }
wd_release_ctx_force(qp->h_ctx); - wd_ctx_unmap_qfr(qp->h_ctx, UACCE_QFRT_MMIO); - wd_ctx_unmap_qfr(qp->h_ctx, UACCE_QFRT_DUS); - if (qp->h_sgl_pool) - hisi_qm_destroy_sglpool(qp->h_sgl_pool); + + hisi_qm_destroy_sglpool(qp->h_sgl_pool); + + hisi_qm_clear_info(qp);
free(qp); }
From: Qi Tao taoqi10@huawei.com
After the memory is applied for, the memory must be initialized before being written.
Signed-off-by: Qi Tao taoqi10@huawei.com --- v1/drv/hisi_qm_udrv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/v1/drv/hisi_qm_udrv.c b/v1/drv/hisi_qm_udrv.c index 6cbcdf5..0ca38d2 100644 --- a/v1/drv/hisi_qm_udrv.c +++ b/v1/drv/hisi_qm_udrv.c @@ -458,8 +458,8 @@ static int qm_init_queue_info(struct wd_queue *q) struct wcrypto_paras *priv = &q->capa.priv; struct q_info *qinfo = q->qinfo; struct qm_queue_info *info = qinfo->priv; - struct hisi_qp_info qp_info; - struct hisi_qp_ctx qp_ctx; + struct hisi_qp_info qp_info = {0}; + struct hisi_qp_ctx qp_ctx = {0}; int ret;
info->sq_tail_index = 0;
When the device needs to be reset, the queue status is set to disable before resetting. The user process checks the queue status before sending the doorbell. If the queue is disable, the user process returns failure.
Currently, the task execution order in user mode is as follows: 1. check the queue status. 2. fill in or parse the BD. 3. send the doorbell to the hardware.
To reduce the possibility of sending doorbells during reset, the task execution order is modified as follows: 1. fill in or parse the BD. 2. check the queue status. 3. send the doorbell to the hardware.
In addition, a rmb() is added before the doorbell is sent to ensure that the queue status check is complete.
rmb() and wmb() can be replaced by mb() in hisi_qm_send(). Therefore, the barrier on the wd_ioread() and wd_iowrite() can be deleted.
Signed-off-by: Weili Qian qianweili@huawei.com --- drv/hisi_qm_udrv.c | 43 ++++++++++++++++++++++++++++--------------- include/wd.h | 6 ++---- 2 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c index 4c80959..983d837 100644 --- a/drv/hisi_qm_udrv.c +++ b/drv/hisi_qm_udrv.c @@ -469,11 +469,6 @@ int hisi_qm_send(handle_t h_qp, const void *req, __u16 expect, __u16 *count)
q_info = &qp->q_info;
- if (unlikely(wd_ioread32(q_info->ds_tx_base) == 1)) { - WD_ERR("wd queue hw error happened before qm send!\n"); - return -WD_HW_EACCESS; - } - pthread_spin_lock(&q_info->sd_lock); free_num = get_free_num(q_info); if (!free_num) { @@ -486,14 +481,26 @@ int hisi_qm_send(handle_t h_qp, const void *req, __u16 expect, __u16 *count) tail = q_info->sq_tail_index; hisi_qm_fill_sqe(req, q_info, tail, send_num); tail = (tail + send_num) % q_info->sq_depth; + + /* + * Before sending doorbell, check the queue status, + * if the queue is disable, return failure. + */ + if (unlikely(wd_ioread32(q_info->ds_tx_base) == 1)) { + pthread_spin_unlock(&q_info->sd_lock); + WD_DEV_ERR(qp->h_ctx, "wd queue hw error happened before qm send!\n"); + return -WD_HW_EACCESS; + } + + /* Make sure sqe is filled before db ring and queue status check is complete. */ + mb(); q_info->db(q_info, QM_DBELL_CMD_SQ, tail, 0); q_info->sq_tail_index = tail;
/* Make sure used_num is changed before the next thread gets free sqe. */ __atomic_add_fetch(&q_info->used_num, send_num, __ATOMIC_RELAXED); - *count = send_num; - pthread_spin_unlock(&q_info->sd_lock); + *count = send_num;
return 0; } @@ -509,6 +516,8 @@ static int hisi_qm_recv_single(struct hisi_qm_queue_info *q_info, void *resp) cqe = q_info->cq_base + i * sizeof(struct cqe);
if (q_info->cqc_phase == CQE_PHASE(cqe)) { + /* Make sure cqe valid bit is set */ + rmb(); j = CQE_SQ_HEAD_INDEX(cqe); if (unlikely(j >= q_info->sq_depth)) { pthread_spin_unlock(&q_info->rv_lock); @@ -529,6 +538,18 @@ static int hisi_qm_recv_single(struct hisi_qm_queue_info *q_info, void *resp) i++; }
+ /* + * Before sending doorbell, check the queue status, + * if the queue is disable, return failure. + */ + if (unlikely(wd_ioread32(q_info->ds_rx_base) == 1)) { + pthread_spin_unlock(&q_info->rv_lock); + WD_DEV_ERR(qp->h_ctx, "wd queue hw error happened before qm receive!\n"); + return -WD_HW_EACCESS; + } + + /* Make sure queue status check is complete. */ + rmb(); q_info->db(q_info, QM_DBELL_CMD_CQ, i, q_info->epoll_en);
/* only support one thread poll one queue, so no need protect */ @@ -554,10 +575,6 @@ int hisi_qm_recv(handle_t h_qp, void *resp, __u16 expect, __u16 *count) return 0;
q_info = &qp->q_info; - if (unlikely(wd_ioread32(q_info->ds_rx_base) == 1)) { - WD_DEV_ERR(qp->h_ctx, "wd queue hw error happened before qm receive!\n"); - return -WD_HW_EACCESS; - }
for (i = 0; i < expect; i++) { offset = i * q_info->sqe_size; @@ -568,10 +585,6 @@ int hisi_qm_recv(handle_t h_qp, void *resp, __u16 expect, __u16 *count) }
*count = recv_num; - if (unlikely(wd_ioread32(q_info->ds_rx_base) == 1)) { - WD_DEV_ERR(qp->h_ctx, "wd queue hw error happened in qm receive!\n"); - return -WD_HW_EACCESS; - }
return ret; } diff --git a/include/wd.h b/include/wd.h index 0e67cad..0a654d6 100644 --- a/include/wd.h +++ b/include/wd.h @@ -167,7 +167,7 @@ static inline uint32_t wd_ioread32(void *addr) uint32_t ret;
ret = *((volatile uint32_t *)addr); - rmb(); + return ret; }
@@ -176,19 +176,17 @@ static inline uint64_t wd_ioread64(void *addr) uint64_t ret;
ret = *((volatile uint64_t *)addr); - rmb(); + return ret; }
static inline void wd_iowrite32(void *addr, uint32_t value) { - wmb(); *((volatile uint32_t *)addr) = value; }
static inline void wd_iowrite64(void *addr, uint64_t value) { - wmb(); *((volatile uint64_t *)addr) = value; }