From 9e6c817192c412264d1dbad6551dbb3d3a426ccd Mon Sep 17 00:00:00 2001 From: Ruben Hakobyan Date: Tue, 2 Jun 2026 17:10:28 -0700 Subject: [PATCH] virtio-devices: add VIRTIO_F_ACCESS_PLATFORM to watchdog and iommu A confidential guest (e.g. SEV-SNP) requires every virtio device to advertise VIRTIO_F_ACCESS_PLATFORM so the guest driver routes DMA through the platform's bounce-buffer path; the driver refuses a device that does not offer it. Add VIRTIO_F_ACCESS_PLATFORM support to virtio-{watchdog,iommu} which are exercised as part of the CVM integration tests. Assisted-by: Claude:Opus-4.8 Signed-off-by: Ruben Hakobyan --- fuzz/fuzz_targets/iommu.rs | 1 + fuzz/fuzz_targets/watchdog.rs | 1 + virtio-devices/src/iommu.rs | 8 +++++++- virtio-devices/src/watchdog.rs | 11 ++++++++--- vmm/src/device_manager.rs | 2 ++ 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/fuzz/fuzz_targets/iommu.rs b/fuzz/fuzz_targets/iommu.rs index 11600a36a..77180df05 100644 --- a/fuzz/fuzz_targets/iommu.rs +++ b/fuzz/fuzz_targets/iommu.rs @@ -67,6 +67,7 @@ fuzz_target!(|bytes: &[u8]| -> Corpus { EventFd::new(EFD_NONBLOCK).unwrap(), ((MEM_SIZE - IOVA_SPACE_SIZE) as u64, (MEM_SIZE - 1) as u64), 64, + false, None, ) .unwrap(); diff --git a/fuzz/fuzz_targets/watchdog.rs b/fuzz/fuzz_targets/watchdog.rs index 60f4afab5..c3fd610b7 100644 --- a/fuzz/fuzz_targets/watchdog.rs +++ b/fuzz/fuzz_targets/watchdog.rs @@ -37,6 +37,7 @@ fuzz_target!(|bytes: &[u8]| -> Corpus { let mut watchdog = virtio_devices::Watchdog::new( "fuzzer_watchdog".to_owned(), + false, EventFd::new(EFD_NONBLOCK).unwrap(), SeccompAction::Allow, EventFd::new(EFD_NONBLOCK).unwrap(), diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index 9780f14c0..8eb316b9a 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -27,7 +27,8 @@ use vmm_sys_util::eventfd::EventFd; use super::{ ActivateResult, EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, EpollHelperHandler, - Error as DeviceError, VIRTIO_F_VERSION_1, VirtioCommon, VirtioDevice, VirtioDeviceType, + Error as DeviceError, VIRTIO_F_ACCESS_PLATFORM, VIRTIO_F_VERSION_1, VirtioCommon, VirtioDevice, + VirtioDeviceType, }; use crate::seccomp_filters::Thread; use crate::{DmaRemapping, GuestMemoryMmap, VirtioInterrupt, VirtioInterruptType}; @@ -1117,6 +1118,7 @@ impl Iommu { exit_evt: EventFd, msi_iova_space: (u64, u64), address_width_bits: u8, + access_platform_enabled: bool, state: Option, ) -> io::Result<(Self, Arc)> { let (mut avail_features, acked_features, endpoints, domains, paused) = @@ -1165,6 +1167,10 @@ impl Iommu { None }; + if access_platform_enabled { + avail_features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; + } + let mapping = Arc::new(IommuMapping { endpoints: Arc::new(RwLock::new(endpoints)), domains: Arc::new(RwLock::new(domains)), diff --git a/virtio-devices/src/watchdog.rs b/virtio-devices/src/watchdog.rs index 8c40d4ee2..45922c9eb 100644 --- a/virtio-devices/src/watchdog.rs +++ b/virtio-devices/src/watchdog.rs @@ -27,8 +27,8 @@ use vmm_sys_util::eventfd::EventFd; use super::{ ActivateError, ActivateResult, EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, - EpollHelperHandler, Error as DeviceError, VIRTIO_F_VERSION_1, VirtioCommon, VirtioDevice, - VirtioDeviceType, + EpollHelperHandler, Error as DeviceError, VIRTIO_F_ACCESS_PLATFORM, VIRTIO_F_VERSION_1, + VirtioCommon, VirtioDevice, VirtioDeviceType, }; use crate::seccomp_filters::Thread; use crate::{GuestMemoryMmap, VirtioInterrupt, VirtioInterruptType}; @@ -208,6 +208,7 @@ impl Watchdog { /// Create a new virtio watchdog device that will reboot VM if the guest hangs pub fn new( id: String, + access_platform_enabled: bool, reset_evt: EventFd, seccomp_action: SeccompAction, exit_evt: EventFd, @@ -226,7 +227,11 @@ impl Watchdog { (state.avail_features, state.acked_features, true) } else { - (1u64 << VIRTIO_F_VERSION_1, 0, false) + let mut avail_features = 1u64 << VIRTIO_F_VERSION_1; + if access_platform_enabled { + avail_features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; + } + (avail_features, 0, false) }; let timer_fd = timerfd_create().map_err(|e| { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 7c52b7ec3..25c769854 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1673,6 +1673,7 @@ impl DeviceManager { .map_err(DeviceManagerError::EventFd)?, self.get_msi_iova_space(), iommu_address_width_bits, + self.force_access_platform, state_from_id(snapshot, iommu_id.as_str()) .map_err(DeviceManagerError::RestoreGetState)?, ) @@ -3728,6 +3729,7 @@ impl DeviceManager { let virtio_watchdog_device = Arc::new(Mutex::new( virtio_devices::Watchdog::new( id.clone(), + self.force_access_platform, self.reset_evt.try_clone().unwrap(), self.seccomp_action.clone(), self.exit_evt