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}