diff --git a/src/main.rs b/src/main.rs index 33d34aac8..1571d1fb7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -155,7 +155,7 @@ fn create_app<'a>( Arg::new("platform") .long("platform") .help( - "num_pci_segments=", + "num_pci_segments=,iommu_segments=", ) .takes_value(true) .group("vm-config"), diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 6616f2bd7..0185ea689 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -539,19 +539,29 @@ fn default_platformconfig_num_pci_segments() -> u16 { pub struct PlatformConfig { #[serde(default = "default_platformconfig_num_pci_segments")] pub num_pci_segments: u16, + #[serde(default)] + pub iommu_segments: Option>, } impl PlatformConfig { pub fn parse(platform: &str) -> Result { let mut parser = OptionParser::new(); parser.add("num_pci_segments"); - parser.parse(platform).map_err(Error::ParseCpus)?; + parser.add("iommu_segments"); + parser.parse(platform).map_err(Error::ParsePlatform)?; let num_pci_segments: u16 = parser .convert("num_pci_segments") .map_err(Error::ParsePlatform)? .unwrap_or(DEFAULT_NUM_PCI_SEGMENTS); - Ok(PlatformConfig { num_pci_segments }) + let iommu_segments = parser + .convert::("iommu_segments") + .map_err(Error::ParsePlatform)? + .map(|v| v.0.iter().map(|e| *e as u16).collect()); + Ok(PlatformConfig { + num_pci_segments, + iommu_segments, + }) } pub fn validate(&self) -> ValidationResult<()> { @@ -561,6 +571,14 @@ impl PlatformConfig { )); } + if let Some(iommu_segments) = &self.iommu_segments { + for segment in iommu_segments { + if *segment >= self.num_pci_segments { + return Err(ValidationError::InvalidPciSegment(*segment)); + } + } + } + Ok(()) } } @@ -569,6 +587,7 @@ impl Default for PlatformConfig { fn default() -> Self { PlatformConfig { num_pci_segments: DEFAULT_NUM_PCI_SEGMENTS, + iommu_segments: None, } } } @@ -2336,6 +2355,11 @@ impl VmConfig { } 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; @@ -3140,12 +3164,28 @@ mod tests { let mut still_valid_config = valid_config.clone(); still_valid_config.platform = Some(PlatformConfig { num_pci_segments: 16, + ..Default::default() + }); + assert!(still_valid_config.validate().is_ok()); + + let mut invalid_config = valid_config.clone(); + invalid_config.platform = Some(PlatformConfig { + num_pci_segments: 17, + ..Default::default() + }); + assert!(invalid_config.validate().is_err()); + + let mut still_valid_config = valid_config.clone(); + still_valid_config.platform = Some(PlatformConfig { + num_pci_segments: 16, + iommu_segments: Some(vec![1, 2, 3]), }); assert!(still_valid_config.validate().is_ok()); let mut invalid_config = valid_config; invalid_config.platform = Some(PlatformConfig { - num_pci_segments: 17, + num_pci_segments: 16, + iommu_segments: Some(vec![17, 18]), }); assert!(invalid_config.validate().is_err()); }