summary refs log tree commit diff
path: root/arch/src/lib.rs
diff options
context:
space:
mode:
authorZhuocheng Ding <zhuocheng.ding@intel.corp-partner.google.com>2019-12-02 15:50:28 +0800
committerCommit Bot <commit-bot@chromium.org>2020-03-05 13:12:23 +0000
commitb9f4c9bca30e65eacfb055951fa994ad5127a8f0 (patch)
tree8c8c886824f819620cf6d5c8b39ee4571ed7fb9b /arch/src/lib.rs
parent2f7dabbd6a0d8620e4b19b92cdae24c08e4c7ccc (diff)
downloadcrosvm-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.rs24
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);