vmm: Add validation logic to check user specified pci_segment is valid

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-10-12 11:30:54 +01:00
parent f71f6da907
commit 7cfeefde57

View File

@ -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<T> = std::result::Result<T, ValidationError>;
@ -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 {