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-all.c (6145B)


      1/*
      2 * Copyright (C) 2014       Citrix Systems UK Ltd.
      3 *
      4 * This work is licensed under the terms of the GNU GPL, version 2.  See
      5 * the COPYING file in the top-level directory.
      6 *
      7 * Contributions after 2012-01-13 are licensed under the terms of the
      8 * GNU GPL, version 2 or (at your option) any later version.
      9 */
     10
     11#include "qemu/osdep.h"
     12#include "qemu/error-report.h"
     13#include "qemu/module.h"
     14#include "qapi/error.h"
     15#include "hw/xen/xen-legacy-backend.h"
     16#include "hw/xen/xen_pt.h"
     17#include "chardev/char.h"
     18#include "qemu/accel.h"
     19#include "sysemu/cpus.h"
     20#include "sysemu/xen.h"
     21#include "sysemu/runstate.h"
     22#include "migration/misc.h"
     23#include "migration/global_state.h"
     24#include "hw/boards.h"
     25
     26//#define DEBUG_XEN
     27
     28#ifdef DEBUG_XEN
     29#define DPRINTF(fmt, ...) \
     30    do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0)
     31#else
     32#define DPRINTF(fmt, ...) \
     33    do { } while (0)
     34#endif
     35
     36bool xen_allowed;
     37
     38xc_interface *xen_xc;
     39xenforeignmemory_handle *xen_fmem;
     40xendevicemodel_handle *xen_dmod;
     41
     42static int store_dev_info(int domid, Chardev *cs, const char *string)
     43{
     44    struct xs_handle *xs = NULL;
     45    char *path = NULL;
     46    char *newpath = NULL;
     47    char *pts = NULL;
     48    int ret = -1;
     49
     50    /* Only continue if we're talking to a pty. */
     51    if (!CHARDEV_IS_PTY(cs)) {
     52        return 0;
     53    }
     54    pts = cs->filename + 4;
     55
     56    /* We now have everything we need to set the xenstore entry. */
     57    xs = xs_open(0);
     58    if (xs == NULL) {
     59        fprintf(stderr, "Could not contact XenStore\n");
     60        goto out;
     61    }
     62
     63    path = xs_get_domain_path(xs, domid);
     64    if (path == NULL) {
     65        fprintf(stderr, "xs_get_domain_path() error\n");
     66        goto out;
     67    }
     68    newpath = realloc(path, (strlen(path) + strlen(string) +
     69                strlen("/tty") + 1));
     70    if (newpath == NULL) {
     71        fprintf(stderr, "realloc error\n");
     72        goto out;
     73    }
     74    path = newpath;
     75
     76    strcat(path, string);
     77    strcat(path, "/tty");
     78    if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
     79        fprintf(stderr, "xs_write for '%s' fail", string);
     80        goto out;
     81    }
     82    ret = 0;
     83
     84out:
     85    free(path);
     86    xs_close(xs);
     87
     88    return ret;
     89}
     90
     91void xenstore_store_pv_console_info(int i, Chardev *chr)
     92{
     93    if (i == 0) {
     94        store_dev_info(xen_domid, chr, "/console");
     95    } else {
     96        char buf[32];
     97        snprintf(buf, sizeof(buf), "/device/console/%d", i);
     98        store_dev_info(xen_domid, chr, buf);
     99    }
    100}
    101
    102
    103static void xenstore_record_dm_state(struct xs_handle *xs, const char *state)
    104{
    105    char path[50];
    106
    107    if (xs == NULL) {
    108        error_report("xenstore connection not initialized");
    109        exit(1);
    110    }
    111
    112    snprintf(path, sizeof (path), "device-model/%u/state", xen_domid);
    113    /*
    114     * This call may fail when running restricted so don't make it fatal in
    115     * that case. Toolstacks should instead use QMP to listen for state changes.
    116     */
    117    if (!xs_write(xs, XBT_NULL, path, state, strlen(state)) &&
    118            !xen_domid_restrict) {
    119        error_report("error recording dm state");
    120        exit(1);
    121    }
    122}
    123
    124
    125static void xen_change_state_handler(void *opaque, bool running,
    126                                     RunState state)
    127{
    128    if (running) {
    129        /* record state running */
    130        xenstore_record_dm_state(xenstore, "running");
    131    }
    132}
    133
    134static bool xen_get_igd_gfx_passthru(Object *obj, Error **errp)
    135{
    136    return xen_igd_gfx_pt_enabled();
    137}
    138
    139static void xen_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
    140{
    141    xen_igd_gfx_pt_set(value, errp);
    142}
    143
    144static void xen_setup_post(MachineState *ms, AccelState *accel)
    145{
    146    int rc;
    147
    148    if (xen_domid_restrict) {
    149        rc = xen_restrict(xen_domid);
    150        if (rc < 0) {
    151            perror("xen: failed to restrict");
    152            exit(1);
    153        }
    154    }
    155}
    156
    157static int xen_init(MachineState *ms)
    158{
    159    MachineClass *mc = MACHINE_GET_CLASS(ms);
    160
    161    xen_xc = xc_interface_open(0, 0, 0);
    162    if (xen_xc == NULL) {
    163        xen_pv_printf(NULL, 0, "can't open xen interface\n");
    164        return -1;
    165    }
    166    xen_fmem = xenforeignmemory_open(0, 0);
    167    if (xen_fmem == NULL) {
    168        xen_pv_printf(NULL, 0, "can't open xen fmem interface\n");
    169        xc_interface_close(xen_xc);
    170        return -1;
    171    }
    172    xen_dmod = xendevicemodel_open(0, 0);
    173    if (xen_dmod == NULL) {
    174        xen_pv_printf(NULL, 0, "can't open xen devicemodel interface\n");
    175        xenforeignmemory_close(xen_fmem);
    176        xc_interface_close(xen_xc);
    177        return -1;
    178    }
    179    qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
    180    /*
    181     * opt out of system RAM being allocated by generic code
    182     */
    183    mc->default_ram_id = NULL;
    184    return 0;
    185}
    186
    187static void xen_accel_class_init(ObjectClass *oc, void *data)
    188{
    189    AccelClass *ac = ACCEL_CLASS(oc);
    190    static GlobalProperty compat[] = {
    191        { "migration", "store-global-state", "off" },
    192        { "migration", "send-configuration", "off" },
    193        { "migration", "send-section-footer", "off" },
    194    };
    195
    196    ac->name = "Xen";
    197    ac->init_machine = xen_init;
    198    ac->setup_post = xen_setup_post;
    199    ac->allowed = &xen_allowed;
    200    ac->compat_props = g_ptr_array_new();
    201
    202    compat_props_add(ac->compat_props, compat, G_N_ELEMENTS(compat));
    203
    204    object_class_property_add_bool(oc, "igd-passthru",
    205        xen_get_igd_gfx_passthru, xen_set_igd_gfx_passthru);
    206    object_class_property_set_description(oc, "igd-passthru",
    207        "Set on/off to enable/disable igd passthrou");
    208}
    209
    210#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")
    211
    212static const TypeInfo xen_accel_type = {
    213    .name = TYPE_XEN_ACCEL,
    214    .parent = TYPE_ACCEL,
    215    .class_init = xen_accel_class_init,
    216};
    217
    218static void xen_accel_ops_class_init(ObjectClass *oc, void *data)
    219{
    220    AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
    221
    222    ops->create_vcpu_thread = dummy_start_vcpu_thread;
    223}
    224
    225static const TypeInfo xen_accel_ops_type = {
    226    .name = ACCEL_OPS_NAME("xen"),
    227
    228    .parent = TYPE_ACCEL_OPS,
    229    .class_init = xen_accel_ops_class_init,
    230    .abstract = true,
    231};
    232
    233static void xen_type_init(void)
    234{
    235    type_register_static(&xen_accel_type);
    236    type_register_static(&xen_accel_ops_type);
    237}
    238type_init(xen_type_init);