vmi_core/driver.rs
1//! VMI driver trait hierarchy.
2//!
3//! Defines the capabilities a VMI driver can provide. Each trait represents
4//! an independent capability; drivers implement only the traits they support.
5//!
6//! # Trait hierarchy
7//!
8//! All sub-traits extend [`VmiDriver`], the base trait that carries the
9//! [`Architecture`] associated type and VM metadata.
10//!
11//! ```text
12//! VmiDriver (base: Architecture type + info)
13//! ├── VmiRead read guest physical pages
14//! ├── VmiWrite write guest physical pages
15//! ├── VmiQueryProtection query EPT/NPT page permissions
16//! ├── VmiSetProtection modify EPT/NPT page permissions
17//! ├── VmiQueryRegisters get vCPU register state
18//! ├── VmiSetRegisters set vCPU register state
19//! ├── VmiViewControl manage EPT/NPT views
20//! ├── VmiEventControl monitor and intercept events
21//! └── VmiVmControl VM lifecycle, interrupt injection
22//! ```
23//!
24//! # Convenience supertraits
25//!
26//! ```text
27//! VmiMemory = VmiRead + VmiWrite
28//! VmiProtection = VmiQueryProtection + VmiSetProtection
29//! VmiRegisters = VmiQueryRegisters + VmiSetRegisters
30//! VmiFullDriver = all of the above
31//! ```
32//!
33//! # Examples
34//!
35//! A crash dump driver only needs read-only access:
36//!
37//! ```ignore
38//! impl VmiDriver for MyDumpDriver { /* ... */ }
39//! impl VmiRead for MyDumpDriver { /* ... */ }
40//! impl VmiQueryRegisters for MyDumpDriver { /* ... */ }
41//! ```
42//!
43//! A hypervisor-backed driver that implements everything automatically
44//! satisfies [`VmiFullDriver`].
45
46use std::time::Duration;
47
48use crate::{
49 Architecture, Gfn, MemoryAccess, MemoryAccessOptions, VcpuId, View, VmiError, VmiEvent,
50 VmiEventResponse, VmiInfo, VmiMappedPage,
51};
52
53/// Base trait for all VMI driver sub-traits.
54///
55/// This trait provides the associated [`Architecture`] type and the
56/// fundamental `info()` method for querying VM metadata.
57///
58/// The `'static` lifetime is required in order to use the driver with the
59/// [`VmiOs`](crate::VmiOs) enumerators.
60pub trait VmiDriver: 'static {
61 /// The architecture supported by the driver.
62 type Architecture: Architecture;
63
64 /// Returns information about the virtual machine.
65 fn info(&self) -> Result<VmiInfo, VmiError>;
66}
67
68/// Capability to read guest physical memory pages.
69pub trait VmiRead: VmiDriver {
70 /// Reads a page of memory from the virtual machine.
71 fn read_page(&self, gfn: Gfn) -> Result<VmiMappedPage, VmiError>;
72}
73
74/// Capability to write guest physical memory pages.
75pub trait VmiWrite: VmiDriver {
76 /// Writes data to a page of memory in the virtual machine.
77 fn write_page(&self, gfn: Gfn, offset: u64, content: &[u8]) -> Result<VmiMappedPage, VmiError>;
78}
79
80/// Capability to query memory access permissions.
81pub trait VmiQueryProtection: VmiDriver {
82 /// Returns the memory access permissions for a specific GFN.
83 fn memory_access(&self, gfn: Gfn, view: View) -> Result<MemoryAccess, VmiError>;
84
85 /// Returns the memory access permissions for a specific GFN with
86 /// additional options.
87 fn memory_access_with_options(
88 &self,
89 gfn: Gfn,
90 view: View,
91 ) -> Result<(MemoryAccess, MemoryAccessOptions), VmiError>;
92}
93
94/// Capability to modify memory access permissions.
95pub trait VmiSetProtection: VmiDriver {
96 /// Sets the memory access permissions for a specific GFN.
97 fn set_memory_access(&self, gfn: Gfn, view: View, access: MemoryAccess)
98 -> Result<(), VmiError>;
99
100 /// Sets the memory access permissions for a specific GFN with additional
101 /// options.
102 fn set_memory_access_with_options(
103 &self,
104 gfn: Gfn,
105 view: View,
106 access: MemoryAccess,
107 options: MemoryAccessOptions,
108 ) -> Result<(), VmiError>;
109}
110
111/// Capability to read vCPU registers.
112pub trait VmiQueryRegisters: VmiDriver {
113 /// Returns the registers of a specific virtual CPU.
114 fn registers(
115 &self,
116 vcpu: VcpuId,
117 ) -> Result<<Self::Architecture as Architecture>::Registers, VmiError>;
118}
119
120/// Capability to write vCPU registers.
121pub trait VmiSetRegisters: VmiDriver {
122 /// Sets the registers of a specific virtual CPU.
123 fn set_registers(
124 &self,
125 vcpu: VcpuId,
126 registers: <Self::Architecture as Architecture>::Registers,
127 ) -> Result<(), VmiError>;
128}
129
130/// Capability to control event monitoring and delivery.
131pub trait VmiEventControl: VmiDriver {
132 /// Enables monitoring of specific events.
133 fn monitor_enable(
134 &self,
135 option: <Self::Architecture as Architecture>::EventMonitor,
136 ) -> Result<(), VmiError>;
137
138 /// Disables monitoring of specific events.
139 fn monitor_disable(
140 &self,
141 option: <Self::Architecture as Architecture>::EventMonitor,
142 ) -> Result<(), VmiError>;
143
144 /// Returns the number of pending events.
145 fn events_pending(&self) -> usize;
146
147 /// Returns the time spent processing events.
148 fn event_processing_overhead(&self) -> Duration;
149
150 /// Waits for an event to occur and processes it with the provided handler.
151 fn wait_for_event(
152 &self,
153 timeout: Duration,
154 handler: impl FnMut(&VmiEvent<Self::Architecture>) -> VmiEventResponse<Self::Architecture>,
155 ) -> Result<(), VmiError>;
156}
157
158/// Capability to manage EPT/NPT views.
159pub trait VmiViewControl: VmiDriver {
160 /// Returns the default view for the virtual machine.
161 fn default_view(&self) -> View;
162
163 /// Creates a new view with the specified default access permissions.
164 fn create_view(&self, default_access: MemoryAccess) -> Result<View, VmiError>;
165
166 /// Destroys a previously created view.
167 fn destroy_view(&self, view: View) -> Result<(), VmiError>;
168
169 /// Switches to a different view.
170 fn switch_to_view(&self, view: View) -> Result<(), VmiError>;
171
172 /// Changes the mapping of a GFN in a specific view.
173 fn change_view_gfn(&self, view: View, old_gfn: Gfn, new_gfn: Gfn) -> Result<(), VmiError>;
174
175 /// Resets the mapping of a GFN in a specific view to its original state.
176 fn reset_view_gfn(&self, view: View, gfn: Gfn) -> Result<(), VmiError>;
177}
178
179/// Capability to control VM lifecycle and GFN allocation.
180pub trait VmiVmControl: VmiDriver {
181 /// Pauses the virtual machine.
182 fn pause(&self) -> Result<(), VmiError>;
183
184 /// Resumes the virtual machine.
185 fn resume(&self) -> Result<(), VmiError>;
186
187 /// Allocates a GFN.
188 fn allocate_gfn(&self) -> Result<Gfn, VmiError>;
189
190 /// Allocates a GFN at a specific location.
191 fn allocate_gfn_at(&self, gfn: Gfn) -> Result<(), VmiError>;
192
193 /// Frees a previously allocated GFN.
194 fn free_gfn(&self, gfn: Gfn) -> Result<(), VmiError>;
195
196 /// Injects an interrupt into a specific virtual CPU.
197 fn inject_interrupt(
198 &self,
199 vcpu: VcpuId,
200 interrupt: <Self::Architecture as Architecture>::Interrupt,
201 ) -> Result<(), VmiError>;
202
203 /// Resets the state of the VMI system.
204 fn reset_state(&self) -> Result<(), VmiError>;
205}
206
207///////////////////////////////////////////////////////////////////////////////
208// Convenience Supertraits
209///////////////////////////////////////////////////////////////////////////////
210
211/// Combined page read and write access.
212pub trait VmiMemory: VmiRead + VmiWrite {}
213impl<T> VmiMemory for T where T: VmiRead + VmiWrite {}
214
215/// Combined memory access read and write.
216pub trait VmiProtection: VmiQueryProtection + VmiSetProtection {}
217impl<T> VmiProtection for T where T: VmiQueryProtection + VmiSetProtection {}
218
219/// Combined register read and write access.
220pub trait VmiRegisters: VmiQueryRegisters + VmiSetRegisters {}
221impl<T> VmiRegisters for T where T: VmiQueryRegisters + VmiSetRegisters {}
222
223/// All read-only VMI capabilities.
224pub trait VmiReadAccess: VmiRead + VmiQueryProtection + VmiQueryRegisters {}
225impl<T> VmiReadAccess for T where T: VmiRead + VmiQueryProtection + VmiQueryRegisters {}
226
227/// All write/control VMI capabilities.
228pub trait VmiWriteAccess: VmiWrite + VmiSetProtection + VmiSetRegisters {}
229impl<T> VmiWriteAccess for T where T: VmiWrite + VmiSetProtection + VmiSetRegisters {}
230
231/// A trait for implementing a VMI driver.
232///
233/// This is a convenience supertrait that combines all sub-traits.
234/// Types implementing all sub-traits automatically implement `VmiDriver`
235/// via a blanket implementation.
236pub trait VmiFullDriver:
237 VmiReadAccess + VmiWriteAccess + VmiEventControl + VmiViewControl + VmiVmControl
238{
239}
240
241impl<T> VmiFullDriver for T where
242 T: VmiReadAccess + VmiWriteAccess + VmiEventControl + VmiViewControl + VmiVmControl
243{
244}