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

io-channel-helpers.c (4261B)


      1/*
      2 * QEMU I/O channel test helpers
      3 *
      4 * Copyright (c) 2015 Red Hat, Inc.
      5 *
      6 * This library is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * This library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18 *
     19 */
     20
     21#include "qemu/osdep.h"
     22#include "io-channel-helpers.h"
     23#include "qemu/iov.h"
     24
     25struct QIOChannelTest {
     26    QIOChannel *src;
     27    QIOChannel *dst;
     28    bool blocking;
     29    size_t len;
     30    size_t niov;
     31    char *input;
     32    struct iovec *inputv;
     33    char *output;
     34    struct iovec *outputv;
     35    Error *writeerr;
     36    Error *readerr;
     37};
     38
     39
     40/* This thread sends all data using iovecs */
     41static gpointer test_io_thread_writer(gpointer opaque)
     42{
     43    QIOChannelTest *data = opaque;
     44
     45    qio_channel_set_blocking(data->src, data->blocking, NULL);
     46
     47    qio_channel_writev_all(data->src,
     48                           data->inputv,
     49                           data->niov,
     50                           &data->writeerr);
     51
     52    return NULL;
     53}
     54
     55
     56/* This thread receives all data using iovecs */
     57static gpointer test_io_thread_reader(gpointer opaque)
     58{
     59    QIOChannelTest *data = opaque;
     60
     61    qio_channel_set_blocking(data->dst, data->blocking, NULL);
     62
     63    qio_channel_readv_all(data->dst,
     64                          data->outputv,
     65                          data->niov,
     66                          &data->readerr);
     67
     68    return NULL;
     69}
     70
     71
     72QIOChannelTest *qio_channel_test_new(void)
     73{
     74    QIOChannelTest *data = g_new0(QIOChannelTest, 1);
     75    size_t i;
     76    size_t offset;
     77
     78
     79    /* We'll send 1 MB of data */
     80#define CHUNK_COUNT 250
     81#define CHUNK_LEN 4194
     82
     83    data->len = CHUNK_COUNT * CHUNK_LEN;
     84    data->input = g_new0(char, data->len);
     85    data->output = g_new0(gchar, data->len);
     86
     87    /* Fill input with a pattern */
     88    for (i = 0; i < data->len; i += CHUNK_LEN) {
     89        memset(data->input + i, (i / CHUNK_LEN), CHUNK_LEN);
     90    }
     91
     92    /* We'll split the data across a bunch of IO vecs */
     93    data->niov = CHUNK_COUNT;
     94    data->inputv = g_new0(struct iovec, data->niov);
     95    data->outputv = g_new0(struct iovec, data->niov);
     96
     97    for (i = 0, offset = 0; i < data->niov; i++, offset += CHUNK_LEN) {
     98        data->inputv[i].iov_base = data->input + offset;
     99        data->outputv[i].iov_base = data->output + offset;
    100        data->inputv[i].iov_len = CHUNK_LEN;
    101        data->outputv[i].iov_len = CHUNK_LEN;
    102    }
    103
    104    return data;
    105}
    106
    107void qio_channel_test_run_threads(QIOChannelTest *test,
    108                                  bool blocking,
    109                                  QIOChannel *src,
    110                                  QIOChannel *dst)
    111{
    112    GThread *reader, *writer;
    113
    114    test->src = src;
    115    test->dst = dst;
    116    test->blocking = blocking;
    117
    118    reader = g_thread_new("reader",
    119                          test_io_thread_reader,
    120                          test);
    121    writer = g_thread_new("writer",
    122                          test_io_thread_writer,
    123                          test);
    124
    125    g_thread_join(reader);
    126    g_thread_join(writer);
    127
    128    test->dst = test->src = NULL;
    129}
    130
    131
    132void qio_channel_test_run_writer(QIOChannelTest *test,
    133                                 QIOChannel *src)
    134{
    135    test->src = src;
    136    test_io_thread_writer(test);
    137    test->src = NULL;
    138}
    139
    140
    141void qio_channel_test_run_reader(QIOChannelTest *test,
    142                                 QIOChannel *dst)
    143{
    144    test->dst = dst;
    145    test_io_thread_reader(test);
    146    test->dst = NULL;
    147}
    148
    149
    150void qio_channel_test_validate(QIOChannelTest *test)
    151{
    152    g_assert(test->readerr == NULL);
    153    g_assert(test->writeerr == NULL);
    154    g_assert_cmpint(memcmp(test->input,
    155                           test->output,
    156                           test->len), ==, 0);
    157
    158    g_free(test->inputv);
    159    g_free(test->outputv);
    160    g_free(test->input);
    161    g_free(test->output);
    162    g_free(test);
    163}