Skip to content

Commit 924432c

Browse files
committed
refactor: use vm_device::Bus as the MMIO bus
Use the vm_device::Bus bus for all MMIO devices. This mainly to prepare for using it for PCIe devices. Also, sepate VirtIO devices from other MMIO devices inside the MMIODeviceManager struct. This makes iterating over VirtIO devices since we don't need to access two data structures as to get a reference to a VirtIO device any more. Signed-off-by: Babis Chalios <bchalios@amazon.es>
1 parent 809f770 commit 924432c

File tree

15 files changed

+473
-498
lines changed

15 files changed

+473
-498
lines changed

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

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@
55
// Use of this source code is governed by a BSD-style license that can be
66
// found in the THIRD-PARTY file.
77

8-
use std::collections::HashMap;
98
use std::ffi::CString;
109
use std::fmt::Debug;
1110

1211
use vm_fdt::{Error as VmFdtError, FdtWriter, FdtWriterNode};
1312
use vm_memory::GuestMemoryError;
1413

15-
use super::super::DeviceType;
1614
use super::cache_info::{CacheEntry, read_cache_config};
1715
use super::gic::GICDevice;
1816
use crate::device_manager::mmio::MMIODeviceInfo;
@@ -55,12 +53,15 @@ pub enum FdtError {
5553
WriteFdtToMemory(#[from] GuestMemoryError),
5654
}
5755

56+
#[allow(clippy::too_many_arguments)]
5857
/// Creates the flattened device tree for this aarch64 microVM.
5958
pub fn create_fdt(
6059
guest_mem: &GuestMemoryMmap,
6160
vcpu_mpidr: Vec<u64>,
6261
cmdline: CString,
63-
device_info: &HashMap<(DeviceType, String), MMIODeviceInfo>,
62+
virtio_devices: Vec<&MMIODeviceInfo>,
63+
rtc: Option<&MMIODeviceInfo>,
64+
serial: Option<&MMIODeviceInfo>,
6465
gic_device: &GICDevice,
6566
vmgenid: &Option<VmGenId>,
6667
initrd: &Option<InitrdConfig>,
@@ -89,7 +90,7 @@ pub fn create_fdt(
8990
create_timer_node(&mut fdt_writer)?;
9091
create_clock_node(&mut fdt_writer)?;
9192
create_psci_node(&mut fdt_writer)?;
92-
create_devices_node(&mut fdt_writer, device_info)?;
93+
create_devices_node(&mut fdt_writer, virtio_devices, rtc, serial)?;
9394
create_vmgenid_node(&mut fdt_writer, vmgenid)?;
9495

9596
// End Header node.
@@ -411,25 +412,21 @@ fn create_rtc_node(fdt: &mut FdtWriter, dev_info: &MMIODeviceInfo) -> Result<(),
411412

412413
fn create_devices_node(
413414
fdt: &mut FdtWriter,
414-
dev_info: &HashMap<(DeviceType, String), MMIODeviceInfo>,
415+
mut virtio_devices: Vec<&MMIODeviceInfo>,
416+
rtc: Option<&MMIODeviceInfo>,
417+
serial: Option<&MMIODeviceInfo>,
415418
) -> Result<(), FdtError> {
416-
// Create one temp Vec to store all virtio devices
417-
let mut ordered_virtio_device: Vec<&MMIODeviceInfo> = Vec::new();
418-
419-
for ((device_type, _device_id), info) in dev_info {
420-
match device_type {
421-
DeviceType::BootTimer => (), // since it's not a real device
422-
DeviceType::Rtc => create_rtc_node(fdt, info)?,
423-
DeviceType::Serial => create_serial_node(fdt, info)?,
424-
DeviceType::Virtio(_) => {
425-
ordered_virtio_device.push(info);
426-
}
427-
}
419+
if let Some(device_info) = rtc {
420+
create_rtc_node(fdt, device_info)?;
421+
}
422+
423+
if let Some(device_info) = serial {
424+
create_serial_node(fdt, device_info)?;
428425
}
429426

430427
// Sort out virtio devices by address from low to high and insert them into fdt table.
431-
ordered_virtio_device.sort_by_key(|a| a.addr);
432-
for ordered_device_info in ordered_virtio_device.drain(..) {
428+
virtio_devices.sort_by_key(|a| a.addr);
429+
for ordered_device_info in virtio_devices.drain(..) {
433430
create_virtio_node(fdt, ordered_device_info)?;
434431
}
435432

@@ -465,43 +462,32 @@ mod tests {
465462
fn test_create_fdt_with_devices() {
466463
let mem = arch_mem(layout::FDT_MAX_SIZE + 0x1000);
467464

468-
let dev_info: HashMap<(DeviceType, std::string::String), MMIODeviceInfo> = [
469-
(
470-
(DeviceType::Serial, DeviceType::Serial.to_string()),
471-
MMIODeviceInfo {
472-
addr: 0x00,
473-
irq: NonZeroU32::new(1),
474-
len: LEN,
475-
},
476-
),
477-
(
478-
(DeviceType::Virtio(1), "virtio".to_string()),
479-
MMIODeviceInfo {
480-
addr: LEN,
481-
irq: NonZeroU32::new(2),
482-
len: LEN,
483-
},
484-
),
485-
(
486-
(DeviceType::Rtc, "rtc".to_string()),
487-
MMIODeviceInfo {
488-
addr: 2 * LEN,
489-
irq: NonZeroU32::new(3),
490-
len: LEN,
491-
},
492-
),
493-
]
494-
.iter()
495-
.cloned()
496-
.collect();
465+
let serial = MMIODeviceInfo {
466+
addr: 0x00,
467+
irq: NonZeroU32::new(1),
468+
len: LEN,
469+
};
470+
let virtio_device = MMIODeviceInfo {
471+
addr: LEN,
472+
irq: NonZeroU32::new(2),
473+
len: LEN,
474+
};
475+
let rtc = MMIODeviceInfo {
476+
addr: 2 * LEN,
477+
irq: NonZeroU32::new(3),
478+
len: LEN,
479+
};
480+
497481
let kvm = Kvm::new().unwrap();
498482
let vm = kvm.create_vm().unwrap();
499483
let gic = create_gic(&vm, 1, None).unwrap();
500484
create_fdt(
501485
&mem,
502486
vec![0],
503487
CString::new("console=tty0").unwrap(),
504-
&dev_info,
488+
vec![&virtio_device],
489+
Some(&rtc),
490+
Some(&serial),
505491
&gic,
506492
&None,
507493
&None,
@@ -521,7 +507,9 @@ mod tests {
521507
&mem,
522508
vec![0],
523509
CString::new("console=tty0").unwrap(),
524-
&HashMap::<(DeviceType, std::string::String), MMIODeviceInfo>::new(),
510+
Vec::new(),
511+
None,
512+
None,
525513
&gic,
526514
&Some(vmgenid),
527515
&None,
@@ -546,7 +534,9 @@ mod tests {
546534
&mem,
547535
vec![0],
548536
CString::new("console=tty0").unwrap(),
549-
&HashMap::<(DeviceType, std::string::String), MMIODeviceInfo>::new(),
537+
Vec::new(),
538+
None,
539+
None,
550540
&gic,
551541
&None,
552542
&None,
@@ -608,7 +598,9 @@ mod tests {
608598
&mem,
609599
vec![0],
610600
CString::new("console=tty0").unwrap(),
611-
&HashMap::<(DeviceType, std::string::String), MMIODeviceInfo>::new(),
601+
vec![],
602+
None,
603+
None,
612604
&gic,
613605
&None,
614606
&Some(initrd),

src/vmm/src/arch/aarch64/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ pub fn configure_system_for_boot(
134134
vmm.vm.guest_memory(),
135135
vcpu_mpidr,
136136
cmdline,
137-
vmm.mmio_device_manager.get_device_info(),
137+
vmm.mmio_device_manager.virtio_device_info(),
138+
vmm.mmio_device_manager.rtc_device_info(),
139+
vmm.mmio_device_manager.serial_device_info(),
138140
vmm.vm.get_irqchip(),
139141
&vmm.acpi_device_manager.vmgenid,
140142
initrd,

src/vmm/src/arch/aarch64/vcpu.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use std::fmt::{Debug, Write};
99
use std::mem::offset_of;
10+
use std::sync::Arc;
1011

1112
use kvm_bindings::*;
1213
use kvm_ioctls::{VcpuExit, VcpuFd, VmFd};
@@ -126,7 +127,7 @@ pub struct KvmVcpu {
126127
#[derive(Default, Debug)]
127128
pub struct Peripherals {
128129
/// mmio bus.
129-
pub mmio_bus: Option<crate::devices::Bus>,
130+
pub mmio_bus: Option<Arc<vm_device::Bus>>,
130131
}
131132

132133
impl KvmVcpu {

src/vmm/src/arch/x86_64/vcpu.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use std::collections::BTreeMap;
99
use std::fmt::Debug;
10+
use std::sync::Arc;
1011

1112
use kvm_bindings::{
1213
CpuId, KVM_MAX_CPUID_ENTRIES, KVM_MAX_MSR_ENTRIES, Msrs, Xsave, kvm_debugregs, kvm_lapic_state,
@@ -161,7 +162,7 @@ pub struct Peripherals {
161162
/// Pio bus.
162163
pub pio_bus: Option<crate::devices::Bus>,
163164
/// Mmio bus.
164-
pub mmio_bus: Option<crate::devices::Bus>,
165+
pub mmio_bus: Option<Arc<vm_device::Bus>>,
165166
}
166167

167168
impl KvmVcpu {

src/vmm/src/builder.rs

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,11 @@ fn attach_legacy_devices_aarch64(
615615
if cmdline_contains_console {
616616
// Make stdout non-blocking.
617617
set_stdout_nonblocking();
618-
let serial = setup_serial_device(event_manager)?;
618+
let serial = Arc::new(Mutex::new(
619+
SerialDevice::new(Some(std::io::stdin()), SerialOut::Stdout(std::io::stdout()))
620+
.map_err(VmmError::EventFd)?,
621+
));
622+
event_manager.add_subscriber(serial.clone());
619623
vmm.mmio_device_manager
620624
.register_mmio_serial(vmm.vm.fd(), &mut vmm.resource_allocator, serial, None)
621625
.map_err(VmmError::RegisterMMIODevice)?;
@@ -800,7 +804,6 @@ pub(crate) mod tests {
800804
use vmm_sys_util::tempfile::TempFile;
801805

802806
use super::*;
803-
use crate::arch::DeviceType;
804807
use crate::device_manager::resources::ResourceAllocator;
805808
#[cfg(target_arch = "x86_64")]
806809
use crate::devices::legacy::serial::SerialOut;
@@ -999,7 +1002,7 @@ pub(crate) mod tests {
9991002

10001003
assert!(
10011004
vmm.mmio_device_manager
1002-
.get_device(DeviceType::Virtio(TYPE_VSOCK), &vsock_dev_id)
1005+
.get_virtio_device(TYPE_VSOCK, &vsock_dev_id)
10031006
.is_some()
10041007
);
10051008
}
@@ -1017,7 +1020,7 @@ pub(crate) mod tests {
10171020

10181021
assert!(
10191022
vmm.mmio_device_manager
1020-
.get_device(DeviceType::Virtio(TYPE_RNG), ENTROPY_DEV_ID)
1023+
.get_virtio_device(TYPE_RNG, ENTROPY_DEV_ID)
10211024
.is_some()
10221025
);
10231026
}
@@ -1042,7 +1045,7 @@ pub(crate) mod tests {
10421045

10431046
assert!(
10441047
vmm.mmio_device_manager
1045-
.get_device(DeviceType::Virtio(TYPE_BALLOON), BALLOON_DEV_ID)
1048+
.get_virtio_device(TYPE_BALLOON, BALLOON_DEV_ID)
10461049
.is_some()
10471050
);
10481051
}
@@ -1093,7 +1096,7 @@ pub(crate) mod tests {
10931096
assert!(cmdline_contains(&cmdline, "root=/dev/vda ro"));
10941097
assert!(
10951098
vmm.mmio_device_manager
1096-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1099+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
10971100
.is_some()
10981101
);
10991102
}
@@ -1114,7 +1117,7 @@ pub(crate) mod tests {
11141117
assert!(cmdline_contains(&cmdline, "root=PARTUUID=0eaa91a0-01 rw"));
11151118
assert!(
11161119
vmm.mmio_device_manager
1117-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1120+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
11181121
.is_some()
11191122
);
11201123
}
@@ -1136,7 +1139,7 @@ pub(crate) mod tests {
11361139
assert!(!cmdline_contains(&cmdline, "root=/dev/vda"));
11371140
assert!(
11381141
vmm.mmio_device_manager
1139-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1142+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
11401143
.is_some()
11411144
);
11421145
}
@@ -1173,17 +1176,17 @@ pub(crate) mod tests {
11731176
assert!(cmdline_contains(&cmdline, "root=PARTUUID=0eaa91a0-01 rw"));
11741177
assert!(
11751178
vmm.mmio_device_manager
1176-
.get_device(DeviceType::Virtio(TYPE_BLOCK), "root")
1179+
.get_virtio_device(TYPE_BLOCK, "root")
11771180
.is_some()
11781181
);
11791182
assert!(
11801183
vmm.mmio_device_manager
1181-
.get_device(DeviceType::Virtio(TYPE_BLOCK), "secondary")
1184+
.get_virtio_device(TYPE_BLOCK, "secondary")
11821185
.is_some()
11831186
);
11841187
assert!(
11851188
vmm.mmio_device_manager
1186-
.get_device(DeviceType::Virtio(TYPE_BLOCK), "third")
1189+
.get_virtio_device(TYPE_BLOCK, "third")
11871190
.is_some()
11881191
);
11891192

@@ -1212,7 +1215,7 @@ pub(crate) mod tests {
12121215
assert!(cmdline_contains(&cmdline, "root=/dev/vda rw"));
12131216
assert!(
12141217
vmm.mmio_device_manager
1215-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1218+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
12161219
.is_some()
12171220
);
12181221
}
@@ -1233,7 +1236,7 @@ pub(crate) mod tests {
12331236
assert!(cmdline_contains(&cmdline, "root=PARTUUID=0eaa91a0-01 ro"));
12341237
assert!(
12351238
vmm.mmio_device_manager
1236-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1239+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
12371240
.is_some()
12381241
);
12391242
}
@@ -1254,7 +1257,7 @@ pub(crate) mod tests {
12541257
assert!(cmdline_contains(&cmdline, "root=/dev/vda rw"));
12551258
assert!(
12561259
vmm.mmio_device_manager
1257-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1260+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
12581261
.is_some()
12591262
);
12601263
}
@@ -1267,11 +1270,7 @@ pub(crate) mod tests {
12671270

12681271
let res = attach_boot_timer_device(&mut vmm, request_ts);
12691272
res.unwrap();
1270-
assert!(
1271-
vmm.mmio_device_manager
1272-
.get_device(DeviceType::BootTimer, &DeviceType::BootTimer.to_string())
1273-
.is_some()
1274-
);
1273+
assert!(vmm.mmio_device_manager.boot_timer.is_some());
12751274
}
12761275

12771276
#[test]

0 commit comments

Comments
 (0)