1 /* 2 * QTest testcase for VirtIO 9P 3 * 4 * Copyright (c) 2014 SUSE LINUX Products GmbH 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-common.h" 13 #include "libqos/libqos-pc.h" 14 #include "libqos/virtio.h" 15 #include "libqos/virtio-pci.h" 16 #include "standard-headers/linux/virtio_ids.h" 17 #include "standard-headers/linux/virtio_pci.h" 18 19 static const char mount_tag[] = "qtest"; 20 static char *test_share; 21 22 23 static QOSState *qvirtio_9p_start(void) 24 { 25 const char *cmd = "-fsdev local,id=fsdev0,security_model=none,path=%s " 26 "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s"; 27 28 test_share = g_strdup("/tmp/qtest.XXXXXX"); 29 g_assert_nonnull(mkdtemp(test_share)); 30 31 return qtest_pc_boot(cmd, test_share, mount_tag); 32 } 33 34 static void qvirtio_9p_stop(QOSState *qs) 35 { 36 qtest_shutdown(qs); 37 rmdir(test_share); 38 g_free(test_share); 39 } 40 41 static void pci_nop(void) 42 { 43 QOSState *qs; 44 45 qs = qvirtio_9p_start(); 46 qvirtio_9p_stop(qs); 47 } 48 49 typedef struct { 50 QVirtioDevice *dev; 51 QOSState *qs; 52 QVirtQueue *vq; 53 } QVirtIO9P; 54 55 static QVirtIO9P *qvirtio_9p_pci_init(QOSState *qs) 56 { 57 QVirtIO9P *v9p; 58 QVirtioPCIDevice *dev; 59 60 v9p = g_new0(QVirtIO9P, 1); 61 62 v9p->qs = qs; 63 dev = qvirtio_pci_device_find(v9p->qs->pcibus, VIRTIO_ID_9P); 64 g_assert_nonnull(dev); 65 g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_9P); 66 v9p->dev = (QVirtioDevice *) dev; 67 68 qvirtio_pci_device_enable(dev); 69 qvirtio_reset(v9p->dev); 70 qvirtio_set_acknowledge(v9p->dev); 71 qvirtio_set_driver(v9p->dev); 72 73 v9p->vq = qvirtqueue_setup(v9p->dev, v9p->qs->alloc, 0); 74 return v9p; 75 } 76 77 static void qvirtio_9p_pci_free(QVirtIO9P *v9p) 78 { 79 qvirtqueue_cleanup(v9p->dev->bus, v9p->vq, v9p->qs->alloc); 80 qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev)); 81 g_free(v9p->dev); 82 g_free(v9p); 83 } 84 85 static void pci_basic_config(void) 86 { 87 QVirtIO9P *v9p; 88 void *addr; 89 size_t tag_len; 90 char *tag; 91 int i; 92 QOSState *qs; 93 94 qs = qvirtio_9p_start(); 95 v9p = qvirtio_9p_pci_init(qs); 96 97 addr = ((QVirtioPCIDevice *) v9p->dev)->addr + VIRTIO_PCI_CONFIG_OFF(false); 98 tag_len = qvirtio_config_readw(v9p->dev, 99 (uint64_t)(uintptr_t)addr); 100 g_assert_cmpint(tag_len, ==, strlen(mount_tag)); 101 addr += sizeof(uint16_t); 102 103 tag = g_malloc(tag_len); 104 for (i = 0; i < tag_len; i++) { 105 tag[i] = qvirtio_config_readb(v9p->dev, (uint64_t)(uintptr_t)addr + i); 106 } 107 g_assert_cmpmem(tag, tag_len, mount_tag, tag_len); 108 g_free(tag); 109 110 qvirtio_9p_pci_free(v9p); 111 qvirtio_9p_stop(qs); 112 } 113 114 int main(int argc, char **argv) 115 { 116 g_test_init(&argc, &argv, NULL); 117 qtest_add_func("/virtio/9p/pci/nop", pci_nop); 118 qtest_add_func("/virtio/9p/pci/basic/configuration", pci_basic_config); 119 120 return g_test_run(); 121 } 122