Skip to content

Commit 5b8acb2

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 f82926b commit 5b8acb2

File tree

7 files changed

+82
-167
lines changed

7 files changed

+82
-167
lines changed

src/vmm/src/builder.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,15 @@ use crate::devices::acpi::vmgenid::{VmGenId, VmGenIdError};
4848
use crate::devices::legacy::serial::SerialOut;
4949
#[cfg(target_arch = "aarch64")]
5050
use crate::devices::legacy::RTCDevice;
51-
use crate::devices::legacy::{EventFdTrigger, SerialEventsWrapper, SerialWrapper};
51+
use crate::devices::legacy::{EventFdTrigger, SerialDevice, SerialEventsWrapper, SerialWrapper};
5252
use crate::devices::virtio::balloon::Balloon;
5353
use crate::devices::virtio::block::device::Block;
5454
use crate::devices::virtio::device::VirtioDevice;
5555
use crate::devices::virtio::mmio::MmioTransport;
5656
use crate::devices::virtio::net::Net;
5757
use crate::devices::virtio::rng::Entropy;
5858
use crate::devices::virtio::vsock::{Vsock, VsockUnixBackend};
59+
#[cfg(target_arch = "x86_64")]
5960
use crate::devices::BusDevice;
6061
use crate::logger::{debug, error};
6162
use crate::persist::{MicrovmState, MicrovmStateError};
@@ -686,11 +687,11 @@ pub fn setup_serial_device(
686687
event_manager: &mut EventManager,
687688
input: std::io::Stdin,
688689
out: std::io::Stdout,
689-
) -> Result<Arc<Mutex<BusDevice>>, VmmError> {
690+
) -> Result<Arc<Mutex<SerialDevice<std::io::Stdin>>>, VmmError> {
690691
let interrupt_evt = EventFdTrigger::new(EventFd::new(EFD_NONBLOCK).map_err(VmmError::EventFd)?);
691692
let kick_stdin_read_evt =
692693
EventFdTrigger::new(EventFd::new(EFD_NONBLOCK).map_err(VmmError::EventFd)?);
693-
let serial = Arc::new(Mutex::new(BusDevice::Serial(SerialWrapper {
694+
let serial = Arc::new(Mutex::new(SerialWrapper {
694695
serial: Serial::with_events(
695696
interrupt_evt,
696697
SerialEventsWrapper {
@@ -699,7 +700,7 @@ pub fn setup_serial_device(
699700
SerialOut::Stdout(out),
700701
),
701702
input: Some(input),
702-
})));
703+
}));
703704
event_manager.add_subscriber(serial.clone());
704705
Ok(serial)
705706
}
@@ -1117,7 +1118,7 @@ pub mod tests {
11171118
let acpi_device_manager = ACPIDeviceManager::new();
11181119
#[cfg(target_arch = "x86_64")]
11191120
let pio_device_manager = PortIODeviceManager::new(
1120-
Arc::new(Mutex::new(BusDevice::Serial(SerialWrapper {
1121+
Arc::new(Mutex::new(SerialWrapper {
11211122
serial: Serial::with_events(
11221123
EventFdTrigger::new(EventFd::new(EFD_NONBLOCK).unwrap()),
11231124
SerialEventsWrapper {
@@ -1126,7 +1127,7 @@ pub mod tests {
11261127
SerialOut::Sink(std::io::sink()),
11271128
),
11281129
input: None,
1129-
}))),
1130+
})),
11301131
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
11311132
)
11321133
.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: 10 additions & 24 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)
@@ -203,7 +203,7 @@ impl MMIODeviceManager {
203203
self.register_mmio_device(
204204
identifier,
205205
device_info.clone(),
206-
Arc::new(Mutex::new(BusDevice::MmioTransport(mmio_device))),
206+
BusDevice::MmioTransport(Arc::new(Mutex::new(mmio_device))),
207207
)
208208
}
209209

@@ -262,7 +262,7 @@ impl MMIODeviceManager {
262262
&mut self,
263263
vm: &VmFd,
264264
resource_allocator: &mut ResourceAllocator,
265-
serial: Arc<Mutex<BusDevice>>,
265+
serial: Arc<Mutex<SerialDevice<std::io::Stdin>>>,
266266
device_info_opt: Option<MMIODeviceInfo>,
267267
) -> Result<(), MmioError> {
268268
// Create a new MMIODeviceInfo object on boot path or unwrap the
@@ -274,20 +274,14 @@ impl MMIODeviceManager {
274274
};
275275

276276
vm.register_irqfd(
277-
serial
278-
.lock()
279-
.expect("Poisoned lock")
280-
.serial_ref()
281-
.unwrap()
282-
.serial
283-
.interrupt_evt(),
277+
serial.lock().expect("Poisoned lock").serial.interrupt_evt(),
284278
device_info.irqs[0],
285279
)
286280
.map_err(MmioError::RegisterIrqFd)?;
287281

288282
let identifier = (DeviceType::Serial, DeviceType::Serial.to_string());
289283
// Register the newly created Serial object.
290-
self.register_mmio_device(identifier, device_info, serial)
284+
self.register_mmio_device(identifier, device_info, BusDevice::Serial(serial))
291285
}
292286

293287
#[cfg(target_arch = "aarch64")]
@@ -328,7 +322,7 @@ impl MMIODeviceManager {
328322
self.register_mmio_device(
329323
identifier,
330324
device_info,
331-
Arc::new(Mutex::new(BusDevice::RTCDevice(rtc))),
325+
BusDevice::RTCDevice(Arc::new(Mutex::new(rtc))),
332326
)
333327
}
334328

@@ -345,7 +339,7 @@ impl MMIODeviceManager {
345339
self.register_mmio_device(
346340
identifier,
347341
device_info,
348-
Arc::new(Mutex::new(BusDevice::BootTimer(device))),
342+
BusDevice::BootTimer(Arc::new(Mutex::new(device))),
349343
)
350344
}
351345

@@ -355,11 +349,7 @@ impl MMIODeviceManager {
355349
}
356350

357351
/// Gets the specified device.
358-
pub fn get_device(
359-
&self,
360-
device_type: DeviceType,
361-
device_id: &str,
362-
) -> Option<&Mutex<BusDevice>> {
352+
pub fn get_device(&self, device_type: DeviceType, device_id: &str) -> Option<&BusDevice> {
363353
if let Some(device_info) = self
364354
.id_to_dev_info
365355
.get(&(device_type, device_id.to_string()))
@@ -374,7 +364,7 @@ impl MMIODeviceManager {
374364
/// Run fn for each registered device.
375365
pub fn for_each_device<F, E: Debug>(&self, mut f: F) -> Result<(), E>
376366
where
377-
F: FnMut(&DeviceType, &String, &MMIODeviceInfo, &Mutex<BusDevice>) -> Result<(), E>,
367+
F: FnMut(&DeviceType, &String, &MMIODeviceInfo, &BusDevice) -> Result<(), E>,
378368
{
379369
for ((device_type, device_id), device_info) in self.get_device_info().iter() {
380370
let bus_device = self
@@ -394,8 +384,6 @@ impl MMIODeviceManager {
394384
self.for_each_device(|device_type, device_id, device_info, bus_device| {
395385
if let Virtio(virtio_type) = device_type {
396386
let virtio_device = bus_device
397-
.lock()
398-
.expect("Poisoned lock")
399387
.mmio_transport_ref()
400388
.expect("Unexpected device type")
401389
.device();
@@ -420,8 +408,6 @@ impl MMIODeviceManager {
420408
{
421409
if let Some(busdev) = self.get_device(DeviceType::Virtio(virtio_type), id) {
422410
let virtio_device = busdev
423-
.lock()
424-
.expect("Poisoned lock")
425411
.mmio_transport_ref()
426412
.expect("Unexpected device type")
427413
.device();

src/vmm/src/device_manager/persist.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,7 @@ impl<'a> Persist<'a> for MMIODeviceManager {
301301
}
302302
}
303303

304-
let locked_bus_dev = bus_dev.lock().expect("Poisoned lock");
305-
306-
let mmio_transport = locked_bus_dev
304+
let mmio_transport = bus_dev
307305
.mmio_transport_ref()
308306
.expect("Unexpected device type");
309307

0 commit comments

Comments
 (0)