@ -123,6 +123,7 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
uint32_t free_head ;
uint8_t status ;
char * data ;
QTestState * qts = global_qtest ;
capacity = qvirtio_config_readq ( dev , 0 ) ;
@ -149,13 +150,14 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 512 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 512 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL , QVIRTIO_BLK_TIMEOUT_US ) ;
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -171,13 +173,14 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 512 , true , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 512 , true , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL , QVIRTIO_BLK_TIMEOUT_US ) ;
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -206,13 +209,14 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
req_addr = virtio_blk_request ( alloc , dev , & req , sizeof ( dwz_hdr ) ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , sizeof ( dwz_hdr ) , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 + sizeof ( dwz_hdr ) , 1 , true , false ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , sizeof ( dwz_hdr ) , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 + sizeof ( dwz_hdr ) , 1 , true ,
false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 16 + sizeof ( dwz_hdr ) ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -229,13 +233,13 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 512 , true , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 512 , true , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -263,13 +267,13 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
req_addr = virtio_blk_request ( alloc , dev , & req , sizeof ( dwz_hdr ) ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , sizeof ( dwz_hdr ) , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 + sizeof ( dwz_hdr ) , 1 , true , false ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , sizeof ( dwz_hdr ) , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 + sizeof ( dwz_hdr ) , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 16 + sizeof ( dwz_hdr ) ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -290,11 +294,11 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 528 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 528 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -311,12 +315,12 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 513 , true , false ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 513 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -353,6 +357,7 @@ static void indirect(void *obj, void *u_data, QGuestAllocator *t_alloc)
uint32_t free_head ;
uint8_t status ;
char * data ;
QTestState * qts = global_qtest ;
capacity = qvirtio_config_readq ( dev , 0 ) ;
g_assert_cmpint ( capacity , = = , TEST_IMAGE_SIZE / 512 ) ;
@ -378,13 +383,13 @@ static void indirect(void *obj, void *u_data, QGuestAllocator *t_alloc)
g_free ( req . data ) ;
indirect = qvring_indirect_desc_setup ( dev , t_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 ( dev , vq , free_head ) ;
indirect = qvring_indirect_desc_setup ( qts , dev , t_alloc , 2 ) ;
qvring_indirect_desc_add ( qts , indirect , req_addr , 528 , false ) ;
qvring_indirect_desc_add ( qts , indirect , req_addr + 528 , 1 , true ) ;
free_head = qvirtqueue_add_indirect ( qts , vq , indirect ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -403,13 +408,13 @@ static void indirect(void *obj, void *u_data, QGuestAllocator *t_alloc)
g_free ( req . data ) ;
indirect = qvring_indirect_desc_setup ( dev , t_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 ( dev , vq , free_head ) ;
indirect = qvring_indirect_desc_setup ( qts , dev , t_alloc , 2 ) ;
qvring_indirect_desc_add ( qts , indirect , req_addr , 16 , false ) ;
qvring_indirect_desc_add ( qts , indirect , req_addr + 16 , 513 , true ) ;
free_head = qvirtqueue_add_indirect ( qts , vq , indirect ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -461,6 +466,7 @@ static void msix(void *obj, void *u_data, QGuestAllocator *t_alloc)
char * data ;
QOSGraphObject * blk_object = obj ;
QPCIDevice * pci_dev = blk_object - > get_driver ( blk_object , " pci-device " ) ;
QTestState * qts = global_qtest ;
if ( qpci_check_buggy_msi ( pci_dev ) ) {
return ;
@ -504,12 +510,12 @@ static void msix(void *obj, void *u_data, QGuestAllocator *t_alloc)
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 512 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 512 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
@ -527,14 +533,14 @@ static void msix(void *obj, void *u_data, QGuestAllocator *t_alloc)
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 512 , true , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 512 , true , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
status = readb ( req_addr + 528 ) ;
@ -569,6 +575,7 @@ static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc)
char * data ;
QOSGraphObject * blk_object = obj ;
QPCIDevice * pci_dev = blk_object - > get_driver ( blk_object , " pci-device " ) ;
QTestState * qts = global_qtest ;
if ( qpci_check_buggy_msi ( pci_dev ) ) {
return ;
@ -603,12 +610,12 @@ static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc)
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 512 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 512 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
qvirtio_wait_used_elem ( dev , vq , free_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , free_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
/* Write request */
@ -623,15 +630,15 @@ static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc)
g_free ( req . data ) ;
/* Notify after processing the third request */
qvirtqueue_set_used_event ( vq , 2 ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 512 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_set_used_event ( qts , vq , 2 ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 512 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
write_head = free_head ;
/* No notification expected */
status = qvirtio_wait_status_byte_no_isr ( dev ,
status = qvirtio_wait_status_byte_no_isr ( qts , dev ,
vq , req_addr + 528 ,
QVIRTIO_BLK_TIMEOUT_US ) ;
g_assert_cmpint ( status , = = , 0 ) ;
@ -648,16 +655,16 @@ static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc)
g_free ( req . data ) ;
free_head = qvirtqueue_add ( vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( vq , req_addr + 16 , 512 , true , true ) ;
qvirtqueue_add ( vq , req_addr + 528 , 1 , true , false ) ;
free_head = qvirtqueue_add ( qts , vq , req_addr , 16 , false , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 16 , 512 , true , true ) ;
qvirtqueue_add ( qts , vq , req_addr + 528 , 1 , true , false ) ;
qvirtqueue_kick ( dev , vq , free_head ) ;
qvirtqueue_kick ( qts , dev , vq , free_head ) ;
/* We get just one notification for both requests */
qvirtio_wait_used_elem ( dev , vq , write_head , NULL ,
qvirtio_wait_used_elem ( qts , dev , vq , write_head , NULL ,
QVIRTIO_BLK_TIMEOUT_US ) ;
g_assert ( qvirtqueue_get_buf ( vq , & desc_idx , NULL ) ) ;
g_assert ( qvirtqueue_get_buf ( qts , vq , & desc_idx , NULL ) ) ;
g_assert_cmpint ( desc_idx , = = , free_head ) ;
status = readb ( req_addr + 528 ) ;