qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

megasas-test.c (2542B)


      1 /*
      2  * QTest testcase for LSI MegaRAID
      3  *
      4  * Copyright (c) 2017 Red Hat Inc.
      5  *
      6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
      7  * See the COPYING file in the top-level directory.
      8  */
      9 
     10 #include "qemu/osdep.h"
     11 #include "libqtest.h"
     12 #include "qemu/bswap.h"
     13 #include "qemu/module.h"
     14 #include "libqos/qgraph.h"
     15 #include "libqos/pci.h"
     16 
     17 typedef struct QMegasas QMegasas;
     18 
     19 struct QMegasas {
     20     QOSGraphObject obj;
     21     QPCIDevice dev;
     22 };
     23 
     24 static void *megasas_get_driver(void *obj, const char *interface)
     25 {
     26     QMegasas *megasas = obj;
     27 
     28     if (!g_strcmp0(interface, "pci-device")) {
     29         return &megasas->dev;
     30     }
     31 
     32     fprintf(stderr, "%s not present in megasas\n", interface);
     33     g_assert_not_reached();
     34 }
     35 
     36 static void *megasas_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
     37 {
     38     QMegasas *megasas = g_new0(QMegasas, 1);
     39     QPCIBus *bus = pci_bus;
     40 
     41     qpci_device_init(&megasas->dev, bus, addr);
     42     megasas->obj.get_driver = megasas_get_driver;
     43 
     44     return &megasas->obj;
     45 }
     46 
     47 /* This used to cause a NULL pointer dereference.  */
     48 static void megasas_pd_get_info_fuzz(void *obj, void *data, QGuestAllocator *alloc)
     49 {
     50     QMegasas *megasas = obj;
     51     QPCIDevice *dev = &megasas->dev;
     52     QPCIBar bar;
     53     uint32_t context[256];
     54     uint64_t context_pa;
     55     int i;
     56 
     57     qpci_device_enable(dev);
     58     bar = qpci_iomap(dev, 0, NULL);
     59 
     60     memset(context, 0, sizeof(context));
     61     context[0] = cpu_to_le32(0x05050505);
     62     context[1] = cpu_to_le32(0x01010101);
     63     for (i = 2; i < ARRAY_SIZE(context); i++) {
     64         context[i] = cpu_to_le32(0x41414141);
     65     }
     66     context[6] = cpu_to_le32(0x02020000);
     67     context[7] = cpu_to_le32(0);
     68 
     69     context_pa = guest_alloc(alloc, sizeof(context));
     70     qtest_memwrite(dev->bus->qts, context_pa, context, sizeof(context));
     71     qpci_io_writel(dev, bar, 0x40, context_pa);
     72 }
     73 
     74 static void megasas_register_nodes(void)
     75 {
     76     QOSGraphEdgeOptions opts = {
     77         .extra_device_opts = "addr=04.0,id=scsi0",
     78         .before_cmd_line = "-drive id=drv0,if=none,file=null-co://,"
     79                            "file.read-zeroes=on,format=raw",
     80         .after_cmd_line = "-device scsi-hd,bus=scsi0.0,drive=drv0",
     81     };
     82 
     83     add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
     84 
     85     qos_node_create_driver("megasas", megasas_create);
     86     qos_node_consumes("megasas", "pci-bus", &opts);
     87     qos_node_produces("megasas", "pci-device");
     88 
     89     qos_add_test("dcmd/pd-get-info/fuzz", "megasas", megasas_pd_get_info_fuzz, NULL);
     90 }
     91 libqos_init(megasas_register_nodes);