[PATCH 01/29] uadk: fix for aead soft compute

From: Wenkai Lin <linwenkai6@hisilicon.com> When soft computing is required, an invalid BD is used to ensure the integrity of the sending and receiving process, it is more efficient. Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_sec.c | 49 ++++++++++++------------------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c index 7f4ae109..5990565a 100644 --- a/drv/hisi_sec.c +++ b/drv/hisi_sec.c @@ -54,6 +54,8 @@ #define SEC_AI_GEN_OFFSET_V3 2 #define SEC_SEQ_OFFSET_V3 6 #define SEC_AUTH_MASK_V3 0xFFFFFFFC +#define SEC_BD3_IVLD_OFFSET 0x4 +#define SEC_BD2_IVLD_OFFSET 0x7 #define SEC_SGL_MODE_MASK_V3 0x4800 #define SEC_PBUFF_MODE_MASK_V3 0x800 @@ -2440,7 +2442,7 @@ static int gcm_do_soft_mac(struct wd_aead_msg *msg) msg->result = WD_SUCCESS; - return WD_SOFT_COMPUTING; + return WD_SUCCESS; } static int fill_stream_bd2(struct wd_aead_msg *msg, struct hisi_sec_sqe *sqe) @@ -2460,6 +2462,8 @@ static int fill_stream_bd2(struct wd_aead_msg *msg, struct hisi_sec_sqe *sqe) if (msg->cmode == WD_CIPHER_GCM) { gcm_auth_ivin(msg); ret = gcm_do_soft_mac(msg); + /* Make the bd invalid to avoid recalculation of the data. */ + sqe->iv_tls_ld = 0x1 << SEC_BD2_IVLD_OFFSET; } break; default: @@ -2577,12 +2581,8 @@ static int hisi_sec_aead_send(struct wd_alg_driver *drv, handle_t ctx, void *wd_ fill_aead_bd2_addr(msg, &sqe); ret = fill_stream_bd2(msg, &sqe); - if (ret == WD_SOFT_COMPUTING) { - ret = 0; - goto put_sgl; - } else if (unlikely(ret)) { + if (unlikely(ret)) goto put_sgl; - } hisi_set_msg_id(h_qp, &msg->tag); sqe.type2.tag = (__u16)msg->tag; @@ -2661,24 +2661,6 @@ static void parse_aead_bd2(struct hisi_qp *qp, struct hisi_sec_sqe *sqe, dump_sec_msg(temp_msg, "aead"); } -static bool soft_compute_check(struct hisi_qp *qp, struct wd_aead_msg *msg) -{ - /* Asynchronous mode does not use the sent message, so ignores it */ - if (qp->q_info.qp_mode == CTX_MODE_ASYNC) - return false; - /* - * For aead gcm stream mode, due to some hardware limitations, - * the final message was not sent to hardware if the qm is - * not higher than v3 version or the input length of the - * message is 0, the software calculation has been executed. - */ - if (msg->msg_state == AEAD_MSG_END && msg->cmode == WD_CIPHER_GCM && - (qp->q_info.hw_type <= HISI_QM_API_VER3_BASE || !msg->in_bytes)) - return true; - - return false; -} - static int hisi_sec_aead_recv(struct wd_alg_driver *drv, handle_t ctx, void *wd_msg) { handle_t h_qp = (handle_t)wd_ctx_get_priv(ctx); @@ -2687,9 +2669,6 @@ static int hisi_sec_aead_recv(struct wd_alg_driver *drv, handle_t ctx, void *wd_ __u16 count = 0; int ret; - if (soft_compute_check((struct hisi_qp *)h_qp, recv_msg)) - return 0; - ret = hisi_qm_recv(h_qp, &sqe, 1, &count); if (ret < 0) return ret; @@ -2886,10 +2865,13 @@ static int fill_stream_bd3(handle_t h_qp, struct wd_aead_msg *msg, struct hisi_s if (msg->cmode == WD_CIPHER_GCM) { gcm_auth_ivin(msg); /* Due to hardware limitations, software compute is required. */ - if (qp->q_info.hw_type <= HISI_QM_API_VER3_BASE || !msg->in_bytes) + if (qp->q_info.hw_type <= HISI_QM_API_VER3_BASE || !msg->in_bytes) { ret = gcm_do_soft_mac(msg); - else + /* Make the bd invalid to avoid recalculation of the data. */ + sqe->bd_param |= 0x1 << SEC_BD3_IVLD_OFFSET; + } else { fill_gcm_final_bd3(msg, sqe); + } } break; default: @@ -2982,12 +2964,8 @@ static int hisi_sec_aead_send_v3(struct wd_alg_driver *drv, handle_t ctx, void * fill_aead_bd3_addr(msg, &sqe); ret = fill_stream_bd3(h_qp, msg, &sqe); - if (ret == WD_SOFT_COMPUTING) { - ret = 0; - goto put_sgl; - } else if (unlikely(ret)) { + if (unlikely(ret)) goto put_sgl; - } hisi_set_msg_id(h_qp, &msg->tag); sqe.tag = msg->tag; @@ -3059,9 +3037,6 @@ static int hisi_sec_aead_recv_v3(struct wd_alg_driver *drv, handle_t ctx, void * __u16 count = 0; int ret; - if (soft_compute_check((struct hisi_qp *)h_qp, recv_msg)) - return 0; - ret = hisi_qm_recv(h_qp, &sqe, 1, &count); if (ret < 0) return ret; -- 2.33.0

