linux: Instantiate VFIO platform device

Extend VFIO command line option to specify full path to VFIO platform
device that is going to be assigned.

BUG=b:185504618
TEST=trogdor64-manatee SDHCI and GENIQUP device passthrough boots/works

Change-Id: Iad6a24124b383fadb9e025dc64f8a90fa8763ff8
Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2961217
Commit-Queue: Micah Morton <mortonm@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
Tomasz Nowicki 2021-09-22 05:51:58 +00:00 committed by Commit Bot
parent b8957f90a8
commit 344eb144bc
3 changed files with 49 additions and 4 deletions

View file

@ -205,6 +205,7 @@ impl Default for SharedDir {
#[derive(Eq, PartialEq, Clone, Copy)]
pub enum VfioType {
Pci,
Platform,
}
impl FromStr for VfioType {
@ -214,7 +215,8 @@ impl FromStr for VfioType {
use VfioType::*;
match s {
"vfio" => Ok(Pci),
_ => Err("invalid vfio device type, must be 'vfio'"),
"vfio-platform" => Ok(Platform),
_ => Err("invalid vfio device type, must be 'vfio|vfio-platform'"),
}
}
}

View file

@ -48,7 +48,8 @@ use devices::Ac97Dev;
use devices::ProtectionType;
use devices::{
self, BusDeviceObj, HostHotPlugKey, IrqChip, IrqEventIndex, KvmKernelIrqChip, PciAddress,
PciDevice, VcpuRunState, VfioContainer, VfioDevice, VfioPciDevice, VirtioPciDevice,
PciDevice, VcpuRunState, VfioContainer, VfioDevice, VfioPciDevice, VfioPlatformDevice,
VirtioPciDevice,
};
#[cfg(feature = "usb")]
use devices::{HostBackendDeviceProvider, XhciController};
@ -1592,6 +1593,28 @@ fn create_vfio_device(
Ok((vfio_pci_device, simple_jail(cfg, "vfio_device")?))
}
fn create_vfio_platform_device(
cfg: &Config,
vm: &impl Vm,
_resources: &mut SystemAllocator,
control_tubes: &mut Vec<TaggedControlTube>,
vfio_path: &Path,
_endpoints: &mut BTreeMap<u32, Arc<Mutex<VfioContainer>>>,
iommu_enabled: bool,
) -> DeviceResult<(VfioPlatformDevice, Option<Minijail>)> {
let vfio_container = VfioCommonSetup::vfio_get_container(vfio_path, iommu_enabled)
.map_err(Error::CreateVfioDevice)?;
let (vfio_host_tube_mem, vfio_device_tube_mem) = Tube::pair().map_err(Error::CreateTube)?;
control_tubes.push(TaggedControlTube::VmMemory(vfio_host_tube_mem));
let vfio_device = VfioDevice::new(vfio_path, vm, vfio_container, iommu_enabled)
.map_err(Error::CreateVfioDevice)?;
let vfio_plat_dev = VfioPlatformDevice::new(vfio_device, vfio_device_tube_mem);
Ok((vfio_plat_dev, simple_jail(cfg, "vfio_platform_device")?))
}
fn create_devices(
cfg: &Config,
vm: &mut impl Vm,
@ -1674,6 +1697,25 @@ fn create_devices(
devices.push((vfio_pci_device, jail));
}
for vfio_dev in cfg
.vfio
.iter()
.filter(|dev| dev.get_type() == VfioType::Platform)
{
let vfio_path = &vfio_dev.vfio_path;
let (vfio_plat_dev, jail) = create_vfio_platform_device(
cfg,
vm,
resources,
control_tubes,
vfio_path.as_path(),
&mut iommu_attached_endpoints,
false, // Virtio IOMMU is not supported yet
)?;
devices.push((Box::new(vfio_plat_dev), jail));
}
if !iommu_attached_endpoints.is_empty() {
let iommu_dev = create_iommu_device(cfg, phys_max_addr, iommu_attached_endpoints)?;

View file

@ -1782,7 +1782,7 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
}
cfg.executable_path = Some(Executable::Bios(PathBuf::from(value.unwrap().to_owned())));
}
"vfio" => {
"vfio" | "vfio-platform" => {
let vfio_type = name.parse().unwrap();
let vfio_dev = VfioCommand::new(vfio_type, value.unwrap())?;
cfg.vfio.push(vfio_dev);
@ -2186,8 +2186,9 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Argument::flag("split-irqchip", "(EXPERIMENTAL) enable split-irqchip support"),
Argument::value("bios", "PATH", "Path to BIOS/firmware ROM"),
Argument::value("vfio", "PATH[,iommu=on|off]", "Path to sysfs of pass through or mdev device.
Argument::value("vfio", "PATH[,iommu=on|off]", "Path to sysfs of PCI pass through or mdev device.
iommu=on|off - indicates whether to enable virtio IOMMU for this device"),
Argument::value("vfio-platform", "PATH", "Path to sysfs of platform pass through"),
#[cfg(feature = "video-decoder")]
Argument::flag("video-decoder", "(EXPERIMENTAL) enable virtio-video decoder device"),
#[cfg(feature = "video-encoder")]