From 79f4c2db01e32c7d7637c31a704b13eb44a34822 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 26 Apr 2022 10:56:15 +0100 Subject: [PATCH] vmm: Enable virtio-iommu in VmConfig::validate() This means that the automatic enabling of the virtio-iommu will also be applied to VMs creates via the API as well as the CLI. Fixes: #4016 Signed-off-by: Rob Bradford --- vmm/src/config.rs | 54 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/vmm/src/config.rs b/vmm/src/config.rs index c3a9c9d8a..78c37f468 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -2323,7 +2323,8 @@ pub struct VmConfig { } impl VmConfig { - pub fn validate(&self) -> ValidationResult<()> { + // Also enables virtio-iommu if the config needs it + pub fn validate(&mut self) -> ValidationResult<()> { #[cfg(not(feature = "tdx"))] self.kernel.as_ref().ok_or(ValidationError::KernelMissing)?; @@ -2367,6 +2368,7 @@ impl VmConfig { return Err(ValidationError::VhostUserMissingSocket); } disk.validate(self)?; + self.iommu |= disk.iommu; } } @@ -2376,6 +2378,7 @@ impl VmConfig { return Err(ValidationError::VhostUserRequiresSharedMemory); } net.validate(self)?; + self.iommu |= net.iommu; } } @@ -2391,9 +2394,13 @@ impl VmConfig { if let Some(pmems) = &self.pmem { for pmem in pmems { pmem.validate(self)?; + self.iommu |= pmem.iommu; } } + self.iommu |= self.rng.iommu; + self.iommu |= self.console.iommu; + if let Some(t) = &self.cpus.topology { if t.threads_per_core == 0 || t.cores_per_die == 0 @@ -2439,6 +2446,7 @@ impl VmConfig { if let Some(vdpa_devices) = &self.vdpa { for vdpa_device in vdpa_devices { vdpa_device.validate(self)?; + self.iommu |= vdpa_device.iommu; } } @@ -2462,11 +2470,13 @@ impl VmConfig { if let Some(devices) = &self.devices { for device in devices { device.validate(self)?; + self.iommu |= device.iommu; } } if let Some(vsock) = &self.vsock { vsock.validate(self)?; + self.iommu |= vsock.iommu; } if let Some(numa) = &self.numa { @@ -2488,21 +2498,21 @@ impl VmConfig { } self.platform.as_ref().map(|p| p.validate()).transpose()?; + self.iommu |= self + .platform + .as_ref() + .map(|p| p.iommu_segments.is_some()) + .unwrap_or_default(); Ok(()) } pub fn parse(vm_params: VmParams) -> Result { - let mut iommu = false; - let mut disks: Option> = None; if let Some(disk_list) = &vm_params.disks { let mut disk_config_list = Vec::new(); for item in disk_list.iter() { let disk_config = DiskConfig::parse(item)?; - if disk_config.iommu { - iommu = true; - } disk_config_list.push(disk_config); } disks = Some(disk_config_list); @@ -2513,18 +2523,12 @@ impl VmConfig { let mut net_config_list = Vec::new(); for item in net_list.iter() { let net_config = NetConfig::parse(item)?; - if net_config.iommu { - iommu = true; - } net_config_list.push(net_config); } net = Some(net_config_list); } let rng = RngConfig::parse(vm_params.rng)?; - if rng.iommu { - iommu = true; - } let mut balloon: Option = None; if let Some(balloon_params) = &vm_params.balloon { @@ -2545,18 +2549,12 @@ impl VmConfig { let mut pmem_config_list = Vec::new(); for item in pmem_list.iter() { let pmem_config = PmemConfig::parse(item)?; - if pmem_config.iommu { - iommu = true; - } pmem_config_list.push(pmem_config); } pmem = Some(pmem_config_list); } let console = ConsoleConfig::parse(vm_params.console)?; - if console.iommu { - iommu = true; - } let serial = ConsoleConfig::parse(vm_params.serial)?; let mut devices: Option> = None; @@ -2564,9 +2562,6 @@ impl VmConfig { let mut device_config_list = Vec::new(); for item in device_list.iter() { let device_config = DeviceConfig::parse(item)?; - if device_config.iommu { - iommu = true; - } device_config_list.push(device_config); } devices = Some(device_config_list); @@ -2587,9 +2582,6 @@ impl VmConfig { let mut vdpa_config_list = Vec::new(); for item in vdpa_list.iter() { let vdpa_config = VdpaConfig::parse(item)?; - if vdpa_config.iommu { - iommu = true; - } vdpa_config_list.push(vdpa_config); } vdpa = Some(vdpa_config_list); @@ -2598,18 +2590,10 @@ impl VmConfig { let mut vsock: Option = None; if let Some(vs) = &vm_params.vsock { let vsock_config = VsockConfig::parse(vs)?; - if vsock_config.iommu { - iommu = true; - } vsock = Some(vsock_config); } let platform = vm_params.platform.map(PlatformConfig::parse).transpose()?; - if let Some(platform_config) = platform.as_ref() { - if platform_config.iommu_segments.is_some() { - iommu = true; - } - } #[cfg(target_arch = "x86_64")] let mut sgx_epc: Option> = None; @@ -2655,7 +2639,7 @@ impl VmConfig { #[cfg(feature = "gdb")] let gdb = vm_params.gdb; - let config = VmConfig { + let mut config = VmConfig { cpus: CpusConfig::parse(vm_params.cpus)?, memory: MemoryConfig::parse(vm_params.memory, vm_params.memory_zones)?, kernel, @@ -2673,7 +2657,7 @@ impl VmConfig { user_devices, vdpa, vsock, - iommu, + iommu: false, // updated in VmConfig::validate() #[cfg(target_arch = "x86_64")] sgx_epc, numa, @@ -3269,7 +3253,7 @@ mod tests { #[test] fn test_config_validation() { - let valid_config = VmConfig { + let mut valid_config = VmConfig { cpus: CpusConfig { boot_vcpus: 1, max_vcpus: 1,