Skip to content

Commit 973596f

Browse files
dianpopaalxiord
authored andcommitted
vmm: refactor start_microvm function
* separate function for seting up the interrupt controller * init_devices was renamed to attach_virtio_devices * init_microvm was removed since its functionality was moved to the relevant functions * created new functions for attaching legacy devices * added unit tests Signed-off-by: Diana Popa <[email protected]>
1 parent 0ce3b0e commit 973596f

File tree

2 files changed

+77
-35
lines changed

2 files changed

+77
-35
lines changed

tests/integration_tests/build/test_coverage.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import host_tools.cargo_build as host # pylint: disable=import-error
2020

21-
COVERAGE_TARGET_PCT = 82.8
21+
COVERAGE_TARGET_PCT = 83.2
2222
COVERAGE_MAX_DELTA = 0.01
2323

2424
CARGO_KCOV_REL_PATH = os.path.join(host.CARGO_BUILD_REL_PATH, 'kcov')

vmm/src/lib.rs

+76-34
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,16 @@ impl Vmm {
907907
let arch_mem_regions = arch::arch_memory_regions(mem_size);
908908
self.guest_memory =
909909
Some(GuestMemory::new(&arch_mem_regions).map_err(StartMicrovmError::GuestMemory)?);
910+
self.vm
911+
.memory_init(
912+
self.guest_memory
913+
.clone()
914+
.ok_or(StartMicrovmError::GuestMemory(
915+
memory_model::GuestMemoryError::MemoryNotInitialized,
916+
))?,
917+
&self.kvm,
918+
)
919+
.map_err(StartMicrovmError::ConfigureVm)?;
910920
Ok(())
911921
}
912922

@@ -917,7 +927,7 @@ impl Vmm {
917927
Ok(())
918928
}
919929

