arcbox_hypervisor/traits.rs
1//! Core traits for hypervisor abstraction.
2//!
3//! These traits define the platform-agnostic interface that all hypervisor
4//! backends must implement.
5
6use std::any::Any;
7
8use crate::{
9 config::VmConfig,
10 error::HypervisorError,
11 memory::GuestAddress,
12 types::{
13 DeviceSnapshot, DirtyPageInfo, PlatformCapabilities, Registers, VcpuExit, VcpuSnapshot,
14 VirtioDeviceConfig,
15 },
16};
17
18/// Main hypervisor trait for creating and managing virtual machines.
19///
20/// Each platform (macOS, Linux) provides its own implementation.
21pub trait Hypervisor: Send + Sync + 'static {
22 /// The virtual machine type created by this hypervisor.
23 type Vm: VirtualMachine;
24
25 /// Returns the platform capabilities.
26 fn capabilities(&self) -> &PlatformCapabilities;
27
28 /// Creates a new virtual machine with the given configuration.
29 ///
30 /// # Errors
31 ///
32 /// Returns an error if the VM cannot be created.
33 fn create_vm(&self, config: VmConfig) -> Result<Self::Vm, HypervisorError>;
34}
35
36/// Virtual machine trait for managing VM lifecycle and devices.
37pub trait VirtualMachine: Send + Sync {
38 /// The vCPU type for this VM.
39 type Vcpu: Vcpu;
40 /// The guest memory type for this VM.
41 type Memory: GuestMemory;
42
43 /// Returns whether this VM uses managed execution.
44 ///
45 /// **Managed execution** (returns `true`):
46 /// - The hypervisor manages vCPU execution internally
47 /// - `start()` begins VM execution, `stop()` ends it
48 /// - `create_vcpu()` is optional/placeholder
49 /// - Examples: macOS Virtualization.framework
50 ///
51 /// **Manual execution** (returns `false`):
52 /// - The caller must create vCPU threads and call `vcpu.run()` in a loop
53 /// - `start()` and `stop()` are optional state markers
54 /// - Examples: Linux KVM
55 fn is_managed_execution(&self) -> bool {
56 false // Default to manual execution (KVM-style)
57 }
58
59 /// Returns a reference to the guest memory.
60 fn memory(&self) -> &Self::Memory;
61
62 /// Creates a new vCPU.
63 ///
64 /// For managed execution VMs, this may return a placeholder vCPU.
65 ///
66 /// # Errors
67 ///
68 /// Returns an error if the vCPU cannot be created.
69 fn create_vcpu(&mut self, id: u32) -> Result<Self::Vcpu, HypervisorError>;
70
71 /// Adds a `VirtIO` device to the VM.
72 ///
73 /// # Errors
74 ///
75 /// Returns an error if the device cannot be added.
76 fn add_virtio_device(&mut self, device: VirtioDeviceConfig) -> Result<(), HypervisorError>;
77
78 /// Starts the VM.
79 ///
80 /// # Errors
81 ///
82 /// Returns an error if the VM cannot be started.
83 fn start(&mut self) -> Result<(), HypervisorError>;
84
85 /// Pauses the VM.
86 ///
87 /// # Errors
88 ///
89 /// Returns an error if the VM cannot be paused.
90 fn pause(&mut self) -> Result<(), HypervisorError>;
91
92 /// Resumes a paused VM.
93 ///
94 /// # Errors
95 ///
96 /// Returns an error if the VM cannot be resumed.
97 fn resume(&mut self) -> Result<(), HypervisorError>;
98
99 /// Stops the VM.
100 ///
101 /// # Errors
102 ///
103 /// Returns an error if the VM cannot be stopped.
104 fn stop(&mut self) -> Result<(), HypervisorError>;
105
106 /// Returns the VM as a reference to `Any` for downcasting.
107 ///
108 /// This allows the caller to downcast the VM to its concrete type
109 /// for platform-specific operations like IRQ injection.
110 fn as_any(&self) -> &dyn Any;
111
112 /// Returns the VM as a mutable reference to `Any` for downcasting.
113 fn as_any_mut(&mut self) -> &mut dyn Any;
114
115 /// Returns the number of vCPUs in the VM.
116 fn vcpu_count(&self) -> u32;
117
118 /// Gets snapshots of all device states.
119 ///
120 /// # Errors
121 ///
122 /// Returns an error if device states cannot be captured.
123 fn snapshot_devices(&self) -> Result<Vec<DeviceSnapshot>, HypervisorError>;
124
125 /// Restores device states from snapshots.
126 ///
127 /// # Errors
128 ///
129 /// Returns an error if device states cannot be restored.
130 fn restore_devices(&mut self, snapshots: &[DeviceSnapshot]) -> Result<(), HypervisorError>;
131}
132
133/// Virtual CPU trait for executing guest code.
134pub trait Vcpu: Send {
135 /// Runs the vCPU until a VM exit occurs.
136 ///
137 /// # Errors
138 ///
139 /// Returns an error if vCPU execution fails.
140 fn run(&mut self) -> Result<VcpuExit, HypervisorError>;
141
142 /// Gets the current register state.
143 ///
144 /// # Errors
145 ///
146 /// Returns an error if registers cannot be read.
147 fn get_regs(&self) -> Result<Registers, HypervisorError>;
148
149 /// Sets the register state.
150 ///
151 /// # Errors
152 ///
153 /// Returns an error if registers cannot be set.
154 fn set_regs(&mut self, regs: &Registers) -> Result<(), HypervisorError>;
155
156 /// Gets the vCPU ID.
157 fn id(&self) -> u32;
158
159 /// Sets the result of an I/O read operation.
160 ///
161 /// This is called after handling an `IoIn` exit to provide the value
162 /// that should be returned to the guest.
163 ///
164 /// # Errors
165 ///
166 /// Returns an error if the result cannot be set.
167 fn set_io_result(&mut self, value: u64) -> Result<(), HypervisorError>;
168
169 /// Sets the result of an MMIO read operation.
170 ///
171 /// This is called after handling an `MmioRead` exit to provide the value
172 /// that should be returned to the guest.
173 ///
174 /// # Errors
175 ///
176 /// Returns an error if the result cannot be set.
177 fn set_mmio_result(&mut self, value: u64) -> Result<(), HypervisorError>;
178
179 /// Creates a snapshot of the vCPU state.
180 ///
181 /// # Errors
182 ///
183 /// Returns an error if the snapshot cannot be created.
184 fn snapshot(&self) -> Result<VcpuSnapshot, HypervisorError>;
185
186 /// Restores the vCPU state from a snapshot.
187 ///
188 /// # Errors
189 ///
190 /// Returns an error if the state cannot be restored.
191 fn restore(&mut self, snapshot: &VcpuSnapshot) -> Result<(), HypervisorError>;
192}
193
194/// Guest memory trait for reading/writing guest physical memory.
195pub trait GuestMemory: Send + Sync {
196 /// Reads bytes from guest memory.
197 ///
198 /// # Errors
199 ///
200 /// Returns an error if the read fails.
201 fn read(&self, addr: GuestAddress, buf: &mut [u8]) -> Result<(), HypervisorError>;
202
203 /// Writes bytes to guest memory.
204 ///
205 /// # Errors
206 ///
207 /// Returns an error if the write fails.
208 fn write(&self, addr: GuestAddress, buf: &[u8]) -> Result<(), HypervisorError>;
209
210 /// Gets the host virtual address for a guest physical address.
211 ///
212 /// This is used for zero-copy operations.
213 ///
214 /// # Safety
215 ///
216 /// The returned pointer is only valid while the memory mapping exists.
217 ///
218 /// # Errors
219 ///
220 /// Returns an error if the address is not mapped.
221 fn get_host_address(&self, addr: GuestAddress) -> Result<*mut u8, HypervisorError>;
222
223 /// Returns the total size of guest memory in bytes.
224 fn size(&self) -> u64;
225
226 /// Enables dirty page tracking.
227 ///
228 /// After enabling, use `get_dirty_pages()` to retrieve modified pages.
229 ///
230 /// # Errors
231 ///
232 /// Returns an error if dirty tracking cannot be enabled.
233 fn enable_dirty_tracking(&mut self) -> Result<(), HypervisorError>;
234
235 /// Disables dirty page tracking.
236 ///
237 /// # Errors
238 ///
239 /// Returns an error if dirty tracking cannot be disabled.
240 fn disable_dirty_tracking(&mut self) -> Result<(), HypervisorError>;
241
242 /// Gets and clears the list of dirty pages since the last call.
243 ///
244 /// This resets the dirty bitmap after returning.
245 ///
246 /// # Errors
247 ///
248 /// Returns an error if dirty pages cannot be retrieved.
249 fn get_dirty_pages(&mut self) -> Result<Vec<DirtyPageInfo>, HypervisorError>;
250
251 /// Reads all guest memory into a buffer.
252 ///
253 /// # Errors
254 ///
255 /// Returns an error if memory cannot be read.
256 fn dump_all(&self, buf: &mut [u8]) -> Result<(), HypervisorError>;
257}