12d888c09SAndreas Färber /* 22d888c09SAndreas Färber * QTest testcase for VirtIO 9P 32d888c09SAndreas Färber * 42d888c09SAndreas Färber * Copyright (c) 2014 SUSE LINUX Products GmbH 52d888c09SAndreas Färber * 62d888c09SAndreas Färber * This work is licensed under the terms of the GNU GPL, version 2 or later. 72d888c09SAndreas Färber * See the COPYING file in the top-level directory. 82d888c09SAndreas Färber */ 92d888c09SAndreas Färber 10fbc04127SPeter Maydell #include "qemu/osdep.h" 112d888c09SAndreas Färber #include "libqtest.h" 122d888c09SAndreas Färber #include "qemu-common.h" 13a980f7f2SLaurent Vivier #include "libqos/libqos-pc.h" 1430ca440eSLaurent Vivier #include "libqos/libqos-spapr.h" 15557a4cc0SGreg Kurz #include "libqos/virtio.h" 16557a4cc0SGreg Kurz #include "libqos/virtio-pci.h" 17557a4cc0SGreg Kurz #include "standard-headers/linux/virtio_ids.h" 18557a4cc0SGreg Kurz #include "standard-headers/linux/virtio_pci.h" 192d888c09SAndreas Färber 20993f8054SGreg Kurz static const char mount_tag[] = "qtest"; 212d888c09SAndreas Färber 22557a4cc0SGreg Kurz typedef struct { 23557a4cc0SGreg Kurz QVirtioDevice *dev; 24a980f7f2SLaurent Vivier QOSState *qs; 25557a4cc0SGreg Kurz QVirtQueue *vq; 26*1211d81bSGreg Kurz char *test_share; 27557a4cc0SGreg Kurz } QVirtIO9P; 28557a4cc0SGreg Kurz 29*1211d81bSGreg Kurz static QVirtIO9P *qvirtio_9p_start(const char *driver) 30557a4cc0SGreg Kurz { 31*1211d81bSGreg Kurz const char *arch = qtest_get_arch(); 32*1211d81bSGreg Kurz const char *cmd = "-fsdev local,id=fsdev0,security_model=none,path=%s " 33*1211d81bSGreg Kurz "-device %s,fsdev=fsdev0,mount_tag=%s"; 34*1211d81bSGreg Kurz QVirtIO9P *v9p = g_new0(QVirtIO9P, 1); 35557a4cc0SGreg Kurz 36*1211d81bSGreg Kurz v9p->test_share = g_strdup("/tmp/qtest.XXXXXX"); 37*1211d81bSGreg Kurz g_assert_nonnull(mkdtemp(v9p->test_share)); 38557a4cc0SGreg Kurz 39*1211d81bSGreg Kurz if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { 40*1211d81bSGreg Kurz v9p->qs = qtest_pc_boot(cmd, v9p->test_share, driver, mount_tag); 41*1211d81bSGreg Kurz } else if (strcmp(arch, "ppc64") == 0) { 42*1211d81bSGreg Kurz v9p->qs = qtest_spapr_boot(cmd, v9p->test_share, driver, mount_tag); 43*1211d81bSGreg Kurz } else { 44*1211d81bSGreg Kurz g_printerr("virtio-9p tests are only available on x86 or ppc64\n"); 45*1211d81bSGreg Kurz exit(EXIT_FAILURE); 46*1211d81bSGreg Kurz } 47*1211d81bSGreg Kurz 48*1211d81bSGreg Kurz return v9p; 49*1211d81bSGreg Kurz } 50*1211d81bSGreg Kurz 51*1211d81bSGreg Kurz static void qvirtio_9p_stop(QVirtIO9P *v9p) 52*1211d81bSGreg Kurz { 53*1211d81bSGreg Kurz qtest_shutdown(v9p->qs); 54*1211d81bSGreg Kurz rmdir(v9p->test_share); 55*1211d81bSGreg Kurz g_free(v9p->test_share); 56*1211d81bSGreg Kurz g_free(v9p); 57*1211d81bSGreg Kurz } 58*1211d81bSGreg Kurz 59*1211d81bSGreg Kurz static QVirtIO9P *qvirtio_9p_pci_start(void) 60*1211d81bSGreg Kurz { 61*1211d81bSGreg Kurz QVirtIO9P *v9p = qvirtio_9p_start("virtio-9p-pci"); 62*1211d81bSGreg Kurz QVirtioPCIDevice *dev = qvirtio_pci_device_find(v9p->qs->pcibus, 63*1211d81bSGreg Kurz VIRTIO_ID_9P); 64557a4cc0SGreg Kurz g_assert_nonnull(dev); 65557a4cc0SGreg Kurz g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_9P); 66557a4cc0SGreg Kurz v9p->dev = (QVirtioDevice *) dev; 67557a4cc0SGreg Kurz 68557a4cc0SGreg Kurz qvirtio_pci_device_enable(dev); 696b9cdf4cSLaurent Vivier qvirtio_reset(v9p->dev); 706b9cdf4cSLaurent Vivier qvirtio_set_acknowledge(v9p->dev); 716b9cdf4cSLaurent Vivier qvirtio_set_driver(v9p->dev); 72557a4cc0SGreg Kurz 73a980f7f2SLaurent Vivier v9p->vq = qvirtqueue_setup(v9p->dev, v9p->qs->alloc, 0); 74557a4cc0SGreg Kurz return v9p; 75557a4cc0SGreg Kurz } 76557a4cc0SGreg Kurz 77*1211d81bSGreg Kurz static void qvirtio_9p_pci_stop(QVirtIO9P *v9p) 78557a4cc0SGreg Kurz { 79a980f7f2SLaurent Vivier qvirtqueue_cleanup(v9p->dev->bus, v9p->vq, v9p->qs->alloc); 80557a4cc0SGreg Kurz qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev)); 81557a4cc0SGreg Kurz g_free(v9p->dev); 82*1211d81bSGreg Kurz qvirtio_9p_stop(v9p); 83557a4cc0SGreg Kurz } 84557a4cc0SGreg Kurz 85*1211d81bSGreg Kurz static void pci_config(QVirtIO9P *v9p) 86557a4cc0SGreg Kurz { 87*1211d81bSGreg Kurz size_t tag_len = qvirtio_config_readw(v9p->dev, 0); 88557a4cc0SGreg Kurz char *tag; 89557a4cc0SGreg Kurz int i; 90557a4cc0SGreg Kurz 91557a4cc0SGreg Kurz g_assert_cmpint(tag_len, ==, strlen(mount_tag)); 92557a4cc0SGreg Kurz 93557a4cc0SGreg Kurz tag = g_malloc(tag_len); 94557a4cc0SGreg Kurz for (i = 0; i < tag_len; i++) { 95246fc0fbSDavid Gibson tag[i] = qvirtio_config_readb(v9p->dev, i + 2); 96557a4cc0SGreg Kurz } 97557a4cc0SGreg Kurz g_assert_cmpmem(tag, tag_len, mount_tag, tag_len); 98557a4cc0SGreg Kurz g_free(tag); 99*1211d81bSGreg Kurz } 100557a4cc0SGreg Kurz 101*1211d81bSGreg Kurz typedef void (*v9fs_test_fn)(QVirtIO9P *v9p); 102*1211d81bSGreg Kurz 103*1211d81bSGreg Kurz static void v9fs_run_pci_test(gconstpointer data) 104*1211d81bSGreg Kurz { 105*1211d81bSGreg Kurz v9fs_test_fn fn = data; 106*1211d81bSGreg Kurz QVirtIO9P *v9p = qvirtio_9p_pci_start(); 107*1211d81bSGreg Kurz 108*1211d81bSGreg Kurz if (fn) { 109*1211d81bSGreg Kurz fn(v9p); 110*1211d81bSGreg Kurz } 111*1211d81bSGreg Kurz qvirtio_9p_pci_stop(v9p); 112*1211d81bSGreg Kurz } 113*1211d81bSGreg Kurz 114*1211d81bSGreg Kurz static void v9fs_qtest_pci_add(const char *path, v9fs_test_fn fn) 115*1211d81bSGreg Kurz { 116*1211d81bSGreg Kurz qtest_add_data_func(path, fn, v9fs_run_pci_test); 117557a4cc0SGreg Kurz } 118557a4cc0SGreg Kurz 1192d888c09SAndreas Färber int main(int argc, char **argv) 1202d888c09SAndreas Färber { 1212d888c09SAndreas Färber g_test_init(&argc, &argv, NULL); 122*1211d81bSGreg Kurz v9fs_qtest_pci_add("/virtio/9p/pci/nop", NULL); 123*1211d81bSGreg Kurz v9fs_qtest_pci_add("/virtio/9p/pci/config", pci_config); 1242d888c09SAndreas Färber 125993f8054SGreg Kurz return g_test_run(); 1262d888c09SAndreas Färber } 127