diff options
author | Marc MarĂ <marc.mari.barcelo@gmail.com> | 2014-09-01 12:07:59 +0200 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2014-09-08 11:12:43 +0100 |
commit | 58368113989403775496b3422f22094713703157 (patch) | |
tree | 164f623592f825c8ee09c1b106f8e475560ef013 /tests/virtio-blk-test.c | |
parent | e11199554c568822c3ede3e3b4820ac3a146b1d9 (diff) |
libqos: Added MSI-X support
Added MSI-X support for qtest PCI.
Added MSI-X support for virtio-pci.
Added MSI-X test case in virtio-blk-test.
Signed-off-by: Marc MarĂ <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'tests/virtio-blk-test.c')
-rw-r--r-- | tests/virtio-blk-test.c | 180 |
1 files changed, 144 insertions, 36 deletions
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 672580b206..0100aaa950 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -134,7 +134,7 @@ static void pci_basic(void) { QVirtioPCIDevice *dev; QPCIBus *bus; - QVirtQueue *vq; + QVirtQueuePCI *vqpci; QGuestAllocator *alloc; QVirtioBlkReq req; void *addr; @@ -162,7 +162,8 @@ static void pci_basic(void) qvirtio_set_features(&qvirtio_pci, &dev->vdev, features); alloc = pc_alloc_init(); - vq = qvirtqueue_setup(&qvirtio_pci, &dev->vdev, alloc, 0); + vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev, + alloc, 0); qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev); @@ -178,11 +179,11 @@ static void pci_basic(void) g_free(req.data); - free_head = qvirtqueue_add(vq, req_addr, 528, false, true); - qvirtqueue_add(vq, req_addr + 528, 1, true, false); - qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head); + free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true); + qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false); + qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); - g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1, + g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, QVIRTIO_BLK_TIMEOUT)); status = readb(req_addr + 528); g_assert_cmpint(status, ==, 0); @@ -199,12 +200,12 @@ static void pci_basic(void) g_free(req.data); - free_head = qvirtqueue_add(vq, req_addr, 16, false, true); - qvirtqueue_add(vq, req_addr + 16, 513, true, false); + free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true); + qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false); - qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head); + qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); - g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1, + g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, QVIRTIO_BLK_TIMEOUT)); status = readb(req_addr + 528); g_assert_cmpint(status, ==, 0); @@ -226,15 +227,13 @@ static void pci_basic(void) req_addr = virtio_blk_request(alloc, &req, 512); - g_free(req.data); - - free_head = qvirtqueue_add(vq, req_addr, 16, false, true); - qvirtqueue_add(vq, req_addr + 16, 512, false, true); - qvirtqueue_add(vq, req_addr + 528, 1, true, false); + free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true); + qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true); + qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false); - qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head); + qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); - g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1, + g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, QVIRTIO_BLK_TIMEOUT)); status = readb(req_addr + 528); g_assert_cmpint(status, ==, 0); @@ -251,19 +250,17 @@ static void pci_basic(void) g_free(req.data); - free_head = qvirtqueue_add(vq, req_addr, 16, false, true); - qvirtqueue_add(vq, req_addr + 16, 512, true, true); - qvirtqueue_add(vq, req_addr + 528, 1, true, false); + free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true); + qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true); + qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false); - qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head); + qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); - g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1, + g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, QVIRTIO_BLK_TIMEOUT)); status = readb(req_addr + 528); g_assert_cmpint(status, ==, 0); - guest_free(alloc, req_addr); - data = g_malloc0(512); memread(req_addr + 16, data, 512); g_assert_cmpstr(data, ==, "TEST"); @@ -272,7 +269,7 @@ static void pci_basic(void) guest_free(alloc, req_addr); /* End test */ - guest_free(alloc, vq->desc); + guest_free(alloc, vqpci->vq.desc); qvirtio_pci_device_disable(dev); g_free(dev); test_end(); @@ -282,7 +279,7 @@ static void pci_indirect(void) { QVirtioPCIDevice *dev; QPCIBus *bus; - QVirtQueue *vq; + QVirtQueuePCI *vqpci; QGuestAllocator *alloc; QVirtioBlkReq req; QVRingIndirectDesc *indirect; @@ -311,8 +308,8 @@ static void pci_indirect(void) qvirtio_set_features(&qvirtio_pci, &dev->vdev, features); alloc = pc_alloc_init(); - vq = qvirtqueue_setup(&qvirtio_pci, &dev->vdev, alloc, 0); - + vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev, + alloc, 0); qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev); /* Write request */ @@ -329,10 +326,10 @@ static void pci_indirect(void) indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2); qvring_indirect_desc_add(indirect, req_addr, 528, false); qvring_indirect_desc_add(indirect, req_addr + 528, 1, true); - free_head = qvirtqueue_add_indirect(vq, indirect); - qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head); + free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect); + qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); - g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1, + g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, QVIRTIO_BLK_TIMEOUT)); status = readb(req_addr + 528); g_assert_cmpint(status, ==, 0); @@ -354,10 +351,10 @@ static void pci_indirect(void) indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2); qvring_indirect_desc_add(indirect, req_addr, 16, false); qvring_indirect_desc_add(indirect, req_addr + 16, 513, true); - free_head = qvirtqueue_add_indirect(vq, indirect); - qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head); + free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect); + qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); - g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1, + g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, QVIRTIO_BLK_TIMEOUT)); status = readb(req_addr + 528); g_assert_cmpint(status, ==, 0); @@ -371,7 +368,7 @@ static void pci_indirect(void) guest_free(alloc, req_addr); /* End test */ - guest_free(alloc, vq->desc); + guest_free(alloc, vqpci->vq.desc); qvirtio_pci_device_disable(dev); g_free(dev); test_end(); @@ -399,7 +396,7 @@ static void pci_config(void) qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', " " 'size': %d } }", n_size); - g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x2, + g_assert(qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT)); capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr); @@ -410,6 +407,116 @@ static void pci_config(void) test_end(); } +static void pci_msix(void) +{ + QVirtioPCIDevice *dev; + QPCIBus *bus; + QVirtQueuePCI *vqpci; + QGuestAllocator *alloc; + QVirtioBlkReq req; + int n_size = TEST_IMAGE_SIZE / 2; + void *addr; + uint64_t req_addr; + uint64_t capacity; + uint32_t features; + uint32_t free_head; + uint8_t status; + char *data; + + bus = test_start(); + alloc = pc_alloc_init(); + + dev = virtio_blk_init(bus); + qpci_msix_enable(dev->pdev); + + qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0); + + /* MSI-X is enabled */ + addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX; + + capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr); + g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512); + + features = qvirtio_get_features(&qvirtio_pci, &dev->vdev); + features = features & ~(QVIRTIO_F_BAD_FEATURE | + QVIRTIO_F_RING_INDIRECT_DESC | + QVIRTIO_F_RING_EVENT_IDX | QVIRTIO_BLK_F_SCSI); + qvirtio_set_features(&qvirtio_pci, &dev->vdev, features); + + vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev, + alloc, 0); + qvirtqueue_pci_msix_setup(dev, vqpci, alloc, 1); + + qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev); + + qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', " + " 'size': %d } }", n_size); + + g_assert(qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, + QVIRTIO_BLK_TIMEOUT)); + + capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr); + g_assert_cmpint(capacity, ==, n_size / 512); + + /* Write request */ + req.type = QVIRTIO_BLK_T_OUT; + req.ioprio = 1; + req.sector = 0; + req.data = g_malloc0(512); + strcpy(req.data, "TEST"); + + req_addr = virtio_blk_request(alloc, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true); + qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false); + qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); + + g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT)); + + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + guest_free(alloc, req_addr); + + /* Read request */ + req.type = QVIRTIO_BLK_T_IN; + req.ioprio = 1; + req.sector = 0; + req.data = g_malloc0(512); + + req_addr = virtio_blk_request(alloc, &req, 512); + + g_free(req.data); + + free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true); + qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false); + + qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head); + + g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq, + QVIRTIO_BLK_TIMEOUT)); + + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + data = g_malloc0(512); + memread(req_addr + 16, data, 512); + g_assert_cmpstr(data, ==, "TEST"); + g_free(data); + + guest_free(alloc, req_addr); + + /* End test */ + guest_free(alloc, vqpci->vq.desc); + qpci_msix_disable(dev->pdev); + qvirtio_pci_device_disable(dev); + g_free(dev); + test_end(); +} + int main(int argc, char **argv) { int ret; @@ -419,6 +526,7 @@ int main(int argc, char **argv) g_test_add_func("/virtio/blk/pci/basic", pci_basic); g_test_add_func("/virtio/blk/pci/indirect", pci_indirect); g_test_add_func("/virtio/blk/pci/config", pci_config); + g_test_add_func("/virtio/blk/pci/msix", pci_msix); ret = g_test_run(); |