Skip to content

Commit 0b19482

Browse files
committed
vm: track device interrupts within Vm object
Add logic to track the device interrupts used by the microVM. This is not strictly needed right now, but we will need it when adding support for MSI-X interrupts. MSI-X interrupts are configured at runtime and we need to interact with KVM to set the interruput routes. To do it, we need to keep track all of the interrupts the VM is using. Signed-off-by: Babis Chalios <[email protected]>
1 parent d141b9b commit 0b19482

File tree

8 files changed

+131
-120
lines changed

8 files changed

+131
-120
lines changed

src/vmm/src/arch/aarch64/fdt.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -499,17 +499,16 @@ mod tests {
499499
use std::ffi::CString;
500500
use std::sync::{Arc, Mutex};
501501

502-
use kvm_ioctls::Kvm;
503502
use linux_loader::cmdline as kernel_cmdline;
504503

505504
use super::*;
506-
use crate::EventManager;
507505
use crate::arch::aarch64::gic::create_gic;
508506
use crate::arch::aarch64::layout;
509507
use crate::device_manager::mmio::tests::DummyDevice;
510508
use crate::device_manager::tests::default_device_manager;
511509
use crate::test_utils::arch_mem;
512510
use crate::vstate::memory::GuestAddress;
511+
use crate::{EventManager, Kvm, Vm};
513512

514513
// The `load` function from the `device_tree` will mistakenly check the actual size
515514
// of the buffer with the allocated size. This works around that.
@@ -525,9 +524,9 @@ mod tests {
525524
let mem = arch_mem(layout::FDT_MAX_SIZE + 0x1000);
526525
let mut event_manager = EventManager::new().unwrap();
527526
let mut device_manager = default_device_manager();
528-
let kvm = Kvm::new().unwrap();
529-
let vm = kvm.create_vm().unwrap();
530-
let gic = create_gic(&vm, 1, None).unwrap();
527+
let kvm = Kvm::new(vec![]).unwrap();
528+
let vm = Vm::new(&kvm).unwrap();
529+
let gic = create_gic(vm.fd(), 1, None).unwrap();
531530
let mut cmdline = kernel_cmdline::Cmdline::new(4096).unwrap();
532531
cmdline.insert("console", "/dev/tty0").unwrap();
533532

@@ -562,9 +561,9 @@ mod tests {
562561
fn test_create_fdt_with_vmgenid() {
563562
let mem = arch_mem(layout::FDT_MAX_SIZE + 0x1000);
564563
let mut device_manager = default_device_manager();
565-
let kvm = Kvm::new().unwrap();
566-
let vm = kvm.create_vm().unwrap();
567-
let gic = create_gic(&vm, 1, None).unwrap();
564+
let kvm = Kvm::new(vec![]).unwrap();
565+
let vm = Vm::new(&kvm).unwrap();
566+
let gic = create_gic(vm.fd(), 1, None).unwrap();
568567
let mut cmdline = kernel_cmdline::Cmdline::new(4096).unwrap();
569568
cmdline.insert("console", "/dev/tty0").unwrap();
570569

@@ -585,9 +584,9 @@ mod tests {
585584
fn test_create_fdt() {
586585
let mem = arch_mem(layout::FDT_MAX_SIZE + 0x1000);
587586
let device_manager = default_device_manager();
588-
let kvm = Kvm::new().unwrap();
589-
let vm = kvm.create_vm().unwrap();
590-
let gic = create_gic(&vm, 1, None).unwrap();
587+
let kvm = Kvm::new(vec![]).unwrap();
588+
let vm = Vm::new(&kvm).unwrap();
589+
let gic = create_gic(vm.fd(), 1, None).unwrap();
591590

592591
let saved_dtb_bytes = match gic.fdt_compatibility() {
593592
"arm,gic-v3" => include_bytes!("output_GICv3.dtb"),
@@ -642,9 +641,9 @@ mod tests {
642641
fn test_create_fdt_with_initrd() {
643642
let mem = arch_mem(layout::FDT_MAX_SIZE + 0x1000);
644643
let device_manager = default_device_manager();
645-
let kvm = Kvm::new().unwrap();
646-
let vm = kvm.create_vm().unwrap();
647-
let gic = create_gic(&vm, 1, None).unwrap();
644+
let kvm = Kvm::new(vec![]).unwrap();
645+
let vm = Vm::new(&kvm).unwrap();
646+
let gic = create_gic(vm.fd(), 1, None).unwrap();
648647

649648
let saved_dtb_bytes = match gic.fdt_compatibility() {
650649
"arm,gic-v3" => include_bytes!("output_initrd_GICv3.dtb"),

src/vmm/src/builder.rs

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -165,23 +165,14 @@ pub fn build_microvm_for_boot(
165165
.cpu_template
166166
.get_cpu_template()?;
167167

168-
/*
169-
let (mut vmm, mut vcpus) = create_vmm_and_vcpus(
170-
instance_info,
171-
event_manager,
172-
vm_resources.machine_config.vcpu_count,
173-
cpu_template.kvm_capabilities.clone(),
174-
)?;
175-
*/
176-
177168
let kvm = Kvm::new(cpu_template.kvm_capabilities.clone())?;
178169
// Set up Kvm Vm and register memory regions.
179170
// Build custom CPU config if a custom template is provided.
180171
let mut vm = Vm::new(&kvm)?;
181172
let (mut vcpus, vcpus_exit_evt) = vm.create_vcpus(vm_resources.machine_config.vcpu_count)?;
182173
vm.register_memory_regions(guest_memory)?;
183174

184-
let mut device_manager = DeviceManager::new(event_manager, &vcpus_exit_evt, vm.fd())?;
175+
let mut device_manager = DeviceManager::new(event_manager, &vcpus_exit_evt, &vm)?;
185176

186177
let entry_point = load_kernel(&boot_config.kernel_file, vm.guest_memory())?;
187178
let initrd = InitrdConfig::from_config(boot_config, vm.guest_memory())?;
@@ -257,9 +248,9 @@ pub fn build_microvm_for_boot(
257248
}
258249

259250
#[cfg(target_arch = "aarch64")]
260-
device_manager.attach_legacy_devices_aarch64(vm.fd(), event_manager, &mut boot_cmdline)?;
251+
device_manager.attach_legacy_devices_aarch64(&vm, event_manager, &mut boot_cmdline)?;
261252

262-
device_manager.attach_vmgenid_device(vm.guest_memory(), vm.fd())?;
253+
device_manager.attach_vmgenid_device(vm.guest_memory(), &vm)?;
263254

264255
#[cfg(target_arch = "aarch64")]
265256
if vcpus[0].kvm_vcpu.supports_pvtime() {
@@ -423,7 +414,7 @@ pub fn build_microvm_from_snapshot(
423414
.create_vcpus(vm_resources.machine_config.vcpu_count)
424415
.map_err(StartMicrovmError::Vm)?;
425416

426-
let mut device_manager = DeviceManager::new(event_manager, &vcpus_exit_evt, vm.fd()).unwrap();
417+
let mut device_manager = DeviceManager::new(event_manager, &vcpus_exit_evt, &vm).unwrap();
427418

428419
vm.register_memory_regions(guest_memory)
429420
.map_err(StartMicrovmError::Vm)?;
@@ -477,7 +468,7 @@ pub fn build_microvm_from_snapshot(
477468
// Restore devices states.
478469
let device_ctor_args = DeviceRestoreArgs {
479470
mem: vm.guest_memory(),
480-
vm: vm.fd(),
471+
vm: &vm,
481472
event_manager,
482473
vm_resources,
483474
instance_id: &instance_info.id,
@@ -580,14 +571,7 @@ fn attach_entropy_device(
580571
.to_string();
581572

582573
event_manager.add_subscriber(entropy_device.clone());
583-
device_manager.attach_virtio_device(
584-
vm.guest_memory(),
585-
vm.fd(),
586-
id,
587-
entropy_device.clone(),
588-
cmdline,
589-
false,
590-
)
574+
device_manager.attach_virtio_device(vm, id, entropy_device.clone(), cmdline, false)
591575
}
592576

593577
fn attach_block_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Block>>> + Debug>(
@@ -614,14 +598,7 @@ fn attach_block_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Block>>> + Debug>(
614598
};
615599
// The device mutex mustn't be locked here otherwise it will deadlock.
616600
event_manager.add_subscriber(block.clone());
617-
device_manager.attach_virtio_device(
618-
vm.guest_memory(),
619-
vm.fd(),
620-
id,
621-
block.clone(),
622-
cmdline,
623-
is_vhost_user,
624-
)?;
601+
device_manager.attach_virtio_device(vm, id, block.clone(), cmdline, is_vhost_user)?;
625602
}
626603
Ok(())
627604
}
@@ -637,14 +614,7 @@ fn attach_net_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Net>>> + Debug>(
637614
let id = net_device.lock().expect("Poisoned lock").id().clone();
638615
event_manager.add_subscriber(net_device.clone());
639616
// The device mutex mustn't be locked here otherwise it will deadlock.
640-
device_manager.attach_virtio_device(
641-
vm.guest_memory(),
642-
vm.fd(),
643-
id,
644-
net_device.clone(),
645-
cmdline,
646-
false,
647-
)?;
617+
device_manager.attach_virtio_device(vm, id, net_device.clone(), cmdline, false)?;
648618
}
649619
Ok(())
650620
}
@@ -659,14 +629,7 @@ fn attach_unixsock_vsock_device(
659629
let id = String::from(unix_vsock.lock().expect("Poisoned lock").id());
660630
event_manager.add_subscriber(unix_vsock.clone());
661631
// The device mutex mustn't be locked here otherwise it will deadlock.
662-
device_manager.attach_virtio_device(
663-
vm.guest_memory(),
664-
vm.fd(),
665-
id,
666-
unix_vsock.clone(),
667-
cmdline,
668-
false,
669-
)
632+
device_manager.attach_virtio_device(vm, id, unix_vsock.clone(), cmdline, false)
670633
}
671634

672635
fn attach_balloon_device(
@@ -679,14 +642,7 @@ fn attach_balloon_device(
679642
let id = String::from(balloon.lock().expect("Poisoned lock").id());
680643
event_manager.add_subscriber(balloon.clone());
681644
// The device mutex mustn't be locked here otherwise it will deadlock.
682-
device_manager.attach_virtio_device(
683-
vm.guest_memory(),
684-
vm.fd(),
685-
id,
686-
balloon.clone(),
687-
cmdline,
688-
false,
689-
)
645+
device_manager.attach_virtio_device(vm, id, balloon.clone(), cmdline, false)
690646
}
691647

692648
#[cfg(test)]
@@ -933,7 +889,7 @@ pub(crate) mod tests {
933889
#[cfg(target_arch = "x86_64")]
934890
pub(crate) fn insert_vmgenid_device(vmm: &mut Vmm) {
935891
vmm.device_manager
936-
.attach_vmgenid_device(vmm.vm.guest_memory(), vmm.vm.fd())
892+
.attach_vmgenid_device(vmm.vm.guest_memory(), &vmm.vm)
937893
.unwrap();
938894
assert!(vmm.device_manager.acpi_devices.vmgenid.is_some());
939895
}

src/vmm/src/device_manager/acpi.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use acpi_tables::{Aml, aml};
5-
use kvm_ioctls::VmFd;
65

6+
use crate::Vm;
77
use crate::devices::acpi::vmgenid::VmGenId;
88

99
#[derive(Debug, Default)]
@@ -21,12 +21,8 @@ impl ACPIDeviceManager {
2121
/// Attach a new VMGenID device to the microVM
2222
///
2323
/// This will register the device's interrupt with KVM
24-
pub fn attach_vmgenid(
25-
&mut self,
26-
vmgenid: VmGenId,
27-
vm_fd: &VmFd,
28-
) -> Result<(), kvm_ioctls::Error> {
29-
vm_fd.register_irqfd(&vmgenid.interrupt_evt, vmgenid.gsi)?;
24+
pub fn attach_vmgenid(&mut self, vmgenid: VmGenId, vm: &Vm) -> Result<(), kvm_ioctls::Error> {
25+
vm.register_irq(&vmgenid.interrupt_evt, vmgenid.gsi)?;
3026
self.vmgenid = Some(vmgenid);
3127
Ok(())
3228
}

src/vmm/src/device_manager/legacy.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ use std::sync::{Arc, Mutex};
1111

1212
use acpi_tables::aml::AmlError;
1313
use acpi_tables::{Aml, aml};
14-
use kvm_ioctls::VmFd;
1514
use libc::EFD_NONBLOCK;
1615
use vm_superio::Serial;
1716
use vmm_sys_util::eventfd::EventFd;
1817

18+
use crate::Vm;
1919
use crate::devices::legacy::serial::SerialOut;
2020
use crate::devices::legacy::{EventFdTrigger, I8042Device, SerialDevice, SerialEventsWrapper};
2121

@@ -100,7 +100,7 @@ impl PortIODeviceManager {
100100
pub fn register_devices(
101101
&mut self,
102102
io_bus: &vm_device::Bus,
103-
vm_fd: &VmFd,
103+
vm: &Vm,
104104
) -> Result<(), LegacyDeviceError> {
105105
let serial_2_4 = Arc::new(Mutex::new(SerialDevice {
106106
serial: Serial::with_events(
@@ -148,18 +148,15 @@ impl PortIODeviceManager {
148148
Self::I8042_KDB_DATA_REGISTER_SIZE,
149149
)?;
150150

151-
vm_fd
152-
.register_irqfd(&self.com_evt_1_3, Self::COM_EVT_1_3_GSI)
151+
vm.register_irq(&self.com_evt_1_3, Self::COM_EVT_1_3_GSI)
153152
.map_err(|e| {
154153
LegacyDeviceError::EventFd(std::io::Error::from_raw_os_error(e.errno()))
155154
})?;
156-
vm_fd
157-
.register_irqfd(&self.com_evt_2_4, Self::COM_EVT_2_4_GSI)
155+
vm.register_irq(&self.com_evt_2_4, Self::COM_EVT_2_4_GSI)
158156
.map_err(|e| {
159157
LegacyDeviceError::EventFd(std::io::Error::from_raw_os_error(e.errno()))
160158
})?;
161-
vm_fd
162-
.register_irqfd(&self.kbd_evt, Self::KBD_EVT_GSI)
159+
vm.register_irq(&self.kbd_evt, Self::KBD_EVT_GSI)
163160
.map_err(|e| {
164161
LegacyDeviceError::EventFd(std::io::Error::from_raw_os_error(e.errno()))
165162
})?;
@@ -264,6 +261,6 @@ mod tests {
264261
)),
265262
)
266263
.unwrap();
267-
ldm.register_devices(&io_bus, vm.fd()).unwrap();
264+
ldm.register_devices(&io_bus, &vm).unwrap();
268265
}
269266
}

0 commit comments

Comments
 (0)