已开启
uadk: fix memory safety, BD3 stream issues and optimize ctx scheduling #128
dorei_bin创建于 11 天前
uadk: fix memory safety, BD3 stream issues and optimize ctx scheduling #128
已开启
共 16 个文件变更+2153-1
| @@ -0,0 +1,78 @@ | |||
| 1 | +From 5eb5a55de2020692104cc0cb8c76499df9d63256 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Junchong Pan <panjunchong@h-partners.com> | ||
| 3 | +Date: Wed, 2 Sep 2026 14:16:07 +0800 | ||
| 4 | +Subject: [PATCH 23/37] uadk: fix -Wmaybe-uninitialized and -Wsign-compare | ||
| 5 | + warnings | ||
| 6 | + | ||
| 7 | +Initialize ret to 0 in wd_ctx_param_init() to fix -Wmaybe-uninitialized | ||
| 8 | +warning. Change ret type from int to size_t in get_str_attr() to fix | ||
| 9 | +-Wsign-compare warning. Move sched_uninit and set_param to the end of | ||
| 10 | +struct wd_sched to maintain ABI compatibility. | ||
| 11 | + | ||
| 12 | +Signed-off-by: Junchong Pan <panjunchong@h-partners.com> | ||
| 13 | +Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> | ||
| 14 | +--- | ||
| 15 | + include/wd_alg_common.h | 4 ++-- | ||
| 16 | + wd.c | 2 +- | ||
| 17 | + wd_util.c | 5 +++-- | ||
| 18 | + 3 files changed, 6 insertions(+), 5 deletions(-) | ||
| 19 | + | ||
| 20 | +diff --git a/include/wd_alg_common.h b/include/wd_alg_common.h | ||
| 21 | +index 05cc5c0..f0e13bb 100644 | ||
| 22 | +--- a/include/wd_alg_common.h | ||
| 23 | ++++ b/include/wd_alg_common.h | ||
| 24 | +@@ -165,13 +165,13 @@ struct wd_sched { | ||
| 25 | + const char *name; | ||
| 26 | + int sched_policy; | ||
| 27 | + handle_t (*sched_init)(handle_t h_sched_ctx, void *sched_param); | ||
| 28 | +- void (*sched_uninit)(handle_t h_sched_ctx, handle_t h_sched_key); | ||
| 29 | + __u32 (*pick_next_ctx)(handle_t h_sched_ctx, | ||
| 30 | + void *sched_key, | ||
| 31 | + const int sched_mode); | ||
| 32 | + int (*poll_policy)(handle_t h_sched_ctx, __u32 expect, __u32 *count); | ||
| 33 | +- void (*set_param)(handle_t h_sched_ctx, void *sched_key, void *sched_param); | ||
| 34 | + handle_t h_sched_ctx; | ||
| 35 | ++ void (*sched_uninit)(handle_t h_sched_ctx, handle_t h_sched_key); | ||
| 36 | ++ void (*set_param)(handle_t h_sched_ctx, void *sched_key, void *sched_param); | ||
| 37 | + }; | ||
| 38 | + | ||
| 39 | + typedef int (*wd_alg_init)(struct wd_ctx_config *config, struct wd_sched *sched); | ||
| 40 | +diff --git a/wd.c b/wd.c | ||
| 41 | +index f973c70..1c28bb3 100644 | ||
| 42 | +--- a/wd.c | ||
| 43 | ++++ b/wd.c | ||
| 44 | +@@ -203,7 +203,7 @@ static int get_int_attr(struct uacce_dev *dev, const char *attr, int *val) | ||
| 45 | + static int get_str_attr(struct uacce_dev *dev, const char *attr, char *buf, | ||
| 46 | + size_t buf_sz) | ||
| 47 | + { | ||
| 48 | +- int ret; | ||
| 49 | ++ size_t ret; | ||
| 50 | + int size; | ||
| 51 | + | ||
| 52 | + size = get_raw_attr(dev->dev_root, attr, buf, buf_sz); | ||
| 53 | +diff --git a/wd_util.c b/wd_util.c | ||
| 54 | +index 1b4c74e..bf6d380 100644 | ||
| 55 | +--- a/wd_util.c | ||
| 56 | ++++ b/wd_util.c | ||
| 57 | +@@ -1765,7 +1765,7 @@ static int wd_env_set_ctx_nums(const char *alg_name, const char *name, const cha | ||
| 58 | + { | ||
| 59 | + char *left, *section, *start; | ||
| 60 | + int is_comp; | ||
| 61 | +- int ret; | ||
| 62 | ++ int ret = 0; | ||
| 63 | + | ||
| 64 | + /* COMP environment variable's format is different, mark it */ | ||
| 65 | + is_comp = strncmp(name, "WD_COMP_CTX_NUM", sizeof("WD_COMP_CTX_NUM") - 1) ? 0 : 1; | ||
| 66 | +@@ -1799,7 +1799,8 @@ int wd_ctx_param_init(struct wd_ctx_params *ctx_params, | ||
| 67 | + { | ||
| 68 | + const char *env_name = wd_env_name[type]; | ||
| 69 | + const char *var_s; | ||
| 70 | +- int i, ret; | ||
| 71 | ++ int ret = 0; | ||
| 72 | ++ int i; | ||
| 73 | + | ||
| 74 | + ctx_params->bmp = numa_allocate_nodemask(); | ||
| 75 | + if (!ctx_params->bmp) { | ||
| 76 | +-- | ||
| 77 | +2.25.1 | ||
| 78 | + | ||
| @@ -0,0 +1,432 @@ | |||
| 1 | +From 090ec971cd35aac3bab33043f63cb0a1ece77da8 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Chenghai Huang <huangchenghai2@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:36 +0800 | ||
| 4 | +Subject: [PATCH 24/37] uadk: bind sync/async ctx to same device under | ||
| 5 | + SCHED_POLICY_DEV | ||
| 6 | + | ||
| 7 | +Under SCHED_POLICY_DEV, allocating sync then async ctxs in two passes | ||
| 8 | +let concurrent contention split them across devices, leaving the async | ||
| 9 | +domain empty (async picks returned 65535, sends failed with -22). | ||
| 10 | + | ||
| 11 | +Add a DEV-only path that opens sync/async ctxs interleaved on ONE device: | ||
| 12 | +the first ctx auto-selects via NUMA scan, its dev_path pins every later | ||
| 13 | +ctx through preferred_dev_path, and wd_hw_alloc_ctx opens that device | ||
| 14 | +without NUMA fallback. Other policies unchanged. | ||
| 15 | + | ||
| 16 | +Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> | ||
| 17 | +--- | ||
| 18 | + drv/wd_drv.c | 26 +++++ | ||
| 19 | + include/wd_alg.h | 3 + | ||
| 20 | + wd_util.c | 283 ++++++++++++++++++++++++++++++++++++++--------- | ||
| 21 | + 3 files changed, 261 insertions(+), 51 deletions(-) | ||
| 22 | + | ||
| 23 | +diff --git a/drv/wd_drv.c b/drv/wd_drv.c | ||
| 24 | +index 381cee1..c839ed4 100644 | ||
| 25 | +--- a/drv/wd_drv.c | ||
| 26 | ++++ b/drv/wd_drv.c | ||
| 27 | +@@ -220,6 +220,32 @@ int wd_hw_alloc_ctx(char *alg_name, void *params, handle_t *ctx) | ||
| 28 | + goto out; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | ++ /* | ||
| 32 | ++ * Preferred-device binding (SCHED_POLICY_DEV): open exactly this device | ||
| 33 | ++ * and fail strictly if unavailable, so the sync and async ctxs of one | ||
| 34 | ++ * (driver, op_type, numa) stay on the same device. No NUMA fallback. | ||
| 35 | ++ */ | ||
| 36 | ++ if (ctx_params->preferred_dev_path) { | ||
| 37 | ++ for (curr = used_list; curr; curr = curr->next) { | ||
| 38 | ++ if (curr->dev && !strcmp(curr->dev->char_dev_path, | ||
| 39 | ++ ctx_params->preferred_dev_path)) | ||
| 40 | ++ break; | ||
| 41 | ++ } | ||
| 42 | ++ | ||
| 43 | ++ if (!curr) { | ||
| 44 | ++ ret = -WD_ENODEV; | ||
| 45 | ++ goto out; | ||
| 46 | ++ } | ||
| 47 | ++ | ||
| 48 | ++ hctx = wd_request_ctx(curr->dev); | ||
| 49 | ++ if (!hctx) { | ||
| 50 | ++ ret = -WD_EBUSY; | ||
| 51 | ++ goto out; | ||
| 52 | ++ } | ||
| 53 | ++ | ||
| 54 | ++ goto success; | ||
| 55 | ++ } | ||
| 56 | ++ | ||
| 57 | + curr = used_list; | ||
| 58 | + while (curr) { | ||
| 59 | + if (curr->dev) { | ||
| 60 | +diff --git a/include/wd_alg.h b/include/wd_alg.h | ||
| 61 | +index b256a2f..3cc4e43 100644 | ||
| 62 | +--- a/include/wd_alg.h | ||
| 63 | ++++ b/include/wd_alg.h | ||
| 64 | +@@ -96,6 +96,8 @@ enum alg_drv_type { | ||
| 65 | + * @ctx_mode: CTX_MODE_SYNC or CTX_MODE_ASYNC | ||
| 66 | + * @op_type: Operation type | ||
| 67 | + * @bmp: NUMA node bitmask (optional, NULL if not needed) | ||
| 68 | ++ * @preferred_dev_path: Preferred device char_dev_path; NULL/empty = auto-select, | ||
| 69 | ++ * non-empty = open only this device and fail strictly if unavailable | ||
| 70 | + */ | ||
| 71 | + struct wd_drv_ctx_params { | ||
| 72 | + __u8 ctx_mode; | ||
| 73 | +@@ -103,6 +105,7 @@ struct wd_drv_ctx_params { | ||
| 74 | + int numa_id; | ||
| 75 | + bool epoll_en; | ||
| 76 | + struct bitmask *bmp; | ||
| 77 | ++ const char *preferred_dev_path; | ||
| 78 | + }; | ||
| 79 | + | ||
| 80 | + /** | ||
| 81 | +diff --git a/wd_util.c b/wd_util.c | ||
| 82 | +index bf6d380..cc89837 100644 | ||
| 83 | +--- a/wd_util.c | ||
| 84 | ++++ b/wd_util.c | ||
| 85 | +@@ -2614,17 +2614,17 @@ static int wd_alg_sched_instance(struct wd_sched *sched, | ||
| 86 | + return WD_SUCCESS; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | +-static void wd_free_ctxs_batch(struct wd_init_attrs *attrs, | ||
| 90 | +- __u32 allocated_count) | ||
| 91 | ++static void wd_free_ctxs_batch_range(struct wd_init_attrs *attrs, | ||
| 92 | ++ __u32 start_idx, __u32 end_idx) | ||
| 93 | + { | ||
| 94 | + struct wd_ctx_config_internal *internal_config = attrs->ctx_config_internal; | ||
| 95 | + struct wd_alg_driver *drv; | ||
| 96 | + __u32 i; | ||
| 97 | + | ||
| 98 | +- if (!internal_config || !internal_config->ctxs || !allocated_count) | ||
| 99 | ++ if (!internal_config || !internal_config->ctxs || start_idx >= end_idx) | ||
| 100 | + return; | ||
| 101 | + | ||
| 102 | +- for (i = 0; i < allocated_count; i++) { | ||
| 103 | ++ for (i = start_idx; i < end_idx; i++) { | ||
| 104 | + if (!internal_config->ctxs[i].ctx) | ||
| 105 | + continue; | ||
| 106 | + | ||
| 107 | +@@ -2636,21 +2636,76 @@ static void wd_free_ctxs_batch(struct wd_init_attrs *attrs, | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | ++static void wd_free_ctxs_batch(struct wd_init_attrs *attrs, | ||
| 112 | ++ __u32 allocated_count) | ||
| 113 | ++{ | ||
| 114 | ++ wd_free_ctxs_batch_range(attrs, 0, allocated_count); | ||
| 115 | ++} | ||
| 116 | ++ | ||
| 117 | ++static void wd_collect_numa_nodes(struct bitmask *bmp, int *numa_nodes, | ||
| 118 | ++ __u8 *numa_count) | ||
| 119 | ++{ | ||
| 120 | ++ int max_node, n; | ||
| 121 | ++ | ||
| 122 | ++ max_node = numa_max_node() + 1; | ||
| 123 | ++ if (max_node <= 0 || max_node > UADK_MAX_NUMA_NODES) | ||
| 124 | ++ max_node = UADK_MAX_NUMA_NODES; | ||
| 125 | ++ | ||
| 126 | ++ *numa_count = 0; | ||
| 127 | ++ | ||
| 128 | ++ for (n = 0; n < max_node; n++) { | ||
| 129 | ++ if (numa_bitmask_isbitset(bmp, n)) | ||
| 130 | ++ numa_nodes[(*numa_count)++] = n; | ||
| 131 | ++ } | ||
| 132 | ++ | ||
| 133 | ++ if (!*numa_count) { | ||
| 134 | ++ numa_nodes[0] = 0; | ||
| 135 | ++ *numa_count = 1; | ||
| 136 | ++ } | ||
| 137 | ++} | ||
| 138 | ++ | ||
| 139 | ++static int wd_alloc_one_ctx(struct wd_init_attrs *attrs, | ||
| 140 | ++ struct wd_alg_driver *drv, | ||
| 141 | ++ struct wd_drv_ctx_params *dparams, | ||
| 142 | ++ __u32 *ctx_idx) | ||
| 143 | ++{ | ||
| 144 | ++ struct wd_ctx_config_internal *internal_config = attrs->ctx_config_internal; | ||
| 145 | ++ handle_t ctx; | ||
| 146 | ++ int ret; | ||
| 147 | ++ | ||
| 148 | ++ ret = drv->alloc_ctx(attrs->alg, dparams, &ctx); | ||
| 149 | ++ if (ret < 0) | ||
| 150 | ++ return ret; | ||
| 151 | ++ | ||
| 152 | ++ if (!ctx) | ||
| 153 | ++ return -WD_EINVAL; | ||
| 154 | ++ | ||
| 155 | ++ internal_config->ctxs[*ctx_idx].ctx = ctx; | ||
| 156 | ++ internal_config->ctxs[*ctx_idx].op_type = dparams->op_type; | ||
| 157 | ++ internal_config->ctxs[*ctx_idx].ctx_mode = dparams->ctx_mode; | ||
| 158 | ++ internal_config->ctxs[*ctx_idx].ctx_type = drv->calc_type; | ||
| 159 | ++ internal_config->ctxs[*ctx_idx].drv = drv; | ||
| 160 | ++ (*ctx_idx)++; | ||
| 161 | ++ return WD_SUCCESS; | ||
| 162 | ++} | ||
| 163 | ++ | ||
| 164 | + static int wd_alloc_single_drv_ctxs(struct wd_init_attrs *attrs, | ||
| 165 | + struct wd_alg_driver *drv, | ||
| 166 | + __u8 ctx_mode, __u8 op_type, | ||
| 167 | + __u32 *ctx_idx) | ||
| 168 | + { | ||
| 169 | +- struct wd_ctx_config_internal *internal_config = attrs->ctx_config_internal; | ||
| 170 | + struct wd_ctx_params *ctx_params = attrs->ctx_params; | ||
| 171 | +- struct wd_drv_ctx_params dparams; | ||
| 172 | ++ struct wd_drv_ctx_params dparams = {0}; | ||
| 173 | + int numa_nodes[UADK_MAX_NUMA_NODES]; | ||
| 174 | +- __u32 mode_ctx_num, numa_count = 0; | ||
| 175 | +- __u32 numa_idx, j; | ||
| 176 | +- int max_node, n; | ||
| 177 | +- handle_t ctx; | ||
| 178 | ++ __u32 mode_ctx_num, numa_idx, j; | ||
| 179 | ++ __u8 numa_count; | ||
| 180 | + int ret; | ||
| 181 | + | ||
| 182 | ++ dparams.ctx_mode = ctx_mode; | ||
| 183 | ++ dparams.op_type = op_type; | ||
| 184 | ++ dparams.bmp = ctx_params->bmp; | ||
| 185 | ++ dparams.epoll_en = false; | ||
| 186 | ++ | ||
| 187 | + if (ctx_mode == CTX_MODE_SYNC) | ||
| 188 | + mode_ctx_num = ctx_params->ctx_set_num[op_type].sync_ctx_num; | ||
| 189 | + else | ||
| 190 | +@@ -2662,46 +2717,26 @@ static int wd_alloc_single_drv_ctxs(struct wd_init_attrs *attrs, | ||
| 191 | + attrs->sched_type == SCHED_POLICY_SINGLE) && mode_ctx_num > 1) | ||
| 192 | + mode_ctx_num = 1; | ||
| 193 | + | ||
| 194 | +- if (drv->calc_type == UADK_ALG_HW) { | ||
| 195 | +- max_node = numa_max_node() + 1; | ||
| 196 | +- if (max_node <= 0 || max_node > UADK_MAX_NUMA_NODES) | ||
| 197 | +- max_node = UADK_MAX_NUMA_NODES; | ||
| 198 | +- for (n = 0; n < max_node; n++) { | ||
| 199 | +- if (numa_bitmask_isbitset(ctx_params->bmp, n)) | ||
| 200 | +- numa_nodes[numa_count++] = n; | ||
| 201 | +- } | ||
| 202 | +- } else { | ||
| 203 | +- numa_nodes[0] = 0; | ||
| 204 | +- numa_count = 1; | ||
| 205 | +- } | ||
| 206 | +- if (!numa_count) { | ||
| 207 | ++ if (drv->calc_type != UADK_ALG_HW) { | ||
| 208 | + numa_nodes[0] = 0; | ||
| 209 | + numa_count = 1; | ||
| 210 | ++ } else { | ||
| 211 | ++ wd_collect_numa_nodes(ctx_params->bmp, numa_nodes, &numa_count); | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + for (numa_idx = 0; numa_idx < numa_count; numa_idx++) { | ||
| 215 | ++ dparams.numa_id = numa_nodes[numa_idx]; | ||
| 216 | ++ | ||
| 217 | + for (j = 0; j < mode_ctx_num; j++) { | ||
| 218 | +- memset(&dparams, 0, sizeof(dparams)); | ||
| 219 | +- dparams.ctx_mode = ctx_mode; | ||
| 220 | +- dparams.op_type = op_type; | ||
| 221 | +- dparams.numa_id = numa_nodes[numa_idx]; | ||
| 222 | +- dparams.bmp = ctx_params->bmp; | ||
| 223 | +- dparams.epoll_en = false; | ||
| 224 | +- ret = drv->alloc_ctx(attrs->alg, &dparams, &ctx); | ||
| 225 | +- if (!ctx || ret < 0) { | ||
| 226 | +- if (ret == -WD_ENODEV) | ||
| 227 | +- break; | ||
| 228 | ++ ret = wd_alloc_one_ctx(attrs, drv, &dparams, ctx_idx); | ||
| 229 | ++ if (ret == -WD_ENODEV) | ||
| 230 | ++ break; | ||
| 231 | ++ | ||
| 232 | ++ if (ret) { | ||
| 233 | + WD_ERR("failed to alloc ctx %u from driver %s on numa %d!\n", | ||
| 234 | + *ctx_idx, drv->drv_name, numa_nodes[numa_idx]); | ||
| 235 | + return ret; | ||
| 236 | + } | ||
| 237 | +- | ||
| 238 | +- internal_config->ctxs[*ctx_idx].ctx = ctx; | ||
| 239 | +- internal_config->ctxs[*ctx_idx].op_type = dparams.op_type; | ||
| 240 | +- internal_config->ctxs[*ctx_idx].ctx_mode = dparams.ctx_mode; | ||
| 241 | +- internal_config->ctxs[*ctx_idx].ctx_type = drv->calc_type; | ||
| 242 | +- internal_config->ctxs[*ctx_idx].drv = drv; | ||
| 243 | +- (*ctx_idx)++; | ||
| 244 | + } | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | +@@ -2750,6 +2785,146 @@ err_ctxs: | ||
| 248 | + return ret; | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | ++/* | ||
| 252 | ++ * SCHED_POLICY_DEV: open sync/async ctxs of (drv, op_type, numa) interleaved on | ||
| 253 | ++ * ONE device. The caller pins the device via dparams->preferred_dev_path. | ||
| 254 | ++ * Stop when both counts are met or the device is full. If both modes are | ||
| 255 | ++ * requested but only one could be opened, roll back and return -WD_ENODEV so | ||
| 256 | ++ * the caller can try the next device; partial within one mode is kept. | ||
| 257 | ++ */ | ||
| 258 | ++static int wd_alloc_dev_group(struct wd_init_attrs *attrs, | ||
| 259 | ++ struct wd_alg_driver *drv, | ||
| 260 | ++ struct wd_drv_ctx_params *dparams, | ||
| 261 | ++ __u32 *ctx_idx) | ||
| 262 | ++{ | ||
| 263 | ++ struct wd_ctx_nums *nums = &attrs->ctx_params->ctx_set_num[dparams->op_type]; | ||
| 264 | ++ __u32 want[2] = {nums->sync_ctx_num, nums->async_ctx_num}; | ||
| 265 | ++ __u8 modes[2] = {CTX_MODE_SYNC, CTX_MODE_ASYNC}; | ||
| 266 | ++ __u32 group_start = *ctx_idx; | ||
| 267 | ++ __u32 done[2] = {0, 0}; | ||
| 268 | ++ __u32 i; | ||
| 269 | ++ int ret; | ||
| 270 | ++ | ||
| 271 | ++ while (done[0] < want[0] || done[1] < want[1]) { | ||
| 272 | ++ for (i = 0; i < 2; i++) { | ||
| 273 | ++ if (done[i] >= want[i]) | ||
| 274 | ++ continue; | ||
| 275 | ++ | ||
| 276 | ++ dparams->ctx_mode = modes[i]; | ||
| 277 | ++ ret = wd_alloc_one_ctx(attrs, drv, dparams, ctx_idx); | ||
| 278 | ++ if (ret) { | ||
| 279 | ++ if (ret != -WD_EBUSY && ret != -WD_ENODEV) | ||
| 280 | ++ return ret; | ||
| 281 | ++ /* | ||
| 282 | ++ * Device full. If both modes were requested | ||
| 283 | ++ * but only one got ctxs, the empty domain | ||
| 284 | ++ * would cause idx 65535 at runtime. Roll back | ||
| 285 | ++ * this group so the caller tries another dev. | ||
| 286 | ++ */ | ||
| 287 | ++ if (want[0] && want[1] && | ||
| 288 | ++ (!done[0] || !done[1])) { | ||
| 289 | ++ wd_free_ctxs_batch_range(attrs, group_start, *ctx_idx); | ||
| 290 | ++ *ctx_idx = group_start; | ||
| 291 | ++ return -WD_ENODEV; | ||
| 292 | ++ } | ||
| 293 | ++ return WD_SUCCESS; | ||
| 294 | ++ } | ||
| 295 | ++ done[i]++; | ||
| 296 | ++ } | ||
| 297 | ++ } | ||
| 298 | ++ return WD_SUCCESS; | ||
| 299 | ++} | ||
| 300 | ++ | ||
| 301 | ++/* | ||
| 302 | ++ * SCHED_POLICY_DEV: per (drv, op_type, numa) open sync/async on one device | ||
| 303 | ++ * (interleaved, partial allowed). Enumerates devices on each numa node and | ||
| 304 | ++ * pins each group to one device via preferred_dev_path, trying the next | ||
| 305 | ++ * device if the current one cannot hold both modes. | ||
| 306 | ++ */ | ||
| 307 | ++static int wd_alloc_ctxs_batch_dev(struct wd_init_attrs *attrs, __u32 *start_idx) | ||
| 308 | ++{ | ||
| 309 | ++ struct wd_ctx_config_internal *internal_config = attrs->ctx_config_internal; | ||
| 310 | ++ struct wd_ctx_params *ctx_params = attrs->ctx_params; | ||
| 311 | ++ struct uacce_dev_list *dev_list, *p; | ||
| 312 | ++ int numa_nodes[UADK_MAX_NUMA_NODES]; | ||
| 313 | ++ char alg_type[CRYPTO_MAX_ALG_NAME]; | ||
| 314 | ++ struct wd_drv_ctx_params dparams; | ||
| 315 | ++ __u32 ctx_idx, drv_idx, start; | ||
| 316 | ++ struct wd_alg_driver *drv; | ||
| 317 | ++ __u8 op_type, numa_count; | ||
| 318 | ++ struct wd_ctx_nums *nums; | ||
| 319 | ++ int n, ret; | ||
| 320 | ++ | ||
| 321 | ++ memset(&dparams, 0, sizeof(dparams)); | ||
| 322 | ++ dparams.bmp = ctx_params->bmp; | ||
| 323 | ++ dparams.epoll_en = false; | ||
| 324 | ++ | ||
| 325 | ++ start = *start_idx; | ||
| 326 | ++ ctx_idx = start; | ||
| 327 | ++ for (drv_idx = 0; drv_idx < internal_config->drv_count; drv_idx++) { | ||
| 328 | ++ drv = internal_config->drv_array[drv_idx]; | ||
| 329 | ++ if (!drv || !drv->alloc_ctx) { | ||
| 330 | ++ WD_ERR("failed to check driver %s alloc_ctx!\n", | ||
| 331 | ++ drv ? drv->drv_name : "unknown"); | ||
| 332 | ++ ret = -WD_EINVAL; | ||
| 333 | ++ goto err_ctxs; | ||
| 334 | ++ } | ||
| 335 | ++ if (drv->calc_type != UADK_ALG_HW) | ||
| 336 | ++ continue; | ||
| 337 | ++ | ||
| 338 | ++ ret = wd_get_alg_type(attrs->alg, alg_type); | ||
| 339 | ++ if (ret) { | ||
| 340 | ++ ret = -WD_EINVAL; | ||
| 341 | ++ goto err_ctxs; | ||
| 342 | ++ } | ||
| 343 | ++ if (!strcmp(alg_type, "ecc")) | ||
| 344 | ++ (void)strcpy(alg_type, "sm2"); | ||
| 345 | ++ if (!strcmp(alg_type, "comp")) | ||
| 346 | ++ (void)strcpy(alg_type, "zlib"); | ||
| 347 | ++ | ||
| 348 | ++ dev_list = wd_get_accel_list(alg_type); | ||
| 349 | ++ if (!dev_list) | ||
| 350 | ++ continue; | ||
| 351 | ++ | ||
| 352 | ++ wd_collect_numa_nodes(ctx_params->bmp, numa_nodes, &numa_count); | ||
| 353 | ++ | ||
| 354 | ++ for (op_type = 0; op_type < ctx_params->op_type_num; op_type++) { | ||
| 355 | ++ nums = &ctx_params->ctx_set_num[op_type]; | ||
| 356 | ++ if (!nums->sync_ctx_num && !nums->async_ctx_num) | ||
| 357 | ++ continue; | ||
| 358 | ++ | ||
| 359 | ++ dparams.op_type = op_type; | ||
| 360 | ++ for (n = 0; n < numa_count; n++) { | ||
| 361 | ++ dparams.numa_id = numa_nodes[n]; | ||
| 362 | ++ for (p = dev_list; p; p = p->next) { | ||
| 363 | ++ if (!p->dev || p->dev->numa_id != numa_nodes[n]) | ||
| 364 | ++ continue; | ||
| 365 | ++ | ||
| 366 | ++ dparams.preferred_dev_path = p->dev->char_dev_path; | ||
| 367 | ++ ret = wd_alloc_dev_group(attrs, drv, | ||
| 368 | ++ &dparams, | ||
| 369 | ++ &ctx_idx); | ||
| 370 | ++ if (!ret) | ||
| 371 | ++ break; | ||
| 372 | ++ if (ret != -WD_ENODEV) | ||
| 373 | ++ goto err_ctxs; | ||
| 374 | ++ } | ||
| 375 | ++ } | ||
| 376 | ++ } | ||
| 377 | ++ wd_free_list_accels(dev_list); | ||
| 378 | ++ dev_list = NULL; | ||
| 379 | ++ } | ||
| 380 | ++ | ||
| 381 | ++ *start_idx = ctx_idx; | ||
| 382 | ++ return ctx_idx == start ? -WD_ENODEV : WD_SUCCESS; | ||
| 383 | ++ | ||
| 384 | ++err_ctxs: | ||
| 385 | ++ if (dev_list) | ||
| 386 | ++ wd_free_list_accels(dev_list); | ||
| 387 | ++ wd_free_ctxs_batch(attrs, ctx_idx); | ||
| 388 | ++ return ret; | ||
| 389 | ++} | ||
| 390 | ++ | ||
| 391 | + /** | ||
| 392 | + * wd_alg_ctx_uninit() - Release ctxs, scheduler, ctx_config. | ||
| 393 | + * | ||
| 394 | +@@ -2881,18 +3056,24 @@ int wd_alg_ctx_init(struct wd_init_attrs *attrs) | ||
| 395 | + return -WD_EINVAL; | ||
| 396 | + } | ||
| 397 | + | ||
| 398 | +- /* | ||
| 399 | +- * Ensure that contexts (ctx) with the same attributes are allocated first, | ||
| 400 | +- * thereby maintaining queue continuity within the contexts. | ||
| 401 | +- */ | ||
| 402 | +- ret = wd_alloc_ctxs_batch(attrs, CTX_MODE_SYNC, &ctx_idx); | ||
| 403 | +- if (ret) | ||
| 404 | +- return -WD_EINVAL; | ||
| 405 | ++ if (attrs->sched_type == SCHED_POLICY_DEV) { | ||
| 406 | ++ ret = wd_alloc_ctxs_batch_dev(attrs, &ctx_idx); | ||
| 407 | ++ /* DEV tolerates partial: only a truly empty result fails. */ | ||
| 408 | ++ if (ret == -WD_ENODEV) | ||
| 409 | ++ return -WD_EINVAL; | ||
| 410 | + | ||
| 411 | +- /* wd_alloc_ctxs_batch already cleaned up via its internal err_ctxs. */ | ||
| 412 | +- ret = wd_alloc_ctxs_batch(attrs, CTX_MODE_ASYNC, &ctx_idx); | ||
| 413 | +- if (ret) | ||
| 414 | +- return -WD_EINVAL; | ||
| 415 | ++ if (ret) | ||
| 416 | ++ return ret; | ||
| 417 | ++ } else { | ||
| 418 | ++ ret = wd_alloc_ctxs_batch(attrs, CTX_MODE_SYNC, &ctx_idx); | ||
| 419 | ++ if (ret) | ||
| 420 | ++ return -WD_EINVAL; | ||
| 421 | ++ | ||
| 422 | ++ /* wd_alloc_ctxs_batch already cleaned up via its internal err_ctxs. */ | ||
| 423 | ++ ret = wd_alloc_ctxs_batch(attrs, CTX_MODE_ASYNC, &ctx_idx); | ||
| 424 | ++ if (ret) | ||
| 425 | ++ return -WD_EINVAL; | ||
| 426 | ++ } | ||
| 427 | + | ||
| 428 | + /* Backfill actual allocated count */ | ||
| 429 | + internal_config = attrs->ctx_config_internal; | ||
| 430 | +-- | ||
| 431 | +2.25.1 | ||
| 432 | + | ||
| @@ -0,0 +1,143 @@ | |||
| 1 | +From 6501898995a32968f79247bba555bb8d3ffb3b56 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Chenghai Huang <huangchenghai2@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:37 +0800 | ||
| 4 | +Subject: [PATCH 25/37] uadk: simplify SCHED_POLICY_DEV ctx alloc to | ||
| 5 | + non-interleaved whole-group | ||
| 6 | + | ||
| 7 | +Replace interleaved sync/async alloc with linear two-pass per device: | ||
| 8 | +open all sync then all async; any shortfall rolls back the whole group | ||
| 9 | +and tries the next device. Add per-op_type gap check, device capacity | ||
| 10 | +pre-check, and dev_list NULL init. | ||
| 11 | + | ||
| 12 | +Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> | ||
| 13 | +--- | ||
| 14 | + wd_util.c | 62 ++++++++++++++++++++++++++----------------------------- | ||
| 15 | + 1 file changed, 29 insertions(+), 33 deletions(-) | ||
| 16 | + | ||
| 17 | +diff --git a/wd_util.c b/wd_util.c | ||
| 18 | +index cc89837..ebe6a56 100644 | ||
| 19 | +--- a/wd_util.c | ||
| 20 | ++++ b/wd_util.c | ||
| 21 | +@@ -2786,11 +2786,10 @@ err_ctxs: | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + /* | ||
| 25 | +- * SCHED_POLICY_DEV: open sync/async ctxs of (drv, op_type, numa) interleaved on | ||
| 26 | +- * ONE device. The caller pins the device via dparams->preferred_dev_path. | ||
| 27 | +- * Stop when both counts are met or the device is full. If both modes are | ||
| 28 | +- * requested but only one could be opened, roll back and return -WD_ENODEV so | ||
| 29 | +- * the caller can try the next device; partial within one mode is kept. | ||
| 30 | ++ * SCHED_POLICY_DEV: open all sync ctxs then all async ctxs of | ||
| 31 | ++ * (drv, op_type, numa) on ONE device pinned by dparams->preferred_dev_path. | ||
| 32 | ++ * If the device cannot hold the whole group, roll back every ctx opened on | ||
| 33 | ++ * it and return -WD_ENODEV so the caller tries the next device. | ||
| 34 | + */ | ||
| 35 | + static int wd_alloc_dev_group(struct wd_init_attrs *attrs, | ||
| 36 | + struct wd_alg_driver *drv, | ||
| 37 | +@@ -2801,58 +2800,44 @@ static int wd_alloc_dev_group(struct wd_init_attrs *attrs, | ||
| 38 | + __u32 want[2] = {nums->sync_ctx_num, nums->async_ctx_num}; | ||
| 39 | + __u8 modes[2] = {CTX_MODE_SYNC, CTX_MODE_ASYNC}; | ||
| 40 | + __u32 group_start = *ctx_idx; | ||
| 41 | +- __u32 done[2] = {0, 0}; | ||
| 42 | +- __u32 i; | ||
| 43 | ++ __u32 i, j; | ||
| 44 | + int ret; | ||
| 45 | + | ||
| 46 | +- while (done[0] < want[0] || done[1] < want[1]) { | ||
| 47 | +- for (i = 0; i < 2; i++) { | ||
| 48 | +- if (done[i] >= want[i]) | ||
| 49 | +- continue; | ||
| 50 | +- | ||
| 51 | +- dparams->ctx_mode = modes[i]; | ||
| 52 | ++ for (i = 0; i < 2; i++) { | ||
| 53 | ++ dparams->ctx_mode = modes[i]; | ||
| 54 | ++ for (j = 0; j < want[i]; j++) { | ||
| 55 | + ret = wd_alloc_one_ctx(attrs, drv, dparams, ctx_idx); | ||
| 56 | + if (ret) { | ||
| 57 | ++ wd_free_ctxs_batch_range(attrs, group_start, *ctx_idx); | ||
| 58 | ++ *ctx_idx = group_start; | ||
| 59 | + if (ret != -WD_EBUSY && ret != -WD_ENODEV) | ||
| 60 | + return ret; | ||
| 61 | +- /* | ||
| 62 | +- * Device full. If both modes were requested | ||
| 63 | +- * but only one got ctxs, the empty domain | ||
| 64 | +- * would cause idx 65535 at runtime. Roll back | ||
| 65 | +- * this group so the caller tries another dev. | ||
| 66 | +- */ | ||
| 67 | +- if (want[0] && want[1] && | ||
| 68 | +- (!done[0] || !done[1])) { | ||
| 69 | +- wd_free_ctxs_batch_range(attrs, group_start, *ctx_idx); | ||
| 70 | +- *ctx_idx = group_start; | ||
| 71 | +- return -WD_ENODEV; | ||
| 72 | +- } | ||
| 73 | +- return WD_SUCCESS; | ||
| 74 | ++ return -WD_ENODEV; | ||
| 75 | + } | ||
| 76 | +- done[i]++; | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + return WD_SUCCESS; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + /* | ||
| 83 | +- * SCHED_POLICY_DEV: per (drv, op_type, numa) open sync/async on one device | ||
| 84 | +- * (interleaved, partial allowed). Enumerates devices on each numa node and | ||
| 85 | +- * pins each group to one device via preferred_dev_path, trying the next | ||
| 86 | +- * device if the current one cannot hold both modes. | ||
| 87 | ++ * SCHED_POLICY_DEV: per (drv, op_type, numa) open all sync+async ctxs on one | ||
| 88 | ++ * device. Enumerates devices on each numa node and pins each group to one | ||
| 89 | ++ * device via preferred_dev_path, trying the next device if the current one | ||
| 90 | ++ * cannot hold the whole group. All devices exhausted => error out. | ||
| 91 | + */ | ||
| 92 | + static int wd_alloc_ctxs_batch_dev(struct wd_init_attrs *attrs, __u32 *start_idx) | ||
| 93 | + { | ||
| 94 | + struct wd_ctx_config_internal *internal_config = attrs->ctx_config_internal; | ||
| 95 | + struct wd_ctx_params *ctx_params = attrs->ctx_params; | ||
| 96 | +- struct uacce_dev_list *dev_list, *p; | ||
| 97 | ++ __u32 ctx_idx, drv_idx, start, group_start; | ||
| 98 | ++ struct uacce_dev_list *dev_list = NULL; | ||
| 99 | + int numa_nodes[UADK_MAX_NUMA_NODES]; | ||
| 100 | + char alg_type[CRYPTO_MAX_ALG_NAME]; | ||
| 101 | + struct wd_drv_ctx_params dparams; | ||
| 102 | +- __u32 ctx_idx, drv_idx, start; | ||
| 103 | + struct wd_alg_driver *drv; | ||
| 104 | + __u8 op_type, numa_count; | ||
| 105 | + struct wd_ctx_nums *nums; | ||
| 106 | ++ struct uacce_dev_list *p; | ||
| 107 | + int n, ret; | ||
| 108 | + | ||
| 109 | + memset(&dparams, 0, sizeof(dparams)); | ||
| 110 | +@@ -2894,12 +2879,18 @@ static int wd_alloc_ctxs_batch_dev(struct wd_init_attrs *attrs, __u32 *start_idx | ||
| 111 | + continue; | ||
| 112 | + | ||
| 113 | + dparams.op_type = op_type; | ||
| 114 | ++ group_start = ctx_idx; | ||
| 115 | + for (n = 0; n < numa_count; n++) { | ||
| 116 | + dparams.numa_id = numa_nodes[n]; | ||
| 117 | + for (p = dev_list; p; p = p->next) { | ||
| 118 | + if (!p->dev || p->dev->numa_id != numa_nodes[n]) | ||
| 119 | + continue; | ||
| 120 | + | ||
| 121 | ++ /* Skip devices that cannot hold the whole group */ | ||
| 122 | ++ if (wd_get_avail_ctx(p->dev) < (int)(nums->sync_ctx_num + | ||
| 123 | ++ nums->async_ctx_num)) | ||
| 124 | ++ continue; | ||
| 125 | ++ | ||
| 126 | + dparams.preferred_dev_path = p->dev->char_dev_path; | ||
| 127 | + ret = wd_alloc_dev_group(attrs, drv, | ||
| 128 | + &dparams, | ||
| 129 | +@@ -2910,6 +2901,11 @@ static int wd_alloc_ctxs_batch_dev(struct wd_init_attrs *attrs, __u32 *start_idx | ||
| 130 | + goto err_ctxs; | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | ++ | ||
| 134 | ++ if (ctx_idx == group_start) { | ||
| 135 | ++ ret = -WD_ENODEV; | ||
| 136 | ++ goto err_ctxs; | ||
| 137 | ++ } | ||
| 138 | + } | ||
| 139 | + wd_free_list_accels(dev_list); | ||
| 140 | + dev_list = NULL; | ||
| 141 | +-- | ||
| 142 | +2.25.1 | ||
| 143 | + | ||
| @@ -0,0 +1,87 @@ | |||
| 1 | +From 29dd74a2047bdb7a3b0a0af9a33d0a8c1206f6cb Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Wenkai Lin <linwenkai6@hisilicon.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:38 +0800 | ||
| 4 | +Subject: [PATCH 26/37] uadk: balance ctx allocation across devices by | ||
| 5 | + available contexts | ||
| 6 | + | ||
| 7 | +wd_hw_alloc_ctx picked the first device whose wd_request_ctx() succeeded. | ||
| 8 | +When PF and VFs share the same NUMA node, the NUMA-distance sort is a | ||
| 9 | +no-op, so the device order comes from readdir() over /sys/class/uacce. | ||
| 10 | +Each concurrent business independently starts from the list head and | ||
| 11 | +binds all ctxs to the same leading device, starving the others. | ||
| 12 | + | ||
| 13 | +Select the device with the most available contexts (wd_get_avail_ctx) | ||
| 14 | +instead, with a fallback to the remaining devices if the chosen one | ||
| 15 | +fails to open. NUMA distance priority is unchanged. | ||
| 16 | + | ||
| 17 | +Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com> | ||
| 18 | +--- | ||
| 19 | + drv/wd_drv.c | 41 +++++++++++++++++++++++++++++++---------- | ||
| 20 | + 1 file changed, 31 insertions(+), 10 deletions(-) | ||
| 21 | + | ||
| 22 | +diff --git a/drv/wd_drv.c b/drv/wd_drv.c | ||
| 23 | +index c839ed4..08014dd 100644 | ||
| 24 | +--- a/drv/wd_drv.c | ||
| 25 | ++++ b/drv/wd_drv.c | ||
| 26 | +@@ -181,12 +181,12 @@ int wd_hw_alloc_ctx(char *alg_name, void *params, handle_t *ctx) | ||
| 27 | + { | ||
| 28 | + struct wd_drv_ctx_params *ctx_params = (struct wd_drv_ctx_params *)params; | ||
| 29 | + struct uacce_dev_list *dev_list, *used_list = NULL; | ||
| 30 | ++ struct uacce_dev_list *curr, *best = NULL; | ||
| 31 | + char alg_type[CRYPTO_MAX_ALG_NAME]; | ||
| 32 | +- struct uacce_dev_list *curr; | ||
| 33 | ++ int target_numa, best_avail = 0; | ||
| 34 | + struct wd_ctx_h *ctx_h; | ||
| 35 | +- int target_numa; | ||
| 36 | ++ int ret, avail; | ||
| 37 | + handle_t hctx; | ||
| 38 | +- int ret; | ||
| 39 | + | ||
| 40 | + if (!params || !ctx) { | ||
| 41 | + WD_ERR("invalid: parameters are NULL!\n"); | ||
| 42 | +@@ -246,14 +246,35 @@ int wd_hw_alloc_ctx(char *alg_name, void *params, handle_t *ctx) | ||
| 43 | + goto success; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | +- curr = used_list; | ||
| 47 | +- while (curr) { | ||
| 48 | +- if (curr->dev) { | ||
| 49 | +- hctx = wd_request_ctx(curr->dev); | ||
| 50 | +- if (hctx) | ||
| 51 | +- goto success; | ||
| 52 | ++ /* Pick the device with the most available contexts to balance load. */ | ||
| 53 | ++ for (curr = used_list; curr; curr = curr->next) { | ||
| 54 | ++ if (!curr->dev) | ||
| 55 | ++ continue; | ||
| 56 | ++ avail = wd_get_avail_ctx(curr->dev); | ||
| 57 | ++ if (avail > best_avail) { | ||
| 58 | ++ best_avail = avail; | ||
| 59 | ++ best = curr; | ||
| 60 | + } | ||
| 61 | +- curr = curr->next; | ||
| 62 | ++ } | ||
| 63 | ++ | ||
| 64 | ++ if (!best) { | ||
| 65 | ++ WD_ERR("failed to request ctx on NUMA node %d for %s\n", | ||
| 66 | ++ target_numa, alg_name); | ||
| 67 | ++ ret = -WD_EBUSY; | ||
| 68 | ++ goto out; | ||
| 69 | ++ } | ||
| 70 | ++ | ||
| 71 | ++ hctx = wd_request_ctx(best->dev); | ||
| 72 | ++ if (hctx) | ||
| 73 | ++ goto success; | ||
| 74 | ++ | ||
| 75 | ++ /* Fall back to remaining devices if the best one fails to open */ | ||
| 76 | ++ for (curr = used_list; curr; curr = curr->next) { | ||
| 77 | ++ if (curr == best || !curr->dev) | ||
| 78 | ++ continue; | ||
| 79 | ++ hctx = wd_request_ctx(curr->dev); | ||
| 80 | ++ if (hctx) | ||
| 81 | ++ goto success; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + WD_ERR("failed to request ctx on NUMA node %d for %s\n", | ||
| 85 | +-- | ||
| 86 | +2.25.1 | ||
| 87 | + | ||
| @@ -0,0 +1,42 @@ | |||
| 1 | +From 7276c3c16a6c95fe7aa9fcbc95dfd62ef6f5b066 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Wenkai Lin <linwenkai6@hisilicon.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:40 +0800 | ||
| 4 | +Subject: [PATCH 28/37] uadk: fix digest BD3 stream mode issue | ||
| 5 | + | ||
| 6 | +Common digests (SHA/SM3) need SCENE_STREAM for streaming hash but only | ||
| 7 | +CTR/GCM streaming was described in the FS, so hash streaming was | ||
| 8 | +misconfigured. GMAC uses SCENE_IPSEC independently. | ||
| 9 | + | ||
| 10 | +Use SCENE_STREAM for common digests; keep SCENE_IPSEC for GMAC only. | ||
| 11 | + | ||
| 12 | +Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com> | ||
| 13 | +--- | ||
| 14 | + v1/drv/hisi_sec_udrv.c | 12 +++++++++++- | ||
| 15 | + 1 file changed, 11 insertions(+), 1 deletion(-) | ||
| 16 | + | ||
| 17 | +diff --git a/v1/drv/hisi_sec_udrv.c b/v1/drv/hisi_sec_udrv.c | ||
| 18 | +index 7eba121..6ad6c57 100644 | ||
| 19 | +--- a/v1/drv/hisi_sec_udrv.c | ||
| 20 | ++++ b/v1/drv/hisi_sec_udrv.c | ||
| 21 | +@@ -1827,7 +1827,17 @@ static int fill_digest_bd3(struct wd_queue *q, struct hisi_sec_bd3_sqe *sqe, | ||
| 22 | + return ret; | ||
| 23 | + | ||
| 24 | + sqe->type = BD_TYPE3; | ||
| 25 | +- sqe->scene = is_storage ? SCENE_STORAGE : SCENE_IPSEC; | ||
| 26 | ++ | ||
| 27 | ++ /* | ||
| 28 | ++ * GMAC is an IPSEC-specific auth algo (RFC4543); other digests use | ||
| 29 | ++ * stream scene for long-data hash processing. | ||
| 30 | ++ */ | ||
| 31 | ++ if (is_storage) | ||
| 32 | ++ sqe->scene = SCENE_STORAGE; | ||
| 33 | ++ else if (msg->alg == WCRYPTO_AES_GMAC) | ||
| 34 | ++ sqe->scene = SCENE_IPSEC; | ||
| 35 | ++ else | ||
| 36 | ++ sqe->scene = SCENE_STREAM; | ||
| 37 | + | ||
| 38 | + sqe->auth = AUTH_MAC_CALCULATE; | ||
| 39 | + sqe->a_len = msg->in_bytes; | ||
| 40 | +-- | ||
| 41 | +2.25.1 | ||
| 42 | + | ||
| @@ -0,0 +1,49 @@ | |||
| 1 | +From bf9dbb3756f0769395aa78d5d547a74626491c2d Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Wenkai Lin <linwenkai6@hisilicon.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:41 +0800 | ||
| 4 | +Subject: [PATCH 29/37] uadk: check CE digest/cipher result before get_sqe | ||
| 5 | + | ||
| 6 | +In sm3_ce_drv_send and isa_ce_cipher_send, the return value of the | ||
| 7 | +software digest/cipher computation (do_sm3_ce, do_hmac_sm3_ce, | ||
| 8 | +sm4_xts_encrypt, sm4_xts_decrypt) is silently overwritten by the | ||
| 9 | +subsequent wd_get_sqe_from_queue call. If the computation fails, | ||
| 10 | +the error is swallowed and the function may return success. | ||
| 11 | + | ||
| 12 | +Add an early return on error before calling wd_get_sqe_from_queue | ||
| 13 | +so that a failed computation does not proceed to queue operations. | ||
| 14 | + | ||
| 15 | +Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com> | ||
| 16 | +--- | ||
| 17 | + drv/isa_ce_sm3.c | 2 ++ | ||
| 18 | + drv/isa_ce_sm4.c | 2 ++ | ||
| 19 | + 2 files changed, 4 insertions(+) | ||
| 20 | + | ||
| 21 | +diff --git a/drv/isa_ce_sm3.c b/drv/isa_ce_sm3.c | ||
| 22 | +index b41f6c5..117b95e 100644 | ||
| 23 | +--- a/drv/isa_ce_sm3.c | ||
| 24 | ++++ b/drv/isa_ce_sm3.c | ||
| 25 | +@@ -374,6 +374,8 @@ static int sm3_ce_drv_send(handle_t ctx, void *digest_msg) | ||
| 26 | + WD_ERR("invalid digest mode!\n"); | ||
| 27 | + ret = -WD_EINVAL; | ||
| 28 | + } | ||
| 29 | ++ if (ret) | ||
| 30 | ++ return ret; | ||
| 31 | + | ||
| 32 | + ret = wd_get_sqe_from_queue(sfctx, msg->tag); | ||
| 33 | + if (ret) | ||
| 34 | +diff --git a/drv/isa_ce_sm4.c b/drv/isa_ce_sm4.c | ||
| 35 | +index 863b99e..7547c00 100644 | ||
| 36 | +--- a/drv/isa_ce_sm4.c | ||
| 37 | ++++ b/drv/isa_ce_sm4.c | ||
| 38 | +@@ -399,6 +399,8 @@ static int isa_ce_cipher_send(handle_t ctx, void *wd_msg) | ||
| 39 | + ret = sm4_xts_encrypt(msg, &rkey); | ||
| 40 | + else | ||
| 41 | + ret = sm4_xts_decrypt(msg, &rkey); | ||
| 42 | ++ if (ret) | ||
| 43 | ++ return ret; | ||
| 44 | + break; | ||
| 45 | + default: | ||
| 46 | + WD_ERR("The current block cipher mode is not supported!\n"); | ||
| 47 | +-- | ||
| 48 | +2.25.1 | ||
| 49 | + | ||
| @@ -0,0 +1,33 @@ | |||
| 1 | +From 48ef855d71a7a3105b2f7f7430e84e1398f70a12 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Weili Qian <qianweili@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:42 +0800 | ||
| 4 | +Subject: [PATCH 30/37] uadk: fix alloc/free pairing in rsa session key error | ||
| 5 | + path | ||
| 6 | + | ||
| 7 | +In wd_rsa.c create_sess_key, prikey is allocated via sess->mm_ops.alloc | ||
| 8 | +which may be backed by mmap (WD_MMAP_MEM), but the pubkey alloc failure | ||
| 9 | +path freed it with free(), causing undefined behavior on mmap memory. | ||
| 10 | +Use sess->mm_ops.free to match the allocator and the normal release | ||
| 11 | +path in del_sess_key. | ||
| 12 | + | ||
| 13 | +Signed-off-by: Weili Qian <qianweili@huawei.com> | ||
| 14 | +--- | ||
| 15 | + wd_rsa.c | 2 +- | ||
| 16 | + 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 17 | + | ||
| 18 | +diff --git a/wd_rsa.c b/wd_rsa.c | ||
| 19 | +index c1f2d9a..59c230d 100644 | ||
| 20 | +--- a/wd_rsa.c | ||
| 21 | ++++ b/wd_rsa.c | ||
| 22 | +@@ -930,7 +930,7 @@ static int create_sess_key(struct wd_rsa_sess_setup *setup, | ||
| 23 | + (int)GEN_PARAMS_SZ(sess->key_size); | ||
| 24 | + sess->pubkey = sess->mm_ops.alloc(sess->mm_ops.usr, len); | ||
| 25 | + if (!sess->pubkey) { | ||
| 26 | +- free(sess->prikey); | ||
| 27 | ++ sess->mm_ops.free(sess->mm_ops.usr, sess->prikey); | ||
| 28 | + WD_ERR("failed to alloc sess pubkey!\n"); | ||
| 29 | + return -WD_ENOMEM; | ||
| 30 | + } | ||
| 31 | +-- | ||
| 32 | +2.25.1 | ||
| 33 | + | ||
| @@ -0,0 +1,50 @@ | |||
| 1 | +From 6f3b7c3f177a6bdea0add561c478d1d3abd99ea9 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Weili Qian <qianweili@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:43 +0800 | ||
| 4 | +Subject: [PATCH 31/37] uadk: fix return values overwritten by sqe queue call | ||
| 5 | + | ||
| 6 | +wd_alg_init_fallback in wd_util.c discarded fb_driver->init() return | ||
| 7 | +value and always returned 0, and wd_agg_rehash_sync_inner in wd_agg.c | ||
| 8 | +ignored wd_agg_set_col_size return value, allowing invalid column | ||
| 9 | +sizes to hardware DMA. Propagate the init return value and check | ||
| 10 | +wd_agg_set_col_size so callers can detect failures. | ||
| 11 | + | ||
| 12 | +Signed-off-by: Weili Qian <qianweili@huawei.com> | ||
| 13 | +--- | ||
| 14 | + wd_agg.c | 4 +++- | ||
| 15 | + wd_util.c | 4 +--- | ||
| 16 | + 2 files changed, 4 insertions(+), 4 deletions(-) | ||
| 17 | + | ||
| 18 | +diff --git a/wd_agg.c b/wd_agg.c | ||
| 19 | +index 95cb869..951e03d 100644 | ||
| 20 | +--- a/wd_agg.c | ||
| 21 | ++++ b/wd_agg.c | ||
| 22 | +@@ -1500,7 +1500,9 @@ static int wd_agg_rehash_sync_inner(struct wd_agg_sess *sess, struct wd_agg_req | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + out_req->real_out_row_count = msg.out_row_count; | ||
| 26 | +- wd_agg_set_col_size(sess, in_req, out_req->real_out_row_count); | ||
| 27 | ++ ret = wd_agg_set_col_size(sess, in_req, out_req->real_out_row_count); | ||
| 28 | ++ if (unlikely(ret)) | ||
| 29 | ++ return ret; | ||
| 30 | + in_req->in_row_count = out_req->real_out_row_count; | ||
| 31 | + | ||
| 32 | + fill_request_msg_input(&in_msg, in_req, sess, true); | ||
| 33 | +diff --git a/wd_util.c b/wd_util.c | ||
| 34 | +index ebe6a56..79bed19 100644 | ||
| 35 | +--- a/wd_util.c | ||
| 36 | ++++ b/wd_util.c | ||
| 37 | +@@ -1566,9 +1566,7 @@ static int wd_alg_init_fallback(struct wd_alg_driver *fb_driver) | ||
| 38 | + return -WD_EINVAL; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | +- fb_driver->init(NULL, NULL); | ||
| 42 | +- | ||
| 43 | +- return 0; | ||
| 44 | ++ return fb_driver->init(NULL, NULL); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + static void wd_alg_uninit_fallback(struct wd_alg_driver *fb_driver) | ||
| 48 | +-- | ||
| 49 | +2.25.1 | ||
| 50 | + | ||
| @@ -0,0 +1,52 @@ | |||
| 1 | +From 8d8909502d5feb4e19f51659a7b3c130c3390bbd Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Weili Qian <qianweili@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:44 +0800 | ||
| 4 | +Subject: [PATCH 32/37] uadk: fix buffer overflow and out-of-bounds access | ||
| 5 | + | ||
| 6 | +wd_parse_log_level in wd.c allocated st_size bytes but fscanf "%[^\n ]" | ||
| 7 | +appends a '\0', causing off-by-one heap overflow when a token is exactly | ||
| 8 | +st_size long. _find_next_bit in wd_mempool.c used "start > bits" in the | ||
| 9 | +loop guard while the initial guard used "start >= bits", reading map out | ||
| 10 | +of bounds when bits is a multiple of BITS_PER_LONG. Allocate st_size + 1 | ||
| 11 | +and use ">=" for the loop guard. | ||
| 12 | + | ||
| 13 | +Signed-off-by: Weili Qian <qianweili@huawei.com> | ||
| 14 | +--- | ||
| 15 | + wd.c | 3 ++- | ||
| 16 | + wd_mempool.c | 2 +- | ||
| 17 | + 2 files changed, 3 insertions(+), 2 deletions(-) | ||
| 18 | + | ||
| 19 | +diff --git a/wd.c b/wd.c | ||
| 20 | +index 1c28bb3..13852f7 100644 | ||
| 21 | +--- a/wd.c | ||
| 22 | ++++ b/wd.c | ||
| 23 | +@@ -114,11 +114,12 @@ static void wd_parse_log_level(void) | ||
| 24 | + goto close_file; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | +- file_contents = malloc(file_info.st_size); | ||
| 28 | ++ file_contents = malloc(file_info.st_size + 1); | ||
| 29 | + if (!file_contents) { | ||
| 30 | + WD_ERR("failed to get file contents memory.\n"); | ||
| 31 | + goto close_file; | ||
| 32 | + } | ||
| 33 | ++ file_contents[file_info.st_size] = '\0'; | ||
| 34 | + | ||
| 35 | + while (fscanf(in_file, " %[^\n ] ", file_contents) != EOF) { | ||
| 36 | + if (!strcmp("local5.debug", file_contents)) | ||
| 37 | +diff --git a/wd_mempool.c b/wd_mempool.c | ||
| 38 | +index 3ce9ef0..15c8d45 100644 | ||
| 39 | +--- a/wd_mempool.c | ||
| 40 | ++++ b/wd_mempool.c | ||
| 41 | +@@ -239,7 +239,7 @@ static unsigned long _find_next_bit(unsigned long *map, unsigned long bits, | ||
| 42 | + | ||
| 43 | + while (!tmp) { | ||
| 44 | + start += BITS_PER_LONG; | ||
| 45 | +- if (start > bits) | ||
| 46 | ++ if (start >= bits) | ||
| 47 | + return bits; | ||
| 48 | + | ||
| 49 | + tmp = map[start / BITS_PER_LONG]; | ||
| 50 | +-- | ||
| 51 | +2.25.1 | ||
| 52 | + | ||
| @@ -0,0 +1,77 @@ | |||
| 1 | +From 77ee79f5c083d819503b6c6ee5c84d382f37a5a2 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Weili Qian <qianweili@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:45 +0800 | ||
| 4 | +Subject: [PATCH 33/37] uadk: fix lock init failure detection | ||
| 5 | + | ||
| 6 | +pthread_spin_init returns a positive errno on failure, but | ||
| 7 | +wd_blockpool_create/wd_mempool_create checked "if (ret < 0)" which was | ||
| 8 | +always false, and wd_soft_alloc_ctx did not check the return value at | ||
| 9 | +all, leaving spinlocks uninitialized. Use "if (ret)" to detect failure, | ||
| 10 | +check both spin_init calls in wd_soft_alloc_ctx, clean up on failure, | ||
| 11 | +and return -ret so callers using "if (ret < 0)" can detect the error. | ||
| 12 | + | ||
| 13 | +Signed-off-by: Weili Qian <qianweili@huawei.com> | ||
| 14 | +--- | ||
| 15 | + drv/wd_drv.c | 16 ++++++++++++++-- | ||
| 16 | + wd_mempool.c | 4 ++-- | ||
| 17 | + 2 files changed, 16 insertions(+), 4 deletions(-) | ||
| 18 | + | ||
| 19 | +diff --git a/drv/wd_drv.c b/drv/wd_drv.c | ||
| 20 | +index 08014dd..4bac551 100644 | ||
| 21 | +--- a/drv/wd_drv.c | ||
| 22 | ++++ b/drv/wd_drv.c | ||
| 23 | +@@ -11,6 +11,7 @@ | ||
| 24 | + int wd_soft_alloc_ctx(char *alg_name, void *params, handle_t *ctx) | ||
| 25 | + { | ||
| 26 | + struct wd_soft_ctx *sfctx; | ||
| 27 | ++ int ret; | ||
| 28 | + | ||
| 29 | + if (!params || !ctx) { | ||
| 30 | + WD_ERR("invalid: params, or ctx is NULL!\n"); | ||
| 31 | +@@ -27,8 +28,19 @@ int wd_soft_alloc_ctx(char *alg_name, void *params, handle_t *ctx) | ||
| 32 | + /* Initialize as software context */ | ||
| 33 | + sfctx->fd = -1; | ||
| 34 | + sfctx->ctx_type = UADK_ALG_SOFT; | ||
| 35 | +- pthread_spin_init(&sfctx->slock, PTHREAD_PROCESS_PRIVATE); | ||
| 36 | +- pthread_spin_init(&sfctx->rlock, PTHREAD_PROCESS_PRIVATE); | ||
| 37 | ++ ret = pthread_spin_init(&sfctx->slock, PTHREAD_PROCESS_PRIVATE); | ||
| 38 | ++ if (ret) { | ||
| 39 | ++ WD_ERR("failed to init slock!\n"); | ||
| 40 | ++ free(sfctx); | ||
| 41 | ++ return -ret; | ||
| 42 | ++ } | ||
| 43 | ++ ret = pthread_spin_init(&sfctx->rlock, PTHREAD_PROCESS_PRIVATE); | ||
| 44 | ++ if (ret) { | ||
| 45 | ++ WD_ERR("failed to init rlock!\n"); | ||
| 46 | ++ pthread_spin_destroy(&sfctx->slock); | ||
| 47 | ++ free(sfctx); | ||
| 48 | ++ return -ret; | ||
| 49 | ++ } | ||
| 50 | + | ||
| 51 | + /* Return context handle */ | ||
| 52 | + *ctx = (handle_t)sfctx; | ||
| 53 | +diff --git a/wd_mempool.c b/wd_mempool.c | ||
| 54 | +index 15c8d45..4081130 100644 | ||
| 55 | +--- a/wd_mempool.c | ||
| 56 | ++++ b/wd_mempool.c | ||
| 57 | +@@ -561,7 +561,7 @@ handle_t wd_blockpool_create(handle_t mempool, size_t block_size, | ||
| 58 | + bp->free_block_num = block_num; | ||
| 59 | + bp->mp = mp; | ||
| 60 | + ret = pthread_spin_init(&bp->lock, PTHREAD_PROCESS_PRIVATE); | ||
| 61 | +- if (ret < 0) | ||
| 62 | ++ if (ret) | ||
| 63 | + goto err_free_bp; | ||
| 64 | + | ||
| 65 | + ret = alloc_mem_from_mempool(mp, bp); | ||
| 66 | +@@ -910,7 +910,7 @@ handle_t wd_mempool_create(size_t size, int node) | ||
| 67 | + mp->size = tmp; | ||
| 68 | + mp->blk_size = WD_MEMPOOL_BLOCK_SIZE; | ||
| 69 | + ret = pthread_spin_init(&mp->lock, PTHREAD_PROCESS_PRIVATE); | ||
| 70 | +- if (ret < 0) | ||
| 71 | ++ if (ret) | ||
| 72 | + goto free_pool; | ||
| 73 | + | ||
| 74 | + ret = alloc_mem_from_hugepage(mp); | ||
| 75 | +-- | ||
| 76 | +2.25.1 | ||
| 77 | + | ||
| @@ -0,0 +1,147 @@ | |||
| 1 | +From 420700bf8853928b002238bb66d79cb306e975de Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Weili Qian <qianweili@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:46 +0800 | ||
| 4 | +Subject: [PATCH 34/37] uadk: fix SGL/DMA resource leak and missing NULL checks | ||
| 5 | + | ||
| 6 | +hisi_qm_create_sglpool missed NULL check on hisi_qm_align_sgl and set | ||
| 7 | +sgl_num to i instead of i + 1 on failure, leaking the already-allocated | ||
| 8 | +sgl[i]. hisi_qm_get_hw_sgl, hisi_sec_cipher_send/_v3, cipher/digest/aead | ||
| 9 | +recv and fill_zip_comp_sqe also leaked SGL/DMA resources or passed NULL | ||
| 10 | +to hardware on error paths. Add NULL checks, fix sgl_num, and recycle | ||
| 11 | +SGL entries on error paths. | ||
| 12 | + | ||
| 13 | +Signed-off-by: Weili Qian <qianweili@huawei.com> | ||
| 14 | +--- | ||
| 15 | + drv/hisi_comp.c | 7 ++++++- | ||
| 16 | + drv/hisi_qm_udrv.c | 15 +++++++++++++-- | ||
| 17 | + drv/hisi_sec.c | 34 ++++++++++++++++++++-------------- | ||
| 18 | + 3 files changed, 39 insertions(+), 17 deletions(-) | ||
| 19 | + | ||
| 20 | +diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c | ||
| 21 | +index b798811..c1b83c3 100644 | ||
| 22 | +--- a/drv/hisi_comp.c | ||
| 23 | ++++ b/drv/hisi_comp.c | ||
| 24 | +@@ -1555,8 +1555,13 @@ static int fill_zip_comp_sqe(struct hisi_qp *qp, struct wd_comp_msg *msg, | ||
| 25 | + ops[alg_type].fill_alg(sqe); | ||
| 26 | + | ||
| 27 | + ret = ops[alg_type].fill_comp_level(sqe, msg->comp_lv); | ||
| 28 | +- if (unlikely(ret)) | ||
| 29 | ++ if (unlikely(ret)) { | ||
| 30 | ++ if (msg->mm_ops && !msg->mm_ops->sva_mode) | ||
| 31 | ++ zip_mem_unmap(msg, sqe); | ||
| 32 | ++ if (msg->req.data_fmt == WD_SGL_BUF) | ||
| 33 | ++ free_hw_sgl((handle_t)qp, &msg->c_sgl, msg->mm_ops); | ||
| 34 | + return ret; | ||
| 35 | ++ } | ||
| 36 | + | ||
| 37 | + ops[alg_type].fill_tag(sqe, msg->tag); | ||
| 38 | + | ||
| 39 | +diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c | ||
| 40 | +index 6da9887..8617b10 100644 | ||
| 41 | +--- a/drv/hisi_qm_udrv.c | ||
| 42 | ++++ b/drv/hisi_qm_udrv.c | ||
| 43 | +@@ -803,6 +803,10 @@ handle_t hisi_qm_create_sglpool(__u32 sgl_num, __u32 sge_num, struct wd_mm_ops * | ||
| 44 | + | ||
| 45 | + sgl_pool->sgl_align[i] = hisi_qm_align_sgl(sgl_pool->sgl[i], | ||
| 46 | + sge_num, sgl_pool->mm_ops); | ||
| 47 | ++ if (!sgl_pool->sgl_align[i]) { | ||
| 48 | ++ sgl_pool->sgl_num = i + 1; | ||
| 49 | ++ goto err_out; | ||
| 50 | ++ } | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + sgl_pool->sgl_num = sgl_num; | ||
| 54 | +@@ -999,11 +1003,18 @@ void *hisi_qm_get_hw_sgl(handle_t sgl_pool, struct wd_datalist *sgl) | ||
| 55 | + ret = WD_ERR_PTR(-WD_EBUSY); | ||
| 56 | + goto err_out; | ||
| 57 | + } | ||
| 58 | +- if (mm_ops) | ||
| 59 | ++ if (mm_ops) { | ||
| 60 | + cur->next_dma = (uintptr_t)mm_ops->iova_map(mm_ops->usr, | ||
| 61 | + next, sizeof(*next)); | ||
| 62 | +- else | ||
| 63 | ++ if (!cur->next_dma) { | ||
| 64 | ++ WD_ERR("invalid: iova_map for sgl chain failed!\n"); | ||
| 65 | ++ hisi_qm_sgl_push(pool, next); | ||
| 66 | ++ ret = WD_ERR_PTR(-WD_ENOMEM); | ||
| 67 | ++ goto err_out; | ||
| 68 | ++ } | ||
| 69 | ++ } else { | ||
| 70 | + cur->next_dma = (uintptr_t)next; | ||
| 71 | ++ } | ||
| 72 | + cur->next = next; | ||
| 73 | + cur = next; | ||
| 74 | + head->entry_sum_in_chain += pool->sge_num; | ||
| 75 | +diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c | ||
| 76 | +index 10bb34e..df086d7 100644 | ||
| 77 | +--- a/drv/hisi_sec.c | ||
| 78 | ++++ b/drv/hisi_sec.c | ||
| 79 | +@@ -1439,22 +1439,25 @@ static int hisi_sec_cipher_send(handle_t ctx, void *wd_msg) | ||
| 80 | + ret = fill_cipher_bd2_addr(msg, &sqe); | ||
| 81 | + if (ret < 0) { | ||
| 82 | + WD_ERR("cipher map memory is err(%d)!\n", ret); | ||
| 83 | +- return ret; | ||
| 84 | ++ goto put_sgl; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + ret = hisi_qm_send(h_qp, &sqe, 1, &count); | ||
| 88 | + if (ret < 0) { | ||
| 89 | + if (ret != -WD_EBUSY) | ||
| 90 | + WD_ERR("cipher send sqe is err(%d)!\n", ret); | ||
| 91 | +- | ||
| 92 | +- if (msg->data_fmt == WD_SGL_BUF) | ||
| 93 | +- hisi_sec_put_sgl(h_qp, msg->alg_type, msg->in, | ||
| 94 | +- msg->out, msg->mm_ops); | ||
| 95 | +- destroy_cipher_bd2_addr(msg, &sqe); | ||
| 96 | +- return ret; | ||
| 97 | ++ goto destroy_addr; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + return 0; | ||
| 101 | ++ | ||
| 102 | ++destroy_addr: | ||
| 103 | ++ destroy_cipher_bd2_addr(msg, &sqe); | ||
| 104 | ++put_sgl: | ||
| 105 | ++ if (msg->data_fmt == WD_SGL_BUF) | ||
| 106 | ++ hisi_sec_put_sgl(h_qp, msg->alg_type, msg->in, | ||
| 107 | ++ msg->out, msg->mm_ops); | ||
| 108 | ++ return ret; | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + int hisi_sec_cipher_recv(handle_t ctx, void *wd_msg) | ||
| 112 | +@@ -1735,22 +1738,25 @@ static int hisi_sec_cipher_send_v3(handle_t ctx, void *wd_msg) | ||
| 113 | + ret = fill_cipher_bd3_addr(msg, &sqe); | ||
| 114 | + if (ret < 0) { | ||
| 115 | + WD_ERR("cipher map memory is err(%d)!\n", ret); | ||
| 116 | +- return ret; | ||
| 117 | ++ goto put_sgl; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + ret = hisi_qm_send(h_qp, &sqe, 1, &count); | ||
| 121 | + if (ret < 0) { | ||
| 122 | + if (ret != -WD_EBUSY) | ||
| 123 | + WD_ERR("cipher send sqe is err(%d)!\n", ret); | ||
| 124 | +- | ||
| 125 | +- if (msg->data_fmt == WD_SGL_BUF) | ||
| 126 | +- hisi_sec_put_sgl(h_qp, msg->alg_type, msg->in, | ||
| 127 | +- msg->out, msg->mm_ops); | ||
| 128 | +- destroy_cipher_bd3_addr(msg, &sqe); | ||
| 129 | +- return ret; | ||
| 130 | ++ goto destroy_addr; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + return 0; | ||
| 134 | ++ | ||
| 135 | ++destroy_addr: | ||
| 136 | ++ destroy_cipher_bd3_addr(msg, &sqe); | ||
| 137 | ++put_sgl: | ||
| 138 | ++ if (msg->data_fmt == WD_SGL_BUF) | ||
| 139 | ++ hisi_sec_put_sgl(h_qp, msg->alg_type, msg->in, | ||
| 140 | ++ msg->out, msg->mm_ops); | ||
| 141 | ++ return ret; | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + static void parse_cipher_bd3(struct hisi_qp *qp, struct hisi_sec_sqe3 *sqe, | ||
| 145 | +-- | ||
| 146 | +2.25.1 | ||
| 147 | + | ||
| @@ -0,0 +1,90 @@ | |||
| 1 | +From 639da114e09715646355b0bcc496cd8c07ee6ba7 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Weili Qian <qianweili@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:47 +0800 | ||
| 4 | +Subject: [PATCH 35/37] uadk: fix message pool pollution and memory leak | ||
| 5 | + | ||
| 6 | +wd_*_poll_ctx in wd_ecc/rsa/dh/udma.c put recv_msg.tag (0 from | ||
| 7 | +zero-initialized recv_msg) back into the message pool on drv->recv | ||
| 8 | +failure, marking slot 0 as free even when in use and causing double-use | ||
| 9 | +or use-after-free. sm2_enc_parse in hisi_hpre.c leaked the second SQE | ||
| 10 | +and its DMA mappings when parse_second_sqe partially succeeded. | ||
| 11 | +Remove the wd_put_msg_to_pool call on recv failure to align with | ||
| 12 | +aead/cipher/digest, and free the second SQE before jumping to free_first. | ||
| 13 | + | ||
| 14 | +Signed-off-by: Weili Qian <qianweili@huawei.com> | ||
| 15 | +--- | ||
| 16 | + drv/hisi_hpre.c | 2 ++ | ||
| 17 | + wd_dh.c | 2 -- | ||
| 18 | + wd_ecc.c | 2 -- | ||
| 19 | + wd_rsa.c | 2 -- | ||
| 20 | + wd_udma.c | 2 -- | ||
| 21 | + 5 files changed, 2 insertions(+), 8 deletions(-) | ||
| 22 | + | ||
| 23 | +diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c | ||
| 24 | +index 70abe92..6d61fa4 100644 | ||
| 25 | +--- a/drv/hisi_hpre.c | ||
| 26 | ++++ b/drv/hisi_hpre.c | ||
| 27 | +@@ -2713,6 +2713,8 @@ static int sm2_enc_parse(handle_t h_qp, struct wd_ecc_msg *msg, | ||
| 28 | + ret = parse_second_sqe(h_qp, msg, &second); | ||
| 29 | + if (unlikely(ret)) { | ||
| 30 | + WD_ERR("failed to parse second BD, ret = %d!\n", ret); | ||
| 31 | ++ if (second) | ||
| 32 | ++ free_req(second); | ||
| 33 | + goto free_first; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | +diff --git a/wd_dh.c b/wd_dh.c | ||
| 37 | +index 8026fd6..f9958b2 100644 | ||
| 38 | +--- a/wd_dh.c | ||
| 39 | ++++ b/wd_dh.c | ||
| 40 | +@@ -520,8 +520,6 @@ int wd_dh_poll_ctx(__u32 idx, __u32 expt, __u32 *count) | ||
| 41 | + } else if (unlikely(ret)) { | ||
| 42 | + WD_ERR("failed to async recv, ret = %d!\n", ret); | ||
| 43 | + *count = rcv_cnt; | ||
| 44 | +- wd_put_msg_to_pool(&wd_dh_setting.pool, idx, | ||
| 45 | +- rcv_msg.tag); | ||
| 46 | + return ret; | ||
| 47 | + } | ||
| 48 | + rcv_cnt++; | ||
| 49 | +diff --git a/wd_ecc.c b/wd_ecc.c | ||
| 50 | +index 4b141c4..679a3fb 100644 | ||
| 51 | +--- a/wd_ecc.c | ||
| 52 | ++++ b/wd_ecc.c | ||
| 53 | +@@ -2519,8 +2519,6 @@ int wd_ecc_poll_ctx(__u32 idx, __u32 expt, __u32 *count) | ||
| 54 | + } else if (ret < 0) { | ||
| 55 | + WD_ERR("failed to async recv, ret = %d!\n", ret); | ||
| 56 | + *count = rcv_cnt; | ||
| 57 | +- wd_put_msg_to_pool(&wd_ecc_setting.pool, idx, | ||
| 58 | +- recv_msg.tag); | ||
| 59 | + return ret; | ||
| 60 | + } | ||
| 61 | + rcv_cnt++; | ||
| 62 | +diff --git a/wd_rsa.c b/wd_rsa.c | ||
| 63 | +index 59c230d..539285d 100644 | ||
| 64 | +--- a/wd_rsa.c | ||
| 65 | ++++ b/wd_rsa.c | ||
| 66 | +@@ -583,8 +583,6 @@ int wd_rsa_poll_ctx(__u32 idx, __u32 expt, __u32 *count) | ||
| 67 | + return ret; | ||
| 68 | + } else if (ret < 0) { | ||
| 69 | + WD_ERR("failed to async recv, ret = %d!\n", ret); | ||
| 70 | +- wd_put_msg_to_pool(&wd_rsa_setting.pool, idx, | ||
| 71 | +- recv_msg.tag); | ||
| 72 | + return ret; | ||
| 73 | + } | ||
| 74 | + rcv_cnt++; | ||
| 75 | +diff --git a/wd_udma.c b/wd_udma.c | ||
| 76 | +index 582c8d1..e329838 100644 | ||
| 77 | +--- a/wd_udma.c | ||
| 78 | ++++ b/wd_udma.c | ||
| 79 | +@@ -337,8 +337,6 @@ static int wd_udma_poll_ctx(__u32 idx, __u32 expt, __u32 *count) | ||
| 80 | + } else if (unlikely(ret)) { | ||
| 81 | + WD_ERR("failed to async recv, ret = %d!\n", ret); | ||
| 82 | + *count = rcv_cnt; | ||
| 83 | +- wd_put_msg_to_pool(&wd_udma_setting.pool, idx, | ||
| 84 | +- rcv_msg.tag); | ||
| 85 | + return ret; | ||
| 86 | + } | ||
| 87 | + rcv_cnt++; | ||
| 88 | +-- | ||
| 89 | +2.25.1 | ||
| 90 | + | ||
| @@ -0,0 +1,53 @@ | |||
| 1 | +From a275a5830c8e44a27641cc2d6efea9dcbbbab839 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Weili Qian <qianweili@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:48 +0800 | ||
| 4 | +Subject: [PATCH 36/37] uadk: fix uninit memory and redundant driver init call | ||
| 5 | + | ||
| 6 | +wd_pool_init in wd_bmm.c allocated blk_array with malloc, leaving | ||
| 7 | +elements uninitialized and passing garbage blk/blk_dma to wd_iova_unmap | ||
| 8 | +on the error cleanup path. wd_comp_init_nolock in wd_comp.c called | ||
| 9 | +wd_alg_init_driver redundantly since the caller already invokes it, | ||
| 10 | +causing double initialization. Use calloc to zero-initialize blk_array | ||
| 11 | +and remove the redundant wd_alg_init_driver call to match other modules. | ||
| 12 | + | ||
| 13 | +Signed-off-by: Weili Qian <qianweili@huawei.com> | ||
| 14 | +--- | ||
| 15 | + wd_bmm.c | 2 +- | ||
| 16 | + wd_comp.c | 6 ------ | ||
| 17 | + 2 files changed, 1 insertion(+), 7 deletions(-) | ||
| 18 | + | ||
| 19 | +diff --git a/wd_bmm.c b/wd_bmm.c | ||
| 20 | +index 811afa2..e393e59 100644 | ||
| 21 | +--- a/wd_bmm.c | ||
| 22 | ++++ b/wd_bmm.c | ||
| 23 | +@@ -707,7 +707,7 @@ static int wd_pool_init(struct wd_blkpool *p) | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + /* Allocate block array */ | ||
| 27 | +- p->blk_array = (struct wd_blk_hd *)malloc(act_num * sizeof(struct wd_blk_hd)); | ||
| 28 | ++ p->blk_array = (struct wd_blk_hd *)calloc(act_num, sizeof(struct wd_blk_hd)); | ||
| 29 | + if (!p->blk_array) { | ||
| 30 | + WD_ERR("Failed to allocate block array.\n"); | ||
| 31 | + return -WD_ENOMEM; | ||
| 32 | +diff --git a/wd_comp.c b/wd_comp.c | ||
| 33 | +index 35af141..523a189 100644 | ||
| 34 | +--- a/wd_comp.c | ||
| 35 | ++++ b/wd_comp.c | ||
| 36 | +@@ -156,14 +156,8 @@ static int wd_comp_init_nolock(struct wd_ctx_config *config, struct wd_sched *sc | ||
| 37 | + if (ret < 0) | ||
| 38 | + goto out_clear_sched; | ||
| 39 | + | ||
| 40 | +- ret = wd_alg_init_driver(&wd_comp_setting.config); | ||
| 41 | +- if (ret) | ||
| 42 | +- goto out_clear_pool; | ||
| 43 | +- | ||
| 44 | + return 0; | ||
| 45 | + | ||
| 46 | +-out_clear_pool: | ||
| 47 | +- wd_uninit_async_request_pool(&wd_comp_setting.pool); | ||
| 48 | + out_clear_sched: | ||
| 49 | + wd_clear_sched(&wd_comp_setting.sched); | ||
| 50 | + out_clear_ctx_config: | ||
| 51 | +-- | ||
| 52 | +2.25.1 | ||
| 53 | + | ||
| @@ -0,0 +1,63 @@ | |||
| 1 | +From 013f8e17cfc4c69fb203ff7fc1f119684681c80e Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Weili Qian <qianweili@huawei.com> | ||
| 3 | +Date: Fri, 16 Oct 2026 17:17:49 +0800 | ||
| 4 | +Subject: [PATCH 37/37] uadk: initialize wd_sched_params to avoid uninitialized | ||
| 5 | + field reads | ||
| 6 | + | ||
| 7 | +Several session alloc functions (agg, join_gather, udma) declared a local | ||
| 8 | +struct wd_sched_params without initialization, setting only alg_name and | ||
| 9 | +ctxs before passing to wd_sched_set_param, which reads pkt_size, data_mode | ||
| 10 | +and prio_mode unconditionally. Uninitialized stack values caused | ||
| 11 | +nondeterministic scheduling. | ||
| 12 | + | ||
| 13 | +Initialize with = {0} at declaration, consistent with wd_comp_alloc_sess. | ||
| 14 | + | ||
| 15 | +Signed-off-by: Weili Qian <qianweili@huawei.com> | ||
| 16 | +--- | ||
| 17 | + wd_agg.c | 2 +- | ||
| 18 | + wd_join_gather.c | 2 +- | ||
| 19 | + wd_udma.c | 2 +- | ||
| 20 | + 3 files changed, 3 insertions(+), 3 deletions(-) | ||
| 21 | + | ||
| 22 | +diff --git a/wd_agg.c b/wd_agg.c | ||
| 23 | +index 951e03d..ed4ba74 100644 | ||
| 24 | +--- a/wd_agg.c | ||
| 25 | ++++ b/wd_agg.c | ||
| 26 | +@@ -446,7 +446,7 @@ static int wd_agg_uninit_sess_priv(struct wd_agg_sess *sess) | ||
| 27 | + | ||
| 28 | + handle_t wd_agg_alloc_sess(struct wd_agg_sess_setup *setup) | ||
| 29 | + { | ||
| 30 | +- struct wd_sched_params params; | ||
| 31 | ++ struct wd_sched_params params = {0}; | ||
| 32 | + struct wd_agg_sess *sess; | ||
| 33 | + __u32 out_agg_cols_num = 0; | ||
| 34 | + int ret; | ||
| 35 | +diff --git a/wd_join_gather.c b/wd_join_gather.c | ||
| 36 | +index e43dbf9..27472d3 100644 | ||
| 37 | +--- a/wd_join_gather.c | ||
| 38 | ++++ b/wd_join_gather.c | ||
| 39 | +@@ -533,7 +533,7 @@ static int wd_join_gather_init_sess(struct wd_join_gather_sess *sess, | ||
| 40 | + | ||
| 41 | + handle_t wd_join_gather_alloc_sess(struct wd_join_gather_sess_setup *setup) | ||
| 42 | + { | ||
| 43 | +- struct wd_sched_params params; | ||
| 44 | ++ struct wd_sched_params params = {0}; | ||
| 45 | + struct wd_join_gather_sess *sess; | ||
| 46 | + int ret; | ||
| 47 | + | ||
| 48 | +diff --git a/wd_udma.c b/wd_udma.c | ||
| 49 | +index e329838..b92e75b 100644 | ||
| 50 | +--- a/wd_udma.c | ||
| 51 | ++++ b/wd_udma.c | ||
| 52 | +@@ -78,7 +78,7 @@ void wd_udma_free_sess(handle_t sess) | ||
| 53 | + | ||
| 54 | + handle_t wd_udma_alloc_sess(struct wd_udma_sess_setup *setup) | ||
| 55 | + { | ||
| 56 | +- struct wd_sched_params params; | ||
| 57 | ++ struct wd_sched_params params = {0}; | ||
| 58 | + struct wd_udma_sess *sess; | ||
| 59 | + int ret; | ||
| 60 | + | ||
| 61 | +-- | ||
| 62 | +2.25.1 | ||
| 63 | + | ||
| @@ -2,7 +2,7 @@ | |||
| 2 | Name: libwd | 2 | Name: libwd |
| 3 | Summary: User Space Accelerator Development Kit | 3 | Summary: User Space Accelerator Development Kit |
| 4 | Version: 2.11.0 | 4 | Version: 2.11.0 |
| 5 | -Release: 3 | 5 | +Release: 4 |
| 6 | License: Apache-2.0 | 6 | License: Apache-2.0 |
| 7 | Source: %{name}-%{version}.tar.gz | 7 | Source: %{name}-%{version}.tar.gz |
| 8 | 8 | ||
| @@ -38,6 +38,21 @@ Patch0019: 0019-uadk-add-debug-configure-option-for-full-stack-trace.patch | |||
| 38 | Patch0020: 0020-uadk-remove-redundant-code-and-unused-variables.patch | 38 | Patch0020: 0020-uadk-remove-redundant-code-and-unused-variables.patch |
| 39 | Patch0021: 0021-uadk-fix-big-number-sign-compare-and-add-non-ARM-HWC.patch | 39 | Patch0021: 0021-uadk-fix-big-number-sign-compare-and-add-non-ARM-HWC.patch |
| 40 | Patch0022: 0022-uadk_tool-fix-segfault-in-digest-aead-init1-from-uni.patch | 40 | Patch0022: 0022-uadk_tool-fix-segfault-in-digest-aead-init1-from-uni.patch |
| 41 | +Patch0023: 0023-uadk-fix-Wmaybe-uninitialized-and-Wsign-compare-warn.patch | ||
| 42 | +Patch0024: 0024-uadk-bind-sync-async-ctx-to-same-device-under-SCHED_.patch | ||
| 43 | +Patch0025: 0025-uadk-simplify-SCHED_POLICY_DEV-ctx-alloc-to-non-inte.patch | ||
| 44 | +Patch0026: 0026-uadk-balance-ctx-allocation-across-devices-by-availa.patch | ||
| 45 | +Patch0027: 0027-uadk-unify-cipher-digest-aead-BD3-fill-and-parse-pat.patch | ||
| 46 | +Patch0028: 0028-uadk-fix-digest-BD3-stream-mode-issue.patch | ||
| 47 | +Patch0029: 0029-uadk-check-CE-digest-cipher-result-before-get_sqe.patch | ||
| 48 | +Patch0030: 0030-uadk-fix-alloc-free-pairing-in-rsa-session-key-error.patch | ||
| 49 | +Patch0031: 0031-uadk-fix-return-values-overwritten-by-sqe-queue-call.patch | ||
| 50 | +Patch0032: 0032-uadk-fix-buffer-overflow-and-out-of-bounds-access.patch | ||
| 51 | +Patch0033: 0033-uadk-fix-lock-init-failure-detection.patch | ||
| 52 | +Patch0034: 0034-uadk-fix-SGL-DMA-resource-leak-and-missing-NULL-chec.patch | ||
| 53 | +Patch0035: 0035-uadk-fix-message-pool-pollution-and-memory-leak.patch | ||
| 54 | +Patch0036: 0036-uadk-fix-uninit-memory-and-redundant-driver-init-cal.patch | ||
| 55 | +Patch0037: 0037-uadk-initialize-wd_sched_params-to-avoid-uninitializ.patch | ||
| 41 | 56 | ||
| 42 | %description | 57 | %description |
| 43 | This package contains the User Space Accelerator Library | 58 | This package contains the User Space Accelerator Library |
| @@ -119,6 +134,9 @@ rm -rf ${RPM_BUILD_ROOT} | |||
| 119 | /sbin/ldconfig | 134 | /sbin/ldconfig |
| 120 | 135 | ||
| 121 | %changelog | 136 | %changelog |
| 137 | +* Thu Oct 22 2026 RuiBin Deng <dengruibin@h-partners.com> 2.11.0-4 | ||
| 138 | +- uadk: fix memory safety, BD3 stream issues and optimize ctx scheduling | ||
| 139 | + | ||
| 122 | * Mon Aug 31 2026 RuiBin Deng <dengruibin@h-partners.com> 2.11.0-3 | 140 | * Mon Aug 31 2026 RuiBin Deng <dengruibin@h-partners.com> 2.11.0-3 |
| 123 | - uadk: add heterogeneous scheduling support and fix critical issues | 141 | - uadk: add heterogeneous scheduling support and fix critical issues |
| 124 | 142 | ||