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

cdrom-test.c (8008B)


      1/*
      2 * Various tests for emulated CD-ROM drives.
      3 *
      4 * Copyright (c) 2018 Red Hat Inc.
      5 *
      6 * Author:
      7 *    Thomas Huth <thuth@redhat.com>
      8 *
      9 * This work is licensed under the terms of the GNU GPL, version 2
     10 * or later. See the COPYING file in the top-level directory.
     11 */
     12
     13#include "qemu/osdep.h"
     14#include "libqos/libqtest.h"
     15#include "boot-sector.h"
     16#include "qapi/qmp/qdict.h"
     17
     18static char isoimage[] = "cdrom-boot-iso-XXXXXX";
     19
     20static int exec_genisoimg(const char **args)
     21{
     22    gchar *out_err = NULL;
     23    gint exit_status = -1;
     24    bool success;
     25
     26    success = g_spawn_sync(NULL, (gchar **)args, NULL,
     27                           G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL,
     28                           NULL, NULL, NULL, &out_err, &exit_status, NULL);
     29    if (!success) {
     30        return -ENOENT;
     31    }
     32    if (out_err) {
     33        fputs(out_err, stderr);
     34        g_free(out_err);
     35    }
     36
     37    return exit_status;
     38}
     39
     40static int prepare_image(const char *arch, char *isoimage)
     41{
     42    char srcdir[] = "cdrom-test-dir-XXXXXX";
     43    char *codefile = NULL;
     44    int ifh, ret = -1;
     45    const char *args[] = {
     46        "genisoimage", "-quiet", "-l", "-no-emul-boot",
     47        "-b", NULL, "-o", isoimage, srcdir, NULL
     48    };
     49
     50    ifh = mkstemp(isoimage);
     51    if (ifh < 0) {
     52        perror("Error creating temporary iso image file");
     53        return -1;
     54    }
     55    if (!mkdtemp(srcdir)) {
     56        perror("Error creating temporary directory");
     57        goto cleanup;
     58    }
     59
     60    if (g_str_equal(arch, "i386") || g_str_equal(arch, "x86_64") ||
     61        g_str_equal(arch, "s390x")) {
     62        codefile = g_strdup_printf("%s/bootcode-XXXXXX", srcdir);
     63        ret = boot_sector_init(codefile);
     64        if (ret) {
     65            goto cleanup;
     66        }
     67    } else {
     68        /* Just create a dummy file */
     69        char txt[] = "empty disc";
     70        codefile = g_strdup_printf("%s/readme.txt", srcdir);
     71        if (!g_file_set_contents(codefile, txt, sizeof(txt) - 1, NULL)) {
     72            fprintf(stderr, "Failed to create '%s'\n", codefile);
     73            goto cleanup;
     74        }
     75    }
     76
     77    args[5] = strchr(codefile, '/') + 1;
     78    ret = exec_genisoimg(args);
     79    if (ret) {
     80        fprintf(stderr, "genisoimage failed: %i\n", ret);
     81    }
     82
     83    unlink(codefile);
     84
     85cleanup:
     86    g_free(codefile);
     87    rmdir(srcdir);
     88    close(ifh);
     89
     90    return ret;
     91}
     92
     93/**
     94 * Check that at least the -cdrom parameter is basically working, i.e. we can
     95 * see the filename of the ISO image in the output of "info block" afterwards
     96 */
     97static void test_cdrom_param(gconstpointer data)
     98{
     99    QTestState *qts;
    100    char *resp;
    101
    102    qts = qtest_initf("-M %s -cdrom %s", (const char *)data, isoimage);
    103    resp = qtest_hmp(qts, "info block");
    104    g_assert(strstr(resp, isoimage) != 0);
    105    g_free(resp);
    106    qtest_quit(qts);
    107}
    108
    109static void add_cdrom_param_tests(const char **machines)
    110{
    111    while (*machines) {
    112        char *testname = g_strdup_printf("cdrom/param/%s", *machines);
    113        qtest_add_data_func(testname, *machines, test_cdrom_param);
    114        g_free(testname);
    115        machines++;
    116    }
    117}
    118
    119static void test_cdboot(gconstpointer data)
    120{
    121    QTestState *qts;
    122
    123    qts = qtest_initf("-accel kvm -accel tcg -no-shutdown %s%s", (const char *)data,
    124                      isoimage);
    125    boot_sector_test(qts);
    126    qtest_quit(qts);
    127}
    128
    129static void add_x86_tests(void)
    130{
    131    qtest_add_data_func("cdrom/boot/default", "-cdrom ", test_cdboot);
    132    qtest_add_data_func("cdrom/boot/virtio-scsi",
    133                        "-device virtio-scsi -device scsi-cd,drive=cdr "
    134                        "-blockdev file,node-name=cdr,filename=", test_cdboot);
    135    /*
    136     * Unstable CI test under load
    137     * See https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg05509.html
    138     */
    139    if (g_test_slow()) {
    140        qtest_add_data_func("cdrom/boot/isapc", "-M isapc "
    141                            "-drive if=ide,media=cdrom,file=", test_cdboot);
    142    }
    143    qtest_add_data_func("cdrom/boot/am53c974",
    144                        "-device am53c974 -device scsi-cd,drive=cd1 "
    145                        "-drive if=none,id=cd1,format=raw,file=", test_cdboot);
    146    qtest_add_data_func("cdrom/boot/dc390",
    147                        "-device dc390 -device scsi-cd,drive=cd1 "
    148                        "-blockdev file,node-name=cd1,filename=", test_cdboot);
    149    qtest_add_data_func("cdrom/boot/lsi53c895a",
    150                        "-device lsi53c895a -device scsi-cd,drive=cd1 "
    151                        "-blockdev file,node-name=cd1,filename=", test_cdboot);
    152    qtest_add_data_func("cdrom/boot/megasas", "-M q35 "
    153                        "-device megasas -device scsi-cd,drive=cd1 "
    154                        "-blockdev file,node-name=cd1,filename=", test_cdboot);
    155    qtest_add_data_func("cdrom/boot/megasas-gen2", "-M q35 "
    156                        "-device megasas-gen2 -device scsi-cd,drive=cd1 "
    157                        "-blockdev file,node-name=cd1,filename=", test_cdboot);
    158}
    159
    160static void add_s390x_tests(void)
    161{
    162    qtest_add_data_func("cdrom/boot/default", "-cdrom ", test_cdboot);
    163    qtest_add_data_func("cdrom/boot/virtio-scsi",
    164                        "-device virtio-scsi -device scsi-cd,drive=cdr "
    165                        "-blockdev file,node-name=cdr,filename=", test_cdboot);
    166    qtest_add_data_func("cdrom/boot/with-bootindex",
    167                        "-device virtio-serial -device virtio-scsi "
    168                        "-device virtio-blk,drive=d1 "
    169                        "-drive driver=null-co,read-zeroes=on,if=none,id=d1 "
    170                        "-device virtio-blk,drive=d2,bootindex=1 "
    171                        "-drive if=none,id=d2,media=cdrom,file=", test_cdboot);
    172    qtest_add_data_func("cdrom/boot/without-bootindex",
    173                        "-device virtio-scsi -device virtio-serial "
    174                        "-device x-terminal3270 -device virtio-blk,drive=d1 "
    175                        "-drive driver=null-co,read-zeroes=on,if=none,id=d1 "
    176                        "-device virtio-blk,drive=d2 "
    177                        "-drive if=none,id=d2,media=cdrom,file=", test_cdboot);
    178}
    179
    180int main(int argc, char **argv)
    181{
    182    int ret;
    183    const char *arch = qtest_get_arch();
    184    const char *genisocheck[] = { "genisoimage", "-version", NULL };
    185
    186    g_test_init(&argc, &argv, NULL);
    187
    188    if (exec_genisoimg(genisocheck)) {
    189        /* genisoimage not available - so can't run tests */
    190        return g_test_run();
    191    }
    192
    193    ret = prepare_image(arch, isoimage);
    194    if (ret) {
    195        return ret;
    196    }
    197
    198    if (g_str_equal(arch, "i386") || g_str_equal(arch, "x86_64")) {
    199        add_x86_tests();
    200    } else if (g_str_equal(arch, "s390x")) {
    201        add_s390x_tests();
    202    } else if (g_str_equal(arch, "ppc64")) {
    203        const char *ppcmachines[] = {
    204            "pseries", "mac99", "g3beige", "40p", NULL
    205        };
    206        add_cdrom_param_tests(ppcmachines);
    207    } else if (g_str_equal(arch, "sparc")) {
    208        const char *sparcmachines[] = {
    209            "LX", "SPARCClassic", "SPARCbook", "SS-10", "SS-20", "SS-4",
    210            "SS-5", "SS-600MP", "Voyager", "leon3_generic", NULL
    211        };
    212        add_cdrom_param_tests(sparcmachines);
    213    } else if (g_str_equal(arch, "sparc64")) {
    214        const char *sparc64machines[] = {
    215            "niagara", "sun4u", "sun4v", NULL
    216        };
    217        add_cdrom_param_tests(sparc64machines);
    218    } else if (!strncmp(arch, "mips64", 6)) {
    219        const char *mips64machines[] = {
    220            "magnum", "malta", "pica61", NULL
    221        };
    222        add_cdrom_param_tests(mips64machines);
    223    } else if (g_str_equal(arch, "arm") || g_str_equal(arch, "aarch64")) {
    224        const char *armmachines[] = {
    225            "realview-eb", "realview-eb-mpcore", "realview-pb-a8",
    226            "realview-pbx-a9", "versatileab", "versatilepb", "vexpress-a15",
    227            "vexpress-a9", "virt", NULL
    228        };
    229        add_cdrom_param_tests(armmachines);
    230    } else {
    231        const char *nonemachine[] = { "none", NULL };
    232        add_cdrom_param_tests(nonemachine);
    233    }
    234
    235    ret = g_test_run();
    236
    237    unlink(isoimage);
    238
    239    return ret;
    240}