1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2020 Intel Corporation. 3 * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. 4 * All rights reserved. 5 */ 6 7 #include "accel_internal.h" 8 #include "spdk_internal/accel_module.h" 9 10 #include "spdk/rpc.h" 11 #include "spdk/util.h" 12 #include "spdk/event.h" 13 #include "spdk/stdinc.h" 14 #include "spdk/string.h" 15 #include "spdk/env.h" 16 #include "spdk/util.h" 17 18 static void 19 rpc_accel_get_opc_assignments(struct spdk_jsonrpc_request *request, 20 const struct spdk_json_val *params) 21 { 22 struct spdk_json_write_ctx *w; 23 enum accel_opcode opcode; 24 const char *name, *module_name = NULL; 25 int rc; 26 27 if (params != NULL) { 28 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 29 "accel_get_opc_assignments requires no parameters"); 30 return; 31 } 32 33 w = spdk_jsonrpc_begin_result(request); 34 35 spdk_json_write_object_begin(w); 36 for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) { 37 rc = _accel_get_opc_name(opcode, &name); 38 if (rc == 0) { 39 rc = spdk_accel_get_opc_module_name(opcode, &module_name); 40 if (rc == 0) { 41 spdk_json_write_named_string(w, name, module_name); 42 } else { 43 /* This isn't fatal but throw an informational message if we 44 * cant get an module name right now */ 45 SPDK_NOTICELOG("FYI error (%d) getting module name.\n", rc); 46 } 47 } else { 48 /* this should never happen */ 49 SPDK_ERRLOG("Invalid opcode (%d)).\n", opcode); 50 assert(0); 51 } 52 } 53 spdk_json_write_object_end(w); 54 55 spdk_jsonrpc_end_result(request, w); 56 } 57 SPDK_RPC_REGISTER("accel_get_opc_assignments", rpc_accel_get_opc_assignments, SPDK_RPC_RUNTIME) 58 59 static void 60 rpc_dump_module_info(struct module_info *info) 61 { 62 struct spdk_json_write_ctx *w = info->w; 63 const char *name; 64 uint32_t i; 65 int rc; 66 67 spdk_json_write_object_begin(w); 68 69 spdk_json_write_named_string(w, "module", info->name); 70 spdk_json_write_named_array_begin(w, "supported ops"); 71 72 for (i = 0; i < info->num_ops; i++) { 73 rc = _accel_get_opc_name(i, &name); 74 if (rc == 0) { 75 spdk_json_write_string(w, name); 76 } else { 77 /* this should never happen */ 78 SPDK_ERRLOG("Invalid opcode (%d)).\n", i); 79 assert(0); 80 } 81 } 82 83 spdk_json_write_array_end(w); 84 spdk_json_write_object_end(w); 85 } 86 87 static void 88 rpc_accel_get_module_info(struct spdk_jsonrpc_request *request, 89 const struct spdk_json_val *params) 90 { 91 struct module_info info; 92 93 if (params != NULL) { 94 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 95 "accel_get_module_info requires no parameters"); 96 return; 97 } 98 99 info.w = spdk_jsonrpc_begin_result(request); 100 spdk_json_write_array_begin(info.w); 101 102 _accel_for_each_module(&info, rpc_dump_module_info); 103 104 spdk_json_write_array_end(info.w); 105 spdk_jsonrpc_end_result(request, info.w); 106 } 107 SPDK_RPC_REGISTER("accel_get_module_info", rpc_accel_get_module_info, SPDK_RPC_RUNTIME) 108 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(accel_get_module_info, accel_get_engine_info) 109 110 struct rpc_accel_assign_opc { 111 char *opname; 112 char *module; 113 }; 114 115 static const struct spdk_json_object_decoder rpc_accel_assign_opc_decoders[] = { 116 {"opname", offsetof(struct rpc_accel_assign_opc, opname), spdk_json_decode_string}, 117 {"module", offsetof(struct rpc_accel_assign_opc, module), spdk_json_decode_string}, 118 }; 119 120 static void 121 free_accel_assign_opc(struct rpc_accel_assign_opc *r) 122 { 123 free(r->opname); 124 free(r->module); 125 } 126 127 static void 128 rpc_accel_assign_opc(struct spdk_jsonrpc_request *request, 129 const struct spdk_json_val *params) 130 { 131 struct rpc_accel_assign_opc req = {}; 132 const char *opcode_str; 133 enum accel_opcode opcode; 134 bool found = false; 135 int rc; 136 137 if (spdk_json_decode_object(params, rpc_accel_assign_opc_decoders, 138 SPDK_COUNTOF(rpc_accel_assign_opc_decoders), 139 &req)) { 140 SPDK_DEBUGLOG(accel, "spdk_json_decode_object failed\n"); 141 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 142 "spdk_json_decode_object failed"); 143 goto cleanup; 144 } 145 146 for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) { 147 rc = _accel_get_opc_name(opcode, &opcode_str); 148 assert(!rc); 149 if (strcmp(opcode_str, req.opname) == 0) { 150 found = true; 151 break; 152 } 153 } 154 155 if (found == false) { 156 SPDK_DEBUGLOG(accel, "Invalid operation name\n"); 157 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 158 "spdk_json_decode_object failed"); 159 goto cleanup; 160 } 161 162 rc = spdk_accel_assign_opc(opcode, req.module); 163 if (rc) { 164 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 165 "error assigning opcode"); 166 goto cleanup; 167 } 168 169 SPDK_NOTICELOG("Operation %s will be assigned to module %s\n", req.opname, req.module); 170 spdk_jsonrpc_send_bool_response(request, true); 171 172 cleanup: 173 free_accel_assign_opc(&req); 174 175 } 176 SPDK_RPC_REGISTER("accel_assign_opc", rpc_accel_assign_opc, SPDK_RPC_STARTUP) 177 178 struct rpc_accel_crypto_key_create { 179 struct spdk_accel_crypto_key_create_param param; 180 }; 181 182 static const struct spdk_json_object_decoder rpc_accel_dek_create_decoders[] = { 183 {"cipher", offsetof(struct rpc_accel_crypto_key_create, param.cipher), spdk_json_decode_string}, 184 {"key", offsetof(struct rpc_accel_crypto_key_create, param.hex_key), spdk_json_decode_string}, 185 {"key2", offsetof(struct rpc_accel_crypto_key_create, param.hex_key2), spdk_json_decode_string, true}, 186 {"name", offsetof(struct rpc_accel_crypto_key_create, param.key_name), spdk_json_decode_string}, 187 }; 188 189 static void 190 rpc_accel_crypto_key_create(struct spdk_jsonrpc_request *request, 191 const struct spdk_json_val *params) 192 { 193 struct rpc_accel_crypto_key_create req = {}; 194 size_t key_size; 195 int rc; 196 197 if (spdk_json_decode_object(params, rpc_accel_dek_create_decoders, 198 SPDK_COUNTOF(rpc_accel_dek_create_decoders), 199 &req)) { 200 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 201 "spdk_json_decode_object failed"); 202 goto cleanup; 203 } 204 205 rc = spdk_accel_crypto_key_create(&req.param); 206 if (rc) { 207 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 208 "failed to create DEK, rc %d", rc); 209 } else { 210 spdk_jsonrpc_send_bool_response(request, true); 211 } 212 213 cleanup: 214 free(req.param.cipher); 215 if (req.param.hex_key) { 216 key_size = strnlen(req.param.hex_key, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH); 217 spdk_memset_s(req.param.hex_key, key_size, 0, key_size); 218 free(req.param.hex_key); 219 } 220 if (req.param.hex_key2) { 221 key_size = strnlen(req.param.hex_key2, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH); 222 spdk_memset_s(req.param.hex_key2, key_size, 0, key_size); 223 free(req.param.hex_key2); 224 } 225 free(req.param.key_name); 226 } 227 SPDK_RPC_REGISTER("accel_crypto_key_create", rpc_accel_crypto_key_create, SPDK_RPC_RUNTIME) 228 229 struct rpc_accel_crypto_keys_get_ctx { 230 char *key_name; 231 }; 232 233 static const struct spdk_json_object_decoder rpc_accel_crypto_keys_get_decoders[] = { 234 {"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string, true}, 235 }; 236 237 static void 238 rpc_accel_crypto_keys_get(struct spdk_jsonrpc_request *request, 239 const struct spdk_json_val *params) 240 { 241 struct rpc_accel_crypto_keys_get_ctx req = {}; 242 struct spdk_accel_crypto_key *key = NULL; 243 struct spdk_json_write_ctx *w; 244 245 if (params && spdk_json_decode_object(params, rpc_accel_crypto_keys_get_decoders, 246 SPDK_COUNTOF(rpc_accel_crypto_keys_get_decoders), 247 &req)) { 248 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 249 "spdk_json_decode_object failed"); 250 free(req.key_name); 251 return; 252 } 253 254 if (req.key_name) { 255 key = spdk_accel_crypto_key_get(req.key_name); 256 free(req.key_name); 257 if (!key) { 258 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "key was not found\n"); 259 return; 260 } 261 } 262 263 w = spdk_jsonrpc_begin_result(request); 264 spdk_json_write_array_begin(w); 265 266 if (key) { 267 _accel_crypto_key_dump_param(w, key); 268 } else { 269 _accel_crypto_keys_dump_param(w); 270 } 271 272 spdk_json_write_array_end(w); 273 spdk_jsonrpc_end_result(request, w); 274 } 275 SPDK_RPC_REGISTER("accel_crypto_keys_get", rpc_accel_crypto_keys_get, SPDK_RPC_RUNTIME) 276 277 static const struct spdk_json_object_decoder rpc_accel_crypto_key_destroy_decoders[] = { 278 {"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string}, 279 }; 280 281 static void 282 rpc_accel_crypto_key_destroy(struct spdk_jsonrpc_request *request, 283 const struct spdk_json_val *params) 284 { 285 struct rpc_accel_crypto_keys_get_ctx req = {}; 286 struct spdk_accel_crypto_key *key = NULL; 287 int rc; 288 289 if (spdk_json_decode_object(params, rpc_accel_crypto_key_destroy_decoders, 290 SPDK_COUNTOF(rpc_accel_crypto_key_destroy_decoders), 291 &req)) { 292 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 293 "spdk_json_decode_object failed"); 294 free(req.key_name); 295 return; 296 } 297 298 key = spdk_accel_crypto_key_get(req.key_name); 299 if (!key) { 300 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 301 "No key object found"); 302 free(req.key_name); 303 return; 304 305 } 306 rc = spdk_accel_crypto_key_destroy(key); 307 if (rc) { 308 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 309 "Failed to destroy key, rc %d\n", rc); 310 } else { 311 spdk_jsonrpc_send_bool_response(request, true); 312 } 313 314 free(req.key_name); 315 } 316 SPDK_RPC_REGISTER("accel_crypto_key_destroy", rpc_accel_crypto_key_destroy, SPDK_RPC_RUNTIME) 317 318 struct rpc_accel_set_driver { 319 char *name; 320 }; 321 322 static const struct spdk_json_object_decoder rpc_accel_set_driver_decoders[] = { 323 {"name", offsetof(struct rpc_accel_set_driver, name), spdk_json_decode_string}, 324 }; 325 326 static void 327 free_rpc_accel_set_driver(struct rpc_accel_set_driver *r) 328 { 329 free(r->name); 330 } 331 332 static void 333 rpc_accel_set_driver(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) 334 { 335 struct rpc_accel_set_driver req = {}; 336 int rc; 337 338 if (spdk_json_decode_object(params, rpc_accel_set_driver_decoders, 339 SPDK_COUNTOF(rpc_accel_set_driver_decoders), &req)) { 340 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 341 "spdk_json_decode_object failed"); 342 return; 343 } 344 345 rc = spdk_accel_set_driver(req.name); 346 if (rc != 0) { 347 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 348 goto cleanup; 349 } 350 351 SPDK_NOTICELOG("Using accel driver: %s\n", req.name); 352 spdk_jsonrpc_send_bool_response(request, true); 353 cleanup: 354 free_rpc_accel_set_driver(&req); 355 } 356 SPDK_RPC_REGISTER("accel_set_driver", rpc_accel_set_driver, SPDK_RPC_STARTUP) 357