@@ -11,6 +11,7 @@ use std::sync::{Arc, Mutex, MutexGuard};
11
11
12
12
use vmm_sys_util:: eventfd:: EventFd ;
13
13
14
+ use super :: { VirtioInterrupt , VirtioInterruptType } ;
14
15
use crate :: devices:: virtio:: device:: VirtioDevice ;
15
16
use crate :: devices:: virtio:: device_status;
16
17
use crate :: devices:: virtio:: queue:: Queue ;
@@ -375,6 +376,15 @@ pub enum IrqType {
375
376
Vring ,
376
377
}
377
378
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
+
378
388
/// Helper struct that is responsible for triggering guest IRQs
379
389
#[ derive( Debug ) ]
380
390
pub struct IrqTrigger {
@@ -388,6 +398,40 @@ impl Default for IrqTrigger {
388
398
}
389
399
}
390
400
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
+
391
435
impl IrqTrigger {
392
436
pub fn new ( ) -> Self {
393
437
Self {
@@ -1060,44 +1104,29 @@ pub(crate) mod tests {
1060
1104
assert_eq ! ( dummy_dev. acked_features( ) , 24 ) ;
1061
1105
}
1062
1106
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
-
1082
1107
#[ test]
1083
1108
fn irq_trigger ( ) {
1084
1109
let irq_trigger = IrqTrigger :: new ( ) ;
1085
1110
assert_eq ! ( irq_trigger. irq_status. load( Ordering :: SeqCst ) , 0 ) ;
1086
1111
1087
1112
// 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 ) ) ) ;
1090
1115
1091
1116
// 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 ) ) ;
1094
1119
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 ) ) ) ;
1097
1122
1098
1123
// Check trigger_irq() failure case (irq_evt is full).
1099
1124
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 ( ) ;
1102
1131
}
1103
1132
}
0 commit comments