From 7cfeefde57bb44066a45ca46ef4ee6a2fb108665 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 12 Oct 2021 11:30:54 +0100 Subject: [PATCH] vmm: Add validation logic to check user specified pci_segment is valid Signed-off-by: Rob Bradford --- vmm/src/config.rs | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 32f48fbc0..8cca3d060 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -156,6 +156,8 @@ pub enum ValidationError { MemoryZoneReused(String, u32, u32), /// Invalid number of PCI segments InvalidNumPciSegments(u16), + /// Invalid PCI segment id + InvalidPciSegment(u16), } type ValidationResult = std::result::Result; @@ -220,6 +222,9 @@ impl fmt::Display for ValidationError { n, MAX_NUM_PCI_SEGMENTS ) } + InvalidPciSegment(pci_segment) => { + write!(f, "Invalid PCI segment id{}", pci_segment) + } } } } @@ -1011,6 +1016,12 @@ impl DiskConfig { return Err(ValidationError::TooManyQueues); } + if let Some(platform_config) = vm_config.platform.as_ref() { + if self.pci_segment >= platform_config.num_pci_segments { + return Err(ValidationError::InvalidPciSegment(self.pci_segment)); + } + } + Ok(()) } } @@ -1295,6 +1306,12 @@ impl NetConfig { return Err(ValidationError::TooManyQueues); } + if let Some(platform_config) = vm_config.platform.as_ref() { + if self.pci_segment >= platform_config.num_pci_segments { + return Err(ValidationError::InvalidPciSegment(self.pci_segment)); + } + } + Ok(()) } } @@ -1493,6 +1510,12 @@ impl FsConfig { return Err(ValidationError::TooManyQueues); } + if let Some(platform_config) = vm_config.platform.as_ref() { + if self.pci_segment >= platform_config.num_pci_segments { + return Err(ValidationError::InvalidPciSegment(self.pci_segment)); + } + } + Ok(()) } } @@ -1566,6 +1589,16 @@ impl PmemConfig { pci_segment, }) } + + pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> { + if let Some(platform_config) = vm_config.platform.as_ref() { + if self.pci_segment >= platform_config.num_pci_segments { + return Err(ValidationError::InvalidPciSegment(self.pci_segment)); + } + } + + Ok(()) + } } #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] @@ -1688,6 +1721,16 @@ impl DeviceConfig { pci_segment, }) } + + pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> { + if let Some(platform_config) = vm_config.platform.as_ref() { + if self.pci_segment >= platform_config.num_pci_segments { + return Err(ValidationError::InvalidPciSegment(self.pci_segment)); + } + } + + Ok(()) + } } #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Default)] @@ -1723,6 +1766,16 @@ impl UserDeviceConfig { pci_segment, }) } + + pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> { + if let Some(platform_config) = vm_config.platform.as_ref() { + if self.pci_segment >= platform_config.num_pci_segments { + return Err(ValidationError::InvalidPciSegment(self.pci_segment)); + } + } + + Ok(()) + } } #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Default)] pub struct VsockConfig { @@ -1776,6 +1829,16 @@ impl VsockConfig { pci_segment, }) } + + pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> { + if let Some(platform_config) = vm_config.platform.as_ref() { + if self.pci_segment >= platform_config.num_pci_segments { + return Err(ValidationError::InvalidPciSegment(self.pci_segment)); + } + } + + Ok(()) + } } #[cfg(feature = "tdx")] @@ -2050,6 +2113,12 @@ impl VmConfig { } } + if let Some(pmems) = &self.pmem { + for pmem in pmems { + pmem.validate(self)?; + } + } + if let Some(t) = &self.cpus.topology { if t.threads_per_core == 0 || t.cores_per_die == 0 @@ -2078,6 +2147,20 @@ impl VmConfig { if !user_devices.is_empty() && !self.memory.shared { return Err(ValidationError::UserDevicesRequireSharedMemory); } + + for user_device in user_devices { + user_device.validate(self)?; + } + } + + if let Some(devices) = &self.devices { + for device in devices { + device.validate(self)?; + } + } + + if let Some(vsock) = &self.vsock { + vsock.validate(self)?; } if let Some(numa) = &self.numa {