From 590361aeb675bac2a9ac1ee49227c493e04d03e6 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 4 Apr 2022 14:14:19 +0200 Subject: [PATCH] virtio-devices: Translate queue addresses back to GVA if needed Whenever a virtio device is placed behind a vIOMMU, we have some code in pci_common_config.rs to translate the queue addresses (descriptor table, available ring and used ring) from GVA to GPA, so that they can be used correctly. But in case of vDPA, we also need to provide the queue addresses to the vhost backend. And since the vhost backend deals with consistent IOVAs, all addresses being provided should be GVAs if the device is placed being a vIOMMU. For that reason, we perform a translation of the queue addresses back from GPA to GVA if necessary, and only to be provided to the vhost backend. Signed-off-by: Sebastien Boeuf --- virtio-devices/src/vdpa.rs | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/virtio-devices/src/vdpa.rs b/virtio-devices/src/vdpa.rs index e2c94b7d9..58e78ba6f 100644 --- a/virtio-devices/src/vdpa.rs +++ b/virtio-devices/src/vdpa.rs @@ -19,10 +19,10 @@ use vhost::{ vhost_kern::VhostKernFeatures, VhostBackend, VringConfigData, }; -use virtio_queue::Queue; +use virtio_queue::{Descriptor, Queue}; use vm_device::dma_mapping::ExternalDmaMapping; use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic}; -use vm_virtio::AccessPlatform; +use vm_virtio::{AccessPlatform, Translatable}; use vmm_sys_util::eventfd::EventFd; #[derive(Error, Debug)] @@ -166,9 +166,30 @@ impl Vdpa { queue_max_size, queue_size, flags: 0u32, - desc_table_addr: queue.state.desc_table.0, - used_ring_addr: queue.state.used_ring.0, - avail_ring_addr: queue.state.avail_ring.0, + desc_table_addr: queue + .state + .desc_table + .translate_gpa( + self.common.access_platform.as_ref(), + queue_size as usize * std::mem::size_of::(), + ) + .0, + used_ring_addr: queue + .state + .used_ring + .translate_gpa( + self.common.access_platform.as_ref(), + 4 + queue_size as usize * 8, + ) + .0, + avail_ring_addr: queue + .state + .avail_ring + .translate_gpa( + self.common.access_platform.as_ref(), + 4 + queue_size as usize * 2, + ) + .0, log_addr: None, };