Skip to content

Commit a6c7c95

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 4a4aaf5 commit a6c7c95

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};
@@ -121,7 +122,7 @@ pub struct KvmVcpu {
121122
#[derive(Default, Debug)]
122123
pub struct Peripherals {
123124
/// mmio bus.
124-
pub mmio_bus: Option<crate::devices::Bus>,
125+
pub mmio_bus: Option<Arc<vm_device::Bus>>,
125126
}
126127

127128
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
@@ -555,7 +555,11 @@ fn attach_legacy_devices_aarch64(
555555
if cmdline_contains_console {
556556
// Make stdout non-blocking.
557557
set_stdout_nonblocking();
558-
let serial = setup_serial_device(event_manager)?;
558+
let serial = Arc::new(Mutex::new(
559+
SerialDevice::new(Some(std::io::stdin()), SerialOut::Stdout(std::io::stdout()))
560+
.map_err(VmmError::EventFd)?,
561+
));
562+
event_manager.add_subscriber(serial.clone());
559563
vmm.mmio_device_manager
560564
.register_mmio_serial(vmm.vm.fd(), &mut vmm.resource_allocator, serial, None)
561565
.map_err(VmmError::RegisterMMIODevice)?;
@@ -740,7 +744,6 @@ pub(crate) mod tests {
740744
use vmm_sys_util::tempfile::TempFile;
741745

742746
use super::*;
743-
use crate::arch::DeviceType;
744747
use crate::device_manager::resources::ResourceAllocator;
745748
#[cfg(target_arch = "x86_64")]
746749
use crate::devices::legacy::serial::SerialOut;
@@ -939,7 +942,7 @@ pub(crate) mod tests {
939942

940943
assert!(
941944
vmm.mmio_device_manager
942-
.get_device(DeviceType::Virtio(TYPE_VSOCK), &vsock_dev_id)
945+
.get_virtio_device(TYPE_VSOCK, &vsock_dev_id)
943946
.is_some()
944947
);
945948
}
@@ -957,7 +960,7 @@ pub(crate) mod tests {
957960

958961
assert!(
959962
vmm.mmio_device_manager
960-
.get_device(DeviceType::Virtio(TYPE_RNG), ENTROPY_DEV_ID)
963+
.get_virtio_device(TYPE_RNG, ENTROPY_DEV_ID)
961964
.is_some()
962965
);
963966
}
@@ -982,7 +985,7 @@ pub(crate) mod tests {
982985

983986
assert!(
984987
vmm.mmio_device_manager
985-
.get_device(DeviceType::Virtio(TYPE_BALLOON), BALLOON_DEV_ID)
988+
.get_virtio_device(TYPE_BALLOON, BALLOON_DEV_ID)
986989
.is_some()
987990
);
988991
}
@@ -1033,7 +1036,7 @@ pub(crate) mod tests {
10331036
assert!(cmdline_contains(&cmdline, "root=/dev/vda ro"));
10341037
assert!(
10351038
vmm.mmio_device_manager
1036-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1039+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
10371040
.is_some()
10381041
);
10391042
}
@@ -1054,7 +1057,7 @@ pub(crate) mod tests {
10541057
assert!(cmdline_contains(&cmdline, "root=PARTUUID=0eaa91a0-01 rw"));
10551058
assert!(
10561059
vmm.mmio_device_manager
1057-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1060+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
10581061
.is_some()
10591062
);
10601063
}
@@ -1076,7 +1079,7 @@ pub(crate) mod tests {
10761079
assert!(!cmdline_contains(&cmdline, "root=/dev/vda"));
10771080
assert!(
10781081
vmm.mmio_device_manager
1079-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1082+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
10801083
.is_some()
10811084
);
10821085
}
@@ -1113,17 +1116,17 @@ pub(crate) mod tests {
11131116
assert!(cmdline_contains(&cmdline, "root=PARTUUID=0eaa91a0-01 rw"));
11141117
assert!(
11151118
vmm.mmio_device_manager
1116-
.get_device(DeviceType::Virtio(TYPE_BLOCK), "root")
1119+
.get_virtio_device(TYPE_BLOCK, "root")
11171120
.is_some()
11181121
);
11191122
assert!(
11201123
vmm.mmio_device_manager
1121-
.get_device(DeviceType::Virtio(TYPE_BLOCK), "secondary")
1124+
.get_virtio_device(TYPE_BLOCK, "secondary")
11221125
.is_some()
11231126
);
11241127
assert!(
11251128
vmm.mmio_device_manager
1126-
.get_device(DeviceType::Virtio(TYPE_BLOCK), "third")
1129+
.get_virtio_device(TYPE_BLOCK, "third")
11271130
.is_some()
11281131
);
11291132

@@ -1152,7 +1155,7 @@ pub(crate) mod tests {
11521155
assert!(cmdline_contains(&cmdline, "root=/dev/vda rw"));
11531156
assert!(
11541157
vmm.mmio_device_manager
1155-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1158+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
11561159
.is_some()
11571160
);
11581161
}
@@ -1173,7 +1176,7 @@ pub(crate) mod tests {
11731176
assert!(cmdline_contains(&cmdline, "root=PARTUUID=0eaa91a0-01 ro"));
11741177
assert!(
11751178
vmm.mmio_device_manager
1176-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1179+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
11771180
.is_some()
11781181
);
11791182
}
@@ -1194,7 +1197,7 @@ pub(crate) mod tests {
11941197
assert!(cmdline_contains(&cmdline, "root=/dev/vda rw"));
11951198
assert!(
11961199
vmm.mmio_device_manager
1197-
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
1200+
.get_virtio_device(TYPE_BLOCK, drive_id.as_str())
11981201
.is_some()
11991202
);
12001203
}
@@ -1207,11 +1210,7 @@ pub(crate) mod tests {
12071210

12081211
let res = attach_boot_timer_device(&mut vmm, request_ts);
12091212
res.unwrap();
1210-
assert!(
1211-
vmm.mmio_device_manager
1212-
.get_device(DeviceType::BootTimer, &DeviceType::BootTimer.to_string())
1213-
.is_some()
1214-
);
1213+
assert!(vmm.mmio_device_manager.boot_timer.is_some());
12151214
}
12161215

12171216
#[test]

0 commit comments

Comments
 (0)