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