@@ -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,13 +376,56 @@ 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 {
381
391
pub ( crate ) irq_status : Arc < AtomicU32 > ,
382
392
pub ( crate ) irq_evt : EventFd ,
383
393
}
384
394
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
+
385
429
impl IrqTrigger {
386
430
pub fn new ( ) -> std:: io:: Result < Self > {
387
431
Ok ( Self {
@@ -993,6 +1037,25 @@ pub(crate) mod tests {
993
1037
assert ! ( d. locked_device( ) . is_activated( ) ) ;
994
1038
}
995
1039
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
+
996
1059
#[ test]
997
1060
fn test_bus_device_reset ( ) {
998
1061
let m = single_region_mem ( 0x1000 ) ;
@@ -1053,25 +1116,6 @@ pub(crate) mod tests {
1053
1116
assert_eq ! ( dummy_dev. acked_features( ) , 24 ) ;
1054
1117
}
1055
1118
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
-
1075
1119
#[ test]
1076
1120
fn irq_trigger ( ) {
1077
1121
let irq_trigger = IrqTrigger :: new ( ) . unwrap ( ) ;
0 commit comments