cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

rng.c (3455B)


      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
     20void 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
     42static bool rng_backend_prop_get_opened(Object *obj, Error **errp)
     43{
     44    RngBackend *s = RNG_BACKEND(obj);
     45
     46    return s->opened;
     47}
     48
     49static void rng_backend_complete(UserCreatable *uc, Error **errp)
     50{
     51    object_property_set_bool(OBJECT(uc), "opened", true, errp);
     52}
     53
     54static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
     55{
     56    RngBackend *s = RNG_BACKEND(obj);
     57    RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
     58    Error *local_err = NULL;
     59
     60    if (value == s->opened) {
     61        return;
     62    }
     63
     64    if (!value && s->opened) {
     65        error_setg(errp, QERR_PERMISSION_DENIED);
     66        return;
     67    }
     68
     69    if (k->opened) {
     70        k->opened(s, &local_err);
     71        if (local_err) {
     72            error_propagate(errp, local_err);
     73            return;
     74        }
     75    }
     76
     77    s->opened = true;
     78}
     79
     80static void rng_backend_free_request(RngRequest *req)
     81{
     82    g_free(req->data);
     83    g_free(req);
     84}
     85
     86static void rng_backend_free_requests(RngBackend *s)
     87{
     88    RngRequest *req, *next;
     89
     90    QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
     91        rng_backend_free_request(req);
     92    }
     93
     94    QSIMPLEQ_INIT(&s->requests);
     95}
     96
     97void rng_backend_finalize_request(RngBackend *s, RngRequest *req)
     98{
     99    QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
    100    rng_backend_free_request(req);
    101}
    102
    103static void rng_backend_init(Object *obj)
    104{
    105    RngBackend *s = RNG_BACKEND(obj);
    106
    107    QSIMPLEQ_INIT(&s->requests);
    108}
    109
    110static void rng_backend_finalize(Object *obj)
    111{
    112    RngBackend *s = RNG_BACKEND(obj);
    113
    114    rng_backend_free_requests(s);
    115}
    116
    117static void rng_backend_class_init(ObjectClass *oc, void *data)
    118{
    119    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    120
    121    ucc->complete = rng_backend_complete;
    122
    123    object_class_property_add_bool(oc, "opened",
    124                                   rng_backend_prop_get_opened,
    125                                   rng_backend_prop_set_opened);
    126}
    127
    128static const TypeInfo rng_backend_info = {
    129    .name = TYPE_RNG_BACKEND,
    130    .parent = TYPE_OBJECT,
    131    .instance_size = sizeof(RngBackend),
    132    .instance_init = rng_backend_init,
    133    .instance_finalize = rng_backend_finalize,
    134    .class_size = sizeof(RngBackendClass),
    135    .class_init = rng_backend_class_init,
    136    .abstract = true,
    137    .interfaces = (InterfaceInfo[]) {
    138        { TYPE_USER_CREATABLE },
    139        { }
    140    }
    141};
    142
    143static void register_types(void)
    144{
    145    type_register_static(&rng_backend_info);
    146}
    147
    148type_init(register_types);