16c4e9d48SLaurent Vivier /* 26c4e9d48SLaurent Vivier * QEMU Builtin Random Number Generator Backend 36c4e9d48SLaurent Vivier * 46c4e9d48SLaurent Vivier * This work is licensed under the terms of the GNU GPL, version 2 or later. 56c4e9d48SLaurent Vivier * See the COPYING file in the top-level directory. 66c4e9d48SLaurent Vivier */ 76c4e9d48SLaurent Vivier 86c4e9d48SLaurent Vivier #include "qemu/osdep.h" 96c4e9d48SLaurent Vivier #include "sysemu/rng.h" 106c4e9d48SLaurent Vivier #include "qemu/main-loop.h" 116c4e9d48SLaurent Vivier #include "qemu/guest-random.h" 12*db1015e9SEduardo Habkost #include "qom/object.h" 136c4e9d48SLaurent Vivier 14*db1015e9SEduardo Habkost typedef struct RngBuiltin RngBuiltin; 156c4e9d48SLaurent Vivier #define RNG_BUILTIN(obj) OBJECT_CHECK(RngBuiltin, (obj), TYPE_RNG_BUILTIN) 166c4e9d48SLaurent Vivier 17*db1015e9SEduardo Habkost struct RngBuiltin { 186c4e9d48SLaurent Vivier RngBackend parent; 196c4e9d48SLaurent Vivier QEMUBH *bh; 20*db1015e9SEduardo Habkost }; 216c4e9d48SLaurent Vivier 226c4e9d48SLaurent Vivier static void rng_builtin_receive_entropy_bh(void *opaque) 236c4e9d48SLaurent Vivier { 246c4e9d48SLaurent Vivier RngBuiltin *s = opaque; 256c4e9d48SLaurent Vivier 266c4e9d48SLaurent Vivier while (!QSIMPLEQ_EMPTY(&s->parent.requests)) { 276c4e9d48SLaurent Vivier RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests); 286c4e9d48SLaurent Vivier 296c4e9d48SLaurent Vivier qemu_guest_getrandom_nofail(req->data, req->size); 306c4e9d48SLaurent Vivier 316c4e9d48SLaurent Vivier req->receive_entropy(req->opaque, req->data, req->size); 326c4e9d48SLaurent Vivier 336c4e9d48SLaurent Vivier rng_backend_finalize_request(&s->parent, req); 346c4e9d48SLaurent Vivier } 356c4e9d48SLaurent Vivier } 366c4e9d48SLaurent Vivier 376c4e9d48SLaurent Vivier static void rng_builtin_request_entropy(RngBackend *b, RngRequest *req) 386c4e9d48SLaurent Vivier { 396c4e9d48SLaurent Vivier RngBuiltin *s = RNG_BUILTIN(b); 406c4e9d48SLaurent Vivier 416c4e9d48SLaurent Vivier qemu_bh_schedule(s->bh); 426c4e9d48SLaurent Vivier } 436c4e9d48SLaurent Vivier 446c4e9d48SLaurent Vivier static void rng_builtin_init(Object *obj) 456c4e9d48SLaurent Vivier { 466c4e9d48SLaurent Vivier RngBuiltin *s = RNG_BUILTIN(obj); 476c4e9d48SLaurent Vivier 486c4e9d48SLaurent Vivier s->bh = qemu_bh_new(rng_builtin_receive_entropy_bh, s); 496c4e9d48SLaurent Vivier } 506c4e9d48SLaurent Vivier 516c4e9d48SLaurent Vivier static void rng_builtin_finalize(Object *obj) 526c4e9d48SLaurent Vivier { 536c4e9d48SLaurent Vivier RngBuiltin *s = RNG_BUILTIN(obj); 546c4e9d48SLaurent Vivier 556c4e9d48SLaurent Vivier qemu_bh_delete(s->bh); 566c4e9d48SLaurent Vivier } 576c4e9d48SLaurent Vivier 586c4e9d48SLaurent Vivier static void rng_builtin_class_init(ObjectClass *klass, void *data) 596c4e9d48SLaurent Vivier { 606c4e9d48SLaurent Vivier RngBackendClass *rbc = RNG_BACKEND_CLASS(klass); 616c4e9d48SLaurent Vivier 626c4e9d48SLaurent Vivier rbc->request_entropy = rng_builtin_request_entropy; 636c4e9d48SLaurent Vivier } 646c4e9d48SLaurent Vivier 656c4e9d48SLaurent Vivier static const TypeInfo rng_builtin_info = { 666c4e9d48SLaurent Vivier .name = TYPE_RNG_BUILTIN, 676c4e9d48SLaurent Vivier .parent = TYPE_RNG_BACKEND, 686c4e9d48SLaurent Vivier .instance_size = sizeof(RngBuiltin), 696c4e9d48SLaurent Vivier .instance_init = rng_builtin_init, 706c4e9d48SLaurent Vivier .instance_finalize = rng_builtin_finalize, 716c4e9d48SLaurent Vivier .class_init = rng_builtin_class_init, 726c4e9d48SLaurent Vivier }; 736c4e9d48SLaurent Vivier 746c4e9d48SLaurent Vivier static void register_types(void) 756c4e9d48SLaurent Vivier { 766c4e9d48SLaurent Vivier type_register_static(&rng_builtin_info); 776c4e9d48SLaurent Vivier } 786c4e9d48SLaurent Vivier 796c4e9d48SLaurent Vivier type_init(register_types); 80