@@ -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 {
@@ -1062,44 +1106,29 @@ pub(crate) mod tests {
1062
1106
assert_eq ! ( dummy_dev. acked_features( ) , 24 ) ;
1063
1107
}
1064
1108
1065
- impl IrqTrigger {
1066
- pub fn has_pending_irq ( & self , irq_type : IrqType ) -> bool {
1067
- if let Ok ( num_irqs) = self . irq_evt . read ( ) {
1068
- if num_irqs == 0 {
1069
- return false ;
1070
- }
1071
-
1072
- let irq_status = self . irq_status . load ( Ordering :: SeqCst ) ;
1073
- return matches ! (
1074
- ( irq_status, irq_type) ,
1075
- ( VIRTIO_MMIO_INT_CONFIG , IrqType :: Config )
1076
- | ( VIRTIO_MMIO_INT_VRING , IrqType :: Vring )
1077
- ) ;
1078
- }
1079
-
1080
- false
1081
- }
1082
- }
1083
-
1084
1109
#[ test]
1085
1110
fn irq_trigger ( ) {
1086
1111
let irq_trigger = IrqTrigger :: new ( ) ;
1087
1112
assert_eq ! ( irq_trigger. irq_status. load( Ordering :: SeqCst ) , 0 ) ;
1088
1113
1089
1114
// Check that there are no pending irqs.
1090
- assert ! ( !irq_trigger. has_pending_irq ( IrqType :: Config ) ) ;
1091
- assert ! ( !irq_trigger. has_pending_irq ( IrqType :: Vring ) ) ;
1115
+ assert ! ( !irq_trigger. has_pending_interrupt ( VirtioInterruptType :: Config ) ) ;
1116
+ assert ! ( !irq_trigger. has_pending_interrupt ( VirtioInterruptType :: Queue ( 0 ) ) ) ;
1092
1117
1093
1118
// Check that trigger_irq() correctly generates irqs.
1094
- irq_trigger. trigger_irq ( IrqType :: Config ) . unwrap ( ) ;
1095
- assert ! ( irq_trigger. has_pending_irq ( IrqType :: Config ) ) ;
1119
+ irq_trigger. trigger ( VirtioInterruptType :: Config ) . unwrap ( ) ;
1120
+ assert ! ( irq_trigger. has_pending_interrupt ( VirtioInterruptType :: Config ) ) ;
1096
1121
irq_trigger. irq_status . store ( 0 , Ordering :: SeqCst ) ;
1097
- irq_trigger. trigger_irq ( IrqType :: Vring ) . unwrap ( ) ;
1098
- assert ! ( irq_trigger. has_pending_irq ( IrqType :: Vring ) ) ;
1122
+ irq_trigger. trigger ( VirtioInterruptType :: Queue ( 0 ) ) . unwrap ( ) ;
1123
+ assert ! ( irq_trigger. has_pending_interrupt ( VirtioInterruptType :: Queue ( 0 ) ) ) ;
1099
1124
1100
1125
// Check trigger_irq() failure case (irq_evt is full).
1101
1126
irq_trigger. irq_evt . write ( u64:: MAX - 1 ) . unwrap ( ) ;
1102
- irq_trigger. trigger_irq ( IrqType :: Config ) . unwrap_err ( ) ;
1103
- irq_trigger. trigger_irq ( IrqType :: Vring ) . unwrap_err ( ) ;
1127
+ irq_trigger
1128
+ . trigger ( VirtioInterruptType :: Config )
1129
+ . unwrap_err ( ) ;
1130
+ irq_trigger
1131
+ . trigger ( VirtioInterruptType :: Queue ( 0 ) )
1132
+ . unwrap_err ( ) ;
1104
1133
}
1105
1134
}
0 commit comments