virt/
io.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::VpHaltReason;
5use hvdef::Vtl;
6use std::future::Future;
7use vm_topology::processor::VpIndex;
8
9/// This trait provides the operations between the VP dispatch loop and the
10/// platform's devices.
11pub trait CpuIo {
12    /// Check if a given address will be handled by a device.
13    fn is_mmio(&self, address: u64) -> bool;
14
15    /// Gets the vector of the next interrupt to inject from the legacy
16    /// interrupt controller (PIC) and sets the IRQ in service.
17    fn acknowledge_pic_interrupt(&self) -> Option<u8>;
18
19    /// Handle End Of Interrupt (EOI)
20    ///
21    /// A `u32` is used for the IRQ value for (future) ARM compat.
22    fn handle_eoi(&self, irq: u32);
23
24    /// Signal a synic event.
25    fn signal_synic_event(&self, vtl: Vtl, connection_id: u32, flag: u16) -> hvdef::HvResult<()>;
26
27    /// Post a synic message.
28    fn post_synic_message(
29        &self,
30        vtl: Vtl,
31        connection_id: u32,
32        secure: bool,
33        message: &[u8],
34    ) -> hvdef::HvResult<()>;
35
36    /// Memory mapped IO read.
37    #[must_use]
38    fn read_mmio(&self, vp: VpIndex, address: u64, data: &mut [u8]) -> impl Future<Output = ()>;
39
40    /// Memory mapped IO write.
41    #[must_use]
42    fn write_mmio(&self, vp: VpIndex, address: u64, data: &[u8]) -> impl Future<Output = ()>;
43
44    /// Programmed IO read.
45    #[must_use]
46    fn read_io(&self, vp: VpIndex, port: u16, data: &mut [u8]) -> impl Future<Output = ()>;
47
48    /// Programmed IO write.
49    #[must_use]
50    fn write_io(&self, vp: VpIndex, port: u16, data: &[u8]) -> impl Future<Output = ()>;
51
52    /// Report an internal fatal error.
53    ///
54    /// The intention behind this method is to allow the top-level VMM
55    /// to specify an error handling policy, while still being able to capture
56    /// stacks and other context from the point of failure. We previously would
57    /// return a `VpHaltReason::Panic` here, but that meant the stack trace
58    /// would be from the point of the panic handler, which lost context.
59    /// See vmotherboard's `FatalErrorPolicy` for an example.
60    #[track_caller]
61    fn fatal_error(&self, error: Box<dyn std::error::Error + Send + Sync>) -> VpHaltReason;
62}