summary refs log tree commit diff
path: root/src/linux.rs
diff options
context:
space:
mode:
authorZhuocheng Ding <zhuocheng.ding@intel.corp-partner.google.com>2019-12-02 15:50:24 +0800
committerCommit Bot <commit-bot@chromium.org>2020-03-05 01:02:49 +0000
commitdb4c70d2151d054b6b4df58be432e500aeafecbe (patch)
tree20c86cafe4e8ca664f90a853518075d204c49173 /src/linux.rs
parentf2e90bf0b0ca101d2925e91ca50d3e9e5ea2fdb7 (diff)
downloadcrosvm-db4c70d2151d054b6b4df58be432e500aeafecbe.tar
crosvm-db4c70d2151d054b6b4df58be432e500aeafecbe.tar.gz
crosvm-db4c70d2151d054b6b4df58be432e500aeafecbe.tar.bz2
crosvm-db4c70d2151d054b6b4df58be432e500aeafecbe.tar.lz
crosvm-db4c70d2151d054b6b4df58be432e500aeafecbe.tar.xz
crosvm-db4c70d2151d054b6b4df58be432e500aeafecbe.tar.zst
crosvm-db4c70d2151d054b6b4df58be432e500aeafecbe.zip
devices: PIC: implement interrupt injection
TODO: Route irqfd to PIC, and use signal to kick vCPU thread when
interrupt is triggered.

BUG=chromium:908689
TEST=Unit tests in file.

Change-Id: I9a87502da57e725d3bb26d746a337d0ba44ef337
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1945797
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Zhuocheng Ding <zhuocheng.ding@intel.corp-partner.google.com>
Diffstat (limited to 'src/linux.rs')
-rw-r--r--src/linux.rs25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/linux.rs b/src/linux.rs
index ad35407..a181e52 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -1349,6 +1349,26 @@ fn runnable_vcpu(vcpu: Vcpu, use_kvm_signals: bool, cpu_id: u32) -> Option<Runna
     }
 }
 
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn inject_interrupt(pic: &Arc<Mutex<devices::Pic>>, vcpu: &RunnableVcpu) {
+    let mut pic = pic.lock();
+    if pic.interrupt_requested() && vcpu.ready_for_interrupt() {
+        if let Some(vector) = pic.get_external_interrupt() {
+            if let Err(e) = vcpu.interrupt(vector as u32) {
+                error!("PIC: failed to inject interrupt to vCPU0: {}", e);
+            }
+        }
+        // The second interrupt request should be handled immediately, so ask
+        // vCPU to exit as soon as possible.
+        if pic.interrupt_requested() {
+            vcpu.request_interrupt_window();
+        }
+    }
+}
+
+#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
+fn inject_interrupt(pic: &Arc<Mutex<devices::Pic>>, vcpu: &RunnableVcpu) {}
+
 fn run_vcpu(
     vcpu: Vcpu,
     cpu_id: u32,
@@ -1480,6 +1500,11 @@ fn run_vcpu(
                             run_mode_lock = run_mode_arc.cvar.wait(run_mode_lock);
                         }
                     }
+
+                    if cpu_id != 0 { continue; }
+                    if let Some((pic, _)) = &split_irqchip {
+                        inject_interrupt(pic, &vcpu);
+                    }
                 }
             }
         })