qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

rng.c (3126B)


      1 /*
      2  * QEMU Random Number Generator Backend
      3  *
      4  * Copyright IBM, Corp. 2012
      5  *
      6  * Authors:
      7  *  Anthony Liguori   <aliguori@us.ibm.com>
      8  *
      9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
     10  * See the COPYING file in the top-level directory.
     11  */
     12 
     13 #include "qemu/osdep.h"
     14 #include "sysemu/rng.h"
     15 #include "qapi/error.h"
     16 #include "qapi/qmp/qerror.h"
     17 #include "qemu/module.h"
     18 #include "qom/object_interfaces.h"
     19 
     20 void rng_backend_request_entropy(RngBackend *s, size_t size,
     21                                  EntropyReceiveFunc *receive_entropy,
     22                                  void *opaque)
     23 {
     24     RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
     25     RngRequest *req;
     26 
     27     if (k->request_entropy) {
     28         req = g_malloc(sizeof(*req));
     29 
     30         req->offset = 0;
     31         req->size = size;
     32         req->receive_entropy = receive_entropy;
     33         req->opaque = opaque;
     34         req->data = g_malloc(req->size);
     35 
     36         k->request_entropy(s, req);
     37 
     38         QSIMPLEQ_INSERT_TAIL(&s->requests, req, next);
     39     }
     40 }
     41 
     42 static bool rng_backend_prop_get_opened(Object *obj, Error **errp)
     43 {
     44     RngBackend *s = RNG_BACKEND(obj);
     45 
     46     return s->opened;
     47 }
     48 
     49 static void rng_backend_complete(UserCreatable *uc, Error **errp)
     50 {
     51     RngBackend *s = RNG_BACKEND(uc);
     52     RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
     53     Error *local_err = NULL;
     54 
     55     if (k->opened) {
     56         k->opened(s, &local_err);
     57         if (local_err) {
     58             error_propagate(errp, local_err);
     59             return;
     60         }
     61     }
     62 
     63     s->opened = true;
     64 }
     65 
     66 static void rng_backend_free_request(RngRequest *req)
     67 {
     68     g_free(req->data);
     69     g_free(req);
     70 }
     71 
     72 static void rng_backend_free_requests(RngBackend *s)
     73 {
     74     RngRequest *req, *next;
     75 
     76     QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
     77         rng_backend_free_request(req);
     78     }
     79 
     80     QSIMPLEQ_INIT(&s->requests);
     81 }
     82 
     83 void rng_backend_finalize_request(RngBackend *s, RngRequest *req)
     84 {
     85     QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
     86     rng_backend_free_request(req);
     87 }
     88 
     89 static void rng_backend_init(Object *obj)
     90 {
     91     RngBackend *s = RNG_BACKEND(obj);
     92 
     93     QSIMPLEQ_INIT(&s->requests);
     94 }
     95 
     96 static void rng_backend_finalize(Object *obj)
     97 {
     98     RngBackend *s = RNG_BACKEND(obj);
     99 
    100     rng_backend_free_requests(s);
    101 }
    102 
    103 static void rng_backend_class_init(ObjectClass *oc, void *data)
    104 {
    105     UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    106 
    107     ucc->complete = rng_backend_complete;
    108 
    109     object_class_property_add_bool(oc, "opened",
    110                                    rng_backend_prop_get_opened,
    111                                    NULL);
    112 }
    113 
    114 static const TypeInfo rng_backend_info = {
    115     .name = TYPE_RNG_BACKEND,
    116     .parent = TYPE_OBJECT,
    117     .instance_size = sizeof(RngBackend),
    118     .instance_init = rng_backend_init,
    119     .instance_finalize = rng_backend_finalize,
    120     .class_size = sizeof(RngBackendClass),
    121     .class_init = rng_backend_class_init,
    122     .abstract = true,
    123     .interfaces = (InterfaceInfo[]) {
    124         { TYPE_USER_CREATABLE },
    125         { }
    126     }
    127 };
    128 
    129 static void register_types(void)
    130 {
    131     type_register_static(&rng_backend_info);
    132 }
    133 
    134 type_init(register_types);