mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 11:22:26 +00:00
vmm: Enable virtio-iommu in VmConfig::validate()
This means that the automatic enabling of the virtio-iommu will also be applied to VMs creates via the API as well as the CLI. Fixes: #4016 Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
6df8f0bbf3
commit
79f4c2db01
@ -2323,7 +2323,8 @@ pub struct VmConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VmConfig {
|
impl VmConfig {
|
||||||
pub fn validate(&self) -> ValidationResult<()> {
|
// Also enables virtio-iommu if the config needs it
|
||||||
|
pub fn validate(&mut self) -> ValidationResult<()> {
|
||||||
#[cfg(not(feature = "tdx"))]
|
#[cfg(not(feature = "tdx"))]
|
||||||
self.kernel.as_ref().ok_or(ValidationError::KernelMissing)?;
|
self.kernel.as_ref().ok_or(ValidationError::KernelMissing)?;
|
||||||
|
|
||||||
@ -2367,6 +2368,7 @@ impl VmConfig {
|
|||||||
return Err(ValidationError::VhostUserMissingSocket);
|
return Err(ValidationError::VhostUserMissingSocket);
|
||||||
}
|
}
|
||||||
disk.validate(self)?;
|
disk.validate(self)?;
|
||||||
|
self.iommu |= disk.iommu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2376,6 +2378,7 @@ impl VmConfig {
|
|||||||
return Err(ValidationError::VhostUserRequiresSharedMemory);
|
return Err(ValidationError::VhostUserRequiresSharedMemory);
|
||||||
}
|
}
|
||||||
net.validate(self)?;
|
net.validate(self)?;
|
||||||
|
self.iommu |= net.iommu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2391,9 +2394,13 @@ impl VmConfig {
|
|||||||
if let Some(pmems) = &self.pmem {
|
if let Some(pmems) = &self.pmem {
|
||||||
for pmem in pmems {
|
for pmem in pmems {
|
||||||
pmem.validate(self)?;
|
pmem.validate(self)?;
|
||||||
|
self.iommu |= pmem.iommu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.iommu |= self.rng.iommu;
|
||||||
|
self.iommu |= self.console.iommu;
|
||||||
|
|
||||||
if let Some(t) = &self.cpus.topology {
|
if let Some(t) = &self.cpus.topology {
|
||||||
if t.threads_per_core == 0
|
if t.threads_per_core == 0
|
||||||
|| t.cores_per_die == 0
|
|| t.cores_per_die == 0
|
||||||
@ -2439,6 +2446,7 @@ impl VmConfig {
|
|||||||
if let Some(vdpa_devices) = &self.vdpa {
|
if let Some(vdpa_devices) = &self.vdpa {
|
||||||
for vdpa_device in vdpa_devices {
|
for vdpa_device in vdpa_devices {
|
||||||
vdpa_device.validate(self)?;
|
vdpa_device.validate(self)?;
|
||||||
|
self.iommu |= vdpa_device.iommu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2462,11 +2470,13 @@ impl VmConfig {
|
|||||||
if let Some(devices) = &self.devices {
|
if let Some(devices) = &self.devices {
|
||||||
for device in devices {
|
for device in devices {
|
||||||
device.validate(self)?;
|
device.validate(self)?;
|
||||||
|
self.iommu |= device.iommu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(vsock) = &self.vsock {
|
if let Some(vsock) = &self.vsock {
|
||||||
vsock.validate(self)?;
|
vsock.validate(self)?;
|
||||||
|
self.iommu |= vsock.iommu;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(numa) = &self.numa {
|
if let Some(numa) = &self.numa {
|
||||||
@ -2488,21 +2498,21 @@ impl VmConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.platform.as_ref().map(|p| p.validate()).transpose()?;
|
self.platform.as_ref().map(|p| p.validate()).transpose()?;
|
||||||
|
self.iommu |= self
|
||||||
|
.platform
|
||||||
|
.as_ref()
|
||||||
|
.map(|p| p.iommu_segments.is_some())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(vm_params: VmParams) -> Result<Self> {
|
pub fn parse(vm_params: VmParams) -> Result<Self> {
|
||||||
let mut iommu = false;
|
|
||||||
|
|
||||||
let mut disks: Option<Vec<DiskConfig>> = None;
|
let mut disks: Option<Vec<DiskConfig>> = None;
|
||||||
if let Some(disk_list) = &vm_params.disks {
|
if let Some(disk_list) = &vm_params.disks {
|
||||||
let mut disk_config_list = Vec::new();
|
let mut disk_config_list = Vec::new();
|
||||||
for item in disk_list.iter() {
|
for item in disk_list.iter() {
|
||||||
let disk_config = DiskConfig::parse(item)?;
|
let disk_config = DiskConfig::parse(item)?;
|
||||||
if disk_config.iommu {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
disk_config_list.push(disk_config);
|
disk_config_list.push(disk_config);
|
||||||
}
|
}
|
||||||
disks = Some(disk_config_list);
|
disks = Some(disk_config_list);
|
||||||
@ -2513,18 +2523,12 @@ impl VmConfig {
|
|||||||
let mut net_config_list = Vec::new();
|
let mut net_config_list = Vec::new();
|
||||||
for item in net_list.iter() {
|
for item in net_list.iter() {
|
||||||
let net_config = NetConfig::parse(item)?;
|
let net_config = NetConfig::parse(item)?;
|
||||||
if net_config.iommu {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
net_config_list.push(net_config);
|
net_config_list.push(net_config);
|
||||||
}
|
}
|
||||||
net = Some(net_config_list);
|
net = Some(net_config_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
let rng = RngConfig::parse(vm_params.rng)?;
|
let rng = RngConfig::parse(vm_params.rng)?;
|
||||||
if rng.iommu {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut balloon: Option<BalloonConfig> = None;
|
let mut balloon: Option<BalloonConfig> = None;
|
||||||
if let Some(balloon_params) = &vm_params.balloon {
|
if let Some(balloon_params) = &vm_params.balloon {
|
||||||
@ -2545,18 +2549,12 @@ impl VmConfig {
|
|||||||
let mut pmem_config_list = Vec::new();
|
let mut pmem_config_list = Vec::new();
|
||||||
for item in pmem_list.iter() {
|
for item in pmem_list.iter() {
|
||||||
let pmem_config = PmemConfig::parse(item)?;
|
let pmem_config = PmemConfig::parse(item)?;
|
||||||
if pmem_config.iommu {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
pmem_config_list.push(pmem_config);
|
pmem_config_list.push(pmem_config);
|
||||||
}
|
}
|
||||||
pmem = Some(pmem_config_list);
|
pmem = Some(pmem_config_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
let console = ConsoleConfig::parse(vm_params.console)?;
|
let console = ConsoleConfig::parse(vm_params.console)?;
|
||||||
if console.iommu {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
let serial = ConsoleConfig::parse(vm_params.serial)?;
|
let serial = ConsoleConfig::parse(vm_params.serial)?;
|
||||||
|
|
||||||
let mut devices: Option<Vec<DeviceConfig>> = None;
|
let mut devices: Option<Vec<DeviceConfig>> = None;
|
||||||
@ -2564,9 +2562,6 @@ impl VmConfig {
|
|||||||
let mut device_config_list = Vec::new();
|
let mut device_config_list = Vec::new();
|
||||||
for item in device_list.iter() {
|
for item in device_list.iter() {
|
||||||
let device_config = DeviceConfig::parse(item)?;
|
let device_config = DeviceConfig::parse(item)?;
|
||||||
if device_config.iommu {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
device_config_list.push(device_config);
|
device_config_list.push(device_config);
|
||||||
}
|
}
|
||||||
devices = Some(device_config_list);
|
devices = Some(device_config_list);
|
||||||
@ -2587,9 +2582,6 @@ impl VmConfig {
|
|||||||
let mut vdpa_config_list = Vec::new();
|
let mut vdpa_config_list = Vec::new();
|
||||||
for item in vdpa_list.iter() {
|
for item in vdpa_list.iter() {
|
||||||
let vdpa_config = VdpaConfig::parse(item)?;
|
let vdpa_config = VdpaConfig::parse(item)?;
|
||||||
if vdpa_config.iommu {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
vdpa_config_list.push(vdpa_config);
|
vdpa_config_list.push(vdpa_config);
|
||||||
}
|
}
|
||||||
vdpa = Some(vdpa_config_list);
|
vdpa = Some(vdpa_config_list);
|
||||||
@ -2598,18 +2590,10 @@ impl VmConfig {
|
|||||||
let mut vsock: Option<VsockConfig> = None;
|
let mut vsock: Option<VsockConfig> = None;
|
||||||
if let Some(vs) = &vm_params.vsock {
|
if let Some(vs) = &vm_params.vsock {
|
||||||
let vsock_config = VsockConfig::parse(vs)?;
|
let vsock_config = VsockConfig::parse(vs)?;
|
||||||
if vsock_config.iommu {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
vsock = Some(vsock_config);
|
vsock = Some(vsock_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
let platform = vm_params.platform.map(PlatformConfig::parse).transpose()?;
|
let platform = vm_params.platform.map(PlatformConfig::parse).transpose()?;
|
||||||
if let Some(platform_config) = platform.as_ref() {
|
|
||||||
if platform_config.iommu_segments.is_some() {
|
|
||||||
iommu = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let mut sgx_epc: Option<Vec<SgxEpcConfig>> = None;
|
let mut sgx_epc: Option<Vec<SgxEpcConfig>> = None;
|
||||||
@ -2655,7 +2639,7 @@ impl VmConfig {
|
|||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
let gdb = vm_params.gdb;
|
let gdb = vm_params.gdb;
|
||||||
|
|
||||||
let config = VmConfig {
|
let mut config = VmConfig {
|
||||||
cpus: CpusConfig::parse(vm_params.cpus)?,
|
cpus: CpusConfig::parse(vm_params.cpus)?,
|
||||||
memory: MemoryConfig::parse(vm_params.memory, vm_params.memory_zones)?,
|
memory: MemoryConfig::parse(vm_params.memory, vm_params.memory_zones)?,
|
||||||
kernel,
|
kernel,
|
||||||
@ -2673,7 +2657,7 @@ impl VmConfig {
|
|||||||
user_devices,
|
user_devices,
|
||||||
vdpa,
|
vdpa,
|
||||||
vsock,
|
vsock,
|
||||||
iommu,
|
iommu: false, // updated in VmConfig::validate()
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
sgx_epc,
|
sgx_epc,
|
||||||
numa,
|
numa,
|
||||||
@ -3269,7 +3253,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_config_validation() {
|
fn test_config_validation() {
|
||||||
let valid_config = VmConfig {
|
let mut valid_config = VmConfig {
|
||||||
cpus: CpusConfig {
|
cpus: CpusConfig {
|
||||||
boot_vcpus: 1,
|
boot_vcpus: 1,
|
||||||
max_vcpus: 1,
|
max_vcpus: 1,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user