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-char.c (3864B)


      1/*
      2 * replay-char.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 "qemu/error-report.h"
     14#include "sysemu/replay.h"
     15#include "replay-internal.h"
     16#include "chardev/char.h"
     17
     18/* Char drivers that generate qemu_chr_be_write events
     19   that should be saved into the log. */
     20static Chardev **char_drivers;
     21static int drivers_count;
     22
     23/* Char event attributes. */
     24typedef struct CharEvent {
     25    int id;
     26    uint8_t *buf;
     27    size_t len;
     28} CharEvent;
     29
     30static int find_char_driver(Chardev *chr)
     31{
     32    int i = 0;
     33    for ( ; i < drivers_count ; ++i) {
     34        if (char_drivers[i] == chr) {
     35            return i;
     36        }
     37    }
     38    return -1;
     39}
     40
     41void replay_register_char_driver(Chardev *chr)
     42{
     43    if (replay_mode == REPLAY_MODE_NONE) {
     44        return;
     45    }
     46    char_drivers = g_realloc(char_drivers,
     47                             sizeof(*char_drivers) * (drivers_count + 1));
     48    char_drivers[drivers_count++] = chr;
     49}
     50
     51void replay_chr_be_write(Chardev *s, uint8_t *buf, int len)
     52{
     53    CharEvent *event = g_malloc0(sizeof(CharEvent));
     54
     55    event->id = find_char_driver(s);
     56    if (event->id < 0) {
     57        fprintf(stderr, "Replay: cannot find char driver\n");
     58        exit(1);
     59    }
     60    event->buf = g_malloc(len);
     61    memcpy(event->buf, buf, len);
     62    event->len = len;
     63
     64    replay_add_event(REPLAY_ASYNC_EVENT_CHAR_READ, event, NULL, 0);
     65}
     66
     67void replay_event_char_read_run(void *opaque)
     68{
     69    CharEvent *event = (CharEvent *)opaque;
     70
     71    qemu_chr_be_write_impl(char_drivers[event->id], event->buf,
     72                           (int)event->len);
     73
     74    g_free(event->buf);
     75    g_free(event);
     76}
     77
     78void replay_event_char_read_save(void *opaque)
     79{
     80    CharEvent *event = (CharEvent *)opaque;
     81
     82    replay_put_byte(event->id);
     83    replay_put_array(event->buf, event->len);
     84}
     85
     86void *replay_event_char_read_load(void)
     87{
     88    CharEvent *event = g_malloc0(sizeof(CharEvent));
     89
     90    event->id = replay_get_byte();
     91    replay_get_array_alloc(&event->buf, &event->len);
     92
     93    return event;
     94}
     95
     96void replay_char_write_event_save(int res, int offset)
     97{
     98    g_assert(replay_mutex_locked());
     99
    100    replay_save_instructions();
    101    replay_put_event(EVENT_CHAR_WRITE);
    102    replay_put_dword(res);
    103    replay_put_dword(offset);
    104}
    105
    106void replay_char_write_event_load(int *res, int *offset)
    107{
    108    g_assert(replay_mutex_locked());
    109
    110    replay_account_executed_instructions();
    111    if (replay_next_event_is(EVENT_CHAR_WRITE)) {
    112        *res = replay_get_dword();
    113        *offset = replay_get_dword();
    114        replay_finish_event();
    115    } else {
    116        error_report("Missing character write event in the replay log");
    117        exit(1);
    118    }
    119}
    120
    121int replay_char_read_all_load(uint8_t *buf)
    122{
    123    g_assert(replay_mutex_locked());
    124
    125    if (replay_next_event_is(EVENT_CHAR_READ_ALL)) {
    126        size_t size;
    127        int res;
    128        replay_get_array(buf, &size);
    129        replay_finish_event();
    130        res = (int)size;
    131        assert(res >= 0);
    132        return res;
    133    } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) {
    134        int res = replay_get_dword();
    135        replay_finish_event();
    136        return res;
    137    } else {
    138        error_report("Missing character read all event in the replay log");
    139        exit(1);
    140    }
    141}
    142
    143void replay_char_read_all_save_error(int res)
    144{
    145    g_assert(replay_mutex_locked());
    146    assert(res < 0);
    147    replay_save_instructions();
    148    replay_put_event(EVENT_CHAR_READ_ALL_ERROR);
    149    replay_put_dword(res);
    150}
    151
    152void replay_char_read_all_save_buf(uint8_t *buf, int offset)
    153{
    154    g_assert(replay_mutex_locked());
    155    replay_save_instructions();
    156    replay_put_event(EVENT_CHAR_READ_ALL);
    157    replay_put_array(buf, offset);
    158}