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

replay-snapshot.c (3028B)


      1/*
      2 * replay-snapshot.c
      3 *
      4 * Copyright (c) 2010-2016 Institute for System Programming
      5 *                         of the Russian Academy of Sciences.
      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
     12#include "qemu/osdep.h"
     13#include "qapi/error.h"
     14#include "sysemu/replay.h"
     15#include "replay-internal.h"
     16#include "monitor/monitor.h"
     17#include "qapi/qmp/qstring.h"
     18#include "qemu/error-report.h"
     19#include "migration/vmstate.h"
     20#include "migration/snapshot.h"
     21
     22static int replay_pre_save(void *opaque)
     23{
     24    ReplayState *state = opaque;
     25    state->file_offset = ftell(replay_file);
     26
     27    return 0;
     28}
     29
     30static int replay_post_load(void *opaque, int version_id)
     31{
     32    ReplayState *state = opaque;
     33    if (replay_mode == REPLAY_MODE_PLAY) {
     34        fseek(replay_file, state->file_offset, SEEK_SET);
     35        /* If this was a vmstate, saved in recording mode,
     36           we need to initialize replay data fields. */
     37        replay_fetch_data_kind();
     38    } else if (replay_mode == REPLAY_MODE_RECORD) {
     39        /* This is only useful for loading the initial state.
     40           Therefore reset all the counters. */
     41        state->instruction_count = 0;
     42        state->block_request_id = 0;
     43    }
     44
     45    return 0;
     46}
     47
     48static const VMStateDescription vmstate_replay = {
     49    .name = "replay",
     50    .version_id = 2,
     51    .minimum_version_id = 2,
     52    .pre_save = replay_pre_save,
     53    .post_load = replay_post_load,
     54    .fields = (VMStateField[]) {
     55        VMSTATE_INT64_ARRAY(cached_clock, ReplayState, REPLAY_CLOCK_COUNT),
     56        VMSTATE_UINT64(current_icount, ReplayState),
     57        VMSTATE_INT32(instruction_count, ReplayState),
     58        VMSTATE_UINT32(data_kind, ReplayState),
     59        VMSTATE_UINT32(has_unread_data, ReplayState),
     60        VMSTATE_UINT64(file_offset, ReplayState),
     61        VMSTATE_UINT64(block_request_id, ReplayState),
     62        VMSTATE_INT32(read_event_kind, ReplayState),
     63        VMSTATE_UINT64(read_event_id, ReplayState),
     64        VMSTATE_INT32(read_event_checkpoint, ReplayState),
     65        VMSTATE_END_OF_LIST()
     66    },
     67};
     68
     69void replay_vmstate_register(void)
     70{
     71    vmstate_register(NULL, 0, &vmstate_replay, &replay_state);
     72}
     73
     74void replay_vmstate_init(void)
     75{
     76    Error *err = NULL;
     77
     78    if (replay_snapshot) {
     79        if (replay_mode == REPLAY_MODE_RECORD) {
     80            if (!save_snapshot(replay_snapshot,
     81                               true, NULL, false, NULL, &err)) {
     82                error_report_err(err);
     83                error_report("Could not create snapshot for icount record");
     84                exit(1);
     85            }
     86        } else if (replay_mode == REPLAY_MODE_PLAY) {
     87            if (!load_snapshot(replay_snapshot, NULL, false, NULL, &err)) {
     88                error_report_err(err);
     89                error_report("Could not load snapshot for icount replay");
     90                exit(1);
     91            }
     92        }
     93    }
     94}
     95
     96bool replay_can_snapshot(void)
     97{
     98    return replay_mode == REPLAY_MODE_NONE
     99        || !replay_has_events();
    100}