@@ -74,7 +74,7 @@ impl PartialOrd for IoRange {
7474}
7575
7676/// System IO manager serving for all devices management and VM exit handling.
77- #[ derive( Default ) ]
77+ #[ derive( Clone , Default ) ]
7878pub struct IoManager {
7979 /// Range mapping for VM exit pio operations.
8080 pio_bus : BTreeMap < IoRange , Arc < dyn DeviceIo > > ,
@@ -276,6 +276,45 @@ mod tests {
276276 }
277277 }
278278
279+ #[ test]
280+ fn test_clone_io_manager ( ) {
281+ let mut io_mgr = IoManager :: new ( ) ;
282+ let dummy = DummyDevice :: new ( 0 ) ;
283+ let dum = Arc :: new ( dummy) ;
284+
285+ let mut resource: Vec < Resource > = Vec :: new ( ) ;
286+ let mmio = Resource :: MmioAddressRange {
287+ base : MMIO_ADDRESS_BASE ,
288+ size : MMIO_ADDRESS_SIZE ,
289+ } ;
290+ let pio = Resource :: PioAddressRange {
291+ base : PIO_ADDRESS_BASE ,
292+ size : PIO_ADDRESS_SIZE ,
293+ } ;
294+ let irq = Resource :: LegacyIrq ( LEGACY_IRQ ) ;
295+
296+ resource. push ( mmio) ;
297+ resource. push ( pio) ;
298+ resource. push ( irq) ;
299+ assert ! ( io_mgr. register_device_io( dum. clone( ) , & resource) . is_ok( ) ) ;
300+
301+ let io_mgr2 = io_mgr. clone ( ) ;
302+ assert_eq ! ( io_mgr2. pio_bus. len( ) , 1 ) ;
303+ assert_eq ! ( io_mgr2. mmio_bus. len( ) , 1 ) ;
304+
305+ let ( dev, addr) = io_mgr2
306+ . get_device ( IoAddress :: Mmio ( MMIO_ADDRESS_BASE + 1 ) )
307+ . unwrap ( ) ;
308+ assert_eq ! ( Arc :: strong_count( dev) , 5 ) ;
309+ assert_eq ! ( addr, IoAddress :: Mmio ( MMIO_ADDRESS_BASE ) ) ;
310+
311+ drop ( io_mgr) ;
312+ assert_eq ! ( Arc :: strong_count( dev) , 3 ) ;
313+
314+ drop ( io_mgr2) ;
315+ assert_eq ! ( Arc :: strong_count( & dum) , 1 ) ;
316+ }
317+
279318 #[ test]
280319 fn test_register_unregister_device_io ( ) {
281320 let mut io_mgr = IoManager :: new ( ) ;
0 commit comments