1#![warn(missing_docs)]
7
8use super::AccessError;
9use super::GuestMemory;
10use super::MemoryRead;
11use super::MemoryWrite;
12use super::PAGE_SIZE;
13use super::PAGE_SIZE64;
14use crate::InvalidGpn;
15
16#[derive(Debug, Copy, Clone, PartialEq, Eq)]
18pub struct AddressRange {
19 pub start: u64,
21 pub end: u64,
23}
24
25impl AddressRange {
26 pub fn len(&self) -> u64 {
28 self.end - self.start
29 }
30
31 pub fn is_empty(&self) -> bool {
33 self.end == self.start
34 }
35}
36
37impl From<std::ops::Range<u64>> for AddressRange {
38 fn from(range: std::ops::Range<u64>) -> Self {
39 Self {
40 start: range.start,
41 end: range.end,
42 }
43 }
44}
45
46#[derive(Debug, Copy, Clone)]
52pub struct PagedRange<'a> {
53 start: usize,
56 end: usize,
59 gpns: &'a [u64],
61}
62
63impl<'a> PagedRange<'a> {
64 pub const PAGE_SIZE: usize = PAGE_SIZE;
66
67 pub const fn new(offset: usize, len: usize, gpns: &'a [u64]) -> Option<Self> {
71 let maxlen = gpns.len() * PAGE_SIZE;
72 if maxlen < offset || maxlen - offset < len {
73 return None;
74 }
75 Some(PagedRange {
76 start: offset,
77 end: offset + len,
78 gpns,
79 })
80 }
81
82 pub const fn empty() -> Self {
84 PagedRange {
85 start: 0,
86 end: 0,
87 gpns: &[],
88 }
89 }
90
91 pub fn try_subrange(&self, offset: usize, len: usize) -> Option<Self> {
93 if self.len() >= offset && self.len() - offset >= len {
94 Some(PagedRange {
95 start: self.start + offset,
96 end: self.start + offset + len,
97 gpns: self.gpns,
98 })
99 } else {
100 None
101 }
102 }
103
104 #[track_caller]
108 pub fn subrange(&self, offset: usize, len: usize) -> Self {
109 self.try_subrange(offset, len)
110 .unwrap_or_else(|| panic!("invalid subrange: {} + {} > {}", offset, len, self.len()))
111 }
112
113 pub fn len(&self) -> usize {
115 self.end - self.start
116 }
117
118 pub fn is_empty(&self) -> bool {
120 self.start == self.end
121 }
122
123 pub fn offset(&self) -> usize {
125 self.start % PAGE_SIZE
126 }
127
128 pub fn gpns(&self) -> &'a [u64] {
130 let start_page = self.start / PAGE_SIZE;
131 let end_page = self.end.div_ceil(PAGE_SIZE);
132 &self.gpns[start_page..end_page]
133 }
134
135 pub fn skip(&mut self, len: usize) {
139 assert!(self.len() >= len);
140 self.start += len;
141 }
142
143 pub fn truncate(&mut self, len: usize) {
147 assert!(self.len() >= len);
148 self.end = self.start + len;
149 }
150
151 pub fn split(self, offset: usize) -> (Self, Self) {
155 assert!(self.len() >= offset);
156 (
157 Self {
158 start: self.start,
159 end: self.start + offset,
160 gpns: self.gpns,
161 },
162 Self {
163 start: self.start + offset,
164 end: self.end,
165 gpns: self.gpns,
166 },
167 )
168 }
169
170 pub fn try_split(self, offset: usize) -> Option<(Self, Self)> {
173 if self.len() >= offset {
174 Some((
175 Self {
176 start: self.start,
177 end: self.start + offset,
178 gpns: self.gpns,
179 },
180 Self {
181 start: self.start + offset,
182 end: self.end,
183 gpns: self.gpns,
184 },
185 ))
186 } else {
187 None
188 }
189 }
190
191 pub fn pop_front_range(&mut self) -> Option<Result<AddressRange, InvalidGpn>> {
193 if self.is_empty() {
194 None
195 } else {
196 let start_page = self.start / PAGE_SIZE;
197 let end_page = self.end.div_ceil(PAGE_SIZE);
198 let mut page = start_page + 1;
199 while page < end_page && self.gpns[page - 1] + 1 == self.gpns[page] {
200 page += 1;
201 }
202
203 let end = (page * PAGE_SIZE).min(self.end);
204
205 let gpa = match crate::gpn_to_gpa(self.gpns[start_page]) {
206 Ok(gpa) => gpa,
207 Err(e) => return Some(Err(e)),
208 };
209 let start_gpa = gpa + self.start as u64 % PAGE_SIZE64;
210 let range = AddressRange {
211 start: start_gpa,
212 end: start_gpa + (end - self.start) as u64,
213 };
214 self.start = end;
215 Some(Ok(range))
216 }
217 }
218
219 pub fn reader(self, mem: &'a GuestMemory) -> PagedRangeReader<'a> {
221 PagedRangeReader { range: self, mem }
222 }
223
224 pub fn writer(self, mem: &'a GuestMemory) -> PagedRangeWriter<'a> {
226 PagedRangeWriter { range: self, mem }
227 }
228
229 pub fn ranges(self) -> PagedRangeRangeIter<'a> {
232 PagedRangeRangeIter(self)
233 }
234}
235
236#[derive(Debug, Clone)]
238pub struct PagedRangeRangeIter<'a>(PagedRange<'a>);
239
240impl Iterator for PagedRangeRangeIter<'_> {
241 type Item = Result<AddressRange, InvalidGpn>;
242
243 fn next(&mut self) -> Option<Self::Item> {
244 self.0.pop_front_range()
245 }
246}
247
248pub struct PagedRangeReader<'a> {
250 range: PagedRange<'a>,
251 mem: &'a GuestMemory,
252}
253
254impl MemoryRead for PagedRangeReader<'_> {
255 fn read(&mut self, data: &mut [u8]) -> Result<&mut Self, AccessError> {
256 let range = self
257 .range
258 .try_subrange(0, data.len())
259 .ok_or_else(|| AccessError::OutOfRange(self.len(), data.len()))?;
260 self.mem
261 .read_range(&range, data)
262 .map_err(AccessError::Memory)?;
263 self.range.skip(data.len());
264 Ok(self)
265 }
266
267 fn skip(&mut self, len: usize) -> Result<&mut Self, AccessError> {
268 if self.len() < len {
269 return Err(AccessError::OutOfRange(self.len(), len));
270 }
271 self.range.skip(len);
272 Ok(self)
273 }
274
275 fn len(&self) -> usize {
276 self.range.len()
277 }
278}
279
280pub struct PagedRangeWriter<'a> {
282 range: PagedRange<'a>,
283 mem: &'a GuestMemory,
284}
285
286impl MemoryWrite for PagedRangeWriter<'_> {
287 fn write(&mut self, data: &[u8]) -> Result<(), AccessError> {
288 let range = self
289 .range
290 .try_subrange(0, data.len())
291 .ok_or_else(|| AccessError::OutOfRange(self.len(), data.len()))?;
292 self.mem
293 .write_range(&range, data)
294 .map_err(AccessError::Memory)?;
295 self.range.skip(data.len());
296 Ok(())
297 }
298
299 fn fill(&mut self, val: u8, len: usize) -> Result<(), AccessError> {
300 let range = self
301 .range
302 .try_subrange(0, len)
303 .ok_or_else(|| AccessError::OutOfRange(self.len(), len))?;
304 self.mem
305 .fill_range(&range, val)
306 .map_err(AccessError::Memory)?;
307 self.range.skip(len);
308 Ok(())
309 }
310
311 fn len(&self) -> usize {
312 self.range.len()
313 }
314}
315
316#[derive(Debug, Clone)]
318pub struct PagedRanges<'a, T> {
319 ranges: T,
320 current: Option<PagedRange<'a>>,
321 start: usize,
322 end: usize,
323}
324
325impl<'a, T: Iterator<Item = PagedRange<'a>> + Clone> PagedRanges<'a, T> {
326 pub fn new<I>(ranges: I) -> Self
328 where
329 I: IntoIterator<IntoIter = T>,
330 {
331 let ranges = ranges.into_iter();
332 let len = ranges.clone().map(|range| range.len()).sum();
333 Self {
334 ranges,
335 current: None,
336 start: 0,
337 end: len,
338 }
339 }
340}
341
342impl<'a, T: Iterator<Item = PagedRange<'a>>> PagedRanges<'a, T> {
343 pub fn len(&self) -> usize {
345 self.end - self.start
346 }
347
348 pub fn is_empty(&self) -> bool {
350 self.start == self.end
351 }
352
353 pub fn skip(&mut self, mut len: usize) {
355 assert!(self.len() >= len);
356 while len > 0 {
357 let n = self.current(len).len();
358 self.advance(n);
359 len -= n;
360 }
361 }
362
363 pub fn truncate(&mut self, len: usize) {
367 assert!(self.len() >= len);
368 self.end = self.start + len;
369 }
370
371 pub fn paged_ranges(self) -> PagedRangesIter<'a, T> {
373 PagedRangesIter(self)
374 }
375
376 pub fn reader(self, mem: &'a GuestMemory) -> PagedRangesReader<'a, T> {
378 PagedRangesReader { views: self, mem }
379 }
380
381 pub fn writer(self, mem: &'a GuestMemory) -> PagedRangesWriter<'a, T> {
383 PagedRangesWriter { views: self, mem }
384 }
385
386 fn current(&mut self, max_len: usize) -> PagedRange<'a> {
387 debug_assert!(max_len <= self.len());
388 if self.current.is_none() {
389 self.current = self.ranges.next();
390 }
391 let range = self.current.unwrap();
392 range.subrange(self.start, max_len.min(range.len() - self.start))
393 }
394
395 fn advance(&mut self, n: usize) {
396 let current = self.current.as_ref().unwrap();
397 self.start += n;
398 if self.start == current.len() {
399 self.current = None;
400 self.end -= self.start;
401 self.start = 0;
402 }
403 }
404}
405
406pub struct PagedRangesIter<'a, T>(PagedRanges<'a, T>);
408
409impl<'a, T: Iterator<Item = PagedRange<'a>>> Iterator for PagedRangesIter<'a, T> {
410 type Item = PagedRange<'a>;
411
412 fn next(&mut self) -> Option<Self::Item> {
413 if self.0.is_empty() {
414 return None;
415 }
416 let current = self
417 .0
418 .current
419 .take()
420 .or_else(|| self.0.ranges.next())
421 .unwrap();
422 let offset = self.0.start;
423 let len = self.0.end.min(current.len()) - offset;
424 self.0.end -= offset + len;
425 self.0.current = None;
426 self.0.start = 0;
427 Some(current.subrange(offset, len))
428 }
429}
430
431#[derive(Debug, Clone)]
433pub struct PagedRangesReader<'a, T> {
434 views: PagedRanges<'a, T>,
435 mem: &'a GuestMemory,
436}
437
438impl<'a, T> PagedRangesReader<'a, T> {
439 pub fn into_inner(self) -> PagedRanges<'a, T> {
441 self.views
442 }
443}
444
445impl<'a, T: Iterator<Item = PagedRange<'a>>> MemoryRead for PagedRangesReader<'a, T> {
446 fn read(&mut self, mut data: &mut [u8]) -> Result<&mut Self, AccessError> {
447 if self.len() < data.len() {
448 return Err(AccessError::OutOfRange(self.len(), data.len()));
449 }
450 while !data.is_empty() {
451 let range = self.views.current(data.len());
452 let (buf, rest) = data.split_at_mut(range.len());
453 self.mem
454 .read_range(&range, buf)
455 .map_err(AccessError::Memory)?;
456 self.views.advance(range.len());
457 data = rest;
458 }
459 Ok(self)
460 }
461
462 fn skip(&mut self, len: usize) -> Result<&mut Self, AccessError> {
463 if self.len() < len {
464 return Err(AccessError::OutOfRange(self.len(), len));
465 }
466 self.views.skip(len);
467 Ok(self)
468 }
469
470 fn len(&self) -> usize {
471 self.views.len()
472 }
473}
474
475#[derive(Debug)]
477pub struct PagedRangesWriter<'a, T> {
478 views: PagedRanges<'a, T>,
479 mem: &'a GuestMemory,
480}
481
482impl<'a, T> PagedRangesWriter<'a, T> {
483 pub fn into_inner(self) -> PagedRanges<'a, T> {
485 self.views
486 }
487}
488
489impl<'a, T: Iterator<Item = PagedRange<'a>>> MemoryWrite for PagedRangesWriter<'a, T> {
490 fn write(&mut self, mut data: &[u8]) -> Result<(), AccessError> {
491 if self.len() < data.len() {
492 return Err(AccessError::OutOfRange(self.len(), data.len()));
493 }
494 while !data.is_empty() {
495 let range = self.views.current(data.len());
496 let (buf, rest) = data.split_at(range.len());
497 self.mem
498 .write_range(&range, buf)
499 .map_err(AccessError::Memory)?;
500 self.views.advance(range.len());
501 data = rest;
502 }
503 Ok(())
504 }
505
506 fn fill(&mut self, val: u8, mut len: usize) -> Result<(), AccessError> {
507 if self.len() < len {
508 return Err(AccessError::OutOfRange(self.len(), len));
509 }
510 while len > 0 {
511 let range = self.views.current(len);
512 self.mem
513 .fill_range(&range, val)
514 .map_err(AccessError::Memory)?;
515 self.views.advance(range.len());
516 len -= range.len();
517 }
518 Ok(())
519 }
520
521 fn len(&self) -> usize {
522 self.views.len()
523 }
524}
525
526#[cfg(test)]
527mod tests {
528 use super::*;
529
530 #[test]
531 fn test_ranges() {
532 assert!(PagedRange::new(1, PAGE_SIZE, &[1]).is_none());
533
534 let view1 = PagedRange::new(0x123, 0x2012, &[0x11, 0x22, 0x33]).unwrap();
535 let view2 = PagedRange::new(0x456, 0x2017, &[0x111, 0x112, 0x222]).unwrap();
536 let views = [view1, view2];
537 let mut multi = PagedRanges::new(views.iter().copied());
538 multi.skip(0x100);
539 multi.truncate(0x2f29);
540
541 let r1: Result<Vec<_>, _> = multi.paged_ranges().flat_map(|r| r.ranges()).collect();
542 let r2: Vec<_> = [
543 0x11223..0x12000,
544 0x22000..0x23000,
545 0x33000..0x33135,
546 0x111456..0x11246d,
547 ]
548 .map(AddressRange::from)
549 .to_vec();
550
551 assert_eq!(&r1.unwrap(), &r2);
552 }
553}