vmi_core/
event.rs

1use crate::{Architecture, Registers, VcpuId, View};
2
3bitflags::bitflags! {
4    /// Flags that can be set in a VMI event.
5    #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
6    pub struct VmiEventFlags: u8 {
7        /// The virtual CPU is paused.
8        const VCPU_PAUSED = 1 << 0;
9    }
10}
11
12/// An event that occurred during VMI.
13#[derive(Debug, Clone, Copy)]
14pub struct VmiEvent<Arch>
15where
16    Arch: Architecture + ?Sized,
17{
18    /// The ID of the virtual CPU where the event occurred.
19    vcpu_id: VcpuId,
20
21    /// Flags associated with the event.
22    flags: VmiEventFlags,
23
24    /// The view associated with the event, if any.
25    view: Option<View>,
26
27    /// The CPU register state at the time of the event.
28    registers: Arch::Registers,
29
30    /// The reason for the event.
31    reason: Arch::EventReason,
32}
33
34impl<Arch> VmiEvent<Arch>
35where
36    Arch: Architecture + ?Sized,
37{
38    /// Creates a new VMI event.
39    pub fn new(
40        vcpu_id: VcpuId,
41        flags: VmiEventFlags,
42        view: Option<View>,
43        registers: Arch::Registers,
44        reason: Arch::EventReason,
45    ) -> Self {
46        Self {
47            vcpu_id,
48            flags,
49            view,
50            registers,
51            reason,
52        }
53    }
54
55    /// Returns the ID of the virtual CPU where the event occurred.
56    pub fn vcpu_id(&self) -> VcpuId {
57        self.vcpu_id
58    }
59
60    /// Returns flags associated with the event.
61    pub fn flags(&self) -> VmiEventFlags {
62        self.flags
63    }
64
65    /// Returns the view associated with the event, if any.
66    pub fn view(&self) -> Option<View> {
67        self.view
68    }
69
70    /// Returns a reference to the CPU registers at the time of the event.
71    pub fn registers(&self) -> &Arch::Registers {
72        &self.registers
73    }
74
75    /// Returns a reference to the reason for the event.
76    pub fn reason(&self) -> &Arch::EventReason {
77        &self.reason
78    }
79}
80
81bitflags::bitflags! {
82    /// Flags that can be set in a VMI event response.
83    #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
84    pub struct VmiEventResponseFlags: u8 {
85        /// Reinject the interrupt.
86        const REINJECT_INTERRUPT = 1 << 0;
87
88        /// Toggle single-step mode.
89        const TOGGLE_SINGLESTEP = 1 << 1;
90
91        /// Toggle fast single-step mode.
92        const TOGGLE_FAST_SINGLESTEP = 1 << 2;
93
94        /// Emulate the instruction.
95        const EMULATE = 1 << 3;
96    }
97}
98
99/// A response to a VMI event.
100#[derive(Debug)]
101pub struct VmiEventResponse<Arch>
102where
103    Arch: Architecture + ?Sized,
104{
105    /// Flags associated with the response.
106    pub flags: VmiEventResponseFlags,
107
108    /// The view to set for the VCPU.
109    pub view: Option<View>,
110
111    /// The VCPU registers to set.
112    pub registers: Option<<Arch::Registers as Registers>::GpRegisters>,
113}
114
115impl<Arch> Default for VmiEventResponse<Arch>
116where
117    Arch: Architecture + ?Sized,
118{
119    fn default() -> Self {
120        Self {
121            flags: VmiEventResponseFlags::empty(),
122            view: None,
123            registers: None,
124        }
125    }
126}
127
128impl<Arch> VmiEventResponse<Arch>
129where
130    Arch: Architecture + ?Sized,
131{
132    /// Creates a response to reinject an interrupt.
133    pub fn reinject_interrupt() -> Self {
134        Self::default().and_reinject_interrupt()
135    }
136
137    /// Creates a response to toggle single-step mode.
138    pub fn toggle_singlestep() -> Self {
139        Self::default().and_toggle_singlestep()
140    }
141
142    /// Creates a response to toggle fast single-step mode.
143    pub fn toggle_fast_singlestep() -> Self {
144        Self::default().and_toggle_fast_singlestep()
145    }
146
147    /// Creates a response to emulate the instruction.
148    pub fn emulate() -> Self {
149        Self::default().and_emulate()
150    }
151
152    /// Creates a response to set a specific view.
153    pub fn set_view(view: View) -> Self {
154        Self::default().and_set_view(view)
155    }
156
157    /// Creates a response to set specific CPU registers.
158    pub fn set_registers(registers: <Arch::Registers as Registers>::GpRegisters) -> Self {
159        Self::default().and_set_registers(registers)
160    }
161
162    /// Adds the reinject interrupt flag to the response.
163    pub fn and_reinject_interrupt(self) -> Self {
164        Self {
165            flags: self.flags | VmiEventResponseFlags::REINJECT_INTERRUPT,
166            ..self
167        }
168    }
169
170    /// Adds the toggle single-step flag to the response.
171    pub fn and_toggle_singlestep(self) -> Self {
172        Self {
173            flags: self.flags | VmiEventResponseFlags::TOGGLE_SINGLESTEP,
174            ..self
175        }
176    }
177
178    /// Adds the toggle fast single-step flag to the response.
179    pub fn and_toggle_fast_singlestep(self) -> Self {
180        Self {
181            flags: self.flags | VmiEventResponseFlags::TOGGLE_FAST_SINGLESTEP,
182            ..self
183        }
184    }
185
186    /// Adds the emulate flag to the response.
187    pub fn and_emulate(self) -> Self {
188        Self {
189            flags: self.flags | VmiEventResponseFlags::EMULATE,
190            ..self
191        }
192    }
193
194    /// Sets a specific view for the response.
195    pub fn and_set_view(self, view: View) -> Self {
196        Self {
197            view: Some(view),
198            ..self
199        }
200    }
201
202    /// Sets specific CPU registers for the response.
203    pub fn and_set_registers(self, registers: <Arch::Registers as Registers>::GpRegisters) -> Self {
204        Self {
205            registers: Some(registers),
206            ..self
207        }
208    }
209}