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/env.h" 15 #include "spdk/util.h" 16 17 static void 18 rpc_accel_get_opc_assignments(struct spdk_jsonrpc_request *request, 19 const struct spdk_json_val *params) 20 { 21 struct spdk_json_write_ctx *w; 22 enum accel_opcode opcode; 23 const char *name, *module_name = NULL; 24 int rc; 25 26 if (params != NULL) { 27 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 28 "accel_get_opc_assignments requires no parameters"); 29 return; 30 } 31 32 w = spdk_jsonrpc_begin_result(request); 33 34 spdk_json_write_object_begin(w); 35 for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) { 36 rc = _accel_get_opc_name(opcode, &name); 37 if (rc == 0) { 38 rc = spdk_accel_get_opc_module_name(opcode, &module_name); 39 if (rc == 0) { 40 spdk_json_write_named_string(w, name, module_name); 41 } else { 42 /* This isn't fatal but throw an informational message if we 43 * cant get an module name right now */ 44 SPDK_NOTICELOG("FYI error (%d) getting module name.\n", rc); 45 } 46 } else { 47 /* this should never happen */ 48 SPDK_ERRLOG("Invalid opcode (%d)).\n", opcode); 49 assert(0); 50 } 51 } 52 spdk_json_write_object_end(w); 53 54 spdk_jsonrpc_end_result(request, w); 55 } 56 SPDK_RPC_REGISTER("accel_get_opc_assignments", rpc_accel_get_opc_assignments, SPDK_RPC_RUNTIME) 57 58 static void 59 rpc_dump_module_info(struct module_info *info) 60 { 61 struct spdk_json_write_ctx *w = info->w; 62 const char *name; 63 uint32_t i; 64 int rc; 65 66 spdk_json_write_object_begin(w); 67 68 spdk_json_write_named_string(w, "module", info->name); 69 spdk_json_write_named_array_begin(w, "supported ops"); 70 71 for (i = 0; i < info->num_ops; i++) { 72 rc = _accel_get_opc_name(i, &name); 73 if (rc == 0) { 74 spdk_json_write_string(w, name); 75 } else { 76 /* this should never happen */ 77 SPDK_ERRLOG("Invalid opcode (%d)).\n", i); 78 assert(0); 79 } 80 } 81 82 spdk_json_write_array_end(w); 83 spdk_json_write_object_end(w); 84 } 85 86 static void 87 rpc_accel_get_module_info(struct spdk_jsonrpc_request *request, 88 const struct spdk_json_val *params) 89 { 90 struct module_info info; 91 92 if (params != NULL) { 93 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 94 "accel_get_module_info requires no parameters"); 95 return; 96 } 97 98 info.w = spdk_jsonrpc_begin_result(request); 99 spdk_json_write_array_begin(info.w); 100 101 _accel_for_each_module(&info, rpc_dump_module_info); 102 103 spdk_json_write_array_end(info.w); 104 spdk_jsonrpc_end_result(request, info.w); 105 } 106 SPDK_RPC_REGISTER("accel_get_module_info", rpc_accel_get_module_info, SPDK_RPC_RUNTIME) 107 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(accel_get_module_info, accel_get_engine_info) 108 109 struct rpc_accel_assign_opc { 110 char *opname; 111 char *module; 112 }; 113 114 static const struct spdk_json_object_decoder rpc_accel_assign_opc_decoders[] = { 115 {"opname", offsetof(struct rpc_accel_assign_opc, opname), spdk_json_decode_string}, 116 {"module", offsetof(struct rpc_accel_assign_opc, module), spdk_json_decode_string}, 117 }; 118 119 static void 120 free_accel_assign_opc(struct rpc_accel_assign_opc *r) 121 { 122 free(r->opname); 123 free(r->module); 124 } 125 126 static void 127 rpc_accel_assign_opc(struct spdk_jsonrpc_request *request, 128 const struct spdk_json_val *params) 129 { 130 struct rpc_accel_assign_opc req = {}; 131 const char *opcode_str; 132 enum accel_opcode opcode; 133 bool found = false; 134 int rc; 135 136 if (spdk_json_decode_object(params, rpc_accel_assign_opc_decoders, 137 SPDK_COUNTOF(rpc_accel_assign_opc_decoders), 138 &req)) { 139 SPDK_DEBUGLOG(accel, "spdk_json_decode_object failed\n"); 140 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 141 "spdk_json_decode_object failed"); 142 goto cleanup; 143 } 144 145 for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) { 146 rc = _accel_get_opc_name(opcode, &opcode_str); 147 assert(!rc); 148 if (strcmp(opcode_str, req.opname) == 0) { 149 found = true; 150 break; 151 } 152 } 153 154 if (found == false) { 155 SPDK_DEBUGLOG(accel, "Invalid operation name\n"); 156 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 157 "spdk_json_decode_object failed"); 158 goto cleanup; 159 } 160 161 rc = spdk_accel_assign_opc(opcode, req.module); 162 if (rc) { 163 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 164 "error assigning opcode"); 165 goto cleanup; 166 } 167 168 SPDK_NOTICELOG("Operation %s will be assigned to module %s\n", req.opname, req.module); 169 spdk_jsonrpc_send_bool_response(request, true); 170 171 cleanup: 172 free_accel_assign_opc(&req); 173 174 } 175 SPDK_RPC_REGISTER("accel_assign_opc", rpc_accel_assign_opc, SPDK_RPC_STARTUP) 176 177 struct rpc_accel_crypto_key_create { 178 struct spdk_accel_crypto_key_create_param param; 179 }; 180 181 static const struct spdk_json_object_decoder rpc_accel_dek_create_decoders[] = { 182 {"cipher", offsetof(struct rpc_accel_crypto_key_create, param.cipher), spdk_json_decode_string}, 183 {"key", offsetof(struct rpc_accel_crypto_key_create, param.hex_key), spdk_json_decode_string}, 184 {"key2", offsetof(struct rpc_accel_crypto_key_create, param.hex_key2), spdk_json_decode_string, true}, 185 {"name", offsetof(struct rpc_accel_crypto_key_create, param.key_name), spdk_json_decode_string}, 186 }; 187 188 static void 189 rpc_accel_crypto_key_create(struct spdk_jsonrpc_request *request, 190 const struct spdk_json_val *params) 191 { 192 struct rpc_accel_crypto_key_create req = {}; 193 size_t key_size; 194 int rc; 195 196 if (spdk_json_decode_object(params, rpc_accel_dek_create_decoders, 197 SPDK_COUNTOF(rpc_accel_dek_create_decoders), 198 &req)) { 199 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 200 "spdk_json_decode_object failed"); 201 goto cleanup; 202 } 203 204 rc = spdk_accel_crypto_key_create(&req.param); 205 if (rc) { 206 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 207 "failed to create DEK, rc %d", rc); 208 } else { 209 spdk_jsonrpc_send_bool_response(request, true); 210 } 211 212 cleanup: 213 free(req.param.cipher); 214 if (req.param.hex_key) { 215 key_size = strnlen(req.param.hex_key, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH); 216 spdk_memset_s(req.param.hex_key, key_size, 0, key_size); 217 free(req.param.hex_key); 218 } 219 if (req.param.hex_key2) { 220 key_size = strnlen(req.param.hex_key2, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH); 221 spdk_memset_s(req.param.hex_key2, key_size, 0, key_size); 222 free(req.param.hex_key2); 223 } 224 free(req.param.key_name); 225 } 226 SPDK_RPC_REGISTER("accel_crypto_key_create", rpc_accel_crypto_key_create, SPDK_RPC_RUNTIME) 227 228 struct rpc_accel_crypto_keys_get_ctx { 229 char *key_name; 230 }; 231 232 static const struct spdk_json_object_decoder rpc_accel_crypto_keys_get_decoders[] = { 233 {"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string, true}, 234 }; 235 236 static void 237 rpc_accel_crypto_keys_get(struct spdk_jsonrpc_request *request, 238 const struct spdk_json_val *params) 239 { 240 struct rpc_accel_crypto_keys_get_ctx req = {}; 241 struct spdk_accel_crypto_key *key = NULL; 242 struct spdk_json_write_ctx *w; 243 244 if (params && spdk_json_decode_object(params, rpc_accel_crypto_keys_get_decoders, 245 SPDK_COUNTOF(rpc_accel_crypto_keys_get_decoders), 246 &req)) { 247 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR, 248 "spdk_json_decode_object failed"); 249 free(req.key_name); 250 return; 251 } 252 253 if (req.key_name) { 254 key = spdk_accel_crypto_key_get(req.key_name); 255 free(req.key_name); 256 if (!key) { 257 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "key was not found\n"); 258 return; 259 } 260 } 261 262 w = spdk_jsonrpc_begin_result(request); 263 spdk_json_write_array_begin(w); 264 265 if (key) { 266 _accel_crypto_key_dump_param(w, key); 267 } else { 268 _accel_crypto_keys_dump_param(w); 269 } 270 271 spdk_json_write_array_end(w); 272 spdk_jsonrpc_end_result(request, w); 273 } 274 SPDK_RPC_REGISTER("accel_crypto_keys_get", rpc_accel_crypto_keys_get, SPDK_RPC_RUNTIME) 275