diff options
author | Zhuocheng Ding <zhuocheng.ding@intel.corp-partner.google.com> | 2019-12-02 15:50:28 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-03-05 13:12:23 +0000 |
commit | b9f4c9bca30e65eacfb055951fa994ad5127a8f0 (patch) | |
tree | 8c8c886824f819620cf6d5c8b39ee4571ed7fb9b /arch/src/lib.rs | |
parent | 2f7dabbd6a0d8620e4b19b92cdae24c08e4c7ccc (diff) | |
download | crosvm-b9f4c9bca30e65eacfb055951fa994ad5127a8f0.tar crosvm-b9f4c9bca30e65eacfb055951fa994ad5127a8f0.tar.gz crosvm-b9f4c9bca30e65eacfb055951fa994ad5127a8f0.tar.bz2 crosvm-b9f4c9bca30e65eacfb055951fa994ad5127a8f0.tar.lz crosvm-b9f4c9bca30e65eacfb055951fa994ad5127a8f0.tar.xz crosvm-b9f4c9bca30e65eacfb055951fa994ad5127a8f0.tar.zst crosvm-b9f4c9bca30e65eacfb055951fa994ad5127a8f0.zip |
crosvm: Add plumbing for split-irqchip interrupts
Devices use irqfd to inject interrupts, we listen to them in the main thread and activate userspace pic/ioapic accordingly. BUG=chromium:908689 TEST=lanuch linux guest with `--split-irqchip` flag Change-Id: If30d17ce7ec9e26dba782c89cc1b9b2ff897a70d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1945798 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Stephen Barber <smbarber@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Commit-Queue: Zhuocheng Ding <zhuocheng.ding@intel.corp-partner.google.com>
Diffstat (limited to 'arch/src/lib.rs')
-rw-r--r-- | arch/src/lib.rs | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/arch/src/lib.rs b/arch/src/lib.rs index 5112798..ab08c21 100644 --- a/arch/src/lib.rs +++ b/arch/src/lib.rs @@ -15,6 +15,7 @@ use std::os::unix::io::AsRawFd; use std::path::PathBuf; use std::sync::Arc; +use devices::split_irqchip_common::GsiRelay; use devices::virtio::VirtioDevice; use devices::{ Bus, BusDevice, BusError, PciDevice, PciDeviceError, PciInterruptPin, PciRoot, ProxyDevice, @@ -62,6 +63,7 @@ pub struct RunnableLinuxVm { pub vcpu_affinity: Vec<usize>, pub irq_chip: Option<File>, pub split_irqchip: Option<(Arc<Mutex<devices::Pic>>, Arc<Mutex<devices::Ioapic>>)>, + pub gsi_relay: Option<Arc<GsiRelay>>, pub io_bus: Bus, pub mmio_bus: Bus, pub pid_debug_label_map: BTreeMap<u32, String>, @@ -118,6 +120,8 @@ pub enum DeviceRegistrationError { CreatePipe(sys_util::Error), // Unable to create serial device from serial parameters CreateSerialDevice(devices::SerialError), + /// Could not clone an event fd. + EventFdClone(sys_util::Error), /// Could not create an event fd. EventFdCreate(sys_util::Error), /// Could not add a device to the mmio bus. @@ -149,6 +153,7 @@ impl Display for DeviceRegistrationError { CreatePipe(e) => write!(f, "failed to create pipe: {}", e), CreateSerialDevice(e) => write!(f, "failed to create serial device: {}", e), Cmdline(e) => write!(f, "unable to add device to kernel command line: {}", e), + EventFdClone(e) => write!(f, "failed to clone eventfd: {}", e), EventFdCreate(e) => write!(f, "failed to create eventfd: {}", e), MmioInsert(e) => write!(f, "failed to add to mmio bus: {}", e), RegisterIoevent(e) => write!(f, "failed to register ioevent to VM: {}", e), @@ -166,6 +171,7 @@ impl Display for DeviceRegistrationError { /// Creates a root PCI device for use by this Vm. pub fn generate_pci_root( devices: Vec<(Box<dyn PciDevice>, Option<Minijail>)>, + gsi_relay: &mut Option<GsiRelay>, mmio_bus: &mut Bus, resources: &mut SystemAllocator, vm: &mut Vm, @@ -191,10 +197,22 @@ pub fn generate_pci_root( 1 => PciInterruptPin::IntB, 2 => PciInterruptPin::IntC, 3 => PciInterruptPin::IntD, - _ => panic!(""), // Obviously not possible, but the compiler is not smart enough. + _ => unreachable!(), // Obviously not possible, but the compiler is not smart enough. }; - vm.register_irqfd_resample(&irqfd, &irq_resample_fd, irq_num) - .map_err(DeviceRegistrationError::RegisterIrqfd)?; + if let Some(relay) = gsi_relay { + relay.register_irqfd_resample( + irqfd + .try_clone() + .map_err(DeviceRegistrationError::EventFdClone)?, + irq_resample_fd + .try_clone() + .map_err(DeviceRegistrationError::EventFdClone)?, + irq_num as usize, + ); + } else { + vm.register_irqfd_resample(&irqfd, &irq_resample_fd, irq_num) + .map_err(DeviceRegistrationError::RegisterIrqfd)?; + } keep_fds.push(irqfd.as_raw_fd()); keep_fds.push(irq_resample_fd.as_raw_fd()); device.assign_irq(irqfd, irq_resample_fd, irq_num, pci_irq_pin); |