vmm: Validate vhost-user-block/net are not configured with iommu=on

Extend the validate() function for both DiskConfig and NetConfig so that
we return an error if a vhost-user-block or vhost-user-net device is
expected to be placed behind the virtual IOMMU. Since these devices
don't support this feature, we can't allow iommu to be set to true in
these cases.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-05-05 11:00:07 +02:00
parent 1108bd1967
commit 54f39aa8cb

View File

@ -169,11 +169,13 @@ pub enum ValidationError {
/// On a IOMMU segment but not behind IOMMU /// On a IOMMU segment but not behind IOMMU
OnIommuSegment(u16), OnIommuSegment(u16),
// On a IOMMU segment but IOMMU not suported // On a IOMMU segment but IOMMU not suported
IommuNotSupported(u16), IommuNotSupportedOnSegment(u16),
// Identifier is not unique // Identifier is not unique
IdentifierNotUnique(String), IdentifierNotUnique(String),
/// Invalid identifier /// Invalid identifier
InvalidIdentifier(String), InvalidIdentifier(String),
/// Placing the device behind a virtual IOMMU is not supported
IommuNotSupported,
} }
type ValidationResult<T> = std::result::Result<T, ValidationError>; type ValidationResult<T> = std::result::Result<T, ValidationError>;
@ -253,10 +255,10 @@ impl fmt::Display for ValidationError {
pci_segment pci_segment
) )
} }
IommuNotSupported(pci_segment) => { IommuNotSupportedOnSegment(pci_segment) => {
write!( write!(
f, f,
"Device is on an IOMMU PCI segment ({}) but does support being placed behind IOMMU", "Device is on an IOMMU PCI segment ({}) but does not support being placed behind IOMMU",
pci_segment pci_segment
) )
} }
@ -266,6 +268,9 @@ impl fmt::Display for ValidationError {
InvalidIdentifier(s) => { InvalidIdentifier(s) => {
write!(f, "Identifier {} is invalid", s) write!(f, "Identifier {} is invalid", s)
} }
IommuNotSupported => {
write!(f, "Device does not support being placed behind IOMMU")
}
} }
} }
} }
@ -1157,6 +1162,10 @@ impl DiskConfig {
return Err(ValidationError::TooManyQueues); return Err(ValidationError::TooManyQueues);
} }
if self.vhost_user && self.iommu {
return Err(ValidationError::IommuNotSupported);
}
if let Some(platform_config) = vm_config.platform.as_ref() { if let Some(platform_config) = vm_config.platform.as_ref() {
if self.pci_segment >= platform_config.num_pci_segments { if self.pci_segment >= platform_config.num_pci_segments {
return Err(ValidationError::InvalidPciSegment(self.pci_segment)); return Err(ValidationError::InvalidPciSegment(self.pci_segment));
@ -1453,6 +1462,10 @@ impl NetConfig {
return Err(ValidationError::TooManyQueues); return Err(ValidationError::TooManyQueues);
} }
if self.vhost_user && self.iommu {
return Err(ValidationError::IommuNotSupported);
}
if let Some(platform_config) = vm_config.platform.as_ref() { if let Some(platform_config) = vm_config.platform.as_ref() {
if self.pci_segment >= platform_config.num_pci_segments { if self.pci_segment >= platform_config.num_pci_segments {
return Err(ValidationError::InvalidPciSegment(self.pci_segment)); return Err(ValidationError::InvalidPciSegment(self.pci_segment));
@ -1682,7 +1695,9 @@ impl FsConfig {
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() { if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
if iommu_segments.contains(&self.pci_segment) { if iommu_segments.contains(&self.pci_segment) {
return Err(ValidationError::IommuNotSupported(self.pci_segment)); return Err(ValidationError::IommuNotSupportedOnSegment(
self.pci_segment,
));
} }
} }
} }
@ -1971,7 +1986,9 @@ impl UserDeviceConfig {
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() { if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
if iommu_segments.contains(&self.pci_segment) { if iommu_segments.contains(&self.pci_segment) {
return Err(ValidationError::IommuNotSupported(self.pci_segment)); return Err(ValidationError::IommuNotSupportedOnSegment(
self.pci_segment,
));
} }
} }
} }
@ -3725,7 +3742,7 @@ mod tests {
}]); }]);
assert_eq!( assert_eq!(
invalid_config.validate(), invalid_config.validate(),
Err(ValidationError::IommuNotSupported(1)) Err(ValidationError::IommuNotSupportedOnSegment(1))
); );
let mut invalid_config = valid_config.clone(); let mut invalid_config = valid_config.clone();
@ -3756,7 +3773,7 @@ mod tests {
}]); }]);
assert_eq!( assert_eq!(
invalid_config.validate(), invalid_config.validate(),
Err(ValidationError::IommuNotSupported(1)) Err(ValidationError::IommuNotSupportedOnSegment(1))
); );
} }
} }