1use xen_sys::{
2 VM_EVENT_X86_CR0, VM_EVENT_X86_CR3, VM_EVENT_X86_CR4, VM_EVENT_X86_XCR0, vm_event_cpuid,
3 vm_event_debug, vm_event_desc_access, vm_event_fast_singlestep, vm_event_interrupt_x86,
4 vm_event_io, vm_event_mem_access, vm_event_mov_to_msr, vm_event_paging, vm_event_sharing,
5 vm_event_singlestep, vm_event_vmexit, vm_event_write_ctrlreg,
6};
7
8use crate::XenX86EventType;
9
10#[derive(Debug)]
11pub struct VmEventMemAccess {
12 pub gfn: u64,
13 pub offset: u64,
14 pub gla: u64,
15 pub flags: u32,
16}
17
18impl From<vm_event_mem_access> for VmEventMemAccess {
19 fn from(value: vm_event_mem_access) -> Self {
20 Self {
21 gfn: value.gfn,
22 offset: value.offset,
23 gla: value.gla,
24 flags: value.flags,
25 }
26 }
27}
28
29impl From<VmEventMemAccess> for vm_event_mem_access {
30 fn from(value: VmEventMemAccess) -> Self {
31 Self {
32 gfn: value.gfn,
33 offset: value.offset,
34 gla: value.gla,
35 flags: value.flags,
36 _pad: Default::default(),
37 }
38 }
39}
40
41#[derive(Debug)]
42pub struct VmEventSharing {
43 pub gfn: u64,
44 pub p2mt: u32,
45}
46
47impl From<vm_event_sharing> for VmEventSharing {
48 fn from(value: vm_event_sharing) -> Self {
49 Self {
50 gfn: value.gfn,
51 p2mt: value.p2mt,
52 }
53 }
54}
55
56impl From<VmEventSharing> for vm_event_sharing {
57 fn from(value: VmEventSharing) -> Self {
58 Self {
59 gfn: value.gfn,
60 p2mt: value.p2mt,
61 _pad: Default::default(),
62 }
63 }
64}
65
66#[derive(Debug)]
67pub struct VmEventPaging {
68 pub gfn: u64,
69 pub p2mt: u32,
70 pub flags: u32,
71}
72
73impl From<vm_event_paging> for VmEventPaging {
74 fn from(value: vm_event_paging) -> Self {
75 Self {
76 gfn: value.gfn,
77 p2mt: value.p2mt,
78 flags: value.flags,
79 }
80 }
81}
82
83impl From<VmEventPaging> for vm_event_paging {
84 fn from(value: VmEventPaging) -> Self {
85 Self {
86 gfn: value.gfn,
87 p2mt: value.p2mt,
88 flags: value.flags,
89 }
90 }
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
94#[repr(u32)]
95pub enum VmEventCtrlReg {
96 Cr0 = VM_EVENT_X86_CR0,
97 Cr3 = VM_EVENT_X86_CR3,
98 Cr4 = VM_EVENT_X86_CR4,
99 Xcr0 = VM_EVENT_X86_XCR0,
100}
101
102impl From<u32> for VmEventCtrlReg {
103 fn from(value: u32) -> Self {
104 match value {
105 VM_EVENT_X86_CR0 => Self::Cr0,
106 VM_EVENT_X86_CR3 => Self::Cr3,
107 VM_EVENT_X86_CR4 => Self::Cr4,
108 VM_EVENT_X86_XCR0 => Self::Xcr0,
109 _ => Self::Cr0,
110 }
111 }
112}
113
114impl From<VmEventCtrlReg> for u32 {
115 fn from(value: VmEventCtrlReg) -> Self {
116 value as u32
117 }
118}
119
120#[derive(Debug)]
121pub struct VmEventWriteCtrlReg {
122 pub index: VmEventCtrlReg,
123 pub new_value: u64,
124 pub old_value: u64,
125}
126
127impl From<vm_event_write_ctrlreg> for VmEventWriteCtrlReg {
128 fn from(value: vm_event_write_ctrlreg) -> Self {
129 Self {
130 index: value.index.into(),
131 new_value: value.new_value,
132 old_value: value.old_value,
133 }
134 }
135}
136
137impl From<VmEventWriteCtrlReg> for vm_event_write_ctrlreg {
138 fn from(value: VmEventWriteCtrlReg) -> Self {
139 Self {
140 index: value.index.into(),
141 new_value: value.new_value,
142 old_value: value.old_value,
143 _pad: Default::default(),
144 }
145 }
146}
147
148#[derive(Debug)]
149pub struct VmEventMovToMsr {
150 pub msr: u64,
151 pub new_value: u64,
152 pub old_value: u64,
153}
154
155impl From<vm_event_mov_to_msr> for VmEventMovToMsr {
156 fn from(value: vm_event_mov_to_msr) -> Self {
157 Self {
158 msr: value.msr,
159 new_value: value.new_value,
160 old_value: value.old_value,
161 }
162 }
163}
164
165impl From<VmEventMovToMsr> for vm_event_mov_to_msr {
166 fn from(value: VmEventMovToMsr) -> Self {
167 Self {
168 msr: value.msr,
169 new_value: value.new_value,
170 old_value: value.old_value,
171 }
172 }
173}
174
175#[derive(Debug)]
176pub struct VmEventDebug {
177 pub gfn: u64,
178 pub pending_dbg: u64, pub insn_length: u32,
180 pub typ: XenX86EventType,
181}
182
183impl From<vm_event_debug> for VmEventDebug {
184 fn from(value: vm_event_debug) -> Self {
185 Self {
186 gfn: value.gfn,
187 pending_dbg: value.pending_dbg,
188 insn_length: value.insn_length,
189 typ: unsafe { std::mem::transmute::<u8, XenX86EventType>(value.type_) },
190 }
191 }
192}
193
194impl From<VmEventDebug> for vm_event_debug {
195 fn from(value: VmEventDebug) -> Self {
196 Self {
197 gfn: value.gfn,
198 pending_dbg: value.pending_dbg,
199 insn_length: value.insn_length,
200 type_: value.typ as u8,
201 _pad: Default::default(),
202 }
203 }
204}
205
206#[derive(Debug)]
207pub struct VmEventSinglestep {
208 pub gfn: u64,
209}
210
211impl From<vm_event_singlestep> for VmEventSinglestep {
212 fn from(value: vm_event_singlestep) -> Self {
213 Self { gfn: value.gfn }
214 }
215}
216
217impl From<VmEventSinglestep> for vm_event_singlestep {
218 fn from(value: VmEventSinglestep) -> Self {
219 Self { gfn: value.gfn }
220 }
221}
222
223#[derive(Debug)]
224pub struct VmEventFastSinglestep {
225 pub p2midx: u16,
226}
227
228impl From<vm_event_fast_singlestep> for VmEventFastSinglestep {
229 fn from(value: vm_event_fast_singlestep) -> Self {
230 Self {
231 p2midx: value.p2midx,
232 }
233 }
234}
235
236impl From<VmEventFastSinglestep> for vm_event_fast_singlestep {
237 fn from(value: VmEventFastSinglestep) -> Self {
238 Self {
239 p2midx: value.p2midx,
240 }
241 }
242}
243
244#[derive(Debug)]
245pub struct VmEventCpuid {
246 pub insn_length: u32,
247 pub leaf: u32,
248 pub subleaf: u32,
249}
250
251impl From<vm_event_cpuid> for VmEventCpuid {
252 fn from(value: vm_event_cpuid) -> Self {
253 Self {
254 insn_length: value.insn_length,
255 leaf: value.leaf,
256 subleaf: value.subleaf,
257 }
258 }
259}
260
261impl From<VmEventCpuid> for vm_event_cpuid {
262 fn from(value: VmEventCpuid) -> Self {
263 Self {
264 insn_length: value.insn_length,
265 leaf: value.leaf,
266 subleaf: value.subleaf,
267 _pad: Default::default(),
268 }
269 }
270}
271
272#[derive(Debug)]
273pub struct VmEventInterrupt {
274 pub vector: u32,
275 pub ty: u32,
276 pub error_code: u32,
277 pub cr2: u64,
278}
279
280impl From<vm_event_interrupt_x86> for VmEventInterrupt {
281 fn from(value: vm_event_interrupt_x86) -> Self {
282 Self {
283 vector: value.vector,
284 ty: value.type_,
285 error_code: value.error_code,
286 cr2: value.cr2,
287 }
288 }
289}
290
291impl From<VmEventInterrupt> for vm_event_interrupt_x86 {
292 fn from(value: VmEventInterrupt) -> Self {
293 Self {
294 vector: value.vector,
295 type_: value.ty,
296 error_code: value.error_code,
297 cr2: value.cr2,
298 _pad: Default::default(),
299 }
300 }
301}
302
303#[derive(Debug)]
304pub struct VmEventDescriptorAccess {
305 pub instr_info: u32, pub exit_qualification: u64, pub descriptor: u8, pub is_write: u8,
309}
310
311impl From<vm_event_desc_access> for VmEventDescriptorAccess {
312 fn from(value: vm_event_desc_access) -> Self {
313 Self {
314 instr_info: unsafe { value.arch.vmx.instr_info },
315 exit_qualification: unsafe { value.arch.vmx.exit_qualification },
316 descriptor: value.descriptor,
317 is_write: value.is_write,
318 }
319 }
320}
321
322impl From<VmEventDescriptorAccess> for vm_event_desc_access {
323 fn from(value: VmEventDescriptorAccess) -> Self {
324 let mut result = Self::default();
325 result.arch.vmx.instr_info = value.instr_info;
326 result.arch.vmx.exit_qualification = value.exit_qualification;
327 result.descriptor = value.descriptor;
328 result.is_write = value.is_write;
329 result
330 }
331}
332
333#[derive(Debug)]
334pub struct VmEventVmExit {
335 pub reason: u64,
336 pub qualification: u64,
337}
338
339impl From<vm_event_vmexit> for VmEventVmExit {
340 fn from(value: vm_event_vmexit) -> Self {
341 Self {
342 reason: value.arch.vmx.reason,
343 qualification: value.arch.vmx.qualification,
344 }
345 }
346}
347
348impl From<VmEventVmExit> for vm_event_vmexit {
349 fn from(value: VmEventVmExit) -> Self {
350 let mut result = Self::default();
351 result.arch.vmx.reason = value.reason;
352 result.arch.vmx.qualification = value.qualification;
353 result
354 }
355}
356
357#[derive(Debug)]
358pub struct VmEventIo {
359 pub bytes: u32, pub port: u16, pub direction: u8, pub str: u8, }
364
365impl From<vm_event_io> for VmEventIo {
366 fn from(value: vm_event_io) -> Self {
367 Self {
368 bytes: value.bytes,
369 port: value.port,
370 direction: value.in_,
371 str: value.str_,
372 }
373 }
374}
375
376impl From<VmEventIo> for vm_event_io {
377 fn from(value: VmEventIo) -> Self {
378 Self {
379 bytes: value.bytes,
380 port: value.port,
381 in_: value.direction,
382 str_: value.str,
383 }
384 }
385}
386
387#[derive(Debug)]
388#[repr(u32)]
389pub enum VmEventReason {
390 Unknown,
392
393 MemoryAccess(VmEventMemAccess),
395
396 MemorySharing(VmEventSharing),
398
399 MemoryPaging(VmEventPaging),
401
402 WriteCtrlReg(VmEventWriteCtrlReg),
404
405 MovToMsr(VmEventMovToMsr),
407
408 SoftwareBreakpoint(VmEventDebug),
410
411 Singlestep(VmEventSinglestep),
413
414 GuestRequest,
416
417 DebugException(VmEventDebug),
419
420 Cpuid(VmEventCpuid),
422
423 PrivilegedCall,
428
429 Interrupt(VmEventInterrupt),
431
432 DescriptorAccess(VmEventDescriptorAccess),
434
435 EmulUnimplemented,
437
438 VmExit(VmEventVmExit),
440
441 IoInstruction(VmEventIo),
443}