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
86/// Capability to modify memory access permissions.
87pub trait VmiSetProtection: VmiDriver {
88 /// Sets the memory access permissions for a specific GFN.
89 fn set_memory_access(&self, gfn: Gfn, view: View, access: MemoryAccess)
90 -> Result<(), VmiError>;
91
92 /// Sets the memory access permissions for a specific GFN with additional
93 /// options.
94 fn set_memory_access_with_options(
95 &self,
96 gfn: Gfn,
97 view: View,
98 access: MemoryAccess,
99 options: MemoryAccessOptions,
100 ) -> Result<(), VmiError>;
101}
102
103/// Capability to read vCPU registers.
104pub trait VmiQueryRegisters: VmiDriver {
105 /// Returns the registers of a specific virtual CPU.
106 fn registers(
107 &self,
108 vcpu: VcpuId,
109 ) -> Result<<Self::Architecture as Architecture>::Registers, VmiError>;
110}
111
112/// Capability to write vCPU registers.
113pub trait VmiSetRegisters: VmiDriver {
114 /// Sets the registers of a specific virtual CPU.
115 fn set_registers(
116 &self,
117 vcpu: VcpuId,
118 registers: <Self::Architecture as Architecture>::Registers,
119 ) -> Result<(), VmiError>;
120}
121
122/// Capability to control event monitoring and delivery.
123pub trait VmiEventControl: VmiDriver {
124 /// Enables monitoring of specific events.
125 fn monitor_enable(
126 &self,
127 option: <Self::Architecture as Architecture>::EventMonitor,
128 ) -> Result<(), VmiError>;
129
130 /// Disables monitoring of specific events.
131 fn monitor_disable(
132 &self,
133 option: <Self::Architecture as Architecture>::EventMonitor,
134 ) -> Result<(), VmiError>;
135
136 /// Returns the number of pending events.
137 fn events_pending(&self) -> usize;
138
139 /// Returns the time spent processing events.
140 fn event_processing_overhead(&self) -> Duration;
141
142 /// Waits for an event to occur and processes it with the provided handler.
143 fn wait_for_event(
144 &self,
145 timeout: Duration,
146 handler: impl FnMut(&VmiEvent<Self::Architecture>) -> VmiEventResponse<Self::Architecture>,
147 ) -> Result<(), VmiError>;
148}
149
150/// Capability to manage EPT/NPT views.
151pub trait VmiViewControl: VmiDriver {
152 /// Returns the default view for the virtual machine.
153 fn default_view(&self) -> View;
154
155 /// Creates a new view with the specified default access permissions.
156 fn create_view(&self, default_access: MemoryAccess) -> Result<View, VmiError>;
157
158 /// Destroys a previously created view.
159 fn destroy_view(&self, view: View) -> Result<(), VmiError>;
160
161 /// Switches to a different view.
162 fn switch_to_view(&self, view: View) -> Result<(), VmiError>;
163
164 /// Changes the mapping of a GFN in a specific view.
165 fn change_view_gfn(&self, view: View, old_gfn: Gfn, new_gfn: Gfn) -> Result<(), VmiError>;
166
167 /// Resets the mapping of a GFN in a specific view to its original state.
168 fn reset_view_gfn(&self, view: View, gfn: Gfn) -> Result<(), VmiError>;
169}
170
171/// Capability to control VM lifecycle and GFN allocation.
172pub trait VmiVmControl: VmiDriver {
173 /// Pauses the virtual machine.
174 fn pause(&self) -> Result<(), VmiError>;
175
176 /// Resumes the virtual machine.
177 fn resume(&self) -> Result<(), VmiError>;
178
179 /// Allocates a GFN.
180 fn allocate_gfn(&self) -> Result<Gfn, VmiError>;
181
182 /// Allocates a GFN at a specific location.
183 fn allocate_gfn_at(&self, gfn: Gfn) -> Result<(), VmiError>;
184
185 /// Frees a previously allocated GFN.
186 fn free_gfn(&self, gfn: Gfn) -> Result<(), VmiError>;
187
188 /// Injects an interrupt into a specific virtual CPU.
189 fn inject_interrupt(
190 &self,
191 vcpu: VcpuId,
192 interrupt: <Self::Architecture as Architecture>::Interrupt,
193 ) -> Result<(), VmiError>;
194
195 /// Resets the state of the VMI system.
196 fn reset_state(&self) -> Result<(), VmiError>;
197}
198
199///////////////////////////////////////////////////////////////////////////////
200// Convenience Supertraits
201///////////////////////////////////////////////////////////////////////////////
202
203/// Combined page read and write access.
204pub trait VmiMemory: VmiRead + VmiWrite {}
205impl<T: VmiRead + VmiWrite> VmiMemory for T {}
206
207/// Combined memory access read and write.
208pub trait VmiProtection: VmiQueryProtection + VmiSetProtection {}
209impl<T: VmiQueryProtection + VmiSetProtection> VmiProtection for T {}
210
211/// Combined register read and write access.
212pub trait VmiRegisters: VmiQueryRegisters + VmiSetRegisters {}
213impl<T: VmiQueryRegisters + VmiSetRegisters> VmiRegisters for T {}
214
215/// All read-only VMI capabilities.
216pub trait VmiReadAccess: VmiRead + VmiQueryProtection + VmiQueryRegisters {}
217impl<T: VmiRead + VmiQueryProtection + VmiQueryRegisters> VmiReadAccess for T {}
218
219/// All write/control VMI capabilities.
220pub trait VmiWriteAccess: VmiWrite + VmiSetProtection + VmiSetRegisters {}
221impl<T> VmiWriteAccess for T where T: VmiWrite + VmiSetProtection + VmiSetRegisters {}
222
223/// A trait for implementing a VMI driver.
224///
225/// This is a convenience supertrait that combines all sub-traits.
226/// Types implementing all sub-traits automatically implement `VmiDriver`
227/// via a blanket implementation.
228pub trait VmiFullDriver:
229 VmiReadAccess + VmiWriteAccess + VmiEventControl + VmiViewControl + VmiVmControl
230{
231}
232
233impl<T> VmiFullDriver for T where
234 T: VmiReadAccess + VmiWriteAccess + VmiEventControl + VmiViewControl + VmiVmControl
235{
236}