@@ -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,6 +376,15 @@ 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 {
@@ -388,6 +398,40 @@ impl Default for IrqTrigger {
388398 }
389399}
390400
401+ impl VirtioInterrupt for IrqTrigger {
402+ fn trigger ( & self , interrupt_type : VirtioInterruptType ) -> Result < ( ) , std:: io:: Error > {
403+ match interrupt_type {
404+ VirtioInterruptType :: Config => self . trigger_irq ( IrqType :: Config ) ,
405+ VirtioInterruptType :: Queue ( _) => self . trigger_irq ( IrqType :: Vring ) ,
406+ }
407+ }
408+
409+ fn notifier ( & self , _interrupt_type : VirtioInterruptType ) -> Option < & EventFd > {
410+ Some ( & self . irq_evt )
411+ }
412+
413+ fn status ( & self ) -> Arc < AtomicU32 > {
414+ self . irq_status . clone ( )
415+ }
416+
417+ #[ cfg( test) ]
418+ fn has_pending_interrupt ( & self , interrupt_type : VirtioInterruptType ) -> bool {
419+ if let Ok ( num_irqs) = self . irq_evt . read ( ) {
420+ if num_irqs == 0 {
421+ return false ;
422+ }
423+
424+ let irq_status = self . irq_status . load ( Ordering :: SeqCst ) ;
425+ return matches ! (
426+ ( irq_status, interrupt_type. into( ) ) ,
427+ ( VIRTIO_MMIO_INT_CONFIG , IrqType :: Config ) | ( VIRTIO_MMIO_INT_VRING , IrqType :: Vring )
428+ ) ;
429+ }
430+
431+ false
432+ }
433+ }
434+
391435impl IrqTrigger {
392436 pub fn new ( ) -> Self {
393437 Self {
@@ -1060,44 +1104,29 @@ pub(crate) mod tests {
10601104 assert_eq ! ( dummy_dev. acked_features( ) , 24 ) ;
10611105 }
10621106
1063- impl IrqTrigger {
1064- pub fn has_pending_irq ( & self , irq_type : IrqType ) -> bool {
1065- if let Ok ( num_irqs) = self . irq_evt . read ( ) {
1066- if num_irqs == 0 {
1067- return false ;
1068- }
1069-
1070- let irq_status = self . irq_status . load ( Ordering :: SeqCst ) ;
1071- return matches ! (
1072- ( irq_status, irq_type) ,
1073- ( VIRTIO_MMIO_INT_CONFIG , IrqType :: Config )
1074- | ( VIRTIO_MMIO_INT_VRING , IrqType :: Vring )
1075- ) ;
1076- }
1077-
1078- false
1079- }
1080- }
1081-
10821107 #[ test]
10831108 fn irq_trigger ( ) {
10841109 let irq_trigger = IrqTrigger :: new ( ) ;
10851110 assert_eq ! ( irq_trigger. irq_status. load( Ordering :: SeqCst ) , 0 ) ;
10861111
10871112 // Check that there are no pending irqs.
1088- assert ! ( !irq_trigger. has_pending_irq ( IrqType :: Config ) ) ;
1089- assert ! ( !irq_trigger. has_pending_irq ( IrqType :: Vring ) ) ;
1113+ assert ! ( !irq_trigger. has_pending_interrupt ( VirtioInterruptType :: Config ) ) ;
1114+ assert ! ( !irq_trigger. has_pending_interrupt ( VirtioInterruptType :: Queue ( 0 ) ) ) ;
10901115
10911116 // Check that trigger_irq() correctly generates irqs.
1092- irq_trigger. trigger_irq ( IrqType :: Config ) . unwrap ( ) ;
1093- assert ! ( irq_trigger. has_pending_irq ( IrqType :: Config ) ) ;
1117+ irq_trigger. trigger ( VirtioInterruptType :: Config ) . unwrap ( ) ;
1118+ assert ! ( irq_trigger. has_pending_interrupt ( VirtioInterruptType :: Config ) ) ;
10941119 irq_trigger. irq_status . store ( 0 , Ordering :: SeqCst ) ;
1095- irq_trigger. trigger_irq ( IrqType :: Vring ) . unwrap ( ) ;
1096- assert ! ( irq_trigger. has_pending_irq ( IrqType :: Vring ) ) ;
1120+ irq_trigger. trigger ( VirtioInterruptType :: Queue ( 0 ) ) . unwrap ( ) ;
1121+ assert ! ( irq_trigger. has_pending_interrupt ( VirtioInterruptType :: Queue ( 0 ) ) ) ;
10971122
10981123 // Check trigger_irq() failure case (irq_evt is full).
10991124 irq_trigger. irq_evt . write ( u64:: MAX - 1 ) . unwrap ( ) ;
1100- irq_trigger. trigger_irq ( IrqType :: Config ) . unwrap_err ( ) ;
1101- irq_trigger. trigger_irq ( IrqType :: Vring ) . unwrap_err ( ) ;
1125+ irq_trigger
1126+ . trigger ( VirtioInterruptType :: Config )
1127+ . unwrap_err ( ) ;
1128+ irq_trigger
1129+ . trigger ( VirtioInterruptType :: Queue ( 0 ) )
1130+ . unwrap_err ( ) ;
11021131 }
11031132}
0 commit comments