Merge tag 'pull-target-arm-20221122' of https://git.linaro.org/people/pmaydell/qemu...
[qemu/ar7.git] / backends / cryptodev.c
blob54ee8c81f50f8d1091903d43a73f45a6ddd6f630
1 /*
2 * QEMU Crypto Device Implementation
4 * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
6 * Authors:
7 * Gonglei <arei.gonglei@huawei.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include "qemu/osdep.h"
25 #include "sysemu/cryptodev.h"
26 #include "qapi/error.h"
27 #include "qapi/visitor.h"
28 #include "qemu/config-file.h"
29 #include "qemu/error-report.h"
30 #include "qom/object_interfaces.h"
31 #include "hw/virtio/virtio-crypto.h"
34 static QTAILQ_HEAD(, CryptoDevBackendClient) crypto_clients;
37 CryptoDevBackendClient *
38 cryptodev_backend_new_client(const char *model,
39 const char *name)
41 CryptoDevBackendClient *cc;
43 cc = g_new0(CryptoDevBackendClient, 1);
44 cc->model = g_strdup(model);
45 if (name) {
46 cc->name = g_strdup(name);
49 QTAILQ_INSERT_TAIL(&crypto_clients, cc, next);
51 return cc;
54 void cryptodev_backend_free_client(
55 CryptoDevBackendClient *cc)
57 QTAILQ_REMOVE(&crypto_clients, cc, next);
58 g_free(cc->name);
59 g_free(cc->model);
60 g_free(cc->info_str);
61 g_free(cc);
64 void cryptodev_backend_cleanup(
65 CryptoDevBackend *backend,
66 Error **errp)
68 CryptoDevBackendClass *bc =
69 CRYPTODEV_BACKEND_GET_CLASS(backend);
71 if (bc->cleanup) {
72 bc->cleanup(backend, errp);
76 int cryptodev_backend_create_session(
77 CryptoDevBackend *backend,
78 CryptoDevBackendSessionInfo *sess_info,
79 uint32_t queue_index,
80 CryptoDevCompletionFunc cb,
81 void *opaque)
83 CryptoDevBackendClass *bc =
84 CRYPTODEV_BACKEND_GET_CLASS(backend);
86 if (bc->create_session) {
87 return bc->create_session(backend, sess_info, queue_index, cb, opaque);
89 return -VIRTIO_CRYPTO_NOTSUPP;
92 int cryptodev_backend_close_session(
93 CryptoDevBackend *backend,
94 uint64_t session_id,
95 uint32_t queue_index,
96 CryptoDevCompletionFunc cb,
97 void *opaque)
99 CryptoDevBackendClass *bc =
100 CRYPTODEV_BACKEND_GET_CLASS(backend);
102 if (bc->close_session) {
103 return bc->close_session(backend, session_id, queue_index, cb, opaque);
105 return -VIRTIO_CRYPTO_NOTSUPP;
108 static int cryptodev_backend_operation(
109 CryptoDevBackend *backend,
110 CryptoDevBackendOpInfo *op_info,
111 uint32_t queue_index,
112 CryptoDevCompletionFunc cb,
113 void *opaque)
115 CryptoDevBackendClass *bc =
116 CRYPTODEV_BACKEND_GET_CLASS(backend);
118 if (bc->do_op) {
119 return bc->do_op(backend, op_info, queue_index, cb, opaque);
121 return -VIRTIO_CRYPTO_NOTSUPP;
124 int cryptodev_backend_crypto_operation(
125 CryptoDevBackend *backend,
126 void *opaque1,
127 uint32_t queue_index,
128 CryptoDevCompletionFunc cb, void *opaque2)
130 VirtIOCryptoReq *req = opaque1;
131 CryptoDevBackendOpInfo *op_info = &req->op_info;
132 enum CryptoDevBackendAlgType algtype = req->flags;
134 if ((algtype != CRYPTODEV_BACKEND_ALG_SYM)
135 && (algtype != CRYPTODEV_BACKEND_ALG_ASYM)) {
136 error_report("Unsupported cryptodev alg type: %" PRIu32 "", algtype);
137 return -VIRTIO_CRYPTO_NOTSUPP;
140 return cryptodev_backend_operation(backend, op_info, queue_index,
141 cb, opaque2);
144 static void
145 cryptodev_backend_get_queues(Object *obj, Visitor *v, const char *name,
146 void *opaque, Error **errp)
148 CryptoDevBackend *backend = CRYPTODEV_BACKEND(obj);
149 uint32_t value = backend->conf.peers.queues;
151 visit_type_uint32(v, name, &value, errp);
154 static void
155 cryptodev_backend_set_queues(Object *obj, Visitor *v, const char *name,
156 void *opaque, Error **errp)
158 CryptoDevBackend *backend = CRYPTODEV_BACKEND(obj);
159 uint32_t value;
161 if (!visit_type_uint32(v, name, &value, errp)) {
162 return;
164 if (!value) {
165 error_setg(errp, "Property '%s.%s' doesn't take value '%" PRIu32 "'",
166 object_get_typename(obj), name, value);
167 return;
169 backend->conf.peers.queues = value;
172 static void
173 cryptodev_backend_complete(UserCreatable *uc, Error **errp)
175 CryptoDevBackend *backend = CRYPTODEV_BACKEND(uc);
176 CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_GET_CLASS(uc);
178 if (bc->init) {
179 bc->init(backend, errp);
183 void cryptodev_backend_set_used(CryptoDevBackend *backend, bool used)
185 backend->is_used = used;
188 bool cryptodev_backend_is_used(CryptoDevBackend *backend)
190 return backend->is_used;
193 void cryptodev_backend_set_ready(CryptoDevBackend *backend, bool ready)
195 backend->ready = ready;
198 bool cryptodev_backend_is_ready(CryptoDevBackend *backend)
200 return backend->ready;
203 static bool
204 cryptodev_backend_can_be_deleted(UserCreatable *uc)
206 return !cryptodev_backend_is_used(CRYPTODEV_BACKEND(uc));
209 static void cryptodev_backend_instance_init(Object *obj)
211 /* Initialize devices' queues property to 1 */
212 object_property_set_int(obj, "queues", 1, NULL);
215 static void cryptodev_backend_finalize(Object *obj)
217 CryptoDevBackend *backend = CRYPTODEV_BACKEND(obj);
219 cryptodev_backend_cleanup(backend, NULL);
222 static void
223 cryptodev_backend_class_init(ObjectClass *oc, void *data)
225 UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
227 ucc->complete = cryptodev_backend_complete;
228 ucc->can_be_deleted = cryptodev_backend_can_be_deleted;
230 QTAILQ_INIT(&crypto_clients);
231 object_class_property_add(oc, "queues", "uint32",
232 cryptodev_backend_get_queues,
233 cryptodev_backend_set_queues,
234 NULL, NULL);
237 static const TypeInfo cryptodev_backend_info = {
238 .name = TYPE_CRYPTODEV_BACKEND,
239 .parent = TYPE_OBJECT,
240 .instance_size = sizeof(CryptoDevBackend),
241 .instance_init = cryptodev_backend_instance_init,
242 .instance_finalize = cryptodev_backend_finalize,
243 .class_size = sizeof(CryptoDevBackendClass),
244 .class_init = cryptodev_backend_class_init,
245 .interfaces = (InterfaceInfo[]) {
246 { TYPE_USER_CREATABLE },
251 static void
252 cryptodev_backend_register_types(void)
254 type_register_static(&cryptodev_backend_info);
257 type_init(cryptodev_backend_register_types);