diff options
-rw-r--r-- | devices/src/virtio/block.rs | 2 | ||||
-rw-r--r-- | devices/src/virtio/queue.rs | 20 |
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); + } + } } |