summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--devices/src/virtio/block.rs2
-rw-r--r--devices/src/virtio/queue.rs20
2 files changed, 20 insertions, 2 deletions
diff --git a/devices/src/virtio/block.rs b/devices/src/virtio/block.rs
index 65be6d5..1e9c63e 100644
--- a/devices/src/virtio/block.rs
+++ b/devices/src/virtio/block.rs
@@ -325,7 +325,7 @@ impl Worker {
             };
 
             queue.add_used(&self.mem, desc_index, len as u32);
-            self.interrupt.signal_used_queue(queue.vector);
+            queue.trigger_interrupt(&self.mem, &self.interrupt);
             queue.set_notify(&self.mem, true);
         }
     }
diff --git a/devices/src/virtio/queue.rs b/devices/src/virtio/queue.rs
index b3c738c..15dc3e1 100644
--- a/devices/src/virtio/queue.rs
+++ b/devices/src/virtio/queue.rs
@@ -8,7 +8,7 @@ use std::sync::atomic::{fence, Ordering};
 
 use sys_util::{error, GuestAddress, GuestMemory};
 
-use super::VIRTIO_MSI_NO_VECTOR;
+use super::{Interrupt, VIRTIO_MSI_NO_VECTOR};
 
 const VIRTQ_DESC_F_NEXT: u16 = 0x1;
 const VIRTQ_DESC_F_WRITE: u16 = 0x2;
@@ -16,6 +16,7 @@ const VIRTQ_DESC_F_WRITE: u16 = 0x2;
 const VIRTQ_DESC_F_INDIRECT: u16 = 0x4;
 
 const VIRTQ_USED_F_NO_NOTIFY: u16 = 0x1;
+const VIRTQ_AVAIL_F_NO_INTERRUPT: u16 = 0x1;
 
 /// An iterator over a single descriptor chain.  Not to be confused with AvailIter,
 /// which iterates over the descriptor chain heads in a queue.
@@ -395,4 +396,21 @@ impl Queue {
         }
         mem.write_obj_at_addr(used_flags, self.used_ring).unwrap();
     }
+
+    // Check Whether guest enable interrupt injection or not.
+    fn available_interrupt_enabled(&self, mem: &GuestMemory) -> bool {
+        let avail_flags: u16 = mem.read_obj_from_addr(self.avail_ring).unwrap();
+        if avail_flags & VIRTQ_AVAIL_F_NO_INTERRUPT == VIRTQ_AVAIL_F_NO_INTERRUPT {
+            false
+        } else {
+            true
+        }
+    }
+
+    /// inject interrupt into guest on this queue
+    pub fn trigger_interrupt(&self, mem: &GuestMemory, interrupt: &Interrupt) {
+        if self.available_interrupt_enabled(mem) {
+            interrupt.signal_used_queue(self.vector);
+        }
+    }
 }