1use crate::{Architecture, Registers, VcpuId, View};
2
3bitflags::bitflags! {
4 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
6 pub struct VmiEventFlags: u8 {
7 const VCPU_PAUSED = 1 << 0;
9 }
10}
11
12#[derive(Debug, Clone, Copy)]
14pub struct VmiEvent<Arch>
15where
16 Arch: Architecture + ?Sized,
17{
18 vcpu_id: VcpuId,
20
21 flags: VmiEventFlags,
23
24 view: Option<View>,
26
27 registers: Arch::Registers,
29
30 reason: Arch::EventReason,
32}
33
34impl<Arch> VmiEvent<Arch>
35where
36 Arch: Architecture + ?Sized,
37{
38 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 pub fn vcpu_id(&self) -> VcpuId {
57 self.vcpu_id
58 }
59
60 pub fn flags(&self) -> VmiEventFlags {
62 self.flags
63 }
64
65 pub fn view(&self) -> Option<View> {
67 self.view
68 }
69
70 pub fn registers(&self) -> &Arch::Registers {
72 &self.registers
73 }
74
75 pub fn reason(&self) -> &Arch::EventReason {
77 &self.reason
78 }
79}
80
81bitflags::bitflags! {
82 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
84 pub struct VmiEventResponseFlags: u8 {
85 const REINJECT_INTERRUPT = 1 << 0;
87
88 const TOGGLE_SINGLESTEP = 1 << 1;
90
91 const TOGGLE_FAST_SINGLESTEP = 1 << 2;
93
94 const EMULATE = 1 << 3;
96 }
97}
98
99#[derive(Debug)]
101pub struct VmiEventResponse<Arch>
102where
103 Arch: Architecture + ?Sized,
104{
105 pub flags: VmiEventResponseFlags,
107
108 pub view: Option<View>,
110
111 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 pub fn reinject_interrupt() -> Self {
134 Self::default().and_reinject_interrupt()
135 }
136
137 pub fn toggle_singlestep() -> Self {
139 Self::default().and_toggle_singlestep()
140 }
141
142 pub fn toggle_fast_singlestep() -> Self {
144 Self::default().and_toggle_fast_singlestep()
145 }
146
147 pub fn emulate() -> Self {
149 Self::default().and_emulate()
150 }
151
152 pub fn set_view(view: View) -> Self {
154 Self::default().and_set_view(view)
155 }
156
157 pub fn set_registers(registers: <Arch::Registers as Registers>::GpRegisters) -> Self {
159 Self::default().and_set_registers(registers)
160 }
161
162 pub fn and_reinject_interrupt(self) -> Self {
164 Self {
165 flags: self.flags | VmiEventResponseFlags::REINJECT_INTERRUPT,
166 ..self
167 }
168 }
169
170 pub fn and_toggle_singlestep(self) -> Self {
172 Self {
173 flags: self.flags | VmiEventResponseFlags::TOGGLE_SINGLESTEP,
174 ..self
175 }
176 }
177
178 pub fn and_toggle_fast_singlestep(self) -> Self {
180 Self {
181 flags: self.flags | VmiEventResponseFlags::TOGGLE_FAST_SINGLESTEP,
182 ..self
183 }
184 }
185
186 pub fn and_emulate(self) -> Self {
188 Self {
189 flags: self.flags | VmiEventResponseFlags::EMULATE,
190 ..self
191 }
192 }
193
194 pub fn and_set_view(self, view: View) -> Self {
196 Self {
197 view: Some(view),
198 ..self
199 }
200 }
201
202 pub fn and_set_registers(self, registers: <Arch::Registers as Registers>::GpRegisters) -> Self {
204 Self {
205 registers: Some(registers),
206 ..self
207 }
208 }
209}