vmm: Add iommu parameter to VdpaConfig

Add a new iommu parameter to VdpaConfig in order to place the vDPA
device behind a virtual IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-04-04 11:29:54 +02:00
parent e9b1ad9558
commit e76a5969e8
3 changed files with 23 additions and 4 deletions

View File

@ -965,6 +965,9 @@ components:
num_queues:
type: integer
default: 1
iommu:
type: boolean
default: false
pci_segment:
type: integer
format: int16

View File

@ -1964,6 +1964,8 @@ pub struct VdpaConfig {
#[serde(default = "default_vdpaconfig_num_queues")]
pub num_queues: usize,
#[serde(default)]
pub iommu: bool,
#[serde(default)]
pub id: Option<String>,
#[serde(default)]
pub pci_segment: u16,
@ -1982,6 +1984,7 @@ impl VdpaConfig {
parser
.add("path")
.add("num_queues")
.add("iommu")
.add("id")
.add("pci_segment");
parser.parse(vdpa).map_err(Error::ParseVdpa)?;
@ -1994,6 +1997,11 @@ impl VdpaConfig {
.convert("num_queues")
.map_err(Error::ParseVdpa)?
.unwrap_or_else(default_vdpaconfig_num_queues);
let iommu = parser
.convert::<Toggle>("iommu")
.map_err(Error::ParseVdpa)?
.unwrap_or(Toggle(false))
.0;
let id = parser.get("id");
let pci_segment = parser
.convert("pci_segment")
@ -2003,6 +2011,7 @@ impl VdpaConfig {
Ok(VdpaConfig {
path,
num_queues,
iommu,
id,
pci_segment,
})
@ -2015,8 +2024,8 @@ impl VdpaConfig {
}
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
if iommu_segments.contains(&self.pci_segment) {
return Err(ValidationError::IommuNotSupported(self.pci_segment));
if iommu_segments.contains(&self.pci_segment) && !self.iommu {
return Err(ValidationError::OnIommuSegment(self.pci_segment));
}
}
}
@ -2566,6 +2575,9 @@ impl VmConfig {
let mut vdpa_config_list = Vec::new();
for item in vdpa_list.iter() {
let vdpa_config = VdpaConfig::parse(item)?;
if vdpa_config.iommu {
iommu = true;
}
vdpa_config_list.push(vdpa_config);
}
vdpa = Some(vdpa_config_list);
@ -3656,7 +3668,7 @@ mod tests {
}]);
assert_eq!(
invalid_config.validate(),
Err(ValidationError::IommuNotSupported(1))
Err(ValidationError::OnIommuSegment(1))
);
let mut invalid_config = valid_config;

View File

@ -2947,7 +2947,7 @@ impl DeviceManager {
Ok(MetaVirtioDevice {
virtio_device: vdpa_device as Arc<Mutex<dyn virtio_devices::VirtioDevice>>,
iommu: false,
iommu: vdpa_cfg.iommu,
id,
pci_segment: vdpa_cfg.pci_segment,
dma_handler: Some(vdpa_mapping),
@ -4010,6 +4010,10 @@ impl DeviceManager {
}
pub fn add_vdpa(&mut self, vdpa_cfg: &mut VdpaConfig) -> DeviceManagerResult<PciDeviceInfo> {
if vdpa_cfg.iommu && !self.is_iommu_segment(vdpa_cfg.pci_segment) {
return Err(DeviceManagerError::InvalidIommuHotplug);
}
let device = self.make_vdpa_device(vdpa_cfg)?;
self.hotplug_virtio_pci_device(device)
}