From: Weili Qian <qianweili@huawei.com> The trng module is not required. Therefore, remove the trng module code. Signed-off-by: Weili Qian <qianweili@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- Makefile.am | 4 +- configure.ac | 1 - uadk_tool/Makefile.am | 1 - uadk_tool/benchmark/trng_wd_benchmark.c | 333 ------------ uadk_tool/benchmark/trng_wd_benchmark.h | 7 - uadk_tool/benchmark/uadk_benchmark.c | 15 - uadk_tool/benchmark/uadk_benchmark.h | 1 - v1/drv/hisi_rng_udrv.c | 167 ------ v1/drv/hisi_rng_udrv.h | 40 -- v1/libwd.map | 5 - v1/test/Makefile.am | 1 - v1/test/hisi_trng_test/Makefile.am | 20 - v1/test/hisi_trng_test/test_hisi_trngk.c | 155 ------ v1/test/hisi_trng_test/test_hisi_trngp.c | 137 ----- v1/test/hisi_trng_test/test_hisi_trngu.c | 624 ----------------------- v1/wd.h | 2 +- v1/wd_adapter.c | 7 - v1/wd_rng.c | 296 ----------- v1/wd_rng.h | 76 --- 19 files changed, 2 insertions(+), 1890 deletions(-) delete mode 100644 uadk_tool/benchmark/trng_wd_benchmark.c delete mode 100644 uadk_tool/benchmark/trng_wd_benchmark.h delete mode 100644 v1/drv/hisi_rng_udrv.c delete mode 100644 v1/drv/hisi_rng_udrv.h delete mode 100644 v1/test/hisi_trng_test/Makefile.am delete mode 100755 v1/test/hisi_trng_test/test_hisi_trngk.c delete mode 100644 v1/test/hisi_trng_test/test_hisi_trngp.c delete mode 100755 v1/test/hisi_trng_test/test_hisi_trngu.c delete mode 100644 v1/wd_rng.c delete mode 100644 v1/wd_rng.h diff --git a/Makefile.am b/Makefile.am index 9725f4dd..c0b0a81f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,7 +59,6 @@ uadk_drivers_LTLIBRARIES=libhisi_sec.la libhisi_hpre.la libhisi_zip.la \ libwd_la_SOURCES=wd.c wd_mempool.c wd.h wd_alg.c wd_alg.h \ v1/wd.c v1/wd.h v1/wd_adapter.c v1/wd_adapter.h \ - v1/wd_rng.c v1/wd_rng.h \ v1/wd_rsa.c v1/wd_rsa.h \ v1/wd_aead.c v1/wd_aead.h \ v1/wd_dh.c v1/wd_dh.h \ @@ -75,8 +74,7 @@ libwd_la_SOURCES=wd.c wd_mempool.c wd.h wd_alg.c wd_alg.h \ v1/drv/hisi_qm_udrv.c v1/drv/hisi_qm_udrv.h \ v1/drv/hisi_zip_udrv.c v1/drv/hisi_zip_udrv.h \ v1/drv/hisi_hpre_udrv.c v1/drv/hisi_hpre_udrv.h \ - v1/drv/hisi_sec_udrv.c v1/drv/hisi_sec_udrv.h \ - v1/drv/hisi_rng_udrv.c v1/drv/hisi_rng_udrv.h + v1/drv/hisi_sec_udrv.c v1/drv/hisi_sec_udrv.h libwd_dae_la_SOURCES=wd_dae.h wd_agg.h wd_agg_drv.h wd_agg.c \ wd_util.c wd_util.h wd_sched.c wd_sched.h wd.c wd.h diff --git a/configure.ac b/configure.ac index 285ac029..ed060d8e 100644 --- a/configure.ac +++ b/configure.ac @@ -102,7 +102,6 @@ AC_CONFIG_FILES([Makefile v1/test/bmm_test/Makefile v1/test/test_mm/Makefile v1/test/hisi_hpre_test/Makefile - v1/test/hisi_trng_test/Makefile v1/test/hisi_sec_test/Makefile v1/test/hisi_sec_test_sgl/Makefile v1/test/hisi_zip_test/Makefile diff --git a/uadk_tool/Makefile.am b/uadk_tool/Makefile.am index ea830098..6fd9d95f 100644 --- a/uadk_tool/Makefile.am +++ b/uadk_tool/Makefile.am @@ -17,7 +17,6 @@ uadk_tool_SOURCES=uadk_tool.c dfx/uadk_dfx.c dfx/uadk_dfx.h \ benchmark/hpre_wd_benchmark.c hpre_wd_benchmark.h \ benchmark/zip_uadk_benchmark.c benchmark/zip_uadk_benchmark.h \ benchmark/zip_wd_benchmark.c benchmark/zip_wd_benchmark.h \ - benchmark/trng_wd_benchmark.c benchmark/trng_wd_benchmark.h \ test/uadk_test.c test/uadk_test.h \ test/test_sec.c test/test_sec.h test/sec_template_tv.h diff --git a/uadk_tool/benchmark/trng_wd_benchmark.c b/uadk_tool/benchmark/trng_wd_benchmark.c deleted file mode 100644 index 2f058d41..00000000 --- a/uadk_tool/benchmark/trng_wd_benchmark.c +++ /dev/null @@ -1,333 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include <numa.h> -#include "uadk_benchmark.h" - -#include "trng_wd_benchmark.h" -#include "v1/wd.h" -#include "v1/wd_rng.h" - -struct thread_bd_res { - struct wd_queue *queue; - void *out; - __u32 in_bytes; -}; - -struct thread_queue_res { - struct thread_bd_res *bd_res; -}; - -struct wd_thread_res { - u32 td_id; - u32 pollid; -}; - -struct trng_async_tag { - void *ctx; - int optype; -}; - -static unsigned int g_thread_num; -static struct thread_queue_res g_thread_queue; - -static int init_trng_wd_queue(struct acc_option *options) -{ - int i, ret; - - g_thread_queue.bd_res = malloc(g_thread_num * sizeof(struct thread_bd_res)); - if (!g_thread_queue.bd_res) { - printf("failed to malloc thread res memory!\n"); - return -ENOMEM; - } - - for (i = 0; i < g_thread_num; i++) { - g_thread_queue.bd_res[i].queue = malloc(sizeof(struct wd_queue)); - if (!g_thread_queue.bd_res[i].queue) { - ret = -ENOMEM; - goto free_mem; - } - - g_thread_queue.bd_res[i].queue->capa.alg = options->algclass; - /* nodemask need to be clean */ - g_thread_queue.bd_res[i].queue->node_mask = 0x0; - memset(g_thread_queue.bd_res[i].queue->dev_path, 0x0, PATH_STR_SIZE); - if (strlen(options->device) != 0) { - ret = snprintf(g_thread_queue.bd_res[i].queue->dev_path, - PATH_STR_SIZE, "%s", options->device); - if (ret < 0) { - WD_ERR("failed to copy dev file path!\n"); - return -WD_EINVAL; - } - } - - g_thread_queue.bd_res[i].in_bytes = options->pktlen; - g_thread_queue.bd_res[i].out = malloc(options->pktlen); - if (!g_thread_queue.bd_res[i].queue) { - free(g_thread_queue.bd_res[i].queue); - ret = -ENOMEM; - goto free_mem; - } - - ret = wd_request_queue(g_thread_queue.bd_res[i].queue); - if (ret) { - printf("failed to request queue %d, ret = %d!\n", i, ret); - free(g_thread_queue.bd_res[i].out); - free(g_thread_queue.bd_res[i].queue); - goto free_mem; - } - } - - return 0; - -free_mem: - for (i = i - 1; i >= 0; i--) { - wd_release_queue(g_thread_queue.bd_res[i].queue); - free(g_thread_queue.bd_res[i].out); - free(g_thread_queue.bd_res[i].queue); - } - - free(g_thread_queue.bd_res); - return ret; -} - -static void uninit_trng_wd_queue(void) -{ - int j; - - for (j = 0; j < g_thread_num; j++) { - wd_release_queue(g_thread_queue.bd_res[j].queue); - free(g_thread_queue.bd_res[j].out); - free(g_thread_queue.bd_res[j].queue); - } - - free(g_thread_queue.bd_res); -} - -static void *trng_wd_sync_run(void *arg) -{ - struct wd_thread_res *pdata = (struct wd_thread_res *)arg; - struct wcrypto_rng_ctx_setup trng_setup; - struct wcrypto_rng_op_data opdata; - struct wd_queue *queue; - void *ctx = NULL; - u32 count = 0; - int ret; - - queue = g_thread_queue.bd_res[pdata->td_id].queue; - ctx = wcrypto_create_rng_ctx(queue, &trng_setup); - if (!ctx) - return NULL; - - memset(&opdata, 0, sizeof(opdata)); - opdata.in_bytes = g_thread_queue.bd_res[pdata->td_id].in_bytes; - opdata.out = g_thread_queue.bd_res[pdata->td_id].out; - opdata.op_type = WCRYPTO_TRNG_GEN; - - do { - ret = wcrypto_do_rng(ctx, &opdata, NULL); - if (ret) { - printf("failed to do rng task, ret: %d\n", ret); - goto ctx_release; - } - - count++; - if (get_run_state() == 0) - break; - } while (true); - -ctx_release: - wcrypto_del_rng_ctx(ctx); - add_recv_data(count, opdata.in_bytes); - - return NULL; -} - -static void trng_wd_sync_threads(void) -{ - struct wd_thread_res threads_args[THREADS_NUM]; - pthread_t tdid[THREADS_NUM]; - int i, ret; - - for (i = 0; i < g_thread_num; i++) { - threads_args[i].td_id = i; - ret = pthread_create(&tdid[i], NULL, trng_wd_sync_run, &threads_args[i]); - if (ret) { - printf("failed to create sync thread!\n"); - return; - } - } - - /* join thread */ - for (i = 0; i < g_thread_num; i++) { - ret = pthread_join(tdid[i], NULL); - if (ret) { - printf("failed to join sync thread!\n"); - return; - } - } -} - -void *wd_trng_poll(void *data) -{ - struct wd_thread_res *pdata = (struct wd_thread_res *)data; - struct wd_queue *queue; - u32 last_time = 2; // poll need one more recv time - u32 count = 0; - u32 in_bytes; - int recv; - - in_bytes = g_thread_queue.bd_res[pdata->pollid].in_bytes; - queue = g_thread_queue.bd_res[pdata->pollid].queue; - - while (last_time) { - recv = wcrypto_rng_poll(queue, ACC_QUEUE_SIZE); - if (recv < 0) { - printf("failed to recv bd, ret: %d!\n", recv); - goto recv_error; - } - count += recv; - - if (get_run_state() == 0) - last_time--; - } - -recv_error: - add_recv_data(count, in_bytes); - - return NULL; -} - -static void *trng_async_cb(const void *msg, void *tag) -{ - return NULL; -} - -static void *wd_trng_async_run(void *arg) -{ - struct wd_thread_res *pdata = (struct wd_thread_res *)arg; - struct wcrypto_rng_ctx_setup trng_setup; - struct wcrypto_rng_op_data opdata; - struct trng_async_tag *tag = NULL; - struct wd_queue *queue; - void *ctx = NULL; - int ret, i; - - memset(&opdata, 0, sizeof(opdata)); - - queue = g_thread_queue.bd_res[pdata->td_id].queue; - trng_setup.cb = (void *)trng_async_cb; - - ctx = wcrypto_create_rng_ctx(queue, &trng_setup); - if (!ctx) - return NULL; - - opdata.in_bytes = g_thread_queue.bd_res[pdata->td_id].in_bytes; - opdata.out = g_thread_queue.bd_res[pdata->td_id].out; - opdata.op_type = WCRYPTO_TRNG_GEN; - - tag = malloc(sizeof(*tag) * MAX_POOL_LENTH); - if (!tag) { - printf("failed to malloc dh tag!\n"); - goto free_ctx; - } - tag->ctx = ctx; - - do { - ret = wcrypto_do_rng(ctx, &opdata, tag); - if (ret && ret != -WD_EBUSY) { - printf("failed to send trng task, ret = %d!\n", ret); - break; - } - - if (get_run_state() == 0) - break; - } while (true); - - /* Release memory after all tasks are complete. */ - i = 0; - while (get_recv_time() != g_thread_num) { - if (i++ >= MAX_TRY_CNT) { - printf("failed to wait poll thread finish!\n"); - break; - } - - usleep(SEND_USLEEP); - } - - if (tag) - free(tag); -free_ctx: - wcrypto_del_rng_ctx(ctx); - add_send_complete(); - - return NULL; -} - -static void trng_wd_async_threads(void) -{ - struct wd_thread_res threads_args[THREADS_NUM]; - pthread_t tdid[THREADS_NUM]; - pthread_t pollid[THREADS_NUM]; - int i, ret; - - for (i = 0; i < g_thread_num; i++) { - threads_args[i].pollid = i; - /* poll thread */ - ret = pthread_create(&pollid[i], NULL, wd_trng_poll, &threads_args[i]); - if (ret) { - printf("failed to create poll thread!\n"); - return; - } - } - - for (i = 0; i < g_thread_num; i++) { - threads_args[i].td_id = i; - ret = pthread_create(&tdid[i], NULL, wd_trng_async_run, &threads_args[i]); - if (ret) { - printf("failed to create async thread!\n"); - return; - } - } - - /* join thread */ - for (i = 0; i < g_thread_num; i++) { - ret = pthread_join(tdid[i], NULL); - if (ret) { - printf("failed to join async thread!\n"); - return; - } - } - - for (i = 0; i < g_thread_num; i++) { - ret = pthread_join(pollid[i], NULL); - if (ret) { - printf("failed to join poll thread!\n"); - return; - } - } -} - -int trng_wd_benchmark(struct acc_option *options) -{ - u32 ptime; - int ret; - - signal(SIGSEGV, segmentfault_handler); - g_thread_num = options->threads; - - ret = init_trng_wd_queue(options); - if (ret) - return ret; - - get_pid_cpu_time(&ptime); - time_start(options->times); - if (options->syncmode) - trng_wd_async_threads(); - else - trng_wd_sync_threads(); - cal_perfermance_data(options, ptime); - - uninit_trng_wd_queue(); - - return 0; -} diff --git a/uadk_tool/benchmark/trng_wd_benchmark.h b/uadk_tool/benchmark/trng_wd_benchmark.h deleted file mode 100644 index 49453c81..00000000 --- a/uadk_tool/benchmark/trng_wd_benchmark.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef TRNG_WD_BENCHMARK_H -#define TRNG_WD_BENCHMARK_H - -extern int trng_wd_benchmark(struct acc_option *options); -#endif /* TRNG_WD_BENCHMARK_H */ diff --git a/uadk_tool/benchmark/uadk_benchmark.c b/uadk_tool/benchmark/uadk_benchmark.c index 16980616..e6cc2ddf 100644 --- a/uadk_tool/benchmark/uadk_benchmark.c +++ b/uadk_tool/benchmark/uadk_benchmark.c @@ -16,8 +16,6 @@ #include "zip_uadk_benchmark.h" #include "zip_wd_benchmark.h" -#include "trng_wd_benchmark.h" - #define TABLE_SPACE_SIZE 8 /*----------------------------------------head struct--------------------------------------------------------*/ @@ -153,7 +151,6 @@ static struct acc_alg_item alg_options[] = { {"sha512", "sha512", SHA512_ALG}, {"sha512-224", "sha512-224", SHA512_224}, {"sha512-256", "sha512-256", SHA512_256}, - {"trng", "trng", TRNG}, {"", "", ALG_MAX} }; @@ -385,11 +382,6 @@ static void parse_alg_param(struct acc_option *option) option->acctype = HPRE_TYPE; option->subtype = X448_TYPE; break; - case TRNG: - snprintf(option->algclass, MAX_ALG_NAME, "%s", "trng"); - option->acctype = TRNG_TYPE; - option->subtype = DEFAULT_TYPE; - break; default: if (option->algtype <= RSA_4096_CRT) { snprintf(option->algclass, MAX_ALG_NAME, "%s", "rsa"); @@ -518,13 +510,6 @@ static int benchmark_run(struct acc_option *option) ret = zip_wd_benchmark(option); } break; - case TRNG_TYPE: - if (option->modetype == SVA_MODE) - ACC_TST_PRT("TRNG not support sva mode..\n"); - else if (option->modetype == NOSVA_MODE) - ret = trng_wd_benchmark(option); - - break; } return ret; diff --git a/uadk_tool/benchmark/uadk_benchmark.h b/uadk_tool/benchmark/uadk_benchmark.h index c4042355..39725724 100644 --- a/uadk_tool/benchmark/uadk_benchmark.h +++ b/uadk_tool/benchmark/uadk_benchmark.h @@ -87,7 +87,6 @@ enum acc_type { SEC_TYPE, HPRE_TYPE, ZIP_TYPE, - TRNG_TYPE, }; enum acc_init_type { diff --git a/v1/drv/hisi_rng_udrv.c b/v1/drv/hisi_rng_udrv.c deleted file mode 100644 index 605ef275..00000000 --- a/v1/drv/hisi_rng_udrv.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2018-2019 Huawei Technologies Co.,Ltd.All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <unistd.h> -#include <stdio.h> -#include <pthread.h> -#include <sys/mman.h> -#include <string.h> -#include <stdint.h> -#include <sys/epoll.h> -#include <sys/eventfd.h> -#include <sys/types.h> - -#include "hisi_rng_udrv.h" - -#define HISI_RNG_BYTES 4 -#define MAX_RETRY_COUNTS 8 -#define RNG_NUM_OFFSET 0x00F0 - -int rng_init_queue(struct wd_queue *q) -{ - struct q_info *qinfo = q->qinfo; - struct rng_queue_info *info; - int ret; - - info = calloc(1, sizeof(*info)); - if (!info) { - WD_ERR("no mem!\n"); - return -ENOMEM; - } - - ret = pthread_spin_init(&info->lock, PTHREAD_PROCESS_PRIVATE); - if (ret) { - free(info); - WD_ERR("failed to init rng qinfo lock!\n"); - return ret; - } - - qinfo->priv = info; - info->mmio_base = wd_drv_mmap_qfr(q, WD_UACCE_QFRT_MMIO, 0); - if (info->mmio_base == MAP_FAILED) { - info->mmio_base = NULL; - qinfo->priv = NULL; - pthread_spin_destroy(&info->lock); - free(info); - WD_ERR("mmap trng mmio fail\n"); - return -ENOMEM; - } - - return 0; -} - -void rng_uninit_queue(struct wd_queue *q) -{ - struct q_info *qinfo = q->qinfo; - struct rng_queue_info *info = qinfo->priv; - - wd_drv_unmmap_qfr(q, info->mmio_base, WD_UACCE_QFRT_MMIO, 0); - - free(qinfo->priv); - qinfo->priv = NULL; - pthread_spin_destroy(&info->lock); -} - -int rng_send(struct wd_queue *q, void **req, __u32 num) -{ - struct q_info *qinfo = q->qinfo; - struct rng_queue_info *info = qinfo->priv; - - pthread_spin_lock(&info->lock); - if (!info->req_cache[info->send_idx]) { - info->req_cache[info->send_idx] = req[0]; - info->send_idx++; - pthread_spin_unlock(&info->lock); - return 0; - } - pthread_spin_unlock(&info->lock); - - WD_ERR("queue is full!\n"); - return -WD_EBUSY; -} - -static int rng_read(struct rng_queue_info *info, struct wcrypto_rng_msg *msg) -{ - __u32 max = msg->in_bytes; - __u32 currsize = 0; - int recv_count = 0; - __u32 val; - - do { - val = wd_reg_read((void *)((uintptr_t)info->mmio_base + - RNG_NUM_OFFSET)); - if (!val) { - if (++recv_count > MAX_RETRY_COUNTS) { - WD_ERR("read random data timeout\n"); - break; - } - - usleep(1); - continue; - } - - recv_count = 0; - if (max - currsize >= HISI_RNG_BYTES) { - memcpy(msg->out + currsize, &val, HISI_RNG_BYTES); - currsize += HISI_RNG_BYTES; - if (currsize == max) - break; - continue; - } - - memcpy(msg->out + currsize, &val, max - currsize); - currsize = max; - } while (currsize < max); - - return currsize; -} - -int rng_recv(struct wd_queue *q, void **resp, __u32 num) -{ - struct q_info *qinfo = q->qinfo; - struct rng_queue_info *info = qinfo->priv; - __u16 usr = (__u16)(uintptr_t)*resp; - struct wcrypto_rng_msg *msg; - struct wcrypto_cb_tag *tag; - __u32 currsize = 0; - - pthread_spin_lock(&info->lock); - msg = info->req_cache[info->recv_idx]; - if (!msg) { - pthread_spin_unlock(&info->lock); - return 0; - } - - info->req_cache[info->recv_idx] = NULL; - info->recv_idx++; - pthread_spin_unlock(&info->lock); - - tag = (void *)(uintptr_t)msg->usr_tag; - if (usr && tag->ctx_id != usr) - return 0; - - currsize = rng_read(info, msg); - if (!currsize) { - WD_ERR("random data err!\n"); - return -WD_EINVAL; - } - - msg->out_bytes = currsize; - *resp = msg; - - return 1; -} diff --git a/v1/drv/hisi_rng_udrv.h b/v1/drv/hisi_rng_udrv.h deleted file mode 100644 index 3efa10e9..00000000 --- a/v1/drv/hisi_rng_udrv.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2018-2019 Huawei Technologies Co.,Ltd.All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HISI_RNG_UDRV_H__ -#define __HISI_RNG_UDRV_H__ - -#include <linux/types.h> -#include "v1/wd.h" -#include "v1/wd_util.h" -#include "v1/wd_rng.h" - -#define TRNG_Q_DEPTH 256 - -struct rng_queue_info { - void *mmio_base; - void *req_cache[TRNG_Q_DEPTH]; - __u8 send_idx; - __u8 recv_idx; - pthread_spinlock_t lock; -}; - -int rng_init_queue(struct wd_queue *q); -void rng_uninit_queue(struct wd_queue *q); -int rng_send(struct wd_queue *q, void **req, __u32 num); -int rng_recv(struct wd_queue *q, void **resp, __u32 num); - -#endif diff --git a/v1/libwd.map b/v1/libwd.map index d53201b5..6c544793 100644 --- a/v1/libwd.map +++ b/v1/libwd.map @@ -133,11 +133,6 @@ global: wcrypto_rsa_poll; wcrypto_del_rsa_ctx; - wcrypto_create_rng_ctx; - wcrypto_del_rng_ctx; - wcrypto_do_rng; - wcrypto_rng_poll; - wd_sglpool_create; wd_sglpool_destroy; wd_alloc_sgl; diff --git a/v1/test/Makefile.am b/v1/test/Makefile.am index 8c262f57..6fa23713 100644 --- a/v1/test/Makefile.am +++ b/v1/test/Makefile.am @@ -4,6 +4,5 @@ SUBDIRS=. test_mm bmm_test SUBDIRS+=hisi_zip_test_sgl -SUBDIRS+=hisi_trng_test if HAVE_CRYPTO SUBDIRS+=hisi_hpre_test diff --git a/v1/test/hisi_trng_test/Makefile.am b/v1/test/hisi_trng_test/Makefile.am deleted file mode 100644 index a9887fc5..00000000 --- a/v1/test/hisi_trng_test/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -AM_CFLAGS=-Wall -Werror -O0 -fno-strict-aliasing -I$(top_srcdir)/include -I$(srcdir) -pthread - -if HAVE_CRYPTO -bin_PROGRAMS=test_hisi_trngu_v1 test_hisi_trngk_v1 test_hisi_trngp_v1 - -test_hisi_trngu_v1_SOURCES=test_hisi_trngu.c -test_hisi_trngk_v1_SOURCES=test_hisi_trngk.c -test_hisi_trngp_v1_SOURCES=test_hisi_trngp.c - -if WD_STATIC_DRV -test_hisi_trngu_v1_LDADD=../../../.libs/libwd.la -test_hisi_trngk_v1_LDADD=../../../.libs/libwd.la -test_hisi_trngp_v1_LDADD=../../../.libs/libwd.la -else -test_hisi_trngu_v1_LDADD=../../../.libs/libwd.so -test_hisi_trngk_v1_LDADD=../../../.libs/libwd.so -test_hisi_trngp_v1_LDADD=../../../.libs/libwd.so -endif - -endif diff --git a/v1/test/hisi_trng_test/test_hisi_trngk.c b/v1/test/hisi_trng_test/test_hisi_trngk.c deleted file mode 100755 index ae719e55..00000000 --- a/v1/test/hisi_trng_test/test_hisi_trngk.c +++ /dev/null @@ -1,155 +0,0 @@ -#include <assert.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#define __USE_GNU -#include <sched.h> -#include <pthread.h> -#include <sys/mman.h> -#include <sys/time.h> -#include <unistd.h> -#include <getopt.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/time.h> -#include <semaphore.h> - - -struct thread_info -{ - pthread_t thread_id; - unsigned int size; - unsigned int num; - int addr; - -}; - -void *trng_thread(void *args) -{ - - int fd = -1; - int fd_w = -1; - int ret; - unsigned int input; - struct thread_info *tinfo = args; - input = tinfo->size; - unsigned int *data = (unsigned int*)malloc(sizeof(unsigned int) * input); - - if(!data) - return NULL; - - if (tinfo->addr == 0){ - -// printf("Now try to get %d bytes random number from /dev/hwrng.\n", input * 4); - fd = open ("/dev/hwrng", O_RDONLY); - } - else if (tinfo->addr == 1){ -// printf("Now try to get %d bytes random number from /dev/random.\n", input * 4); - fd = open ("/dev/random", O_RDONLY); - } - - if (fd <0 ) { - printf("can not open\n"); - return NULL; - } - - fd_w = open ("/root/trng_file", O_WRONLY|O_CREAT|O_APPEND,0777); - if (fd_w <0 ) { - printf("can not open trng_file\n"); - return NULL; - } - memset(data, 0, sizeof(int) * input); - ret = read(fd, data, input); - if (ret < 0) { - printf("read error %d\n", ret); - return NULL; - } - ret =write(fd_w,data,input); - if (ret < 0) { - printf("write error %d\n", ret); - return NULL; - } - - close(fd); - close(fd_w); - - return NULL; -} - - -void trng_test(int addr,int num,unsigned int si,int thread_num) -{ - - int i; - void *ret = NULL; - struct thread_info *tinfo; - tinfo = calloc(thread_num, sizeof(struct thread_info)); - - if (tinfo == NULL) - { - printf("calloc fail...\n"); - return; - } - - for (i = 0; i<thread_num; ++i) - { - tinfo[i].thread_id = i; - tinfo[i].addr = addr; - tinfo[i].num = num; - tinfo[i].size = si; - - if ((pthread_create(&tinfo[i].thread_id,NULL,trng_thread, (void *)&tinfo[i])) != 0) - { - return; - } - } - - for (i=0; i<thread_num; ++i) - { - if (pthread_join(tinfo[i].thread_id, &ret) != 0) - { - printf("thread is not exit....\n"); - return; - } - //printf("thread exit coid %d\n", (int *)ret); - free(ret); - } - free(tinfo); -} - - - - -int main (int argc, char* argv[]) { - - int opt; - int addr = 0, num = 0, thread_num = 0; - unsigned int si = 0; - - while ((opt = getopt(argc, argv, "hri:p:s:")) != -1) { - switch (opt) { - case 'h': - addr = 0; - break; - case 'r': - addr = 1; - break; - case 'i': - num = atoi(optarg); - break; - case 'p': - thread_num = atoi(optarg); - break; - case 's': - si = (unsigned int)atoi(optarg); - break; - default: - break; - } - } - - trng_test(addr,num,si,thread_num); - - return 0; -} diff --git a/v1/test/hisi_trng_test/test_hisi_trngp.c b/v1/test/hisi_trng_test/test_hisi_trngp.c deleted file mode 100644 index 2330b1e1..00000000 --- a/v1/test/hisi_trng_test/test_hisi_trngp.c +++ /dev/null @@ -1,137 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/time.h> -#include <pthread.h> -#include <unistd.h> - -static int input; -static int thread_num; -struct thread_info -{ - pthread_t thread_id; - unsigned int size; - int num; -}; - -void *trng_thread(void *args) -{ - int j; - int fd = -1; - int data; - int ret; - struct thread_info *tinfo = args; - int si; - int num; - int size; - int fd_w = -1; - si = tinfo->size; - num = tinfo->num; - size=si/num; - printf("Now try to get bytes random number from /dev/random.\n"); - fd = open("/dev/random", O_RDONLY); - if (fd <0 ) { - printf("can not open\n"); - return NULL; - } - for (j = 0; j< size; j++) { - ret = read(fd, &data, 1); - if (ret < 0) { - printf("read error %d\n", ret); - return NULL; - } -// else if (ret < 1) -// goto rd_ag; -// if (!data) { -// printf("read data error!\n"); -// return data; -// } - printf("the read num:%x\n",data); - } - fd_w = open ("/root/trng_file", O_RDWR | O_CREAT |O_APPEND , 0777); - if (fd_w <0 ) { - printf("can not open trng_file\n"); - return NULL; - } - ret = write(fd_w,&data,size); - if (ret < 0) { - printf("write error %d\n", ret); - return NULL; - } - close(fd); - close(fd_w); - return NULL; -} - -void trng_test(int input,int thread_num) -{ - int i; - void *ret = NULL; - struct thread_info *tinfo; - tinfo = calloc(thread_num, sizeof(struct thread_info)); - if(tinfo == NULL) - { - printf("calloc fail...\n"); - return; - } - for(i = 0; i<thread_num; ++i) - { - tinfo[i].thread_id = i; - tinfo[i].num=thread_num; -// tinfo[i].addr = addr; -// tinfo[i].num = num; - tinfo[i].size = input; - if((pthread_create(&tinfo[i].thread_id,NULL,trng_thread, (void *)&tinfo[i])) != 0) - { - return; - } - } - - for(i=0; i<thread_num; ++i) - { - if(pthread_join(tinfo[i].thread_id, &ret) != 0) - { - printf("thread is not exit....\n"); - return; - } -// printf("thread exit coid %d\n", (int *)ret); - free(ret); - } - free(tinfo); -} - -int main (int argc, char* argv[]) -{ - struct timeval start_tval, end_tval; - float time,speed; - int fd_f=-1; - fd_f = open ("/root/trng_file", O_RDWR | O_CREAT |O_TRUNC, 0777); - if (fd_f <0 ) { - printf("can not open trng_file\n"); - return fd_f; - } - input = strtoul(argv[1], NULL, 10); - if (input <= 0){ - printf("input error!\n"); - return -1; - } - thread_num = strtoul((char *)argv[2], NULL, 10); - if (thread_num <= 0 || thread_num > 128) { - printf("Invalid threads num:%d!\n",thread_num); - printf("Now set threads num as 2\n"); - thread_num = 2; - } - gettimeofday(&start_tval, NULL); - trng_test(input,thread_num); - gettimeofday(&end_tval, NULL); - time = (float)((end_tval.tv_sec - start_tval.tv_sec) * 1000000 + - (end_tval.tv_usec - start_tval.tv_usec)); - speed = input/(time / 1000000); - printf("read random speed: %0.0f time\n", time); - printf("read random speed: %0.0f bytes/s\n", speed); - close(fd_f); - return 0; -} diff --git a/v1/test/hisi_trng_test/test_hisi_trngu.c b/v1/test/hisi_trng_test/test_hisi_trngu.c deleted file mode 100755 index 86aa8a9b..00000000 --- a/v1/test/hisi_trng_test/test_hisi_trngu.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Copyright 2019 Huawei Technologies Co.,Ltd.All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#define __USE_GNU -#include <sched.h> -#include <pthread.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/syscall.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <unistd.h> -#include <semaphore.h> - -#include "../../wd.h" -#include "../../wd_rng.h" - -#define RNG_TST_PRT printf -#define BN_ULONG unsigned long -#define TEST_MAX_THRD 128 -#define MAX_TRY_TIMES 10000 -#define LOG_INTVL_NUM 8 -#define TEST_CNT 10 - -static int q_num = 1; -static int ctx_num_per_q = 1; - -enum alg_op_type { - TRNG_GEN, - TRNG_AGEN, -}; - -struct trng_user_tag_info { - int pid; - int thread_id; -}; - -struct test_trng_pthread_dt { - int cpu_id; - int thread_num; - void *q; -}; - -static struct test_trng_pthread_dt test_thrds_data[TEST_MAX_THRD]; -static pthread_t system_test_thrds[TEST_MAX_THRD]; -static unsigned int g_input; - - -static inline int _get_cpu_id(int thr, __u64 core_mask) -{ - __u64 i; - int cnt = 0; - - for (i = 1; i < 64; i++) { - if (core_mask & (0x1ull << i)) { - if (thr == cnt) - return i; - cnt++; - } - } - - return 0; -} - -static inline int _get_one_bits(__u64 val) -{ - int count = 0; - - while (val) { - if (val % 2 == 1) - count++; - val = val / 2; - } - - return count; -} - -void *_trng_sys_test_thread(void *data) -{ - int ret, cpuid, i = 0; - struct test_trng_pthread_dt *pdata = data; - struct wcrypto_rng_ctx_setup setup; - struct wcrypto_rng_op_data opdata; - int pid = getpid(); - int thread_id = (int)syscall(__NR_gettid); - struct wd_queue *q; - int *out_data; - void *ctx = NULL; - void *tag = NULL; - - cpu_set_t mask; - CPU_ZERO(&mask); - cpuid = pdata->cpu_id; - q = pdata->q; - CPU_SET(cpuid, &mask); - - if (cpuid) { - ret = pthread_setaffinity_np(pthread_self(), - sizeof(mask), &mask); - if (ret < 0) { - RNG_TST_PRT("Proc-%d, thrd-%d:set affinity fail!\n", - pid, thread_id); - return NULL; - } - RNG_TST_PRT("Proc-%d, thrd-%d bind to cpu-%d!\n", - pid, thread_id, cpuid); - } - - memset(&setup, 0, sizeof(setup)); - memset(&opdata, 0, sizeof(opdata)); - ctx = wcrypto_create_rng_ctx(q, &setup); - if (!ctx) { - RNG_TST_PRT("Proc-%d, %d-TD:create %s ctx fail!\n", - pid, thread_id, q->capa.alg); - ret = -EINVAL; - goto fail_release; - } - - out_data = malloc(g_input); - if(!out_data) { - RNG_TST_PRT("malloc out_data memory fail!\n"); - } - RNG_TST_PRT("request queue fail5!\n"); - - while (1) { - opdata.in_bytes = g_input; - opdata.out = out_data; - ret = wcrypto_do_rng(ctx, &opdata, tag); - if (ret < 0) { - RNG_TST_PRT("Proc-%d, T-%d:trng %d fail!\n", pid, thread_id, i); - goto fail_release; - } - RNG_TST_PRT("the read data size %d!\n", opdata.out_bytes); - i++; - } -fail_release: - if (opdata.out) - free(opdata.out); - if (ctx) - wcrypto_del_rng_ctx(ctx); - return NULL; -} - - -static int trng_sys_test(int thread_num, __u64 lcore_mask, - __u64 hcore_mask) -{ - int i, ret, cnt = 0, j; - struct wd_queue *q; - int h_cpuid, qidx; - - q = malloc(q_num * sizeof(struct wd_queue)); - if (!q) { - RNG_TST_PRT("malloc q memory fail!\n"); - return -ENOMEM; - } - memset(q, 0, q_num * sizeof(struct wd_queue)); - - for (j = 0; j < q_num; j++) { - q[j].capa.alg = "trng"; - ret = wd_request_queue(&q[j]); - if (ret) { - RNG_TST_PRT("request queue %d fail!\n", j); - return ret; - } - } - RNG_TST_PRT("request queue fail!\n"); - if (_get_one_bits(lcore_mask) > 0) - cnt = _get_one_bits(lcore_mask); - else if (_get_one_bits(lcore_mask) == 0 && - _get_one_bits(hcore_mask) == 0) - cnt = thread_num; - - for (i = 0; i < cnt; i++) { - qidx = i / ctx_num_per_q; - test_thrds_data[i].q = &q[qidx]; - test_thrds_data[i].thread_num = thread_num; - test_thrds_data[i].cpu_id = _get_cpu_id(i, lcore_mask); - ret = pthread_create(&system_test_thrds[i], NULL, - _trng_sys_test_thread, &test_thrds_data[i]); - if (ret) { - RNG_TST_PRT("Create %dth thread fail!\n", i); - return ret; - } - } - RNG_TST_PRT("request queue fail2!\n"); - for (i = 0; i < thread_num - cnt; i++) { - h_cpuid = _get_cpu_id(i, hcore_mask); - if (h_cpuid > 0) - h_cpuid += 64; - - qidx = (i + cnt) / ctx_num_per_q; - test_thrds_data[i + cnt].q = &q[qidx]; - test_thrds_data[i + cnt].thread_num = thread_num; - test_thrds_data[i + cnt].cpu_id = h_cpuid; - ret = pthread_create(&system_test_thrds[i + cnt], NULL, - _trng_sys_test_thread, &test_thrds_data[i + cnt]); - if (ret) { - RNG_TST_PRT("Create %dth thread fail!\n", i); - return ret; - } - } - RNG_TST_PRT("request queue fail3!\n"); - for (i = 0; i < thread_num; i++) { - ret = pthread_join(system_test_thrds[i], NULL); - if (ret) { - RNG_TST_PRT("Join %dth thread fail!\n", i); - return ret; - } - } - free(q); - return 0; -} - - -static void _trng_cb(const void *message, void *tag) -{ - const struct wcrypto_rng_msg *msg = message; - struct trng_user_tag_info* pSwData = (struct trng_user_tag_info*)tag; - struct wcrypto_rng_op_data opdata; - int pid, threadId; - - if (NULL == pSwData) { - RNG_TST_PRT("pSwData NULL!\n"); - return; - } - memset(&opdata, 0, sizeof(opdata)); - - opdata.out = (void *)msg->out; - opdata.out_bytes = msg->out_bytes; - pid = pSwData->pid; - threadId = pSwData->thread_id; - RNG_TST_PRT("Proc-%d, %d-TD trng\n", pid, threadId); - RNG_TST_PRT("the random number size :%d\n", opdata.out_bytes); - - if (opdata.out) - free(opdata.out); - - if (pSwData) - free(pSwData); -} - -static void *_trng_asys_test_thread(void *data) -{ - int ret, cpuid; - struct test_trng_pthread_dt *pdata = data; - struct wd_queue *q = NULL; - cpu_set_t mask; - struct wcrypto_rng_ctx_setup setup; - struct wcrypto_rng_ctx *ctx = NULL; - struct trng_user_tag_info *tag = NULL; - struct wcrypto_rng_op_data opdata; - int pid = getpid(); - int thread_id = (int)syscall(__NR_gettid); - int *out_data; - int i = 0; - - CPU_ZERO(&mask); - cpuid = pdata->cpu_id; - q = (struct wd_queue *)pdata->q; - CPU_SET(cpuid, &mask); - - if (!q) { - RNG_TST_PRT("q null!\n"); - return NULL; - } - if (cpuid) { - ret = pthread_setaffinity_np(pthread_self(), - sizeof(mask), &mask); - if (ret < 0) { - RNG_TST_PRT("Proc-%d, thrd-%d:set affinity fail!\n", - pid, thread_id); - return NULL; - } - RNG_TST_PRT("Proc-%d, thrd-%d bind to cpu-%d!\n", - pid, thread_id, cpuid); - } - - q->capa.alg = "trng"; - memset(&setup, 0, sizeof(setup)); - memset(&opdata, 0, sizeof(opdata)); - setup.cb = _trng_cb; - ctx = wcrypto_create_rng_ctx(q, &setup); - if (!ctx) { - RNG_TST_PRT("Proc-%d, %d-TD:create %s ctx fail!\n", - pid, thread_id, q->capa.alg); - goto fail_release; - } - - while(1) { - tag = malloc(sizeof(struct trng_user_tag_info)); - if (!tag) { - RNG_TST_PRT("malloc tag fail!\n"); - goto fail_release; - } - - tag->pid = pid; - tag->thread_id = thread_id; - - out_data = malloc(g_input); - if(!out_data) { - RNG_TST_PRT("malloc fail\n"); - return 0; - } - - opdata.in_bytes = g_input; - opdata.out = out_data; - try_again: - ret = wcrypto_do_rng(ctx, &opdata, tag); - if (ret == -WD_EBUSY) { - usleep(100); - goto try_again; - } else if(ret) { - RNG_TST_PRT("Proc-%d, T-%d:trng %d fail!\n", pid, thread_id, i); - goto fail_release; - } - i++; - } -fail_release: - wcrypto_del_rng_ctx(ctx); - return NULL; -} - -static void* _trng_async_poll_test_thread(void *data) -{ - struct test_trng_pthread_dt *pdata = data; - struct wd_queue *q = pdata->q; - int ret, cpuid; - int pid = getpid(); - cpu_set_t mask; - int thread_id = (int)syscall(__NR_gettid); - - CPU_ZERO(&mask); - cpuid = pdata->cpu_id; - CPU_SET(cpuid, &mask); - if (cpuid) { - ret = pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask); - if (ret < 0) { - RNG_TST_PRT("Proc-%d, thrd-%d:set affinity fail!\n", - pid, thread_id); - return NULL; - } - RNG_TST_PRT("Proc-%d, poll thrd-%d bind to cpu-%d!\n", - pid, thread_id, cpuid); - } - - while (1) { - ret = wcrypto_rng_poll(q, 1); - if (ret < 0) { - break; - } - } - - return NULL; -} - -static int trng_asys_test(int thread_num, __u64 lcore_mask, __u64 hcore_mask) -{ - int i, ret, cnt = 0; - struct wd_queue q; - int h_cpuid; - - memset(&q, 0, sizeof(q)); - - q.capa.alg = "trng"; - ret = wd_request_queue(&q); - if (ret) { - RNG_TST_PRT("request queue fail!\n"); - return ret; - } - - if (_get_one_bits(lcore_mask) > 0) - cnt = _get_one_bits(lcore_mask); - else if (_get_one_bits(lcore_mask) == 0 && - _get_one_bits(hcore_mask) == 0) - cnt = thread_num; - - test_thrds_data[0].q= &q; - test_thrds_data[0].thread_num = 1; - test_thrds_data[0].cpu_id = _get_cpu_id(0, lcore_mask); - ret = pthread_create(&system_test_thrds[0], NULL, - _trng_async_poll_test_thread, &test_thrds_data[0]); - if (ret) { - RNG_TST_PRT("Create poll thread fail!\n"); - return ret; - } - - for (i = 1; i <= cnt; i++) { - test_thrds_data[i].q = &q; - test_thrds_data[i].thread_num = thread_num; - test_thrds_data[i].cpu_id = _get_cpu_id(i, lcore_mask); - ret = pthread_create(&system_test_thrds[i], NULL, - _trng_asys_test_thread, &test_thrds_data[i]); - if (ret) { - RNG_TST_PRT("Create %dth thread fail!\n", i); - return ret; - } - } - - for (i = 1; i <= thread_num - cnt; i++) { - h_cpuid = _get_cpu_id(i, hcore_mask); - if (h_cpuid > 0) - h_cpuid += 64; - test_thrds_data[i + cnt].q = &q; - test_thrds_data[i + cnt].thread_num = thread_num; - test_thrds_data[i + cnt].cpu_id = h_cpuid; - ret = pthread_create(&system_test_thrds[i + cnt], NULL, - _trng_asys_test_thread, &test_thrds_data[i + cnt]); - if (ret) { - RNG_TST_PRT("Create %dth thread fail!\n", i); - return ret; - } - } - - for (i = 0; i < thread_num; i++) { - ret = pthread_join(system_test_thrds[i], NULL); - if (ret) { - RNG_TST_PRT("Join %dth thread fail!\n", i); - return ret; - } - } - - wd_release_queue(&q); - return 0; - -} -int main(int argc, char *argv[]) -{ - struct wcrypto_rng_ctx *ctx; - struct wcrypto_rng_op_data opdata; - struct wcrypto_rng_ctx_setup setup; - enum alg_op_type alg_op_type = TRNG_GEN; - int thread_num, bits; - __u64 core_mask[2]; - struct wd_queue q; - void *tag = NULL; - int *data; - int ret; - int fd = -1; - int fd_w = -1; - if (!argv[1]) { - RNG_TST_PRT("pls printf the size of the random data!\n"); - return -WD_EINVAL; - } - g_input = (unsigned int)strtoul(argv[1], NULL, 10); - printf("g_input:%d\n",g_input); - //if (g_input <= 0){ - // printf("input error!\n"); - // return -WD_EINVAL; - //} - if (argv[2]) { - if(!strcmp(argv[2], "-system-gen")) { - alg_op_type = TRNG_GEN; - RNG_TST_PRT("Now doing system random number gen test!\n"); - } else if(!strcmp(argv[2], "-system-agen")) { - alg_op_type = TRNG_AGEN; - RNG_TST_PRT("Now doing system random number agen test!\n"); - } - - thread_num = strtoul((char *)argv[3], NULL, 10); - if (thread_num <= 0 || thread_num > TEST_MAX_THRD) { - RNG_TST_PRT("Invalid threads num:%d!\n", - thread_num); - RNG_TST_PRT("Now set threads num as 2\n"); - thread_num = 2; - } - - if (strcmp(argv[4], "-c")) { - RNG_TST_PRT("./test_hisi_trng --help get details\n"); - return -EINVAL; - } - if (argv[5][0] != '0' || argv[5][1] != 'x') { - RNG_TST_PRT("Err:coremask should be hex!\n"); - return -EINVAL; - } - - if (strlen(argv[5]) > 34) { - RNG_TST_PRT("Warning: coremask is cut!\n"); - argv[5][34] = 0; - } - - if (strlen(argv[5]) <= 18) { - core_mask[0] = strtoull(argv[5], NULL, 16); - if (core_mask[0] & 0x1) { - RNG_TST_PRT("Warn:cannot bind to core 0,\n"); - RNG_TST_PRT("now run without binding\n"); - core_mask[0] = 0x0; /* no binding */ - } - core_mask[1] = 0; - } else { - int offset = 0; - char *temp; - - offset = strlen(argv[5]) - 16; - core_mask[0] = strtoull(&argv[5][offset], NULL, 16); - if (core_mask[0] & 0x1) { - RNG_TST_PRT("Warn:cannot bind to core 0,\n"); - RNG_TST_PRT("now run without binding\n"); - core_mask[0] = 0x0; /* no binding */ - } - temp = malloc(64); - strcpy(temp, argv[5]); - temp[offset] = 0; - core_mask[1] = strtoull(temp, NULL, 16); - free(temp); - } - - bits = _get_one_bits(core_mask[0]); - bits += _get_one_bits(core_mask[1]); - if (thread_num > bits) { - RNG_TST_PRT("Coremask not covers all thrds,\n"); - RNG_TST_PRT("Bind first %d thrds!\n", bits); - } else if (thread_num < bits) { - RNG_TST_PRT("Coremask overflow,\n"); - RNG_TST_PRT("Just try to bind all thrds!\n"); - } - - if (argv[6]) { - ctx_num_per_q = strtoul(argv[6], NULL, 10); - if (ctx_num_per_q <= 0) { - RNG_TST_PRT("Invalid ctx num per queue:%s!\n", - argv[6]); - RNG_TST_PRT("Now ctx num per queue is set as 1!\n"); - ctx_num_per_q = 1; - } - } else { - RNG_TST_PRT("Now ctx num per queue is set as 1!\n"); - ctx_num_per_q = 1; - } - - q_num = (thread_num - 1) / ctx_num_per_q + 1; - - RNG_TST_PRT("Proc-%d: starts %d threads bind to %s\n", - getpid(), thread_num, argv[5]); - RNG_TST_PRT(" lcoremask=0x%llx, hcoremask=0x%llx\n", - core_mask[0], core_mask[1]); - if(alg_op_type == TRNG_GEN) - return trng_sys_test(thread_num, core_mask[0], - core_mask[1]); - - return trng_asys_test(thread_num, core_mask[0], - core_mask[1]); - } - - RNG_TST_PRT("Now try to get %d bytes random number.\n", g_input); - - data = malloc(g_input); - if (!data) { - RNG_TST_PRT("malloc data failed.\n"); - return -1; - } - - memset((void *)&q, 0, sizeof(q)); - memset(&setup, 0, sizeof(setup)); - memset(&opdata, 0, sizeof(opdata)); - - q.capa.alg = "trng"; - ret = wd_request_queue(&q); - if (ret) { - RNG_TST_PRT("request queue fail!\n"); - return ret; - } - ctx = wcrypto_create_rng_ctx(&q, &setup); - if (!ctx) { - ret = -ENOMEM; - RNG_TST_PRT("create trng ctx fail!\n"); - goto release_q; - } - - opdata.in_bytes = g_input; - opdata.out = data; - ret = wcrypto_do_rng(ctx, &opdata, tag); - if (ret != 1) { - RNG_TST_PRT("a wd_do_trng fail!\n"); - goto del_ctx; - } - - RNG_TST_PRT("random_data size= %d.\n", opdata.out_bytes); - fd_w = open ("/root/trng_file", O_RDWR|O_CREAT|O_TRUNC,0777); - if (fd_w <0 ) { - printf("can not open trng_file\n"); - return fd_w; - } - /*fd = open ("/dev/random", O_RDONLY); - if (fd <0 ) { - printf("can not open\n"); - return fd; - }*/ - /*ret = read(fd, data, g_input); - if (ret < 0) { - printf("read error %d\n", ret); - return ret; - }*/ - ret = write(fd_w,opdata.out,opdata.out_bytes); - if (ret < 0) { - printf("write error %d\n", ret); - return ret; - } - close(fd); - close(fd_w); -del_ctx: - wcrypto_del_rng_ctx(ctx); - -release_q: - wd_release_queue(&q); - free(data); - return ret; -} diff --git a/v1/wd.h b/v1/wd.h index 4618a8cb..90e2321a 100644 --- a/v1/wd.h +++ b/v1/wd.h @@ -181,7 +181,7 @@ struct wd_capa { * Other capabilities. * 0~15 bits: number of cookies that the user wants to allocate. * Optional, user can set value based on the number of requests and system memory, - * 1~1024 is valid. If the value is not set or invalid, the default value 64 (rng is 256) + * 1~1024 is valid. If the value is not set or invalid, the default value 64 * is used to initialize cookies. */ __u32 flags; diff --git a/v1/wd_adapter.c b/v1/wd_adapter.c index 07fe6591..f9d5f041 100644 --- a/v1/wd_adapter.c +++ b/v1/wd_adapter.c @@ -20,7 +20,6 @@ #include "v1/wd_util.h" #include "v1/drv/hisi_qm_udrv.h" -#include "v1/drv/hisi_rng_udrv.h" #include "v1/wd_adapter.h" #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) @@ -86,12 +85,6 @@ static const struct wd_drv_dio_if hw_dio_tbl[] = { { .init_sgl = qm_init_hwsgl_mem, .uninit_sgl = qm_uninit_hwsgl_mem, .sgl_merge = qm_merge_hwsgl, - }, { - .hw_type = "hisi-trng-v2", - .open = rng_init_queue, - .close = rng_uninit_queue, - .send = rng_send, - .recv = rng_recv, }, }; diff --git a/v1/wd_rng.c b/v1/wd_rng.c deleted file mode 100644 index 7a89cd15..00000000 --- a/v1/wd_rng.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright 2019 Huawei Technologies Co.,Ltd.All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/mman.h> - -#include "wd.h" -#include "wd_util.h" -#include "wd_rng.h" - -#define RNG_RESEND_CNT 8 -#define RNG_RECV_CNT 8 -#define WD_RNG_CTX_COOKIE_NUM 256 - -struct wcrypto_rng_cookie { - struct wcrypto_cb_tag tag; - struct wcrypto_rng_msg msg; -}; - -struct wcrypto_rng_ctx { - struct wd_cookie_pool pool; - unsigned long ctx_id; - struct wd_queue *q; - struct wcrypto_rng_ctx_setup setup; -}; - -static int wcrypto_setup_qinfo(struct wcrypto_rng_ctx_setup *setup, - struct wd_queue *q, __u32 *ctx_id) -{ - struct q_info *qinfo; - int ret = -WD_EINVAL; - - if (!q || !q->qinfo || !setup) { - WD_ERR("input parameter err!\n"); - return ret; - } - - if (strcmp(q->capa.alg, "trng")) { - WD_ERR("algorithm mismatch!\n"); - return ret; - } - qinfo = q->qinfo; - /* lock at ctx creating */ - wd_spinlock(&qinfo->qlock); - if (qinfo->ctx_num >= WD_MAX_CTX_NUM) { - WD_ERR("create too many trng ctx!\n"); - goto unlock; - } - - ret = wd_alloc_id(qinfo->ctx_id, WD_MAX_CTX_NUM, ctx_id, 0, - WD_MAX_CTX_NUM); - if (ret) { - WD_ERR("err: alloc ctx id fail!\n"); - goto unlock; - } - qinfo->ctx_num++; - ret = WD_SUCCESS; -unlock: - wd_unspinlock(&qinfo->qlock); - return ret; -} - -void *wcrypto_create_rng_ctx(struct wd_queue *q, - struct wcrypto_rng_ctx_setup *setup) -{ - struct wcrypto_rng_cookie *cookie; - struct wcrypto_rng_ctx *ctx; - struct q_info *qinfo; - __u32 cookies_num, i; - __u32 ctx_id = 0; - int ret; - - if (wcrypto_setup_qinfo(setup, q, &ctx_id)) - return NULL; - - ctx = calloc(1, sizeof(struct wcrypto_rng_ctx)); - if (!ctx) { - WD_ERR("alloc ctx memory fail!\n"); - goto free_ctx_id; - } - memcpy(&ctx->setup, setup, sizeof(*setup)); - ctx->q = q; - ctx->ctx_id = ctx_id + 1; - - cookies_num = wd_get_ctx_cookies_num(q->capa.flags, WD_RNG_CTX_COOKIE_NUM); - ret = wd_init_cookie_pool(&ctx->pool, - sizeof(struct wcrypto_rng_cookie), cookies_num); - if (ret) { - WD_ERR("fail to init cookie pool!\n"); - free(ctx); - goto free_ctx_id; - } - for (i = 0; i < cookies_num; i++) { - cookie = (void *)((uintptr_t)ctx->pool.cookies + - i * ctx->pool.cookies_size); - cookie->msg.alg_type = WCRYPTO_RNG; - cookie->tag.ctx = ctx; - cookie->tag.ctx_id = ctx->ctx_id; - cookie->msg.usr_tag = (uintptr_t)&cookie->tag; - } - - return ctx; - -free_ctx_id: - qinfo = q->qinfo; - wd_spinlock(&qinfo->qlock); - qinfo->ctx_num--; - wd_free_id(qinfo->ctx_id, WD_MAX_CTX_NUM, ctx_id, WD_MAX_CTX_NUM); - wd_unspinlock(&qinfo->qlock); - - return NULL; -} - -void wcrypto_del_rng_ctx(void *ctx) -{ - struct wcrypto_rng_ctx *cx; - struct q_info *qinfo; - - if (!ctx) { - WD_ERR("delete trng ctx is NULL!\n"); - return; - } - - cx = ctx; - qinfo = cx->q->qinfo; - - wd_uninit_cookie_pool(&cx->pool); - wd_spinlock(&qinfo->qlock); - if (qinfo->ctx_num <= 0) { - wd_unspinlock(&qinfo->qlock); - WD_ERR("repeat delete trng ctx!\n"); - return; - } - qinfo->ctx_num--; - wd_free_id(qinfo->ctx_id, WD_MAX_CTX_NUM, cx->ctx_id - 1, - WD_MAX_CTX_NUM); - wd_unspinlock(&qinfo->qlock); - - free(ctx); -} - -int wcrypto_rng_poll(struct wd_queue *q, unsigned int num) -{ - struct wcrypto_rng_msg *resp = NULL; - struct wcrypto_rng_ctx *ctx; - struct wcrypto_cb_tag *tag; - unsigned int tmp = num; - int count = 0; - int ret; - - if (!q) { - WD_ERR("%s(): input parameter err!\n", __func__); - return -WD_EINVAL; - } - - do { - ret = wd_recv(q, (void **)&resp); - if (!ret) - break; - - if (ret < 0) { - WD_ERR("recv err at trng poll!\n"); - return ret; - } - - count++; - tag = (void *)(uintptr_t)resp->usr_tag; - ctx = tag->ctx; - ctx->setup.cb(resp, tag->tag); - wd_put_cookies(&ctx->pool, (void **)&tag, 1); - resp = NULL; - } while (--tmp); - - return count; -} - -static int wcrypto_do_prepare(struct wcrypto_rng_cookie **cookie_addr, - struct wcrypto_rng_op_data *opdata, - struct wcrypto_rng_msg **req_addr, - struct wcrypto_rng_ctx *ctxt, - void *tag) -{ - struct wcrypto_rng_cookie *cookie; - struct wcrypto_rng_msg *req; - int ret; - - if (unlikely(!ctxt || !opdata)) { - WD_ERR("invalid: rng input parameter err!\n"); - return -WD_EINVAL; - } - - if (unlikely((opdata->in_bytes && !opdata->out))) { - WD_ERR("invalid: dst addr is NULL when in_bytes is non-zero!!\n"); - return -WD_EINVAL; - } - - ret = wd_get_cookies(&ctxt->pool, (void **)&cookie, 1); - if (ret) - return ret; - - if (tag) { - if (!ctxt->setup.cb) { - WD_ERR("invalid: ctx call back is null!\n"); - wd_put_cookies(&ctxt->pool, (void **)&cookie, 1); - return -WD_EINVAL; - } - cookie->tag.tag = tag; - } - - req = &cookie->msg; - req->in_bytes = opdata->in_bytes; - req->out = opdata->out; - *cookie_addr = cookie; - *req_addr = req; - - return 0; -} - -int wcrypto_do_rng(void *ctx, struct wcrypto_rng_op_data *opdata, void *tag) -{ - struct wcrypto_rng_ctx *ctxt = ctx; - struct wcrypto_rng_cookie *cookie; - struct wcrypto_rng_msg *req; - struct wcrypto_rng_msg *resp; - uint32_t tx_cnt = 0; - uint32_t rx_cnt = 0; - int ret = 0; - - ret = wcrypto_do_prepare(&cookie, opdata, &req, ctxt, tag); - if (ret) - return ret; - - do { - ret = wd_send(ctxt->q, req); - if (!ret) { - break; - } else if (ret == -WD_EBUSY) { - if (++tx_cnt > RNG_RESEND_CNT) { - WD_ERR("do trng send cnt %u, exit!\n", tx_cnt); - goto fail_with_cookie; - } - - usleep(1); - } else { - WD_ERR("do rng wd_send err!\n"); - goto fail_with_cookie; - } - } while (true); - - if (tag) - return ret; - - resp = (void *)(uintptr_t)ctxt->ctx_id; - - do { - ret = wd_recv(ctxt->q, (void **)&resp); - if (ret > 0) { - break; - } else if (!ret) { - if (++rx_cnt > RNG_RECV_CNT) { - WD_ERR("do trng recv cnt %u, exit!\n", rx_cnt); - ret = -WD_ETIMEDOUT; - goto fail_with_cookie; - } - - usleep(1); - } else { - WD_ERR("do trng recv err!\n"); - goto fail_with_cookie; - } - } while (true); - - opdata->out_bytes = resp->out_bytes; - ret = WD_SUCCESS; -fail_with_cookie: - wd_put_cookies(&ctxt->pool, (void **)&cookie, 1); - return ret; -} diff --git a/v1/wd_rng.h b/v1/wd_rng.h deleted file mode 100644 index fcde26d7..00000000 --- a/v1/wd_rng.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2019 Huawei Technologies Co.,Ltd.All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __WD_RNG_H -#define __WD_RNG_H - -#include "wd.h" -#include "wd_digest.h" -#include "wd_cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct wcrypto_rng_ctx_setup { - wcrypto_cb cb; - __u16 data_fmt; /* Data format, denoted by enum wd_buff_type */ - enum wcrypto_type type; /* Please refer to the definition of enum */ - enum wcrypto_cipher_alg calg; /* DRBG cipher algorithm */ - enum wcrypto_cipher_mode cmode; /* DRBG cipher mode */ - enum wcrypto_digest_alg dalg; /* DRBG digest algorithm */ - enum wcrypto_digest_mode dmode; /* DRBG digest mode */ -}; - -struct wcrypto_rng_msg { - __u8 alg_type; /* Denoted by enum wcrypto_type */ - __u8 op_type; /* Denoted by enum wcrypto_rng_op_type */ - __u8 data_fmt; /* Data format, denoted by enum wd_buff_type */ - __u8 result; /* Data format, denoted by WD error code */ - __u8 *out; /* Result address */ - __u8 *in; /* Input address */ - __u32 out_bytes; /* output bytes */ - __u32 in_bytes; /* input bytes */ - __u64 usr_tag; /* user identifier */ -}; - -enum wcrypto_rng_op_type { - WCRYPTO_RNG_INVALID, /* Invalid RNG operational type */ - WCRYPTO_DRBG_RESEED, /* seed operation */ - WCRYPTO_DRBG_GEN, /* deterministic random number generation */ - WCRYPTO_TRNG_GEN, /* true random number generation */ -}; - -struct wcrypto_rng_op_data { - enum wcrypto_rng_op_type op_type; - __u32 status; /* Operation result status */ - void *in; /* input */ - void *out; /* output */ - __u32 in_bytes; /* input bytes */ - __u32 out_bytes; /* output bytes */ -}; - -void *wcrypto_create_rng_ctx(struct wd_queue *q, - struct wcrypto_rng_ctx_setup *setup); -void wcrypto_del_rng_ctx(void *ctx); -int wcrypto_do_rng(void *ctx, struct wcrypto_rng_op_data *opdata, void *tag); -int wcrypto_rng_poll(struct wd_queue *q, unsigned int num); - -#ifdef __cplusplus -} -#endif - -#endif -- 2.33.0

From: lizhi <lizhi206@huawei.com> Upstream: Yes Bugfix or Feature: Bugfix DTS: DTS2024111417327 1. Support ecdh with secp256r1 curve. 2. The algorithm will be scheduled first for high-performance cores. 3. The result of configuration does not affect the task success or failure. Signed-off-by: lizhi <lizhi206@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_hpre.c | 90 +++++++++++++++++++++++++++++++++++++++- include/drv/wd_ecc_drv.h | 9 ++++ include/wd_ecc_curve.h | 27 ++++++++++++ wd_ecc.c | 60 +++++++++++++++++++++++++-- 4 files changed, 182 insertions(+), 4 deletions(-) diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index 7c652d10..a18d358f 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -10,6 +10,7 @@ #include <sys/mman.h> #include <sys/types.h> #include "hisi_qm_udrv.h" +#include "../include/wd_ecc_curve.h" #include "../include/drv/wd_rsa_drv.h" #include "../include/drv/wd_dh_drv.h" #include "../include/drv/wd_ecc_drv.h" @@ -42,6 +43,10 @@ #define WD_TRANS_FAIL 0 +#define CURVE_PARAM_NUM 6 +#define SECP256R1_KEY_SIZE 32 +#define SECP256R1_PARAM_SIZE (CURVE_PARAM_NUM * SECP256R1_KEY_SIZE) + enum hpre_alg_type { HPRE_ALG_NC_NCRT = 0x0, HPRE_ALG_NC_CRT = 0x1, @@ -110,6 +115,10 @@ struct hisi_hpre_ctx { struct wd_ctx_config_internal config; }; +struct hpre_ecc_ctx { + __u32 enable_hpcore; +}; + static void dump_hpre_msg(void *msg, int alg) { struct wd_rsa_msg *rsa_msg; @@ -1358,6 +1367,7 @@ static int u_is_in_p(struct wd_ecc_msg *msg) static int ecc_prepare_in(struct wd_ecc_msg *msg, struct hisi_hpre_sqe *hw_msg, void **data) { + struct hpre_ecc_ctx *ecc_ctx = msg->drv_cfg; int ret = -WD_EINVAL; switch (msg->req.op_type) { @@ -1366,11 +1376,15 @@ static int ecc_prepare_in(struct wd_ecc_msg *msg, /* driver to identify sm2 algorithm when async receive */ hw_msg->sm2_mlen = msg->req.op_type; hw_msg->bd_rsv2 = 1; /* fall through */ - case WD_SM2_KG: /* fall through */ + case WD_SM2_KG: + ret = ecc_prepare_dh_gen_in(msg, hw_msg, data); + break; case WD_ECXDH_GEN_KEY: + hw_msg->bd_rsv2 = ecc_ctx->enable_hpcore; ret = ecc_prepare_dh_gen_in(msg, hw_msg, data); break; case WD_ECXDH_COMPUTE_KEY: + hw_msg->bd_rsv2 = ecc_ctx->enable_hpcore; ret = ecc_prepare_dh_compute_in(msg, hw_msg, data); if (!ret && (msg->curve_id == WD_X25519 || msg->curve_id == WD_X448)) @@ -2491,6 +2505,79 @@ static int hpre_get_usage(void *param) return WD_SUCCESS; } +static int ecc_sess_eops_init(void **params) +{ + struct hpre_ecc_ctx *ecc_ctx; + + if (!params) { + WD_ERR("invalid: extend ops init params address is NULL!\n"); + return -WD_EINVAL; + } + + if (*params) { + WD_ERR("invalid: extend ops init params repeatedly!\n"); + return -WD_EINVAL; + } + + ecc_ctx = calloc(1, sizeof(struct hpre_ecc_ctx)); + if (!ecc_ctx) + return -WD_ENOMEM; + + *params = ecc_ctx; + + return WD_SUCCESS; +} + +static void ecc_sess_eops_uninit(void *params) +{ + if (!params) { + WD_ERR("invalid: extend ops uninit params is NULL!\n"); + return; + } + + free(params); + params = NULL; +} + +static void ecc_sess_eops_params_cfg(struct wd_ecc_sess_setup *setup, + struct wd_ecc_curve *cv, void *params) +{ + __u8 data[SECP256R1_PARAM_SIZE] = SECG_P256_R1_PARAM; + struct hpre_ecc_ctx *ecc_ctx = params; + __u32 key_size; + int ret = 0; + + if (!ecc_ctx) { + WD_INFO("Info: eops config exits, but params is NULL!\n"); + return; + } + + if (strcmp(setup->alg, "ecdh")) + return; + + key_size = BITS_TO_BYTES(setup->key_bits); + if (key_size != SECP256R1_KEY_SIZE) + return; + + ret = memcmp(data, cv->p.data, SECP256R1_PARAM_SIZE); + if (!ret) + ecc_ctx->enable_hpcore = 1; +} + +static int hpre_ecc_get_extend_ops(void *ops) +{ + struct wd_ecc_extend_ops *ecc_ops = ops; + + if (!ecc_ops) + return -WD_EINVAL; + + ecc_ops->params = NULL; + ecc_ops->sess_init = ecc_sess_eops_init; + ecc_ops->eops_params_cfg = ecc_sess_eops_params_cfg; + ecc_ops->sess_uninit = ecc_sess_eops_uninit; + return WD_SUCCESS; +} + #define GEN_HPRE_ALG_DRIVER(hpre_alg_name) \ {\ .drv_name = "hisi_hpre",\ @@ -2505,6 +2592,7 @@ static int hpre_get_usage(void *param) .send = ecc_send,\ .recv = ecc_recv,\ .get_usage = hpre_get_usage,\ + .get_extend_ops = hpre_ecc_get_extend_ops,\ } static struct wd_alg_driver hpre_ecc_driver[] = { diff --git a/include/drv/wd_ecc_drv.h b/include/drv/wd_ecc_drv.h index f5805cdc..37908cd2 100644 --- a/include/drv/wd_ecc_drv.h +++ b/include/drv/wd_ecc_drv.h @@ -54,6 +54,7 @@ struct wd_ecc_msg { __u16 key_bytes; /* key bytes */ __u8 curve_id; /* Ec curve denoted by enum wd_ecc_curve_type */ __u8 result; /* alg op error code */ + void *drv_cfg; /* internal driver configuration */ }; struct wd_ecc_pubkey { @@ -175,6 +176,14 @@ struct wd_ecc_out { char data[]; }; +struct wd_ecc_extend_ops { + void *params; /* the params are passed to the following ops */ + int (*eops_params_cfg)(struct wd_ecc_sess_setup *setup, + struct wd_ecc_curve *cv, void *params); + int (*sess_init)(void **params); + void (*sess_uninit)(void *params); +}; + struct wd_ecc_msg *wd_ecc_get_msg(__u32 idx, __u32 tag); #ifdef __cplusplus diff --git a/include/wd_ecc_curve.h b/include/wd_ecc_curve.h index 20b017a8..1f83edcd 100644 --- a/include/wd_ecc_curve.h +++ b/include/wd_ecc_curve.h @@ -175,6 +175,33 @@ extern "C" { 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41\ } +#define SECG_P256_R1_PARAM {\ + /* p */\ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,\ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\ + /* a */\ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,\ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,\ + /* b */\ + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,\ + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,\ + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,\ + /* x */\ + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,\ + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,\ + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,\ + /* y */\ + 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A,\ + 0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,\ + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5,\ + /* order */\ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,\ + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,\ + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51,\ +} + #define BRAINPOOL_P320_R1_PARAM {\ /* p */\ 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E,\ diff --git a/wd_ecc.c b/wd_ecc.c index 4e6a9c57..7ae5f757 100644 --- a/wd_ecc.c +++ b/wd_ecc.c @@ -28,6 +28,7 @@ #define SM2_KEY_SIZE 32 #define GET_NEGATIVE(val) (0 - (val)) #define ZA_PARAM_NUM 6 +#define WD_SECP256R1 0x18 /* consistent with enum wd_ecc_curve_id */ static __thread __u64 balance; @@ -49,6 +50,7 @@ struct wd_ecc_sess { __u32 key_size; struct wd_ecc_key key; struct wd_ecc_sess_setup setup; + struct wd_ecc_extend_ops eops; void *sched_key; }; @@ -84,7 +86,8 @@ static const struct wd_ecc_curve_list curve_list[] = { { WD_BRAINPOOLP384R1, "bpP384r1", 384, BRAINPOOL_P384_R1_PARAM }, { WD_SECP384R1, "secp384r1", 384, SECG_P384_R1_PARAM }, { WD_SECP521R1, "secp521r1", 521, SECG_P521_R1_PARAM }, - { WD_SM2P256, "sm2", 256, SM2_P256_V1_PARAM } + { WD_SM2P256, "sm2", 256, SM2_P256_V1_PARAM }, + { WD_SECP256R1, "secp256r1", 256, SECG_P256_R1_PARAM }, }; static const struct curve_param_desc curve_pram_list[] = { @@ -1166,6 +1169,39 @@ static void del_sess_key(struct wd_ecc_sess *sess) } } +static int wd_ecc_sess_eops_init(struct wd_ecc_sess *sess) +{ + int ret; + + if (sess->eops.sess_init) { + if (!sess->eops.sess_uninit) { + WD_ERR("failed to get extend ops in session!\n"); + return -WD_EINVAL; + } + ret = sess->eops.sess_init(&sess->eops.params); + if (ret) { + WD_ERR("failed to init extend ops params in session!\n"); + return ret; + } + } + return WD_SUCCESS; +} + +static void wd_ecc_sess_eops_uninit(struct wd_ecc_sess *sess) +{ + if (sess->eops.sess_uninit) + sess->eops.sess_uninit(sess->eops.params); +} + +static void wd_ecc_sess_eops_cfg(struct wd_ecc_sess_setup *setup, + struct wd_ecc_sess *sess) +{ + if (sess->eops.sess_init && sess->eops.eops_params_cfg) { + /* the config result does not impact task sucesss or failure */ + sess->eops.eops_params_cfg(setup, sess->key.cv, sess->eops.params); + } +} + handle_t wd_ecc_alloc_sess(struct wd_ecc_sess_setup *setup) { struct wd_ecc_sess *sess; @@ -1187,12 +1223,26 @@ handle_t wd_ecc_alloc_sess(struct wd_ecc_sess_setup *setup) memcpy(&sess->setup, setup, sizeof(*setup)); sess->key_size = BITS_TO_BYTES(setup->key_bits); - ret = create_sess_key(setup, sess); + ret = wd_ecc_setting.driver->get_extend_ops(&sess->eops); + if (ret) { + WD_ERR("failed to get ecc sess extend ops!\n"); + goto sess_err; + } + + ret = wd_ecc_sess_eops_init(sess); if (ret) { - WD_ERR("failed to creat ecc sess keys!\n"); + WD_ERR("failed to init ecc sess extend eops!\n"); goto sess_err; } + ret = create_sess_key(setup, sess); + if (ret) { + WD_ERR("failed to create ecc sess keys!\n"); + goto eops_err; + } + + wd_ecc_sess_eops_cfg(setup, sess); + /* Some simple scheduler don't need scheduling parameters */ sess->sched_key = (void *)wd_ecc_setting.sched.sched_init( wd_ecc_setting.sched.h_sched_ctx, setup->sched_param); @@ -1205,6 +1255,8 @@ handle_t wd_ecc_alloc_sess(struct wd_ecc_sess_setup *setup) sched_err: del_sess_key(sess); +eops_err: + wd_ecc_sess_eops_uninit(sess); sess_err: free(sess); return (handle_t)0; @@ -1222,6 +1274,7 @@ void wd_ecc_free_sess(handle_t sess) if (sess_t->sched_key) free(sess_t->sched_key); del_sess_key(sess_t); + wd_ecc_sess_eops_uninit(sess); free(sess_t); } @@ -1494,6 +1547,7 @@ static int fill_ecc_msg(struct wd_ecc_msg *msg, struct wd_ecc_req *req, memcpy(&msg->hash, &sess->setup.hash, sizeof(msg->hash)); msg->key_bytes = sess->key_size; msg->curve_id = sess->setup.cv.cfg.id; + msg->drv_cfg = sess->eops.params; msg->result = WD_EINVAL; switch (req->op_type) { -- 2.33.0

From: lizhi <lizhi206@huawei.com> Upstream: Yes Bugfix or Feature: Bugfix DTS: DTS2024111417327 1. Add ecdh benchmark with secp256r1 curve 2. To diff with original mode, the new mode is named ecdh-256r1, adding 'r1' as suffix. Signed-off-by: lizhi <lizhi206@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- uadk_tool/benchmark/hpre_uadk_benchmark.c | 35 +++++++++++++++++++---- uadk_tool/benchmark/uadk_benchmark.c | 3 +- uadk_tool/benchmark/uadk_benchmark.h | 1 + 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/uadk_tool/benchmark/hpre_uadk_benchmark.c b/uadk_tool/benchmark/hpre_uadk_benchmark.c index bc0687da..44d513da 100644 --- a/uadk_tool/benchmark/hpre_uadk_benchmark.c +++ b/uadk_tool/benchmark/hpre_uadk_benchmark.c @@ -11,10 +11,12 @@ #include "include/wd_ecc.h" #include "include/wd_sched.h" -#define ECC_CURVE_ID 0x3 /* def set secp256k1 */ +#define ECC_CURVE_SECP256K1 0x3 /* def set with secp256k1 */ +#define ECC_CURVE_SECP256R1 0x7 /* optional set with secp256r1 */ #define HPRE_TST_PRT printf #define ERR_OPTYPE 0xFF #define SM2_DG_SZ 1024 +#define WD_SECP256R1 0x18 /* consistent with wd_ecc.c */ struct hpre_rsa_key_in { void *e; @@ -92,6 +94,7 @@ typedef struct uadk_thread_res { u32 kmode; u32 optype; u32 td_id; + u32 algtype; } thread_data; static struct wd_ctx_config g_ctx_cfg; @@ -217,6 +220,9 @@ static void get_ecc_param(u32 algtype, u32 *keysize) case ECDH_256: *keysize = 256; break; + case ECDH_256R1: + *keysize = 256; + break; case ECDH_384: *keysize = 384; break; @@ -337,6 +343,7 @@ static int hpre_uadk_param_parse(thread_data *tddata, struct acc_option *options tddata->keybits = keysize; tddata->kmode = mode; tddata->optype = optype; + tddata->algtype = algtype; HPRE_TST_PRT("%s to run %s task!\n", options->algclass, alg_operations[options->optype]); @@ -1038,6 +1045,10 @@ static int get_ecc_curve(struct hpre_ecc_setup *setup, u32 cid) setup->nid = 716; setup->curve_id = WD_SECP521R1; break; + case 7: // secp256R1 + setup->nid = 415; + setup->curve_id = WD_SECP256R1; + break; default: HPRE_TST_PRT("failed to get ecc curve id!\n"); return -EINVAL; @@ -2253,7 +2264,7 @@ static void *ecc_uadk_sync_run(void *arg) struct wd_ecc_point pbk; struct wd_dtb prk; struct wd_ecc_req req; - u32 cid = ECC_CURVE_ID; + u32 cid; handle_t h_sess; u32 count = 0; int ret; @@ -2263,6 +2274,12 @@ static void *ecc_uadk_sync_run(void *arg) memset(&req, 0, sizeof(req)); memset(&setup, 0, sizeof(setup)); + + if (pdata->algtype == ECDH_256R1) + cid = ECC_CURVE_SECP256R1; + else + cid = ECC_CURVE_SECP256K1; + if (subtype != X448_TYPE && subtype != X25519_TYPE) { ret = get_ecc_curve(&setup, cid); if (ret) @@ -2271,7 +2288,7 @@ static void *ecc_uadk_sync_run(void *arg) sess_setup.key_bits = pdata->keybits; if (subtype == ECDH_TYPE || subtype == ECDSA_TYPE) { - if (cid > ECC_CURVE_ID) { + if (cid > ECC_CURVE_SECP256R1) { sess_setup.cv.type = WD_CV_CFG_PARAM; get_ecc_key_param(¶m, pdata->keybits); sess_setup.cv.cfg.pparam = ¶m; @@ -2411,7 +2428,7 @@ static void *ecc_uadk_async_run(void *arg) struct wd_ecc_point pbk; struct wd_ecc_req req; struct wd_dtb prk; - u32 cid = ECC_CURVE_ID; + u32 cid; handle_t h_sess; int try_cnt = 0; u32 count = 0; @@ -2422,6 +2439,12 @@ static void *ecc_uadk_async_run(void *arg) memset(&req, 0, sizeof(req)); memset(&setup, 0, sizeof(setup)); + + if (pdata->algtype == ECDH_256R1) + cid = ECC_CURVE_SECP256R1; + else + cid = ECC_CURVE_SECP256K1; + if (subtype != X448_TYPE && subtype != X25519_TYPE) { ret = get_ecc_curve(&setup, cid); if (ret) @@ -2430,7 +2453,7 @@ static void *ecc_uadk_async_run(void *arg) sess_setup.key_bits = pdata->keybits; if (subtype == ECDH_TYPE || subtype == ECDSA_TYPE) { - if (cid > ECC_CURVE_ID) { + if (cid > ECC_CURVE_SECP256R1) { sess_setup.cv.type = WD_CV_CFG_PARAM; get_ecc_key_param(¶m, pdata->keybits); sess_setup.cv.cfg.pparam = ¶m; @@ -2627,6 +2650,7 @@ static int hpre_uadk_sync_threads(struct acc_option *options) threads_args[i].keybits = threads_option.keybits; threads_args[i].optype = threads_option.optype; threads_args[i].td_id = i; + threads_args[i].algtype = threads_option.algtype; ret = pthread_create(&tdid[i], NULL, uadk_hpre_sync_run, &threads_args[i]); if (ret) { HPRE_TST_PRT("Create sync thread fail!\n"); @@ -2703,6 +2727,7 @@ static int hpre_uadk_async_threads(struct acc_option *options) threads_args[i].keybits = threads_option.keybits; threads_args[i].optype = threads_option.optype; threads_args[i].td_id = i; + threads_args[i].algtype = threads_option.algtype; ret = pthread_create(&tdid[i], NULL, uadk_hpre_async_run, &threads_args[i]); if (ret) { HPRE_TST_PRT("Create async thread fail!\n"); diff --git a/uadk_tool/benchmark/uadk_benchmark.c b/uadk_tool/benchmark/uadk_benchmark.c index e6cc2ddf..d8f9e7af 100644 --- a/uadk_tool/benchmark/uadk_benchmark.c +++ b/uadk_tool/benchmark/uadk_benchmark.c @@ -83,6 +83,7 @@ static struct acc_alg_item alg_options[] = { {"dh", "dh-3072", DH_3072}, {"dh", "dh-4096", DH_4096}, {"ecdh", "ecdh-256", ECDH_256}, + {"ecdh", "ecdh-256r1", ECDH_256R1}, {"ecdh", "ecdh-384", ECDH_384}, {"ecdh", "ecdh-521", ECDH_521}, {"ecdsa", "ecdsa-256", ECDSA_256}, @@ -632,7 +633,7 @@ void print_benchmark_help(void) ACC_TST_PRT(" specify numa nodes for cpu and memory\n"); ACC_TST_PRT("DESCRIPTION\n"); ACC_TST_PRT(" [--alg aes-128-cbc ]:\n"); - ACC_TST_PRT(" The name of the algorithm for benchmarking\n"); + ACC_TST_PRT(" The name of the algorithm for benchmarking, note that alg ecdh-256r1 means ecdh with secp256r1\n"); ACC_TST_PRT(" [--mode sva/nosva/soft/sva-soft/nosva-soft/instr/multibuff]: start UADK or Warpdrive or Openssl or Instruction mode test\n"); ACC_TST_PRT(" [--sync/--async]: start asynchronous/synchronous mode test\n"); ACC_TST_PRT(" [--opt 0,1,2,3,4,5]:\n"); diff --git a/uadk_tool/benchmark/uadk_benchmark.h b/uadk_tool/benchmark/uadk_benchmark.h index 39725724..81ab2cf3 100644 --- a/uadk_tool/benchmark/uadk_benchmark.h +++ b/uadk_tool/benchmark/uadk_benchmark.h @@ -135,6 +135,7 @@ enum test_alg { DH_3072, DH_4096, ECDH_256, // ecdh + ECDH_256R1, // ecdh with secp256r1 curve ECDH_384, ECDH_521, ECDSA_256, // ecdsa -- 2.33.0

1. Use 'intptr_t' or 'uintptr_t' to convert pointer into integer. 2. Forbidden exit function 'pthread_exit' is called. 3. Use 1 blank space(' ') instead of TAB('\t') between the right comment and the previous code. 4. Do not add blank lines on the start of a code block defined by braces. Signed-off-by: Qi Tao <taoqi10@huawei.com> --- include/uacce.h | 4 ++-- include/wd.h | 2 +- include/wd_digest.h | 6 +++--- wd_util.c | 2 -- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/include/uacce.h b/include/uacce.h index bb8d7402..f7fae272 100644 --- a/include/uacce.h +++ b/include/uacce.h @@ -31,8 +31,8 @@ enum { #define UACCE_API_VER_NOIOMMU_SUBFIX "_noiommu" enum uacce_qfrt { - UACCE_QFRT_MMIO = 0, /* device mmio region */ - UACCE_QFRT_DUS = 1, /* device user share */ + UACCE_QFRT_MMIO = 0, /* device mmio region */ + UACCE_QFRT_DUS = 1, /* device user share */ UACCE_QFRT_MAX, }; diff --git a/include/wd.h b/include/wd.h index 21e5e069..944c3e85 100644 --- a/include/wd.h +++ b/include/wd.h @@ -201,7 +201,7 @@ static inline void *WD_ERR_PTR(uintptr_t error) static inline long WD_PTR_ERR(const void *ptr) { - return (long)ptr; + return (intptr_t)ptr; } /** diff --git a/include/wd_digest.h b/include/wd_digest.h index f0916c36..6ce31f29 100644 --- a/include/wd_digest.h +++ b/include/wd_digest.h @@ -144,9 +144,9 @@ struct wd_digest_req { }; struct wd_cb_tag { - void *ctx; /* user: context or other user relatives */ - void *tag; /* to store user tag */ - int ctx_id; /* user id: context ID or other user identifier */ + void *ctx; /* user: context or other user relatives */ + void *tag; /* to store user tag */ + int ctx_id; /* user id: context ID or other user identifier */ }; /* Digest tag format */ diff --git a/wd_util.c b/wd_util.c index 93249a3f..2236b957 100644 --- a/wd_util.c +++ b/wd_util.c @@ -1480,7 +1480,6 @@ static void *async_poll_process_func(void *args) goto out; } out: - pthread_exit(NULL); return NULL; } @@ -1987,7 +1986,6 @@ err_alloc: void wd_alg_uninit_driver(struct wd_ctx_config_internal *config, struct wd_alg_driver *driver) { - driver->exit(driver); /* Ctx config just need clear once */ wd_clear_ctx_config(config); -- 2.33.0

From: Chenghai Huang <huangchenghai2@huawei.com> When wd_do_comp_strm returns error ret, status in req is not updated to that in strm_req. As a result, when the internal status of strm_req is WD_IN_EPARA, the req obtained by the user is not WD_IN_EPARA. Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_comp.c | 8 ++++---- wd_comp.c | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 71e859f5..1e55094b 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -340,7 +340,7 @@ static void fill_buf_sgl_skip(struct hisi_zip_sqe *sqe, __u32 src_skip, sqe->dw8 = val; } -static int fill_buf_deflate_slg_generic(handle_t h_qp, struct hisi_zip_sqe *sqe, +static int fill_buf_deflate_sgl_generic(handle_t h_qp, struct hisi_zip_sqe *sqe, struct wd_comp_msg *msg, const char *head, int head_size) { @@ -376,19 +376,19 @@ static int fill_buf_deflate_slg_generic(handle_t h_qp, struct hisi_zip_sqe *sqe, static int fill_buf_deflate_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe, struct wd_comp_msg *msg) { - return fill_buf_deflate_slg_generic(h_qp, sqe, msg, NULL, 0); + return fill_buf_deflate_sgl_generic(h_qp, sqe, msg, NULL, 0); } static int fill_buf_zlib_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe, struct wd_comp_msg *msg) { - return fill_buf_deflate_slg_generic(h_qp, sqe, msg, ZLIB_HEADER, ZLIB_HEADER_SZ); + return fill_buf_deflate_sgl_generic(h_qp, sqe, msg, ZLIB_HEADER, ZLIB_HEADER_SZ); } static int fill_buf_gzip_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe, struct wd_comp_msg *msg) { - return fill_buf_deflate_slg_generic(h_qp, sqe, msg, GZIP_HEADER, GZIP_HEADER_SZ); + return fill_buf_deflate_sgl_generic(h_qp, sqe, msg, GZIP_HEADER, GZIP_HEADER_SZ); } static void fill_buf_size_lz77_zstd(struct hisi_zip_sqe *sqe, __u32 in_size, diff --git a/wd_comp.c b/wd_comp.c index 4768642a..e7246740 100644 --- a/wd_comp.c +++ b/wd_comp.c @@ -688,6 +688,10 @@ int wd_do_comp_sync2(handle_t h_sess, struct wd_comp_req *req) ret = wd_do_comp_strm(h_sess, &strm_req); if (unlikely(ret < 0 || strm_req.status == WD_IN_EPARA)) { + req->status = strm_req.status; + if (!ret) + ret = -WD_EINVAL; + WD_ERR("wd comp, invalid or incomplete data! ret = %d, status = %u!\n", ret, strm_req.status); return ret; @@ -784,7 +788,7 @@ static void wd_do_comp_strm_end_check(struct wd_comp_sess *sess, int wd_do_comp_strm(handle_t h_sess, struct wd_comp_req *req) { struct wd_comp_sess *sess = (struct wd_comp_sess *)h_sess; - struct wd_comp_msg msg; + struct wd_comp_msg msg = {0}; __u32 src_len; int ret; -- 2.33.0

From: Chenghai Huang <huangchenghai2@huawei.com> Replace the user output buffer with the internal buffer when the size of the user-provided buffer is less than 200 bytes. It need to copy data in either of the following scenarios: 1.There is data in the internal buffer before hardware processing. 2.After the hardware uses the internal buffer to process. The following two situations may occur during each copy process: a.Data is completely copied and output. b.Part of the data is copied and output. 1 and 2 are combined with a and b to implement the code logic of check_store_buf and copy_from_hw. Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_comp.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 217 insertions(+), 6 deletions(-) diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 1e55094b..bfeb8fad 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -81,6 +81,13 @@ #define BUF_TYPE 2 +/* 200 * 1.125 + GZIP_HEADER_SZ, align with 4 byte */ +#define STORE_BUF_SIZE 236 +/* The hardware requires at least 200byte output buffers */ +#define SW_STOREBUF_TH 200 +/* The 38KB offset in ctx_buf is used as the internal buffer */ +#define CTX_STOREBUF_OFFSET 0x9800 + enum alg_type { HW_DEFLATE = 0x1, HW_ZLIB, @@ -110,6 +117,23 @@ enum lz77_compress_status { COMP_BLK, }; +struct hisi_comp_buf { + /* Denoted whether the output is copied from the storage buffer */ + bool skip_hw; + /* Denoted internal store buf */ + __u8 dst[STORE_BUF_SIZE]; + /* Denoted data size left in uadk */ + __u32 pending_out; + /* Size that have been copied */ + __u32 output_offset; + /* Input data consumption when all data copies are complete */ + __u32 fallback_size; + /* Store end flag return by HW */ + __u32 status; + /* Denoted internal store sgl */ + struct wd_datalist list_dst; +}; + struct hisi_zip_sqe { __u32 consumed; __u32 produced; @@ -214,6 +238,127 @@ static int buf_size_check_deflate(__u32 *in_size, __u32 *out_size) return 0; } +static __u32 copy_to_out(struct wd_comp_msg *msg, struct hisi_comp_buf *buf, __u32 total_len) +{ + struct wd_comp_req *req = &msg->req; + struct wd_datalist *node = req->list_dst; + __u32 sgl_restlen, copy_len; + __u32 len = 0, sgl_cplen = 0; + + copy_len = total_len > req->dst_len ? + req->dst_len : total_len; + sgl_restlen = copy_len; + + if (req->data_fmt == WD_FLAT_BUF) { + memcpy(req->dst, buf->dst + buf->output_offset, copy_len); + return copy_len; + } + + while (node != NULL && sgl_restlen > 0) { + len = node->len > sgl_restlen ? sgl_restlen : node->len; + memcpy(node->data, buf->list_dst.data + buf->output_offset + sgl_cplen, + len); + sgl_restlen -= len; + sgl_cplen += len; + node = node->next; + } + + return sgl_cplen; +} + +static int check_store_buf(struct wd_comp_msg *msg) +{ + struct wd_comp_req *req = &msg->req; + struct hisi_comp_buf *buf; + __u32 copy_len; + + if (!msg->ctx_buf) + return 0; + + buf = (struct hisi_comp_buf *)(msg->ctx_buf + CTX_STOREBUF_OFFSET); + if (!buf->pending_out) + return 0; + + if (!req->src_len && buf->fallback_size) { + WD_ERR("Couldn't handle, input size is 0!\n"); + return -WD_EINVAL; + } + + copy_len = copy_to_out(msg, buf, buf->pending_out); + buf->pending_out -= copy_len; + msg->produced = copy_len; + buf->skip_hw = true; + + if (!buf->pending_out) { + /* All data copied to output */ + msg->in_cons = buf->fallback_size; + buf->fallback_size = 0; + buf->output_offset = 0; + memset(buf->dst, 0, STORE_BUF_SIZE); + req->status = buf->status == WD_STREAM_END ? WD_STREAM_END : WD_SUCCESS; + } else { + /* Still data need to be copied */ + buf->output_offset += copy_len; + req->status = WD_SUCCESS; + } + + return 1; +} + +static void copy_from_hw(struct wd_comp_msg *msg, struct hisi_comp_buf *buf) +{ + struct wd_comp_req *req = &msg->req; + __u32 copy_len; + + copy_len = copy_to_out(msg, buf, msg->produced); + buf->pending_out = msg->produced - copy_len; + msg->produced = copy_len; + + if (!buf->pending_out) { + /* All data copied to output */ + buf->fallback_size = 0; + buf->output_offset = 0; + memset(buf->dst, 0, STORE_BUF_SIZE); + } else { + /* Still data need to be copied */ + buf->output_offset += copy_len; + + /* Feedback to users that a maximum of 1 byte of data is not consumed */ + if (msg->in_cons > 1) { + buf->fallback_size = 1; + msg->in_cons--; + } else { + buf->fallback_size = msg->in_cons; + msg->in_cons = 0; + } + + /* + * The end flag is cached. It can be output only + * after the data is completely copied to the output. + */ + if (req->status == WD_STREAM_END) { + buf->status = WD_STREAM_END; + req->status = WD_SUCCESS; + } + } +} + +static int check_enable_store_buf(struct wd_comp_msg *msg, __u32 out_size, int head_size) +{ + if (msg->stream_mode != WD_COMP_STATEFUL) + return 0; + + if (msg->stream_pos != WD_COMP_STREAM_NEW && out_size > SW_STOREBUF_TH) + return 0; + + if (msg->stream_pos == WD_COMP_STREAM_NEW && + out_size - head_size > SW_STOREBUF_TH) + return 0; + + /* 1 mean it need store buf */ + return 1; +} + static void fill_buf_size_deflate(struct hisi_zip_sqe *sqe, __u32 in_size, __u32 out_size) { @@ -238,11 +383,29 @@ static int fill_buf_deflate_generic(struct hisi_zip_sqe *sqe, { __u32 in_size = msg->req.src_len; __u32 out_size = msg->avail_out; + struct hisi_comp_buf *buf; void *src = msg->req.src; void *dst = msg->req.dst; void *ctx_buf = NULL; int ret; + /* + * When the output buffer is smaller than the SW_STOREBUF_TH in STATEFUL, + * the internal buffer is used. + */ + ret = check_enable_store_buf(msg, out_size, head_size); + if (ret) { + if (!msg->ctx_buf) { + WD_ERR("ctx_buf is NULL when out_size is less than 200!\n"); + return -WD_EINVAL; + } + + buf = (struct hisi_comp_buf *)(msg->ctx_buf + CTX_STOREBUF_OFFSET); + dst = buf->dst; + out_size = STORE_BUF_SIZE; + buf->pending_out = STORE_BUF_SIZE; + } + if (msg->stream_pos == WD_COMP_STREAM_NEW && head != NULL) { if (msg->req.op_type == WD_DIR_COMPRESS) { memcpy(dst, head, head_size); @@ -296,9 +459,9 @@ static void fill_buf_type_sgl(struct hisi_zip_sqe *sqe) } static int fill_buf_addr_deflate_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe, - struct wd_comp_msg *msg) + struct wd_datalist *list_src, + struct wd_datalist *list_dst) { - struct wd_comp_req *req = &msg->req; void *hw_sgl_in, *hw_sgl_out; handle_t h_sgl_pool; @@ -308,13 +471,13 @@ static int fill_buf_addr_deflate_sgl(handle_t h_qp, struct hisi_zip_sqe *sqe, return -WD_EINVAL; } - hw_sgl_in = hisi_qm_get_hw_sgl(h_sgl_pool, req->list_src); + hw_sgl_in = hisi_qm_get_hw_sgl(h_sgl_pool, list_src); if (unlikely(!hw_sgl_in)) { WD_ERR("failed to get hw sgl in!\n"); return -WD_ENOMEM; } - hw_sgl_out = hisi_qm_get_hw_sgl(h_sgl_pool, req->list_dst); + hw_sgl_out = hisi_qm_get_hw_sgl(h_sgl_pool, list_dst); if (unlikely(!hw_sgl_out)) { WD_ERR("failed to get hw sgl out!\n"); hisi_qm_put_hw_sgl(h_sgl_pool, hw_sgl_in); @@ -345,15 +508,37 @@ static int fill_buf_deflate_sgl_generic(handle_t h_qp, struct hisi_zip_sqe *sqe, int head_size) { struct wd_comp_req *req = &msg->req; + struct wd_datalist *list_src = req->list_src; + struct wd_datalist *list_dst = req->list_dst; __u32 out_size = msg->avail_out; __u32 in_size = req->src_len; + struct hisi_comp_buf *buf; __u32 src_skip = 0; __u32 dst_skip = 0; int ret; + /* + * When the output buffer is smaller than the SW_STOREBUF_TH in STATEFUL, + * the internal buffer is used. + */ + ret = check_enable_store_buf(msg, out_size, head_size); + if (ret) { + if (!msg->ctx_buf) { + WD_ERR("ctx_buf is NULL when out_size is less than 200!\n"); + return -WD_EINVAL; + } + + buf = (struct hisi_comp_buf *)(msg->ctx_buf + CTX_STOREBUF_OFFSET); + buf->pending_out = STORE_BUF_SIZE; + buf->list_dst.data = buf->dst; + buf->list_dst.len = STORE_BUF_SIZE; + list_dst = &buf->list_dst; + out_size = STORE_BUF_SIZE; + } + fill_buf_type_sgl(sqe); - ret = fill_buf_addr_deflate_sgl(h_qp, sqe, msg); + ret = fill_buf_addr_deflate_sgl(h_qp, sqe, list_src, list_dst); if (unlikely(ret)) return ret; @@ -943,6 +1128,11 @@ static int hisi_zip_comp_send(struct wd_alg_driver *drv, handle_t ctx, void *com __u16 count = 0; int ret; + /* Skip hardware, if the store buffer need to be copied to output */ + ret = check_store_buf(msg); + if (ret) + return ret < 0 ? ret : 0; + hisi_set_msg_id(h_qp, &msg->tag); ret = fill_zip_comp_sqe(qp, msg, &sqe); if (unlikely(ret < 0)) { @@ -1082,16 +1272,37 @@ static int hisi_zip_comp_recv(struct wd_alg_driver *drv, handle_t ctx, void *com { struct hisi_qp *qp = wd_ctx_get_priv(ctx); struct wd_comp_msg *recv_msg = comp_msg; + struct hisi_comp_buf *buf = NULL; handle_t h_qp = (handle_t)qp; struct hisi_zip_sqe sqe = {0}; __u16 count = 0; int ret; + if (recv_msg && recv_msg->ctx_buf) { + buf = (struct hisi_comp_buf *)(recv_msg->ctx_buf + CTX_STOREBUF_OFFSET); + /* + * The output has been copied from the storage buffer, + * and no data need to be received. + */ + if (buf->skip_hw) { + buf->skip_hw = false; + return 0; + } + } + ret = hisi_qm_recv(h_qp, &sqe, 1, &count); if (unlikely(ret < 0)) return ret; - return parse_zip_sqe(qp, &sqe, recv_msg); + ret = parse_zip_sqe(qp, &sqe, recv_msg); + if (unlikely(ret < 0 || recv_msg->req.status == WD_IN_EPARA)) + return ret; + + /* There are data in buf, copy to output */ + if (buf && buf->pending_out) + copy_from_hw(recv_msg, buf); + + return 0; } #define GEN_ZIP_ALG_DRIVER(zip_alg_name) \ -- 2.33.0

From: Chenghai Huang <huangchenghai2@huawei.com> Modify the output size to ensure that the output size is 1.125 times of the input size. Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_comp.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index bfeb8fad..e8c8d1d9 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -66,6 +66,11 @@ #define lower_32_bits(addr) ((__u32)((uintptr_t)(addr))) #define upper_32_bits(addr) ((__u32)((uintptr_t)(addr) >> HZ_HADDR_SHIFT)) +/* the min output buffer size is (input size * 1.125) */ +#define min_out_buf_size(inl) ((((__u64)inl * 9) + 7) >> 3) +/* the max input size is (output buffer size * 8 / 9) and align with 4 byte */ +#define max_in_data_size(outl) ((__u32)(((__u64)outl << 3) / 9) & 0xfffffffc) + #define HZ_MAX_SIZE (8 * 1024 * 1024) #define RSV_OFFSET 64 @@ -417,6 +422,16 @@ static int fill_buf_deflate_generic(struct hisi_zip_sqe *sqe, } } + /* + * When the output buffer is smaller than the 1.125*input len in STATEFUL, + * shrink the input len. + */ + if (msg->stream_mode == WD_COMP_STATEFUL && + (__u64)out_size < min_out_buf_size(in_size)) { + in_size = max_in_data_size(out_size); + msg->req.last = 0; + } + ret = buf_size_check_deflate(&in_size, &out_size); if (unlikely(ret)) return ret; @@ -551,6 +566,16 @@ static int fill_buf_deflate_sgl_generic(handle_t h_qp, struct hisi_zip_sqe *sqe, in_size -= head_size; } + /* + * When the output buffer is smaller than the 1.125*input len in STATEFUL, + * shrink the input len. + */ + if (msg->stream_mode == WD_COMP_STATEFUL && + (__u64)out_size < min_out_buf_size(in_size)) { + in_size = max_in_data_size(out_size); + msg->req.last = 0; + } + fill_buf_sgl_skip(sqe, src_skip, dst_skip); fill_buf_size_deflate(sqe, in_size, out_size); -- 2.33.0

From: Chenghai Huang <huangchenghai2@huawei.com> The resp_msg in wd_comp_poll_ctx is used before being initialized. The null pointer check in recv function is invalid. As a result, the memory is empty. Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- wd_comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wd_comp.c b/wd_comp.c index e7246740..02863df6 100644 --- a/wd_comp.c +++ b/wd_comp.c @@ -356,7 +356,7 @@ int wd_comp_poll_ctx(__u32 idx, __u32 expt, __u32 *count) { struct wd_ctx_config_internal *config = &wd_comp_setting.config; struct wd_ctx_internal *ctx; - struct wd_comp_msg resp_msg; + struct wd_comp_msg resp_msg = {0}; struct wd_comp_msg *msg; struct wd_comp_req *req; __u64 recv_count = 0; -- 2.33.0

From: Chenghai Huang <huangchenghai2@huawei.com> Replace the user output buffer with the internal buffer when the size of the user-provided buffer is less than 200 bytes. When cached data needs to be copied for multiple times, hardware processing is skipped. The way to skip hardware is to change the output size to 16. Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- v1/drv/hisi_zip_udrv.c | 189 +++++++++++++++++++++++++++++++++++------ 1 file changed, 161 insertions(+), 28 deletions(-) diff --git a/v1/drv/hisi_zip_udrv.c b/v1/drv/hisi_zip_udrv.c index fba6eca7..9ab2812a 100644 --- a/v1/drv/hisi_zip_udrv.c +++ b/v1/drv/hisi_zip_udrv.c @@ -74,6 +74,15 @@ #define lower_32_bits(phy) ((__u32)((__u64)(phy))) #define upper_32_bits(phy) ((__u32)((__u64)(phy) >> QM_HADDR_SHIFT)) +/* 200 * 1.125 + GZIP_HEADER_SZ, align with 4 byte */ +#define STORE_BUF_SIZE 236 +/* The hardware requires at least 200byte output buffers */ +#define SW_STOREBUF_TH 200 +/* The 38KB + CTX_BUFFER_OFFSET offset in ctx_buf is used as the internal buffer */ +#define CTX_STOREBUF_OFFSET 0x9840 +/* When the available output length is less than 0x10, hw will ignores the request */ +#define BYPASS_DEST_LEN 0x10 + enum { BD_TYPE, BD_TYPE3 = 3, @@ -85,6 +94,21 @@ enum lz77_compress_status { COMP_BLK, }; +struct hisi_zip_buf { + /* Denoted internal store buf */ + __u8 dst[STORE_BUF_SIZE]; + /* Denoted whether the output is copied from the storage buffer */ + __u8 skip_hw; + /* Denoted data size left in store buf */ + __u32 pending_out; + /* Size that have been copied */ + __u32 output_offset; + /* Input data consumption when all data copies are complete */ + __u32 fallback_size; + /* Store end flag return by HW */ + __u32 status; +}; + struct hisi_zip_sqe_addr { uintptr_t source_addr; uintptr_t dest_addr; @@ -137,6 +161,77 @@ static void zip_err_bd_print(__u16 ctx_st, __u32 status, __u32 type) } } +static __u32 copy_to_out(struct wcrypto_comp_msg *msg, struct hisi_zip_buf *buf, + __u32 pending_out) +{ + __u32 copy_len; + + /* + * msg->avail_out which inputed by user, is the size of user's dst buf, + * and there will ensure that the copy length will not exceed the + * available output length. + */ + copy_len = pending_out > msg->avail_out ? msg->avail_out : pending_out; + memcpy(msg->dst, buf->dst + buf->output_offset, copy_len); + + return copy_len; +} + +static void copy_from_buf(struct wcrypto_comp_msg *msg, struct hisi_zip_buf *buf) +{ + __u32 copy_len; + + if (!msg->in_size && buf->fallback_size) { + WD_ERR("Couldn't handle, input size is 0!\n"); + return; + } + + /* + * After hw processing, pending_out is the length of the hardware output. + * After hw is skipped, pending_out is the remaining length in the buf. + */ + if (!buf->skip_hw) + buf->pending_out = msg->produced; + + copy_len = copy_to_out(msg, buf, buf->pending_out); + buf->pending_out -= copy_len; + msg->produced = copy_len; + + if (!buf->pending_out) { + /* All data copied to output, reset the buf status */ + if (buf->skip_hw) { + buf->skip_hw = 0; + msg->in_cons = buf->fallback_size; + msg->status = buf->status == WCRYPTO_DECOMP_END ? + WCRYPTO_DECOMP_END : WD_SUCCESS; + } + + buf->fallback_size = 0; + buf->output_offset = 0; + } else { + /* Still data need to be copied */ + buf->output_offset += copy_len; + buf->skip_hw = 0; + + /* Feedback to users that a maximum of 1 byte of data is not consumed */ + if (msg->in_cons > 1) { + buf->fallback_size = 1; + msg->in_cons--; + } else { + msg->in_cons = 0; + } + + /* + * The end flag is cached. It can be output only + * after the data is completely copied to the output. + */ + if (msg->status == WCRYPTO_DECOMP_END) { + buf->status = WCRYPTO_DECOMP_END; + msg->status = WD_SUCCESS; + } + } +} + static int fill_zip_comp_alg_v1(struct hisi_zip_sqe *sqe, struct wcrypto_comp_msg *msg) { @@ -158,17 +253,37 @@ static int qm_fill_zip_sqe_get_phy_addr(struct hisi_zip_sqe_addr *addr, struct wcrypto_comp_msg *msg, struct wd_queue *q, bool is_lz77) { + struct hisi_zip_buf *buf; uintptr_t phy_ctxbuf = 0; uintptr_t phy_out = 0; uintptr_t phy_in; + if (msg->stream_mode == WCRYPTO_COMP_STATEFUL) { + phy_ctxbuf = (uintptr_t)drv_iova_map(q, msg->ctx_buf, + MAX_CTX_RSV_SIZE); + if (!phy_ctxbuf) { + WD_ERR("Get zip ctx buf dma address fail!\n"); + return -WD_ENOMEM; + } + + buf = (struct hisi_zip_buf *)(msg->ctx_buf + CTX_STOREBUF_OFFSET); + if (buf->pending_out) { + /* skip hw and output from internal buf */ + buf->skip_hw = 1; + } else if (msg->avail_out <= SW_STOREBUF_TH && msg->data_fmt != WD_SGL_BUF) { + /* Enable internal buf to replace the user output buffer. */ + phy_out = phy_ctxbuf + CTX_STOREBUF_OFFSET; + buf->pending_out = STORE_BUF_SIZE; + } + } + phy_in = (uintptr_t)drv_iova_map(q, msg->src, msg->in_size); if (!phy_in) { WD_ERR("Get zip in buf dma address fail!\n"); - return -WD_ENOMEM; + goto unmap_phy_ctx; } - if (!(is_lz77 && msg->data_fmt == WD_SGL_BUF)) { + if (!(is_lz77 && msg->data_fmt == WD_SGL_BUF) && !phy_out) { phy_out = (uintptr_t)drv_iova_map(q, msg->dst, msg->avail_out); if (!phy_out) { WD_ERR("Get zip out buf dma address fail!\n"); @@ -176,26 +291,18 @@ static int qm_fill_zip_sqe_get_phy_addr(struct hisi_zip_sqe_addr *addr, } } - if (msg->stream_mode == WCRYPTO_COMP_STATEFUL) { - phy_ctxbuf = (uintptr_t)drv_iova_map(q, msg->ctx_buf, - MAX_CTX_RSV_SIZE); - if (!phy_ctxbuf) { - WD_ERR("Get zip ctx buf dma address fail!\n"); - goto unmap_phy_out; - } - } - addr->source_addr = phy_in; addr->dest_addr = phy_out; addr->ctxbuf_addr = phy_ctxbuf + CTX_BUFFER_OFFSET; return WD_SUCCESS; -unmap_phy_out: - if (!(is_lz77 && msg->data_fmt == WD_SGL_BUF)) - drv_iova_unmap(q, msg->dst, (void *)phy_out, msg->avail_out); unmap_phy_in: drv_iova_unmap(q, msg->src, (void *)phy_in, msg->in_size); +unmap_phy_ctx: + if (msg->stream_mode == WCRYPTO_COMP_STATEFUL) + drv_iova_unmap(q, msg->ctx_buf, (void *)phy_ctxbuf, + MAX_CTX_RSV_SIZE); return -WD_ENOMEM; } @@ -390,6 +497,7 @@ static int fill_zip_comp_alg_zstd(void *ssqe, struct wcrypto_comp_msg *msg) static int fill_zip_buffer_size_deflate(void *ssqe, struct wcrypto_comp_msg *msg) { struct hisi_zip_sqe_v3 *sqe = ssqe; + struct hisi_zip_buf *buf; if (unlikely(msg->data_fmt != WD_SGL_BUF && msg->in_size > MAX_BUFFER_SIZE)) { @@ -406,6 +514,17 @@ static int fill_zip_buffer_size_deflate(void *ssqe, struct wcrypto_comp_msg *msg sqe->input_data_length = msg->in_size; sqe->dest_avail_out = msg->avail_out; + if (msg->ctx_buf) { + buf = (struct hisi_zip_buf *)(msg->ctx_buf + CTX_STOREBUF_OFFSET); + if (buf->skip_hw) { + /* Change dest_avail_out to BYPASS_DEST_LEN to skip hw */ + sqe->dest_avail_out = BYPASS_DEST_LEN; + sqe->input_data_length = 0; + } else if (buf->pending_out == STORE_BUF_SIZE) { + /* Change dest_avail_out to STORE_BUF_SIZE when enable internal buf.*/ + sqe->dest_avail_out = STORE_BUF_SIZE; + } + } return WD_SUCCESS; } @@ -648,12 +767,6 @@ int qm_fill_zip_sqe_v3(void *smsg, struct qm_queue_info *info, __u16 i) return ret; } - ret = ops[msg->alg_type].fill_sqe_buffer_size(sqe, msg); - if (unlikely(ret)) { - WD_ERR("The buffer size is invalid!\n"); - return ret; - } - ret = ops[msg->alg_type].fill_sqe_window_size(sqe, msg); if (unlikely(ret)) { WD_ERR("The window size is invalid!\n"); @@ -664,6 +777,12 @@ int qm_fill_zip_sqe_v3(void *smsg, struct qm_queue_info *info, __u16 i) if (unlikely(ret)) return ret; + ret = ops[msg->alg_type].fill_sqe_buffer_size(sqe, msg); + if (unlikely(ret)) { + WD_ERR("The buffer size is invalid!\n"); + return ret; + } + flush_type = (msg->flush_type == WCRYPTO_FINISH) ? HZ_FINISH : HZ_SYNC_FLUSH; sqe->dw7 |= ((msg->stream_pos << STREAM_POS_SHIFT) | @@ -736,6 +855,7 @@ int qm_parse_zip_sqe_v3(void *hw_msg, const struct qm_queue_info *info, __u32 status = sqe->dw3 & HZ_STATUS_MASK; __u32 type = sqe->dw9 & HZ_REQ_TYPE_MASK; uintptr_t phy_in, phy_out, phy_ctxbuf; + struct hisi_zip_buf *buf = NULL; struct wd_queue *q = info->q; struct wcrypto_comp_tag *tag; @@ -747,12 +867,6 @@ int qm_parse_zip_sqe_v3(void *hw_msg, const struct qm_queue_info *info, if (usr && sqe->tag_l != usr) return 0; - if (status != 0 && status != HW_NEGACOMPRESS && status != HW_DECOMP_END) { - zip_err_bd_print(ctx_st, status, type); - recv_msg->status = WD_IN_EPARA; - } else { - recv_msg->status = 0; - } recv_msg->in_cons = sqe->consumed; recv_msg->produced = sqe->produced; if (recv_msg->ctx_buf) { @@ -765,17 +879,36 @@ int qm_parse_zip_sqe_v3(void *hw_msg, const struct qm_queue_info *info, phy_in = DMA_ADDR(sqe->source_addr_h, sqe->source_addr_l); drv_iova_unmap(q, recv_msg->src, (void *)phy_in, recv_msg->in_size); - phy_out = DMA_ADDR(sqe->dest_addr_h, sqe->dest_addr_l); - drv_iova_unmap(q, recv_msg->dst, (void *)phy_out, recv_msg->avail_out); if (recv_msg->ctx_buf) { + buf = (struct hisi_zip_buf *)(recv_msg->ctx_buf + CTX_STOREBUF_OFFSET); phy_ctxbuf = DMA_ADDR(sqe->stream_ctx_addr_h, sqe->stream_ctx_addr_l) - CTX_BUFFER_OFFSET; drv_iova_unmap(q, recv_msg->ctx_buf, (void *)phy_ctxbuf, MAX_CTX_RSV_SIZE); } + /* + * The output mapping address needs to be released only when the internal buffer + * is not enabled or hw is skipped. + */ + if (!buf || !buf->pending_out || buf->skip_hw) { + phy_out = DMA_ADDR(sqe->dest_addr_h, sqe->dest_addr_l); + drv_iova_unmap(q, recv_msg->dst, (void *)phy_out, recv_msg->avail_out); + } + + if (status != 0 && status != HW_NEGACOMPRESS && status != HW_DECOMP_END && + (!buf || !buf->skip_hw)) { + zip_err_bd_print(ctx_st, status, type); + recv_msg->status = WD_IN_EPARA; + } else { + recv_msg->status = 0; + } + qm_parse_zip_sqe_set_status(recv_msg, status, lstblk, ctx_st); + if (buf && buf->pending_out) + copy_from_buf(recv_msg, buf); + tag = (void *)(uintptr_t)recv_msg->udata; if (tag && tag->priv && !info->sqe_fill_priv) fill_priv_lz77_zstd(sqe, recv_msg); -- 2.33.0

From: Chenghai Huang <huangchenghai2@huawei.com> Only stateful compression need to adjust the output size to ensure that the output size is 1.125 times of the input size. Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_comp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index e8c8d1d9..645b2bc8 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -423,10 +423,10 @@ static int fill_buf_deflate_generic(struct hisi_zip_sqe *sqe, } /* - * When the output buffer is smaller than the 1.125*input len in STATEFUL, + * When the output buffer is smaller than the 1.125*input len in STATEFUL compression, * shrink the input len. */ - if (msg->stream_mode == WD_COMP_STATEFUL && + if (msg->stream_mode == WD_COMP_STATEFUL && msg->req.op_type == WD_DIR_COMPRESS && (__u64)out_size < min_out_buf_size(in_size)) { in_size = max_in_data_size(out_size); msg->req.last = 0; @@ -567,10 +567,10 @@ static int fill_buf_deflate_sgl_generic(handle_t h_qp, struct hisi_zip_sqe *sqe, } /* - * When the output buffer is smaller than the 1.125*input len in STATEFUL, + * When the output buffer is smaller than the 1.125*input len in STATEFUL compression, * shrink the input len. */ - if (msg->stream_mode == WD_COMP_STATEFUL && + if (msg->stream_mode == WD_COMP_STATEFUL && msg->req.op_type == WD_DIR_COMPRESS && (__u64)out_size < min_out_buf_size(in_size)) { in_size = max_in_data_size(out_size); msg->req.last = 0; -- 2.33.0

From: Chenghai Huang <huangchenghai2@huawei.com> Check whether the pointer is null before the ctx_buf is reset. Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_comp.c | 4 ++++ wd_comp.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 645b2bc8..7a106652 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -856,6 +856,10 @@ static int fill_comp_level_lz77_zstd(struct hisi_zip_sqe *sqe, enum wd_comp_leve switch (comp_lv) { case WD_COMP_L8: + /* + * L8 indicates that the price mode is disabled. + * By default, the price mode is disabled. + */ break; case WD_COMP_L9: val = sqe->dw9 & ~HZ_REQ_TYPE_MASK; diff --git a/wd_comp.c b/wd_comp.c index 02863df6..ca8faa39 100644 --- a/wd_comp.c +++ b/wd_comp.c @@ -502,7 +502,9 @@ int wd_comp_reset_sess(handle_t h_sess) } sess->stream_pos = WD_COMP_STREAM_NEW; - memset(sess->ctx_buf, 0, HW_CTX_SIZE); + + if (sess->ctx_buf) + memset(sess->ctx_buf, 0, HW_CTX_SIZE); return 0; } -- 2.33.0

From: Longfang Liu <liulongfang@huawei.com> Upstream: Yes Feature or Bugfix: Bugfix DTS: DTS2025022803997 There are some problems in the public framework code of v1: 1. Some memory judgments are not comprehensive. 2. Some function return values are not checked 3. Some function input parameter verification is incomplete 4. Add some comments to improve code readability 5. Modify some log description errors Signed-off-by: Longfang Liu <liulongfang@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- v1/drv/hisi_qm_udrv.c | 9 ++++++--- v1/wd.c | 13 +++++++++++-- v1/wd_adapter.c | 3 ++- v1/wd_ecc.c | 5 +++-- v1/wd_sgl.c | 6 ++++-- v1/wd_util.c | 2 +- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/v1/drv/hisi_qm_udrv.c b/v1/drv/hisi_qm_udrv.c index 7b0183bc..755d88e1 100644 --- a/v1/drv/hisi_qm_udrv.c +++ b/v1/drv/hisi_qm_udrv.c @@ -768,13 +768,16 @@ static int hw_type_check(struct wd_queue *q, const char *hw_type) int hisi_qm_inject_op_register(struct wd_queue *q, struct hisi_qm_inject_op *op) { - struct q_info *qinfo = q->qinfo; - struct qm_queue_info *info = qinfo->priv; + struct qm_queue_info *info; + struct q_info *qinfo; - if (!op || !op->sqe_fill_priv || !op->sqe_parse_priv) { + if (!q || !q->qinfo || !op || !op->sqe_fill_priv || + !op->sqe_parse_priv) { WD_ERR("inject option is invalid!\n"); return -WD_EINVAL; } + qinfo = q->qinfo; + info = qinfo->priv; if (hw_type_check(q, op->hw_type)) { WD_ERR("inject option hw compare error!\n"); diff --git a/v1/wd.c b/v1/wd.c index 02bc49cc..13239b58 100644 --- a/v1/wd.c +++ b/v1/wd.c @@ -868,14 +868,18 @@ void wd_drv_unmmap_qfr(struct wd_queue *q, void *addr, enum uacce_qfrt qfrt, size_t size) { struct q_info *qinfo = q->qinfo; + int ret; if (!addr) return; if (qfrt != WD_UACCE_QFRT_SS) - munmap(addr, qinfo->qfrs_offset[qfrt]); + ret = munmap(addr, qinfo->qfrs_offset[qfrt]); else - munmap(addr, size); + ret = munmap(addr, size); + + if (ret) + WD_ERR("wd qfr unmap failed!\n"); } int wd_register_log(wd_log log) @@ -890,6 +894,11 @@ int wd_register_log(wd_log log) return -WD_EINVAL; } + /* + * No exceptions are generated during concurrency. + * Users are required to ensure the order of configuration + * operations + */ log_out = log; dbg("log register\n"); diff --git a/v1/wd_adapter.c b/v1/wd_adapter.c index f9d5f041..0c9cd334 100644 --- a/v1/wd_adapter.c +++ b/v1/wd_adapter.c @@ -93,10 +93,11 @@ static const struct wd_drv_dio_if hw_dio_tbl[] = { { int drv_open(struct wd_queue *q) { struct q_info *qinfo = q->qinfo; + __u32 type_size = MAX_HW_TYPE; __u32 i; /* try to find another device if the user driver is not available */ - for (i = 0; i < MAX_HW_TYPE; i++) { + for (i = 0; i < type_size; i++) { if (!strcmp(qinfo->hw_type, hw_dio_tbl[i].hw_type)) { qinfo->hw_type_id = i; diff --git a/v1/wd_ecc.c b/v1/wd_ecc.c index 8bb58792..a887e00c 100644 --- a/v1/wd_ecc.c +++ b/v1/wd_ecc.c @@ -200,7 +200,8 @@ static void *br_alloc(struct wd_mm_br *br, __u64 size) } if (br->get_bufsize && br->get_bufsize(br->usr) < size) { - WD_ERR("Blk_size < need_size<0x%llx>.\n", size); + WD_ERR("Blk_size<0x%x> < need_size<0x%llx>.\n", + br->get_bufsize(br->usr), size); return NULL; } @@ -2199,7 +2200,7 @@ int wcrypto_do_ecdsa(void *ctx, struct wcrypto_ecc_op_data *opdata, void *tag) int wcrypto_ecdsa_poll(struct wd_queue *q, unsigned int num) { if (unlikely(!q || strcmp(q->capa.alg, "ecdsa"))) { - WD_ERR("sm2 poll: input parameter error!\n"); + WD_ERR("ecdsa poll: input parameter error!\n"); return -WD_EINVAL; } diff --git a/v1/wd_sgl.c b/v1/wd_sgl.c index cb3b8eeb..eef4f6c0 100644 --- a/v1/wd_sgl.c +++ b/v1/wd_sgl.c @@ -1026,6 +1026,8 @@ void wd_sgl_memset(struct wd_sgl *sgl, int ch) return; } - for (i = 0; i < sgl->buf_num; i++) - memset(sgl->sge[i].buf, ch, sgl->pool->setup.buf_size); + for (i = 0; i < sgl->buf_num; i++) { + if (sgl->sge[i].buf) + memset(sgl->sge[i].buf, ch, sgl->pool->setup.buf_size); + } } diff --git a/v1/wd_util.c b/v1/wd_util.c index 3dac2d74..0bc9d04e 100644 --- a/v1/wd_util.c +++ b/v1/wd_util.c @@ -143,7 +143,7 @@ int wd_init_cookie_pool(struct wd_cookie_pool *pool, void wd_uninit_cookie_pool(struct wd_cookie_pool *pool) { - if (pool->cookies) { + if (pool && pool->cookies) { free(pool->cookies); pool->cookies = NULL; } -- 2.33.0

From: Zhiqi Song <songzhiqi1@huawei.com> The operation of setting the input parameter to NULL is redundant and therefore deleted. Signed-off-by: Zhiqi Song <songzhiqi1@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_hpre.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index a18d358f..30411609 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -2536,7 +2536,6 @@ static void ecc_sess_eops_uninit(void *params) } free(params); - params = NULL; } static void ecc_sess_eops_params_cfg(struct wd_ecc_sess_setup *setup, -- 2.33.0

From: Wenkai Lin <linwenkai6@hisilicon.com> The full life cycle of the shared memory is shmget(create memory), shmat(attach to the process), shmdt(detach to the process) and shmctl(delete memory), so fix for the uadk code according to this rule. Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- wd_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wd_util.c b/wd_util.c index 2236b957..af4d949b 100644 --- a/wd_util.c +++ b/wd_util.c @@ -205,6 +205,7 @@ static void wd_shm_delete(struct wd_ctx_config_internal *in) return; /* deleted shared memory */ + shmdt(in->msg_cnt); shmctl(in->shmid, IPC_RMID, NULL); in->shmid = 0; -- 2.33.0

From: lizhi <lizhi206@huawei.com> Upstream: Yes Bugfix or Feature: Bugfix DTS: DTS2024111417327 Change eops_params_cfg return type from int to void. Clear params pointer after session uninit to prevent leaks. Signed-off-by: lizhi <lizhi206@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- include/drv/wd_ecc_drv.h | 2 +- wd_ecc.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/drv/wd_ecc_drv.h b/include/drv/wd_ecc_drv.h index 37908cd2..085bd4ae 100644 --- a/include/drv/wd_ecc_drv.h +++ b/include/drv/wd_ecc_drv.h @@ -178,7 +178,7 @@ struct wd_ecc_out { struct wd_ecc_extend_ops { void *params; /* the params are passed to the following ops */ - int (*eops_params_cfg)(struct wd_ecc_sess_setup *setup, + void (*eops_params_cfg)(struct wd_ecc_sess_setup *setup, struct wd_ecc_curve *cv, void *params); int (*sess_init)(void **params); void (*sess_uninit)(void *params); diff --git a/wd_ecc.c b/wd_ecc.c index 7ae5f757..cf5c4720 100644 --- a/wd_ecc.c +++ b/wd_ecc.c @@ -1189,8 +1189,10 @@ static int wd_ecc_sess_eops_init(struct wd_ecc_sess *sess) static void wd_ecc_sess_eops_uninit(struct wd_ecc_sess *sess) { - if (sess->eops.sess_uninit) + if (sess->eops.sess_uninit) { sess->eops.sess_uninit(sess->eops.params); + sess->eops.params = NULL; + } } static void wd_ecc_sess_eops_cfg(struct wd_ecc_sess_setup *setup, @@ -1274,7 +1276,7 @@ void wd_ecc_free_sess(handle_t sess) if (sess_t->sched_key) free(sess_t->sched_key); del_sess_key(sess_t); - wd_ecc_sess_eops_uninit(sess); + wd_ecc_sess_eops_uninit(sess_t); free(sess_t); } -- 2.33.0

From: Weili Qian <qianweili@huawei.com> The variable 'pos' is enumeration type, and the case branches cover all values. So remove default branch. Signed-off-by: Weili Qian <qianweili@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hisi_dae.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drv/hisi_dae.c b/drv/hisi_dae.c index b9f6ee07..1a1741b7 100644 --- a/drv/hisi_dae.c +++ b/drv/hisi_dae.c @@ -294,6 +294,10 @@ static void put_ext_addr(struct dae_extend_addr *ext_addr, int idx) static void fill_hashagg_task_type(struct wd_agg_msg *msg, struct dae_sqe *sqe) { + /* + * The variable 'pos' is enumeration type, and the case branches + * cover all values. + */ switch (msg->pos) { case WD_AGG_REHASH_INPUT: case WD_AGG_STREAM_INPUT: @@ -303,8 +307,6 @@ static void fill_hashagg_task_type(struct wd_agg_msg *msg, struct dae_sqe *sqe) case WD_AGG_REHASH_OUTPUT: sqe->task_type_ext = DAE_HASHAGG_OUTPUT; break; - default: - break; } } @@ -337,9 +339,13 @@ static void fill_hashagg_table_data(struct dae_sqe *sqe, struct dae_addr_list *a struct wd_agg_msg *msg) { struct hashagg_ctx *agg_ctx = (struct hashagg_ctx *)msg->priv; - struct hash_table_data *table_data = NULL; - struct dae_table_addr *hw_table = NULL; + struct hash_table_data *table_data = &agg_ctx->table_data; + struct dae_table_addr *hw_table = &addr_list->src_table; + /* + * The variable 'pos' is enumeration type, and the case branches + * cover all values. + */ switch (msg->pos) { case WD_AGG_STREAM_INPUT: case WD_AGG_REHASH_INPUT: @@ -347,15 +353,11 @@ static void fill_hashagg_table_data(struct dae_sqe *sqe, struct dae_addr_list *a table_data = &agg_ctx->table_data; break; case WD_AGG_STREAM_OUTPUT: - hw_table = &addr_list->src_table; - table_data = &agg_ctx->table_data; break; case WD_AGG_REHASH_OUTPUT: hw_table = &addr_list->src_table; table_data = &agg_ctx->rehash_table; break; - default: - break; } sqe->table_row_size = agg_ctx->row_size; @@ -454,6 +456,10 @@ static void fill_hashagg_input_data(struct dae_sqe *sqe, struct dae_ext_sqe *ext __u32 agg_col_num = 0; __u32 i, usr_col_idx; + /* + * The variable 'pos' is enumeration type, and the case branches + * cover all values. + */ switch (msg->pos) { case WD_AGG_STREAM_INPUT: agg_data = cols_data->input_data; @@ -477,8 +483,6 @@ static void fill_hashagg_input_data(struct dae_sqe *sqe, struct dae_ext_sqe *ext agg_col_num = cols_data->output_num; fill_hashagg_normal_info(sqe, ext_sqe, cols_data, cols_data->input_num); break; - default: - break; } for (i = 0; i < agg_col_num; i++) { -- 2.33.0

From: Weili Qian <qianweili@huawei.com> Pointer check is added to prevent memcpy errors. In addition, the comment of the wd_dtb structure is added. Signed-off-by: Weili Qian <qianweili@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- v1/wd.h | 5 ++++- v1/wd_dh.c | 6 ++---- v1/wd_ecc.c | 1 - v1/wd_rsa.c | 12 +++++++----- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/v1/wd.h b/v1/wd.h index 90e2321a..79b8a2ad 100644 --- a/v1/wd.h +++ b/v1/wd.h @@ -110,7 +110,10 @@ struct wd_mm_br { wd_bufsize get_bufsize; /* optional */ }; -/* Warpdrive data buffer */ +/* + * Warpdrive data buffer. If the actual size of data is inconsistent + * with dsize, undefined behavior occurs. + */ struct wd_dtb { char *data; /* data/buffer start address */ __u32 dsize; /* data size */ diff --git a/v1/wd_dh.c b/v1/wd_dh.c index 0329dde6..12f7b19d 100644 --- a/v1/wd_dh.c +++ b/v1/wd_dh.c @@ -243,10 +243,8 @@ int wcrypto_set_dh_g(void *ctx, struct wd_dtb *g) return -WD_EINVAL; } - if (g->dsize - && g->bsize <= cx->g.bsize - && g->dsize <= cx->g.bsize) { - memset(cx->g.data, 0, g->bsize); + if (g->dsize && g->data && g->dsize <= cx->g.bsize) { + memset(cx->g.data, 0, cx->g.bsize); memcpy(cx->g.data, g->data, g->dsize); cx->g.dsize = g->dsize; if (*g->data != WD_DH_G2 && cx->setup.is_g2) diff --git a/v1/wd_ecc.c b/v1/wd_ecc.c index a887e00c..bb65dfbe 100644 --- a/v1/wd_ecc.c +++ b/v1/wd_ecc.c @@ -1713,7 +1713,6 @@ void wcrypto_get_ecdsa_sign_out_params(struct wcrypto_ecc_out *out, get_sign_out_params(out, r, s); } - static bool less_than_latter(struct wd_dtb *d, struct wd_dtb *n) { int ret, shift; diff --git a/v1/wd_rsa.c b/v1/wd_rsa.c index 2c8692b6..1703dd37 100644 --- a/v1/wd_rsa.c +++ b/v1/wd_rsa.c @@ -161,15 +161,17 @@ static int kg_in_param_check(void *ctx, struct wd_dtb *e, return -WD_EINVAL; } - if (unlikely(e->dsize > c->key_size)) { + if (unlikely(!e->dsize || e->dsize > c->key_size || !e->data)) { WD_ERR("e para err at create kg in!\n"); return -WD_EINVAL; } - if (unlikely(p->dsize > CRT_PARAM_SZ(c->key_size))) { + + if (unlikely(!p->dsize || p->dsize > CRT_PARAM_SZ(c->key_size) || !p->data)) { WD_ERR("p para err at create kg in!\n"); return -WD_EINVAL; } - if (unlikely(q->dsize > CRT_PARAM_SZ(c->key_size))) { + + if (unlikely(!q->dsize || q->dsize > CRT_PARAM_SZ(c->key_size) || !q->data)) { WD_ERR("q para err at create kg in!\n"); return -WD_EINVAL; } @@ -762,7 +764,7 @@ void wcrypto_get_rsa_prikey_params(struct wcrypto_rsa_prikey *pvk, struct wd_dtb static int rsa_set_param(struct wd_dtb *src, struct wd_dtb *dst) { - if (!src || !dst || dst->dsize > src->bsize) + if (dst->dsize > src->bsize) return -WD_EINVAL; src->dsize = dst->dsize; @@ -778,7 +780,7 @@ static int rsa_prikey2_param_set(struct wcrypto_rsa_prikey2 *pkey2, { int ret; - if (param->dsize > pkey2->key_size || !param->data) + if (!param->dsize || !param->data) return -WD_EINVAL; switch (type) { -- 2.33.0

From: Weili Qian <qianweili@huawei.com> Pointer check is added to prevent memcpy errors. In addition, the comment of the wd_dtb structure is added. Signed-off-by: Weili Qian <qianweili@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- include/wd.h | 4 ++++ wd_dh.c | 6 ++---- wd_ecc.c | 1 - wd_rsa.c | 12 +++++++----- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/wd.h b/include/wd.h index 944c3e85..b62d355b 100644 --- a/include/wd.h +++ b/include/wd.h @@ -115,6 +115,10 @@ enum wd_alg_type { WD_AEAD, }; +/* + * If the actual size of data is inconsistent + * with dsize, undefined behavior occurs. + */ struct wd_dtb { /* data/buffer start address */ char *data; diff --git a/wd_dh.c b/wd_dh.c index 043c3be9..3e02f2a1 100644 --- a/wd_dh.c +++ b/wd_dh.c @@ -555,10 +555,8 @@ int wd_dh_set_g(handle_t sess, struct wd_dtb *g) return -WD_EINVAL; } - if (g->dsize && - g->bsize <= sess_t->g.bsize && - g->dsize <= sess_t->g.bsize) { - memset(sess_t->g.data, 0, g->bsize); + if (g->dsize && g->data && g->dsize <= sess_t->g.bsize) { + memset(sess_t->g.data, 0, sess_t->g.bsize); memcpy(sess_t->g.data, g->data, g->dsize); sess_t->g.dsize = g->dsize; if (*g->data != WD_DH_G2 && sess_t->setup.is_g2) diff --git a/wd_ecc.c b/wd_ecc.c index cf5c4720..36e5206f 100644 --- a/wd_ecc.c +++ b/wd_ecc.c @@ -1710,7 +1710,6 @@ static int generate_random(struct wd_ecc_sess *sess, struct wd_dtb *k) static int sm2_compute_za_hash(__u8 *za, __u32 *len, struct wd_dtb *id, struct wd_ecc_sess *sess) - { __u32 key_size = BITS_TO_BYTES(sess->setup.key_bits); struct wd_hash_mt *hash = &sess->setup.hash; diff --git a/wd_rsa.c b/wd_rsa.c index f0dfb567..caac7e60 100644 --- a/wd_rsa.c +++ b/wd_rsa.c @@ -623,15 +623,17 @@ struct wd_rsa_kg_in *wd_rsa_new_kg_in(handle_t sess, struct wd_dtb *e, return NULL; } - if (!e->dsize || e->dsize > c->key_size) { + if (!e->dsize || e->dsize > c->key_size || !e->data) { WD_ERR("invalid: e para err at create kg in!\n"); return NULL; } - if (!p->dsize || p->dsize > CRT_PARAM_SZ(c->key_size)) { + + if (!p->dsize || p->dsize > CRT_PARAM_SZ(c->key_size) || !p->data) { WD_ERR("invalid: p para err at create kg in!\n"); return NULL; } - if (!q->dsize || q->dsize > CRT_PARAM_SZ(c->key_size)) { + + if (!q->dsize || q->dsize > CRT_PARAM_SZ(c->key_size) || !q->data) { WD_ERR("invalid: q para err at create kg in!\n"); return NULL; } @@ -1105,7 +1107,7 @@ void wd_rsa_get_prikey_params(struct wd_rsa_prikey *pvk, struct wd_dtb **d, static int rsa_set_param(struct wd_dtb *src, struct wd_dtb *dst) { - if (!src || !dst || dst->dsize > src->bsize) + if (dst->dsize > src->bsize) return -WD_EINVAL; src->dsize = dst->dsize; @@ -1121,7 +1123,7 @@ static int rsa_prikey2_param_set(struct wd_rsa_prikey2 *pkey2, { int ret = -WD_EINVAL; - if (param->dsize > pkey2->key_size || !param->data) + if (!param->dsize || !param->data) return -WD_EINVAL; switch (type) { -- 2.33.0

From: Longfang Liu <liulongfang@huawei.com> In the user-space driver of UADK, when performing the operation to exit and deregister the driver, the added parameter check is placed before the variable declarations in the function, causing inconsistency in code style with other parts. Signed-off-by: Longfang Liu <liulongfang@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/hash_mb/hash_mb.c | 7 ++++--- drv/hisi_comp.c | 9 +++++---- drv/hisi_dae.c | 9 +++++---- drv/hisi_hpre.c | 9 +++++---- drv/hisi_sec.c | 9 +++++---- drv/isa_ce_sm3.c | 7 ++++--- drv/isa_ce_sm4.c | 7 ++++--- 7 files changed, 32 insertions(+), 25 deletions(-) diff --git a/drv/hash_mb/hash_mb.c b/drv/hash_mb/hash_mb.c index f0f27b59..bd412b23 100644 --- a/drv/hash_mb/hash_mb.c +++ b/drv/hash_mb/hash_mb.c @@ -217,11 +217,12 @@ static int hash_mb_init(struct wd_alg_driver *drv, void *conf) static void hash_mb_exit(struct wd_alg_driver *drv) { - if(!drv || !drv->priv) - return; + struct hash_mb_ctx *priv; - struct hash_mb_ctx *priv = (struct hash_mb_ctx *)drv->priv; + if (!drv || !drv->priv) + return; + priv = (struct hash_mb_ctx *)drv->priv; hash_mb_queue_uninit(&priv->config, priv->config.ctx_num); free(priv); drv->priv = NULL; diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 7a106652..0e9cd65d 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -1054,14 +1054,15 @@ out: static void hisi_zip_exit(struct wd_alg_driver *drv) { - if(!drv || !drv->priv) - return; - - struct hisi_zip_ctx *priv = (struct hisi_zip_ctx *)drv->priv; struct wd_ctx_config_internal *config; + struct hisi_zip_ctx *priv; handle_t h_qp; __u32 i; + if (!drv || !drv->priv) + return; + + priv = (struct hisi_zip_ctx *)drv->priv; config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); diff --git a/drv/hisi_dae.c b/drv/hisi_dae.c index b9f6ee07..9c2ca8b1 100644 --- a/drv/hisi_dae.c +++ b/drv/hisi_dae.c @@ -1612,14 +1612,15 @@ out: static void dae_exit(struct wd_alg_driver *drv) { - if(!drv || !drv->priv) - return; - - struct hisi_dae_ctx *priv = (struct hisi_dae_ctx *)drv->priv; struct wd_ctx_config_internal *config; + struct hisi_dae_ctx *priv; handle_t h_qp; __u32 i; + if (!drv || !drv->priv) + return; + + priv = (struct hisi_dae_ctx *)drv->priv; config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index 30411609..e0cd7424 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -592,14 +592,15 @@ static int hpre_ecc_init(struct wd_alg_driver *drv, void *conf) static void hpre_exit(struct wd_alg_driver *drv) { - if(!drv || !drv->priv) - return; - - struct hisi_hpre_ctx *priv = (struct hisi_hpre_ctx *)drv->priv; struct wd_ctx_config_internal *config; + struct hisi_hpre_ctx *priv; handle_t h_qp; __u32 i; + if (!drv || !drv->priv) + return; + + priv = (struct hisi_hpre_ctx *)drv->priv; config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c index 5990565a..747d3a8e 100644 --- a/drv/hisi_sec.c +++ b/drv/hisi_sec.c @@ -3104,14 +3104,15 @@ out: static void hisi_sec_exit(struct wd_alg_driver *drv) { - if(!drv || !drv->priv) - return; - - struct hisi_sec_ctx *priv = (struct hisi_sec_ctx *)drv->priv; struct wd_ctx_config_internal *config; + struct hisi_sec_ctx *priv; handle_t h_qp; __u32 i; + if (!drv || !drv->priv) + return; + + priv = (struct hisi_sec_ctx *)drv->priv; config = &priv->config; for (i = 0; i < config->ctx_num; i++) { h_qp = (handle_t)wd_ctx_get_priv(config->ctxs[i].ctx); diff --git a/drv/isa_ce_sm3.c b/drv/isa_ce_sm3.c index 4ad21705..68be912a 100644 --- a/drv/isa_ce_sm3.c +++ b/drv/isa_ce_sm3.c @@ -387,11 +387,12 @@ static int sm3_ce_drv_init(struct wd_alg_driver *drv, void *conf) static void sm3_ce_drv_exit(struct wd_alg_driver *drv) { - if(!drv || !drv->priv) - return; + struct sm3_ce_drv_ctx *sctx; - struct sm3_ce_drv_ctx *sctx = (struct sm3_ce_drv_ctx *)drv->priv; + if (!drv || !drv->priv) + return; + sctx = (struct sm3_ce_drv_ctx *)drv->priv; free(sctx); drv->priv = NULL; } diff --git a/drv/isa_ce_sm4.c b/drv/isa_ce_sm4.c index 5e448fa0..52dca1f5 100644 --- a/drv/isa_ce_sm4.c +++ b/drv/isa_ce_sm4.c @@ -53,11 +53,12 @@ static int isa_ce_init(struct wd_alg_driver *drv, void *conf) static void isa_ce_exit(struct wd_alg_driver *drv) { - if(!drv || !drv->priv) - return; + struct sm4_ce_drv_ctx *sctx; - struct sm4_ce_drv_ctx *sctx = (struct sm4_ce_drv_ctx *)drv->priv; + if (!drv || !drv->priv) + return; + sctx = (struct sm4_ce_drv_ctx *)drv->priv; free(sctx); drv->priv = NULL; } -- 2.33.0

From: Hao Fang <fanghao11@huawei.com> uadk_tool test --m zip supports the most of function tests except for one command --ilist, so the test file size set to 8MB for block mode. The --ilist cmd has been removed because a complex user protocol was constructed only for large file compression in block mode. Signed-off-by: Hao Fang <fanghao11@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- test/sanity_test.sh | 62 ++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/test/sanity_test.sh b/test/sanity_test.sh index 591f8e2d..a1f2b234 100755 --- a/test/sanity_test.sh +++ b/test/sanity_test.sh @@ -88,10 +88,10 @@ hw_blk_deflate() case $3 in "gzip") ${RM} -f /tmp/gzip_list.bin - run_cmd zip_sva_perf --in $1 --out $2 --olist /tmp/gzip_list.bin $@ + run_cmd uadk_tool test --m zip --in $1 --out $2 $@ ;; "zlib") - run_cmd zip_sva_perf -z --in $1 --out $2 --olist /tmp/zlib_list.bin $@ + run_cmd uadk_tool test --m zip --alg 1 --in $1 --out $2 $@ ;; *) echo "Unsupported algorithm type: $3" @@ -105,10 +105,10 @@ hw_blk_inflate() { case $3 in "gzip") - run_cmd zip_sva_perf -d --in $1 --out $2 --ilist /tmp/gzip_list.bin $@ + run_cmd uadk_tool test --m zip --inf --in $1 --out $2 $@ ;; "zlib") - run_cmd zip_sva_perf -z -d --in $1 --out $2 --ilist /tmp/zlib_list.bin $@ + run_cmd uadk_tool test --m zip --alg 1 --inf --in $1 --out $2 $@ ;; *) echo "Unsupported algorithm type: $3" @@ -122,10 +122,10 @@ hw_strm_deflate() { case $3 in "gzip") - run_cmd zip_sva_perf -S --in $1 --out $2 $@ + run_cmd uadk_tool test --m zip --stream --in $1 --out $2 $@ ;; "zlib") - run_cmd zip_sva_perf -z -S --in $1 --out $2 $@ + run_cmd uadk_tool test --m zip --stream --alg 1 --in $1 --out $2 $@ ;; *) echo "Unsupported algorithm type: $3" @@ -139,10 +139,10 @@ hw_strm_inflate() { case $3 in "gzip") - run_cmd zip_sva_perf -S -d --in $1 --out $2 $@ + run_cmd uadk_tool test --m zip --stream --inf --in $1 --out $2 $@ ;; "zlib") - run_cmd zip_sva_perf -z -S -d --in $1 --out $2 $@ + run_cmd uadk_tool test --m zip --stream --inf --in $1 --out $2 $@ ;; *) echo "Unsupported algorithm type: $3" @@ -234,12 +234,12 @@ hw_dfl_sw_ifl() prepare_src_file random 1 md5sum origin > ori.md5 - hw_blk_deflate origin /tmp/ori.gz gzip -b 8192 --env + hw_blk_deflate origin /tmp/ori.gz gzip --blksize 8192 --env sw_blk_inflate /tmp/ori.gz origin gzip md5sum -c ori.md5 ${RM} -f /tmp/ori.gz - hw_strm_deflate origin /tmp/ori.gz gzip -b 8192 --env + hw_strm_deflate origin /tmp/ori.gz gzip --blksize 8192 --env sw_strm_inflate /tmp/ori.gz origin gzip md5sum -c ori.md5 @@ -249,7 +249,7 @@ hw_dfl_sw_ifl() md5sum origin > ori.md5 ${RM} -f /tmp/ori.gz - hw_strm_deflate origin /tmp/ori.gz gzip -b 8192 --env + hw_strm_deflate origin /tmp/ori.gz gzip --blksize 8192 --env sw_strm_inflate /tmp/ori.gz origin gzip md5sum -c ori.md5 @@ -259,13 +259,13 @@ hw_dfl_sw_ifl() prepare_src_file $1 md5sum origin > ori.md5 - hw_blk_deflate origin /tmp/ori.gz gzip -b 8192 --env + hw_blk_deflate origin /tmp/ori.gz gzip --blksize 8192 --env sw_blk_inflate /tmp/ori.gz origin gzip md5sum -c ori.md5 # This case fails. ${RM} -f /tmp/ori.gz - hw_strm_deflate origin /tmp/ori.gz gzip -b 8192 --env + hw_strm_deflate origin /tmp/ori.gz gzip --blksize 8192 --env sw_strm_inflate /tmp/ori.gz origin gzip md5sum -c ori.md5 } @@ -282,13 +282,13 @@ sw_dfl_hw_ifl() # Only gzip compress and hardware decompress sw_blk_deflate origin /tmp/ori.gz gzip 8192 - hw_blk_inflate /tmp/ori.gz origin gzip -b 8192 + hw_blk_inflate /tmp/ori.gz origin gzip --blksize 8192 md5sum -c ori.md5 - hw_blk_inflate /tmp/ori.gz origin gzip -b 8192 --env + hw_blk_inflate /tmp/ori.gz origin gzip --blksize 8192 --env md5sum -c ori.md5 sw_strm_deflate origin /tmp/ori.gz gzip 8192 - hw_strm_inflate /tmp/ori.gz origin gzip -b 8192 --env + hw_strm_inflate /tmp/ori.gz origin gzip --blksize 8192 --env md5sum -c ori.md5 # Generate random data with 500MB size @@ -298,7 +298,7 @@ sw_dfl_hw_ifl() ${RM} -f /tmp/ori.gz sw_strm_deflate origin /tmp/ori.gz gzip 8192 - hw_strm_inflate /tmp/ori.gz origin gzip -b 8192 --env + hw_strm_inflate /tmp/ori.gz origin gzip --blksize 8192 --env md5sum -c ori.md5 # Use existed text file. It's not in alignment. @@ -308,11 +308,11 @@ sw_dfl_hw_ifl() md5sum origin > ori.md5 #sw_blk_deflate origin /tmp/ori.gz gzip 8192 - #hw_blk_inflate /tmp/ori.gz origin gzip -b 8192 --env + #hw_blk_inflate /tmp/ori.gz origin gzip --blksize 8192 --env #md5sum -c ori.md5 sw_strm_deflate origin /tmp/ori.gz gzip 8192 - hw_strm_inflate /tmp/ori.gz origin gzip -b 8192 --env + hw_strm_inflate /tmp/ori.gz origin gzip --blksize 8192 --env md5sum -c ori.md5 } @@ -326,13 +326,13 @@ hw_dfl_hw_ifl() prepare_src_file random 1 md5sum origin > ori.md5 - hw_blk_deflate origin /tmp/ori.gz gzip -b 8192 - hw_blk_inflate /tmp/ori.gz origin gzip -b 8192 + hw_blk_deflate origin /tmp/ori.gz gzip --blksize 8192 + hw_blk_inflate /tmp/ori.gz origin gzip --blksize 8192 md5sum -c ori.md5 ${RM} -f /tmp/ori.gz - hw_strm_deflate origin /tmp/ori.gz gzip -b 8192 - hw_strm_inflate /tmp/ori.gz origin gzip -b 8192 + hw_strm_deflate origin /tmp/ori.gz gzip --blksize 8192 + hw_strm_inflate /tmp/ori.gz origin gzip --blksize 8192 md5sum -c ori.md5 # Use existed text file. It's not in alignment. @@ -341,13 +341,13 @@ hw_dfl_hw_ifl() prepare_src_file $1 md5sum origin > ori.md5 - #hw_blk_deflate origin /tmp/ori.gz gzip -b 8192 - #hw_blk_inflate /tmp/ori.gz origin gzip -b 8192 + #hw_blk_deflate origin /tmp/ori.gz gzip --blksize 8192 + #hw_blk_inflate /tmp/ori.gz origin gzip --blksize 8192 #md5sum -c ori.md5 ${RM} -f /tmp/ori.gz - hw_strm_deflate origin /tmp/ori.gz gzip -b 8192 - hw_strm_inflate /tmp/ori.gz origin gzip -b 8192 + hw_strm_deflate origin /tmp/ori.gz gzip --blksize 8192 + hw_strm_inflate /tmp/ori.gz origin gzip --blksize 8192 md5sum -c ori.md5 } @@ -358,17 +358,17 @@ run_zip_test_v2() export WD_COMP_ASYNC_POLL_EN=1 export WD_COMP_ASYNC_POLL_NUM="4@0" # test without environment variables - # limit test file in 64MB + # limit test file in 8MB rm -fr /tmp/syslog - dd if=/var/log/syslog of=/tmp/syslog bs=1M count=16 >& /dev/null + dd if=/var/log/syslog of=/tmp/syslog bs=1M count=8 >& /dev/null sw_dfl_hw_ifl /tmp/syslog hw_dfl_sw_ifl /tmp/syslog WD_COMP_EPOLL_EN=1 hw_dfl_hw_ifl /tmp/syslog WD_COMP_EPOLL_EN=0 hw_dfl_hw_ifl /tmp/syslog # test without environment variables - #run_cmd zip_sva_perf -b 8192 -s 81920 -l 1000 --self + #run_cmd uadk_tool test --m zip --blksize 8192 --size 81920 --loop 1000 --self # test with environment variables - #run_cmd zip_sva_perf -b 8192 -s 81920 -l 1000 --self --env + #run_cmd uadk_tool test --m zip --blksize 8192 --size 81920 --loop 1000 --self --env } # Accept more paraterms -- 2.33.0

From: Hao Fang <fanghao11@huawei.com> The zip_sva_perf tool has been replaced by uadk_tool. Signed-off-by: Hao Fang <fanghao11@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- cleanup.sh | 5 +- configure.ac | 1 - test/Makefile.am | 4 - test/hisi_zip_test/Makefile.am | 23 - test/hisi_zip_test/test_lib.c | 1874 -------------------------------- test/hisi_zip_test/test_lib.h | 352 ------ test/hisi_zip_test/testsuit.c | 1844 ------------------------------- 7 files changed, 2 insertions(+), 4101 deletions(-) delete mode 100644 test/hisi_zip_test/Makefile.am delete mode 100644 test/hisi_zip_test/test_lib.c delete mode 100644 test/hisi_zip_test/test_lib.h delete mode 100644 test/hisi_zip_test/testsuit.c diff --git a/cleanup.sh b/cleanup.sh index 60adc988..b7997f2a 100755 --- a/cleanup.sh +++ b/cleanup.sh @@ -10,9 +10,8 @@ FILES="aclocal.m4 autom4te.cache compile config.guess config.h.in config.log \ ar-lib m4 Makefile.in missing src/Makefile src/Makefile.in \ test/Makefile test/Makefile.in test/hisi_hpre_test/Makefile.in \ test/hisi_hpre_test/Makefile test/hisi_sec_test/Makefile \ - test/hisi_sec_test/Makefile.in test/hisi_zip_test/Makefile \ - test/hisi_zip_test/Makefile.in uadk_tool/Makefile \ - uadk_tool/Makefile.in \ + test/hisi_sec_test/Makefile.in \ + uadk_tool/Makefile uadk_tool/Makefile.in \ v1/Makefile.in v1/Makefile.in v1/test/Makefile v1/test/Makefile.in \ v1/test/test_mm/Makefile v1/test/test_mm/Makefile.in \ v1/test/bmm_test/Makefile v1/test/bmm_test/Makefile.in" diff --git a/configure.ac b/configure.ac index de70457a..f5c625cc 100644 --- a/configure.ac +++ b/configure.ac @@ -95,7 +95,6 @@ AC_CONFIG_FILES([Makefile lib/libwd_crypto.pc lib/libwd_comp.pc lib/libwd.pc test/Makefile test/hisi_hpre_test/Makefile - test/hisi_zip_test/Makefile uadk_tool/Makefile sample/Makefile v1/test/Makefile diff --git a/test/Makefile.am b/test/Makefile.am index 5666000c..c7918f32 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,8 +16,4 @@ SUBDIRS = . if HAVE_CRYPTO SUBDIRS += hisi_hpre_test -if HAVE_ZLIB -SUBDIRS += hisi_zip_test -endif - endif diff --git a/test/hisi_zip_test/Makefile.am b/test/hisi_zip_test/Makefile.am deleted file mode 100644 index 8b464f58..00000000 --- a/test/hisi_zip_test/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -AM_CFLAGS=-Wall -Werror -fno-strict-aliasing -I$(top_srcdir)/include -AUTOMAKE_OPTIONS = subdir-objects - -bin_PROGRAMS=zip_sva_perf - -zip_sva_perf_SOURCES=testsuit.c test_lib.c - -if WD_STATIC_DRV -zip_sva_perf_LDADD=../../.libs/libwd.a ../../.libs/libwd_comp.a \ - ../../.libs/libhisi_zip.a -ldl -lpthread -lnuma $(libcrypto_LIBS) -else -zip_sva_perf_LDADD=-L../../.libs -l:libwd.so.2 -l:libwd_comp.so.2 \ - -lpthread -lnuma $(libcrypto_LIBS) -endif -zip_sva_perf_LDFLAGS=-Wl,-rpath,'/usr/local/lib' - -# For statistics -zip_sva_perf_LDADD+=-lm - -if HAVE_ZLIB -zip_sva_perf_LDADD+=-lz -zip_sva_perf_CPPFLAGS=-DUSE_ZLIB -endif diff --git a/test/hisi_zip_test/test_lib.c b/test/hisi_zip_test/test_lib.c deleted file mode 100644 index 384be496..00000000 --- a/test/hisi_zip_test/test_lib.c +++ /dev/null @@ -1,1874 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright 2020-2021 Huawei Technologies Co.,Ltd. All rights reserved. - * Copyright 2020-2021 Linaro ltd. - */ - -#include <pthread.h> -#include <signal.h> -#include <math.h> -#include <sys/mman.h> -#include <zlib.h> - -#include "test_lib.h" - -#define SCHED_RR_NAME "sched_rr" - -struct check_rand_ctx { - int off; - unsigned long global_off; - __u32 last; - unsigned short state[3]; -}; - -#define dbg(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__) - -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_spinlock_t lock; -static int count = 0; - -static struct wd_ctx_config *g_conf; - -int sum_pend = 0, sum_thread_end = 0; - -__attribute__((constructor)) -void lock_constructor(void) -{ - if (pthread_spin_init(&lock, PTHREAD_PROCESS_SHARED) != 0) - exit(1); -} - -__attribute__((destructor)) -void lock_destructor(void) -{ - if (pthread_spin_destroy(&lock) != 0) - exit(1); -} - -void *mmap_alloc(size_t len) -{ - void *p; - long page_size = sysconf(_SC_PAGESIZE); - - if (len % page_size) - return malloc(len); - - p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); - if (p == MAP_FAILED) - WD_ERR("Failed to allocate %zu bytes\n", len); - - return p == MAP_FAILED ? NULL : p; -} - -int mmap_free(void *addr, size_t len) -{ - long page_size = sysconf(_SC_PAGESIZE); - - if (len % page_size) { - free(addr); - return 0; - } - - return munmap(addr, len); -} - -static int hizip_check_rand(unsigned char *buf, unsigned int size, void *opaque) -{ - int i; - int *j; - __u32 n; - struct check_rand_ctx *rand_ctx = opaque; - - j = &rand_ctx->off; - for (i = 0; i < size; i += 4) { - if (*j) { - /* Something left from a previous run */ - n = rand_ctx->last; - } else { - n = nrand48(rand_ctx->state); - rand_ctx->last = n; - } - for (; *j < 4 && i + *j < size; (*j)++) { - char expected = (n >> (8 * *j)) & 0xff; - char actual = buf[i + *j]; - - if (expected != actual) { - WD_ERR("Invalid decompressed char at offset %lu: expected 0x%x != 0x%x\n", - rand_ctx->global_off + i + *j, expected, - actual); - return -EINVAL; - } - } - if (*j == 4) - *j = 0; - } - rand_ctx->global_off += size; - return 0; -} - -static struct wd_datalist *get_datalist(void *addr, __u32 size) -{ - int count = (int)ceil((double)size / SGE_SIZE); - struct wd_datalist *head, *cur, *tmp; - int i; - - head = calloc(1, sizeof(struct wd_datalist)); - if (!head) { - WD_ERR("failed to alloc datalist head\n"); - return NULL; - } - - cur = head; - - for (i = 0; i < count; i++) { - cur->data = addr; - cur->len = (size > SGE_SIZE) ? SGE_SIZE : size; - addr += SGE_SIZE; - size -= SGE_SIZE; - if (i != count - 1) { - tmp = calloc(1, sizeof(struct wd_datalist)); - cur->next = tmp; - cur = tmp; - } - } - - return head; -} - -/** - * compress() - compress memory buffer. - * @alg_type: alg_type. - * - * This function compress memory buffer. - */ -int hw_blk_compress(int alg_type, int blksize, __u8 data_fmt, void *priv, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen) -{ - handle_t h_sess; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - struct wd_datalist *list; - struct wd_comp_req req; - int ret = 0; - - setup.alg_type = alg_type; - setup.op_type = WD_DIR_COMPRESS; - setup.comp_lv = WD_COMP_L8; - setup.win_sz = WD_COMP_WS_8K; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) { - fprintf(stderr,"fail to alloc comp sess!\n"); - return -EINVAL; - } - - if (data_fmt) { - WD_ERR("now sge size is %u\n", SGE_SIZE); - list = get_datalist(src, (__u32)srclen); - req.list_src = list; - list = get_datalist(dst, (__u32)*dstlen); - req.list_dst = list; - } else { - req.src = src; - req.dst = dst; - } - - req.src_len = srclen; - req.dst_len = *dstlen; - req.op_type = WD_DIR_COMPRESS; - req.cb = NULL; - req.data_fmt = data_fmt; - req.priv = priv; - - dbg("%s:input req: src_len: %d, dst_len:%d, data_fmt:%d\n", - __func__, req.src_len, req.dst_len, req.data_fmt); - - ret = wd_do_comp_sync(h_sess, &req); - if (ret < 0) { - fprintf(stderr,"fail to do comp sync(ret = %d)!\n", ret); - return ret; - } - - if (req.status) { - fprintf(stderr,"fail to do comp sync(status = %d)!\n", - req.status); - wd_comp_free_sess(h_sess); - return req.status; - } - *dstlen = req.dst_len; - - dbg("%s:input req: src_len: %d, dst_len:%d, data_fmt:%d\n", - __func__, req.src_len, req.dst_len, req.data_fmt); - - wd_comp_free_sess(h_sess); - - return ret; -} - -int hw_blk_decompress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen) -{ - handle_t h_sess; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - struct wd_datalist *list; - struct wd_comp_req req; - int ret = 0; - - setup.alg_type = alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) { - fprintf(stderr,"fail to alloc comp sess!\n"); - return -EINVAL; - } - - if (data_fmt) { - WD_ERR("now sge size is %u\n", SGE_SIZE); - list = get_datalist(src, (__u32)srclen); - req.list_src = list; - list = get_datalist(dst, (__u32)*dstlen); - req.list_dst = list; - } else { - req.src = src; - req.dst = dst; - } - - req.src_len = srclen; - req.dst_len = *dstlen; - req.op_type = WD_DIR_DECOMPRESS; - req.cb = NULL; - req.data_fmt = data_fmt; - - dbg("%s:input req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - - ret = wd_do_comp_sync(h_sess, &req); - if (ret < 0) { - fprintf(stderr,"fail to do comp sync(ret = %d)!\n", ret); - return ret; - } - - if (req.status) { - fprintf(stderr,"fail to do comp sync(status = %d)!\n", - req.status); - wd_comp_free_sess(h_sess); - return req.status; - } - *dstlen = req.dst_len; - - dbg("%s:output req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - wd_comp_free_sess(h_sess); - - return ret; -} - -int hw_stream_compress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen) -{ - handle_t h_sess; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - struct wd_comp_req req; - int ret = 0; - - setup.alg_type = alg_type; - setup.op_type = WD_DIR_COMPRESS; - setup.comp_lv = WD_COMP_L8; - setup.win_sz = WD_COMP_WS_8K; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) { - fprintf(stderr,"fail to alloc comp sess!\n"); - return -EINVAL; - } - req.src = src; - req.src_len = srclen; - req.dst = dst; - req.dst_len = *dstlen; - req.op_type = WD_DIR_COMPRESS; - req.cb = NULL; - req.data_fmt = data_fmt; - - dbg("%s:input req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - ret = wd_do_comp_sync2(h_sess, &req); - if (ret < 0) { - fprintf(stderr,"fail to do comp sync(ret = %d)!\n", ret); - return ret; - } - - if (req.status) { - fprintf(stderr,"fail to do comp sync(status = %d)!\n", - req.status); - wd_comp_free_sess(h_sess); - return req.status; - } - *dstlen = req.dst_len; - - dbg("%s:output req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - wd_comp_free_sess(h_sess); - - return ret; -} - - -int hw_stream_decompress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen) -{ - handle_t h_sess; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - struct wd_comp_req req; - int ret = 0; - - - setup.alg_type = alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) { - fprintf(stderr,"fail to alloc comp sess!\n"); - return -EINVAL; - } - req.src = src; - req.src_len = srclen; - req.dst = dst; - req.dst_len = *dstlen; - req.op_type = WD_DIR_DECOMPRESS; - req.cb = NULL; - req.data_fmt = data_fmt; - - dbg("%s:input req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - - ret = wd_do_comp_sync2(h_sess, &req); - if (ret < 0) { - fprintf(stderr,"fail to do comp sync(ret = %d)!\n", ret); - return ret; - } - - if (req.status) { - fprintf(stderr,"fail to do comp sync(status = %d)!\n", - req.status); - wd_comp_free_sess(h_sess); - return req.status; - } - *dstlen = req.dst_len; - - dbg("%s:output req: src:%p, dst:%p,src_len: %d, dst_len:%d\n", - __func__, req.src, req.dst, req.src_len, req.dst_len); - - wd_comp_free_sess(h_sess); - - return ret; -} - -void hizip_prepare_random_input_data(char *buf, size_t len, size_t block_size) -{ - __u32 seed = 0; - unsigned short rand_state[3] = {(seed >> 16) & 0xffff, seed & 0xffff, 0x330e}; - - unsigned long remain_size; - __u32 size; - size_t i, j; - - /* - * TODO: change state for each buffer, to make sure there is no TLB - * aliasing. - */ - remain_size = len; - - while (remain_size > 0) { - if (remain_size > block_size) - size = block_size; - else - size = remain_size; - /* - * Prepare the input buffer with a reproducible sequence of - * numbers. nrand48() returns a pseudo-random number in the - * interval [0; 2^31). It's not really possible to compress a - * pseudo-random stream using deflate, since it can't find any - * string repetition. As a result the output size is bigger, - * with a ratio of 1.041. - */ - for (i = 0; i < size; i += 4) { - __u64 n = nrand48(rand_state); - - for (j = 0; j < 4 && i + j < size; j++) - buf[i + j] = (n >> (8 * j)) & 0xff; - } - - buf += size; - remain_size -= size; - } -} - -int hizip_prepare_random_compressed_data(char *buf, size_t out_len, size_t in_len, - size_t *produced, - struct test_options *opts) -{ - off_t off; - int ret = -EINVAL; - void *init_buf = mmap_alloc(in_len); - size_t in_block_size = opts->block_size; - size_t out_block_size = 2 * in_block_size; - - if (!init_buf) - return -ENOMEM; - - hizip_prepare_random_input_data(init_buf, in_len, opts->block_size); - - /* Compress each chunk separately since we're working in stateless mode */ - for (off = 0; off < in_len; off += in_block_size) { - ret = zlib_deflate(buf, out_block_size, init_buf + off, - in_block_size, produced, opts->alg_type); - if (ret) - break; - buf += out_block_size; - } - - munmap(init_buf, in_len); - return ret; -} - -int hizip_verify_random_output(struct test_options *opts, - struct hizip_test_info *info, - size_t out_sz) -{ - int ret; - int seed = 0; - off_t off = 0; - size_t checked = 0; - size_t total_checked = 0; - struct check_rand_ctx rand_ctx = { - .state = {(seed >> 16) & 0xffff, seed & 0xffff, 0x330e}, - }; - - if (!opts->verify) - return 0; - - if (opts->op_type == WD_DIR_DECOMPRESS) - /* Check plain output */ - return hizip_check_rand((void *)info->out_buf, out_sz, - &rand_ctx); - - do { - ret = hizip_check_output(info->out_buf + off, out_sz, - &checked, hizip_check_rand, &rand_ctx); - if (ret) { - WD_ERR("Check output failed with %d\n", ret); - return ret; - } - total_checked += checked; - off += opts->block_size * EXPANSION_RATIO; - } while (!ret && total_checked < opts->total_len); - - if (rand_ctx.global_off != opts->total_len) { - WD_ERR("Invalid output size %lu != %lu\n", - rand_ctx.global_off, opts->total_len); - return -EINVAL; - } - return 0; -} - -static void *async_cb(struct wd_comp_req *req, void *data) -{ - return NULL; -} - -void *send_thread_func(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - size_t src_block_size, dst_block_size; - struct wd_comp_sess_setup setup; - struct sched_params param = {0}; - handle_t h_sess; - int j, ret; - size_t left; - - if (opts->op_type == WD_DIR_COMPRESS) { - src_block_size = opts->block_size; - dst_block_size = opts->block_size * EXPANSION_RATIO; - } else { - src_block_size = opts->block_size * EXPANSION_RATIO; - dst_block_size = opts->block_size; - } - - memset(&setup, 0, sizeof(struct wd_comp_sess_setup)); - setup.alg_type = opts->alg_type; - setup.op_type = opts->op_type; - setup.comp_lv = WD_COMP_L8; - setup.win_sz = WD_COMP_WS_8K; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_sess = wd_comp_alloc_sess(&setup); - if (!h_sess) - return NULL; - - for (j = 0; j < opts->compact_run_num; j++) { - if (opts->option & TEST_ZLIB) { - ret = zlib_deflate(info->out_buf, info->out_size, - info->in_buf, info->in_size, - &tdata->sum, opts->alg_type); - continue; - } - /* not TEST_ZLIB */ - left = opts->total_len; - tdata->req.op_type = opts->op_type; - tdata->req.src = info->in_buf; - tdata->req.dst = info->out_buf; - tdata->sum = 0; - while (left > 0) { - tdata->req.src_len = src_block_size; - tdata->req.dst_len = dst_block_size; - tdata->req.cb_param = &tdata->req; - if (opts->sync_mode) { - tdata->req.cb = async_cb; - count++; - ret = wd_do_comp_async(h_sess, &tdata->req); - } else { - tdata->req.cb = NULL; - ret = wd_do_comp_sync(h_sess, &tdata->req); - if (info->opts->faults & INJECT_SIG_WORK) - kill(getpid(), SIGTERM); - } - if (ret < 0) { - WD_ERR("do comp test fail with %d\n", ret); - return (void *)(uintptr_t)ret; - } else if (tdata->req.status) { - return (void *)(uintptr_t)tdata->req.status; - } - if (opts->op_type == WD_DIR_COMPRESS) - left -= src_block_size; - else - left -= dst_block_size; - tdata->req.src += src_block_size; - /* - * It's BLOCK (STATELESS) mode, so user needs to - * combine output buffer by himself. - */ - tdata->req.dst += dst_block_size; - tdata->sum += tdata->req.dst_len; - if (tdata->sum > info->out_size) { - fprintf(stderr, - "%s: exceed OUT limits (%ld > %ld)\n", - __func__, - tdata->sum, info->out_size); - break; - } - } - /* info->total_out are accessed by multiple threads */ - __atomic_add_fetch(&info->total_out, tdata->sum, - __ATOMIC_RELEASE); - } - wd_comp_free_sess(h_sess); - return NULL; -} - -int lib_poll_func(__u32 pos, __u32 expect, __u32 *count) -{ - int ret; - - ret = wd_comp_poll_ctx(pos, expect, count); - if (ret < 0) - return ret; - return 0; -} - -void *poll_thread_func(void *arg) -{ - struct hizip_test_info *info = (struct hizip_test_info *)arg; - int ret = 0, total = 0; - __u32 expected = 0, received; - - if (!info->opts->sync_mode) - return NULL; - while (1) { - if (info->opts->faults & INJECT_SIG_WORK) - kill(getpid(), SIGTERM); - - pthread_mutex_lock(&mutex); - if (!expected) - expected = 1; - if (count == 0) { - pthread_mutex_unlock(&mutex); - usleep(10); - continue; - } - expected = 1; - received = 0; - ret = wd_comp_poll(expected, &received); - if (ret == 0) - total += received; - if (count == total) { - pthread_mutex_unlock(&mutex); - break; - } else { - if (count > total) - expected = count - total; - pthread_mutex_unlock(&mutex); - usleep(10); - } - } - pthread_exit(NULL); -} - -int create_send_threads(struct test_options *opts, - struct hizip_test_info *info, - void *(*send_thread_func)(void *arg)) -{ - pthread_attr_t attr; - thread_data_t *tdatas; - int i, j, num, ret; - - num = opts->thread_num; - info->send_tds = calloc(1, sizeof(pthread_t) * num); - if (!info->send_tds) - return -ENOMEM; - info->send_tnum = num; - tdatas = calloc(1, sizeof(thread_data_t) * num); - if (!tdatas) { - ret = -ENOMEM; - goto out; - } - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - for (i = 0; i < num; i++) { - tdatas[i].info = info; - ret = pthread_create(&info->send_tds[i], &attr, - send_thread_func, &tdatas[i]); - if (ret < 0) { - fprintf(stderr, "Fail to create send thread %d (%d)\n", - i, ret); - goto out_thd; - } - } - pthread_attr_destroy(&attr); - g_conf = &info->ctx_conf; - return 0; -out_thd: - for (j = 0; j < i; j++) - pthread_cancel(info->send_tds[j]); - free(tdatas); -out: - free(info->send_tds); - return ret; -} - -int create_poll_threads(struct hizip_test_info *info, - void *(*poll_thread_func)(void *arg), - int num) -{ - struct test_options *opts = info->opts; - pthread_attr_t attr; - int i, ret; - - if (!opts->sync_mode) - return 0; - info->poll_tds = calloc(1, sizeof(pthread_t) * num); - if (!info->poll_tds) - return -ENOMEM; - info->poll_tnum = num; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - for (i = 0; i < num; i++) { - ret = pthread_create(&info->poll_tds[i], &attr, - poll_thread_func, info); - if (ret < 0) { - fprintf(stderr, "Fail to create send thread %d (%d)\n", - i, ret); - goto out; - } - } - pthread_attr_destroy(&attr); - count = 0; - return 0; -out: - free(info->poll_tds); - return ret; -} - -void free_threads(struct hizip_test_info *info) -{ - if (info->send_tds) - free(info->send_tds); - if (info->poll_tds) - free(info->poll_tds); -} - -int attach_threads(struct test_options *opts, struct hizip_test_info *info) -{ - int i, ret; - void *tret; - - if (opts->sync_mode) { - for (i = 0; i < info->poll_tnum; i++) { - ret = pthread_join(info->poll_tds[i], NULL); - if (ret < 0) - fprintf(stderr, "Fail on poll thread with %d\n", - ret); - } - } - for (i = 0; i < info->send_tnum; i++) { - ret = pthread_join(info->send_tds[i], &tret); - if (ret < 0) - fprintf(stderr, "Fail on send thread with %d\n", ret); - } - return (int)(uintptr_t)tret; -} - -void gen_random_data(void *buf, size_t len) -{ - int i; - uint32_t seed = 0; - unsigned short rand_state[3] = {(seed >> 16) & 0xffff, - seed & 0xffff, - 0x330e}; - - for (i = 0; i < len >> 3; i++) - *((uint64_t *)buf + i) = nrand48(rand_state); -} - -int calculate_md5(comp_md5_t *md5, const void *buf, size_t len) -{ - if (!md5 || !buf || !len) - return -EINVAL; - MD5_Init(&md5->md5_ctx); - MD5_Update(&md5->md5_ctx, buf, len); - MD5_Final(md5->md, &md5->md5_ctx); - return 0; -} - -void dump_md5(comp_md5_t *md5) -{ - int i; - - for (i = 0; i < MD5_DIGEST_LENGTH - 1; i++) - printf("%02x-", md5->md[i]); - printf("%02x\n", md5->md[i]); -} - -int cmp_md5(comp_md5_t *orig, comp_md5_t *final) -{ - int i; - - if (!orig || !final) - return -EINVAL; - for (i = 0; i < MD5_DIGEST_LENGTH; i++) { - if (orig->md[i] != final->md[i]) { - printf("Original MD5: "); - dump_md5(orig); - printf("Final MD5: "); - dump_md5(final); - return -EINVAL; - } - } - return 0; -} - -static void *async2_cb(struct wd_comp_req *req, void *data) -{ - sem_t *sem = (sem_t *)data; - - if (sem) - sem_post(sem); - return NULL; -} - -/* used in BATCH mode */ -static void *async5_cb(struct wd_comp_req *req, void *data) -{ - thread_data_t *tdata = (thread_data_t *)data; - - pthread_spin_lock(&lock); - tdata->pcnt++; - if (tdata->batch_flag && (tdata->pcnt == tdata->bcnt)) { - tdata->pcnt = 0; - tdata->bcnt = 0; - tdata->batch_flag = 0; - pthread_spin_unlock(&lock); - sem_post(&tdata->sem); - } else - pthread_spin_unlock(&lock); - return NULL; -} - -void init_chunk_list(chunk_list_t *list, void *buf, size_t buf_sz, - size_t chunk_sz) -{ - chunk_list_t *p = NULL; - int i, count; - size_t sum; - - count = (buf_sz + chunk_sz - 1) / chunk_sz; - for (i = 0, sum = 0, p = list; i < count && sum <= buf_sz; i++, p++) { - p->addr = buf + sum; - p->size = MIN(buf_sz - sum, chunk_sz); - if (i == count - 1) - p->next = NULL; - else - p->next = p + 1; - sum += p->size; - } -} - -chunk_list_t *create_chunk_list(void *buf, size_t buf_sz, size_t chunk_sz) -{ - chunk_list_t *list; - int count; - - count = (buf_sz + chunk_sz - 1) / chunk_sz; - if (count > HIZIP_CHUNK_LIST_ENTRIES) - count = HIZIP_CHUNK_LIST_ENTRIES; - if (buf_sz / chunk_sz > count) - return NULL; - /* allocate entries with additional one */ - list = malloc(sizeof(chunk_list_t) * (count + 1)); - if (!list) - return NULL; - init_chunk_list(list, buf, buf_sz, chunk_sz); - return list; -} - -void free_chunk_list(chunk_list_t *list) -{ - free(list); -} - -/* - * Deflate a data block with compressed header. - */ -static int chunk_deflate2(void *in, size_t in_sz, void *out, size_t *out_sz, - struct test_options *opts) -{ - int alg_type = opts->alg_type; - z_stream strm; - int windowBits; - int ret; - - switch (alg_type) { - case WD_ZLIB: - windowBits = 15; - break; - case WD_DEFLATE: - windowBits = -15; - break; - case WD_GZIP: - windowBits = 15 + 16; - break; - default: - printf("algorithm %d unsupported by zlib\n", alg_type); - return -EINVAL; - } - memset(&strm, 0, sizeof(z_stream)); - strm.next_in = in; - strm.avail_in = in_sz; - strm.next_out = out; - strm.avail_out = *out_sz; - - ret = deflateInit2(&strm, Z_BEST_SPEED, Z_DEFLATED, windowBits, - 8, Z_DEFAULT_STRATEGY); - if (ret != Z_OK) { - printf("deflateInit2: %d\n", ret); - return -EINVAL; - } - - do { - ret = deflate(&strm, Z_FINISH); - if ((ret == Z_STREAM_ERROR) || (ret == Z_BUF_ERROR)) { - printf("defalte error %d - %s\n", ret, strm.msg); - ret = -ENOSR; - break; - } else if (!strm.avail_in) { - if (ret != Z_STREAM_END) - printf("deflate unexpected return: %d\n", ret); - ret = 0; - break; - } else if (!strm.avail_out) { - printf("deflate out of memory\n"); - ret = -ENOSPC; - break; - } - } while (ret == Z_OK); - - deflateEnd(&strm); - *out_sz = *out_sz - strm.avail_out; - return ret; -} - - -/* - * This function is used in BLOCK mode. Each compressing in BLOCK mode - * produces compression header. - */ -static int chunk_inflate2(void *in, size_t in_sz, void *out, size_t *out_sz, - struct test_options *opts) -{ - z_stream strm; - int ret; - - memset(&strm, 0, sizeof(z_stream)); - /* Window size of 15, +32 for auto-decoding gzip/zlib */ - ret = inflateInit2(&strm, 15 + 32); - if (ret != Z_OK) { - printf("zlib inflateInit: %d\n", ret); - return -EINVAL; - } - - strm.next_in = in; - strm.avail_in = in_sz; - strm.next_out = out; - strm.avail_out = *out_sz; - do { - ret = inflate(&strm, Z_NO_FLUSH); - if ((ret < 0) || (ret == Z_NEED_DICT)) { - printf("zlib error %d - %s\n", ret, strm.msg); - goto out; - } - if (!strm.avail_out) { - if (!strm.avail_in || (ret == Z_STREAM_END)) - break; - printf("%s: avail_out is empty!\n", __func__); - goto out; - } - } while (strm.avail_in && (ret != Z_STREAM_END)); - inflateEnd(&strm); - *out_sz = *out_sz - strm.avail_out; - return 0; -out: - inflateEnd(&strm); - ret = -EINVAL; - return ret; -} - -/* - * Compress a list of chunk data and produce a list of chunk data by software. - * in_list & out_list should be formated first. - */ -int sw_deflate2(chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts) -{ - chunk_list_t *p, *q; - int ret = -EINVAL; - - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - ret = chunk_deflate2(p->addr, p->size, q->addr, &q->size, - opts); - if (ret) - return ret; - } - return ret; -} - -/* - * Compress a list of chunk data and produce a list of chunk data by software. - * in_list & out_list should be formated first. - */ -int sw_inflate2(chunk_list_t *in_list, chunk_list_t *out_list, - struct test_options *opts) -{ - chunk_list_t *p, *q; - int ret = -EINVAL; - - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - ret = chunk_inflate2(p->addr, p->size, q->addr, &q->size, - opts); - if (ret) - return ret; - } - return ret; -} - -int hw_deflate4(handle_t h_dfl, - chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts, - sem_t *sem) -{ - struct wd_comp_req *reqs; - chunk_list_t *p = in_list, *q = out_list; - int i, ret; - - if (!in_list || !out_list || !opts || !sem) - return -EINVAL; - /* reqs array could make async operations in parallel */ - reqs = malloc(sizeof(struct wd_comp_req) * HIZIP_CHUNK_LIST_ENTRIES); - if (!reqs) - return -ENOMEM; - - for (i = 0; p && q; p = p->next, q = q->next, i++) { - reqs[i].src = p->addr; - reqs[i].src_len = p->size; - reqs[i].dst = q->addr; - reqs[i].dst_len = q->size; - reqs[i].op_type = WD_DIR_COMPRESS; - - if (opts->sync_mode) { - reqs[i].cb = async2_cb; - reqs[i].cb_param = sem; - } - do { - if (opts->sync_mode) { - ret = wd_do_comp_async(h_dfl, &reqs[i]); - if (!ret) { - __atomic_add_fetch(&sum_pend, 1, - __ATOMIC_ACQ_REL); - sem_wait(sem); - } - } else - ret = wd_do_comp_sync(h_dfl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret) - goto out; - q->size = reqs[i].dst_len; - /* make sure olist has the same length with ilist */ - if (!p->next) - q->next = NULL; - i++; - } - free(reqs); - return 0; -out: - free(reqs); - return ret; -} - -int hw_inflate4(handle_t h_ifl, - chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts, - sem_t *sem) -{ - struct wd_comp_req *reqs; - chunk_list_t *p, *q; - int i = 0, ret; - - /* reqs array could make async operations in parallel */ - reqs = calloc(1, sizeof(struct wd_comp_req) * HIZIP_CHUNK_LIST_ENTRIES); - if (!reqs) - return -ENOMEM; - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - reqs[i].src = p->addr; - reqs[i].src_len = p->size; - reqs[i].dst = q->addr; - reqs[i].dst_len = q->size; - reqs[i].op_type = WD_DIR_DECOMPRESS; - if (opts->sync_mode) { - reqs[i].cb = async2_cb; - reqs[i].cb_param = sem; - } - do { - if (opts->sync_mode) { - ret = wd_do_comp_async(h_ifl, &reqs[i]); - if (!ret) { - __atomic_add_fetch(&sum_pend, 1, - __ATOMIC_ACQ_REL); - sem_wait(sem); - } - } else - ret = wd_do_comp_sync(h_ifl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret) - goto out; - q->size = reqs[i].dst_len; - /* make sure olist has the same length with ilist */ - if (!p->next) - q->next = NULL; - i++; - } - free(reqs); - return 0; -out: - free(reqs); - return ret; -} - -/* used in BATCH mode */ -int hw_deflate5(handle_t h_dfl, - chunk_list_t *in_list, - chunk_list_t *out_list, - thread_data_t *tdata) -{ - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_req *reqs = tdata->reqs; - chunk_list_t *p = in_list, *q = out_list; - int i = 0, ret = 0; - - if (!in_list || !out_list || !opts) - return -EINVAL; - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - reqs[i].src = p->addr; - reqs[i].src_len = p->size; - reqs[i].dst = q->addr; - reqs[i].dst_len = q->size; - reqs[i].op_type = WD_DIR_COMPRESS; - reqs[i].data_fmt = opts->data_fmt; - if (opts->sync_mode) { - reqs[i].cb = async5_cb; - reqs[i].cb_param = tdata; - } else { - reqs[i].cb = NULL; - reqs[i].cb_param = NULL; - } - if (opts->sync_mode) { - do { - ret = wd_do_comp_async(h_dfl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret < 0) - goto out; - __atomic_add_fetch(&sum_pend, 1, __ATOMIC_ACQ_REL); - pthread_spin_lock(&lock); - tdata->bcnt++; - if (((i + 1) == opts->batch_num) || !p->next) { - tdata->batch_flag = 1; - pthread_spin_unlock(&lock); - sem_wait(&tdata->sem); - } else - pthread_spin_unlock(&lock); - } else { - do { - ret = wd_do_comp_sync(h_dfl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret) - goto out; - } - q->size = reqs[i].dst_len; - i = (i + 1) % opts->batch_num; - /* make sure olist has the same length with ilist */ - if (!p->next) - q->next = NULL; - } - return 0; -out: - return ret; -} - -/* used in BATCH mode */ -int hw_inflate5(handle_t h_ifl, - chunk_list_t *in_list, - chunk_list_t *out_list, - thread_data_t *tdata) -{ - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_req *reqs = tdata->reqs; - chunk_list_t *p = in_list, *q = out_list; - int ret = 0, i = 0; - - if (!in_list || !out_list || !opts) - return -EINVAL; - for (p = in_list, q = out_list; p && q; p = p->next, q = q->next) { - reqs[i].src = p->addr; - reqs[i].src_len = p->size; - reqs[i].dst = q->addr; - reqs[i].dst_len = q->size; - reqs[i].op_type = WD_DIR_DECOMPRESS; - reqs[i].data_fmt = opts->data_fmt; - if (opts->sync_mode) { - reqs[i].cb = async5_cb; - reqs[i].cb_param = tdata; - } else { - reqs[i].cb = NULL; - reqs[i].cb_param = NULL; - } - if (opts->sync_mode) { - do { - ret = wd_do_comp_async(h_ifl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret < 0) - goto out; - __atomic_add_fetch(&sum_pend, 1, __ATOMIC_ACQ_REL); - pthread_spin_lock(&lock); - tdata->bcnt++; - if (((i + 1) == opts->batch_num) || !p->next) { - tdata->batch_flag = 1; - pthread_spin_unlock(&lock); - sem_wait(&tdata->sem); - } else - pthread_spin_unlock(&lock); - } else { - do { - ret = wd_do_comp_sync(h_ifl, &reqs[i]); - } while (ret == -WD_EBUSY); - if (ret) - goto out; - } - q->size = reqs[i].dst_len; - i = (i + 1) % opts->batch_num; - /* make sure olist has the same length with ilist */ - if (!p->next) - q->next = NULL; - } - return 0; -out: - return ret; -} - -/* - * info->in_buf & info->out_buf should be allocated first. - * Thread 0 shares info->out_buf. Other threads need to create its own - * dst buffer. - */ -int create_send_tdata(struct test_options *opts, - struct hizip_test_info *info) -{ - thread_data_t *tdata; - chunk_list_t *in_list, *out_list; - int i, j, num, ret; - - if (!opts || !info || !info->in_chunk_sz || !info->out_chunk_sz) - return -EINVAL; - num = opts->thread_num; - info->send_tds = calloc(1, sizeof(pthread_t) * num); - if (!info->send_tds) - return -ENOMEM; - info->send_tnum = num; - info->tdatas = calloc(1, sizeof(thread_data_t) * num); - if (!info->tdatas) { - ret = -ENOMEM; - goto out; - } - if (!opts->batch_num) - opts->batch_num = 1; - else if (opts->batch_num > HIZIP_CHUNK_LIST_ENTRIES) - opts->batch_num = HIZIP_CHUNK_LIST_ENTRIES; - if (opts->is_stream) { - in_list = create_chunk_list(info->in_buf, info->in_size, - info->in_size); - } else { - in_list = create_chunk_list(info->in_buf, info->in_size, - info->in_chunk_sz); - } - if (!in_list) { - ret = -EINVAL; - goto out_in; - } - if (opts->option & TEST_THP) { - ret = madvise(info->in_buf, info->in_size, MADV_HUGEPAGE); - if (ret) { - printf("madvise(MADV_HUGEPAGE)"); - goto out_in; - } - } - for (i = 0; i < num; i++) { - tdata = &info->tdatas[i]; - /* src address is shared among threads */ - tdata->tid = i; - tdata->src_sz = info->in_size; - tdata->src = info->in_buf; - tdata->in_list = in_list; - tdata->dst_sz = info->out_size; - tdata->dst = mmap_alloc(tdata->dst_sz); - if (!tdata->dst) { - ret = -ENOMEM; - goto out_dst; - } - if (opts->option & TEST_THP) { - ret = madvise(tdata->dst, tdata->dst_sz, MADV_HUGEPAGE); - if (ret) { - printf("madvise(MADV_HUGEPAGE)"); - goto out_dst; - } - } - /* - * Without memset, valgrind reports uninitialized buf - * for writing to file. - */ - memset(tdata->dst, 0, tdata->dst_sz); - if (opts->is_stream) { - out_list = create_chunk_list(tdata->dst, - tdata->dst_sz, - tdata->dst_sz); - } else { - out_list = create_chunk_list(tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - } - tdata->out_list = out_list; - if (!tdata->out_list) { - ret = -EINVAL; - goto out_list; - } - calculate_md5(&tdata->md5, tdata->src, tdata->src_sz); - tdata->reqs = malloc(sizeof(struct wd_comp_req) * - opts->batch_num); - if (!tdata->reqs) - goto out_list; - sem_init(&tdata->sem, 0, 0); - tdata->info = info; - } - return 0; -out_list: - mmap_free(tdata->dst, tdata->dst_sz); -out_dst: - for (j = 0; j < i; j++) { - pthread_cancel(info->send_tds[j]); - free_chunk_list(info->tdatas[j].out_list); - mmap_free(info->tdatas[j].dst, info->tdatas[j].dst_sz); - } - free_chunk_list(in_list); -out_in: - free(info->tdatas); -out: - free(info->send_tds); - return ret; -} - -int create_poll_tdata(struct test_options *opts, - struct hizip_test_info *info, - int poll_num) -{ - thread_data_t *tdatas; - int i, ret; - - if (opts->sync_mode == 0) - return 0; - else if (poll_num <= 0) - return -EINVAL; - info->poll_tnum = poll_num; - info->poll_tds = calloc(1, sizeof(pthread_t) * poll_num); - if (!info->poll_tds) - return -ENOMEM; - info->p_tdatas = calloc(1, sizeof(thread_data_t) * poll_num); - if (!info->p_tdatas) { - ret = -ENOMEM; - goto out; - } - tdatas = info->p_tdatas; - for (i = 0; i < poll_num; i++) { - tdatas[i].tid = i; - tdatas[i].info = info; - } - return 0; -out: - free(info->poll_tds); - return ret; -} - -/* - * Free source and destination buffer contained in sending threads. - * Free sending threads and polling threads. - */ -void free2_threads(struct hizip_test_info *info) -{ - thread_data_t *tdatas = info->tdatas; - int i; - - if (info->send_tds) - free(info->send_tds); - if (info->poll_tds) { - free(info->poll_tds); - free(info->p_tdatas); - } - free_chunk_list(tdatas[0].in_list); - for (i = 0; i < info->send_tnum; i++) { - free_chunk_list(tdatas[i].out_list); - free(tdatas[i].reqs); - } - /* info->out_buf is bound to tdatas[0].dst */ - for (i = 0; i < info->send_tnum; i++) - mmap_free(tdatas[i].dst, tdatas[i].dst_sz); - free(info->tdatas); - mmap_free(info->in_buf, info->in_size); -} - -int attach2_threads(struct test_options *opts, - struct hizip_test_info *info, - void *(*send_thread_func)(void *arg), - void *(*poll_thread_func)(void *arg)) -{ - int i, j, ret, num; - void *tret; - pthread_attr_t attr; - - num = opts->thread_num; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - for (i = 0; i < num; i++) { - ret = pthread_create(&info->send_tds[i], &attr, - send_thread_func, &info->tdatas[i]); - if (ret < 0) { - printf("Fail to create send thread %d (%d)\n", i, ret); - goto out; - } - } - if (opts->sync_mode && !opts->use_env) { - for (i = 0; i < opts->poll_num; i++) { - ret = pthread_create(&info->poll_tds[i], &attr, - poll_thread_func, - &info->tdatas[i]); - if (ret < 0) { - printf("Fail to create poll thread %d (%d)\n", - i, ret); - goto out_poll; - } - } - for (i = 0; i < info->poll_tnum; i++) { - ret = pthread_join(info->poll_tds[i], &tret); - if (ret < 0) { - fprintf(stderr, "Fail on poll thread with %d\n", - ret); - goto out_poll; - } - } - } - for (i = 0; i < info->send_tnum; i++) { - ret = pthread_join(info->send_tds[i], &tret); - if (ret < 0) { - fprintf(stderr, "Fail on send thread with %d\n", ret); - goto out_poll; - } - } - pthread_attr_destroy(&attr); - return (int)(uintptr_t)tret; -out_poll: - for (j = 0; j < i; j++) - pthread_cancel(info->poll_tds[j]); - i = opts->thread_num; -out: - for (j = 0; j < i; j++) - pthread_cancel(info->send_tds[j]); - pthread_attr_destroy(&attr); - return ret; -} - -void *poll2_thread_func(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - __u32 received; - int ret = 0; - struct timeval start_tvl, end_tvl; - int pending; - int end_threads; - - gettimeofday(&start_tvl, NULL); - while (1) { - end_threads = __atomic_load_n(&sum_thread_end, - __ATOMIC_ACQUIRE); - pending = __atomic_load_n(&sum_pend, __ATOMIC_ACQUIRE); - if ((end_threads == info->send_tnum) && (pending == 0)) - break; - else if (pending == 0) - continue; - received = 0; - ret = wd_comp_poll(pending, &received); - if (ret == 0) { - __atomic_sub_fetch(&sum_pend, - received, - __ATOMIC_ACQ_REL); - } - } - gettimeofday(&end_tvl, NULL); - timersub(&end_tvl, &start_tvl, &start_tvl); - pthread_exit(NULL); -} - -/* - * Choose a device and check whether it can afford the requested contexts. - * Return a list whose the first device is chosen. - */ -struct uacce_dev_list *get_dev_list(struct test_options *opts, - int children) -{ - struct uacce_dev_list *list, *p, *head = NULL, *prev = NULL; - int max_q_num; - - list = wd_get_accel_list("zlib"); - if (!list) - return NULL; - - p = list; - /* Find one device matching the requested contexts. */ - while (p) { - max_q_num = wd_get_avail_ctx(p->dev); - /* - * Check whether there's enough contexts. - * There may be multiple taskes running together. - * The number of multiple taskes is specified in children. - */ - if (max_q_num < 4 * opts->q_num * children) { - if (!head) - head = p; - prev = p; - p = p->next; - } else - break; - } - - if (!p) { - WD_ERR("Request too much contexts: %d\n", - opts->q_num * 4 * children); - goto out; - } - - /* Adjust p to the head of list if p is in the middle. */ - if (p && (p != list)) { - prev->next = p->next; - p->next = head; - return p; - } - return list; -out: - wd_free_list_accels(list); - return NULL; -} - -/* - * Initialize context numbers by the four times of opts->q_num. - * [sync, async] * [compress, decompress] = 4 - */ -int init_ctx_config(struct test_options *opts, void *priv, - struct wd_sched **sched) -{ - struct hizip_test_info *info = priv; - struct wd_ctx_config *ctx_conf = &info->ctx_conf; - struct sched_params param; - int i, j, ret = -EINVAL; - int q_num = opts->q_num; - - - __atomic_store_n(&sum_pend, 0, __ATOMIC_RELEASE); - __atomic_store_n(&sum_thread_end, 0, __ATOMIC_RELEASE); - *sched = wd_sched_rr_alloc(SCHED_POLICY_RR, 2, 2, lib_poll_func); - if (!*sched) { - WD_ERR("wd_sched_rr_alloc fail\n"); - goto out_sched; - } - - (*sched)->name = SCHED_RR_NAME; - - memset(ctx_conf, 0, sizeof(struct wd_ctx_config)); - ctx_conf->ctx_num = q_num * 4; - ctx_conf->ctxs = calloc(1, q_num * 4 * sizeof(struct wd_ctx)); - if (!ctx_conf->ctxs) { - WD_ERR("Not enough memory to allocate contexts.\n"); - ret = -ENOMEM; - goto out_ctx; - } - for (i = 0; i < ctx_conf->ctx_num; i++) { - ctx_conf->ctxs[i].ctx = wd_request_ctx(info->list->dev); - if (!ctx_conf->ctxs[i].ctx) { - WD_ERR("Fail to allocate context #%d\n", i); - ret = -EINVAL; - goto out_req; - } - } - /* - * All contexts for 2 modes & 2 types. - * The test only uses one kind of contexts at the same time. - */ - for (i = 0; i < q_num; i++) { - ctx_conf->ctxs[i].ctx_mode = 0; - ctx_conf->ctxs[i].op_type = 0; - } - param.numa_id = 0; - param.mode = 0; - param.type = 0; - param.begin = 0; - param.end = q_num - 1; - ret = wd_sched_rr_instance((const struct wd_sched *)*sched, ¶m); - if (ret < 0) { - WD_ERR("Fail to fill sched region.\n"); - goto out_fill; - } - for (i = q_num; i < q_num * 2; i++) { - ctx_conf->ctxs[i].ctx_mode = 0; - ctx_conf->ctxs[i].op_type = 1; - } - param.mode = 0; - param.type = 1; - param.begin = q_num; - param.end = q_num * 2 - 1; - ret = wd_sched_rr_instance((const struct wd_sched *)*sched, ¶m); - if (ret < 0) { - WD_ERR("Fail to fill sched region.\n"); - goto out_fill; - } - for (i = q_num * 2; i < q_num * 3; i++) { - ctx_conf->ctxs[i].ctx_mode = 1; - ctx_conf->ctxs[i].op_type = 0; - } - param.mode = 1; - param.type = 0; - param.begin = q_num * 2; - param.end = q_num * 3 - 1; - ret = wd_sched_rr_instance((const struct wd_sched *)*sched, ¶m); - if (ret < 0) { - WD_ERR("Fail to fill sched region.\n"); - goto out_fill; - } - for (i = q_num * 3; i < q_num * 4; i++) { - ctx_conf->ctxs[i].ctx_mode = 1; - ctx_conf->ctxs[i].op_type = 1; - } - param.mode = 1; - param.type = 1; - param.begin = q_num * 3; - param.end = q_num * 4 - 1; - ret = wd_sched_rr_instance((const struct wd_sched *)*sched, ¶m); - if (ret < 0) { - WD_ERR("Fail to fill sched region.\n"); - goto out_fill; - } - - ret = wd_comp_init(ctx_conf, *sched); - if (ret) - goto out_fill; - return ret; - -out_fill: - for (i = 0; i < ctx_conf->ctx_num; j++) - wd_release_ctx(ctx_conf->ctxs[i].ctx); -out_req: - free(ctx_conf->ctxs); -out_ctx: - wd_sched_rr_release(*sched); -out_sched: - return ret; -} - -void uninit_config(void *priv, struct wd_sched *sched) -{ - struct hizip_test_info *info = priv; - struct wd_ctx_config *ctx_conf = &info->ctx_conf; - int i; - - wd_comp_uninit(); - for (i = 0; i < ctx_conf->ctx_num; i++) - wd_release_ctx(ctx_conf->ctxs[i].ctx); - free(ctx_conf->ctxs); - wd_sched_rr_release(sched); -} - - -int parse_common_option(const char opt, const char *optarg, - struct test_options *opts) -{ - switch (opt) { - case 'b': - opts->block_size = strtol(optarg, NULL, 0); - if (opts->block_size <= 0) - return 1; - break; - case 'l': - opts->compact_run_num = strtol(optarg, NULL, 0); - if (opts->compact_run_num <= 0) - return 1; - break; - case 'n': - opts->run_num = strtol(optarg, NULL, 0); - SYS_ERR_COND(opts->run_num > MAX_RUNS, - "No more than %d runs supported\n", MAX_RUNS); - if (opts->run_num <= 0) - return 1; - break; - case 'q': - opts->q_num = strtol(optarg, NULL, 0); - if (opts->q_num <= 0) - return 1; - break; - case 'd': - opts->op_type = WD_DIR_DECOMPRESS; - break; - case 'F': - opts->is_file = true; - break; - case 'S': - opts->is_stream = MODE_STREAM; - break; - case 's': - opts->total_len = strtol(optarg, NULL, 0); - SYS_ERR_COND(opts->total_len <= 0, "invalid size '%s'\n", - optarg); - break; - case 't': - opts->thread_num = strtol(optarg, NULL, 0); - SYS_ERR_COND(opts->thread_num < 0, "invalid thread num '%s'\n", - optarg); - break; - case 'm': - opts->sync_mode = strtol(optarg, NULL, 0); - SYS_ERR_COND(opts->sync_mode < 0 || opts->sync_mode > 1, - "invalid sync mode '%s'\n", optarg); - break; - case 'V': - opts->verify = true; - break; - case 'v': - opts->verbose = true; - break; - case 'a': - opts->alg_type = WD_DEFLATE; - break; - case 'z': - opts->alg_type = WD_ZLIB; - break; - case 'L': - opts->data_fmt = WD_SGL_BUF; - break; - case 'Z': - opts->alg_type = WD_LZ77_ZSTD; - break; - default: - return 1; - } - - return 0; -} - -#ifdef HAVE_ZLIB - -#include <zlib.h> - -/* - * Try to decompress a buffer using zLib's inflate(). Call compare_output with - * the decompressed stream as argument - * - * Return 0 on success, or an error. - */ -int hizip_check_output(void *buf, size_t size, size_t *checked, - check_output_fn compare_output, void *opaque) -{ - int ret, ret2; - unsigned char *out_buffer; - const size_t out_buf_size = 0x100000; - z_stream stream = { - .next_in = buf, - .avail_in = size, - }; - - out_buffer = calloc(1, out_buf_size); - if (!out_buffer) - return -ENOMEM; - - stream.next_out = out_buffer; - stream.avail_out = out_buf_size; - - /* Window size of 15, +32 for auto-decoding gzip/zlib */ - ret = inflateInit2(&stream, 15 + 32); - if (ret != Z_OK) { - WD_ERR("zlib inflateInit: %d\n", ret); - ret = -EINVAL; - goto out_free_buf; - } - - do { - ret = inflate(&stream, Z_NO_FLUSH); - if (ret < 0 || ret == Z_NEED_DICT) { - WD_ERR("zlib error %d - %s\n", ret, stream.msg); - ret = -ENOSR; - break; - } - - ret2 = compare_output(out_buffer, out_buf_size - - stream.avail_out, opaque); - /* compare_output should print diagnostic messages. */ - if (ret2) { - ret = Z_STREAM_ERROR; - break; - } - - if (!stream.avail_out) { - stream.next_out = out_buffer; - stream.avail_out = out_buf_size; - } - } while (ret != Z_STREAM_END); - - if (ret == Z_STREAM_END || ret == Z_OK) { - *checked = stream.total_out; - ret = 0; - } - - inflateEnd(&stream); -out_free_buf: - free(out_buffer); - return ret; -} - -int zlib_deflate(void *output, unsigned int out_size, - void *input, unsigned int in_size, - unsigned long *produced, int alg_type) -{ - int ret; - int windowBits; - z_stream stream = { - .next_in = input, - .avail_in = in_size, - .next_out = output, - .avail_out = out_size, - }; - - switch (alg_type) { - case WD_ZLIB: - windowBits = 15; - break; - case WD_DEFLATE: - windowBits = -15; - break; - case WD_GZIP: - windowBits = 15 + 16; - break; - default: - WD_ERR("algorithm %d unsupported by zlib\n", alg_type); - return -EINVAL; - } - - ret = deflateInit2(&stream, Z_BEST_SPEED, Z_DEFLATED, windowBits, 9, - Z_DEFAULT_STRATEGY); - if (ret != Z_OK) { - WD_ERR("zlib deflateInit: %d\n", ret); - return -EINVAL; - } - - do { - ret = deflate(&stream, Z_FINISH); - if (ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR) { - WD_ERR("zlib error %d - %s\n", ret, stream.msg); - ret = -ENOSR; - break; - } else if (!stream.avail_in) { - if (ret != Z_STREAM_END) - WD_ERR("unexpected deflate return value %d\n", ret); - *produced = stream.total_out; - ret = 0; - break; - } else if (!stream.avail_out) { - WD_ERR("No more output available\n"); - ret = -ENOSPC; - break; - } - } while (ret == Z_OK); - - deflateEnd(&stream); - - return ret; -} -#endif diff --git a/test/hisi_zip_test/test_lib.h b/test/hisi_zip_test/test_lib.h deleted file mode 100644 index 70d2c9d6..00000000 --- a/test/hisi_zip_test/test_lib.h +++ /dev/null @@ -1,352 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright 2020-2021 Huawei Technologies Co.,Ltd. All rights reserved. - * Copyright 2020-2021 Linaro ltd. - */ - -#ifndef TEST_LIB_H_ -#define TEST_LIB_H_ - -#include <errno.h> -#include <openssl/md5.h> -#include <semaphore.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <sys/resource.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <unistd.h> -#include "config.h" -#include "wd_comp.h" -#include "wd_sched.h" - -#define SYS_ERR_COND(cond, msg, ...) \ -do { \ - if (cond) { \ - if (errno) \ - perror(msg); \ - else \ - fprintf(stderr, msg, ##__VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } \ -} while (0) - -enum mode { - MODE_BLOCK, - MODE_STREAM, -}; - -#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) -#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) -#define MIN(a, b) ((a < b) ? a : b) - -/* - * I observed a worst case of 1.041x expansion with random data, but let's say 2 - * just in case. TODO: reduce this - */ -#define EXPANSION_RATIO 2 -/* The INFLATION_RATIO is high for text file. */ -#define INFLATION_RATIO 24 - -#define SGE_SIZE (8 * 1024) - -#define HIZIP_CHUNK_LIST_ENTRIES 32768 - -struct test_options { - int alg_type; - int op_type; - - /* bytes of data for a request */ - int block_size; - int q_num; - unsigned long total_len; - -#define MAX_RUNS 1024 - int run_num; - /* tasks running in parallel */ - int compact_run_num; - - /* send thread number */ - int thread_num; - /* poll thread number -- ASYNC */ - int poll_num; - /* 0: sync mode, 1: async mode */ - int sync_mode; - /* - * positive value: the number of messages are sent at a time. - * 0: batch mode is disabled. - * batch mode is only valid for ASYNC operations. - */ - int batch_num; - /* input file */ - int fd_in; - /* output file */ - int fd_out; - /* inlist file */ - int fd_ilist; - /* outlist file */ - int fd_olist; - - /* 0: pbuffer, 1: sgl */ - __u8 data_fmt; - - bool verify; - bool verbose; - bool is_decomp; - bool is_stream; - bool is_file; - bool use_env; - - int warmup_num; - -#define PERFORMANCE (1UL << 0) -#define TEST_ZLIB (1UL << 1) -#define TEST_THP (1UL << 2) - unsigned long option; - -#define STATS_NONE 0 -#define STATS_PRETTY 1 -#define STATS_CSV 2 - unsigned long display_stats; - - /* bind test case related below */ - int children; - -#define INJECT_SIG_BIND (1UL << 0) -#define INJECT_SIG_WORK (1UL << 1) -#define INJECT_TLB_FAULT (1UL << 2) - unsigned long faults; - -}; - -typedef struct _comp_md5_t { - MD5_CTX md5_ctx; - unsigned char md[MD5_DIGEST_LENGTH]; -} comp_md5_t; - -typedef struct hizip_chunk_list { - void *addr; - size_t size; - struct hizip_chunk_list *next; -} chunk_list_t; - -typedef struct _thread_data_t { - struct hizip_test_info *info; - struct wd_comp_req req; - comp_md5_t md5; - void *src; - void *dst; - size_t src_sz; - size_t dst_sz; - size_t sum; /* produced bytes for OUT */ - int tid; /* thread ID */ - int bcnt; /* batch mode: count */ - int pcnt; /* batch mode: poll count */ - int flush_bcnt; /* batch mode: flush count that is less batch_num */ - /* - * batch mode: set flag and wait batch end in sending thread. - * Clear batch flag if pcnt == bcnt in polling thread. - * batch_flag could replace flush_bcnt. - */ - int batch_flag; - sem_t sem; - chunk_list_t *in_list; - chunk_list_t *out_list; - struct wd_comp_req *reqs; -} thread_data_t; - -struct hizip_test_info { - struct test_options *opts; - char *in_buf, *out_buf; - size_t in_size, out_size; - /* in_chunk_sz & out_chunk_sz are used to format entries in list */ - size_t in_chunk_sz, out_chunk_sz; - size_t total_out; - struct uacce_dev_list *list; - handle_t h_sess; - struct wd_ctx_config ctx_conf; - pthread_t *send_tds; - int send_tnum; - pthread_t *poll_tds; - int poll_tnum; - /* tdatas: send thread data array, p_tdatas: poll thread data array */ - thread_data_t *tdatas; - thread_data_t *p_tdatas; - struct hizip_stats *stats; - struct { - struct timespec setup_time; - struct timespec start_time; - struct timespec end_time; - struct timespec setup_cputime; - struct timespec start_cputime; - struct timespec end_cputime; - struct rusage setup_rusage; - struct rusage start_rusage; - struct rusage end_rusage; - } tv; -}; - -extern int sum_pend, sum_thread_end; - -void *send_thread_func(void *arg); -void *poll_thread_func(void *arg); -void *sw_dfl_sw_ifl(void *arg); -int create_send_threads(struct test_options *opts, - struct hizip_test_info *info, - void *(*send_thread_func)(void *arg)); -int create_poll_threads(struct hizip_test_info *info, - void *(*poll_thread_func)(void *arg), - int num); -void free_threads(struct hizip_test_info *info); -int attach_threads(struct test_options *opts, - struct hizip_test_info *info); - -void gen_random_data(void *buf, size_t len); -int calculate_md5(comp_md5_t *md5, const void *buf, size_t len); -void dump_md5(comp_md5_t *md5); -int cmp_md5(comp_md5_t *orig, comp_md5_t *final); -void init_chunk_list(chunk_list_t *list, void *buf, size_t buf_sz, - size_t chunk_sz); -chunk_list_t *create_chunk_list(void *buf, size_t buf_sz, size_t chunk_sz); -void free_chunk_list(chunk_list_t *list); -int sw_deflate2(chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts); -int sw_inflate2(chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts); -int hw_deflate4(handle_t h_dfl, - chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts, - sem_t *sem); -int hw_inflate4(handle_t h_ifl, - chunk_list_t *in_list, - chunk_list_t *out_list, - struct test_options *opts, - sem_t *sem); -int hw_deflate5(handle_t h_dfl, - chunk_list_t *in_list, - chunk_list_t *out_list, - thread_data_t *tdata); -int hw_inflate5(handle_t h_ifl, - chunk_list_t *in_list, - chunk_list_t *out_list, - thread_data_t *tdata); -int create_send_tdata(struct test_options *opts, - struct hizip_test_info *info); -int create_poll_tdata(struct test_options *opts, - struct hizip_test_info *info, - int poll_num); -void free2_threads(struct hizip_test_info *info); -int attach2_threads(struct test_options *opts, - struct hizip_test_info *info, - void *(*send_thread_func)(void *arg), - void *(*poll_thread_func)(void *arg)); -void *poll2_thread_func(void *arg); -int run_self_test(struct test_options *opts); -int run_cmd(struct test_options *opts); -int init_ctx_config(struct test_options *opts, - void *priv, - struct wd_sched **sched - ); -void uninit_config(void *priv, struct wd_sched *sched); -struct uacce_dev_list *get_dev_list(struct test_options *opts, int children); - -void hizip_prepare_random_input_data(char *buf, size_t len, size_t block_size); -int hizip_prepare_random_compressed_data(char *buf, size_t out_len, - size_t in_len, size_t *produced, - struct test_options *opts); - -int hizip_verify_random_output(struct test_options *opts, - struct hizip_test_info *info, - size_t out_sz); - -void *mmap_alloc(size_t len); -int mmap_free(void *addr, size_t len); - -int lib_poll_func(__u32 pos, __u32 expect, __u32 *count); -typedef int (*check_output_fn)(unsigned char *buf, unsigned int size, void *opaque); - -/* for block interface */ -int hw_blk_compress(int alg_type, int blksize, __u8 data_fmt, void *priv, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen); - -int hw_blk_decompress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen); - -/* for stream memory interface */ -int hw_stream_compress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen); - -int hw_stream_decompress(int alg_type, int blksize, __u8 data_fmt, - unsigned char *dst, __u32 *dstlen, - unsigned char *src, __u32 srclen); - -#ifdef USE_ZLIB -int hizip_check_output(void *buf, size_t size, size_t *checked, - check_output_fn check_output, void *opaque); -int zlib_deflate(void *output, unsigned int out_size, - void *input, unsigned int in_size, unsigned long *produced, - int alg_type); -#else -static inline int hizip_check_output(void *buf, size_t size, size_t *checked, - check_output_fn check_output, - void *opaque) -{ - static bool printed = false; - - if (!printed) { - WD_ERR("no zlib available, output buffer won't be checked\n"); - printed = true; - } - return -ENOSYS; -} -static inline int zlib_deflate(void *output, unsigned int out_size, void *input, - unsigned int in_size, unsigned long *produced, - int alg_type) -{ - WD_ERR("no zlib available\n"); - return -ENOSYS; -} -#endif - -static inline void hizip_test_adjust_len(struct test_options *opts) -{ - /* - * Align size to the next block. We allow non-power-of-two block sizes. - */ - opts->total_len = (opts->total_len + opts->block_size - 1) / - opts->block_size * opts->block_size; -} - -#define COMMON_OPTSTRING "hb:n:q:l:FSs:Vvzt:m:dacLZ" - -#define COMMON_HELP "%s [opts]\n" \ - " -b <size> block size\n" \ - " -n <num> number of runs\n" \ - " -q <num> number of queues\n" \ - " -l <num> number of compact runs\n" \ - " -F input file, default no input\n" \ - " -S stream mode, default block mode\n" \ - " -s <size> total size\n" \ - " -V verify output\n" \ - " -v display detailed performance information\n" \ - " -a test deflate algorithm, default gzip\n" \ - " -z test zlib algorithm, default gzip\n" \ - " -t <num> number of thread per process\n" \ - " -m <mode> mode of queues: 0 sync, 1 async\n" \ - " -d test decompression, default compression\n" \ - " -c use cpu to do zlib\n" \ - " -L test sgl type buffer, default pbuffer\n" \ - " -Z test lz77_zstd algorithm, default gzip\n" \ - "\n\n" - -int parse_common_option(const char opt, const char *optarg, - struct test_options *opts); -#endif /* TEST_LIB_H_ */ diff --git a/test/hisi_zip_test/testsuit.c b/test/hisi_zip_test/testsuit.c deleted file mode 100644 index e1b157a7..00000000 --- a/test/hisi_zip_test/testsuit.c +++ /dev/null @@ -1,1844 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright 2020-2021 Huawei Technologies Co.,Ltd. All rights reserved. - * Copyright 2020-2021 Linaro ltd. - */ -#include <linux/perf_event.h> -#include <asm/unistd.h> /* For __NR_perf_event_open */ -#include <fenv.h> -#include <getopt.h> -#include <inttypes.h> -#include <math.h> -#include <signal.h> -#include <time.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include "test_lib.h" -#include "wd_sched.h" - -#define POLL_STRING_LEN 128 - -enum hizip_stats_variable { - ST_SETUP_TIME, - ST_RUN_TIME, - ST_CPU_TIME, - - /* CPU usage */ - ST_USER_TIME, - ST_SYSTEM_TIME, - - /* Faults */ - ST_MINFLT, - ST_MAJFLT, - - /* Context switches */ - ST_INVCTX, - ST_VCTX, - - /* Signals */ - ST_SIGNALS, - - /* Aggregated */ - ST_SPEED, - ST_TOTAL_SPEED, - ST_CPU_IDLE, - ST_FAULTS, - ST_IOPF, - - ST_COMPRESSION_RATIO, - - NUM_STATS -}; - -struct hizip_stats { - double v[NUM_STATS]; -}; - -extern int perf_event_open(struct perf_event_attr *attr, - pid_t pid, int cpu, int group_fd, - unsigned long flags); -extern int perf_event_get(const char *event_name, int **perf_fds, int *nr_fds); -extern unsigned long long perf_event_put(int *perf_fds, int nr_fds); -extern void stat_setup(struct hizip_test_info *info); -extern void stat_start(struct hizip_test_info *info); -extern void stat_end(struct hizip_test_info *info); - -static size_t count_chunk_list_sz(chunk_list_t *list) -{ - size_t sum = 0; - chunk_list_t *p; - - for (p = list; p; p = p->next) - sum += p->size; - return sum; -} - -static void *sw_dfl_hw_ifl(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_ifl; - void *tbuf; - size_t tbuf_sz; - chunk_list_t *tlist; - comp_md5_t final_md5 = {{0}}; - int i, ret; - __u32 tout_sz; - - tbuf_sz = tdata->src_sz * EXPANSION_RATIO; - tbuf = mmap_alloc(tbuf_sz); - if (!tbuf) - return (void *)(uintptr_t)(-ENOMEM); - tlist = create_chunk_list(tbuf, tbuf_sz, - info->in_chunk_sz * EXPANSION_RATIO); - if (!tlist) { - ret = -ENOMEM; - goto out; - } - if (opts->option & PERFORMANCE) { - /* hack: - * memset buffer and trigger page fault early in the cpu - * instead of later in the SMMU - * Enhance performance in sva case - * no impact to non-sva case - */ - memset(tbuf, 5, tbuf_sz); - } - if (opts->is_stream) { - /* STREAM mode: only one entry in the list */ - init_chunk_list(tdata->in_list, tdata->src, - tdata->src_sz, tdata->src_sz); - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, tbuf_sz); - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, tdata->dst_sz); - ret = sw_deflate2(tdata->in_list, tlist, opts); - if (ret) { - printf("Fail to deflate by zlib: %d\n", ret); - goto out_strm; - } - tout_sz = tdata->dst_sz; - ret = hw_stream_decompress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tlist->addr, - tlist->size); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out_strm; - } - ret = calculate_md5(&tdata->md5, tdata->in_list->addr, - tdata->in_list->size); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_strm; - } - ret = calculate_md5(&final_md5, tdata->out_list->addr, - tout_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_strm; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_strm; - } - } - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - return NULL; - } - - /* BLOCK mode */ - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_ifl = wd_comp_alloc_sess(&setup); - if (!h_ifl) { - ret = -EINVAL; - goto out_strm; - } - - init_chunk_list(tdata->in_list, tdata->src, tdata->src_sz, - info->in_chunk_sz); - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, - info->in_chunk_sz * EXPANSION_RATIO); - init_chunk_list(tdata->out_list, tdata->dst, tdata->dst_sz, - info->out_chunk_sz); - ret = sw_deflate2(tdata->in_list, tlist, opts); - if (ret) { - printf("Fail to deflate by zlib: %d\n", ret); - goto out_run; - } - ret = hw_inflate4(h_ifl, tlist, tdata->out_list, opts, - &tdata->sem); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out_run; - } - ret = calculate_md5(&tdata->md5, tdata->src, tdata->src_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = calculate_md5(&final_md5, tdata->dst, tdata->dst_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_run; - } - } - wd_comp_free_sess(h_ifl); - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out_run: - wd_comp_free_sess(h_ifl); -out_strm: - free_chunk_list(tlist); -out: - mmap_free(tbuf, tbuf_sz); - return (void *)(uintptr_t)(ret); -} - -static void *hw_dfl_sw_ifl(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_dfl; - void *tbuf; - size_t tbuf_sz; - chunk_list_t *tlist; - comp_md5_t final_md5 = {{0}}; - int i, ret; - __u32 tmp_sz; - - tbuf_sz = tdata->src_sz * EXPANSION_RATIO; - tbuf = mmap_alloc(tbuf_sz); - if (!tbuf) - return (void *)(uintptr_t)(-ENOMEM); - tlist = create_chunk_list(tbuf, tbuf_sz, - opts->block_size * EXPANSION_RATIO); - if (!tlist) { - ret = -ENOMEM; - goto out; - } - if (opts->option & PERFORMANCE) { - /* hack: - * memset buffer and trigger page fault early in the cpu - * instead of later in the SMMU - * Enhance performance in sva case - * no impact to non-sva case - */ - memset(tbuf, 5, tbuf_sz); - } - if (opts->is_stream) { - /* STREAM mode: only one entry in the list */ - init_chunk_list(tdata->in_list, tdata->src, - tdata->src_sz, tdata->src_sz); - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, tbuf_sz); - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, tdata->dst_sz); - tmp_sz = tbuf_sz; - ret = hw_stream_compress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tlist->addr, - &tmp_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out_strm; - } - tlist->size = tmp_sz; // write back - ret = sw_inflate2(tlist, tdata->out_list, opts); - if (ret) { - printf("Fail to inflate by zlib: %d\n", ret); - goto out_strm; - } - ret = calculate_md5(&tdata->md5, tdata->in_list->addr, - tdata->in_list->size); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_strm; - } - ret = calculate_md5(&final_md5, tdata->out_list->addr, - tdata->out_list->size); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_strm; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_strm; - } - } - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - return NULL; - } - - /* BLOCK mode */ - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_COMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_dfl = wd_comp_alloc_sess(&setup); - if (!h_dfl) { - ret = -EINVAL; - goto out_strm; - } - - init_chunk_list(tdata->in_list, tdata->src, tdata->src_sz, - info->in_chunk_sz); - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, - opts->block_size * EXPANSION_RATIO); - init_chunk_list(tdata->out_list, tdata->dst, tdata->dst_sz, - info->out_chunk_sz); - ret = hw_deflate4(h_dfl, tdata->in_list, tlist, opts, - &tdata->sem); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out_run; - } - ret = sw_inflate2(tlist, tdata->out_list, opts); - if (ret) { - printf("Fail to inflate by zlib: %d\n", ret); - goto out_run; - } - ret = calculate_md5(&tdata->md5, tdata->src, tdata->src_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = calculate_md5(&final_md5, tdata->dst, tdata->dst_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_run; - } - } - wd_comp_free_sess(h_dfl); - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out_run: - wd_comp_free_sess(h_dfl); -out_strm: - free_chunk_list(tlist); -out: - mmap_free(tbuf, tbuf_sz); - return (void *)(uintptr_t)(ret); -} - -static void *hw_dfl_hw_ifl(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_dfl, h_ifl; - void *tbuf; - size_t tbuf_sz; - chunk_list_t *tlist; - comp_md5_t final_md5 = {{0}}; - int i, ret; - __u32 tmp_sz, tout_sz; - - tbuf_sz = tdata->src_sz * EXPANSION_RATIO; - tbuf = mmap_alloc(tbuf_sz); - if (!tbuf) - return (void *)(uintptr_t)(-ENOMEM); - if (opts->option & PERFORMANCE) { - /* hack: - * memset buffer and trigger page fault early in the cpu - * instead of later in the SMMU - * Enhance performance in sva case - * no impact to non-sva case - */ - memset(tbuf, 5, tbuf_sz); - } - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tmp_sz = tbuf_sz; - ret = hw_stream_compress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tbuf, - &tmp_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out; - } - tout_sz = tdata->dst_sz; - ret = hw_stream_decompress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tbuf, - tmp_sz); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out; - } - ret = calculate_md5(&tdata->md5, tdata->in_list->addr, - tdata->in_list->size); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out; - } - ret = calculate_md5(&final_md5, tdata->dst, tout_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out; - } - } - mmap_free(tbuf, tbuf_sz); - return NULL; - } - - /* BLOCK mode */ - tlist = create_chunk_list(tbuf, tbuf_sz, - opts->block_size * EXPANSION_RATIO); - if (!tlist) { - ret = -ENOMEM; - goto out; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_COMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_dfl = wd_comp_alloc_sess(&setup); - if (!h_dfl) { - ret = -EINVAL; - goto out_dfl; - } - - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - setup.sched_param = ¶m; - h_ifl = wd_comp_alloc_sess(&setup); - if (!h_ifl) { - ret = -EINVAL; - goto out_ifl; - } - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tlist, tbuf, tbuf_sz, - opts->block_size * EXPANSION_RATIO); - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_deflate4(h_dfl, tdata->in_list, tlist, opts, - &tdata->sem); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out_run; - } - ret = hw_inflate4(h_ifl, tlist, tdata->out_list, opts, - &tdata->sem); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out_run; - } - ret = calculate_md5(&tdata->md5, tdata->src, tdata->src_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = calculate_md5(&final_md5, tdata->dst, tdata->dst_sz); - if (ret) { - printf("Fail to generate MD5 (%d)\n", ret); - goto out_run; - } - ret = cmp_md5(&tdata->md5, &final_md5); - if (ret) { - printf("MD5 is unmatched (%d) at %dth times on " - "thread %d\n", ret, i, tdata->tid); - goto out_run; - } - } - wd_comp_free_sess(h_ifl); - wd_comp_free_sess(h_dfl); - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out_run: - wd_comp_free_sess(h_ifl); -out_ifl: - wd_comp_free_sess(h_dfl); -out_dfl: - free_chunk_list(tlist); -out: - mmap_free(tbuf, tbuf_sz); - return (void *)(uintptr_t)(ret); -} - -static void *hw_dfl_perf(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_dfl; - int i, ret; - uint32_t tout_sz; - - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tout_sz = tdata->dst_sz; - ret = hw_stream_compress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - return (void *)(uintptr_t)ret; - } - } - tdata->out_list->addr = tdata->dst; - tdata->out_list->size = tout_sz; - tdata->out_list->next = NULL; - return NULL; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_COMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_dfl = wd_comp_alloc_sess(&setup); - if (!h_dfl) - return (void *)(uintptr_t)(-EINVAL); - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_deflate4(h_dfl, tdata->in_list, tdata->out_list, opts, - &tdata->sem); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out; - } - } - wd_comp_free_sess(h_dfl); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out: - wd_comp_free_sess(h_dfl); - return (void *)(uintptr_t)(ret); -} - -static void *hw_ifl_perf(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_ifl; - int i, ret; - uint32_t tout_sz; - - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tout_sz = tdata->dst_sz; - ret = hw_stream_decompress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tdata->in_list->addr, - tdata->in_list->size); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - return (void *)(uintptr_t)ret; - } - tdata->out_list->addr = tdata->dst; - tdata->out_list->size = tout_sz; - tdata->out_list->next = NULL; - } - return NULL; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_ifl = wd_comp_alloc_sess(&setup); - if (!h_ifl) - return (void *)(uintptr_t)(-EINVAL); - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_inflate4(h_ifl, tdata->in_list, tdata->out_list, opts, - &tdata->sem); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out; - } - } - wd_comp_free_sess(h_ifl); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out: - wd_comp_free_sess(h_ifl); - return (void *)(uintptr_t)(ret); -} - -/* BATCH mode is used */ -void *hw_dfl_perf3(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_dfl; - int i, ret; - uint32_t tout_sz; - - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tout_sz = tdata->dst_sz; - ret = hw_stream_compress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - return (void *)(uintptr_t)ret; - } - } - tdata->out_list->addr = tdata->dst; - tdata->out_list->size = tout_sz; - tdata->out_list->next = NULL; - return NULL; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_COMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_dfl = wd_comp_alloc_sess(&setup); - if (!h_dfl) - return (void *)(uintptr_t)(-EINVAL); - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_deflate5(h_dfl, tdata->in_list, tdata->out_list, - tdata); - if (ret) { - printf("Fail to deflate by HW: %d\n", ret); - goto out; - } - } - wd_comp_free_sess(h_dfl); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out: - wd_comp_free_sess(h_dfl); - return (void *)(uintptr_t)(ret); -} - -/* BATCH mode is used */ -void *hw_ifl_perf3(void *arg) -{ - thread_data_t *tdata = (thread_data_t *)arg; - struct hizip_test_info *info = tdata->info; - struct test_options *opts = info->opts; - struct wd_comp_sess_setup setup = {0}; - struct sched_params param = {0}; - handle_t h_ifl; - int i, ret; - uint32_t tout_sz; - - if (opts->is_stream) { - for (i = 0; i < opts->compact_run_num; i++) { - tout_sz = tdata->dst_sz; - ret = hw_stream_decompress(opts->alg_type, - opts->block_size, - opts->data_fmt, - tdata->dst, - &tout_sz, - tdata->src, - tdata->src_sz); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - return (void *)(uintptr_t)ret; - } - tdata->out_list->addr = tdata->dst; - tdata->out_list->size = tout_sz; - tdata->out_list->next = NULL; - } - return NULL; - } - - setup.alg_type = opts->alg_type; - setup.op_type = WD_DIR_DECOMPRESS; - param.type = setup.op_type; - param.numa_id = 0; - setup.sched_param = ¶m; - h_ifl = wd_comp_alloc_sess(&setup); - if (!h_ifl) - return (void *)(uintptr_t)(-EINVAL); - - for (i = 0; i < opts->compact_run_num; i++) { - init_chunk_list(tdata->out_list, tdata->dst, - tdata->dst_sz, - info->out_chunk_sz); - ret = hw_inflate5(h_ifl, tdata->in_list, tdata->out_list, - tdata); - if (ret) { - printf("Fail to inflate by HW: %d\n", ret); - goto out; - } - } - wd_comp_free_sess(h_ifl); - /* mark sending thread to end */ - __atomic_add_fetch(&sum_thread_end, 1, __ATOMIC_ACQ_REL); - return NULL; -out: - wd_comp_free_sess(h_ifl); - return (void *)(uintptr_t)(ret); -} - -/* - * Load both ilist file. - */ -int load_ilist(struct hizip_test_info *info, char *model) -{ - struct test_options *opts = info->opts; - thread_data_t *tdata = &info->tdatas[0]; - chunk_list_t *p; - size_t sum = 0; - ssize_t file_sz = 0; - void *addr; - - if (!strcmp(model, "hw_ifl_perf")) { - if (!opts->is_stream) { - if (opts->fd_ilist < 0) { - printf("Missing IN list file!\n"); - return -EINVAL; - } - p = tdata->in_list; - addr = info->in_buf; - while (p) { - file_sz = read(opts->fd_ilist, p, - sizeof(chunk_list_t)); - if (file_sz < 0) - return -EFAULT; - p->addr = addr; - sum += file_sz; - if (p->next) - p->next = p + 1; - addr += p->size; - p = p->next; - } - } - } - return (int)sum; -} - -/* - * Load compression/decompression content. - */ -int load_file_data(struct hizip_test_info *info) -{ - struct test_options *opts = info->opts; - size_t file_sz; - - file_sz = read(opts->fd_in, info->in_buf, info->in_size); - if (file_sz < info->in_size) { - printf("Expect to read %ld bytes. " - "But only read %ld bytes!\n", - info->in_size, file_sz); - return -EFAULT; - } - return (int)file_sz; -} - -/* - * Store both olist file. opts->is_file must be enabled first. - */ -int store_olist(struct hizip_test_info *info, char *model) -{ - struct test_options *opts = info->opts; - thread_data_t *tdata = &info->tdatas[0]; - chunk_list_t *p; - size_t sum = 0; - ssize_t file_sz = 0; - - if (!opts->is_stream) { - if (opts->fd_olist >= 0) { - /* compress with BLOCK */ - p = tdata->out_list; - while (p) { - file_sz = write(opts->fd_olist, p, - sizeof(chunk_list_t)); - if (file_sz < sizeof(chunk_list_t)) - return -EFAULT; - file_sz = write(opts->fd_out, p->addr, - p->size); - if (file_sz < p->size) - return -EFAULT; - p = p->next; - sum += file_sz; - } - } else { - /* decompress with BLOCK */ - p = tdata->out_list; - while (p) { - file_sz = write(opts->fd_out, p->addr, - p->size); - if (file_sz < p->size) - return -EFAULT; - p = p->next; - sum += file_sz; - } - } - } else if (opts->is_stream) { - p = tdata->out_list; - file_sz = write(opts->fd_out, p->addr, p->size); - if (file_sz < p->size) - return -EFAULT; - sum = file_sz; - } - return (int)sum; -} - -static int nonenv_resource_init(struct test_options *opts, - struct hizip_test_info *info, - struct wd_sched **sched) -{ - int ret; - - info->list = get_dev_list(opts, 1); - if (!info->list) - return -EINVAL; - ret = init_ctx_config(opts, info, sched); - if (ret < 0) { - wd_free_list_accels(info->list); - return ret; - } - return 0; -} - -static void nonenv_resource_uninit(struct test_options *opts, - struct hizip_test_info *info, - struct wd_sched *sched) -{ - uninit_config(info, sched); - wd_free_list_accels(info->list); -} - -static bool event_unavailable = false; - -int test_hw(struct test_options *opts, char *model) -{ - struct hizip_test_info info = {0}; - struct wd_sched *sched = NULL; - double ilen, usec, speed; - char zbuf[120]; - int ret, zbuf_idx, ifl_flag = 0; - void *(*func)(void *); - size_t tbuf_sz = 0; - void *tbuf = NULL; - struct stat statbuf; - chunk_list_t *tlist = NULL; - int div; - __u32 num; - __u8 enable; - int nr_fds = 0; - int *perf_fds = NULL; - struct hizip_stats stats; - - if (!opts || !model) { - ret = -EINVAL; - goto out; - } - info.opts = opts; - info.stats = &stats; - - if (!event_unavailable && - perf_event_get("iommu/dev_fault", &perf_fds, &nr_fds)) { - printf("IOPF statistic unavailable\n"); - /* No need to retry and print an error on every run */ - event_unavailable = true; - } - stat_setup(&info); - - memset(zbuf, 0, 120); - if (!strcmp(model, "sw_dfl_hw_ifl")) { - func = sw_dfl_hw_ifl; - info.in_size = opts->total_len; - if (opts->is_stream) - info.out_size = opts->total_len; - else - info.out_size = opts->total_len; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size; - zbuf_idx = sprintf(zbuf, "Mix SW deflate and HW %s %s inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_dfl_sw_ifl")) { - func = hw_dfl_sw_ifl; - info.in_size = opts->total_len; - info.out_size = opts->total_len; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size; - zbuf_idx = sprintf(zbuf, "Mix HW %s %s deflate and SW inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_dfl_hw_ifl")) { - func = hw_dfl_hw_ifl; - info.in_size = opts->total_len; - if (opts->is_stream) - info.out_size = opts->total_len; - else - info.out_size = opts->total_len; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size; - zbuf_idx = sprintf(zbuf, - "Mix HW %s %s deflate and HW %s %s inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_dfl_perf")) { - func = hw_dfl_perf; - info.in_size = opts->total_len; - info.out_size = opts->total_len * EXPANSION_RATIO; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size * EXPANSION_RATIO; - zbuf_idx = sprintf(zbuf, "HW %s %s deflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_dfl_perf3")) { - func = hw_dfl_perf3; - info.in_size = opts->total_len; - info.out_size = opts->total_len * EXPANSION_RATIO; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size * EXPANSION_RATIO; - zbuf_idx = sprintf(zbuf, "HW %s %s deflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - } else if (!strcmp(model, "hw_ifl_perf")) { - func = hw_ifl_perf; - info.in_size = opts->total_len; - info.out_size = opts->total_len * INFLATION_RATIO; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size * INFLATION_RATIO; - zbuf_idx = sprintf(zbuf, "HW %s %s inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - ifl_flag = 1; - } else if (!strcmp(model, "hw_ifl_perf3")) { - func = hw_ifl_perf3; - info.in_size = opts->total_len * EXPANSION_RATIO; - info.out_size = opts->total_len; - info.in_chunk_sz = opts->block_size; - info.out_chunk_sz = opts->block_size * INFLATION_RATIO; - zbuf_idx = sprintf(zbuf, "HW %s %s inflate", - opts->sync_mode ? "ASYNC" : "SYNC", - opts->is_stream ? "STREAM" : "BLOCK"); - ifl_flag = 1; - } else { - printf("Wrong model is specified:%s\n", model); - ret = -EINVAL; - goto out; - } - - if (opts->use_env) - ret = wd_comp_env_init(NULL); - else - ret = nonenv_resource_init(opts, &info, &sched); - if (ret < 0) - goto out; - - if (opts->faults & INJECT_SIG_BIND) - kill(getpid(), SIGTERM); - - if (opts->use_env) { - ret = wd_comp_get_env_param(0, opts->op_type, opts->sync_mode, &num, &enable); - if (ret < 0) - goto out; - } - - if (opts->is_file) { - ret = fstat(opts->fd_in, &statbuf); - if (ret < 0) - goto out_src; - opts->total_len = statbuf.st_size; - info.in_size = opts->total_len; - if (ifl_flag) - info.out_size = opts->total_len * INFLATION_RATIO; - else - info.out_size = opts->total_len * EXPANSION_RATIO; - /* - * If fd_ilist exists, it's inflation. - * Make sure block inflation has enough room. - */ - if (opts->fd_ilist >= 0) { - ret = fstat(opts->fd_ilist, &statbuf); - if (!ret) { - div = statbuf.st_size / sizeof(chunk_list_t); - info.in_chunk_sz = (info.in_size + div - 1) / - div; - info.out_chunk_sz = (info.out_size + div - 1) / - div; - } - } - } - info.in_buf = mmap_alloc(info.in_size); - if (!info.in_buf) { - ret = -ENOMEM; - goto out_src; - } - ret = create_send_tdata(opts, &info); - if (ret) - goto out_send; - ret = create_poll_tdata(opts, &info, opts->poll_num); - if (ret) - goto out_poll; - if (opts->is_file) { - /* in_list is created by create_send3_threads(). */ - ret = load_file_data(&info); - if (ret < 0) - goto out_buf; - ret = load_ilist(&info, model); - if (ret < 0) - goto out_buf; - } else { - if (ifl_flag) { - thread_data_t *tdata = info.tdatas; - tbuf_sz = info.in_size / EXPANSION_RATIO; - tbuf = mmap_alloc(tbuf_sz); - if (!tbuf) { - ret = -ENOMEM; - goto out_buf; - } - tlist = create_chunk_list(tbuf, tbuf_sz, - opts->block_size / - EXPANSION_RATIO); - init_chunk_list(tlist, tbuf, tbuf_sz, - opts->block_size / EXPANSION_RATIO); - gen_random_data(tbuf, tbuf_sz); - ret = sw_deflate2(tlist, tdata[0].in_list, opts); - if (ret) { - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - goto out_buf; - } - free_chunk_list(tlist); - mmap_free(tbuf, tbuf_sz); - } else - gen_random_data(info.in_buf, info.in_size); - } - if (opts->faults & INJECT_TLB_FAULT) { - /* - * Now unmap the buffers and retry the access. Normally we - * should get an access fault, but if the TLB wasn't properly - * invalidated, the access succeeds and corrupts memory! - * This test requires small jobs, to make sure that we reuse - * the same TLB entry between the tests. Run for example with - * "-s 0x1000 -b 0x1000". - */ - ret = munmap(info.in_buf, info.in_size); - if (ret) { - printf("Failed to unmap."); - goto out_buf; - } - /* A warning if the parameters might produce false positives */ - if (opts->total_len > 0x54000) - fprintf(stderr, "NOTE: test might trash the TLB\n"); - } - stat_start(&info); - ret = attach2_threads(opts, &info, func, poll2_thread_func); - if (ret) - goto out_buf; - stat_end(&info); - info.stats->v[ST_IOPF] = perf_event_put(perf_fds, nr_fds); - if (opts->is_file) - store_olist(&info, model); - - usec = info.stats->v[ST_RUN_TIME] / 1000; - if (opts->op_type == WD_DIR_DECOMPRESS) - ilen = (float)count_chunk_list_sz(info.tdatas[0].out_list); - else - ilen = opts->total_len; - ilen *= opts->thread_num * opts->compact_run_num; - speed = ilen * 1000 * 1000 / 1024 / 1024 / usec; - if (opts->sync_mode) { - zbuf_idx += sprintf(zbuf + zbuf_idx, - " with %d send + %d poll threads", - opts->thread_num, - opts->poll_num); - } else { - zbuf_idx += sprintf(zbuf + zbuf_idx, - " with %d send threads", - opts->thread_num); - } - if (!strcmp(model, "hw_dfl_perf") || !strcmp(model, "hw_ifl_perf") || - !strcmp(model, "hw_dfl_perf3") || !strcmp(model, "hw_ifl_perf3")) { - printf("%s at %.2fMB/s in %f usec (BLK:%d, Bnum:%d).\n", - zbuf, speed, usec, opts->block_size, opts->batch_num); - } else { - printf("%s in %f usec (BLK:%d, Bnum:%d).\n", - zbuf, usec, opts->block_size, opts->batch_num); - } - free2_threads(&info); - if (opts->use_env) - wd_comp_env_uninit(); - else - nonenv_resource_uninit(opts, &info, sched); - usleep(1000); - return 0; -out_buf: -out_poll: - free2_threads(&info); - if (opts->use_env) - wd_comp_env_uninit(); - else - nonenv_resource_uninit(opts, &info, sched); - printf("Fail to run %s() (%d)!\n", model, ret); - return ret; -out_send: - mmap_free(info.in_buf, info.in_size); -out_src: - if (opts->use_env) - wd_comp_env_uninit(); - else - nonenv_resource_uninit(opts, &info, sched); -out: - printf("Fail to run %s() (%d)!\n", model, ret); - return ret; -} - -int run_self_test(struct test_options *opts) -{ - int i, f_ret = 0; - char poll_str[POLL_STRING_LEN]; - - printf("Start to run self test!\n"); - opts->alg_type = WD_ZLIB; - opts->data_fmt = WD_FLAT_BUF; - opts->sync_mode = 0; - opts->q_num = 16; - for (i = 0; i < 10; i++) { - opts->sync_mode = 0; - switch (i) { - case 0: - opts->thread_num = 1; - break; - case 1: - opts->thread_num = 2; - break; - case 2: - opts->thread_num = 4; - break; - case 3: - opts->thread_num = 8; - break; - case 4: - opts->thread_num = 16; - break; - case 5: - opts->thread_num = 1; - opts->is_stream = 1; - break; - case 6: - opts->thread_num = 2; - opts->is_stream = 1; - break; - case 7: - opts->thread_num = 4; - opts->is_stream = 1; - break; - case 8: - opts->thread_num = 8; - opts->is_stream = 1; - break; - case 9: - opts->thread_num = 16; - opts->is_stream = 1; - break; - } - f_ret |= test_hw(opts, "hw_dfl_perf"); - f_ret |= test_hw(opts, "hw_ifl_perf"); - } - opts->is_stream = 0; /* restore to BLOCK mode */ - for (i = 0; i < 5; i++) { - opts->thread_num = 8; - switch (i) { - case 0: - opts->sync_mode = 0; - break; - case 1: - opts->sync_mode = 1; opts->poll_num = 1; - break; - case 2: - opts->sync_mode = 1; opts->poll_num = 2; - break; - case 3: - opts->sync_mode = 1; opts->poll_num = 4; - break; - case 4: - opts->sync_mode = 1; opts->poll_num = 8; - break; - default: - return -EINVAL; - } - if (opts->use_env && opts->poll_num) { - memset(poll_str, 0, POLL_STRING_LEN); - sprintf(poll_str, - "sync-comp:8@0,sync-decomp:8@0," - "async-comp:8@0,async-decomp:8@0"); - setenv("WD_COMP_CTX_NUM", poll_str, 1); - memset(poll_str, 0, POLL_STRING_LEN); - sprintf(poll_str, "%d@0", opts->poll_num), - setenv("WD_COMP_ASYNC_POLL_NUM", poll_str, 1); - } - f_ret |= test_hw(opts, "sw_dfl_hw_ifl"); - f_ret |= test_hw(opts, "hw_dfl_sw_ifl"); - f_ret |= test_hw(opts, "hw_dfl_hw_ifl"); - f_ret |= test_hw(opts, "hw_dfl_perf"); - f_ret |= test_hw(opts, "hw_ifl_perf"); - } - if (!f_ret) - printf("Run self test successfully!\n"); - return f_ret; -} - -static int set_default_opts(struct test_options *opts) -{ - if (!opts->block_size) - opts->block_size = 8192; - if (!opts->total_len) { - if (opts->block_size) - opts->total_len = opts->block_size * 10; - else - opts->total_len = 8192 * 10; - } - if (!opts->thread_num) - opts->thread_num = 1; - if (!opts->q_num) - opts->q_num = opts->thread_num; - if (!opts->compact_run_num) - opts->compact_run_num = 1; - if (!opts->poll_num) - opts->poll_num = 1; - if (opts->alg_type == WD_COMP_ALG_MAX) - opts->alg_type = WD_GZIP; - return 0; -} - -static int run_one_cmd(struct test_options *opts) -{ - int ret; - - if (opts->op_type == WD_DIR_COMPRESS) { - if (opts->verify) - ret = test_hw(opts, "hw_dfl_sw_ifl"); - else - ret = test_hw(opts, "hw_dfl_perf"); - } else { - if (opts->verify) - ret = test_hw(opts, "sw_dfl_hw_ifl"); - else - ret = test_hw(opts, "hw_ifl_perf"); - } - return ret; -} - -int run_cmd(struct test_options *opts) -{ - int ret = 0, i; - int nr_children = 0, status; - pid_t pid, *pids = NULL; - bool success = true; - - set_default_opts(opts); - if (opts->children) { - pids = calloc(opts->children, sizeof(pid_t)); - if (!pids) - return -ENOMEM; - for (i = 0; i < opts->children; i++) { - pid = fork(); - if (pid < 0) { - printf("cannot fork: %d\n", errno); - success = false; - break; - } else if (pid > 0) { - /* Parent */ - pids[nr_children++] = pid; - continue; - } - /* Child */ - ret = run_one_cmd(opts); - return ret; - } - for (i = 0; i < nr_children; i++) { - pid = pids[i]; - ret = waitpid(pid, &status, 0); - if (ret < 0) { - printf("wait(pid=%d) error %d\n", pid, errno); - success = false; - continue; - } - if (WIFEXITED(status)) { - ret = WEXITSTATUS(status); - if (ret) { - printf("child %d returned with %d\n", - pid, ret); - success = false; - } - } else if (WIFSIGNALED(status)) { - ret = WTERMSIG(status); - printf("child %d killed by sig %d\n", pid, ret); - success = false; - } else { - printf("unexpected status for child %d\n", pid); - success = false; - } - } - if (success == false) { - printf("Failed to run spawn test!\n"); - if (!ret) - ret = -EINVAL; - } - } else - ret = run_one_cmd(opts); - return ret; -} - -int perf_event_open(struct perf_event_attr *attr, - pid_t pid, int cpu, int group_fd, - unsigned long flags) -{ - return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); -} - -unsigned long long perf_event_put(int *perf_fds, int nr_fds); - -int perf_event_get(const char *event_name, int **perf_fds, int *nr_fds) -{ - int ret; - int cpu; - FILE *fd; - int nr_cpus; - unsigned int event_id; - char event_id_file[256]; - struct perf_event_attr event = { - .type = PERF_TYPE_TRACEPOINT, - .size = sizeof(event), - .disabled = true, - }; - - *perf_fds = NULL; - *nr_fds = 0; - - nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); - if (nr_cpus <= 0) { - WD_ERR("invalid number of CPUs\n"); - return nr_cpus; - } - - ret = snprintf(event_id_file, sizeof(event_id_file), - "/sys/kernel/debug/tracing/events/%s/id", event_name); - if (ret >= sizeof(event_id_file)) { - WD_ERR("event_id buffer overflow\n"); - return -EOVERFLOW; - } - fd = fopen(event_id_file, "r"); - if (fd == NULL) { - ret = -errno; - WD_ERR("Couldn't open file %s\n", event_id_file); - return ret; - } - - if (fscanf(fd, "%d", &event_id) != 1) { - WD_ERR("Couldn't parse file %s\n", event_id_file); - return -EINVAL; - } - fclose(fd); - event.config = event_id; - - *perf_fds = calloc(nr_cpus, sizeof(int)); - if (!*perf_fds) - return -ENOMEM; - *nr_fds = nr_cpus; - - /* - * An event is bound to either a CPU or a PID. If we want both, we need - * to open the event on all CPUs. Note that we can't use a perf group - * since they have to be on the same CPU. - */ - for (cpu = 0; cpu < nr_cpus; cpu++) { - int fd = perf_event_open(&event, -1, cpu, -1, 0); - - if (fd < 0) { - WD_ERR("Couldn't get perf event %s on CPU%d: %d\n", - event_name, cpu, errno); - perf_event_put(*perf_fds, cpu); - return fd; - } - - ioctl(fd, PERF_EVENT_IOC_RESET, 0); - ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); - (*perf_fds)[cpu] = fd; - } - - return 0; -} - -/* - * Closes the perf fd and return the sample count. If it wasn't open, return 0. - */ -unsigned long long perf_event_put(int *perf_fds, int nr_fds) -{ - int ret; - int cpu; - uint64_t count, total = 0; - - if (!perf_fds) - return 0; - - for (cpu = 0; cpu < nr_fds; cpu++) { - int fd = perf_fds[cpu]; - - if (fd <= 0) { - WD_ERR("Invalid perf fd %d\n", cpu); - continue; - } - - ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); - - ret = read(fd, &count, sizeof(count)); - if (ret < sizeof(count)) - WD_ERR("Couldn't read perf event for CPU%d\n", cpu); - - total += count; - close(fd); - - } - - free(perf_fds); - return total; -} - -static void set_thp(struct test_options *opts) -{ - char *p; - char s[14]; - FILE *file; - - file = fopen("/sys/kernel/mm/transparent_hugepage/enabled", "r"); - if (!file) - goto out_err; - p = fgets(s, 14, file); - fclose(file); - if (!p) - goto out_err; - - if (strcmp(s, "never") == 0) { - printf("Cannot test THP with enable=never\n"); - return; - } - - file = fopen("/sys/kernel/mm/transparent_hugepage/defrag", "r"); - if (!file) - goto out_err; - p = fgets(s, 14, file); - fclose(file); - if (!p) - goto out_err; - - if (strcmp(s, "defer") == 0 || strcmp(s, "never") == 0) { - printf("Cannot test THP with defrag=%s\n", s); - return; - } - - return; -out_err: - printf("THP unsupported?\n"); -} - -void stat_setup(struct hizip_test_info *info) -{ - clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.setup_time); - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.setup_cputime); - getrusage(RUSAGE_SELF, &info->tv.setup_rusage); -} - -void stat_start(struct hizip_test_info *info) -{ - clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.start_time); - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.start_cputime); - getrusage(RUSAGE_SELF, &info->tv.start_rusage); -} - -void stat_end(struct hizip_test_info *info) -{ - struct test_options *opts = info->opts; - struct hizip_stats *stats = info->stats; - double v; - size_t total_out; - unsigned long total_len; - - total_out = __atomic_load_n(&info->total_out, __ATOMIC_ACQUIRE); - clock_gettime(CLOCK_MONOTONIC_RAW, &info->tv.end_time); - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->tv.end_cputime); - getrusage(RUSAGE_SELF, &info->tv.end_rusage); - - stats->v[ST_SETUP_TIME] = (info->tv.start_time.tv_sec - - info->tv.setup_time.tv_sec) * 1000000000 + - info->tv.start_time.tv_nsec - - info->tv.setup_time.tv_nsec; - stats->v[ST_RUN_TIME] = (info->tv.end_time.tv_sec - - info->tv.start_time.tv_sec) * 1000000000 + - info->tv.end_time.tv_nsec - - info->tv.start_time.tv_nsec; - - stats->v[ST_CPU_TIME] = (info->tv.end_cputime.tv_sec - - info->tv.setup_cputime.tv_sec) * 1000000000 + - info->tv.end_cputime.tv_nsec - - info->tv.setup_cputime.tv_nsec; - stats->v[ST_USER_TIME] = (info->tv.end_rusage.ru_utime.tv_sec - - info->tv.setup_rusage.ru_utime.tv_sec) * - 1000000 + - info->tv.end_rusage.ru_utime.tv_usec - - info->tv.setup_rusage.ru_utime.tv_usec; - stats->v[ST_SYSTEM_TIME] = (info->tv.end_rusage.ru_stime.tv_sec - - info->tv.setup_rusage.ru_stime.tv_sec) * - 1000000 + - info->tv.end_rusage.ru_stime.tv_usec - - info->tv.setup_rusage.ru_stime.tv_usec; - - stats->v[ST_MINFLT] = info->tv.end_rusage.ru_minflt - - info->tv.setup_rusage.ru_minflt; - stats->v[ST_MAJFLT] = info->tv.end_rusage.ru_majflt - - info->tv.setup_rusage.ru_majflt; - - stats->v[ST_VCTX] = info->tv.end_rusage.ru_nvcsw - - info->tv.setup_rusage.ru_nvcsw; - stats->v[ST_INVCTX] = info->tv.end_rusage.ru_nivcsw - - info->tv.setup_rusage.ru_nivcsw; - - stats->v[ST_SIGNALS] = info->tv.end_rusage.ru_nsignals - - info->tv.setup_rusage.ru_nsignals; - - /* check last loop is enough, same as below hizip_verify_output */ - stats->v[ST_COMPRESSION_RATIO] = (double)opts->total_len / - total_out * 100; - - total_len = opts->total_len * opts->compact_run_num; - /* ST_RUN_TIME records nanoseconds */ - stats->v[ST_SPEED] = (total_len * opts->thread_num * 1000) / - (1.024 * 1.024 * stats->v[ST_RUN_TIME]); - - stats->v[ST_TOTAL_SPEED] = (total_len * opts->thread_num * 1000) / - ((stats->v[ST_RUN_TIME] + - stats->v[ST_SETUP_TIME]) * 1.024 * 1.024); - - v = stats->v[ST_RUN_TIME] + stats->v[ST_SETUP_TIME]; - stats->v[ST_CPU_IDLE] = (v - stats->v[ST_CPU_TIME]) / v * 100; - stats->v[ST_FAULTS] = stats->v[ST_MAJFLT] + stats->v[ST_MINFLT]; -} - -static void handle_sigbus(int sig) -{ - printf("SIGBUS!\n"); - _exit(0); -} - -int main(int argc, char **argv) -{ - struct test_options opts = { - .alg_type = WD_GZIP, - .op_type = WD_DIR_COMPRESS, - .q_num = 1, - .run_num = 1, - .compact_run_num = 1, - .thread_num = 1, - .sync_mode = 0, - .block_size = 512000, - .total_len = opts.block_size * 10, - .verify = false, - .verbose = false, - .is_decomp = false, - .is_stream = false, - .is_file = false, - .display_stats = STATS_PRETTY, - .children = 0, - .faults = 0, - .data_fmt = 0, - }; - struct option long_options[] = { - {"self", no_argument, 0, 0 }, - {"in", required_argument, 0, 0 }, - {"out", required_argument, 0, 0 }, - {"ilist", required_argument, 0, 0 }, - {"olist", required_argument, 0, 0 }, - {"env", no_argument, 0, 0 }, - {0, 0, 0, 0 }, - }; - int show_help = 0; - int opt, option_idx; - int self = 0; - - opts.fd_in = -1; - opts.fd_out = -1; - opts.fd_ilist = -1; - opts.fd_olist = -1; - opts.alg_type = WD_COMP_ALG_MAX; - while ((opt = getopt_long(argc, argv, COMMON_OPTSTRING "f:o:w:k:r:", - long_options, &option_idx)) != -1) { - switch (opt) { - case 0: - switch (option_idx) { - case 0: /* self */ - self = 1; - break; - case 1: /* in */ - if (optarg) { - opts.fd_in = open(optarg, O_RDONLY); - if (opts.fd_in < 0) { - printf("Fail to open %s\n", - optarg); - show_help = 1; - } else - opts.is_file = true; - } else { - printf("Input file is missing!\n"); - show_help = 1; - } - if (lseek(opts.fd_in, 0, SEEK_SET) < 0) { - printf("Fail on lseek()!\n"); - show_help = 1; - } - break; - case 2: /* out */ - if (optarg) { - opts.fd_out = open(optarg, - O_CREAT | O_WRONLY, - S_IWUSR | S_IRGRP | - S_IROTH); - if (opts.fd_out < 0) { - printf("Fail to open %s\n", - optarg); - show_help = 1; - } else - opts.is_file = true; - } else { - printf("Output file is missing!\n"); - show_help = 1; - } - if (lseek(opts.fd_out, 0, SEEK_SET) < 0) { - printf("Fail on lseek()!\n"); - show_help = 1; - } - break; - case 3: /* ilist */ - if (!optarg) { - printf("IN list file is missing!\n"); - show_help = 1; - break; - } - opts.fd_ilist = open(optarg, O_RDONLY); - if (opts.fd_ilist < 0) { - printf("Fail to open %s\n", optarg); - show_help = 1; - break; - } - opts.is_file = true; - if (lseek(opts.fd_ilist, 0, SEEK_SET) < 0) { - printf("Fail on lseek()!\n"); - show_help = 1; - break; - } - break; - case 4: /* olist */ - if (!optarg) { - printf("OUT list file is missing!\n"); - show_help = 1; - break; - } - opts.fd_olist = open(optarg, - O_CREAT | O_WRONLY, - S_IWUSR | S_IRGRP | - S_IROTH); - if (opts.fd_olist < 0) { - printf("Fail to open %s\n", optarg); - show_help = 1; - break; - } - opts.is_file = true; - if (lseek(opts.fd_olist, 0, SEEK_SET) < 0) { - printf("Fail on lseek()!\n"); - show_help = 1; - break; - } - break; - case 5: /* env */ - opts.use_env = true; - break; - default: - show_help = 1; - break; - } - break; - case 'f': - if (strcmp(optarg, "none") == 0) { - opts.display_stats = STATS_NONE; - } else if (strcmp(optarg, "csv") == 0) { - opts.display_stats = STATS_CSV; - } else if (strcmp(optarg, "pretty") == 0) { - opts.display_stats = STATS_PRETTY; - } else { - SYS_ERR_COND(1, "invalid argument to -f: '%s'\n", optarg); - break; - } - break; - case 'o': - switch (optarg[0]) { - case 'p': - opts.option |= PERFORMANCE; - break; - case 't': - opts.option |= TEST_THP; - set_thp(&opts); - break; - default: - SYS_ERR_COND(1, "invalid argument to -o: '%s'\n", optarg); - break; - } - break; - case 'c': - opts.option |= TEST_ZLIB; - break; - case 'r': - opts.children = strtol(optarg, NULL, 0); - if (opts.children < 0) - show_help = 1; - break; - case 'k': - switch (optarg[0]) { - case 'b': - opts.faults |= INJECT_SIG_BIND; - break; - case 't': - opts.faults |= INJECT_TLB_FAULT; - break; - case 'w': - opts.faults |= INJECT_SIG_WORK; - break; - default: - SYS_ERR_COND(1, "invalid argument to -k: '%s'\n", optarg); - break; - } - break; - default: - show_help = parse_common_option(opt, optarg, &opts); - break; - } - } - - signal(SIGBUS, handle_sigbus); - - if (!show_help) { - if (self) - return run_self_test(&opts); - return run_cmd(&opts); - } - - hizip_test_adjust_len(&opts); - - SYS_ERR_COND(show_help || optind > argc, - COMMON_HELP - " -f <format> output format for the statistics\n" - " 'none' do not output statistics\n" - " 'pretty' human readable format\n" - " 'csv' raw, machine readable\n" - " -o <mode> options\n" - " 'perf' prefaults the output pages\n" - " 'thp' try to enable transparent huge pages\n" - " 'zlib' use zlib instead of the device\n" - " -r <children> number of children to create\n" - " -k <mode> kill thread\n" - " 'bind' kills the process after bind\n" - " 'tlb' tries to access an unmapped buffer\n" - " 'work' kills the process while the queue is working\n", - argv[0] - ); - return 0; -} \ No newline at end of file -- 2.33.0

From: Hao Fang <fanghao11@huawei.com> These need to be ignore: v1/test/hisi_hpre_test/hpre_test_tools_v1 v1/test/hisi_hpre_test/test_hisi_hpre_times_v1 v1/test/hisi_hpre_test/test_hisi_hpre_v1 v1/test/hisi_sec_test/test_hisi_sec_v1 v1/test/hisi_sec_test_sgl/test_hisi_sec_sgl_v1 v1/test/hisi_trng_test/test_hisi_trngk_v1 v1/test/hisi_trng_test/test_hisi_trngp_v1 v1/test/hisi_trng_test/test_hisi_trngu_v1 Signed-off-by: Hao Fang <fanghao11@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- .gitignore | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitignore b/.gitignore index 35180815..bb95cf75 100644 --- a/.gitignore +++ b/.gitignore @@ -175,6 +175,15 @@ v1/test/hisi_zip_test/wd_zip_test v1/test/hisi_zip_test_sgl/sgl_test v1/test/hisi_zip_test_sgl/wd_zip_test_sgl v1/test/test_mm/test_wd_mem +v1/test/bmm_test/bmm_test +v1/test/hisi_hpre_test/hpre_test_tools_v1 +v1/test/hisi_hpre_test/test_hisi_hpre_times_v1 +v1/test/hisi_hpre_test/test_hisi_hpre_v1 +v1/test/hisi_sec_test/test_hisi_sec_v1 +v1/test/hisi_sec_test_sgl/test_hisi_sec_sgl_v1 +v1/test/hisi_trng_test/test_hisi_trngk_v1 +v1/test/hisi_trng_test/test_hisi_trngp_v1 +v1/test/hisi_trng_test/test_hisi_trngu_v1 *.gcda *.ut *.eml -- 2.33.0

From: Hao Fang <fanghao11@huawei.com> The macro HAVE_CRYPTO is defined in config.h test_comp_entry() depends on this. Signed-off-by: Hao Fang <fanghao11@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- uadk_tool/test/uadk_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/uadk_tool/test/uadk_test.c b/uadk_tool/test/uadk_test.c index a4182aeb..536861a4 100644 --- a/uadk_tool/test/uadk_test.c +++ b/uadk_tool/test/uadk_test.c @@ -11,6 +11,7 @@ #include <sys/ipc.h> #include <sys/shm.h> +#include "config.h" #include "comp_main.h" #include "test_sec.h" -- 2.33.0

From: Hao Fang <fanghao11@huawei.com> The judement is incorrect. As a result, the x448 and x25519 alg process is intercepted. So just remove it. Signed-off-by: Hao Fang <fanghao11@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- uadk_tool/benchmark/hpre_uadk_benchmark.c | 32 ++++++++++------------- uadk_tool/benchmark/hpre_wd_benchmark.c | 32 ++++++++++------------- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/uadk_tool/benchmark/hpre_uadk_benchmark.c b/uadk_tool/benchmark/hpre_uadk_benchmark.c index 44d513da..da212b4b 100644 --- a/uadk_tool/benchmark/hpre_uadk_benchmark.c +++ b/uadk_tool/benchmark/hpre_uadk_benchmark.c @@ -2269,22 +2269,20 @@ static void *ecc_uadk_sync_run(void *arg) u32 count = 0; int ret; - memset(&sess_setup, 0, sizeof(sess_setup)); - memset(¶m, 0, sizeof(param)); - memset(&req, 0, sizeof(req)); + memset(&sess_setup, 0, sizeof(sess_setup)); + memset(¶m, 0, sizeof(param)); + memset(&req, 0, sizeof(req)); - memset(&setup, 0, sizeof(setup)); + memset(&setup, 0, sizeof(setup)); if (pdata->algtype == ECDH_256R1) cid = ECC_CURVE_SECP256R1; else cid = ECC_CURVE_SECP256K1; - if (subtype != X448_TYPE && subtype != X25519_TYPE) { - ret = get_ecc_curve(&setup, cid); - if (ret) - return NULL; - } + ret = get_ecc_curve(&setup, cid); + if (ret) + return NULL; sess_setup.key_bits = pdata->keybits; if (subtype == ECDH_TYPE || subtype == ECDSA_TYPE) { @@ -2434,22 +2432,20 @@ static void *ecc_uadk_async_run(void *arg) u32 count = 0; int i, ret; - memset(&sess_setup, 0, sizeof(sess_setup)); - memset(¶m, 0, sizeof(param)); - memset(&req, 0, sizeof(req)); + memset(&sess_setup, 0, sizeof(sess_setup)); + memset(¶m, 0, sizeof(param)); + memset(&req, 0, sizeof(req)); - memset(&setup, 0, sizeof(setup)); + memset(&setup, 0, sizeof(setup)); if (pdata->algtype == ECDH_256R1) cid = ECC_CURVE_SECP256R1; else cid = ECC_CURVE_SECP256K1; - if (subtype != X448_TYPE && subtype != X25519_TYPE) { - ret = get_ecc_curve(&setup, cid); - if (ret) - return NULL; - } + ret = get_ecc_curve(&setup, cid); + if (ret) + return NULL; sess_setup.key_bits = pdata->keybits; if (subtype == ECDH_TYPE || subtype == ECDSA_TYPE) { diff --git a/uadk_tool/benchmark/hpre_wd_benchmark.c b/uadk_tool/benchmark/hpre_wd_benchmark.c index 0196e62a..40f7f0b4 100644 --- a/uadk_tool/benchmark/hpre_wd_benchmark.c +++ b/uadk_tool/benchmark/hpre_wd_benchmark.c @@ -2107,19 +2107,17 @@ static void *ecc_wd_sync_run(void *arg) u32 count = 0; int ret; - memset(&ctx_setup, 0, sizeof(ctx_setup)); - memset(¶m, 0, sizeof(param)); - memset(&opdata, 0, sizeof(opdata)); + memset(&ctx_setup, 0, sizeof(ctx_setup)); + memset(¶m, 0, sizeof(param)); + memset(&opdata, 0, sizeof(opdata)); pool = g_thread_queue.bd_res[pdata->td_id].pool; queue = g_thread_queue.bd_res[pdata->td_id].queue; - memset(&setup, 0, sizeof(setup)); - if (subtype != X448_TYPE && subtype != X25519_TYPE) { - ret = get_ecc_curve(&setup, cid); - if (ret) - return NULL; - } + memset(&setup, 0, sizeof(setup)); + ret = get_ecc_curve(&setup, cid); + if (ret) + return NULL; ctx_setup.br.alloc = (void *)wd_alloc_blk; ctx_setup.br.free = (void *)wd_free_blk; @@ -2265,19 +2263,17 @@ static void *ecc_wd_async_run(void *arg) u32 count = 0; int i, ret; - memset(&ctx_setup, 0, sizeof(ctx_setup)); - memset(¶m, 0, sizeof(param)); - memset(&opdata, 0, sizeof(opdata)); + memset(&ctx_setup, 0, sizeof(ctx_setup)); + memset(¶m, 0, sizeof(param)); + memset(&opdata, 0, sizeof(opdata)); pool = g_thread_queue.bd_res[pdata->td_id].pool; queue = g_thread_queue.bd_res[pdata->td_id].queue; - memset(&setup, 0, sizeof(setup)); - if (subtype != X448_TYPE && subtype != X25519_TYPE) { - ret = get_ecc_curve(&setup, cid); - if (ret) - return NULL; - } + memset(&setup, 0, sizeof(setup)); + ret = get_ecc_curve(&setup, cid); + if (ret) + return NULL; ctx_setup.cb = (void *)ecc_async_cb; ctx_setup.br.alloc = (void *)wd_alloc_blk; -- 2.33.0

From: Wenkai Lin <linwenkai6@hisilicon.com> The implementation of the SM3 algorithm requires 64B alignment of the first packet or middle packet, if the user use unaligned data, it should intercepted. Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/isa_ce_sm3.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drv/isa_ce_sm3.c b/drv/isa_ce_sm3.c index 68be912a..84ae2854 100644 --- a/drv/isa_ce_sm3.c +++ b/drv/isa_ce_sm3.c @@ -19,6 +19,8 @@ #include "wd_digest.h" #include "wd_util.h" +#define SM3_ALIGN_MASK 63U + typedef void (sm3_ce_block_fn)(__u32 word_reg[SM3_STATE_WORDS], const unsigned char *src, size_t blocks); @@ -348,6 +350,13 @@ static int sm3_ce_drv_send(struct wd_alg_driver *drv, handle_t ctx, void *digest return -WD_EINVAL; } + if (msg->has_next) { + if (msg->in_bytes & SM3_ALIGN_MASK) { + WD_ERR("input data isn't aligned, size = %u\n", msg->in_bytes); + return -WD_EINVAL; + } + } + if (msg->mode == WD_DIGEST_NORMAL) { ret = do_sm3_ce(msg, digest); } else if (msg->mode == WD_DIGEST_HMAC) { -- 2.33.0

From: Longfang Liu <liulongfang@huawei.com> In UADK's algorithm registration framework, the specific algorithm driver name should be decoupled from the framework to prevent compatibility issues. Additionally, the filtering rules when the framework opens the driver SO file need to be updated to prevent errors caused by extremely short file names. Signed-off-by: Longfang Liu <liulongfang@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- drv/isa_ce_sm3.c | 1 + wd_alg.c | 17 ++++++++------ wd_util.c | 58 ++++++++++++++++++++++++------------------------ 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/drv/isa_ce_sm3.c b/drv/isa_ce_sm3.c index 84ae2854..0e88b614 100644 --- a/drv/isa_ce_sm3.c +++ b/drv/isa_ce_sm3.c @@ -57,6 +57,7 @@ static void __attribute__((constructor)) sm3_ce_probe(void) static void __attribute__((destructor)) sm3_ce_remove(void) { + WD_INFO("Info: unregister SM3 CE alg drivers!\n"); wd_alg_driver_unregister(&sm3_ce_alg_driver); } diff --git a/wd_alg.c b/wd_alg.c index a33f5d66..a2999e36 100644 --- a/wd_alg.c +++ b/wd_alg.c @@ -91,7 +91,7 @@ static bool wd_check_accel_dev(const char *dev_name) return false; } -static bool wd_check_ce_support(const char *dev_name) +static bool wd_check_ce_support(const char *alg_name) { unsigned long hwcaps = 0; @@ -100,10 +100,10 @@ static bool wd_check_ce_support(const char *dev_name) #elif defined(__aarch64__) hwcaps = getauxval(AT_HWCAP); #endif - if (!strcmp("isa_ce_sm3", dev_name) && (hwcaps & HWCAP_CE_SM3)) + if (!strcmp("sm3", alg_name) && (hwcaps & HWCAP_CE_SM3)) return true; - if (!strcmp("isa_ce_sm4", dev_name) && (hwcaps & HWCAP_CE_SM4)) + if (!strcmp("sm4", alg_name) && (hwcaps & HWCAP_CE_SM4)) return true; return false; @@ -122,7 +122,8 @@ static bool wd_check_sve_support(void) return false; } -static bool wd_alg_check_available(int calc_type, const char *dev_name) +static bool wd_alg_check_available(int calc_type, + const char *alg_name, const char *dev_name) { bool ret = false; @@ -131,7 +132,7 @@ static bool wd_alg_check_available(int calc_type, const char *dev_name) break; /* Should find the CPU if not support CE */ case UADK_ALG_CE_INSTR: - ret = wd_check_ce_support(dev_name); + ret = wd_check_ce_support(alg_name); break; /* Should find the CPU if not support SVE */ case UADK_ALG_SVE_INSTR: @@ -217,7 +218,8 @@ int wd_alg_driver_register(struct wd_alg_driver *drv) new_alg->refcnt = 0; new_alg->next = NULL; - new_alg->available = wd_alg_check_available(drv->calc_type, drv->drv_name); + new_alg->available = wd_alg_check_available(drv->calc_type, + drv->alg_name, drv->drv_name); if (!new_alg->available) { free(new_alg); return -WD_ENODEV; @@ -307,7 +309,8 @@ void wd_enable_drv(struct wd_alg_driver *drv) } if (pnext) - pnext->available = wd_alg_check_available(drv->calc_type, drv->drv_name); + pnext->available = wd_alg_check_available(drv->calc_type, + drv->alg_name, drv->drv_name); pthread_mutex_unlock(&mutex); } diff --git a/wd_util.c b/wd_util.c index af4d949b..01536f4c 100644 --- a/wd_util.c +++ b/wd_util.c @@ -1901,35 +1901,6 @@ static void wd_get_alg_type(const char *alg_name, char *alg_type) } } -/** - * There are many other .so files in this file directory (/root/lib/), - * and it is necessary to screen out valid uadk driver files - * through this function. - */ -static int file_check_valid(char *lib_file) -{ -#define FILE_HEAD_SZ 4 -#define FILE_TAIL_SZ 4 - int file_len = strlen(lib_file); - char file_head[FILE_HEAD_SZ] = "lib"; - char file_tail[FILE_TAIL_SZ] = ".so"; - int i, j; - - /* Lib file name is libxx_xxx.so */ - for (i = 0; i < FILE_HEAD_SZ - 1; i++) { - if (lib_file[i] != file_head[i]) - return -EINVAL; - } - - for (i = file_len - (FILE_TAIL_SZ - 1), j = 0; - i < file_len && j < FILE_TAIL_SZ; i++, j++) { - if (lib_file[i] != file_tail[j]) - return -EINVAL; - } - - return 0; -} - static int wd_alg_init_fallback(struct wd_alg_driver *fb_driver) { if (!fb_driver->init) { @@ -2222,6 +2193,34 @@ int wd_get_lib_file_path(const char *lib_file, char *lib_path, bool is_dir) return 0; } +/** + * There are many other .so files in this file directory (/root/lib/), + * and it is necessary to screen out valid uadk driver files + * through this function. + */ +static int file_check_valid(const char *lib_file) +{ +#define MIN_FILE_LEN 6 +#define FILE_TAIL_LEN 3 + const char *dot = strrchr(lib_file, '.'); + size_t len; + + /* Check if the filename length is sufficient. */ + len = strlen(lib_file); + if (len < MIN_FILE_LEN) + return -EINVAL; + + /* Check if it starts with "lib". */ + if (strncmp(lib_file, "lib", FILE_TAIL_LEN) != 0) + return -EINVAL; + + /* Check if it ends with ".so". */ + if (!dot || strcmp(dot, ".so") != 0) + return -EINVAL; + + return 0; +} + void *wd_dlopen_drv(const char *cust_lib_dir) { typedef int (*alg_ops)(struct wd_alg_driver *drv); @@ -2243,6 +2242,7 @@ void *wd_dlopen_drv(const char *cust_lib_dir) return NULL; } strncpy(lib_dir_path, cust_lib_dir, PATH_MAX - 1); + lib_dir_path[PATH_MAX - 1] = '\0'; } wd_dir = opendir(lib_dir_path); -- 2.33.0

From: Longfang Liu <liulongfang@huawei.com> When registering the SM4 algorithm in UADK, the algorithm name will be in the format xxx(sm4), such as cbc(sm4) or ctr(sm4). Therefore, when checking the process algorithm instruction, to determine if it's an SM4 algorithm, we need to match the trailing characters of the algorithm name. Signed-off-by: Longfang Liu <liulongfang@huawei.com> Signed-off-by: Qi Tao <taoqi10@huawei.com> --- wd_alg.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/wd_alg.c b/wd_alg.c index a2999e36..b465e719 100644 --- a/wd_alg.c +++ b/wd_alg.c @@ -94,6 +94,9 @@ static bool wd_check_accel_dev(const char *dev_name) static bool wd_check_ce_support(const char *alg_name) { unsigned long hwcaps = 0; + const char *alg_tail; + size_t tail_len; + size_t alg_len; #if defined(__arm__) || defined(__arm) hwcaps = getauxval(AT_HWCAP2); @@ -103,7 +106,13 @@ static bool wd_check_ce_support(const char *alg_name) if (!strcmp("sm3", alg_name) && (hwcaps & HWCAP_CE_SM3)) return true; - if (!strcmp("sm4", alg_name) && (hwcaps & HWCAP_CE_SM4)) + alg_len = strlen(alg_name); + tail_len = strlen("(sm4)"); + if (alg_len <= tail_len) + return false; + + alg_tail = alg_name + (alg_len - tail_len); + if (!strcmp("(sm4)", alg_tail) && (hwcaps & HWCAP_CE_SM4)) return true; return false; -- 2.33.0

Solve the compilation warning problem. Signed-off-by: Qi Tao <taoqi10@huawei.com> --- v1/wd_aead.c | 2 +- wd_util.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/v1/wd_aead.c b/v1/wd_aead.c index 2b98547f..cb36a166 100644 --- a/v1/wd_aead.c +++ b/v1/wd_aead.c @@ -472,7 +472,7 @@ static int check_op_data(struct wcrypto_aead_op_data **op, } } if (unlikely(op[idx]->state >= WCRYPTO_AEAD_MSG_INVALID)) { - WD_ERR("fail to check message state: %d, idx: %u!\n", + WD_ERR("fail to check message state: %u, idx: %u!\n", op[idx]->state, idx); return -WD_EINVAL; } else if (idx && op[idx]->state != WCRYPTO_AEAD_MSG_BLOCK) { diff --git a/wd_util.c b/wd_util.c index 01536f4c..1992a5d4 100644 --- a/wd_util.c +++ b/wd_util.c @@ -1891,7 +1891,7 @@ int wd_init_param_check(struct wd_ctx_config *config, struct wd_sched *sched) static void wd_get_alg_type(const char *alg_name, char *alg_type) { - int i; + __u64 i; for (i = 0; i < ARRAY_SIZE(alg_options); i++) { if (strcmp(alg_name, alg_options[i].name) == 0) { -- 2.33.0
participants (1)
-
Qi Tao