From 3c973fa7ce208e7113f69424b7574b83f584885d Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Tue, 29 Mar 2022 21:27:05 +0200 Subject: [PATCH] virtio-devices: vhost-user: Add support for TDX By enabling the VIRTIO feature VIRTIO_F_IOMMU_PLATFORM for all vhost-user devices when needed, we force the guest to use the DMA API, making these devices compatible with TDX. By using DMA API, the guest triggers the TDX codepath to share some of the guest memory, in particular the virtqueues and associated buffers so that the VMM and vhost-user backends/processes can access this memory. Signed-off-by: Sebastien Boeuf --- virtio-devices/src/vhost_user/blk.rs | 12 ++++++++++-- virtio-devices/src/vhost_user/fs.rs | 12 ++++++++++-- virtio-devices/src/vhost_user/net.rs | 13 +++++++++++-- vmm/src/device_manager.rs | 3 +++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index b08798df5..f24b2ff9c 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -7,8 +7,8 @@ use super::{Error, Result, DEFAULT_VIRTIO_FEATURES}; use crate::seccomp_filters::Thread; use crate::thread_helper::spawn_virtio_thread; use crate::vhost_user::VhostUserCommon; -use crate::VirtioInterrupt; use crate::{GuestMemoryMmap, GuestRegionMmap}; +use crate::{VirtioInterrupt, VIRTIO_F_IOMMU_PLATFORM}; use block_util::VirtioBlockConfig; use seccompiler::SeccompAction; use std::mem; @@ -61,6 +61,7 @@ pub struct Blk { epoll_thread: Option>, seccomp_action: SeccompAction, exit_evt: EventFd, + iommu: bool, } impl Blk { @@ -71,6 +72,7 @@ impl Blk { restoring: bool, seccomp_action: SeccompAction, exit_evt: EventFd, + iommu: bool, ) -> Result { let num_queues = vu_cfg.num_queues; @@ -97,6 +99,7 @@ impl Blk { epoll_thread: None, seccomp_action, exit_evt, + iommu, }); } @@ -189,6 +192,7 @@ impl Blk { epoll_thread: None, seccomp_action, exit_evt, + iommu, }) } @@ -241,7 +245,11 @@ impl VirtioDevice for Blk { } fn features(&self) -> u64 { - self.common.avail_features + let mut features = self.common.avail_features; + if self.iommu { + features |= 1u64 << VIRTIO_F_IOMMU_PLATFORM; + } + features } fn ack_features(&mut self, value: u64) { diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index 0b24fc55a..d8c4e2ba2 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -8,7 +8,7 @@ use crate::thread_helper::spawn_virtio_thread; use crate::vhost_user::VhostUserCommon; use crate::{ ActivateError, ActivateResult, UserspaceMapping, VirtioCommon, VirtioDevice, VirtioDeviceType, - VirtioInterrupt, VirtioSharedMemoryList, + VirtioInterrupt, VirtioSharedMemoryList, VIRTIO_F_IOMMU_PLATFORM, }; use crate::{GuestMemoryMmap, GuestRegionMmap, MmapRegion}; use libc::{self, c_void, off64_t, pread64, pwrite64}; @@ -301,6 +301,7 @@ pub struct Fs { guest_memory: Option>, epoll_thread: Option>, exit_evt: EventFd, + iommu: bool, } impl Fs { @@ -316,6 +317,7 @@ impl Fs { seccomp_action: SeccompAction, restoring: bool, exit_evt: EventFd, + iommu: bool, ) -> Result { let mut slave_req_support = false; @@ -347,6 +349,7 @@ impl Fs { guest_memory: None, epoll_thread: None, exit_evt, + iommu, }); } @@ -428,6 +431,7 @@ impl Fs { guest_memory: None, epoll_thread: None, exit_evt, + iommu, }) } @@ -481,7 +485,11 @@ impl VirtioDevice for Fs { } fn features(&self) -> u64 { - self.common.avail_features + let mut features = self.common.avail_features; + if self.iommu { + features |= 1u64 << VIRTIO_F_IOMMU_PLATFORM; + } + features } fn ack_features(&mut self, value: u64) { diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index e5556524b..fb90edda1 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -7,7 +7,7 @@ use crate::vhost_user::vu_common_ctrl::{VhostUserConfig, VhostUserHandle}; use crate::vhost_user::{Error, Result, VhostUserCommon}; use crate::{ ActivateResult, NetCtrlEpollHandler, VirtioCommon, VirtioDevice, VirtioDeviceType, - VirtioInterrupt, VIRTIO_F_RING_EVENT_IDX, VIRTIO_F_VERSION_1, + VirtioInterrupt, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_RING_EVENT_IDX, VIRTIO_F_VERSION_1, }; use crate::{GuestMemoryMmap, GuestRegionMmap}; use net_util::{build_net_config_space, CtrlQueue, MacAddr, VirtioNetConfig}; @@ -61,10 +61,12 @@ pub struct Net { epoll_thread: Option>, seccomp_action: SeccompAction, exit_evt: EventFd, + iommu: bool, } impl Net { /// Create a new vhost-user-net device + #[allow(clippy::too_many_arguments)] pub fn new( id: String, mac_addr: MacAddr, @@ -73,6 +75,7 @@ impl Net { seccomp_action: SeccompAction, restoring: bool, exit_evt: EventFd, + iommu: bool, ) -> Result { let mut num_queues = vu_cfg.num_queues; @@ -102,6 +105,7 @@ impl Net { epoll_thread: None, seccomp_action, exit_evt, + iommu, }); } @@ -192,6 +196,7 @@ impl Net { epoll_thread: None, seccomp_action, exit_evt, + iommu, }) } @@ -248,7 +253,11 @@ impl VirtioDevice for Net { } fn features(&self) -> u64 { - self.common.avail_features + let mut features = self.common.avail_features; + if self.iommu { + features |= 1u64 << VIRTIO_F_IOMMU_PLATFORM; + } + features } fn ack_features(&mut self, value: u64) { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 8f160b993..f2675b739 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -2003,6 +2003,7 @@ impl DeviceManager { self.exit_evt .try_clone() .map_err(DeviceManagerError::EventFd)?, + self.force_iommu, ) { Ok(vub_device) => vub_device, Err(e) => { @@ -2184,6 +2185,7 @@ impl DeviceManager { self.exit_evt .try_clone() .map_err(DeviceManagerError::EventFd)?, + self.force_iommu, ) { Ok(vun_device) => vun_device, Err(e) => { @@ -2474,6 +2476,7 @@ impl DeviceManager { self.exit_evt .try_clone() .map_err(DeviceManagerError::EventFd)?, + self.force_iommu, ) .map_err(DeviceManagerError::CreateVirtioFs)?, ));