summary refs log tree commit diff
path: root/devices/src/ioapic.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 /devices/src/ioapic.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 'devices/src/ioapic.rs')
-rw-r--r--devices/src/ioapic.rs13
1 files changed, 13 insertions, 0 deletions
diff --git a/devices/src/ioapic.rs b/devices/src/ioapic.rs
index e1fbfb8..09ccb89 100644
--- a/devices/src/ioapic.rs
+++ b/devices/src/ioapic.rs
@@ -10,6 +10,7 @@ use crate::BusDevice;
 use bit_field::*;
 use kvm::Vm;
 use msg_socket::{MsgReceiver, MsgSender};
+use std::sync::Arc;
 use sys_util::{error, warn, EventFd, Result};
 use vm_control::{VmIrqRequest, VmIrqRequestSocket, VmIrqResponse};
 
@@ -89,6 +90,7 @@ pub struct Ioapic {
     redirect_table: [RedirectionTableEntry; kvm::NUM_IOAPIC_PINS],
     // IOREGSEL is technically 32 bits, but only bottom 8 are writable: all others are fixed to 0.
     ioregsel: u8,
+    relay: Arc<GsiRelay>,
     irqfd: Vec<EventFd>,
     socket: VmIrqRequestSocket,
 }
@@ -166,11 +168,16 @@ impl Ioapic {
             current_interrupt_level_bitmap: 0,
             redirect_table: entries,
             ioregsel: 0,
+            relay: Default::default(),
             irqfd,
             socket,
         })
     }
 
+    pub fn register_relay(&mut self, relay: Arc<GsiRelay>) {
+        self.relay = relay;
+    }
+
     // The ioapic must be informed about EOIs in order to avoid sending multiple interrupts of the
     // same type at the same time.
     pub fn end_of_interrupt(&mut self, vector: u8) {
@@ -183,6 +190,12 @@ impl Ioapic {
             if self.redirect_table[i].get_vector() == vector
                 && self.redirect_table[i].get_trigger_mode() == TriggerMode::Level
             {
+                if self.relay.irqfd_resample[i].is_some() {
+                    self.service_irq(i, false);
+                }
+                if let Some(resample_evt) = &self.relay.irqfd_resample[i] {
+                    resample_evt.write(1).unwrap();
+                }
                 self.redirect_table[i].set_remote_irr(false);
             }
             // There is an inherent race condition in hardware if the OS is finished processing an