@@ -11,6 +11,7 @@ use std::sync::{Arc, Mutex, MutexGuard};
1111
1212use vmm_sys_util:: eventfd:: EventFd ;
1313
14+ use super :: { VirtioInterrupt , VirtioInterruptType } ;
1415use crate :: devices:: virtio:: device:: VirtioDevice ;
1516use crate :: devices:: virtio:: device_status;
1617use crate :: devices:: virtio:: queue:: Queue ;
@@ -375,13 +376,56 @@ pub enum IrqType {
375376 Vring ,
376377}
377378
379+ impl From < VirtioInterruptType > for IrqType {
380+ fn from ( interrupt_type : VirtioInterruptType ) -> Self {
381+ match interrupt_type {
382+ VirtioInterruptType :: Config => IrqType :: Config ,
383+ VirtioInterruptType :: Queue ( _) => IrqType :: Vring ,
384+ }
385+ }
386+ }
387+
378388/// Helper struct that is responsible for triggering guest IRQs
379389#[ derive( Debug ) ]
380390pub struct IrqTrigger {
381391 pub ( crate ) irq_status : Arc < AtomicU32 > ,
382392 pub ( crate ) irq_evt : EventFd ,
383393}
384394
395+ impl VirtioInterrupt for IrqTrigger {
396+ fn trigger ( & self , interrupt_type : super :: VirtioInterruptType ) -> Result < ( ) , std:: io:: Error > {
397+ match interrupt_type {
398+ VirtioInterruptType :: Config => self . trigger_irq ( IrqType :: Config ) ,
399+ VirtioInterruptType :: Queue ( _) => self . trigger_irq ( IrqType :: Vring ) ,
400+ }
401+ }
402+
403+ fn notifier ( & self , _interrupt_type : VirtioInterruptType ) -> Option < EventFd > {
404+ self . irq_evt . try_clone ( ) . ok ( )
405+ }
406+
407+ fn status ( & self ) -> Arc < AtomicU32 > {
408+ self . irq_status . clone ( )
409+ }
410+
411+ #[ cfg( test) ]
412+ fn has_pending_interrupt ( & self , interrupt_type : VirtioInterruptType ) -> bool {
413+ if let Ok ( num_irqs) = self . irq_evt . read ( ) {
414+ if num_irqs == 0 {
415+ return false ;
416+ }
417+
418+ let irq_status = self . irq_status . load ( Ordering :: SeqCst ) ;
419+ return matches ! (
420+ ( irq_status, interrupt_type. into( ) ) ,
421+ ( VIRTIO_MMIO_INT_CONFIG , IrqType :: Config ) | ( VIRTIO_MMIO_INT_VRING , IrqType :: Vring )
422+ ) ;
423+ }
424+
425+ false
426+ }
427+ }
428+
385429impl IrqTrigger {
386430 pub fn new ( ) -> std:: io:: Result < Self > {
387431 Ok ( Self {
@@ -993,6 +1037,25 @@ pub(crate) mod tests {
9931037 assert ! ( d. locked_device( ) . is_activated( ) ) ;
9941038 }
9951039
1040+ impl IrqTrigger {
1041+ pub fn has_pending_irq ( & self , irq_type : IrqType ) -> bool {
1042+ if let Ok ( num_irqs) = self . irq_evt . read ( ) {
1043+ if num_irqs == 0 {
1044+ return false ;
1045+ }
1046+
1047+ let irq_status = self . irq_status . load ( Ordering :: SeqCst ) ;
1048+ return matches ! (
1049+ ( irq_status, irq_type) ,
1050+ ( VIRTIO_MMIO_INT_CONFIG , IrqType :: Config )
1051+ | ( VIRTIO_MMIO_INT_VRING , IrqType :: Vring )
1052+ ) ;
1053+ }
1054+
1055+ false
1056+ }
1057+ }
1058+
9961059 #[ test]
9971060 fn test_bus_device_reset ( ) {
9981061 let m = single_region_mem ( 0x1000 ) ;
@@ -1053,25 +1116,6 @@ pub(crate) mod tests {
10531116 assert_eq ! ( dummy_dev. acked_features( ) , 24 ) ;
10541117 }
10551118
1056- impl IrqTrigger {
1057- pub fn has_pending_irq ( & self , irq_type : IrqType ) -> bool {
1058- if let Ok ( num_irqs) = self . irq_evt . read ( ) {
1059- if num_irqs == 0 {
1060- return false ;
1061- }
1062-
1063- let irq_status = self . irq_status . load ( Ordering :: SeqCst ) ;
1064- return matches ! (
1065- ( irq_status, irq_type) ,
1066- ( VIRTIO_MMIO_INT_CONFIG , IrqType :: Config )
1067- | ( VIRTIO_MMIO_INT_VRING , IrqType :: Vring )
1068- ) ;
1069- }
1070-
1071- false
1072- }
1073- }
1074-
10751119 #[ test]
10761120 fn irq_trigger ( ) {
10771121 let irq_trigger = IrqTrigger :: new ( ) . unwrap ( ) ;
0 commit comments