2 * QTest testcase for VirtIO Block Device
4 * Copyright (c) 2014 SUSE LINUX Products GmbH
5 * Copyright (c) 2014 Marc MarĂ
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
11 #include "qemu/osdep.h"
13 #include "libqos/libqos-pc.h"
14 #include "libqos/libqos-spapr.h"
15 #include "libqos/virtio.h"
16 #include "libqos/virtio-pci.h"
17 #include "libqos/virtio-mmio.h"
18 #include "libqos/malloc-generic.h"
19 #include "qemu/bswap.h"
20 #include "standard-headers/linux/virtio_ids.h"
21 #include "standard-headers/linux/virtio_config.h"
22 #include "standard-headers/linux/virtio_ring.h"
23 #include "standard-headers/linux/virtio_blk.h"
24 #include "standard-headers/linux/virtio_pci.h"
26 #define TEST_IMAGE_SIZE (64 * 1024 * 1024)
27 #define QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000)
28 #define PCI_SLOT_HP 0x06
32 #define MMIO_PAGE_SIZE 4096
33 #define MMIO_DEV_BASE_ADDR 0x0A003E00
34 #define MMIO_RAM_ADDR 0x40000000
35 #define MMIO_RAM_SIZE 0x20000000
37 typedef struct QVirtioBlkReq
{
45 static char *drive_create(void)
48 char *tmp_path
= g_strdup("/tmp/qtest.XXXXXX");
50 /* Create a temporary raw image */
51 fd
= mkstemp(tmp_path
);
52 g_assert_cmpint(fd
, >=, 0);
53 ret
= ftruncate(fd
, TEST_IMAGE_SIZE
);
54 g_assert_cmpint(ret
, ==, 0);
60 static QOSState
*pci_test_start(void)
63 const char *arch
= qtest_get_arch();
65 const char *cmd
= "-drive if=none,id=drive0,file=%s,format=raw "
66 "-drive if=none,id=drive1,file=null-co://,format=raw "
67 "-device virtio-blk-pci,id=drv0,drive=drive0,"
70 tmp_path
= drive_create();
72 if (strcmp(arch
, "i386") == 0 || strcmp(arch
, "x86_64") == 0) {
73 qs
= qtest_pc_boot(cmd
, tmp_path
, PCI_SLOT
, PCI_FN
);
74 } else if (strcmp(arch
, "ppc64") == 0) {
75 qs
= qtest_spapr_boot(cmd
, tmp_path
, PCI_SLOT
, PCI_FN
);
77 g_printerr("virtio-blk tests are only available on x86 or ppc64\n");
85 static void arm_test_start(void)
90 tmp_path
= drive_create();
92 cmdline
= g_strdup_printf("-machine virt "
93 "-drive if=none,id=drive0,file=%s,format=raw "
94 "-device virtio-blk-device,drive=drive0",
102 static void test_end(void)
107 static QVirtioPCIDevice
*virtio_blk_pci_init(QPCIBus
*bus
, int slot
)
109 QVirtioPCIDevice
*dev
;
111 dev
= qvirtio_pci_device_find_slot(bus
, VIRTIO_ID_BLOCK
, slot
);
112 g_assert(dev
!= NULL
);
113 g_assert_cmphex(dev
->vdev
.device_type
, ==, VIRTIO_ID_BLOCK
);
114 g_assert_cmphex(dev
->pdev
->devfn
, ==, ((slot
<< 3) | PCI_FN
));
116 qvirtio_pci_device_enable(dev
);
117 qvirtio_reset(&dev
->vdev
);
118 qvirtio_set_acknowledge(&dev
->vdev
);
119 qvirtio_set_driver(&dev
->vdev
);
124 static inline void virtio_blk_fix_request(QVirtioDevice
*d
, QVirtioBlkReq
*req
)
126 #ifdef HOST_WORDS_BIGENDIAN
127 const bool host_is_big_endian
= true;
129 const bool host_is_big_endian
= false;
132 if (qvirtio_is_big_endian(d
) != host_is_big_endian
) {
133 req
->type
= bswap32(req
->type
);
134 req
->ioprio
= bswap32(req
->ioprio
);
135 req
->sector
= bswap64(req
->sector
);
139 static uint64_t virtio_blk_request(QGuestAllocator
*alloc
, QVirtioDevice
*d
,
140 QVirtioBlkReq
*req
, uint64_t data_size
)
143 uint8_t status
= 0xFF;
145 g_assert_cmpuint(data_size
% 512, ==, 0);
146 addr
= guest_alloc(alloc
, sizeof(*req
) + data_size
);
148 virtio_blk_fix_request(d
, req
);
150 memwrite(addr
, req
, 16);
151 memwrite(addr
+ 16, req
->data
, data_size
);
152 memwrite(addr
+ 16 + data_size
, &status
, sizeof(status
));
157 static void test_basic(QVirtioDevice
*dev
, QGuestAllocator
*alloc
,
168 capacity
= qvirtio_config_readq(dev
, 0);
170 g_assert_cmpint(capacity
, ==, TEST_IMAGE_SIZE
/ 512);
172 features
= qvirtio_get_features(dev
);
173 features
= features
& ~(QVIRTIO_F_BAD_FEATURE
|
174 (1u << VIRTIO_RING_F_INDIRECT_DESC
) |
175 (1u << VIRTIO_RING_F_EVENT_IDX
) |
176 (1u << VIRTIO_BLK_F_SCSI
));
177 qvirtio_set_features(dev
, features
);
179 qvirtio_set_driver_ok(dev
);
181 /* Write and read with 3 descriptor layout */
183 req
.type
= VIRTIO_BLK_T_OUT
;
186 req
.data
= g_malloc0(512);
187 strcpy(req
.data
, "TEST");
189 req_addr
= virtio_blk_request(alloc
, dev
, &req
, 512);
193 free_head
= qvirtqueue_add(vq
, req_addr
, 16, false, true);
194 qvirtqueue_add(vq
, req_addr
+ 16, 512, false, true);
195 qvirtqueue_add(vq
, req_addr
+ 528, 1, true, false);
197 qvirtqueue_kick(dev
, vq
, free_head
);
199 qvirtio_wait_used_elem(dev
, vq
, free_head
, QVIRTIO_BLK_TIMEOUT_US
);
200 status
= readb(req_addr
+ 528);
201 g_assert_cmpint(status
, ==, 0);
203 guest_free(alloc
, req_addr
);
206 req
.type
= VIRTIO_BLK_T_IN
;
209 req
.data
= g_malloc0(512);
211 req_addr
= virtio_blk_request(alloc
, dev
, &req
, 512);
215 free_head
= qvirtqueue_add(vq
, req_addr
, 16, false, true);
216 qvirtqueue_add(vq
, req_addr
+ 16, 512, true, true);
217 qvirtqueue_add(vq
, req_addr
+ 528, 1, true, false);
219 qvirtqueue_kick(dev
, vq
, free_head
);
221 qvirtio_wait_used_elem(dev
, vq
, free_head
, QVIRTIO_BLK_TIMEOUT_US
);
222 status
= readb(req_addr
+ 528);
223 g_assert_cmpint(status
, ==, 0);
225 data
= g_malloc0(512);
226 memread(req_addr
+ 16, data
, 512);
227 g_assert_cmpstr(data
, ==, "TEST");
230 guest_free(alloc
, req_addr
);
232 if (features
& (1u << VIRTIO_F_ANY_LAYOUT
)) {
233 /* Write and read with 2 descriptor layout */
235 req
.type
= VIRTIO_BLK_T_OUT
;
238 req
.data
= g_malloc0(512);
239 strcpy(req
.data
, "TEST");
241 req_addr
= virtio_blk_request(alloc
, dev
, &req
, 512);
245 free_head
= qvirtqueue_add(vq
, req_addr
, 528, false, true);
246 qvirtqueue_add(vq
, req_addr
+ 528, 1, true, false);
247 qvirtqueue_kick(dev
, vq
, free_head
);
249 qvirtio_wait_used_elem(dev
, vq
, free_head
, QVIRTIO_BLK_TIMEOUT_US
);
250 status
= readb(req_addr
+ 528);
251 g_assert_cmpint(status
, ==, 0);
253 guest_free(alloc
, req_addr
);
256 req
.type
= VIRTIO_BLK_T_IN
;
259 req
.data
= g_malloc0(512);
261 req_addr
= virtio_blk_request(alloc
, dev
, &req
, 512);
265 free_head
= qvirtqueue_add(vq
, req_addr
, 16, false, true);
266 qvirtqueue_add(vq
, req_addr
+ 16, 513, true, false);
268 qvirtqueue_kick(dev
, vq
, free_head
);
270 qvirtio_wait_used_elem(dev
, vq
, free_head
, QVIRTIO_BLK_TIMEOUT_US
);
271 status
= readb(req_addr
+ 528);
272 g_assert_cmpint(status
, ==, 0);
274 data
= g_malloc0(512);
275 memread(req_addr
+ 16, data
, 512);
276 g_assert_cmpstr(data
, ==, "TEST");
279 guest_free(alloc
, req_addr
);
283 static void pci_basic(void)
285 QVirtioPCIDevice
*dev
;
287 QVirtQueuePCI
*vqpci
;
289 qs
= pci_test_start();
290 dev
= virtio_blk_pci_init(qs
->pcibus
, PCI_SLOT
);
292 vqpci
= (QVirtQueuePCI
*)qvirtqueue_setup(&dev
->vdev
, qs
->alloc
, 0);
294 test_basic(&dev
->vdev
, qs
->alloc
, &vqpci
->vq
);
297 qvirtqueue_cleanup(dev
->vdev
.bus
, &vqpci
->vq
, qs
->alloc
);
298 qvirtio_pci_device_disable(dev
);
299 qvirtio_pci_device_free(dev
);
303 static void pci_indirect(void)
305 QVirtioPCIDevice
*dev
;
306 QVirtQueuePCI
*vqpci
;
309 QVRingIndirectDesc
*indirect
;
317 qs
= pci_test_start();
319 dev
= virtio_blk_pci_init(qs
->pcibus
, PCI_SLOT
);
321 capacity
= qvirtio_config_readq(&dev
->vdev
, 0);
322 g_assert_cmpint(capacity
, ==, TEST_IMAGE_SIZE
/ 512);
324 features
= qvirtio_get_features(&dev
->vdev
);
325 g_assert_cmphex(features
& (1u << VIRTIO_RING_F_INDIRECT_DESC
), !=, 0);
326 features
= features
& ~(QVIRTIO_F_BAD_FEATURE
|
327 (1u << VIRTIO_RING_F_EVENT_IDX
) |
328 (1u << VIRTIO_BLK_F_SCSI
));
329 qvirtio_set_features(&dev
->vdev
, features
);
331 vqpci
= (QVirtQueuePCI
*)qvirtqueue_setup(&dev
->vdev
, qs
->alloc
, 0);
332 qvirtio_set_driver_ok(&dev
->vdev
);
335 req
.type
= VIRTIO_BLK_T_OUT
;
338 req
.data
= g_malloc0(512);
339 strcpy(req
.data
, "TEST");
341 req_addr
= virtio_blk_request(qs
->alloc
, &dev
->vdev
, &req
, 512);
345 indirect
= qvring_indirect_desc_setup(&dev
->vdev
, qs
->alloc
, 2);
346 qvring_indirect_desc_add(indirect
, req_addr
, 528, false);
347 qvring_indirect_desc_add(indirect
, req_addr
+ 528, 1, true);
348 free_head
= qvirtqueue_add_indirect(&vqpci
->vq
, indirect
);
349 qvirtqueue_kick(&dev
->vdev
, &vqpci
->vq
, free_head
);
351 qvirtio_wait_used_elem(&dev
->vdev
, &vqpci
->vq
, free_head
,
352 QVIRTIO_BLK_TIMEOUT_US
);
353 status
= readb(req_addr
+ 528);
354 g_assert_cmpint(status
, ==, 0);
357 guest_free(qs
->alloc
, req_addr
);
360 req
.type
= VIRTIO_BLK_T_IN
;
363 req
.data
= g_malloc0(512);
364 strcpy(req
.data
, "TEST");
366 req_addr
= virtio_blk_request(qs
->alloc
, &dev
->vdev
, &req
, 512);
370 indirect
= qvring_indirect_desc_setup(&dev
->vdev
, qs
->alloc
, 2);
371 qvring_indirect_desc_add(indirect
, req_addr
, 16, false);
372 qvring_indirect_desc_add(indirect
, req_addr
+ 16, 513, true);
373 free_head
= qvirtqueue_add_indirect(&vqpci
->vq
, indirect
);
374 qvirtqueue_kick(&dev
->vdev
, &vqpci
->vq
, free_head
);
376 qvirtio_wait_used_elem(&dev
->vdev
, &vqpci
->vq
, free_head
,
377 QVIRTIO_BLK_TIMEOUT_US
);
378 status
= readb(req_addr
+ 528);
379 g_assert_cmpint(status
, ==, 0);
381 data
= g_malloc0(512);
382 memread(req_addr
+ 16, data
, 512);
383 g_assert_cmpstr(data
, ==, "TEST");
387 guest_free(qs
->alloc
, req_addr
);
390 qvirtqueue_cleanup(dev
->vdev
.bus
, &vqpci
->vq
, qs
->alloc
);
391 qvirtio_pci_device_disable(dev
);
392 qvirtio_pci_device_free(dev
);
396 static void pci_config(void)
398 QVirtioPCIDevice
*dev
;
400 int n_size
= TEST_IMAGE_SIZE
/ 2;
403 qs
= pci_test_start();
405 dev
= virtio_blk_pci_init(qs
->pcibus
, PCI_SLOT
);
407 capacity
= qvirtio_config_readq(&dev
->vdev
, 0);
408 g_assert_cmpint(capacity
, ==, TEST_IMAGE_SIZE
/ 512);
410 qvirtio_set_driver_ok(&dev
->vdev
);
412 qmp_discard_response("{ 'execute': 'block_resize', "
413 " 'arguments': { 'device': 'drive0', "
414 " 'size': %d } }", n_size
);
415 qvirtio_wait_config_isr(&dev
->vdev
, QVIRTIO_BLK_TIMEOUT_US
);
417 capacity
= qvirtio_config_readq(&dev
->vdev
, 0);
418 g_assert_cmpint(capacity
, ==, n_size
/ 512);
420 qvirtio_pci_device_disable(dev
);
421 qvirtio_pci_device_free(dev
);
426 static void pci_msix(void)
428 QVirtioPCIDevice
*dev
;
430 QVirtQueuePCI
*vqpci
;
432 int n_size
= TEST_IMAGE_SIZE
/ 2;
440 qs
= pci_test_start();
442 dev
= virtio_blk_pci_init(qs
->pcibus
, PCI_SLOT
);
443 qpci_msix_enable(dev
->pdev
);
445 qvirtio_pci_set_msix_configuration_vector(dev
, qs
->alloc
, 0);
447 capacity
= qvirtio_config_readq(&dev
->vdev
, 0);
448 g_assert_cmpint(capacity
, ==, TEST_IMAGE_SIZE
/ 512);
450 features
= qvirtio_get_features(&dev
->vdev
);
451 features
= features
& ~(QVIRTIO_F_BAD_FEATURE
|
452 (1u << VIRTIO_RING_F_INDIRECT_DESC
) |
453 (1u << VIRTIO_RING_F_EVENT_IDX
) |
454 (1u << VIRTIO_BLK_F_SCSI
));
455 qvirtio_set_features(&dev
->vdev
, features
);
457 vqpci
= (QVirtQueuePCI
*)qvirtqueue_setup(&dev
->vdev
, qs
->alloc
, 0);
458 qvirtqueue_pci_msix_setup(dev
, vqpci
, qs
->alloc
, 1);
460 qvirtio_set_driver_ok(&dev
->vdev
);
462 qmp_discard_response("{ 'execute': 'block_resize', "
463 " 'arguments': { 'device': 'drive0', "
464 " 'size': %d } }", n_size
);
466 qvirtio_wait_config_isr(&dev
->vdev
, QVIRTIO_BLK_TIMEOUT_US
);
468 capacity
= qvirtio_config_readq(&dev
->vdev
, 0);
469 g_assert_cmpint(capacity
, ==, n_size
/ 512);
472 req
.type
= VIRTIO_BLK_T_OUT
;
475 req
.data
= g_malloc0(512);
476 strcpy(req
.data
, "TEST");
478 req_addr
= virtio_blk_request(qs
->alloc
, &dev
->vdev
, &req
, 512);
482 free_head
= qvirtqueue_add(&vqpci
->vq
, req_addr
, 16, false, true);
483 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 16, 512, false, true);
484 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 528, 1, true, false);
485 qvirtqueue_kick(&dev
->vdev
, &vqpci
->vq
, free_head
);
487 qvirtio_wait_used_elem(&dev
->vdev
, &vqpci
->vq
, free_head
,
488 QVIRTIO_BLK_TIMEOUT_US
);
490 status
= readb(req_addr
+ 528);
491 g_assert_cmpint(status
, ==, 0);
493 guest_free(qs
->alloc
, req_addr
);
496 req
.type
= VIRTIO_BLK_T_IN
;
499 req
.data
= g_malloc0(512);
501 req_addr
= virtio_blk_request(qs
->alloc
, &dev
->vdev
, &req
, 512);
505 free_head
= qvirtqueue_add(&vqpci
->vq
, req_addr
, 16, false, true);
506 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 16, 512, true, true);
507 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 528, 1, true, false);
509 qvirtqueue_kick(&dev
->vdev
, &vqpci
->vq
, free_head
);
512 qvirtio_wait_used_elem(&dev
->vdev
, &vqpci
->vq
, free_head
,
513 QVIRTIO_BLK_TIMEOUT_US
);
515 status
= readb(req_addr
+ 528);
516 g_assert_cmpint(status
, ==, 0);
518 data
= g_malloc0(512);
519 memread(req_addr
+ 16, data
, 512);
520 g_assert_cmpstr(data
, ==, "TEST");
523 guest_free(qs
->alloc
, req_addr
);
526 qvirtqueue_cleanup(dev
->vdev
.bus
, &vqpci
->vq
, qs
->alloc
);
527 qpci_msix_disable(dev
->pdev
);
528 qvirtio_pci_device_disable(dev
);
529 qvirtio_pci_device_free(dev
);
533 static void pci_idx(void)
535 QVirtioPCIDevice
*dev
;
537 QVirtQueuePCI
*vqpci
;
548 qs
= pci_test_start();
550 dev
= virtio_blk_pci_init(qs
->pcibus
, PCI_SLOT
);
551 qpci_msix_enable(dev
->pdev
);
553 qvirtio_pci_set_msix_configuration_vector(dev
, qs
->alloc
, 0);
555 capacity
= qvirtio_config_readq(&dev
->vdev
, 0);
556 g_assert_cmpint(capacity
, ==, TEST_IMAGE_SIZE
/ 512);
558 features
= qvirtio_get_features(&dev
->vdev
);
559 features
= features
& ~(QVIRTIO_F_BAD_FEATURE
|
560 (1u << VIRTIO_RING_F_INDIRECT_DESC
) |
561 (1u << VIRTIO_F_NOTIFY_ON_EMPTY
) |
562 (1u << VIRTIO_BLK_F_SCSI
));
563 qvirtio_set_features(&dev
->vdev
, features
);
565 vqpci
= (QVirtQueuePCI
*)qvirtqueue_setup(&dev
->vdev
, qs
->alloc
, 0);
566 qvirtqueue_pci_msix_setup(dev
, vqpci
, qs
->alloc
, 1);
568 qvirtio_set_driver_ok(&dev
->vdev
);
571 req
.type
= VIRTIO_BLK_T_OUT
;
574 req
.data
= g_malloc0(512);
575 strcpy(req
.data
, "TEST");
577 req_addr
= virtio_blk_request(qs
->alloc
, &dev
->vdev
, &req
, 512);
581 free_head
= qvirtqueue_add(&vqpci
->vq
, req_addr
, 16, false, true);
582 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 16, 512, false, true);
583 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 528, 1, true, false);
584 qvirtqueue_kick(&dev
->vdev
, &vqpci
->vq
, free_head
);
586 qvirtio_wait_used_elem(&dev
->vdev
, &vqpci
->vq
, free_head
,
587 QVIRTIO_BLK_TIMEOUT_US
);
590 req
.type
= VIRTIO_BLK_T_OUT
;
593 req
.data
= g_malloc0(512);
594 strcpy(req
.data
, "TEST");
596 req_addr
= virtio_blk_request(qs
->alloc
, &dev
->vdev
, &req
, 512);
600 /* Notify after processing the third request */
601 qvirtqueue_set_used_event(&vqpci
->vq
, 2);
602 free_head
= qvirtqueue_add(&vqpci
->vq
, req_addr
, 16, false, true);
603 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 16, 512, false, true);
604 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 528, 1, true, false);
605 qvirtqueue_kick(&dev
->vdev
, &vqpci
->vq
, free_head
);
606 write_head
= free_head
;
608 /* No notification expected */
609 status
= qvirtio_wait_status_byte_no_isr(&dev
->vdev
,
610 &vqpci
->vq
, req_addr
+ 528,
611 QVIRTIO_BLK_TIMEOUT_US
);
612 g_assert_cmpint(status
, ==, 0);
614 guest_free(qs
->alloc
, req_addr
);
617 req
.type
= VIRTIO_BLK_T_IN
;
620 req
.data
= g_malloc0(512);
622 req_addr
= virtio_blk_request(qs
->alloc
, &dev
->vdev
, &req
, 512);
626 free_head
= qvirtqueue_add(&vqpci
->vq
, req_addr
, 16, false, true);
627 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 16, 512, true, true);
628 qvirtqueue_add(&vqpci
->vq
, req_addr
+ 528, 1, true, false);
630 qvirtqueue_kick(&dev
->vdev
, &vqpci
->vq
, free_head
);
632 /* We get just one notification for both requests */
633 qvirtio_wait_used_elem(&dev
->vdev
, &vqpci
->vq
, write_head
,
634 QVIRTIO_BLK_TIMEOUT_US
);
635 g_assert(qvirtqueue_get_buf(&vqpci
->vq
, &desc_idx
));
636 g_assert_cmpint(desc_idx
, ==, free_head
);
638 status
= readb(req_addr
+ 528);
639 g_assert_cmpint(status
, ==, 0);
641 data
= g_malloc0(512);
642 memread(req_addr
+ 16, data
, 512);
643 g_assert_cmpstr(data
, ==, "TEST");
646 guest_free(qs
->alloc
, req_addr
);
649 qvirtqueue_cleanup(dev
->vdev
.bus
, &vqpci
->vq
, qs
->alloc
);
650 qpci_msix_disable(dev
->pdev
);
651 qvirtio_pci_device_disable(dev
);
652 qvirtio_pci_device_free(dev
);
656 static void pci_hotplug(void)
658 QVirtioPCIDevice
*dev
;
660 const char *arch
= qtest_get_arch();
662 qs
= pci_test_start();
664 /* plug secondary disk */
665 qpci_plug_device_test("virtio-blk-pci", "drv1", PCI_SLOT_HP
,
666 "'drive': 'drive1'");
668 dev
= virtio_blk_pci_init(qs
->pcibus
, PCI_SLOT_HP
);
670 qvirtio_pci_device_disable(dev
);
671 qvirtio_pci_device_free(dev
);
673 /* unplug secondary disk */
674 if (strcmp(arch
, "i386") == 0 || strcmp(arch
, "x86_64") == 0) {
675 qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP
);
680 static void mmio_basic(void)
682 QVirtioMMIODevice
*dev
;
684 QGuestAllocator
*alloc
;
685 int n_size
= TEST_IMAGE_SIZE
/ 2;
690 dev
= qvirtio_mmio_init_device(MMIO_DEV_BASE_ADDR
, MMIO_PAGE_SIZE
);
691 g_assert(dev
!= NULL
);
692 g_assert_cmphex(dev
->vdev
.device_type
, ==, VIRTIO_ID_BLOCK
);
694 qvirtio_reset(&dev
->vdev
);
695 qvirtio_set_acknowledge(&dev
->vdev
);
696 qvirtio_set_driver(&dev
->vdev
);
698 alloc
= generic_alloc_init(MMIO_RAM_ADDR
, MMIO_RAM_SIZE
, MMIO_PAGE_SIZE
);
699 vq
= qvirtqueue_setup(&dev
->vdev
, alloc
, 0);
701 test_basic(&dev
->vdev
, alloc
, vq
);
703 qmp_discard_response("{ 'execute': 'block_resize', "
704 " 'arguments': { 'device': 'drive0', "
705 " 'size': %d } }", n_size
);
707 qvirtio_wait_queue_isr(&dev
->vdev
, vq
, QVIRTIO_BLK_TIMEOUT_US
);
709 capacity
= qvirtio_config_readq(&dev
->vdev
, 0);
710 g_assert_cmpint(capacity
, ==, n_size
/ 512);
713 qvirtqueue_cleanup(dev
->vdev
.bus
, vq
, alloc
);
715 generic_alloc_uninit(alloc
);
719 int main(int argc
, char **argv
)
721 const char *arch
= qtest_get_arch();
723 g_test_init(&argc
, &argv
, NULL
);
725 if (strcmp(arch
, "i386") == 0 || strcmp(arch
, "x86_64") == 0 ||
726 strcmp(arch
, "ppc64") == 0) {
727 qtest_add_func("/virtio/blk/pci/basic", pci_basic
);
728 qtest_add_func("/virtio/blk/pci/indirect", pci_indirect
);
729 qtest_add_func("/virtio/blk/pci/config", pci_config
);
730 if (strcmp(arch
, "i386") == 0 || strcmp(arch
, "x86_64") == 0) {
731 qtest_add_func("/virtio/blk/pci/msix", pci_msix
);
732 qtest_add_func("/virtio/blk/pci/idx", pci_idx
);
734 qtest_add_func("/virtio/blk/pci/hotplug", pci_hotplug
);
735 } else if (strcmp(arch
, "arm") == 0) {
736 qtest_add_func("/virtio/blk/mmio/basic", mmio_basic
);