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::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<thread::JoinHandle<()>>,
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<Blk> {
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) {

View File

@ -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<GuestMemoryAtomic<GuestMemoryMmap>>,
epoll_thread: Option<thread::JoinHandle<()>>,
exit_evt: EventFd,
iommu: bool,
}
impl Fs {
@ -316,6 +317,7 @@ impl Fs {
seccomp_action: SeccompAction,
restoring: bool,
exit_evt: EventFd,
iommu: bool,
) -> Result<Fs> {
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) {

View File

@ -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<thread::JoinHandle<()>>,
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<Net> {
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) {

View File

@ -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)?,
));