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: num_queues:
type: integer type: integer
default: 1 default: 1
iommu:
type: boolean
default: false
pci_segment: pci_segment:
type: integer type: integer
format: int16 format: int16

View File

@ -1964,6 +1964,8 @@ pub struct VdpaConfig {
#[serde(default = "default_vdpaconfig_num_queues")] #[serde(default = "default_vdpaconfig_num_queues")]
pub num_queues: usize, pub num_queues: usize,
#[serde(default)] #[serde(default)]
pub iommu: bool,
#[serde(default)]
pub id: Option<String>, pub id: Option<String>,
#[serde(default)] #[serde(default)]
pub pci_segment: u16, pub pci_segment: u16,
@ -1982,6 +1984,7 @@ impl VdpaConfig {
parser parser
.add("path") .add("path")
.add("num_queues") .add("num_queues")
.add("iommu")
.add("id") .add("id")
.add("pci_segment"); .add("pci_segment");
parser.parse(vdpa).map_err(Error::ParseVdpa)?; parser.parse(vdpa).map_err(Error::ParseVdpa)?;
@ -1994,6 +1997,11 @@ impl VdpaConfig {
.convert("num_queues") .convert("num_queues")
.map_err(Error::ParseVdpa)? .map_err(Error::ParseVdpa)?
.unwrap_or_else(default_vdpaconfig_num_queues); .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 id = parser.get("id");
let pci_segment = parser let pci_segment = parser
.convert("pci_segment") .convert("pci_segment")
@ -2003,6 +2011,7 @@ impl VdpaConfig {
Ok(VdpaConfig { Ok(VdpaConfig {
path, path,
num_queues, num_queues,
iommu,
id, id,
pci_segment, pci_segment,
}) })
@ -2015,8 +2024,8 @@ impl VdpaConfig {
} }
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) && !self.iommu {
return Err(ValidationError::IommuNotSupported(self.pci_segment)); return Err(ValidationError::OnIommuSegment(self.pci_segment));
} }
} }
} }
@ -2566,6 +2575,9 @@ 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);
@ -3656,7 +3668,7 @@ mod tests {
}]); }]);
assert_eq!( assert_eq!(
invalid_config.validate(), invalid_config.validate(),
Err(ValidationError::IommuNotSupported(1)) Err(ValidationError::OnIommuSegment(1))
); );
let mut invalid_config = valid_config; let mut invalid_config = valid_config;

View File

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