summary refs log tree commit diff
path: root/devices/src/virtio/wl.rs
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2018-10-24 17:06:07 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-10-29 21:18:14 -0700
commit120d95e03123ede9cc3aa05a8ce976fd4678a890 (patch)
tree011d7e856f3085de6f024a08674b7ef499cfcf69 /devices/src/virtio/wl.rs
parent510c783c847b6d0c18516f31fbe3dbdc782f1252 (diff)
downloadcrosvm-120d95e03123ede9cc3aa05a8ce976fd4678a890.tar
crosvm-120d95e03123ede9cc3aa05a8ce976fd4678a890.tar.gz
crosvm-120d95e03123ede9cc3aa05a8ce976fd4678a890.tar.bz2
crosvm-120d95e03123ede9cc3aa05a8ce976fd4678a890.tar.lz
crosvm-120d95e03123ede9cc3aa05a8ce976fd4678a890.tar.xz
crosvm-120d95e03123ede9cc3aa05a8ce976fd4678a890.tar.zst
crosvm-120d95e03123ede9cc3aa05a8ce976fd4678a890.zip
devices: pci: support level-triggered interrupts
Register the irqfd with resample support so that we can correctly
emulate level-triggered interrupts.  This requires each PciDevice to
listen for interrupt_resample events and re-assert the IRQ eventfd if it
should still be active.

BUG=None
TEST=Boot crosvm on x86-64 and arm devices

Change-Id: I5cf8d1d1705cf675b453962c00d2d606801fee91
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1298654
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'devices/src/virtio/wl.rs')
-rw-r--r--devices/src/virtio/wl.rs17
1 files changed, 16 insertions, 1 deletions
diff --git a/devices/src/virtio/wl.rs b/devices/src/virtio/wl.rs
index e1a9025..1933be5 100644
--- a/devices/src/virtio/wl.rs
+++ b/devices/src/virtio/wl.rs
@@ -1352,6 +1352,7 @@ impl WlState {
 struct Worker {
     mem: GuestMemory,
     interrupt_evt: EventFd,
+    interrupt_resample_evt: EventFd,
     interrupt_status: Arc<AtomicUsize>,
     in_queue: Queue,
     out_queue: Queue,
@@ -1363,6 +1364,7 @@ impl Worker {
     fn new(
         mem: GuestMemory,
         interrupt_evt: EventFd,
+        interrupt_resample_evt: EventFd,
         interrupt_status: Arc<AtomicUsize>,
         in_queue: Queue,
         out_queue: Queue,
@@ -1373,6 +1375,7 @@ impl Worker {
         Worker {
             mem,
             interrupt_evt,
+            interrupt_resample_evt,
             interrupt_status,
             in_queue,
             out_queue,
@@ -1396,6 +1399,7 @@ impl Worker {
             OutQueue,
             Kill,
             State,
+            InterruptResample,
         }
 
         let poll_ctx: PollContext<Token> = match PollContext::new()
@@ -1403,7 +1407,10 @@ impl Worker {
             .and_then(|pc| pc.add(&out_queue_evt, Token::OutQueue).and(Ok(pc)))
             .and_then(|pc| pc.add(&kill_evt, Token::Kill).and(Ok(pc)))
             .and_then(|pc| pc.add(&self.state.poll_ctx, Token::State).and(Ok(pc)))
-        {
+            .and_then(|pc| {
+                pc.add(&self.interrupt_resample_evt, Token::InterruptResample)
+                    .and(Ok(pc))
+            }) {
             Ok(pc) => pc,
             Err(e) => {
                 error!("failed creating PollContext: {:?}", e);
@@ -1496,6 +1503,12 @@ impl Worker {
                     }
                     Token::Kill => break 'poll,
                     Token::State => self.state.process_poll_context(),
+                    Token::InterruptResample => {
+                        let _ = self.interrupt_resample_evt.read();
+                        if self.interrupt_status.load(Ordering::SeqCst) != 0 {
+                            self.interrupt_evt.write(1).unwrap();
+                        }
+                    }
                 }
             }
 
@@ -1602,6 +1615,7 @@ impl VirtioDevice for Wl {
         &mut self,
         mem: GuestMemory,
         interrupt_evt: EventFd,
+        interrupt_resample_evt: EventFd,
         status: Arc<AtomicUsize>,
         mut queues: Vec<Queue>,
         queue_evts: Vec<EventFd>,
@@ -1629,6 +1643,7 @@ impl VirtioDevice for Wl {
                         Worker::new(
                             mem,
                             interrupt_evt,
+                            interrupt_resample_evt,
                             status,
                             queues.remove(0),
                             queues.remove(0),