Skip to main content

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}