@@ -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