@@ -274,8 +274,6 @@ pub mod aarch64 {
274274 vcpus. push ( vcpu) ;
275275 }
276276
277- setup_interrupt_controller ( vm, vcpu_count) ?;
278-
279277 Ok ( vcpus)
280278 }
281279
@@ -317,6 +315,9 @@ pub mod aarch64 {
317315 let vcpus = create_vcpus ( & mut vmm. vm , vm_config. vcpu_count , & vmm. vcpus_exit_evt )
318316 . map_err ( StartMicrovmError :: Internal ) ?;
319317
318+ setup_interrupt_controller ( & mut vmm. vm , vm_config. vcpu_count )
319+ . map_err ( StartMicrovmError :: Internal ) ?;
320+
320321 Ok ( ( vmm, vcpus) )
321322 }
322323}
@@ -459,6 +460,33 @@ pub mod x86_64 {
459460 kvm_capabilities,
460461 ) ?;
461462
463+ let pio_device_manager = {
464+ // Serial device setup.
465+ let serial_device = setup_serial_device ( std:: io:: stdin ( ) , io:: stdout ( ) )
466+ . map_err ( StartMicrovmError :: Internal ) ?;
467+
468+ // x86_64 uses the i8042 reset event as the Vmm exit event.
469+ let reset_evt = vmm
470+ . vcpus_exit_evt
471+ . try_clone ( )
472+ . map_err ( VmmError :: EventFd )
473+ . map_err ( StartMicrovmError :: Internal ) ?;
474+
475+ setup_interrupt_controller ( & mut vmm. vm ) . map_err ( StartMicrovmError :: Internal ) ?;
476+
477+ // create pio dev manager with legacy devices
478+ let pio_device_manager = {
479+ // TODO Remove these unwraps.
480+ let mut pio_dev_mgr = PortIODeviceManager :: new ( serial_device, reset_evt) . unwrap ( ) ;
481+ pio_dev_mgr. register_devices ( vmm. vm . fd ( ) ) . unwrap ( ) ;
482+ pio_dev_mgr
483+ } ;
484+
485+ pio_device_manager
486+ } ;
487+
488+ vmm. pio_device_manager = Some ( pio_device_manager) ;
489+
462490 let vcpus = create_vcpus ( & mut vmm. vm , vm_config. vcpu_count , & vmm. vcpus_exit_evt )
463491 . map_err ( StartMicrovmError :: Internal ) ?;
464492
@@ -499,33 +527,6 @@ fn build_vmm(
499527 // Instantiate ACPI device manager.
500528 let acpi_device_manager = ACPIDeviceManager :: new ( ) ;
501529
502- // For x86_64 we need to create the interrupt controller before calling `KVM_CREATE_VCPUS`
503- // while on aarch64 we need to do it the other way around.
504- #[ cfg( target_arch = "x86_64" ) ]
505- let pio_device_manager = {
506- // Serial device setup.
507- let serial_device =
508- setup_serial_device ( std:: io:: stdin ( ) , io:: stdout ( ) ) . map_err ( Internal ) ?;
509-
510- // x86_64 uses the i8042 reset event as the Vmm exit event.
511- let reset_evt = vcpus_exit_evt
512- . try_clone ( )
513- . map_err ( VmmError :: EventFd )
514- . map_err ( Internal ) ?;
515-
516- x86_64:: setup_interrupt_controller ( & mut vm) . map_err ( Internal ) ?;
517-
518- // create pio dev manager with legacy devices
519- let pio_device_manager = {
520- // TODO Remove these unwraps.
521- let mut pio_dev_mgr = PortIODeviceManager :: new ( serial_device, reset_evt) . unwrap ( ) ;
522- pio_dev_mgr. register_devices ( vm. fd ( ) ) . unwrap ( ) ;
523- pio_dev_mgr
524- } ;
525-
526- pio_device_manager
527- } ;
528-
529530 Ok ( Vmm {
530531 events_observer : Some ( std:: io:: stdin ( ) ) ,
531532 instance_info : instance_info. clone ( ) ,
@@ -538,7 +539,7 @@ fn build_vmm(
538539 resource_allocator,
539540 mmio_device_manager,
540541 #[ cfg( target_arch = "x86_64" ) ]
541- pio_device_manager,
542+ pio_device_manager : None ,
542543 acpi_device_manager,
543544 } )
544545}
@@ -590,7 +591,9 @@ pub fn build_microvm_for_boot(
590591 cpu_template. kvm_capabilities . clone ( ) ,
591592 ) ?;
592593 #[ cfg( target_arch = "x86_64" ) ]
593- event_manager. add_subscriber ( vmm. pio_device_manager . stdio_serial . clone ( ) ) ;
594+ if let Some ( pio_manager) = & vmm. pio_device_manager {
595+ event_manager. add_subscriber ( pio_manager. stdio_serial . clone ( ) ) ;
596+ }
594597
595598 #[ cfg( target_arch = "aarch64" ) ]
596599 let ( mut vmm, mut vcpus) = aarch64:: create_vmm_and_vcpus (
@@ -801,7 +804,9 @@ pub fn build_microvm_from_snapshot(
801804 microvm_state. vm_state . kvm_cap_modifiers . clone ( ) ,
802805 ) ?;
803806 #[ cfg( target_arch = "x86_64" ) ]
804- event_manager. add_subscriber ( vmm. pio_device_manager . stdio_serial . clone ( ) ) ;
807+ if let Some ( pio_manager) = & vmm. pio_device_manager {
808+ event_manager. add_subscriber ( pio_manager. stdio_serial . clone ( ) ) ;
809+ }
805810 #[ cfg( target_arch = "aarch64" ) ]
806811 let ( mut vmm, mut vcpus) = aarch64:: create_vmm_and_vcpus (
807812 instance_info,
@@ -1281,7 +1286,7 @@ pub mod tests {
12811286 resource_allocator : ResourceAllocator :: new ( ) . unwrap ( ) ,
12821287 mmio_device_manager,
12831288 #[ cfg( target_arch = "x86_64" ) ]
1284- pio_device_manager,
1289+ pio_device_manager : Some ( pio_device_manager ) ,
12851290 acpi_device_manager,
12861291 }
12871292 }
0 commit comments