1mod arch;
4mod driver;
5mod error;
6
7use std::{path::Path, time::Duration};
8
9use vmi_core::{
10 Architecture, Gfn, MemoryAccess, MemoryAccessOptions, VcpuId, View, VmiDriver, VmiError,
11 VmiEvent, VmiEventResponse, VmiInfo, VmiMappedPage,
12};
13
14pub use self::error::Error;
15use self::{arch::ArchAdapter, driver::KdmpDriver};
16
17pub struct VmiKdmpDriver<Arch>
19where
20 Arch: Architecture + ArchAdapter,
21{
22 inner: KdmpDriver<Arch>,
23}
24
25impl<Arch> VmiKdmpDriver<Arch>
26where
27 Arch: Architecture + ArchAdapter,
28{
29 pub fn new(path: impl AsRef<Path>) -> Result<Self, VmiError> {
31 Ok(Self {
32 inner: KdmpDriver::new(path)?,
33 })
34 }
35}
36
37impl<Arch> VmiDriver for VmiKdmpDriver<Arch>
38where
39 Arch: Architecture + ArchAdapter,
40{
41 type Architecture = Arch;
42
43 fn info(&self) -> Result<VmiInfo, VmiError> {
44 Ok(self.inner.info()?)
45 }
46
47 fn pause(&self) -> Result<(), VmiError> {
48 Ok(self.inner.pause()?)
49 }
50
51 fn resume(&self) -> Result<(), VmiError> {
52 Ok(self.inner.resume()?)
53 }
54
55 fn registers(&self, vcpu: VcpuId) -> Result<Arch::Registers, VmiError> {
56 Ok(self.inner.registers(vcpu)?)
57 }
58
59 fn set_registers(&self, vcpu: VcpuId, registers: Arch::Registers) -> Result<(), VmiError> {
60 Ok(self.inner.set_registers(vcpu, registers)?)
61 }
62
63 fn memory_access(&self, gfn: Gfn, view: View) -> Result<MemoryAccess, VmiError> {
64 Ok(self.inner.memory_access(gfn, view)?)
65 }
66
67 fn set_memory_access(
68 &self,
69 gfn: Gfn,
70 view: View,
71 access: MemoryAccess,
72 ) -> Result<(), VmiError> {
73 Ok(self.inner.set_memory_access(gfn, view, access)?)
74 }
75
76 fn set_memory_access_with_options(
77 &self,
78 gfn: Gfn,
79 view: View,
80 access: MemoryAccess,
81 options: MemoryAccessOptions,
82 ) -> Result<(), VmiError> {
83 Ok(self
84 .inner
85 .set_memory_access_with_options(gfn, view, access, options)?)
86 }
87
88 fn read_page(&self, gfn: Gfn) -> Result<VmiMappedPage, VmiError> {
89 Ok(self.inner.read_page(gfn)?)
90 }
91
92 fn write_page(&self, gfn: Gfn, offset: u64, content: &[u8]) -> Result<VmiMappedPage, VmiError> {
93 Ok(self.inner.write_page(gfn, offset, content)?)
94 }
95
96 fn allocate_gfn(&self, gfn: Gfn) -> Result<(), VmiError> {
97 Ok(self.inner.allocate_gfn(gfn)?)
98 }
99
100 fn free_gfn(&self, gfn: Gfn) -> Result<(), VmiError> {
101 Ok(self.inner.free_gfn(gfn)?)
102 }
103
104 fn default_view(&self) -> View {
105 self.inner.default_view()
106 }
107
108 fn create_view(&self, default_access: MemoryAccess) -> Result<View, VmiError> {
109 Ok(self.inner.create_view(default_access)?)
110 }
111
112 fn destroy_view(&self, view: View) -> Result<(), VmiError> {
113 Ok(self.inner.destroy_view(view)?)
114 }
115
116 fn switch_to_view(&self, view: View) -> Result<(), VmiError> {
117 Ok(self.inner.switch_to_view(view)?)
118 }
119
120 fn change_view_gfn(&self, view: View, old_gfn: Gfn, new_gfn: Gfn) -> Result<(), VmiError> {
121 Ok(self.inner.change_view_gfn(view, old_gfn, new_gfn)?)
122 }
123
124 fn reset_view_gfn(&self, view: View, gfn: Gfn) -> Result<(), VmiError> {
125 Ok(self.inner.reset_view_gfn(view, gfn)?)
126 }
127
128 fn monitor_enable(&self, option: Arch::EventMonitor) -> Result<(), VmiError> {
129 Ok(self.inner.monitor_enable(option)?)
130 }
131
132 fn monitor_disable(&self, option: Arch::EventMonitor) -> Result<(), VmiError> {
133 Ok(self.inner.monitor_disable(option)?)
134 }
135
136 fn inject_interrupt(&self, vcpu: VcpuId, interrupt: Arch::Interrupt) -> Result<(), VmiError> {
137 Ok(self.inner.inject_interrupt(vcpu, interrupt)?)
138 }
139
140 fn events_pending(&self) -> usize {
141 self.inner.events_pending()
142 }
143
144 fn event_processing_overhead(&self) -> Duration {
145 self.inner.event_processing_overhead()
146 }
147
148 fn wait_for_event(
149 &self,
150 timeout: Duration,
151 handler: impl FnMut(&VmiEvent<Arch>) -> VmiEventResponse<Arch>,
152 ) -> Result<(), VmiError> {
153 Ok(self.inner.wait_for_event(timeout, handler)?)
154 }
155
156 fn reset_state(&self) -> Result<(), VmiError> {
157 Ok(self.inner.reset_state()?)
158 }
159}