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
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}