mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-01 01:15:24 +00:00
vmm: introduce platform option to limit maximum IOMMU address width
Signed-off-by: Nikolay Edigaryev <edigaryev@gmail.com>
This commit is contained in:
parent
fa686fdfc7
commit
74ca38f7a9
@ -204,7 +204,7 @@ fn create_app(default_vcpus: String, default_memory: String, default_rng: String
|
||||
.arg(
|
||||
Arg::new("platform")
|
||||
.long("platform")
|
||||
.help("num_pci_segments=<num_pci_segments>,iommu_segments=<list_of_segments>,serial_number=<dmi_device_serial_number>,uuid=<dmi_device_uuid>,oem_strings=<list_of_strings>")
|
||||
.help("num_pci_segments=<num_pci_segments>,iommu_segments=<list_of_segments>,iommu_address_width=<bits>,serial_number=<dmi_device_serial_number>,uuid=<dmi_device_uuid>,oem_strings=<list_of_strings>")
|
||||
.num_args(1)
|
||||
.group("vm-config"),
|
||||
)
|
||||
|
@ -718,6 +718,9 @@ components:
|
||||
items:
|
||||
type: integer
|
||||
format: int16
|
||||
iommu_address_width:
|
||||
type: integer
|
||||
format: uint8
|
||||
serial_number:
|
||||
type: string
|
||||
uuid:
|
||||
|
@ -21,6 +21,7 @@ use crate::landlock::LandlockAccess;
|
||||
use crate::vm_config::*;
|
||||
|
||||
const MAX_NUM_PCI_SEGMENTS: u16 = 96;
|
||||
const MAX_IOMMU_ADDRESS_WIDTH_BITS: u8 = 64;
|
||||
|
||||
/// Errors associated with VM configuration parameters.
|
||||
#[derive(Debug, Error)]
|
||||
@ -183,6 +184,8 @@ pub enum ValidationError {
|
||||
InvalidPciSegment(u16),
|
||||
/// Invalid PCI segment aperture weight
|
||||
InvalidPciSegmentApertureWeight(u32),
|
||||
/// Invalid IOMMU address width in bits
|
||||
InvalidIommuAddressWidthBits(u8),
|
||||
/// Balloon too big
|
||||
BalloonLargerThanRam(u64, u64),
|
||||
/// On a IOMMU segment but not behind IOMMU
|
||||
@ -309,6 +312,9 @@ impl fmt::Display for ValidationError {
|
||||
InvalidPciSegmentApertureWeight(aperture_weight) => {
|
||||
write!(f, "Invalid PCI segment aperture weight: {aperture_weight}")
|
||||
}
|
||||
InvalidIommuAddressWidthBits(iommu_address_width_bits) => {
|
||||
write!(f, "IOMMU address width in bits ({iommu_address_width_bits}) should be less than or equal to {MAX_IOMMU_ADDRESS_WIDTH_BITS}")
|
||||
}
|
||||
BalloonLargerThanRam(balloon_size, ram_size) => {
|
||||
write!(
|
||||
f,
|
||||
@ -817,6 +823,7 @@ impl PlatformConfig {
|
||||
parser
|
||||
.add("num_pci_segments")
|
||||
.add("iommu_segments")
|
||||
.add("iommu_address_width")
|
||||
.add("serial_number")
|
||||
.add("uuid")
|
||||
.add("oem_strings");
|
||||
@ -834,6 +841,10 @@ impl PlatformConfig {
|
||||
.convert::<IntegerList>("iommu_segments")
|
||||
.map_err(Error::ParsePlatform)?
|
||||
.map(|v| v.0.iter().map(|e| *e as u16).collect());
|
||||
let iommu_address_width_bits: u8 = parser
|
||||
.convert("iommu_address_width")
|
||||
.map_err(Error::ParsePlatform)?
|
||||
.unwrap_or(MAX_IOMMU_ADDRESS_WIDTH_BITS);
|
||||
let serial_number = parser
|
||||
.convert("serial_number")
|
||||
.map_err(Error::ParsePlatform)?;
|
||||
@ -857,6 +868,7 @@ impl PlatformConfig {
|
||||
Ok(PlatformConfig {
|
||||
num_pci_segments,
|
||||
iommu_segments,
|
||||
iommu_address_width_bits,
|
||||
serial_number,
|
||||
uuid,
|
||||
oem_strings,
|
||||
@ -882,6 +894,12 @@ impl PlatformConfig {
|
||||
}
|
||||
}
|
||||
|
||||
if self.iommu_address_width_bits > MAX_IOMMU_ADDRESS_WIDTH_BITS {
|
||||
return Err(ValidationError::InvalidIommuAddressWidthBits(
|
||||
self.iommu_address_width_bits,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -3998,6 +4016,7 @@ mod tests {
|
||||
PlatformConfig {
|
||||
num_pci_segments: MAX_NUM_PCI_SEGMENTS,
|
||||
iommu_segments: None,
|
||||
iommu_address_width_bits: MAX_IOMMU_ADDRESS_WIDTH_BITS,
|
||||
serial_number: None,
|
||||
uuid: None,
|
||||
oem_strings: None,
|
||||
@ -4296,6 +4315,18 @@ mod tests {
|
||||
Err(ValidationError::InvalidPciSegment(MAX_NUM_PCI_SEGMENTS + 1))
|
||||
);
|
||||
|
||||
let mut invalid_config = valid_config.clone();
|
||||
invalid_config.platform = Some(PlatformConfig {
|
||||
iommu_address_width_bits: MAX_IOMMU_ADDRESS_WIDTH_BITS + 1,
|
||||
..platform_fixture()
|
||||
});
|
||||
assert_eq!(
|
||||
invalid_config.validate(),
|
||||
Err(ValidationError::InvalidIommuAddressWidthBits(
|
||||
MAX_IOMMU_ADDRESS_WIDTH_BITS + 1
|
||||
))
|
||||
);
|
||||
|
||||
let mut still_valid_config = valid_config.clone();
|
||||
still_valid_config.platform = Some(PlatformConfig {
|
||||
iommu_segments: Some(vec![1, 2, 3]),
|
||||
|
@ -88,12 +88,19 @@ pub fn default_platformconfig_num_pci_segments() -> u16 {
|
||||
DEFAULT_NUM_PCI_SEGMENTS
|
||||
}
|
||||
|
||||
pub const DEFAULT_IOMMU_ADDRESS_WIDTH_BITS: u8 = 64;
|
||||
pub fn default_platformconfig_iommu_address_width_bits() -> u8 {
|
||||
DEFAULT_IOMMU_ADDRESS_WIDTH_BITS
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub struct PlatformConfig {
|
||||
#[serde(default = "default_platformconfig_num_pci_segments")]
|
||||
pub num_pci_segments: u16,
|
||||
#[serde(default)]
|
||||
pub iommu_segments: Option<Vec<u16>>,
|
||||
#[serde(default = "default_platformconfig_iommu_address_width_bits")]
|
||||
pub iommu_address_width_bits: u8,
|
||||
#[serde(default)]
|
||||
pub serial_number: Option<String>,
|
||||
#[serde(default)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user