Skip to contentSkip to conversation

virtio: Ensure virt_queue is always initialised

PATCH In review Will Deacon 2 participants 3 messages Oct 10, 2019 – Oct 25, 2019 KVM

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 virtio: Ensure virt_queue is always initialised

Failing to initialise the virt_queue via virtio_init_device_vq() leaves, amongst other things, the endianness unspecified. On arm/arm64 this results in virtio_guest_to_host_uxx() treating the queue as big-endian and trying to translate bogus addresses:

Warning: unable to translate guest address 0x80b8249800000000 to host

Ensure the virt_queue is always initialised by the virtio device during setup.

Cc Marc Zyngier <[email protected]>
Cc Julien Thierry <[email protected]>
Cc Andre Przywara <[email protected]>
---
 virtio/balloon.c | 1 +
 virtio/rng.c     | 1 +
 virtio/scsi.c    | 1 +
 3 files changed, 3 insertions(+)
virtio/balloon.c +1 -0
index 15a9a46e77e0..0bd16703dfee 100644
@@ -212,6 +212,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 
 	thread_pool__init_job(&bdev->jobs[vq], kvm, virtio_bln_do_io, queue);
 	vring_init(&queue->vring, VIRTIO_BLN_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&bdev->vdev, queue);
 
 	return 0;
 }
virtio/rng.c +1 -0
index 9dd757b7e6e9..78eaa64bda17 100644
@@ -103,6 +103,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	job = &rdev->jobs[vq];
 
 	vring_init(&queue->vring, VIRTIO_RNG_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&rdev->vdev, queue);
 
 	*job = (struct rng_dev_job) {
 		.vq	= queue,
virtio/scsi.c +1 -0
index a72bb2a9a206..1ec78fe0945a 100644
@@ -72,6 +72,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	p		= virtio_get_vq(kvm, queue->pfn, page_size);
 
 	vring_init(&queue->vring, VIRTIO_SCSI_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&sdev->vdev, queue);
 
 	if (sdev->vhost_fd == 0)
 		return 0;
Signature · 1 line
2.23.0.700.g56cf767bdb-goog
Reviewed-by Tested-by on v1 1/1
#1 lore raw

On Thu, 10 Oct 2019 15:28:52 +0100
Will Deacon <[email protected]> wrote:

Hi Will,

Quoted 6 lines

Failing to initialise the virt_queue via virtio_init_device_vq() leaves, amongst other things, the endianness unspecified. On arm/arm64 this results in virtio_guest_to_host_uxx() treating the queue as big-endian and trying to translate bogus addresses:

Warning: unable to translate guest address 0x80b8249800000000 to host

Ouch, a user! ;-)

Quoted 2 lines

Ensure the virt_queue is always initialised by the virtio device during setup.

Indeed, this is also what the other virtio devices do. Confirmed to fix rng and balloon.

Thanks for spotting this!

Cheers,
Andre.

Quoted 47 lines
Cc Marc Zyngier <[email protected]>
Cc Julien Thierry <[email protected]>
Cc Andre Przywara <[email protected]>
---
 virtio/balloon.c | 1 +
 virtio/rng.c     | 1 +
 virtio/scsi.c    | 1 +
 3 files changed, 3 insertions(+)
virtio/balloon.c +1 -0
index 15a9a46e77e0..0bd16703dfee 100644
@@ -212,6 +212,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 
 	thread_pool__init_job(&bdev->jobs[vq], kvm, virtio_bln_do_io, queue);
 	vring_init(&queue->vring, VIRTIO_BLN_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&bdev->vdev, queue);
 
 	return 0;
 }
virtio/rng.c +1 -0
index 9dd757b7e6e9..78eaa64bda17 100644
@@ -103,6 +103,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	job = &rdev->jobs[vq];
 
 	vring_init(&queue->vring, VIRTIO_RNG_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&rdev->vdev, queue);
 
 	*job = (struct rng_dev_job) {
 		.vq	= queue,
virtio/scsi.c +1 -0
index a72bb2a9a206..1ec78fe0945a 100644
@@ -72,6 +72,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	p		= virtio_get_vq(kvm, queue->pfn, page_size);
 
 	vring_init(&queue->vring, VIRTIO_SCSI_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&sdev->vdev, queue);
 
 	if (sdev->vhost_fd == 0)
 		return 0;
#2 lore raw
Quoted 14 lines · Andre Przywara
Quoted 6 lines · On Thu, 10 Oct 2019 15:28:52 +0100 Will Deacon <[email protected]> wrote:

Failing to initialise the virt_queue via virtio_init_device_vq() leaves, amongst other things, the endianness unspecified. On arm/arm64 this results in virtio_guest_to_host_uxx() treating the queue as big-endian and trying to translate bogus addresses:

Warning: unable to translate guest address 0x80b8249800000000 to host

Ouch, a user! ;-)

Quoted 2 lines

Ensure the virt_queue is always initialised by the virtio device during setup.

Quoted 7 lines

Indeed, this is also what the other virtio devices do. Confirmed to fix rng and balloon.

Thanks for spotting this!

Cheers, Andre. Now pushed with your tags.

Will