xref: /openbmc/qemu/backends/rng-builtin.c (revision 6c4e9d487fea67ceaebf5942be5b76ed675d0e9a)
1*6c4e9d48SLaurent Vivier /*
2*6c4e9d48SLaurent Vivier  * QEMU Builtin Random Number Generator Backend
3*6c4e9d48SLaurent Vivier  *
4*6c4e9d48SLaurent Vivier  * This work is licensed under the terms of the GNU GPL, version 2 or later.
5*6c4e9d48SLaurent Vivier  * See the COPYING file in the top-level directory.
6*6c4e9d48SLaurent Vivier  */
7*6c4e9d48SLaurent Vivier 
8*6c4e9d48SLaurent Vivier #include "qemu/osdep.h"
9*6c4e9d48SLaurent Vivier #include "sysemu/rng.h"
10*6c4e9d48SLaurent Vivier #include "qemu/main-loop.h"
11*6c4e9d48SLaurent Vivier #include "qemu/guest-random.h"
12*6c4e9d48SLaurent Vivier 
13*6c4e9d48SLaurent Vivier #define TYPE_RNG_BUILTIN "rng-builtin"
14*6c4e9d48SLaurent Vivier #define RNG_BUILTIN(obj) OBJECT_CHECK(RngBuiltin, (obj), TYPE_RNG_BUILTIN)
15*6c4e9d48SLaurent Vivier 
16*6c4e9d48SLaurent Vivier typedef struct RngBuiltin {
17*6c4e9d48SLaurent Vivier     RngBackend parent;
18*6c4e9d48SLaurent Vivier     QEMUBH *bh;
19*6c4e9d48SLaurent Vivier } RngBuiltin;
20*6c4e9d48SLaurent Vivier 
21*6c4e9d48SLaurent Vivier static void rng_builtin_receive_entropy_bh(void *opaque)
22*6c4e9d48SLaurent Vivier {
23*6c4e9d48SLaurent Vivier     RngBuiltin *s = opaque;
24*6c4e9d48SLaurent Vivier 
25*6c4e9d48SLaurent Vivier     while (!QSIMPLEQ_EMPTY(&s->parent.requests)) {
26*6c4e9d48SLaurent Vivier         RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests);
27*6c4e9d48SLaurent Vivier 
28*6c4e9d48SLaurent Vivier         qemu_guest_getrandom_nofail(req->data, req->size);
29*6c4e9d48SLaurent Vivier 
30*6c4e9d48SLaurent Vivier         req->receive_entropy(req->opaque, req->data, req->size);
31*6c4e9d48SLaurent Vivier 
32*6c4e9d48SLaurent Vivier         rng_backend_finalize_request(&s->parent, req);
33*6c4e9d48SLaurent Vivier     }
34*6c4e9d48SLaurent Vivier }
35*6c4e9d48SLaurent Vivier 
36*6c4e9d48SLaurent Vivier static void rng_builtin_request_entropy(RngBackend *b, RngRequest *req)
37*6c4e9d48SLaurent Vivier {
38*6c4e9d48SLaurent Vivier     RngBuiltin *s = RNG_BUILTIN(b);
39*6c4e9d48SLaurent Vivier 
40*6c4e9d48SLaurent Vivier     qemu_bh_schedule(s->bh);
41*6c4e9d48SLaurent Vivier }
42*6c4e9d48SLaurent Vivier 
43*6c4e9d48SLaurent Vivier static void rng_builtin_init(Object *obj)
44*6c4e9d48SLaurent Vivier {
45*6c4e9d48SLaurent Vivier     RngBuiltin *s = RNG_BUILTIN(obj);
46*6c4e9d48SLaurent Vivier 
47*6c4e9d48SLaurent Vivier     s->bh = qemu_bh_new(rng_builtin_receive_entropy_bh, s);
48*6c4e9d48SLaurent Vivier }
49*6c4e9d48SLaurent Vivier 
50*6c4e9d48SLaurent Vivier static void rng_builtin_finalize(Object *obj)
51*6c4e9d48SLaurent Vivier {
52*6c4e9d48SLaurent Vivier     RngBuiltin *s = RNG_BUILTIN(obj);
53*6c4e9d48SLaurent Vivier 
54*6c4e9d48SLaurent Vivier     qemu_bh_delete(s->bh);
55*6c4e9d48SLaurent Vivier }
56*6c4e9d48SLaurent Vivier 
57*6c4e9d48SLaurent Vivier static void rng_builtin_class_init(ObjectClass *klass, void *data)
58*6c4e9d48SLaurent Vivier {
59*6c4e9d48SLaurent Vivier     RngBackendClass *rbc = RNG_BACKEND_CLASS(klass);
60*6c4e9d48SLaurent Vivier 
61*6c4e9d48SLaurent Vivier     rbc->request_entropy = rng_builtin_request_entropy;
62*6c4e9d48SLaurent Vivier }
63*6c4e9d48SLaurent Vivier 
64*6c4e9d48SLaurent Vivier static const TypeInfo rng_builtin_info = {
65*6c4e9d48SLaurent Vivier     .name = TYPE_RNG_BUILTIN,
66*6c4e9d48SLaurent Vivier     .parent = TYPE_RNG_BACKEND,
67*6c4e9d48SLaurent Vivier     .instance_size = sizeof(RngBuiltin),
68*6c4e9d48SLaurent Vivier     .instance_init = rng_builtin_init,
69*6c4e9d48SLaurent Vivier     .instance_finalize = rng_builtin_finalize,
70*6c4e9d48SLaurent Vivier     .class_init = rng_builtin_class_init,
71*6c4e9d48SLaurent Vivier };
72*6c4e9d48SLaurent Vivier 
73*6c4e9d48SLaurent Vivier static void register_types(void)
74*6c4e9d48SLaurent Vivier {
75*6c4e9d48SLaurent Vivier     type_register_static(&rng_builtin_info);
76*6c4e9d48SLaurent Vivier }
77*6c4e9d48SLaurent Vivier 
78*6c4e9d48SLaurent Vivier type_init(register_types);
79