From d63805740f014e8b073cc568a95377802eb899c7 Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Wed, 4 Feb 2026 21:57:21 -0800 Subject: [PATCH 1/5] refactor(mem): remove MmioRange type alias Replace the `MmioRange` type alias with `Arc` to improve code clarity by making type signatures more explicit. Signed-off-by: Changyuan Lyu --- alioth/src/mem/emulated.rs | 8 +++----- alioth/src/mem/mem.rs | 18 +++++++++--------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/alioth/src/mem/emulated.rs b/alioth/src/mem/emulated.rs index da87ef85..d03dc5c0 100644 --- a/alioth/src/mem/emulated.rs +++ b/alioth/src/mem/emulated.rs @@ -43,9 +43,7 @@ pub trait Mmio: Debug + Send + Sync + 'static { fn size(&self) -> u64; } -pub type MmioRange = Arc; - -impl Mmio for MmioRange { +impl Mmio for Arc { fn read(&self, offset: u64, size: u8) -> Result { Mmio::read(self.as_ref(), offset, size) } @@ -59,7 +57,7 @@ impl Mmio for MmioRange { } } -impl SlotBackend for MmioRange { +impl SlotBackend for Arc { fn size(&self) -> u64 { Mmio::size(self.as_ref()) } @@ -120,7 +118,7 @@ macro_rules! impl_mmio_for_zerocopy { } #[derive(Debug)] -pub struct MmioBus +pub struct MmioBus> where R: Debug + SlotBackend, { diff --git a/alioth/src/mem/mem.rs b/alioth/src/mem/mem.rs index 19aa79cc..eee40191 100644 --- a/alioth/src/mem/mem.rs +++ b/alioth/src/mem/mem.rs @@ -31,7 +31,7 @@ use crate::errors::{DebugTrace, trace_error}; use crate::hv::{MemMapOption, VmEntry, VmMemory}; use self::addressable::{Addressable, SlotBackend}; -use self::emulated::{Action, MmioBus, MmioRange}; +use self::emulated::{Action, Mmio, MmioBus}; use self::mapped::{ArcMemPages, Ram, RamBus}; #[trace_error] @@ -125,7 +125,7 @@ impl MemConfig { pub enum MemRange { Ram(ArcMemPages), DevMem(ArcMemPages), - Emulated(MmioRange), + Emulated(Arc), Span(u64), } @@ -133,7 +133,7 @@ impl MemRange { pub fn size(&self) -> u64 { match self { MemRange::Ram(pages) | MemRange::DevMem(pages) => pages.size(), - MemRange::Emulated(range) => range.size(), + MemRange::Emulated(range) => Mmio::size(range), MemRange::Span(size) => *size, } } @@ -192,8 +192,8 @@ impl MemRegion { } } - pub fn with_emulated(range: MmioRange, type_: MemRegionType) -> MemRegion { - let size = range.size(); + pub fn with_emulated(range: Arc, type_: MemRegionType) -> MemRegion { + let size = Mmio::size(&range); MemRegion { ranges: vec![MemRange::Emulated(range)], entries: vec![MemRegionEntry { type_, size }], @@ -223,12 +223,12 @@ impl SlotBackend for Arc { #[derive(Debug)] pub struct IoRegion { - pub range: MmioRange, + pub range: Arc, pub callbacks: Mutex>>, } impl IoRegion { - pub fn new(range: MmioRange) -> IoRegion { + pub fn new(range: Arc) -> IoRegion { IoRegion { range, callbacks: Mutex::new(vec![]), @@ -238,7 +238,7 @@ impl IoRegion { impl SlotBackend for Arc { fn size(&self) -> u64 { - self.range.size() + Mmio::size(self.range.as_ref()) } } @@ -460,7 +460,7 @@ impl Memory { entries } - pub fn add_io_dev(&self, port: u16, dev: MmioRange) -> Result<()> { + pub fn add_io_dev(&self, port: u16, dev: Arc) -> Result<()> { self.add_io_region(port, Arc::new(IoRegion::new(dev))) } From f374a1d75be7b0d6e8fe01e62bf7101a02cd042d Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Wed, 4 Feb 2026 23:20:47 -0800 Subject: [PATCH 2/5] refactor(pvpanic): move PvPanic device to pci module Move the `PvPanic` device from the `device` module to the `pci` module to resolve a circular dependency. Signed-off-by: Changyuan Lyu --- alioth/src/device/device.rs | 1 - alioth/src/pci/bus_test.rs | 2 +- alioth/src/pci/pci.rs | 1 + alioth/src/{device => pci}/pvpanic.rs | 0 alioth/src/{device => pci}/pvpanic_test.rs | 2 +- alioth/src/pci/segment_test.rs | 2 +- alioth/src/vm/vm.rs | 2 +- 7 files changed, 5 insertions(+), 5 deletions(-) rename alioth/src/{device => pci}/pvpanic.rs (100%) rename alioth/src/{device => pci}/pvpanic_test.rs (95%) diff --git a/alioth/src/device/device.rs b/alioth/src/device/device.rs index ecd309e2..6a3c190a 100644 --- a/alioth/src/device/device.rs +++ b/alioth/src/device/device.rs @@ -21,6 +21,5 @@ pub mod net; pub mod pl011; #[cfg(target_arch = "aarch64")] pub mod pl031; -pub mod pvpanic; #[cfg(target_arch = "x86_64")] pub mod serial; diff --git a/alioth/src/pci/bus_test.rs b/alioth/src/pci/bus_test.rs index c0a74b79..15bc1398 100644 --- a/alioth/src/pci/bus_test.rs +++ b/alioth/src/pci/bus_test.rs @@ -17,11 +17,11 @@ use std::sync::atomic::AtomicU32; use assert_matches::assert_matches; -use crate::device::pvpanic::{PVPANIC_DEVICE_ID, PVPANIC_VENDOR_ID, PvPanic}; use crate::mem::emulated::{Action, Mmio}; use crate::pci::Bdf; use crate::pci::bus::{Address, PciBus, PciIoBus}; use crate::pci::config::{BAR_MEM64, BAR_PREFETCHABLE, CommonHeader, offset_bar}; +use crate::pci::pvpanic::{PVPANIC_DEVICE_ID, PVPANIC_VENDOR_ID, PvPanic}; use crate::pci::segment::PciSegment; #[test] diff --git a/alioth/src/pci/pci.rs b/alioth/src/pci/pci.rs index d2a469ec..712aa09b 100644 --- a/alioth/src/pci/pci.rs +++ b/alioth/src/pci/pci.rs @@ -16,6 +16,7 @@ pub mod bus; pub mod cap; pub mod config; pub mod host_bridge; +pub mod pvpanic; pub mod segment; use std::fmt::{Debug, Display, Formatter}; diff --git a/alioth/src/device/pvpanic.rs b/alioth/src/pci/pvpanic.rs similarity index 100% rename from alioth/src/device/pvpanic.rs rename to alioth/src/pci/pvpanic.rs diff --git a/alioth/src/device/pvpanic_test.rs b/alioth/src/pci/pvpanic_test.rs similarity index 95% rename from alioth/src/device/pvpanic_test.rs rename to alioth/src/pci/pvpanic_test.rs index 8b76ff51..795e6b32 100644 --- a/alioth/src/device/pvpanic_test.rs +++ b/alioth/src/pci/pvpanic_test.rs @@ -15,10 +15,10 @@ use assert_matches::assert_matches; use rstest::rstest; -use crate::device::pvpanic::{PVPANIC_DEVICE_ID, PVPANIC_VENDOR_ID, PvPanic, PvPanicBar}; use crate::mem::emulated::{Action, Mmio}; use crate::pci::Pci; use crate::pci::config::{BAR_MEM64, BAR_PREFETCHABLE, CommonHeader, HeaderType, offset_bar}; +use crate::pci::pvpanic::{PVPANIC_DEVICE_ID, PVPANIC_VENDOR_ID, PvPanic, PvPanicBar}; #[rstest] #[case(CommonHeader::OFFSET_VENDOR, 2, PVPANIC_VENDOR_ID as u64)] diff --git a/alioth/src/pci/segment_test.rs b/alioth/src/pci/segment_test.rs index fcc1d1a6..e2f03224 100644 --- a/alioth/src/pci/segment_test.rs +++ b/alioth/src/pci/segment_test.rs @@ -17,10 +17,10 @@ use std::sync::Arc; use assert_matches::assert_matches; use rstest::rstest; -use crate::device::pvpanic::{PVPANIC_DEVICE_ID, PVPANIC_VENDOR_ID, PvPanic}; use crate::mem::emulated::{Action, Mmio}; use crate::pci::Bdf; use crate::pci::config::{BAR_MEM_MASK, CommonHeader, offset_bar}; +use crate::pci::pvpanic::{PVPANIC_DEVICE_ID, PVPANIC_VENDOR_ID, PvPanic}; use crate::pci::segment::PciSegment; #[rstest] diff --git a/alioth/src/vm/vm.rs b/alioth/src/vm/vm.rs index 8a12d3d4..b0f38f2a 100644 --- a/alioth/src/vm/vm.rs +++ b/alioth/src/vm/vm.rs @@ -34,7 +34,6 @@ use crate::device::fw_cfg::{FwCfg, FwCfgItemParam}; use crate::device::pl011::Pl011; #[cfg(target_arch = "aarch64")] use crate::device::pl031::Pl031; -use crate::device::pvpanic::PvPanic; #[cfg(target_arch = "x86_64")] use crate::device::serial::Serial; use crate::errors::{DebugTrace, trace_error}; @@ -43,6 +42,7 @@ use crate::loader::Payload; use crate::mem::Memory; #[cfg(target_arch = "aarch64")] use crate::mem::{MemRegion, MemRegionType}; +use crate::pci::pvpanic::PvPanic; use crate::pci::{Bdf, Pci}; #[cfg(target_os = "linux")] use crate::sys::vfio::VfioIommu; From a3e6100c4060591fb435157e6ec300e526aee6ea Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Wed, 4 Feb 2026 21:35:23 -0800 Subject: [PATCH 3/5] refactor(device): introduce MmioDev trait Create the `MmioDev` trait as an abstraction for MMIO devices, inheriting from the `Mmio` trait. Signed-off-by: Changyuan Lyu --- alioth/src/board/board.rs | 8 ++++---- alioth/src/device/device.rs | 4 ++++ alioth/src/device/fw_cfg/fw_cfg.rs | 3 +++ alioth/src/device/pl011.rs | 3 +++ alioth/src/device/pl031.rs | 3 +++ alioth/src/device/serial.rs | 5 ++++- alioth/src/mem/mem.rs | 5 +++++ alioth/src/vm/vm.rs | 20 ++++---------------- 8 files changed, 30 insertions(+), 21 deletions(-) diff --git a/alioth/src/board/board.rs b/alioth/src/board/board.rs index 40c761e6..ede0651c 100644 --- a/alioth/src/board/board.rs +++ b/alioth/src/board/board.rs @@ -39,6 +39,7 @@ use crate::arch::layout::{ PCIE_MMIO_32_NON_PREFETCHABLE_START, PCIE_MMIO_32_PREFETCHABLE_END, PCIE_MMIO_32_PREFETCHABLE_START, RAM_32_SIZE, }; +use crate::device::MmioDev; #[cfg(target_arch = "x86_64")] use crate::device::fw_cfg::FwCfg; use crate::errors::{DebugTrace, trace_error}; @@ -46,7 +47,6 @@ use crate::hv::{Coco, Vcpu, Vm, VmEntry, VmExit}; #[cfg(target_arch = "x86_64")] use crate::loader::xen; use crate::loader::{Executable, InitState, Payload, linux}; -use crate::mem::emulated::Mmio; use crate::mem::mapped::ArcMemPages; use crate::mem::{MemBackend, MemConfig, MemRegion, MemRegionType, Memory}; use crate::pci::bus::PciBus; @@ -210,9 +210,9 @@ where pub arch: ArchBoard, pub config: BoardConfig, pub payload: RwLock>, - pub io_devs: RwLock)>>, + pub io_devs: RwLock)>>, #[cfg(target_arch = "aarch64")] - pub mmio_devs: RwLock)>>, + pub mmio_devs: RwLock)>>, pub pci_bus: PciBus, #[cfg(target_arch = "x86_64")] pub fw_cfg: Mutex>>>, @@ -419,7 +419,7 @@ where } #[cfg(target_arch = "aarch64")] for (addr, dev) in self.mmio_devs.read().iter() { - self.memory.add_region(*addr, dev.clone())?; + self.memory.add_mmio_dev(*addr, dev.clone())?; } self.add_pci_devs()?; let init_state = self.load_payload()?; diff --git a/alioth/src/device/device.rs b/alioth/src/device/device.rs index 6a3c190a..ddc6de31 100644 --- a/alioth/src/device/device.rs +++ b/alioth/src/device/device.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::mem::emulated::Mmio; + pub mod console; #[cfg(target_arch = "x86_64")] #[path = "fw_cfg/fw_cfg.rs"] @@ -23,3 +25,5 @@ pub mod pl011; pub mod pl031; #[cfg(target_arch = "x86_64")] pub mod serial; + +pub trait MmioDev: Mmio {} diff --git a/alioth/src/device/fw_cfg/fw_cfg.rs b/alioth/src/device/fw_cfg/fw_cfg.rs index e742b849..34ab4e09 100644 --- a/alioth/src/device/fw_cfg/fw_cfg.rs +++ b/alioth/src/device/fw_cfg/fw_cfg.rs @@ -39,6 +39,7 @@ use zerocopy::{FromBytes, Immutable, IntoBytes}; use crate::arch::layout::{ PORT_FW_CFG_DATA, PORT_FW_CFG_DMA_HI, PORT_FW_CFG_DMA_LO, PORT_FW_CFG_SELECTOR, }; +use crate::device::MmioDev; #[cfg(target_arch = "x86_64")] use crate::firmware::acpi::AcpiTable; #[cfg(target_arch = "x86_64")] @@ -512,6 +513,8 @@ impl Mmio for Mutex { } } +impl MmioDev for Mutex {} + #[derive(Debug, PartialEq, Eq, Deserialize, Help)] pub enum FwCfgContentParam { /// Path to a file with binary contents. diff --git a/alioth/src/device/pl011.rs b/alioth/src/device/pl011.rs index 90837f70..5ed2c253 100644 --- a/alioth/src/device/pl011.rs +++ b/alioth/src/device/pl011.rs @@ -19,6 +19,7 @@ use std::sync::Arc; use bitflags::bitflags; use parking_lot::Mutex; +use crate::device::MmioDev; use crate::device::console::{Console, UartRecv}; use crate::hv::IrqSender; use crate::mem::emulated::{Action, Mmio}; @@ -258,6 +259,8 @@ where } } +impl MmioDev for Pl011 where I: IrqSender {} + struct Pl011Recv { irq_line: Arc, reg: Arc>, diff --git a/alioth/src/device/pl031.rs b/alioth/src/device/pl031.rs index a00496ec..2035b528 100644 --- a/alioth/src/device/pl031.rs +++ b/alioth/src/device/pl031.rs @@ -20,6 +20,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use bitflags::bitflags; use parking_lot::Mutex; +use crate::device::MmioDev; use crate::mem; use crate::mem::emulated::{Action, Mmio}; @@ -141,3 +142,5 @@ impl Mmio for Pl031 { Ok(Action::None) } } + +impl MmioDev for Pl031 {} diff --git a/alioth/src/device/serial.rs b/alioth/src/device/serial.rs index 98a35850..9d5b21ff 100644 --- a/alioth/src/device/serial.rs +++ b/alioth/src/device/serial.rs @@ -20,6 +20,7 @@ use bitfield::bitfield; use bitflags::bitflags; use parking_lot::Mutex; +use crate::device::MmioDev; use crate::device::console::{Console, UartRecv}; use crate::hv::IrqSender; use crate::mem; @@ -191,7 +192,7 @@ pub struct Serial { impl Mmio for Serial where - I: IrqSender + Sync + Send + 'static, + I: IrqSender, { fn size(&self) -> u64 { 8 @@ -282,6 +283,8 @@ where } } +impl MmioDev for Serial where I: IrqSender {} + struct SerialRecv { pub name: Arc, pub irq_sender: Arc, diff --git a/alioth/src/mem/mem.rs b/alioth/src/mem/mem.rs index eee40191..46a50969 100644 --- a/alioth/src/mem/mem.rs +++ b/alioth/src/mem/mem.rs @@ -339,6 +339,11 @@ impl Memory { Ok(()) } + pub fn add_mmio_dev(&self, addr: u64, dev: Arc) -> Result<()> { + let region = MemRegion::with_emulated(dev, MemRegionType::Hidden); + self.add_region(addr, Arc::new(region)) + } + pub fn add_region(&self, addr: u64, region: Arc) -> Result<()> { region.validate()?; let mut regions = self.regions.lock(); diff --git a/alioth/src/vm/vm.rs b/alioth/src/vm/vm.rs index b0f38f2a..fb687e1b 100644 --- a/alioth/src/vm/vm.rs +++ b/alioth/src/vm/vm.rs @@ -40,8 +40,6 @@ use crate::errors::{DebugTrace, trace_error}; use crate::hv::{Hypervisor, IoeventFdRegistry, Vm, VmConfig}; use crate::loader::Payload; use crate::mem::Memory; -#[cfg(target_arch = "aarch64")] -use crate::mem::{MemRegion, MemRegionType}; use crate::pci::pvpanic::PvPanic; use crate::pci::{Bdf, Pci}; #[cfg(target_os = "linux")] @@ -175,26 +173,16 @@ where pub fn add_pl011(&self) -> Result<(), Error> { let irq_line = self.board.vm.create_irq_sender(1)?; let pl011_dev = Pl011::new(PL011_START, irq_line).context(error::CreateConsole)?; - self.board.mmio_devs.write().push(( - PL011_START, - Arc::new(MemRegion::with_emulated( - Arc::new(pl011_dev), - MemRegionType::Hidden, - )), - )); + let mut mmio_devs = self.board.mmio_devs.write(); + mmio_devs.push((PL011_START, Arc::new(pl011_dev))); Ok(()) } #[cfg(target_arch = "aarch64")] pub fn add_pl031(&self) { let pl031_dev = Pl031::new(PL031_START); - self.board.mmio_devs.write().push(( - PL031_START, - Arc::new(MemRegion::with_emulated( - Arc::new(pl031_dev), - MemRegionType::Hidden, - )), - )); + let mut mmio_devs = self.board.mmio_devs.write(); + mmio_devs.push((PL031_START, Arc::new(pl031_dev))); } pub fn add_pci_dev(&self, bdf: Option, dev: Arc) -> Result<(), Error> { From 93a0292bf69f76492b3a65b8ab69353f98e35e8d Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Wed, 4 Feb 2026 22:29:39 -0800 Subject: [PATCH 4/5] feat(device): introduce Pause trait Define a common interface for pausing and resuming devices. Provide a default implementation that returns a `NotPausable` error and implement the trait for all MMIO devices. Signed-off-by: Changyuan Lyu --- alioth/src/device/device.rs | 25 ++++++++++++++++++++++++- alioth/src/device/fw_cfg/fw_cfg.rs | 12 +++++++++++- alioth/src/device/pl011.rs | 15 ++++++++++++++- alioth/src/device/pl031.rs | 12 +++++++++++- alioth/src/device/serial.rs | 15 ++++++++++++++- 5 files changed, 74 insertions(+), 5 deletions(-) diff --git a/alioth/src/device/device.rs b/alioth/src/device/device.rs index ddc6de31..e69f4cea 100644 --- a/alioth/src/device/device.rs +++ b/alioth/src/device/device.rs @@ -12,6 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +use alioth_macros::trace_error; +use snafu::Snafu; + +use crate::errors::DebugTrace; use crate::mem::emulated::Mmio; pub mod console; @@ -26,4 +30,23 @@ pub mod pl031; #[cfg(target_arch = "x86_64")] pub mod serial; -pub trait MmioDev: Mmio {} +#[trace_error] +#[derive(Snafu, DebugTrace)] +#[snafu(module, visibility(pub(crate)), context(suffix(false)))] +pub enum Error { + #[snafu(display("Device is not pausable"))] + NotPausable, +} + +pub type Result = std::result::Result; + +pub trait Pause { + fn pause(&self) -> Result<()> { + error::NotPausable.fail() + } + fn resume(&self) -> Result<()> { + error::NotPausable.fail() + } +} + +pub trait MmioDev: Mmio + Pause {} diff --git a/alioth/src/device/fw_cfg/fw_cfg.rs b/alioth/src/device/fw_cfg/fw_cfg.rs index 34ab4e09..46cafb90 100644 --- a/alioth/src/device/fw_cfg/fw_cfg.rs +++ b/alioth/src/device/fw_cfg/fw_cfg.rs @@ -39,7 +39,7 @@ use zerocopy::{FromBytes, Immutable, IntoBytes}; use crate::arch::layout::{ PORT_FW_CFG_DATA, PORT_FW_CFG_DMA_HI, PORT_FW_CFG_DMA_LO, PORT_FW_CFG_SELECTOR, }; -use crate::device::MmioDev; +use crate::device::{self, MmioDev, Pause}; #[cfg(target_arch = "x86_64")] use crate::firmware::acpi::AcpiTable; #[cfg(target_arch = "x86_64")] @@ -513,6 +513,16 @@ impl Mmio for Mutex { } } +impl Pause for Mutex { + fn pause(&self) -> device::Result<()> { + Ok(()) + } + + fn resume(&self) -> device::Result<()> { + Ok(()) + } +} + impl MmioDev for Mutex {} #[derive(Debug, PartialEq, Eq, Deserialize, Help)] diff --git a/alioth/src/device/pl011.rs b/alioth/src/device/pl011.rs index 5ed2c253..06586fd8 100644 --- a/alioth/src/device/pl011.rs +++ b/alioth/src/device/pl011.rs @@ -19,8 +19,8 @@ use std::sync::Arc; use bitflags::bitflags; use parking_lot::Mutex; -use crate::device::MmioDev; use crate::device::console::{Console, UartRecv}; +use crate::device::{self, MmioDev, Pause}; use crate::hv::IrqSender; use crate::mem::emulated::{Action, Mmio}; use crate::{hv, mem}; @@ -259,6 +259,19 @@ where } } +impl Pause for Pl011 +where + I: IrqSender, +{ + fn pause(&self) -> device::Result<()> { + Ok(()) + } + + fn resume(&self) -> device::Result<()> { + Ok(()) + } +} + impl MmioDev for Pl011 where I: IrqSender {} struct Pl011Recv { diff --git a/alioth/src/device/pl031.rs b/alioth/src/device/pl031.rs index 2035b528..616e2966 100644 --- a/alioth/src/device/pl031.rs +++ b/alioth/src/device/pl031.rs @@ -20,7 +20,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use bitflags::bitflags; use parking_lot::Mutex; -use crate::device::MmioDev; +use crate::device::{self, MmioDev, Pause}; use crate::mem; use crate::mem::emulated::{Action, Mmio}; @@ -143,4 +143,14 @@ impl Mmio for Pl031 { } } +impl Pause for Pl031 { + fn pause(&self) -> device::Result<()> { + Ok(()) + } + + fn resume(&self) -> device::Result<()> { + Ok(()) + } +} + impl MmioDev for Pl031 {} diff --git a/alioth/src/device/serial.rs b/alioth/src/device/serial.rs index 9d5b21ff..78e30ab4 100644 --- a/alioth/src/device/serial.rs +++ b/alioth/src/device/serial.rs @@ -20,8 +20,8 @@ use bitfield::bitfield; use bitflags::bitflags; use parking_lot::Mutex; -use crate::device::MmioDev; use crate::device::console::{Console, UartRecv}; +use crate::device::{self, MmioDev, Pause}; use crate::hv::IrqSender; use crate::mem; use crate::mem::emulated::{Action, Mmio}; @@ -283,6 +283,19 @@ where } } +impl Pause for Serial +where + I: IrqSender, +{ + fn pause(&self) -> device::Result<()> { + Ok(()) + } + + fn resume(&self) -> device::Result<()> { + Ok(()) + } +} + impl MmioDev for Serial where I: IrqSender {} struct SerialRecv { From c99885738863803e6ad8f509eeb24b5ed27a26c6 Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Wed, 4 Feb 2026 23:14:21 -0800 Subject: [PATCH 5/5] feat(pci): make PCI devices pausable Require the `Pci` trait to implement the `Pause` trait. Signed-off-by: Changyuan Lyu --- alioth/src/pci/host_bridge.rs | 11 +++++++++++ alioth/src/pci/pci.rs | 3 ++- alioth/src/pci/pvpanic.rs | 11 +++++++++++ alioth/src/pci/segment.rs | 11 +++++++++++ alioth/src/vfio/pci.rs | 8 ++++++++ alioth/src/virtio/pci.rs | 8 ++++++++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/alioth/src/pci/host_bridge.rs b/alioth/src/pci/host_bridge.rs index 9d7fcba7..2ba275d2 100644 --- a/alioth/src/pci/host_bridge.rs +++ b/alioth/src/pci/host_bridge.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::device::{self, Pause}; use crate::pci; use crate::pci::cap::PciCapList; use crate::pci::config::{CommonHeader, DeviceHeader, EmulatedConfig, HeaderType, PciConfig}; @@ -47,6 +48,16 @@ impl HostBridge { } } +impl Pause for HostBridge { + fn pause(&self) -> device::Result<()> { + Ok(()) + } + + fn resume(&self) -> device::Result<()> { + Ok(()) + } +} + impl Pci for HostBridge { fn name(&self) -> &str { "host_bridge" diff --git a/alioth/src/pci/pci.rs b/alioth/src/pci/pci.rs index 712aa09b..00f9172e 100644 --- a/alioth/src/pci/pci.rs +++ b/alioth/src/pci/pci.rs @@ -25,6 +25,7 @@ use std::sync::Arc; use bitfield::bitfield; use snafu::Snafu; +use crate::device::Pause; use crate::errors::{DebugTrace, trace_error}; use crate::mem::{IoRegion, MemRegion}; @@ -60,7 +61,7 @@ pub enum Error { pub type Result = std::result::Result; -pub trait Pci: Debug + Send + Sync + 'static { +pub trait Pci: Debug + Send + Sync + Pause + 'static { fn name(&self) -> &str; fn config(&self) -> &dyn PciConfig; fn reset(&self) -> Result<()>; diff --git a/alioth/src/pci/pvpanic.rs b/alioth/src/pci/pvpanic.rs index a1583c75..419e5063 100644 --- a/alioth/src/pci/pvpanic.rs +++ b/alioth/src/pci/pvpanic.rs @@ -16,6 +16,7 @@ use std::sync::Arc; use bitflags::bitflags; +use crate::device::{self, Pause}; use crate::mem::emulated::{Action, Mmio}; use crate::mem::{self, MemRegion}; use crate::pci::cap::PciCapList; @@ -92,6 +93,16 @@ impl Default for PvPanic { } } +impl Pause for PvPanic { + fn pause(&self) -> device::Result<()> { + Ok(()) + } + + fn resume(&self) -> device::Result<()> { + Ok(()) + } +} + impl Pci for PvPanic { fn name(&self) -> &str { "pvpanic" diff --git a/alioth/src/pci/segment.rs b/alioth/src/pci/segment.rs index 755014ee..a1d145d3 100644 --- a/alioth/src/pci/segment.rs +++ b/alioth/src/pci/segment.rs @@ -18,6 +18,7 @@ use std::sync::Arc; use parking_lot::{Mutex, RwLock}; +use crate::device::{self, Pause}; use crate::mem::emulated::{Action, Mmio}; use crate::pci::config::{BAR_IO, BAR_MEM64, BAR_PREFETCHABLE, PciConfig}; use crate::pci::{Bdf, Pci, Result}; @@ -26,6 +27,16 @@ use crate::{align_up, mem}; #[derive(Debug)] struct EmptyDevice; +impl Pause for EmptyDevice { + fn pause(&self) -> device::Result<()> { + Ok(()) + } + + fn resume(&self) -> device::Result<()> { + Ok(()) + } +} + impl Pci for EmptyDevice { fn name(&self) -> &str { "empty_device" diff --git a/alioth/src/vfio/pci.rs b/alioth/src/vfio/pci.rs index 0c4c8273..14c0d65e 100644 --- a/alioth/src/vfio/pci.rs +++ b/alioth/src/vfio/pci.rs @@ -26,6 +26,7 @@ use libc::{PROT_READ, PROT_WRITE}; use parking_lot::{Mutex, RwLock}; use zerocopy::{FromBytes, transmute}; +use crate::device::Pause; use crate::errors::BoxTrace; use crate::hv::{IrqFd, MsiSender}; use crate::mem::emulated::{Action, Mmio, MmioBus}; @@ -331,6 +332,13 @@ where msix_table: Arc>, } +impl Pause for VfioPciDev +where + M: MsiSender, + D: Device, +{ +} + impl Pci for VfioPciDev where D: Device, diff --git a/alioth/src/virtio/pci.rs b/alioth/src/virtio/pci.rs index 97e8be87..a1444746 100644 --- a/alioth/src/virtio/pci.rs +++ b/alioth/src/virtio/pci.rs @@ -24,6 +24,7 @@ use alioth_macros::Layout; use parking_lot::{Mutex, RwLock}; use zerocopy::{FromZeros, Immutable, IntoBytes}; +use crate::device::Pause; use crate::hv::{self, IoeventFd, IoeventFdRegistry, IrqFd, MsiSender}; use crate::mem::emulated::{Action, Mmio}; use crate::mem::{MemRange, MemRegion, MemRegionCallback, MemRegionEntry}; @@ -914,6 +915,13 @@ where } } +impl Pause for VirtioPciDevice +where + M: MsiSender, + E: IoeventFd, +{ +} + impl Pci for VirtioPciDevice where M: MsiSender,