920-
fn init_devices(&mut self) -> std::result::Result<(), StartMicrovmError> {
930+
fn attach_virtio_devices(&mut self) -> std::result::Result<(), StartMicrovmError> {
921931
let guest_mem = self
922932
.guest_memory
923933
.clone()
@@ -938,21 +948,18 @@ impl Vmm {
938948
#[cfg(feature = "vsock")]
939949
self.attach_vsock_devices(&mut device_manager, &guest_mem)?;
940950

951+
// Register the associated IRQ events and IO events for the virtio devices.
952+
for request in &device_manager.vm_requests {
953+
if let VmResponse::Err(e) = request.execute(self.vm.get_fd()) {
954+
return Err(StartMicrovmError::DeviceVmRequest(e))?;
955+
}
956+
}
957+
941958
self.mmio_device_manager = Some(device_manager);
942959
Ok(())
943960
}
944961

945-
fn init_microvm(&mut self) -> std::result::Result<(), StartMicrovmError> {
946-
self.vm
947-
.memory_init(
948-
self.guest_memory
949-
.clone()
950-
.ok_or(StartMicrovmError::GuestMemory(
951-
memory_model::GuestMemoryError::MemoryNotInitialized,
952-
))?,
953-
&self.kvm,
954-
)
955-
.map_err(StartMicrovmError::ConfigureVm)?;
962+
fn setup_interrupt_controller(&mut self) -> std::result::Result<(), StartMicrovmError> {
956963
self.vm
957964
.setup_irqchip(
958965
&self.legacy_device_manager.com_evt_1_3,
@@ -964,18 +971,10 @@ impl Vmm {
964971
self.vm
965972
.create_pit()
966973
.map_err(StartMicrovmError::ConfigureVm)?;
974+
Ok(())
975+
}
967976

968-
// mmio_device_manager is instantiated in init_devices, which is called before init_microvm.
969-
let device_manager = self
970-
.mmio_device_manager
971-
.as_ref()
972-
.ok_or(StartMicrovmError::DeviceManager)?;
973-
for request in &device_manager.vm_requests {
974-
if let VmResponse::Err(e) = request.execute(self.vm.get_fd()) {
975-
return Err(StartMicrovmError::DeviceVmRequest(e))?;
976-
}
977-
}
978-
977+
fn attach_legacy_devices(&mut self) -> std::result::Result<(), StartMicrovmError> {
979978
self.legacy_device_manager
980979
.register_devices()
981980
.map_err(StartMicrovmError::LegacyIOBus)?;
@@ -1273,9 +1272,12 @@ impl Vmm {
12731272
self.init_guest_memory()
12741273
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
12751274

1276-
self.init_devices()
1275+
self.setup_interrupt_controller()
1276+
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1277+
1278+
self.attach_virtio_devices()
12771279
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1278-
self.init_microvm()
1280+
self.attach_legacy_devices()
12791281
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
12801282

12811283
let entry_addr = self
@@ -2809,7 +2811,7 @@ mod tests {
28092811
vmm.default_kernel_config();
28102812
assert!(vmm.init_guest_memory().is_ok());
28112813

2812-
assert!(vmm.init_devices().is_ok());
2814+
assert!(vmm.attach_virtio_devices().is_ok());
28132815
}
28142816

28152817
#[test]
@@ -3039,21 +3041,15 @@ mod tests {
30393041
// Booting an actual guest and getting real data is covered by `kvm::tests::run_code_test`.
30403042
}
30413043

3042-
#[cfg(target_arch = "x86_64")]
30433044
#[test]
30443045
fn test_create_vcpus() {
30453046
let mut vmm = create_vmm_object(InstanceState::Uninitialized);
30463047
vmm.default_kernel_config();
30473048

30483049
assert!(vmm.init_guest_memory().is_ok());
3049-
assert!(vmm.guest_memory.is_some());
3050-
let kvm = KvmContext::new().unwrap();
3051-
let guest_mem = vmm.guest_memory.clone().unwrap();
3052-
3053-
vmm.vm
3054-
.memory_init(guest_mem.clone(), &kvm)
3055-
.expect("Cannot initialize memory for test vm");
30563050
assert!(vmm.vm.get_memory().is_some());
3051+
3052+
#[cfg(target_arch = "x86_64")]
30573053
// `KVM_CREATE_VCPU` fails if the irqchip is not created beforehand. This is x86_64 speciifc.
30583054
vmm.vm
30593055
.setup_irqchip(
@@ -3064,4 +3060,50 @@ mod tests {
30643060
.expect("Cannot create IRQCHIP");
30653061
assert!(vmm.create_vcpus(GuestAddress(0x0)).is_ok());
30663062
}
3063+
3064+
#[test]
3065+
fn test_setup_interrupt_controller() {
3066+
let mut vmm = create_vmm_object(InstanceState::Uninitialized);
3067+
assert!(vmm.setup_interrupt_controller().is_ok());
3068+
}
3069+
3070+
#[test]
3071+
fn test_attach_virtio_devices() {
3072+
let mut vmm = create_vmm_object(InstanceState::Uninitialized);
3073+
vmm.default_kernel_config();
3074+
3075+
assert!(vmm.init_guest_memory().is_ok());
3076+
assert!(vmm.vm.get_memory().is_some());
3077+
3078+
// Create test network interface.
3079+
let network_interface = NetworkInterfaceConfig {
3080+
iface_id: String::from("netif"),
3081+
host_dev_name: String::from("hostname"),
3082+
guest_mac: None,
3083+
rx_rate_limiter: None,
3084+
tx_rate_limiter: None,
3085+
allow_mmds_requests: false,
3086+
tap: None,
3087+
};
3088+
3089+
assert!(vmm.insert_net_device(network_interface).is_ok());
3090+
assert!(vmm.attach_virtio_devices().is_ok());
3091+
assert!(vmm.mmio_device_manager.is_some());
3092+
// 2 io events and 1 irq event.
3093+
assert!(vmm.mmio_device_manager.unwrap().vm_requests.len() == 3);
3094+
}
3095+
3096+
#[test]
3097+
fn test_attach_legacy_devices() {
3098+
let mut vmm = create_vmm_object(InstanceState::Uninitialized);
3099+
3100+
assert!(vmm.attach_legacy_devices().is_ok());
3101+
assert!(vmm.legacy_device_manager.io_bus.get_device(0x3f8).is_some());
3102+
assert!(vmm.legacy_device_manager.io_bus.get_device(0x2f8).is_some());
3103+
assert!(vmm.legacy_device_manager.io_bus.get_device(0x3e8).is_some());
3104+
assert!(vmm.legacy_device_manager.io_bus.get_device(0x2e8).is_some());
3105+
assert!(vmm.legacy_device_manager.io_bus.get_device(0x060).is_some());
3106+
let stdin_handle = io::stdin();
3107+
stdin_handle.lock().set_canon_mode().unwrap();
3108+
}
30673109
}

0 commit comments

Comments
 (0)