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

tod.c (3441B)


      1/*
      2 * TOD (Time Of Day) clock
      3 *
      4 * Copyright 2018 Red Hat, Inc.
      5 * Author(s): David Hildenbrand <david@redhat.com>
      6 *
      7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      8 * See the COPYING file in the top-level directory.
      9 */
     10
     11#include "qemu/osdep.h"
     12#include "hw/s390x/tod.h"
     13#include "qapi/error.h"
     14#include "qemu/error-report.h"
     15#include "qemu/module.h"
     16#include "sysemu/kvm.h"
     17#include "sysemu/tcg.h"
     18#include "sysemu/qtest.h"
     19#include "migration/qemu-file-types.h"
     20#include "migration/register.h"
     21
     22void s390_init_tod(void)
     23{
     24    Object *obj;
     25
     26    if (kvm_enabled()) {
     27        obj = object_new(TYPE_KVM_S390_TOD);
     28    } else if (tcg_enabled()) {
     29        obj = object_new(TYPE_QEMU_S390_TOD);
     30    } else if (qtest_enabled()) {
     31        return;
     32    } else {
     33        error_report("current accelerator not handled in s390_init_tod!");
     34        abort();
     35    }
     36    object_property_add_child(qdev_get_machine(), TYPE_S390_TOD, obj);
     37    object_unref(obj);
     38
     39    qdev_realize(DEVICE(obj), NULL, &error_fatal);
     40}
     41
     42S390TODState *s390_get_todstate(void)
     43{
     44    static S390TODState *ts;
     45
     46    if (!ts) {
     47        ts = S390_TOD(object_resolve_path_type("", TYPE_S390_TOD, NULL));
     48    }
     49
     50    return ts;
     51}
     52
     53#define S390_TOD_CLOCK_VALUE_MISSING    0x00
     54#define S390_TOD_CLOCK_VALUE_PRESENT    0x01
     55
     56static void s390_tod_save(QEMUFile *f, void *opaque)
     57{
     58    S390TODState *td = opaque;
     59    S390TODClass *tdc = S390_TOD_GET_CLASS(td);
     60    Error *err = NULL;
     61    S390TOD tod;
     62
     63    tdc->get(td, &tod, &err);
     64    if (err) {
     65        warn_report_err(err);
     66        error_printf("Guest clock will not be migrated "
     67                     "which could cause the guest to hang.");
     68        qemu_put_byte(f, S390_TOD_CLOCK_VALUE_MISSING);
     69        return;
     70    }
     71
     72    qemu_put_byte(f, S390_TOD_CLOCK_VALUE_PRESENT);
     73    qemu_put_byte(f, tod.high);
     74    qemu_put_be64(f, tod.low);
     75}
     76
     77static int s390_tod_load(QEMUFile *f, void *opaque, int version_id)
     78{
     79    S390TODState *td = opaque;
     80    S390TODClass *tdc = S390_TOD_GET_CLASS(td);
     81    Error *err = NULL;
     82    S390TOD tod;
     83
     84    if (qemu_get_byte(f) == S390_TOD_CLOCK_VALUE_MISSING) {
     85        warn_report("Guest clock was not migrated. This could "
     86                    "cause the guest to hang.");
     87        return 0;
     88    }
     89
     90    tod.high = qemu_get_byte(f);
     91    tod.low = qemu_get_be64(f);
     92
     93    tdc->set(td, &tod, &err);
     94    if (err) {
     95        error_report_err(err);
     96        return -1;
     97    }
     98    return 0;
     99}
    100
    101static SaveVMHandlers savevm_tod = {
    102    .save_state = s390_tod_save,
    103    .load_state = s390_tod_load,
    104};
    105
    106static void s390_tod_realize(DeviceState *dev, Error **errp)
    107{
    108    S390TODState *td = S390_TOD(dev);
    109
    110    /* Legacy migration interface */
    111    register_savevm_live("todclock", 0, 1, &savevm_tod, td);
    112}
    113
    114static void s390_tod_class_init(ObjectClass *oc, void *data)
    115{
    116    DeviceClass *dc = DEVICE_CLASS(oc);
    117
    118    dc->desc = "TOD (Time Of Day) Clock";
    119    dc->realize = s390_tod_realize;
    120    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    121
    122    /* We only have one TOD clock in the system attached to the machine */
    123    dc->user_creatable = false;
    124}
    125
    126static TypeInfo s390_tod_info = {
    127    .name = TYPE_S390_TOD,
    128    .parent = TYPE_DEVICE,
    129    .instance_size = sizeof(S390TODState),
    130    .class_init = s390_tod_class_init,
    131    .class_size = sizeof(S390TODClass),
    132    .abstract = true,
    133};
    134
    135static void register_types(void)
    136{
    137    type_register_static(&s390_tod_info);
    138}
    139type_init(register_types);