From ce984b73f533d7e10a39e59072c8dfc5f770f0d8 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 26 Jan 2022 17:11:18 +0100 Subject: [PATCH] virtio-devices: console: Handle descriptor address translation Since we're trying to move away from the translation happening in the virtio-queue crate, the device itself is performing the address translation when needed. Signed-off-by: Sebastien Boeuf --- virtio-devices/src/console.rs | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/virtio-devices/src/console.rs b/virtio-devices/src/console.rs index 2b6da5fc7..81206baa8 100644 --- a/virtio-devices/src/console.rs +++ b/virtio-devices/src/console.rs @@ -24,8 +24,8 @@ use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::sync::{Arc, Barrier, Mutex}; use versionize::{VersionMap, Versionize, VersionizeResult}; use versionize_derive::Versionize; -use virtio_queue::Queue; -use vm_memory::{ByteValued, Bytes, GuestMemoryAtomic}; +use virtio_queue::{AccessPlatform, Queue}; +use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemoryAtomic}; use vm_migration::VersionMapped; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vmm_sys_util::eventfd::EventFd; @@ -85,6 +85,7 @@ struct ConsoleEpollHandler { resize_pipe: Option, kill_evt: EventFd, pause_evt: EventFd, + access_platform: Option>, } pub enum Endpoint { @@ -145,9 +146,20 @@ impl ConsoleEpollHandler { let desc = desc_chain.next().unwrap(); let len = cmp::min(desc.len() as u32, in_buffer.len() as u32); let source_slice = in_buffer.drain(..len as usize).collect::>(); + + let desc_addr = if let Some(access_platform) = &self.access_platform { + GuestAddress( + access_platform + .translate(desc.addr().0, u64::from(desc.len())) + .unwrap(), + ) + } else { + desc.addr() + }; + if let Err(e) = desc_chain .memory() - .write_slice(&source_slice[..], desc.addr()) + .write_slice(&source_slice[..], desc_addr) { error!("Failed to write slice: {:?}", e); avail_iter.go_to_previous_position(); @@ -184,9 +196,19 @@ impl ConsoleEpollHandler { for mut desc_chain in trans_queue.iter().unwrap() { let desc = desc_chain.next().unwrap(); if let Some(ref mut out) = self.endpoint.out_file() { + let desc_addr = if let Some(access_platform) = &self.access_platform { + GuestAddress( + access_platform + .translate(desc.addr().0, u64::from(desc.len())) + .unwrap(), + ) + } else { + desc.addr() + }; + let _ = desc_chain .memory() - .write_to(desc.addr(), out, desc.len() as usize); + .write_to(desc_addr, out, desc.len() as usize); let _ = out.flush(); } used_desc_heads[used_count] = (desc_chain.head_index(), desc.len()); @@ -513,6 +535,7 @@ impl VirtioDevice for Console { resizer: Arc::clone(&self.resizer), kill_evt, pause_evt, + access_platform: self.common.access_platform.clone(), }; let paused = self.common.paused.clone(); @@ -543,6 +566,10 @@ impl VirtioDevice for Console { event!("virtio-device", "reset", "id", &self.id); result } + + fn set_access_platform(&mut self, access_platform: Arc) { + self.common.set_access_platform(access_platform) + } } impl Pausable for Console {