mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-06-30 23:12:36 +00:00
vmm: config: Reject VFIO devices with the same path
By checking in the validation logic we get checking for both devices specified in the initial config but also hotplug too. Fixes: #4453 Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
3c26e9b741
commit
6bc46ba9c1
|
@ -175,6 +175,8 @@ pub enum ValidationError {
|
||||||
InvalidIdentifier(String),
|
InvalidIdentifier(String),
|
||||||
/// Placing the device behind a virtual IOMMU is not supported
|
/// Placing the device behind a virtual IOMMU is not supported
|
||||||
IommuNotSupported,
|
IommuNotSupported,
|
||||||
|
/// Duplicated device path (device added twice)
|
||||||
|
DuplicateDevicePath(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidationResult<T> = std::result::Result<T, ValidationError>;
|
type ValidationResult<T> = std::result::Result<T, ValidationError>;
|
||||||
|
@ -270,6 +272,7 @@ impl fmt::Display for ValidationError {
|
||||||
IommuNotSupported => {
|
IommuNotSupported => {
|
||||||
write!(f, "Device does not support being placed behind IOMMU")
|
write!(f, "Device does not support being placed behind IOMMU")
|
||||||
}
|
}
|
||||||
|
DuplicateDevicePath(p) => write!(f, "Duplicated device path: {}", p),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2464,7 +2467,14 @@ impl VmConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(devices) = &self.devices {
|
if let Some(devices) = &self.devices {
|
||||||
|
let mut device_paths = BTreeSet::new();
|
||||||
for device in devices {
|
for device in devices {
|
||||||
|
if !device_paths.insert(device.path.to_string_lossy()) {
|
||||||
|
return Err(ValidationError::DuplicateDevicePath(
|
||||||
|
device.path.to_string_lossy().to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
device.validate(self)?;
|
device.validate(self)?;
|
||||||
self.iommu |= device.iommu;
|
self.iommu |= device.iommu;
|
||||||
|
|
||||||
|
@ -3657,7 +3667,7 @@ mod tests {
|
||||||
Err(ValidationError::OnIommuSegment(1))
|
Err(ValidationError::OnIommuSegment(1))
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut invalid_config = valid_config;
|
let mut invalid_config = valid_config.clone();
|
||||||
invalid_config.memory.shared = true;
|
invalid_config.memory.shared = true;
|
||||||
invalid_config.platform = Some(PlatformConfig {
|
invalid_config.platform = Some(PlatformConfig {
|
||||||
num_pci_segments: 16,
|
num_pci_segments: 16,
|
||||||
|
@ -3672,5 +3682,31 @@ mod tests {
|
||||||
invalid_config.validate(),
|
invalid_config.validate(),
|
||||||
Err(ValidationError::IommuNotSupportedOnSegment(1))
|
Err(ValidationError::IommuNotSupportedOnSegment(1))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut still_valid_config = valid_config.clone();
|
||||||
|
still_valid_config.devices = Some(vec![
|
||||||
|
DeviceConfig {
|
||||||
|
path: "/device1".into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
DeviceConfig {
|
||||||
|
path: "/device2".into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
assert!(still_valid_config.validate().is_ok());
|
||||||
|
|
||||||
|
let mut invalid_config = valid_config;
|
||||||
|
invalid_config.devices = Some(vec![
|
||||||
|
DeviceConfig {
|
||||||
|
path: "/device1".into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
DeviceConfig {
|
||||||
|
path: "/device1".into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
assert!(invalid_config.validate().is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user