]> Git Repo - qemu.git/blame - tests/virtio-blk-test.c
tests: virtio-serial: Check if hot-plug/unplug works
[qemu.git] / tests / virtio-blk-test.c
CommitLineData
c7a59bed
AF
1/*
2 * QTest testcase for VirtIO Block Device
3 *
4 * Copyright (c) 2014 SUSE LINUX Products GmbH
311e666a 5 * Copyright (c) 2014 Marc Marí
c7a59bed
AF
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 <glib.h>
12#include <string.h>
311e666a
MM
13#include <stdlib.h>
14#include <unistd.h>
15#include <stdio.h>
c7a59bed 16#include "libqtest.h"
311e666a
MM
17#include "libqos/virtio.h"
18#include "libqos/virtio-pci.h"
19#include "libqos/pci-pc.h"
bf3c63d2
MM
20#include "libqos/malloc.h"
21#include "libqos/malloc-pc.h"
22#include "qemu/bswap.h"
c7a59bed 23
bf3c63d2
MM
24#define QVIRTIO_BLK_F_BARRIER 0x00000001
25#define QVIRTIO_BLK_F_SIZE_MAX 0x00000002
26#define QVIRTIO_BLK_F_SEG_MAX 0x00000004
27#define QVIRTIO_BLK_F_GEOMETRY 0x00000010
28#define QVIRTIO_BLK_F_RO 0x00000020
29#define QVIRTIO_BLK_F_BLK_SIZE 0x00000040
30#define QVIRTIO_BLK_F_SCSI 0x00000080
31#define QVIRTIO_BLK_F_WCE 0x00000200
32#define QVIRTIO_BLK_F_TOPOLOGY 0x00000400
33#define QVIRTIO_BLK_F_CONFIG_WCE 0x00000800
34
35#define QVIRTIO_BLK_T_IN 0
36#define QVIRTIO_BLK_T_OUT 1
37#define QVIRTIO_BLK_T_SCSI_CMD 2
38#define QVIRTIO_BLK_T_SCSI_CMD_OUT 3
39#define QVIRTIO_BLK_T_FLUSH 4
40#define QVIRTIO_BLK_T_FLUSH_OUT 5
41#define QVIRTIO_BLK_T_GET_ID 8
42
43#define TEST_IMAGE_SIZE (64 * 1024 * 1024)
e8c81b4d 44#define QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000)
bf3c63d2
MM
45#define PCI_SLOT 0x04
46#define PCI_FN 0x00
47
48typedef struct QVirtioBlkReq {
49 uint32_t type;
50 uint32_t ioprio;
51 uint64_t sector;
52 char *data;
53 uint8_t status;
54} QVirtioBlkReq;
311e666a
MM
55
56static QPCIBus *test_start(void)
c7a59bed 57{
311e666a
MM
58 char cmdline[100];
59 char tmp_path[] = "/tmp/qtest.XXXXXX";
60 int fd, ret;
61
62 /* Create a temporary raw image */
63 fd = mkstemp(tmp_path);
64 g_assert_cmpint(fd, >=, 0);
65 ret = ftruncate(fd, TEST_IMAGE_SIZE);
66 g_assert_cmpint(ret, ==, 0);
67 close(fd);
68
69 snprintf(cmdline, 100, "-drive if=none,id=drive0,file=%s "
70 "-device virtio-blk-pci,drive=drive0,addr=%x.%x",
71 tmp_path, PCI_SLOT, PCI_FN);
72 qtest_start(cmdline);
73 unlink(tmp_path);
74
75 return qpci_init_pc();
76}
77
78static void test_end(void)
79{
80 qtest_end();
81}
82
46e0cf76 83static QVirtioPCIDevice *virtio_blk_init(QPCIBus *bus)
311e666a
MM
84{
85 QVirtioPCIDevice *dev;
311e666a
MM
86
87 dev = qvirtio_pci_device_find(bus, QVIRTIO_BLK_DEVICE_ID);
88 g_assert(dev != NULL);
89 g_assert_cmphex(dev->vdev.device_type, ==, QVIRTIO_BLK_DEVICE_ID);
90 g_assert_cmphex(dev->pdev->devfn, ==, ((PCI_SLOT << 3) | PCI_FN));
91
46e0cf76
MM
92 qvirtio_pci_device_enable(dev);
93 qvirtio_reset(&qvirtio_pci, &dev->vdev);
94 qvirtio_set_acknowledge(&qvirtio_pci, &dev->vdev);
95 qvirtio_set_driver(&qvirtio_pci, &dev->vdev);
96
97 return dev;
98}
99
bf3c63d2
MM
100static inline void virtio_blk_fix_request(QVirtioBlkReq *req)
101{
102#ifdef HOST_WORDS_BIGENDIAN
103 bool host_endian = true;
104#else
105 bool host_endian = false;
106#endif
107
108 if (qtest_big_endian() != host_endian) {
109 req->type = bswap32(req->type);
110 req->ioprio = bswap32(req->ioprio);
111 req->sector = bswap64(req->sector);
112 }
113}
114
115static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioBlkReq *req,
116 uint64_t data_size)
117{
118 uint64_t addr;
119 uint8_t status = 0xFF;
120
121 g_assert_cmpuint(data_size % 512, ==, 0);
122 addr = guest_alloc(alloc, sizeof(*req) + data_size);
123
124 virtio_blk_fix_request(req);
125
126 memwrite(addr, req, 16);
127 memwrite(addr + 16, req->data, data_size);
128 memwrite(addr + 16 + data_size, &status, sizeof(status));
129
130 return addr;
131}
132
46e0cf76
MM
133static void pci_basic(void)
134{
135 QVirtioPCIDevice *dev;
136 QPCIBus *bus;
58368113 137 QVirtQueuePCI *vqpci;
bf3c63d2
MM
138 QGuestAllocator *alloc;
139 QVirtioBlkReq req;
46e0cf76 140 void *addr;
bf3c63d2 141 uint64_t req_addr;
46e0cf76 142 uint64_t capacity;
bf3c63d2
MM
143 uint32_t features;
144 uint32_t free_head;
145 uint8_t status;
146 char *data;
46e0cf76
MM
147
148 bus = test_start();
149
150 dev = virtio_blk_init(bus);
151
152 /* MSI-X is not enabled */
153 addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
154
155 capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
156 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
157
bf3c63d2
MM
158 features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
159 features = features & ~(QVIRTIO_F_BAD_FEATURE |
160 QVIRTIO_F_RING_INDIRECT_DESC | QVIRTIO_F_RING_EVENT_IDX |
161 QVIRTIO_BLK_F_SCSI);
162 qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
163
164 alloc = pc_alloc_init();
58368113
MM
165 vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
166 alloc, 0);
bf3c63d2
MM
167
168 qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
169
170 /* Write and read with 2 descriptor layout */
171 /* Write request */
172 req.type = QVIRTIO_BLK_T_OUT;
173 req.ioprio = 1;
174 req.sector = 0;
175 req.data = g_malloc0(512);
176 strcpy(req.data, "TEST");
177
178 req_addr = virtio_blk_request(alloc, &req, 512);
179
180 g_free(req.data);
181
58368113
MM
182 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
183 qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
184 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
bf3c63d2 185
70556264
SH
186 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
187 QVIRTIO_BLK_TIMEOUT_US);
bf3c63d2
MM
188 status = readb(req_addr + 528);
189 g_assert_cmpint(status, ==, 0);
190
191 guest_free(alloc, req_addr);
192
193 /* Read request */
194 req.type = QVIRTIO_BLK_T_IN;
195 req.ioprio = 1;
196 req.sector = 0;
197 req.data = g_malloc0(512);
198
199 req_addr = virtio_blk_request(alloc, &req, 512);
200
201 g_free(req.data);
202
58368113
MM
203 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
204 qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false);
bf3c63d2 205
58368113 206 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
bf3c63d2 207
70556264
SH
208 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
209 QVIRTIO_BLK_TIMEOUT_US);
bf3c63d2
MM
210 status = readb(req_addr + 528);
211 g_assert_cmpint(status, ==, 0);
212
213 data = g_malloc0(512);
214 memread(req_addr + 16, data, 512);
215 g_assert_cmpstr(data, ==, "TEST");
216 g_free(data);
217
218 guest_free(alloc, req_addr);
219
220 /* Write and read with 3 descriptor layout */
221 /* Write request */
222 req.type = QVIRTIO_BLK_T_OUT;
223 req.ioprio = 1;
224 req.sector = 1;
225 req.data = g_malloc0(512);
226 strcpy(req.data, "TEST");
227
228 req_addr = virtio_blk_request(alloc, &req, 512);
229
58368113
MM
230 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
231 qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
232 qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
bf3c63d2 233
58368113 234 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
bf3c63d2 235
70556264
SH
236 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
237 QVIRTIO_BLK_TIMEOUT_US);
bf3c63d2
MM
238 status = readb(req_addr + 528);
239 g_assert_cmpint(status, ==, 0);
240
241 guest_free(alloc, req_addr);
242
243 /* Read request */
244 req.type = QVIRTIO_BLK_T_IN;
245 req.ioprio = 1;
246 req.sector = 1;
247 req.data = g_malloc0(512);
248
249 req_addr = virtio_blk_request(alloc, &req, 512);
250
251 g_free(req.data);
252
58368113
MM
253 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
254 qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
255 qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
bf3c63d2 256
58368113 257 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
bf3c63d2 258
70556264
SH
259 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
260 QVIRTIO_BLK_TIMEOUT_US);
bf3c63d2
MM
261 status = readb(req_addr + 528);
262 g_assert_cmpint(status, ==, 0);
263
bf3c63d2
MM
264 data = g_malloc0(512);
265 memread(req_addr + 16, data, 512);
266 g_assert_cmpstr(data, ==, "TEST");
267 g_free(data);
268
269 guest_free(alloc, req_addr);
270
271 /* End test */
58368113 272 guest_free(alloc, vqpci->vq.desc);
46e0cf76 273 qvirtio_pci_device_disable(dev);
311e666a
MM
274 g_free(dev);
275 test_end();
c7a59bed
AF
276}
277
f294b029
MM
278static void pci_indirect(void)
279{
280 QVirtioPCIDevice *dev;
281 QPCIBus *bus;
58368113 282 QVirtQueuePCI *vqpci;
f294b029
MM
283 QGuestAllocator *alloc;
284 QVirtioBlkReq req;
285 QVRingIndirectDesc *indirect;
286 void *addr;
287 uint64_t req_addr;
288 uint64_t capacity;
289 uint32_t features;
290 uint32_t free_head;
291 uint8_t status;
292 char *data;
293
294 bus = test_start();
295
296 dev = virtio_blk_init(bus);
297
298 /* MSI-X is not enabled */
299 addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
300
301 capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
302 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
303
304 features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
305 g_assert_cmphex(features & QVIRTIO_F_RING_INDIRECT_DESC, !=, 0);
306 features = features & ~(QVIRTIO_F_BAD_FEATURE | QVIRTIO_F_RING_EVENT_IDX |
307 QVIRTIO_BLK_F_SCSI);
308 qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
309
310 alloc = pc_alloc_init();
58368113
MM
311 vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
312 alloc, 0);
f294b029
MM
313 qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
314
315 /* Write request */
316 req.type = QVIRTIO_BLK_T_OUT;
317 req.ioprio = 1;
318 req.sector = 0;
319 req.data = g_malloc0(512);
320 strcpy(req.data, "TEST");
321
322 req_addr = virtio_blk_request(alloc, &req, 512);
323
324 g_free(req.data);
325
326 indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2);
327 qvring_indirect_desc_add(indirect, req_addr, 528, false);
328 qvring_indirect_desc_add(indirect, req_addr + 528, 1, true);
58368113
MM
329 free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
330 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
f294b029 331
70556264
SH
332 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
333 QVIRTIO_BLK_TIMEOUT_US);
f294b029
MM
334 status = readb(req_addr + 528);
335 g_assert_cmpint(status, ==, 0);
336
337 g_free(indirect);
338 guest_free(alloc, req_addr);
339
340 /* Read request */
341 req.type = QVIRTIO_BLK_T_IN;
342 req.ioprio = 1;
343 req.sector = 0;
344 req.data = g_malloc0(512);
345 strcpy(req.data, "TEST");
346
347 req_addr = virtio_blk_request(alloc, &req, 512);
348
349 g_free(req.data);
350
351 indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2);
352 qvring_indirect_desc_add(indirect, req_addr, 16, false);
353 qvring_indirect_desc_add(indirect, req_addr + 16, 513, true);
58368113
MM
354 free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
355 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
f294b029 356
70556264
SH
357 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
358 QVIRTIO_BLK_TIMEOUT_US);
f294b029
MM
359 status = readb(req_addr + 528);
360 g_assert_cmpint(status, ==, 0);
361
362 data = g_malloc0(512);
363 memread(req_addr + 16, data, 512);
364 g_assert_cmpstr(data, ==, "TEST");
365 g_free(data);
366
367 g_free(indirect);
368 guest_free(alloc, req_addr);
369
370 /* End test */
58368113 371 guest_free(alloc, vqpci->vq.desc);
f294b029
MM
372 qvirtio_pci_device_disable(dev);
373 g_free(dev);
374 test_end();
375}
376
e1119955
MM
377static void pci_config(void)
378{
379 QVirtioPCIDevice *dev;
380 QPCIBus *bus;
381 int n_size = TEST_IMAGE_SIZE / 2;
382 void *addr;
383 uint64_t capacity;
384
385 bus = test_start();
386
387 dev = virtio_blk_init(bus);
388
389 /* MSI-X is not enabled */
390 addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
391
392 capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
393 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
394
395 qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
396
397 qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
398 " 'size': %d } }", n_size);
70556264 399 qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
e1119955
MM
400
401 capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
402 g_assert_cmpint(capacity, ==, n_size / 512);
403
404 qvirtio_pci_device_disable(dev);
405 g_free(dev);
406 test_end();
407}
408
58368113
MM
409static void pci_msix(void)
410{
411 QVirtioPCIDevice *dev;
412 QPCIBus *bus;
413 QVirtQueuePCI *vqpci;
414 QGuestAllocator *alloc;
415 QVirtioBlkReq req;
416 int n_size = TEST_IMAGE_SIZE / 2;
417 void *addr;
418 uint64_t req_addr;
419 uint64_t capacity;
420 uint32_t features;
421 uint32_t free_head;
422 uint8_t status;
423 char *data;
424
425 bus = test_start();
426 alloc = pc_alloc_init();
427
428 dev = virtio_blk_init(bus);
429 qpci_msix_enable(dev->pdev);
430
431 qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
432
433 /* MSI-X is enabled */
434 addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX;
435
436 capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
437 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
438
439 features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
440 features = features & ~(QVIRTIO_F_BAD_FEATURE |
441 QVIRTIO_F_RING_INDIRECT_DESC |
442 QVIRTIO_F_RING_EVENT_IDX | QVIRTIO_BLK_F_SCSI);
443 qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
444
445 vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
446 alloc, 0);
447 qvirtqueue_pci_msix_setup(dev, vqpci, alloc, 1);
448
449 qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
450
451 qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
452 " 'size': %d } }", n_size);
453
70556264 454 qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
58368113
MM
455
456 capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
457 g_assert_cmpint(capacity, ==, n_size / 512);
458
459 /* Write request */
460 req.type = QVIRTIO_BLK_T_OUT;
461 req.ioprio = 1;
462 req.sector = 0;
463 req.data = g_malloc0(512);
464 strcpy(req.data, "TEST");
465
466 req_addr = virtio_blk_request(alloc, &req, 512);
467
468 g_free(req.data);
469
470 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
471 qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
472 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
473
70556264
SH
474 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
475 QVIRTIO_BLK_TIMEOUT_US);
58368113
MM
476
477 status = readb(req_addr + 528);
478 g_assert_cmpint(status, ==, 0);
479
480 guest_free(alloc, req_addr);
481
482 /* Read request */
483 req.type = QVIRTIO_BLK_T_IN;
484 req.ioprio = 1;
485 req.sector = 0;
486 req.data = g_malloc0(512);
487
488 req_addr = virtio_blk_request(alloc, &req, 512);
489
490 g_free(req.data);
491
492 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
493 qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false);
494
495 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
496
1053587c 497
70556264
SH
498 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
499 QVIRTIO_BLK_TIMEOUT_US);
1053587c
MM
500
501 status = readb(req_addr + 528);
502 g_assert_cmpint(status, ==, 0);
503
504 data = g_malloc0(512);
505 memread(req_addr + 16, data, 512);
506 g_assert_cmpstr(data, ==, "TEST");
507 g_free(data);
508
509 guest_free(alloc, req_addr);
510
511 /* End test */
512 guest_free(alloc, (uint64_t)vqpci->vq.desc);
513 qpci_msix_disable(dev->pdev);
514 qvirtio_pci_device_disable(dev);
515 g_free(dev);
516 test_end();
517}
518
519static void pci_idx(void)
520{
521 QVirtioPCIDevice *dev;
522 QPCIBus *bus;
523 QVirtQueuePCI *vqpci;
524 QGuestAllocator *alloc;
525 QVirtioBlkReq req;
526 void *addr;
527 uint64_t req_addr;
528 uint64_t capacity;
529 uint32_t features;
530 uint32_t free_head;
531 uint8_t status;
532 char *data;
533
534 bus = test_start();
535 alloc = pc_alloc_init();
536
537 dev = virtio_blk_init(bus);
538 qpci_msix_enable(dev->pdev);
539
540 qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
541
542 /* MSI-X is enabled */
543 addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX;
544
545 capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
546 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
547
548 features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
549 features = features & ~(QVIRTIO_F_BAD_FEATURE |
550 QVIRTIO_F_RING_INDIRECT_DESC |
551 QVIRTIO_F_NOTIFY_ON_EMPTY | QVIRTIO_BLK_F_SCSI);
552 qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
553
554 vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
555 alloc, 0);
556 qvirtqueue_pci_msix_setup(dev, vqpci, alloc, 1);
557
558 qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
559
560 /* Write request */
561 req.type = QVIRTIO_BLK_T_OUT;
562 req.ioprio = 1;
563 req.sector = 0;
564 req.data = g_malloc0(512);
565 strcpy(req.data, "TEST");
566
567 req_addr = virtio_blk_request(alloc, &req, 512);
568
569 g_free(req.data);
570
571 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
572 qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
573 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
574
70556264
SH
575 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
576 QVIRTIO_BLK_TIMEOUT_US);
1053587c
MM
577
578 /* Write request */
579 req.type = QVIRTIO_BLK_T_OUT;
580 req.ioprio = 1;
581 req.sector = 1;
582 req.data = g_malloc0(512);
583 strcpy(req.data, "TEST");
584
585 req_addr = virtio_blk_request(alloc, &req, 512);
586
587 g_free(req.data);
588
589 /* Notify after processing the third request */
590 qvirtqueue_set_used_event(&vqpci->vq, 2);
591 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
592 qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
593 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
594
595 /* No notification expected */
e8c81b4d
SH
596 status = qvirtio_wait_status_byte_no_isr(&qvirtio_pci, &dev->vdev,
597 &vqpci->vq, req_addr + 528,
598 QVIRTIO_BLK_TIMEOUT_US);
1053587c
MM
599 g_assert_cmpint(status, ==, 0);
600
601 guest_free(alloc, req_addr);
602
603 /* Read request */
604 req.type = QVIRTIO_BLK_T_IN;
605 req.ioprio = 1;
606 req.sector = 1;
607 req.data = g_malloc0(512);
608
609 req_addr = virtio_blk_request(alloc, &req, 512);
610
611 g_free(req.data);
612
613 free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
614 qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false);
615
616 qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
617
618
70556264
SH
619 qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
620 QVIRTIO_BLK_TIMEOUT_US);
58368113
MM
621
622 status = readb(req_addr + 528);
623 g_assert_cmpint(status, ==, 0);
624
625 data = g_malloc0(512);
626 memread(req_addr + 16, data, 512);
627 g_assert_cmpstr(data, ==, "TEST");
628 g_free(data);
629
630 guest_free(alloc, req_addr);
631
632 /* End test */
633 guest_free(alloc, vqpci->vq.desc);
634 qpci_msix_disable(dev->pdev);
635 qvirtio_pci_device_disable(dev);
636 g_free(dev);
637 test_end();
638}
639
c7a59bed
AF
640int main(int argc, char **argv)
641{
642 int ret;
643
644 g_test_init(&argc, &argv, NULL);
c7a59bed 645
311e666a 646 g_test_add_func("/virtio/blk/pci/basic", pci_basic);
f294b029 647 g_test_add_func("/virtio/blk/pci/indirect", pci_indirect);
e1119955 648 g_test_add_func("/virtio/blk/pci/config", pci_config);
58368113 649 g_test_add_func("/virtio/blk/pci/msix", pci_msix);
1053587c 650 g_test_add_func("/virtio/blk/pci/idx", pci_idx);
c7a59bed 651
311e666a 652 ret = g_test_run();
c7a59bed
AF
653
654 return ret;
655}
This page took 0.170023 seconds and 4 git commands to generate.