diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 17d67d6f9..aa7136092 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -2413,7 +2413,7 @@ impl DebugConsoleConfig { impl DeviceConfig { pub const SYNTAX: &'static str = "Direct device assignment parameters \ - \"path=,iommu=on|off,id=,\ + \"path=,fd=,iommu=on|off,id=,\ pci_segment=,pci_device_id=,\ x_nv_gpudirect_clique=,\ x_exclude_mmap_bars=[...]\""; @@ -2422,6 +2422,7 @@ impl DeviceConfig { let mut parser = OptionParser::new(); parser .add("path") + .add("fd") .add_all(PciDeviceCommonConfig::OPTIONS_IOMMU) .add("x_nv_gpudirect_clique") .add("x_exclude_mmap_bars"); @@ -2432,6 +2433,7 @@ impl DeviceConfig { .get("path") .map(PathBuf::from) .ok_or(Error::ParseDevicePathMissing)?; + let fd = parser.convert::("fd").map_err(Error::ParseDevice)?; let x_nv_gpudirect_clique = parser .convert::("x_nv_gpudirect_clique") .map_err(Error::ParseDevice)?; @@ -2443,6 +2445,7 @@ impl DeviceConfig { Ok(DeviceConfig { pci_common, path: Some(path), + fd, x_nv_gpudirect_clique, x_exclude_mmap_bars, }) @@ -4722,6 +4725,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" DeviceConfig { pci_common: PciDeviceCommonConfig::default(), path: Some(PathBuf::from("/path/to/device")), + fd: None, x_nv_gpudirect_clique: None, x_exclude_mmap_bars: Vec::new(), } diff --git a/vmm/src/vm_config.rs b/vmm/src/vm_config.rs index 5561966d6..2d9283c1d 100644 --- a/vmm/src/vm_config.rs +++ b/vmm/src/vm_config.rs @@ -760,12 +760,30 @@ pub struct DeviceConfig { pub pci_common: PciDeviceCommonConfig, #[serde(default)] pub path: Option, + // FDs are not serialized and any deserialized value is invalid; see NetConfig::fds. + #[serde(default, deserialize_with = "deserialize_deviceconfig_fd")] + pub fd: Option, #[serde(default)] pub x_nv_gpudirect_clique: Option, #[serde(default)] pub x_exclude_mmap_bars: Vec, } +fn deserialize_deviceconfig_fd<'de, D>(d: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let invalid_fd: Option = Option::deserialize(d)?; + if invalid_fd.is_some() { + debug!( + "FD in 'DeviceConfig' won't be deserialized as it is most likely invalid now. Deserializing it as -1." + ); + Ok(Some(-1)) + } else { + Ok(None) + } +} + impl ApplyLandlock for DeviceConfig { fn apply_landlock(&self, landlock: &mut Landlock) -> LandlockResult<()> { let path = self