Skip to content

Commit 3987c19

Browse files
committed
refactor: use vm_device::Bus for IO bus
WIP Signed-off-by: Babis Chalios <bchalios@amazon.es>
1 parent a6c7c95 commit 3987c19

File tree

11 files changed

+112
-457
lines changed

11 files changed

+112
-457
lines changed

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ pub struct KvmVcpu {
160160
#[derive(Default, Debug)]
161161
pub struct Peripherals {
162162
/// Pio bus.
163-
pub pio_bus: Option<crate::devices::Bus>,
163+
pub pio_bus: Option<Arc<vm_device::Bus>>,
164164
/// Mmio bus.
165165
pub mmio_bus: Option<Arc<vm_device::Bus>>,
166166
}
@@ -267,7 +267,7 @@ impl KvmVcpu {
267267
}
268268

269269
/// Sets a Port Mapped IO bus for this vcpu.
270-
pub fn set_pio_bus(&mut self, pio_bus: crate::devices::Bus) {
270+
pub fn set_pio_bus(&mut self, pio_bus: Arc<vm_device::Bus>) {
271271
self.peripherals.pio_bus = Some(pio_bus);
272272
}
273273

@@ -711,15 +711,19 @@ impl Peripherals {
711711
VcpuExit::IoIn(addr, data) => {
712712
if let Some(pio_bus) = &self.pio_bus {
713713
let _metric = METRICS.vcpu.exit_io_in_agg.record_latency_metrics();
714-
pio_bus.read(u64::from(addr), data);
714+
if let Err(err) = pio_bus.read(u64::from(addr), data) {
715+
warn!("vcpu: IO read @ {addr:#x}:{:#x} failed: {err}", data.len());
716+
}
715717
METRICS.vcpu.exit_io_in.inc();
716718
}
717719
Ok(VcpuEmulation::Handled)
718720
}
719721
VcpuExit::IoOut(addr, data) => {
720722
if let Some(pio_bus) = &self.pio_bus {
721723
let _metric = METRICS.vcpu.exit_io_out_agg.record_latency_metrics();
722-
pio_bus.write(u64::from(addr), data);
724+
if let Err(err) = pio_bus.write(u64::from(addr), data) {
725+
warn!("vcpu: IO write @ {addr:#x}:{:#x} failed: {err}", data.len());
726+
}
723727
METRICS.vcpu.exit_io_out.inc();
724728
}
725729
Ok(VcpuEmulation::Handled)

src/vmm/src/builder.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use userfaultfd::Uffd;
1515
use utils::time::TimestampUs;
1616
#[cfg(target_arch = "aarch64")]
1717
use vm_superio::Rtc;
18+
#[cfg(target_arch = "x86_64")]
19+
use vmm_sys_util::eventfd::EventFd;
1820

1921
use crate::arch::{ConfigurationError, configure_system_for_boot, load_kernel};
2022
#[cfg(target_arch = "aarch64")]
@@ -30,8 +32,9 @@ use crate::device_manager::persist::{
3032
ACPIDeviceManagerConstructorArgs, ACPIDeviceManagerRestoreError, MMIODevManagerConstructorArgs,
3133
};
3234
use crate::device_manager::resources::ResourceAllocator;
33-
use crate::devices::BusDevice;
3435
use crate::devices::acpi::vmgenid::{VmGenId, VmGenIdError};
36+
#[cfg(target_arch = "x86_64")]
37+
use crate::devices::legacy::I8042Device;
3538
#[cfg(target_arch = "aarch64")]
3639
use crate::devices::legacy::RTCDevice;
3740
use crate::devices::legacy::SerialDevice;
@@ -159,10 +162,14 @@ fn create_vmm_and_vcpus(
159162

160163
// x86_64 uses the i8042 reset event as the Vmm exit event.
161164
let reset_evt = vcpus_exit_evt.try_clone().map_err(VmmError::EventFd)?;
165+
let i8042 = Arc::new(Mutex::new(I8042Device::new(
166+
reset_evt,
167+
EventFd::new(libc::EFD_NONBLOCK).map_err(VmmError::EventFd)?,
168+
)));
162169

163170
// create pio dev manager with legacy devices
164171
let mut pio_dev_mgr =
165-
PortIODeviceManager::new(serial_device, reset_evt).map_err(VmmError::LegacyIOBus)?;
172+
PortIODeviceManager::new(serial_device, i8042).map_err(VmmError::LegacyIOBus)?;
166173
pio_dev_mgr
167174
.register_devices(vm.fd())
168175
.map_err(VmmError::LegacyIOBus)?;
@@ -529,11 +536,11 @@ pub fn build_microvm_from_snapshot(
529536
/// Sets up the serial device.
530537
pub fn setup_serial_device(
531538
event_manager: &mut EventManager,
532-
) -> Result<Arc<Mutex<BusDevice>>, VmmError> {
533-
let serial = Arc::new(Mutex::new(BusDevice::Serial(
539+
) -> Result<Arc<Mutex<SerialDevice>>, VmmError> {
540+
let serial = Arc::new(Mutex::new(
534541
SerialDevice::new(Some(std::io::stdin()), SerialOut::Stdout(std::io::stdout()))
535542
.map_err(VmmError::EventFd)?,
536-
)));
543+
));
537544
event_manager.add_subscriber(serial.clone());
538545
Ok(serial)
539546
}
@@ -823,10 +830,13 @@ pub(crate) mod tests {
823830
let acpi_device_manager = ACPIDeviceManager::new();
824831
#[cfg(target_arch = "x86_64")]
825832
let pio_device_manager = PortIODeviceManager::new(
826-
Arc::new(Mutex::new(BusDevice::Serial(
833+
Arc::new(Mutex::new(
827834
SerialDevice::new(None, SerialOut::Sink(std::io::sink())).unwrap(),
835+
)),
836+
Arc::new(Mutex::new(I8042Device::new(
837+
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
838+
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
828839
))),
829-
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
830840
)
831841
.unwrap();
832842

src/vmm/src/device_manager/legacy.rs

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@ use libc::EFD_NONBLOCK;
1616
use vm_superio::Serial;
1717
use vmm_sys_util::eventfd::EventFd;
1818

19-
use crate::devices::bus::BusDevice;
2019
use crate::devices::legacy::serial::SerialOut;
21-
use crate::devices::legacy::{EventFdTrigger, SerialDevice, SerialEventsWrapper};
20+
use crate::devices::legacy::{EventFdTrigger, I8042Device, SerialDevice, SerialEventsWrapper};
2221

2322
/// Errors corresponding to the `PortIODeviceManager`.
2423
#[derive(Debug, derive_more::From, thiserror::Error, displaydoc::Display)]
2524
pub enum LegacyDeviceError {
2625
/// Failed to add legacy device to Bus: {0}
27-
BusError(crate::devices::BusError),
26+
BusError(vm_device::BusError),
2827
/// Failed to create EventFd: {0}
2928
EventFd(std::io::Error),
3029
}
@@ -34,11 +33,11 @@ pub enum LegacyDeviceError {
3433
/// The `LegacyDeviceManger` should be initialized only by using the constructor.
3534
#[derive(Debug)]
3635
pub struct PortIODeviceManager {
37-
pub io_bus: crate::devices::Bus,
36+
pub io_bus: Arc<vm_device::Bus>,
3837
// BusDevice::Serial
39-
pub stdio_serial: Arc<Mutex<BusDevice>>,
38+
pub stdio_serial: Arc<Mutex<SerialDevice>>,
4039
// BusDevice::I8042Device
41-
pub i8042: Arc<Mutex<BusDevice>>,
40+
pub i8042: Arc<Mutex<I8042Device>>,
4241

4342
// Communication event on ports 1 & 3.
4443
pub com_evt_1_3: EventFdTrigger,
@@ -73,29 +72,26 @@ impl PortIODeviceManager {
7372

7473
/// Create a new DeviceManager handling legacy devices (uart, i8042).
7574
pub fn new(
76-
serial: Arc<Mutex<BusDevice>>,
77-
i8042_reset_evfd: EventFd,
75+
stdio_serial: Arc<Mutex<SerialDevice>>,
76+
i8042: Arc<Mutex<I8042Device>>,
7877
) -> Result<Self, LegacyDeviceError> {
79-
debug_assert!(matches!(*serial.lock().unwrap(), BusDevice::Serial(_)));
80-
let io_bus = crate::devices::Bus::new();
81-
let com_evt_1_3 = serial
78+
let io_bus = Arc::new(vm_device::Bus::new());
79+
let com_evt_1_3 = stdio_serial
8280
.lock()
8381
.expect("Poisoned lock")
84-
.serial_mut()
85-
.unwrap()
8682
.serial
8783
.interrupt_evt()
8884
.try_clone()?;
8985
let com_evt_2_4 = EventFdTrigger::new(EventFd::new(EFD_NONBLOCK)?);
90-
let kbd_evt = EventFd::new(libc::EFD_NONBLOCK)?;
91-
92-
let i8042 = Arc::new(Mutex::new(BusDevice::I8042Device(
93-
crate::devices::legacy::I8042Device::new(i8042_reset_evfd, kbd_evt.try_clone()?),
94-
)));
86+
let kbd_evt = i8042
87+
.lock()
88+
.expect("Poisoned lock")
89+
.kbd_interrupt_evt
90+
.try_clone()?;
9591

9692
Ok(PortIODeviceManager {
9793
io_bus,
98-
stdio_serial: serial,
94+
stdio_serial,
9995
i8042,
10096
com_evt_1_3,
10197
com_evt_2_4,
@@ -105,7 +101,7 @@ impl PortIODeviceManager {
105101

106102
/// Register supported legacy devices.
107103
pub fn register_devices(&mut self, vm_fd: &VmFd) -> Result<(), LegacyDeviceError> {
108-
let serial_2_4 = Arc::new(Mutex::new(BusDevice::Serial(SerialDevice {
104+
let serial_2_4 = Arc::new(Mutex::new(SerialDevice {
109105
serial: Serial::with_events(
110106
self.com_evt_2_4.try_clone()?.try_clone()?,
111107
SerialEventsWrapper {
@@ -114,8 +110,8 @@ impl PortIODeviceManager {
114110
SerialOut::Sink(std::io::sink()),
115111
),
116112
input: None,
117-
})));
118-
let serial_1_3 = Arc::new(Mutex::new(BusDevice::Serial(SerialDevice {
113+
}));
114+
let serial_1_3 = Arc::new(Mutex::new(SerialDevice {
119115
serial: Serial::with_events(
120116
self.com_evt_1_3.try_clone()?.try_clone()?,
121117
SerialEventsWrapper {
@@ -124,7 +120,7 @@ impl PortIODeviceManager {
124120
SerialOut::Sink(std::io::sink()),
125121
),
126122
input: None,
127-
})));
123+
}));
128124
self.io_bus.insert(
129125
self.stdio_serial.clone(),
130126
Self::SERIAL_PORT_ADDRESSES[0],
@@ -251,7 +247,7 @@ mod tests {
251247
let (_, vm) = setup_vm_with_memory(0x1000);
252248
vm.setup_irqchip().unwrap();
253249
let mut ldm = PortIODeviceManager::new(
254-
Arc::new(Mutex::new(BusDevice::Serial(SerialDevice {
250+
Arc::new(Mutex::new(SerialDevice {
255251
serial: Serial::with_events(
256252
EventFdTrigger::new(EventFd::new(EFD_NONBLOCK).unwrap()),
257253
SerialEventsWrapper {
@@ -260,8 +256,11 @@ mod tests {
260256
SerialOut::Sink(std::io::sink()),
261257
),
262258
input: None,
263-
}))),
264-
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
259+
})),
260+
Arc::new(Mutex::new(I8042Device::new(
261+
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
262+
EventFd::new(libc::EFD_NONBLOCK).unwrap(),
263+
))),
265264
)
266265
.unwrap();
267266
ldm.register_devices(vm.fd()).unwrap();

0 commit comments

Comments
 (0)