]> Git Repo - qemu.git/blob - tests/virtio-blk-test.c
Merge remote-tracking branch 'remotes/kraxel/tags/pull-ui-20161028-1' into staging
[qemu.git] / tests / virtio-blk-test.c
1 /*
2  * QTest testcase for VirtIO Block Device
3  *
4  * Copyright (c) 2014 SUSE LINUX Products GmbH
5  * Copyright (c) 2014 Marc MarĂ­
6  *
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.
9  */
10
11 #include "qemu/osdep.h"
12 #include "libqtest.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"
25
26 #define TEST_IMAGE_SIZE         (64 * 1024 * 1024)
27 #define QVIRTIO_BLK_TIMEOUT_US  (30 * 1000 * 1000)
28 #define PCI_SLOT_HP             0x06
29 #define PCI_SLOT                0x04
30 #define PCI_FN                  0x00
31
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
36
37 typedef struct QVirtioBlkReq {
38     uint32_t type;
39     uint32_t ioprio;
40     uint64_t sector;
41     char *data;
42     uint8_t status;
43 } QVirtioBlkReq;
44
45 static char *drive_create(void)
46 {
47     int fd, ret;
48     char *tmp_path = g_strdup("/tmp/qtest.XXXXXX");
49
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);
55     close(fd);
56
57     return tmp_path;
58 }
59
60 static QOSState *pci_test_start(void)
61 {
62     QOSState *qs;
63     const char *arch = qtest_get_arch();
64     char *tmp_path;
65     const char *cmd = "-drive if=none,id=drive0,file=%s,format=raw "
66                       "-drive if=none,id=drive1,file=/dev/null,format=raw "
67                       "-device virtio-blk-pci,id=drv0,drive=drive0,"
68                       "addr=%x.%x";
69
70     tmp_path = drive_create();
71
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);
76     } else {
77         g_printerr("virtio-blk tests are only available on x86 or ppc64\n");
78         exit(EXIT_FAILURE);
79     }
80     unlink(tmp_path);
81     g_free(tmp_path);
82     return qs;
83 }
84
85 static void arm_test_start(void)
86 {
87     char *cmdline;
88     char *tmp_path;
89
90     tmp_path = drive_create();
91
92     cmdline = g_strdup_printf("-machine virt "
93                                 "-drive if=none,id=drive0,file=%s,format=raw "
94                                 "-device virtio-blk-device,drive=drive0",
95                                 tmp_path);
96     qtest_start(cmdline);
97     unlink(tmp_path);
98     g_free(tmp_path);
99     g_free(cmdline);
100 }
101
102 static void test_end(void)
103 {
104     qtest_end();
105 }
106
107 static QVirtioPCIDevice *virtio_blk_pci_init(QPCIBus *bus, int slot)
108 {
109     QVirtioPCIDevice *dev;
110
111     dev = qvirtio_pci_device_find(bus, VIRTIO_ID_BLOCK);
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));
115
116     qvirtio_pci_device_enable(dev);
117     qvirtio_reset(&dev->vdev);
118     qvirtio_set_acknowledge(&dev->vdev);
119     qvirtio_set_driver(&dev->vdev);
120
121     return dev;
122 }
123
124 static inline void virtio_blk_fix_request(QVirtioDevice *d, QVirtioBlkReq *req)
125 {
126 #ifdef HOST_WORDS_BIGENDIAN
127     const bool host_is_big_endian = true;
128 #else
129     const bool host_is_big_endian = false;
130 #endif
131
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);
136     }
137 }
138
139 static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d,
140                                    QVirtioBlkReq *req, uint64_t data_size)
141 {
142     uint64_t addr;
143     uint8_t status = 0xFF;
144
145     g_assert_cmpuint(data_size % 512, ==, 0);
146     addr = guest_alloc(alloc, sizeof(*req) + data_size);
147
148     virtio_blk_fix_request(d, req);
149
150     memwrite(addr, req, 16);
151     memwrite(addr + 16, req->data, data_size);
152     memwrite(addr + 16 + data_size, &status, sizeof(status));
153
154     return addr;
155 }
156
157 static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
158                        QVirtQueue *vq)
159 {
160     QVirtioBlkReq req;
161     uint64_t req_addr;
162     uint64_t capacity;
163     uint32_t features;
164     uint32_t free_head;
165     uint8_t status;
166     char *data;
167
168     capacity = qvirtio_config_readq(dev, 0);
169
170     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
171
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);
178
179     qvirtio_set_driver_ok(dev);
180
181     /* Write and read with 3 descriptor layout */
182     /* Write request */
183     req.type = VIRTIO_BLK_T_OUT;
184     req.ioprio = 1;
185     req.sector = 0;
186     req.data = g_malloc0(512);
187     strcpy(req.data, "TEST");
188
189     req_addr = virtio_blk_request(alloc, dev, &req, 512);
190
191     g_free(req.data);
192
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);
196
197     qvirtqueue_kick(dev, vq, free_head);
198
199     qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
200     status = readb(req_addr + 528);
201     g_assert_cmpint(status, ==, 0);
202
203     guest_free(alloc, req_addr);
204
205     /* Read request */
206     req.type = VIRTIO_BLK_T_IN;
207     req.ioprio = 1;
208     req.sector = 0;
209     req.data = g_malloc0(512);
210
211     req_addr = virtio_blk_request(alloc, dev, &req, 512);
212
213     g_free(req.data);
214
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);
218
219     qvirtqueue_kick(dev, vq, free_head);
220
221     qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
222     status = readb(req_addr + 528);
223     g_assert_cmpint(status, ==, 0);
224
225     data = g_malloc0(512);
226     memread(req_addr + 16, data, 512);
227     g_assert_cmpstr(data, ==, "TEST");
228     g_free(data);
229
230     guest_free(alloc, req_addr);
231
232     if (features & (1u << VIRTIO_F_ANY_LAYOUT)) {
233         /* Write and read with 2 descriptor layout */
234         /* Write request */
235         req.type = VIRTIO_BLK_T_OUT;
236         req.ioprio = 1;
237         req.sector = 1;
238         req.data = g_malloc0(512);
239         strcpy(req.data, "TEST");
240
241         req_addr = virtio_blk_request(alloc, dev, &req, 512);
242
243         g_free(req.data);
244
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);
248
249         qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
250         status = readb(req_addr + 528);
251         g_assert_cmpint(status, ==, 0);
252
253         guest_free(alloc, req_addr);
254
255         /* Read request */
256         req.type = VIRTIO_BLK_T_IN;
257         req.ioprio = 1;
258         req.sector = 1;
259         req.data = g_malloc0(512);
260
261         req_addr = virtio_blk_request(alloc, dev, &req, 512);
262
263         g_free(req.data);
264
265         free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
266         qvirtqueue_add(vq, req_addr + 16, 513, true, false);
267
268         qvirtqueue_kick(dev, vq, free_head);
269
270         qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
271         status = readb(req_addr + 528);
272         g_assert_cmpint(status, ==, 0);
273
274         data = g_malloc0(512);
275         memread(req_addr + 16, data, 512);
276         g_assert_cmpstr(data, ==, "TEST");
277         g_free(data);
278
279         guest_free(alloc, req_addr);
280     }
281 }
282
283 static void pci_basic(void)
284 {
285     QVirtioPCIDevice *dev;
286     QOSState *qs;
287     QVirtQueuePCI *vqpci;
288
289     qs = pci_test_start();
290     dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
291
292     vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
293
294     test_basic(&dev->vdev, qs->alloc, &vqpci->vq);
295
296     /* End test */
297     qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
298     qvirtio_pci_device_disable(dev);
299     g_free(dev);
300     qtest_shutdown(qs);
301 }
302
303 static void pci_indirect(void)
304 {
305     QVirtioPCIDevice *dev;
306     QVirtQueuePCI *vqpci;
307     QOSState *qs;
308     QVirtioBlkReq req;
309     QVRingIndirectDesc *indirect;
310     uint64_t req_addr;
311     uint64_t capacity;
312     uint32_t features;
313     uint32_t free_head;
314     uint8_t status;
315     char *data;
316
317     qs = pci_test_start();
318
319     dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
320
321     capacity = qvirtio_config_readq(&dev->vdev, 0);
322     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
323
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);
330
331     vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
332     qvirtio_set_driver_ok(&dev->vdev);
333
334     /* Write request */
335     req.type = VIRTIO_BLK_T_OUT;
336     req.ioprio = 1;
337     req.sector = 0;
338     req.data = g_malloc0(512);
339     strcpy(req.data, "TEST");
340
341     req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
342
343     g_free(req.data);
344
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);
350
351     qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
352                            QVIRTIO_BLK_TIMEOUT_US);
353     status = readb(req_addr + 528);
354     g_assert_cmpint(status, ==, 0);
355
356     g_free(indirect);
357     guest_free(qs->alloc, req_addr);
358
359     /* Read request */
360     req.type = VIRTIO_BLK_T_IN;
361     req.ioprio = 1;
362     req.sector = 0;
363     req.data = g_malloc0(512);
364     strcpy(req.data, "TEST");
365
366     req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
367
368     g_free(req.data);
369
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);
375
376     qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
377                            QVIRTIO_BLK_TIMEOUT_US);
378     status = readb(req_addr + 528);
379     g_assert_cmpint(status, ==, 0);
380
381     data = g_malloc0(512);
382     memread(req_addr + 16, data, 512);
383     g_assert_cmpstr(data, ==, "TEST");
384     g_free(data);
385
386     g_free(indirect);
387     guest_free(qs->alloc, req_addr);
388
389     /* End test */
390     qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
391     qvirtio_pci_device_disable(dev);
392     g_free(dev);
393     qtest_shutdown(qs);
394 }
395
396 static void pci_config(void)
397 {
398     QVirtioPCIDevice *dev;
399     QOSState *qs;
400     int n_size = TEST_IMAGE_SIZE / 2;
401     uint64_t capacity;
402
403     qs = pci_test_start();
404
405     dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
406
407     capacity = qvirtio_config_readq(&dev->vdev, 0);
408     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
409
410     qvirtio_set_driver_ok(&dev->vdev);
411
412     qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
413                                                     " 'size': %d } }", n_size);
414     qvirtio_wait_config_isr(&dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
415
416     capacity = qvirtio_config_readq(&dev->vdev, 0);
417     g_assert_cmpint(capacity, ==, n_size / 512);
418
419     qvirtio_pci_device_disable(dev);
420     g_free(dev);
421
422     qtest_shutdown(qs);
423 }
424
425 static void pci_msix(void)
426 {
427     QVirtioPCIDevice *dev;
428     QOSState *qs;
429     QVirtQueuePCI *vqpci;
430     QVirtioBlkReq req;
431     int n_size = TEST_IMAGE_SIZE / 2;
432     uint64_t req_addr;
433     uint64_t capacity;
434     uint32_t features;
435     uint32_t free_head;
436     uint8_t status;
437     char *data;
438
439     qs = pci_test_start();
440
441     dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
442     qpci_msix_enable(dev->pdev);
443
444     qvirtio_pci_set_msix_configuration_vector(dev, qs->alloc, 0);
445
446     capacity = qvirtio_config_readq(&dev->vdev, 0);
447     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
448
449     features = qvirtio_get_features(&dev->vdev);
450     features = features & ~(QVIRTIO_F_BAD_FEATURE |
451                             (1u << VIRTIO_RING_F_INDIRECT_DESC) |
452                             (1u << VIRTIO_RING_F_EVENT_IDX) |
453                             (1u << VIRTIO_BLK_F_SCSI));
454     qvirtio_set_features(&dev->vdev, features);
455
456     vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
457     qvirtqueue_pci_msix_setup(dev, vqpci, qs->alloc, 1);
458
459     qvirtio_set_driver_ok(&dev->vdev);
460
461     qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
462                                                     " 'size': %d } }", n_size);
463
464     qvirtio_wait_config_isr(&dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
465
466     capacity = qvirtio_config_readq(&dev->vdev, 0);
467     g_assert_cmpint(capacity, ==, n_size / 512);
468
469     /* Write request */
470     req.type = VIRTIO_BLK_T_OUT;
471     req.ioprio = 1;
472     req.sector = 0;
473     req.data = g_malloc0(512);
474     strcpy(req.data, "TEST");
475
476     req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
477
478     g_free(req.data);
479
480     free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
481     qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
482     qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
483     qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
484
485     qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
486                            QVIRTIO_BLK_TIMEOUT_US);
487
488     status = readb(req_addr + 528);
489     g_assert_cmpint(status, ==, 0);
490
491     guest_free(qs->alloc, req_addr);
492
493     /* Read request */
494     req.type = VIRTIO_BLK_T_IN;
495     req.ioprio = 1;
496     req.sector = 0;
497     req.data = g_malloc0(512);
498
499     req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
500
501     g_free(req.data);
502
503     free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
504     qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
505     qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
506
507     qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
508
509
510     qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
511                            QVIRTIO_BLK_TIMEOUT_US);
512
513     status = readb(req_addr + 528);
514     g_assert_cmpint(status, ==, 0);
515
516     data = g_malloc0(512);
517     memread(req_addr + 16, data, 512);
518     g_assert_cmpstr(data, ==, "TEST");
519     g_free(data);
520
521     guest_free(qs->alloc, req_addr);
522
523     /* End test */
524     qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
525     qpci_msix_disable(dev->pdev);
526     qvirtio_pci_device_disable(dev);
527     g_free(dev);
528     qtest_shutdown(qs);
529 }
530
531 static void pci_idx(void)
532 {
533     QVirtioPCIDevice *dev;
534     QOSState *qs;
535     QVirtQueuePCI *vqpci;
536     QVirtioBlkReq req;
537     uint64_t req_addr;
538     uint64_t capacity;
539     uint32_t features;
540     uint32_t free_head;
541     uint8_t status;
542     char *data;
543
544     qs = pci_test_start();
545
546     dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
547     qpci_msix_enable(dev->pdev);
548
549     qvirtio_pci_set_msix_configuration_vector(dev, qs->alloc, 0);
550
551     capacity = qvirtio_config_readq(&dev->vdev, 0);
552     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
553
554     features = qvirtio_get_features(&dev->vdev);
555     features = features & ~(QVIRTIO_F_BAD_FEATURE |
556                             (1u << VIRTIO_RING_F_INDIRECT_DESC) |
557                             (1u << VIRTIO_F_NOTIFY_ON_EMPTY) |
558                             (1u << VIRTIO_BLK_F_SCSI));
559     qvirtio_set_features(&dev->vdev, features);
560
561     vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
562     qvirtqueue_pci_msix_setup(dev, vqpci, qs->alloc, 1);
563
564     qvirtio_set_driver_ok(&dev->vdev);
565
566     /* Write request */
567     req.type = VIRTIO_BLK_T_OUT;
568     req.ioprio = 1;
569     req.sector = 0;
570     req.data = g_malloc0(512);
571     strcpy(req.data, "TEST");
572
573     req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
574
575     g_free(req.data);
576
577     free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
578     qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
579     qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
580     qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
581
582     qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq, QVIRTIO_BLK_TIMEOUT_US);
583
584     /* Write request */
585     req.type = VIRTIO_BLK_T_OUT;
586     req.ioprio = 1;
587     req.sector = 1;
588     req.data = g_malloc0(512);
589     strcpy(req.data, "TEST");
590
591     req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
592
593     g_free(req.data);
594
595     /* Notify after processing the third request */
596     qvirtqueue_set_used_event(&vqpci->vq, 2);
597     free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
598     qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
599     qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
600     qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
601
602     /* No notification expected */
603     status = qvirtio_wait_status_byte_no_isr(&dev->vdev,
604                                              &vqpci->vq, req_addr + 528,
605                                              QVIRTIO_BLK_TIMEOUT_US);
606     g_assert_cmpint(status, ==, 0);
607
608     guest_free(qs->alloc, req_addr);
609
610     /* Read request */
611     req.type = VIRTIO_BLK_T_IN;
612     req.ioprio = 1;
613     req.sector = 1;
614     req.data = g_malloc0(512);
615
616     req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
617
618     g_free(req.data);
619
620     free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
621     qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
622     qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
623
624     qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
625
626     qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
627                            QVIRTIO_BLK_TIMEOUT_US);
628
629     status = readb(req_addr + 528);
630     g_assert_cmpint(status, ==, 0);
631
632     data = g_malloc0(512);
633     memread(req_addr + 16, data, 512);
634     g_assert_cmpstr(data, ==, "TEST");
635     g_free(data);
636
637     guest_free(qs->alloc, req_addr);
638
639     /* End test */
640     qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
641     qpci_msix_disable(dev->pdev);
642     qvirtio_pci_device_disable(dev);
643     g_free(dev);
644     qtest_shutdown(qs);
645 }
646
647 static void pci_hotplug(void)
648 {
649     QVirtioPCIDevice *dev;
650     QOSState *qs;
651     const char *arch = qtest_get_arch();
652
653     qs = pci_test_start();
654
655     /* plug secondary disk */
656     qpci_plug_device_test("virtio-blk-pci", "drv1", PCI_SLOT_HP,
657                           "'drive': 'drive1'");
658
659     dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT_HP);
660     g_assert(dev);
661     qvirtio_pci_device_disable(dev);
662     g_free(dev);
663
664     /* unplug secondary disk */
665     if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
666         qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP);
667     }
668     qtest_shutdown(qs);
669 }
670
671 static void mmio_basic(void)
672 {
673     QVirtioMMIODevice *dev;
674     QVirtQueue *vq;
675     QGuestAllocator *alloc;
676     int n_size = TEST_IMAGE_SIZE / 2;
677     uint64_t capacity;
678
679     arm_test_start();
680
681     dev = qvirtio_mmio_init_device(MMIO_DEV_BASE_ADDR, MMIO_PAGE_SIZE);
682     g_assert(dev != NULL);
683     g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_BLOCK);
684
685     qvirtio_reset(&dev->vdev);
686     qvirtio_set_acknowledge(&dev->vdev);
687     qvirtio_set_driver(&dev->vdev);
688
689     alloc = generic_alloc_init(MMIO_RAM_ADDR, MMIO_RAM_SIZE, MMIO_PAGE_SIZE);
690     vq = qvirtqueue_setup(&dev->vdev, alloc, 0);
691
692     test_basic(&dev->vdev, alloc, vq);
693
694     qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
695                                                     " 'size': %d } }", n_size);
696
697     qvirtio_wait_queue_isr(&dev->vdev, vq, QVIRTIO_BLK_TIMEOUT_US);
698
699     capacity = qvirtio_config_readq(&dev->vdev, 0);
700     g_assert_cmpint(capacity, ==, n_size / 512);
701
702     /* End test */
703     qvirtqueue_cleanup(dev->vdev.bus, vq, alloc);
704     g_free(dev);
705     generic_alloc_uninit(alloc);
706     test_end();
707 }
708
709 int main(int argc, char **argv)
710 {
711     const char *arch = qtest_get_arch();
712
713     g_test_init(&argc, &argv, NULL);
714
715     if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0 ||
716         strcmp(arch, "ppc64") == 0) {
717         qtest_add_func("/virtio/blk/pci/basic", pci_basic);
718         qtest_add_func("/virtio/blk/pci/indirect", pci_indirect);
719         qtest_add_func("/virtio/blk/pci/config", pci_config);
720         if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
721             qtest_add_func("/virtio/blk/pci/msix", pci_msix);
722             qtest_add_func("/virtio/blk/pci/idx", pci_idx);
723         }
724         qtest_add_func("/virtio/blk/pci/hotplug", pci_hotplug);
725     } else if (strcmp(arch, "arm") == 0) {
726         qtest_add_func("/virtio/blk/mmio/basic", mmio_basic);
727     }
728
729     return g_test_run();
730 }
This page took 0.0619150000000001 seconds and 4 git commands to generate.