vmi_core/core/
access_context.rs1use serde::{Deserialize, Serialize};
2
3use super::macros::impl_ops;
4use crate::AddressContext;
5
6impl_ops!(Gfn, u64, "Guest Frame Number");
7impl_ops!(Pa, u64, "Guest Physical Address");
8impl_ops!(Va, u64, "Guest Virtual Address");
9
10impl Va {
11 pub fn is_null(self) -> bool {
13 self.0 == 0
14 }
15}
16
17pub trait VmiVa {
19 fn va(&self) -> Va;
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
29pub enum TranslationMechanism {
30 Direct,
35
36 Paging {
42 root: Option<Pa>,
46 },
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
56pub struct AccessContext {
57 pub address: u64,
64
65 pub mechanism: TranslationMechanism,
74}
75
76impl AccessContext {
77 pub fn direct(address: impl Into<Pa>) -> Self {
79 Self {
80 address: u64::from(address.into()),
81 mechanism: TranslationMechanism::Direct,
82 }
83 }
84
85 pub fn paging(address: impl Into<Va>, root: impl Into<Pa>) -> Self {
87 Self {
88 address: address.into().0,
89 mechanism: TranslationMechanism::Paging {
90 root: Some(root.into()),
91 },
92 }
93 }
94}
95
96impl From<Pa> for AccessContext {
97 fn from(value: Pa) -> Self {
98 Self::direct(value)
99 }
100}
101
102impl From<(Va, Pa)> for AccessContext {
103 fn from(value: (Va, Pa)) -> Self {
104 Self::paging(value.0, value.1)
105 }
106}
107
108impl From<AddressContext> for AccessContext {
109 fn from(value: AddressContext) -> Self {
110 Self {
111 address: value.va.0,
112 mechanism: TranslationMechanism::Paging {
113 root: Some(value.root),
114 },
115 }
116 }
117}
118
119impl ::std::ops::Add<u64> for AccessContext {
120 type Output = AccessContext;
121
122 fn add(self, rhs: u64) -> Self::Output {
123 Self {
124 address: self.address + rhs,
125 ..self
126 }
127 }
128}
129
130impl ::std::ops::Add<AccessContext> for AccessContext {
131 type Output = AccessContext;
132
133 fn add(self, rhs: AccessContext) -> Self::Output {
134 Self {
135 address: self.address + rhs.address,
136 ..self
137 }
138 }
139}
140
141impl ::std::ops::AddAssign<u64> for AccessContext {
142 fn add_assign(&mut self, rhs: u64) {
143 self.address += rhs;
144 }
145}
146
147impl ::std::ops::AddAssign<AccessContext> for AccessContext {
148 fn add_assign(&mut self, rhs: AccessContext) {
149 self.address += rhs.address;
150 }
151}
152
153impl ::std::ops::Sub<u64> for AccessContext {
154 type Output = AccessContext;
155
156 fn sub(self, rhs: u64) -> Self::Output {
157 Self {
158 address: self.address - rhs,
159 ..self
160 }
161 }
162}
163
164impl ::std::ops::Sub<AccessContext> for AccessContext {
165 type Output = AccessContext;
166
167 fn sub(self, rhs: AccessContext) -> Self::Output {
168 Self {
169 address: self.address - rhs.address,
170 ..self
171 }
172 }
173}
174
175impl ::std::ops::SubAssign<u64> for AccessContext {
176 fn sub_assign(&mut self, rhs: u64) {
177 self.address -= rhs;
178 }
179}
180
181impl ::std::ops::SubAssign<AccessContext> for AccessContext {
182 fn sub_assign(&mut self, rhs: AccessContext) {
183 self.address -= rhs.address;
184 }
185}
186
187impl ::std::ops::Mul<u64> for AccessContext {
188 type Output = AccessContext;
189
190 fn mul(self, rhs: u64) -> Self::Output {
191 Self {
192 address: self.address * rhs,
193 ..self
194 }
195 }
196}
197
198impl ::std::ops::Mul<AccessContext> for AccessContext {
199 type Output = AccessContext;
200
201 fn mul(self, rhs: AccessContext) -> Self::Output {
202 Self {
203 address: self.address * rhs.address,
204 ..self
205 }
206 }
207}
208
209impl ::std::ops::MulAssign<u64> for AccessContext {
210 fn mul_assign(&mut self, rhs: u64) {
211 self.address *= rhs;
212 }
213}
214
215impl ::std::ops::MulAssign<AccessContext> for AccessContext {
216 fn mul_assign(&mut self, rhs: AccessContext) {
217 self.address *= rhs.address;
218 }
219}
220
221impl ::std::ops::Div<u64> for AccessContext {
222 type Output = AccessContext;
223
224 fn div(self, rhs: u64) -> Self::Output {
225 Self {
226 address: self.address / rhs,
227 ..self
228 }
229 }
230}
231
232impl ::std::ops::Div<AccessContext> for AccessContext {
233 type Output = AccessContext;
234
235 fn div(self, rhs: AccessContext) -> Self::Output {
236 Self {
237 address: self.address / rhs.address,
238 ..self
239 }
240 }
241}
242
243impl ::std::ops::DivAssign<u64> for AccessContext {
244 fn div_assign(&mut self, rhs: u64) {
245 self.address /= rhs;
246 }
247}
248
249impl ::std::ops::DivAssign<AccessContext> for AccessContext {
250 fn div_assign(&mut self, rhs: AccessContext) {
251 self.address /= rhs.address;
252 }
253}
254
255impl ::std::ops::BitAnd<u64> for AccessContext {
256 type Output = AccessContext;
257
258 fn bitand(self, rhs: u64) -> Self::Output {
259 Self {
260 address: self.address & rhs,
261 ..self
262 }
263 }
264}
265
266impl ::std::ops::BitAndAssign<u64> for AccessContext {
267 fn bitand_assign(&mut self, rhs: u64) {
268 self.address &= rhs;
269 }
270}
271
272impl ::std::ops::BitOr<u64> for AccessContext {
273 type Output = AccessContext;
274
275 fn bitor(self, rhs: u64) -> Self::Output {
276 Self {
277 address: self.address | rhs,
278 ..self
279 }
280 }
281}
282
283impl ::std::ops::BitOrAssign<u64> for AccessContext {
284 fn bitor_assign(&mut self, rhs: u64) {
285 self.address |= rhs;
286 }
287}