[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 17/18] qtest: Add test case for "needs reset" of vir
From: |
Fam Zheng |
Subject: |
[Qemu-devel] [PATCH 17/18] qtest: Add test case for "needs reset" of virtio-blk |
Date: |
Fri, 17 Apr 2015 15:59:32 +0800 |
Signed-off-by: Fam Zheng <address@hidden>
---
tests/virtio-blk-test.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 154 insertions(+)
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 866415a..c5a599d 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -734,6 +734,159 @@ static void pci_hotplug(void)
test_end();
}
+typedef void (*err_func)(QGuestAllocator *alloc, const QVirtioBus *bus,
+ QVirtioDevice *vdev, QVirtQueue *vq);
+
+static void test_pci_needs_reset(err_func ef)
+{
+ QVirtioPCIDevice *dev;
+ QVirtioDevice *vdev;
+ QPCIBus *bus;
+ QVirtQueuePCI *vqpci;
+ QGuestAllocator *alloc;
+ void *addr;
+
+ bus = pci_test_start();
+ dev = virtio_blk_pci_init(bus, PCI_SLOT);
+ vdev = &dev->vdev;
+
+ alloc = pc_alloc_init();
+ vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, vdev, alloc, 0);
+ /* MSI-X is not enabled */
+ addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
+
+ setup(&qvirtio_pci, vdev, (uint64_t)(uintptr_t)addr);
+ g_assert(!qvirtio_needs_reset(&qvirtio_pci, vdev));
+
+ ef(alloc, &qvirtio_pci, vdev, &vqpci->vq);
+ g_assert(qvirtio_needs_reset(&qvirtio_pci, vdev));
+
+ /* Kicking when needs_rest should be nop. */
+ qvirtqueue_kick(&qvirtio_pci, vdev, &vqpci->vq, 0);
+
+ qvirtio_reset(&qvirtio_pci, vdev);
+ g_free(vqpci);
+ vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, vdev, alloc, 0);
+ g_assert(!qvirtio_needs_reset(&qvirtio_pci, vdev));
+
+ qvirtio_set_acknowledge(&qvirtio_pci, vdev);
+ qvirtio_set_driver(&qvirtio_pci, vdev);
+
+ /* The device should be back to functional once reset */
+ test_basic(&qvirtio_pci, &dev->vdev, alloc, &vqpci->vq,
+ (uint64_t)(uintptr_t)addr);
+
+ guest_free(alloc, vqpci->vq.desc);
+ pc_alloc_uninit(alloc);
+ qvirtio_pci_device_disable(dev);
+ g_free(dev);
+ qpci_free_pc(bus);
+ test_end();
+}
+
+static void kick_with_no_request(QGuestAllocator *alloc,
+ const QVirtioBus *bus,
+ QVirtioDevice *vdev,
+ QVirtQueue *vq)
+{
+ qvirtqueue_kick(bus, vdev, vq, 0);
+}
+
+static void short_outhdr(QGuestAllocator *alloc,
+ const QVirtioBus *bus,
+ QVirtioDevice *vdev,
+ QVirtQueue *vq)
+{
+ QVirtioBlkReq req;
+ uint64_t req_addr;
+ uint32_t free_head;
+
+ 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(vq, req_addr, 1, false, true);
+ qvirtqueue_add(vq, req_addr + 16, 1, false, true);
+ qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+
+ qvirtqueue_kick(bus, vdev, vq, free_head);
+}
+
+static void invalid_avail_index(QGuestAllocator *alloc,
+ const QVirtioBus *bus,
+ QVirtioDevice *vdev,
+ QVirtQueue *vq)
+{
+ uint16_t idx = vq->size + 1;
+
+ writel(vq->avail + 4 + (2 * (idx % vq->size)), 0);
+ writel(vq->avail + 2, idx + 1);
+ bus->virtqueue_kick(vdev, vq);
+}
+
+static uint32_t add_indirect_len(QVirtQueue *vq,
+ QVRingIndirectDesc *indirect,
+ size_t len)
+{
+ vq->num_free--;
+
+ /* vq->desc[vq->free_head].addr */
+ writeq(vq->desc + (16 * vq->free_head), indirect->desc);
+ /* vq->desc[vq->free_head].len */
+ writel(vq->desc + (16 * vq->free_head) + 8, len);
+ /* vq->desc[vq->free_head].flags */
+ writew(vq->desc + (16 * vq->free_head) + 12, QVRING_DESC_F_INDIRECT);
+
+ return vq->free_head++; /* Return and increase, in this order */
+}
+
+
+static void invalid_indirect(QGuestAllocator *alloc,
+ const QVirtioBus *bus,
+ QVirtioDevice *vdev,
+ QVirtQueue *vq)
+{
+ QVirtioBlkReq req;
+ uint64_t req_addr;
+ uint32_t free_head;
+ uint32_t features;
+ QVRingIndirectDesc *indirect;
+
+ features = qvirtio_get_features(&qvirtio_pci, vdev);
+ g_assert_cmphex(features & QVIRTIO_F_RING_INDIRECT_DESC, !=, 0);
+
+ 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(vdev, alloc, 2);
+ qvring_indirect_desc_add(indirect, req_addr, 528, false);
+ qvring_indirect_desc_add(indirect, req_addr + 528, 1, true);
+ free_head = add_indirect_len(vq, indirect, 511);
+ qvirtqueue_kick(&qvirtio_pci, vdev, vq, free_head);
+ g_free(indirect);
+}
+
+static void pci_needs_reset(void)
+{
+ test_pci_needs_reset(kick_with_no_request);
+ test_pci_needs_reset(short_outhdr);
+ test_pci_needs_reset(invalid_avail_index);
+ test_pci_needs_reset(invalid_indirect);
+}
+
static void mmio_basic(void)
{
QVirtioMMIODevice *dev;
@@ -789,6 +942,7 @@ int main(int argc, char **argv)
qtest_add_func("/virtio/blk/pci/msix", pci_msix);
qtest_add_func("/virtio/blk/pci/idx", pci_idx);
qtest_add_func("/virtio/blk/pci/hotplug", pci_hotplug);
+ qtest_add_func("/virtio/blk/pci/needs_reset", pci_needs_reset);
} else if (strcmp(arch, "arm") == 0) {
qtest_add_func("/virtio/blk/mmio/basic", mmio_basic);
}
--
1.9.3
- Re: [Qemu-devel] [PATCH 06/18] virtio: Return error from virtqueue_pop, (continued)
- [Qemu-devel] [PATCH 07/18] virtio: Return error from virtqueue_avail_bytes, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 09/18] virtio: Return error from virtio_del_queue, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 10/18] virtio: Add macro for VIRTIO_CONFIG_S_NEEDS_RESET, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 11/18] virtio: Add "needs_reset" flag to virtio device, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 12/18] virtio: Return -EINVAL if the vdev needs reset in virtqueue_pop, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 13/18] virtio-blk: Graceful error handling of virtqueue_pop, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 14/18] qtest: Add "QTEST_FILTER" to filter test cases, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 15/18] qtest: virtio-blk: Extract "setup" for future reuse, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 16/18] libqos: Add qvirtio_needs_reset, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 17/18] qtest: Add test case for "needs reset" of virtio-blk,
Fam Zheng <=
- [Qemu-devel] [PATCH 18/18] qtest: virtio-blk: Suppress virtio error messages in "make check", Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 04/18] virtio: Return error from virtqueue_next_desc, Fam Zheng, 2015/04/17
- [Qemu-devel] [PATCH 08/18] virtio: Return error from virtio_add_queue, Fam Zheng, 2015/04/17
- Re: [Qemu-devel] [PATCH 00/18] virtio-blk: Support "VIRTIO_CONFIG_S_NEEDS_RESET", Cornelia Huck, 2015/04/20