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

xen-bus-helper.c (4628B)


      1/*
      2 * Copyright (c) 2018  Citrix Systems Inc.
      3 *
      4 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      5 * See the COPYING file in the top-level directory.
      6 */
      7
      8#include "qemu/osdep.h"
      9#include "hw/xen/xen.h"
     10#include "hw/xen/xen-bus.h"
     11#include "hw/xen/xen-bus-helper.h"
     12#include "qapi/error.h"
     13
     14#include <glib/gprintf.h>
     15
     16struct xs_state {
     17    enum xenbus_state statenum;
     18    const char *statestr;
     19};
     20#define XS_STATE(state) { state, #state }
     21
     22static struct xs_state xs_state[] = {
     23    XS_STATE(XenbusStateUnknown),
     24    XS_STATE(XenbusStateInitialising),
     25    XS_STATE(XenbusStateInitWait),
     26    XS_STATE(XenbusStateInitialised),
     27    XS_STATE(XenbusStateConnected),
     28    XS_STATE(XenbusStateClosing),
     29    XS_STATE(XenbusStateClosed),
     30    XS_STATE(XenbusStateReconfiguring),
     31    XS_STATE(XenbusStateReconfigured),
     32};
     33
     34#undef XS_STATE
     35
     36const char *xs_strstate(enum xenbus_state state)
     37{
     38    unsigned int i;
     39
     40   for (i = 0; i < ARRAY_SIZE(xs_state); i++) {
     41        if (xs_state[i].statenum == state) {
     42            return xs_state[i].statestr;
     43        }
     44    }
     45
     46    return "INVALID";
     47}
     48
     49void xs_node_create(struct xs_handle *xsh, xs_transaction_t tid,
     50                    const char *node, struct xs_permissions perms[],
     51                    unsigned int nr_perms, Error **errp)
     52{
     53    trace_xs_node_create(node);
     54
     55    if (!xs_write(xsh, tid, node, "", 0)) {
     56        error_setg_errno(errp, errno, "failed to create node '%s'", node);
     57        return;
     58    }
     59
     60    if (!xs_set_permissions(xsh, tid, node, perms, nr_perms)) {
     61        error_setg_errno(errp, errno, "failed to set node '%s' permissions",
     62                         node);
     63    }
     64}
     65
     66void xs_node_destroy(struct xs_handle *xsh, xs_transaction_t tid,
     67                     const char *node, Error **errp)
     68{
     69    trace_xs_node_destroy(node);
     70
     71    if (!xs_rm(xsh, tid, node)) {
     72        error_setg_errno(errp, errno, "failed to destroy node '%s'", node);
     73    }
     74}
     75
     76void xs_node_vprintf(struct xs_handle *xsh, xs_transaction_t tid,
     77                     const char *node, const char *key, Error **errp,
     78                     const char *fmt, va_list ap)
     79{
     80    char *path, *value;
     81    int len;
     82
     83    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
     84        g_strdup(key);
     85    len = g_vasprintf(&value, fmt, ap);
     86
     87    trace_xs_node_vprintf(path, value);
     88
     89    if (!xs_write(xsh, tid, path, value, len)) {
     90        error_setg_errno(errp, errno, "failed to write '%s' to '%s'",
     91                         value, path);
     92    }
     93
     94    g_free(value);
     95    g_free(path);
     96}
     97
     98void xs_node_printf(struct xs_handle *xsh,  xs_transaction_t tid,
     99                    const char *node, const char *key, Error **errp,
    100                    const char *fmt, ...)
    101{
    102    va_list ap;
    103
    104    va_start(ap, fmt);
    105    xs_node_vprintf(xsh, tid, node, key, errp, fmt, ap);
    106    va_end(ap);
    107}
    108
    109int xs_node_vscanf(struct xs_handle *xsh,  xs_transaction_t tid,
    110                   const char *node, const char *key, Error **errp,
    111                   const char *fmt, va_list ap)
    112{
    113    char *path, *value;
    114    int rc;
    115
    116    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
    117        g_strdup(key);
    118    value = xs_read(xsh, tid, path, NULL);
    119
    120    trace_xs_node_vscanf(path, value);
    121
    122    if (value) {
    123        rc = vsscanf(value, fmt, ap);
    124    } else {
    125        error_setg_errno(errp, errno, "failed to read from '%s'",
    126                         path);
    127        rc = EOF;
    128    }
    129
    130    free(value);
    131    g_free(path);
    132
    133    return rc;
    134}
    135
    136int xs_node_scanf(struct xs_handle *xsh,  xs_transaction_t tid,
    137                  const char *node, const char *key, Error **errp,
    138                  const char *fmt, ...)
    139{
    140    va_list ap;
    141    int rc;
    142
    143    va_start(ap, fmt);
    144    rc = xs_node_vscanf(xsh, tid, node, key, errp, fmt, ap);
    145    va_end(ap);
    146
    147    return rc;
    148}
    149
    150void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
    151                   char *token, Error **errp)
    152{
    153    char *path;
    154
    155    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
    156        g_strdup(key);
    157
    158    trace_xs_node_watch(path);
    159
    160    if (!xs_watch(xsh, path, token)) {
    161        error_setg_errno(errp, errno, "failed to watch node '%s'", path);
    162    }
    163
    164    g_free(path);
    165}
    166
    167void xs_node_unwatch(struct xs_handle *xsh, const char *node,
    168                     const char *key, const char *token, Error **errp)
    169{
    170    char *path;
    171
    172    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
    173        g_strdup(key);
    174
    175    trace_xs_node_unwatch(path);
    176
    177    if (!xs_unwatch(xsh, path, token)) {
    178        error_setg_errno(errp, errno, "failed to unwatch node '%s'", path);
    179    }
    180
    181    g_free(path);
    182}