Skip to content

Commit 6c721ea

Browse files
committed
Refactor Bus and BusDevice
Bus has been refactored to store a Vec of BusDevices, and the BusDevice enum now stores ArcMutexes of the actual devices. This does not change any of the existing functionality, however it additionally allows the devices to be shared. This is needed for vCPU hotplugging, as the CpuContainer struct has to be accessed by both the MMIODeviceManager and ACPIDeviceManager. Signed-off-by: James Curtis <[email protected]>
1 parent 680b8c1 commit 6c721ea

File tree

8 files changed

+89
-167
lines changed

8 files changed

+89
-167
lines changed

src/vmm/src/builder.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,15 @@ use crate::devices::acpi::vmgenid::{VmGenId, VmGenIdError};
5252
use crate::devices::legacy::serial::SerialOut;
5353
#[cfg(target_arch = "aarch64")]
5454
use crate::devices::legacy::RTCDevice;
55-
use crate::devices::legacy::{EventFdTrigger, SerialEventsWrapper, SerialWrapper};
55+
use crate::devices::legacy::{EventFdTrigger, SerialDevice, SerialEventsWrapper, SerialWrapper};
5656
use crate::devices::virtio::balloon::Balloon;
5757
use crate::devices::virtio::block::device::Block;
5858
use crate::devices::virtio::device::VirtioDevice;
5959
use crate::devices::virtio::mmio::MmioTransport;
6060
use crate::devices::virtio::net::Net;
6161
use crate::devices::virtio::rng::Entropy;
6262
use crate::devices::virtio::vsock::{Vsock, VsockUnixBackend};
63+
#[cfg(target_arch = "x86_64")]
6364
use crate::devices::BusDevice;
6465
use crate::logger::{debug, error};
6566
use crate::persist::{MicrovmState, MicrovmStateError};
@@ -697,11 +698,11 @@ pub fn setup_serial_device(
697698
event_manager: &mut EventManager,
698699
input: std::io::Stdin,
699700
out: std::io::Stdout,
700-
) -> Result<Arc<Mutex<BusDevice>>, VmmError> {
701+
) -> Result<Arc<Mutex<SerialDevice<std::io::Stdin>>>, VmmError> {
701702
let interrupt_evt = EventFdTrigger::new(EventFd::new(EFD_NONBLOCK).map_err(VmmError::EventFd)?);
702703
let kick_stdin_read_evt =
703704
EventFdTrigger::new(EventFd::new(EFD_NONBLOCK).map_err(VmmError::EventFd)?);
704-
let serial = Arc::new(Mutex::new(BusDevice::Serial(SerialWrapper {
705+
let serial = Arc::new(Mutex::new(SerialWrapper {
705706
serial: Serial::with_events(
706707
interrupt_evt,
707708
SerialEventsWrapper {
@@ -710,7 +711,7 @@ pub fn setup_serial_device(
710711
SerialOut::Stdout(out),
711712
),
712713
input: Some(input),
713-
})));
714+
}));
714715
event_manager.add_subscriber(serial.clone());
715716
Ok(serial)
716717
}
@@ -1130,7 +1131,7 @@ pub mod tests {
11301131
let acpi_device_manager = ACPIDeviceManager::new();
11311132
#[cfg(target_arch = "x86_64")]
11321133
let pio_device_manager = PortIODeviceManager::new(
1133-
Arc::new(Mutex::new(BusDevice::Serial(SerialWrapper {
1134+
Arc::new(Mutex::new(SerialWrapper {
11341135
serial: Serial::with_events(
11351136
EventFdTrigger::new(EventFd::new(EFD_NONBLOCK).unwrap()),
11361137
SerialEventsWrapper {
@@ -1139,7 +1140,7 @@ pub mod tests {
11391140
SerialOut::Sink(std::io::sink()),
11401141
),
11411142
input: None,
1142-
}))),
1143+
})),
11431144
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
11441145
)
11451146
.unwrap();

src/vmm/src/device_manager/legacy.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#![cfg(target_arch = "x86_64")]
88

99
use std::fmt::Debug;
10+
use std::io::Stdin;
1011
use std::sync::{Arc, Mutex};
1112

1213
use acpi_tables::{aml, Aml};
@@ -17,7 +18,7 @@ use vm_superio::Serial;
1718

1819
use crate::devices::bus::BusDevice;
1920
use crate::devices::legacy::serial::SerialOut;
20-
use crate::devices::legacy::{EventFdTrigger, SerialDevice, SerialEventsWrapper};
21+
use crate::devices::legacy::{EventFdTrigger, I8042Device, SerialDevice, SerialEventsWrapper};
2122

2223
/// Errors corresponding to the `PortIODeviceManager`.
2324
#[derive(Debug, derive_more::From, thiserror::Error, displaydoc::Display)]
@@ -35,9 +36,9 @@ pub enum LegacyDeviceError {
3536
pub struct PortIODeviceManager {
3637
pub io_bus: crate::devices::Bus,
3738
// BusDevice::Serial
38-
pub stdio_serial: Arc<Mutex<BusDevice>>,
39+
pub stdio_serial: Arc<Mutex<SerialDevice<Stdin>>>,
3940
// BusDevice::I8042Device
40-
pub i8042: Arc<Mutex<BusDevice>>,
41+
pub i8042: Arc<Mutex<I8042Device>>,
4142

4243
// Communication event on ports 1 & 3.
4344
pub com_evt_1_3: EventFdTrigger,
@@ -72,24 +73,22 @@ impl PortIODeviceManager {
7273

7374
/// Create a new DeviceManager handling legacy devices (uart, i8042).
7475
pub fn new(
75-
serial: Arc<Mutex<BusDevice>>,
76+
serial: Arc<Mutex<SerialDevice<std::io::Stdin>>>,
7677
i8042_reset_evfd: EventFd,
7778
) -> Result<Self, LegacyDeviceError> {
78-
debug_assert!(matches!(*serial.lock().unwrap(), BusDevice::Serial(_)));
7979
let io_bus = crate::devices::Bus::new();
8080
let com_evt_1_3 = serial
8181
.lock()
8282
.expect("Poisoned lock")
83-
.serial_mut()
84-
.unwrap()
8583
.serial
8684
.interrupt_evt()
8785
.try_clone()?;
8886
let com_evt_2_4 = EventFdTrigger::new(EventFd::new(EFD_NONBLOCK)?);
8987
let kbd_evt = EventFd::new(libc::EFD_NONBLOCK)?;
9088

91-
let i8042 = Arc::new(Mutex::new(BusDevice::I8042Device(
92-
crate::devices::legacy::I8042Device::new(i8042_reset_evfd, kbd_evt.try_clone()?),
89+
let i8042 = Arc::new(Mutex::new(crate::devices::legacy::I8042Device::new(
90+
i8042_reset_evfd,
91+
kbd_evt.try_clone()?,
9392
)));
9493

9594
Ok(PortIODeviceManager {
@@ -104,7 +103,7 @@ impl PortIODeviceManager {
104103

105104
/// Register supported legacy devices.
106105
pub fn register_devices(&mut self, vm_fd: &VmFd) -> Result<(), LegacyDeviceError> {
107-
let serial_2_4 = Arc::new(Mutex::new(BusDevice::Serial(SerialDevice {
106+
let serial_2_4 = BusDevice::Serial(Arc::new(Mutex::new(SerialDevice {
108107
serial: Serial::with_events(
109108
self.com_evt_2_4.try_clone()?.try_clone()?,
110109
SerialEventsWrapper {
@@ -114,7 +113,7 @@ impl PortIODeviceManager {
114113
),
115114
input: None,
116115
})));
117-
let serial_1_3 = Arc::new(Mutex::new(BusDevice::Serial(SerialDevice {
116+
let serial_1_3 = BusDevice::Serial(Arc::new(Mutex::new(SerialDevice {
118117
serial: Serial::with_events(
119118
self.com_evt_1_3.try_clone()?.try_clone()?,
120119
SerialEventsWrapper {
@@ -125,7 +124,7 @@ impl PortIODeviceManager {
125124
input: None,
126125
})));
127126
self.io_bus.insert(
128-
self.stdio_serial.clone(),
127+
BusDevice::Serial(self.stdio_serial.clone()),
129128
Self::SERIAL_PORT_ADDRESSES[0],
130129
Self::SERIAL_PORT_SIZE,
131130
)?;
@@ -145,7 +144,7 @@ impl PortIODeviceManager {
145144
Self::SERIAL_PORT_SIZE,
146145
)?;
147146
self.io_bus.insert(
148-
self.i8042.clone(),
147+
BusDevice::I8042Device(self.i8042.clone()),
149148
Self::I8042_KDB_DATA_REGISTER_ADDRESS,
150149
Self::I8042_KDB_DATA_REGISTER_SIZE,
151150
)?;
@@ -248,7 +247,7 @@ mod tests {
248247
vm.memory_init(&guest_mem, false).unwrap();
249248
crate::builder::setup_interrupt_controller(&mut vm).unwrap();
250249
let mut ldm = PortIODeviceManager::new(
251-
Arc::new(Mutex::new(BusDevice::Serial(SerialDevice {
250+
Arc::new(Mutex::new(SerialDevice {
252251
serial: Serial::with_events(
253252
EventFdTrigger::new(EventFd::new(EFD_NONBLOCK).unwrap()),
254253
SerialEventsWrapper {
@@ -257,7 +256,7 @@ mod tests {
257256
SerialOut::Sink(std::io::sink()),
258257
),
259258
input: None,
260-
}))),
259+
})),
261260
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
262261
)
263262
.unwrap();

src/vmm/src/device_manager/mmio.rs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::arch::aarch64::DeviceInfoForFDT;
2525
use crate::arch::DeviceType;
2626
use crate::arch::DeviceType::Virtio;
2727
#[cfg(target_arch = "aarch64")]
28-
use crate::devices::legacy::RTCDevice;
28+
use crate::devices::legacy::{RTCDevice, SerialDevice};
2929
use crate::devices::pseudo::BootTimer;
3030
use crate::devices::virtio::balloon::Balloon;
3131
use crate::devices::virtio::block::device::Block;
@@ -160,7 +160,7 @@ impl MMIODeviceManager {
160160
&mut self,
161161
identifier: (DeviceType, String),
162162
device_info: MMIODeviceInfo,
163-
device: Arc<Mutex<BusDevice>>,
163+
device: BusDevice,
164164
) -> Result<(), MmioError> {
165165
self.bus
166166
.insert(device, device_info.addr, device_info.len)
@@ -200,7 +200,7 @@ impl MMIODeviceManager {
200200
self.register_mmio_device(
201201
identifier,
202202
device_info.clone(),
203-
Arc::new(Mutex::new(BusDevice::MmioTransport(mmio_device))),
203+
BusDevice::MmioTransport(Arc::new(Mutex::new(mmio_device))),
204204
)
205205
}
206206

@@ -259,7 +259,7 @@ impl MMIODeviceManager {
259259
&mut self,
260260
vm: &VmFd,
261261
resource_allocator: &mut ResourceAllocator,
262-
serial: Arc<Mutex<BusDevice>>,
262+
serial: Arc<Mutex<SerialDevice<std::io::Stdin>>>,
263263
device_info_opt: Option<MMIODeviceInfo>,
264264
) -> Result<(), MmioError> {
265265
// Create a new MMIODeviceInfo object on boot path or unwrap the
@@ -271,20 +271,14 @@ impl MMIODeviceManager {
271271
};
272272

273273
vm.register_irqfd(
274-
serial
275-
.lock()
276-
.expect("Poisoned lock")
277-
.serial_ref()
278-
.unwrap()
279-
.serial
280-
.interrupt_evt(),
274+
serial.lock().expect("Poisoned lock").serial.interrupt_evt(),
281275
device_info.irqs[0],
282276
)
283277
.map_err(MmioError::RegisterIrqFd)?;
284278

285279
let identifier = (DeviceType::Serial, DeviceType::Serial.to_string());
286280
// Register the newly created Serial object.
287-
self.register_mmio_device(identifier, device_info, serial)
281+
self.register_mmio_device(identifier, device_info, BusDevice::Serial(serial))
288282
}
289283

290284
#[cfg(target_arch = "aarch64")]
@@ -342,7 +336,7 @@ impl MMIODeviceManager {
342336
self.register_mmio_device(
343337
identifier,
344338
device_info,
345-
Arc::new(Mutex::new(BusDevice::BootTimer(device))),
339+
BusDevice::BootTimer(Arc::new(Mutex::new(device))),
346340
)
347341
}
348342

@@ -352,11 +346,7 @@ impl MMIODeviceManager {
352346
}
353347

354348
/// Gets the specified device.
355-
pub fn get_device(
356-
&self,
357-
device_type: DeviceType,
358-
device_id: &str,
359-
) -> Option<&Mutex<BusDevice>> {
349+
pub fn get_device(&self, device_type: DeviceType, device_id: &str) -> Option<&BusDevice> {
360350
if let Some(device_info) = self
361351
.id_to_dev_info
362352
.get(&(device_type, device_id.to_string()))
@@ -371,7 +361,7 @@ impl MMIODeviceManager {
371361
/// Run fn for each registered device.
372362
pub fn for_each_device<F, E: Debug>(&self, mut f: F) -> Result<(), E>
373363
where
374-
F: FnMut(&DeviceType, &String, &MMIODeviceInfo, &Mutex<BusDevice>) -> Result<(), E>,
364+
F: FnMut(&DeviceType, &String, &MMIODeviceInfo, &BusDevice) -> Result<(), E>,
375365
{
376366
for ((device_type, device_id), device_info) in self.get_device_info().iter() {
377367
let bus_device = self
@@ -391,8 +381,6 @@ impl MMIODeviceManager {
391381
self.for_each_device(|device_type, device_id, device_info, bus_device| {
392382
if let Virtio(virtio_type) = device_type {
393383
let virtio_device = bus_device
394-
.lock()
395-
.expect("Poisoned lock")
396384
.mmio_transport_ref()
397385
.expect("Unexpected device type")
398386
.device();
@@ -417,8 +405,6 @@ impl MMIODeviceManager {
417405
{
418406
if let Some(busdev) = self.get_device(DeviceType::Virtio(virtio_type), id) {
419407
let virtio_device = busdev
420-
.lock()
421-
.expect("Poisoned lock")
422408
.mmio_transport_ref()
423409
.expect("Unexpected device type")
424410
.device();

src/vmm/src/device_manager/persist.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,7 @@ impl<'a> Persist<'a> for MMIODeviceManager {
307307
}
308308
}
309309

310-
let locked_bus_dev = bus_dev.lock().expect("Poisoned lock");
311-
312-
let mmio_transport = locked_bus_dev
310+
let mmio_transport = bus_dev
313311
.mmio_transport_ref()
314312
.expect("Unexpected device type");
315313

0 commit comments

Comments
 (0)