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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-03-29 21:27:05 +02:00
parent d310abed44
commit 3c973fa7ce
4 changed files with 34 additions and 6 deletions

View File

@ -7,8 +7,8 @@ use super::{Error, Result, DEFAULT_VIRTIO_FEATURES};
use crate::seccomp_filters::Thread; use crate::seccomp_filters::Thread;
use crate::thread_helper::spawn_virtio_thread; use crate::thread_helper::spawn_virtio_thread;
use crate::vhost_user::VhostUserCommon; use crate::vhost_user::VhostUserCommon;
use crate::VirtioInterrupt;
use crate::{GuestMemoryMmap, GuestRegionMmap}; use crate::{GuestMemoryMmap, GuestRegionMmap};
use crate::{VirtioInterrupt, VIRTIO_F_IOMMU_PLATFORM};
use block_util::VirtioBlockConfig; use block_util::VirtioBlockConfig;
use seccompiler::SeccompAction; use seccompiler::SeccompAction;
use std::mem; use std::mem;
@ -61,6 +61,7 @@ pub struct Blk {
epoll_thread: Option<thread::JoinHandle<()>>, epoll_thread: Option<thread::JoinHandle<()>>,
seccomp_action: SeccompAction, seccomp_action: SeccompAction,
exit_evt: EventFd, exit_evt: EventFd,
iommu: bool,
} }
impl Blk { impl Blk {
@ -71,6 +72,7 @@ impl Blk {
restoring: bool, restoring: bool,
seccomp_action: SeccompAction, seccomp_action: SeccompAction,
exit_evt: EventFd, exit_evt: EventFd,
iommu: bool,
) -> Result<Blk> { ) -> Result<Blk> {
let num_queues = vu_cfg.num_queues; let num_queues = vu_cfg.num_queues;
@ -97,6 +99,7 @@ impl Blk {
epoll_thread: None, epoll_thread: None,
seccomp_action, seccomp_action,
exit_evt, exit_evt,
iommu,
}); });
} }
@ -189,6 +192,7 @@ impl Blk {
epoll_thread: None, epoll_thread: None,
seccomp_action, seccomp_action,
exit_evt, exit_evt,
iommu,
}) })
} }
@ -241,7 +245,11 @@ impl VirtioDevice for Blk {
} }
fn features(&self) -> u64 { 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) { fn ack_features(&mut self, value: u64) {

View File

@ -8,7 +8,7 @@ use crate::thread_helper::spawn_virtio_thread;
use crate::vhost_user::VhostUserCommon; use crate::vhost_user::VhostUserCommon;
use crate::{ use crate::{
ActivateError, ActivateResult, UserspaceMapping, VirtioCommon, VirtioDevice, VirtioDeviceType, ActivateError, ActivateResult, UserspaceMapping, VirtioCommon, VirtioDevice, VirtioDeviceType,
VirtioInterrupt, VirtioSharedMemoryList, VirtioInterrupt, VirtioSharedMemoryList, VIRTIO_F_IOMMU_PLATFORM,
}; };
use crate::{GuestMemoryMmap, GuestRegionMmap, MmapRegion}; use crate::{GuestMemoryMmap, GuestRegionMmap, MmapRegion};
use libc::{self, c_void, off64_t, pread64, pwrite64}; use libc::{self, c_void, off64_t, pread64, pwrite64};
@ -301,6 +301,7 @@ pub struct Fs {
guest_memory: Option<GuestMemoryAtomic<GuestMemoryMmap>>, guest_memory: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
epoll_thread: Option<thread::JoinHandle<()>>, epoll_thread: Option<thread::JoinHandle<()>>,
exit_evt: EventFd, exit_evt: EventFd,
iommu: bool,
} }
impl Fs { impl Fs {
@ -316,6 +317,7 @@ impl Fs {
seccomp_action: SeccompAction, seccomp_action: SeccompAction,
restoring: bool, restoring: bool,
exit_evt: EventFd, exit_evt: EventFd,
iommu: bool,
) -> Result<Fs> { ) -> Result<Fs> {
let mut slave_req_support = false; let mut slave_req_support = false;
@ -347,6 +349,7 @@ impl Fs {
guest_memory: None, guest_memory: None,
epoll_thread: None, epoll_thread: None,
exit_evt, exit_evt,
iommu,
}); });
} }
@ -428,6 +431,7 @@ impl Fs {
guest_memory: None, guest_memory: None,
epoll_thread: None, epoll_thread: None,
exit_evt, exit_evt,
iommu,
}) })
} }
@ -481,7 +485,11 @@ impl VirtioDevice for Fs {
} }
fn features(&self) -> u64 { 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) { fn ack_features(&mut self, value: u64) {

View File

@ -7,7 +7,7 @@ use crate::vhost_user::vu_common_ctrl::{VhostUserConfig, VhostUserHandle};
use crate::vhost_user::{Error, Result, VhostUserCommon}; use crate::vhost_user::{Error, Result, VhostUserCommon};
use crate::{ use crate::{
ActivateResult, NetCtrlEpollHandler, VirtioCommon, VirtioDevice, VirtioDeviceType, 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 crate::{GuestMemoryMmap, GuestRegionMmap};
use net_util::{build_net_config_space, CtrlQueue, MacAddr, VirtioNetConfig}; use net_util::{build_net_config_space, CtrlQueue, MacAddr, VirtioNetConfig};
@ -61,10 +61,12 @@ pub struct Net {
epoll_thread: Option<thread::JoinHandle<()>>, epoll_thread: Option<thread::JoinHandle<()>>,
seccomp_action: SeccompAction, seccomp_action: SeccompAction,
exit_evt: EventFd, exit_evt: EventFd,
iommu: bool,
} }
impl Net { impl Net {
/// Create a new vhost-user-net device /// Create a new vhost-user-net device
#[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
id: String, id: String,
mac_addr: MacAddr, mac_addr: MacAddr,
@ -73,6 +75,7 @@ impl Net {
seccomp_action: SeccompAction, seccomp_action: SeccompAction,
restoring: bool, restoring: bool,
exit_evt: EventFd, exit_evt: EventFd,
iommu: bool,
) -> Result<Net> { ) -> Result<Net> {
let mut num_queues = vu_cfg.num_queues; let mut num_queues = vu_cfg.num_queues;
@ -102,6 +105,7 @@ impl Net {
epoll_thread: None, epoll_thread: None,
seccomp_action, seccomp_action,
exit_evt, exit_evt,
iommu,
}); });
} }
@ -192,6 +196,7 @@ impl Net {
epoll_thread: None, epoll_thread: None,
seccomp_action, seccomp_action,
exit_evt, exit_evt,
iommu,
}) })
} }
@ -248,7 +253,11 @@ impl VirtioDevice for Net {
} }
fn features(&self) -> u64 { 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) { fn ack_features(&mut self, value: u64) {

View File

@ -2003,6 +2003,7 @@ impl DeviceManager {
self.exit_evt self.exit_evt
.try_clone() .try_clone()
.map_err(DeviceManagerError::EventFd)?, .map_err(DeviceManagerError::EventFd)?,
self.force_iommu,
) { ) {
Ok(vub_device) => vub_device, Ok(vub_device) => vub_device,
Err(e) => { Err(e) => {
@ -2184,6 +2185,7 @@ impl DeviceManager {
self.exit_evt self.exit_evt
.try_clone() .try_clone()
.map_err(DeviceManagerError::EventFd)?, .map_err(DeviceManagerError::EventFd)?,
self.force_iommu,
) { ) {
Ok(vun_device) => vun_device, Ok(vun_device) => vun_device,
Err(e) => { Err(e) => {
@ -2474,6 +2476,7 @@ impl DeviceManager {
self.exit_evt self.exit_evt
.try_clone() .try_clone()
.map_err(DeviceManagerError::EventFd)?, .map_err(DeviceManagerError::EventFd)?,
self.force_iommu,
) )
.map_err(DeviceManagerError::CreateVirtioFs)?, .map_err(DeviceManagerError::CreateVirtioFs)?,
)); ));