After a series of modification, the 'hw_msg->low_tag' is used to represent the sequence of sync or async task element now.
In async mode, the value of 'hw_msg->low_tag' comes from async task pool, refers to wd_get_msg_from_pool(). In sync mode, the value of 'hw_msg->low_tag' is a random number, refers to hisi_set_msg_id(). Therefore, whether 'hw_msg->low_tag' is zero cannot be used as the judgment condition for different modes, so 'hw_msg->low_tag' cannot be set to zero directly. This is the reason why the async task of sm2 failed.
To fix this problem, we remove the operation of setting tag to zero, use 'qp_mode' to distinguish between sync and async modes.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- drv/hisi_hpre.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index 5d6e537..116097d 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -827,7 +827,6 @@ static int ecc_prepare_alg(struct wd_ecc_msg *msg, return 0; }
- static int trans_cv_param_to_hpre_bin(struct wd_dtb *p, struct wd_dtb *a, struct wd_dtb *b, struct wd_dtb *n, struct wd_ecc_point *g) @@ -1942,13 +1941,12 @@ static int sm2_enc_out_transfer(struct wd_ecc_msg *msg, }
static int ecc_out_transfer(struct wd_ecc_msg *msg, - struct hisi_hpre_sqe *hw_msg) + struct hisi_hpre_sqe *hw_msg, __u8 qp_mode) { int ret = -WD_EINVAL; void *va;
- /* async */ - if (LW_U16(hw_msg->low_tag)) { + if (qp_mode == CTX_MODE_ASYNC) { va = VA_ADDR(hw_msg->hi_out, hw_msg->low_out); msg->req.dst = container_of(va, struct wd_ecc_out, data); } @@ -2240,7 +2238,8 @@ static int sm2_convert_dec_out(struct wd_ecc_msg *src, return ret; }
-static int ecc_sqe_parse(struct hisi_qp *qp, struct wd_ecc_msg *msg, struct hisi_hpre_sqe *hw_msg) +static int ecc_sqe_parse(struct hisi_qp *qp, struct wd_ecc_msg *msg, + struct hisi_hpre_sqe *hw_msg) { struct wd_ecc_msg *temp_msg; __u64 tag; @@ -2262,7 +2261,7 @@ static int ecc_sqe_parse(struct hisi_qp *qp, struct wd_ecc_msg *msg, struct hisi
hpre_result_check(hw_msg, &msg->result); if (!msg->result) { - ret = ecc_out_transfer(msg, hw_msg); + ret = ecc_out_transfer(msg, hw_msg, qp->q_info.qp_mode); if (ret) { msg->result = WD_OUT_EPARA; WD_ERR("failed to transfer out ecc BD, ret = %d!\n", ret); @@ -2306,7 +2305,7 @@ static int parse_second_sqe(handle_t h_qp, hsz = (hw_msg.task_len1 + 1) * BYTE_BITS; dst = *(struct wd_ecc_msg **)((uintptr_t)data + hsz * ECDH_OUT_PARAM_NUM); - hw_msg.low_tag = 0; /* use sync mode */ + ret = ecc_sqe_parse((struct hisi_qp *)h_qp, dst, &hw_msg); msg->result = dst->result; *second = dst; @@ -2325,6 +2324,7 @@ static int sm2_enc_parse(handle_t h_qp, __u32 hsz; int ret;
+ msg->tag = tag; data = VA_ADDR(hw_msg->hi_out, hw_msg->low_out); hsz = (hw_msg->task_len1 + 1) * BYTE_BITS; first = *(struct wd_ecc_msg **)((uintptr_t)data + @@ -2332,7 +2332,6 @@ static int sm2_enc_parse(handle_t h_qp, memcpy(&src, first + 1, sizeof(src));
/* parse first sqe */ - hw_msg->low_tag = 0; /* use sync mode */ ret = ecc_sqe_parse((struct hisi_qp *)h_qp, first, hw_msg); if (ret) { WD_ERR("failed to parse first BD, ret = %d!\n", ret); @@ -2351,11 +2350,12 @@ static int sm2_enc_parse(handle_t h_qp, WD_ERR("failed to convert sm2 std format, ret = %d!\n", ret); goto free_second; } + free_second: free_req(second); free_first: free_req(first); - msg->tag = tag; + return ret; }
@@ -2376,21 +2376,21 @@ static int sm2_dec_parse(handle_t ctx, struct wd_ecc_msg *msg, memcpy(&src, dst + 1, sizeof(src));
/* parse first sqe */ - hw_msg->low_tag = 0; /* use sync mode */ ret = ecc_sqe_parse((struct hisi_qp *)ctx, dst, hw_msg); if (ret) { WD_ERR("failed to parse decode BD, ret = %d!\n", ret); goto fail; } msg->result = dst->result; + msg->tag = tag;
ret = sm2_convert_dec_out(&src, dst); if (unlikely(ret)) { WD_ERR("failed to convert sm2 decode out, ret = %d!\n", ret); goto fail; } + fail: - msg->tag = tag; free(dst->req.dst); free(dst);
Use 'qp_mode' to distinguish between sync and async modes of RSA and DH algs.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- drv/hisi_hpre.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index 116097d..a232e84 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -334,7 +334,7 @@ static int hpre_tri_bin_transfer(struct wd_dtb *bin0, struct wd_dtb *bin1, }
static int rsa_out_transfer(struct wd_rsa_msg *msg, - struct hisi_hpre_sqe *hw_msg) + struct hisi_hpre_sqe *hw_msg, __u8 qp_mode) { struct wd_rsa_req *req = &msg->req; struct wd_rsa_kg_out *key = req->dst; @@ -345,8 +345,7 @@ static int rsa_out_transfer(struct wd_rsa_msg *msg, int ret;
if (hw_msg->alg == HW_ALG_KG_CRT || hw_msg->alg == HW_ALG_KG_STD) { - /* async */ - if (LW_U16(hw_msg->low_tag)) { + if (qp_mode == CTX_MODE_ASYNC) { data = VA_ADDR(hw_msg->hi_out, hw_msg->low_out); key = container_of(data, struct wd_rsa_kg_out, data); } else { @@ -607,7 +606,7 @@ static int rsa_recv(handle_t ctx, void *rsa_msg)
hpre_result_check(&hw_msg, &msg->result); if (!msg->result) { - ret = rsa_out_transfer(msg, &hw_msg); + ret = rsa_out_transfer(msg, &hw_msg, qp->q_info.qp_mode); if (ret) { WD_ERR("failed to transfer out rsa BD!\n"); msg->result = WD_OUT_EPARA; @@ -660,15 +659,14 @@ static int fill_dh_xp_params(struct wd_dh_msg *msg, }
static int dh_out_transfer(struct wd_dh_msg *msg, - struct hisi_hpre_sqe *hw_msg) + struct hisi_hpre_sqe *hw_msg, __u8 qp_mode) { __u16 key_bytes = (hw_msg->task_len1 + 1) * BYTE_BITS; struct wd_dh_req *req = &msg->req; void *out; int ret;
- /* async */ - if (LW_U16(hw_msg->low_tag)) + if (qp_mode == CTX_MODE_ASYNC) out = VA_ADDR(hw_msg->hi_out, hw_msg->low_out); else out = req->pri; @@ -763,7 +761,7 @@ static int dh_recv(handle_t ctx, void *dh_msg)
hpre_result_check(&hw_msg, &msg->result); if (!msg->result) { - ret = dh_out_transfer(msg, &hw_msg); + ret = dh_out_transfer(msg, &hw_msg, qp->q_info.qp_mode); if (ret) { WD_ERR("failed to transfer out dh BD!\n"); msg->result = WD_OUT_EPARA;
The previous processing logic of ecc_sqe_parse() was not clear enough, so it was modified.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- drv/hisi_hpre.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index a232e84..877b2a5 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -557,6 +557,7 @@ static void hpre_result_check(struct hisi_hpre_sqe *hw_msg, __u8 *result) { *result = WD_SUCCESS; + if (hw_msg->done != HPRE_HW_TASK_DONE || hw_msg->etype || hw_msg->etype1) { WD_ERR("failed to do hpre task! done=0x%x, etype=0x%x, etype1=0x%x!\n", @@ -2258,18 +2259,22 @@ static int ecc_sqe_parse(struct hisi_qp *qp, struct wd_ecc_msg *msg, }
hpre_result_check(hw_msg, &msg->result); - if (!msg->result) { - ret = ecc_out_transfer(msg, hw_msg, qp->q_info.qp_mode); - if (ret) { - msg->result = WD_OUT_EPARA; - WD_ERR("failed to transfer out ecc BD, ret = %d!\n", ret); - } - } else { + if (msg->result) { ret = -msg->result; + goto err; }
- if (unlikely(msg->result != WD_SUCCESS)) - dump_hpre_msg(temp_msg, "ecc"); + ret = ecc_out_transfer(msg, hw_msg, qp->q_info.qp_mode); + if (ret) { + msg->result = WD_OUT_EPARA; + WD_ERR("failed to transfer out ecc BD, ret = %d!\n", ret); + goto err; + } + + return ret; + +err: + dump_hpre_msg(temp_msg, "ecc");
return ret; }