1a9b7b2adSAnthony Liguori /*
2a9b7b2adSAnthony Liguori * QEMU Random Number Generator Backend
3a9b7b2adSAnthony Liguori *
4a9b7b2adSAnthony Liguori * Copyright IBM, Corp. 2012
5a9b7b2adSAnthony Liguori *
6a9b7b2adSAnthony Liguori * Authors:
7a9b7b2adSAnthony Liguori * Anthony Liguori <aliguori@us.ibm.com>
8a9b7b2adSAnthony Liguori *
9a9b7b2adSAnthony Liguori * This work is licensed under the terms of the GNU GPL, version 2 or later.
10a9b7b2adSAnthony Liguori * See the COPYING file in the top-level directory.
11a9b7b2adSAnthony Liguori */
12a9b7b2adSAnthony Liguori
139c058332SPeter Maydell #include "qemu/osdep.h"
14dccfcd0eSPaolo Bonzini #include "sysemu/rng.h"
15da34e65cSMarkus Armbruster #include "qapi/error.h"
160b8fa32fSMarkus Armbruster #include "qemu/module.h"
17269e09f3SIgor Mammedov #include "qom/object_interfaces.h"
18a9b7b2adSAnthony Liguori
rng_backend_request_entropy(RngBackend * s,size_t size,EntropyReceiveFunc * receive_entropy,void * opaque)19a9b7b2adSAnthony Liguori void rng_backend_request_entropy(RngBackend *s, size_t size,
20a9b7b2adSAnthony Liguori EntropyReceiveFunc *receive_entropy,
21a9b7b2adSAnthony Liguori void *opaque)
22a9b7b2adSAnthony Liguori {
23a9b7b2adSAnthony Liguori RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
2460253ed1SLadi Prosek RngRequest *req;
25a9b7b2adSAnthony Liguori
26a9b7b2adSAnthony Liguori if (k->request_entropy) {
2760253ed1SLadi Prosek req = g_malloc(sizeof(*req));
2860253ed1SLadi Prosek
2960253ed1SLadi Prosek req->offset = 0;
3060253ed1SLadi Prosek req->size = size;
3160253ed1SLadi Prosek req->receive_entropy = receive_entropy;
3260253ed1SLadi Prosek req->opaque = opaque;
3360253ed1SLadi Prosek req->data = g_malloc(req->size);
3460253ed1SLadi Prosek
3560253ed1SLadi Prosek k->request_entropy(s, req);
3660253ed1SLadi Prosek
37443590c2SLadi Prosek QSIMPLEQ_INSERT_TAIL(&s->requests, req, next);
38a9b7b2adSAnthony Liguori }
39a9b7b2adSAnthony Liguori }
40a9b7b2adSAnthony Liguori
rng_backend_prop_get_opened(Object * obj,Error ** errp)41a9b7b2adSAnthony Liguori static bool rng_backend_prop_get_opened(Object *obj, Error **errp)
42a9b7b2adSAnthony Liguori {
43a9b7b2adSAnthony Liguori RngBackend *s = RNG_BACKEND(obj);
44a9b7b2adSAnthony Liguori
45a9b7b2adSAnthony Liguori return s->opened;
46a9b7b2adSAnthony Liguori }
47a9b7b2adSAnthony Liguori
rng_backend_complete(UserCreatable * uc,Error ** errp)4857d3e1b3SIgor Mammedov static void rng_backend_complete(UserCreatable *uc, Error **errp)
49a9b7b2adSAnthony Liguori {
50*6e577937SPaolo Bonzini RngBackend *s = RNG_BACKEND(uc);
51a9b7b2adSAnthony Liguori RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
5265cd9064SMarkus Armbruster Error *local_err = NULL;
53a9b7b2adSAnthony Liguori
54a9b7b2adSAnthony Liguori if (k->opened) {
5565cd9064SMarkus Armbruster k->opened(s, &local_err);
5665cd9064SMarkus Armbruster if (local_err) {
5765cd9064SMarkus Armbruster error_propagate(errp, local_err);
5865cd9064SMarkus Armbruster return;
5965cd9064SMarkus Armbruster }
60a9b7b2adSAnthony Liguori }
61a9b7b2adSAnthony Liguori
6265cd9064SMarkus Armbruster s->opened = true;
63a9b7b2adSAnthony Liguori }
64a9b7b2adSAnthony Liguori
rng_backend_free_request(RngRequest * req)659f14b0adSLadi Prosek static void rng_backend_free_request(RngRequest *req)
669f14b0adSLadi Prosek {
679f14b0adSLadi Prosek g_free(req->data);
689f14b0adSLadi Prosek g_free(req);
699f14b0adSLadi Prosek }
709f14b0adSLadi Prosek
rng_backend_free_requests(RngBackend * s)719f14b0adSLadi Prosek static void rng_backend_free_requests(RngBackend *s)
729f14b0adSLadi Prosek {
73443590c2SLadi Prosek RngRequest *req, *next;
749f14b0adSLadi Prosek
75443590c2SLadi Prosek QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
76443590c2SLadi Prosek rng_backend_free_request(req);
779f14b0adSLadi Prosek }
789f14b0adSLadi Prosek
79443590c2SLadi Prosek QSIMPLEQ_INIT(&s->requests);
809f14b0adSLadi Prosek }
819f14b0adSLadi Prosek
rng_backend_finalize_request(RngBackend * s,RngRequest * req)829f14b0adSLadi Prosek void rng_backend_finalize_request(RngBackend *s, RngRequest *req)
839f14b0adSLadi Prosek {
84443590c2SLadi Prosek QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
859f14b0adSLadi Prosek rng_backend_free_request(req);
869f14b0adSLadi Prosek }
879f14b0adSLadi Prosek
rng_backend_init(Object * obj)88a9b7b2adSAnthony Liguori static void rng_backend_init(Object *obj)
89a9b7b2adSAnthony Liguori {
90443590c2SLadi Prosek RngBackend *s = RNG_BACKEND(obj);
91443590c2SLadi Prosek
92443590c2SLadi Prosek QSIMPLEQ_INIT(&s->requests);
93a9b7b2adSAnthony Liguori }
94a9b7b2adSAnthony Liguori
rng_backend_finalize(Object * obj)959f14b0adSLadi Prosek static void rng_backend_finalize(Object *obj)
969f14b0adSLadi Prosek {
979f14b0adSLadi Prosek RngBackend *s = RNG_BACKEND(obj);
989f14b0adSLadi Prosek
999f14b0adSLadi Prosek rng_backend_free_requests(s);
1009f14b0adSLadi Prosek }
1019f14b0adSLadi Prosek
rng_backend_class_init(ObjectClass * oc,void * data)10257d3e1b3SIgor Mammedov static void rng_backend_class_init(ObjectClass *oc, void *data)
10357d3e1b3SIgor Mammedov {
10457d3e1b3SIgor Mammedov UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
10557d3e1b3SIgor Mammedov
10657d3e1b3SIgor Mammedov ucc->complete = rng_backend_complete;
10729ee2a18SEduardo Habkost
10829ee2a18SEduardo Habkost object_class_property_add_bool(oc, "opened",
10929ee2a18SEduardo Habkost rng_backend_prop_get_opened,
110*6e577937SPaolo Bonzini NULL);
11157d3e1b3SIgor Mammedov }
11257d3e1b3SIgor Mammedov
1138c43a6f0SAndreas Färber static const TypeInfo rng_backend_info = {
114a9b7b2adSAnthony Liguori .name = TYPE_RNG_BACKEND,
115a9b7b2adSAnthony Liguori .parent = TYPE_OBJECT,
116a9b7b2adSAnthony Liguori .instance_size = sizeof(RngBackend),
117a9b7b2adSAnthony Liguori .instance_init = rng_backend_init,
1189f14b0adSLadi Prosek .instance_finalize = rng_backend_finalize,
119a9b7b2adSAnthony Liguori .class_size = sizeof(RngBackendClass),
12057d3e1b3SIgor Mammedov .class_init = rng_backend_class_init,
121a9b7b2adSAnthony Liguori .abstract = true,
122269e09f3SIgor Mammedov .interfaces = (InterfaceInfo[]) {
123269e09f3SIgor Mammedov { TYPE_USER_CREATABLE },
124269e09f3SIgor Mammedov { }
125269e09f3SIgor Mammedov }
126a9b7b2adSAnthony Liguori };
127a9b7b2adSAnthony Liguori
register_types(void)128a9b7b2adSAnthony Liguori static void register_types(void)
129a9b7b2adSAnthony Liguori {
130a9b7b2adSAnthony Liguori type_register_static(&rng_backend_info);
131a9b7b2adSAnthony Liguori }
132a9b7b2adSAnthony Liguori
133a9b7b2adSAnthony Liguori type_init(register_types);
134