xref: /qemu/backends/rng.c (revision 6f1e91f7)
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 {
506e577937SPaolo 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,
1106e577937SPaolo 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