crosvm: Preserve platform devices in RunnableLinuxVm

If a vfio-platform device has no mmio regions, it is unexpectedly
destroyed at startup (in particular, its vfio device fd is unexpectedly
closed, so its interrupt forwarding stops working, etc) since in
generate_platform_bus() arced_dev is not added to mmio_bus so there are
no more references to the device. To fix this issue, preserve references
to platform devices also in platform_devices field of RunnableLinuxVm.

BUG=b:197169350
TEST=Use vfio-platform for passthrough of a device with interrupts but
without mmio regions, e.g. touchpad on Brya, and check if it works in
the VM (i.e. its interrupts are successfully delivered).

Change-Id: I4042c5508ef6b69649c7d20962edf61b735abc03
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3820043
Commit-Queue: Dmytro Maluka <dmaluka@google.com>
Tested-by: Dmytro Maluka <dmy@semihalf.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
Dmytro Maluka 2022-06-24 18:35:34 +00:00 committed by crosvm LUCI
parent 9ac7ca65fd
commit d98e20b908
4 changed files with 17 additions and 9 deletions

View file

@ -444,13 +444,14 @@ impl arch::LinuxArch for AArch64 {
.into_iter()
.map(|(dev, jail_orig)| (*(dev.into_platform_device().unwrap()), jail_orig))
.collect();
let mut platform_pid_debug_label_map = arch::sys::unix::generate_platform_bus(
platform_devices,
irq_chip.as_irq_chip_mut(),
&mmio_bus,
system_allocator,
)
.map_err(Error::CreatePlatformBus)?;
let (platform_devices, mut platform_pid_debug_label_map) =
arch::sys::unix::generate_platform_bus(
platform_devices,
irq_chip.as_irq_chip_mut(),
&mmio_bus,
system_allocator,
)
.map_err(Error::CreatePlatformBus)?;
pid_debug_label_map.append(&mut platform_pid_debug_label_map);
Self::add_arch_devs(
@ -595,6 +596,7 @@ impl arch::LinuxArch for AArch64 {
pm: None,
resume_notify_devices: Vec::new(),
root_config: pci_root,
platform_devices,
hotplug_bus: BTreeMap::new(),
})
}

View file

@ -188,6 +188,8 @@ pub struct RunnableLinuxVm<V: VmArch, Vcpu: VcpuArch> {
pub mmio_bus: Arc<Bus>,
pub no_smt: bool,
pub pid_debug_label_map: BTreeMap<u32, String>,
#[cfg(unix)]
pub platform_devices: Vec<Arc<Mutex<dyn BusDevice>>>,
pub pm: Option<Arc<Mutex<dyn PmResource>>>,
/// Devices to be notified before the system resumes from the S3 suspended state.
pub resume_notify_devices: Vec<Arc<Mutex<dyn BusResumeDevice>>>,

View file

@ -139,7 +139,8 @@ pub fn generate_platform_bus(
irq_chip: &mut dyn IrqChip,
mmio_bus: &Bus,
resources: &mut SystemAllocator,
) -> Result<BTreeMap<u32, String>, DeviceRegistrationError> {
) -> Result<(Vec<Arc<Mutex<dyn BusDevice>>>, BTreeMap<u32, String>), DeviceRegistrationError> {
let mut platform_devices = Vec::new();
let mut pid_labels = BTreeMap::new();
// Allocate ranges that may need to be in the Platform MMIO region (MmioType::Platform).
@ -199,11 +200,12 @@ pub fn generate_platform_bus(
device.on_sandboxed();
Arc::new(Mutex::new(device))
};
platform_devices.push(arced_dev.clone());
for range in &ranges {
mmio_bus
.insert(arced_dev.clone(), range.0, range.1)
.map_err(DeviceRegistrationError::MmioInsert)?;
}
}
Ok(pid_labels)
Ok((platform_devices, pid_labels))
}

View file

@ -854,6 +854,8 @@ impl arch::LinuxArch for X8664arch {
gdb: components.gdb,
pm: Some(acpi_dev_resource.pm),
root_config: pci,
#[cfg(unix)]
platform_devices: Vec::new(),
hotplug_bus: BTreeMap::new(),
})
}