diff options
author | Marc MarĂ <marc.mari.barcelo@gmail.com> | 2014-09-01 12:07:57 +0200 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2014-09-08 11:12:43 +0100 |
commit | f294b029aa2beb1c67116e04bff5d331f0b18288 (patch) | |
tree | c310d6a49c2e00e2316d8cbac5400aab2838642a /tests/virtio-blk-test.c | |
parent | bf3c63d2010c5ef52f8b988bee2a1486a056795f (diff) |
libqos: Added indirect descriptor support to virtio implementation
Add functions necessary for working with indirect descriptors.
Add test using new functions.
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
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 | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index b048938083..2f9cc2b7e7 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -278,6 +278,105 @@ static void pci_basic(void) test_end(); } +static void pci_indirect(void) +{ + QVirtioPCIDevice *dev; + QPCIBus *bus; + QVirtQueue *vq; + QGuestAllocator *alloc; + QVirtioBlkReq req; + QVRingIndirectDesc *indirect; + void *addr; + uint64_t req_addr; + uint64_t capacity; + uint32_t features; + uint32_t free_head; + uint8_t status; + char *data; + + bus = test_start(); + + dev = virtio_blk_init(bus); + + /* MSI-X is not enabled */ + addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_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); + g_assert_cmphex(features & QVIRTIO_F_RING_INDIRECT_DESC, !=, 0); + features = features & ~(QVIRTIO_F_BAD_FEATURE | QVIRTIO_F_RING_EVENT_IDX | + QVIRTIO_BLK_F_SCSI); + qvirtio_set_features(&qvirtio_pci, &dev->vdev, features); + + alloc = pc_alloc_init(); + vq = qvirtqueue_setup(&qvirtio_pci, &dev->vdev, alloc, 0); + + qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev); + + /* 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); + + 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); + + g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1, + QVIRTIO_BLK_TIMEOUT)); + status = readb(req_addr + 528); + g_assert_cmpint(status, ==, 0); + + g_free(indirect); + guest_free(alloc, req_addr); + + /* Read request */ + req.type = QVIRTIO_BLK_T_IN; + 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); + + 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); + + g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1, + 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); + + g_free(indirect); + guest_free(alloc, req_addr); + + /* End test */ + guest_free(alloc, vq->desc); + qvirtio_pci_device_disable(dev); + g_free(dev); + test_end(); +} + int main(int argc, char **argv) { int ret; @@ -285,6 +384,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); g_test_add_func("/virtio/blk/pci/basic", pci_basic); + g_test_add_func("/virtio/blk/pci/indirect", pci_indirect); ret = g_test_run(); |