virtio_queue/
descriptor_utils.rs

1// Portions Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE-BSD-3-Clause file.
4//
5// Copyright (C) 2024 Red Hat, Inc. All rights reserved.
6//
7// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
8
9use std::collections::VecDeque;
10use std::io::{self, Read, Write};
11use std::mem::{size_of, MaybeUninit};
12use std::ops::Deref;
13use std::ptr::copy_nonoverlapping;
14use std::{cmp, result};
15
16use crate::{DescriptorChain, Error};
17use vm_memory::bitmap::{BitmapSlice, WithBitmapSlice};
18use vm_memory::{
19    Address, ByteValued, GuestMemory, GuestMemoryRegion, MemoryRegionAddress, VolatileSlice,
20};
21
22pub type Result<T> = result::Result<T, Error>;
23
24#[derive(Clone)]
25struct DescriptorChainConsumer<'a, B> {
26    buffers: VecDeque<VolatileSlice<'a, B>>,
27    bytes_consumed: usize,
28}
29
30impl<'a, B: BitmapSlice> DescriptorChainConsumer<'a, B> {
31    fn available_bytes(&self) -> usize {
32        // This is guaranteed not to overflow because the total length of the chain
33        // is checked during all creations of `DescriptorChainConsumer` (see
34        // `Reader::new()` and `Writer::new()`).
35        self.buffers
36            .iter()
37            .fold(0usize, |count, vs| count + vs.len())
38    }
39
40    fn bytes_consumed(&self) -> usize {
41        self.bytes_consumed
42    }
43
44    /// Consumes at most `count` bytes from the `DescriptorChain`. Callers must provide a function
45    /// that takes a `&[VolatileSlice]` and returns the total number of bytes consumed. This
46    /// function guarantees that the combined length of all the slices in the `&[VolatileSlice]` is
47    /// less than or equal to `count`.
48    ///
49    /// # Errors
50    ///
51    /// If the provided function returns any error then no bytes are consumed from the buffer and
52    /// the error is returned to the caller.
53    fn consume<F>(&mut self, count: usize, f: F) -> io::Result<usize>
54    where
55        F: FnOnce(&[&VolatileSlice<B>]) -> io::Result<usize>,
56    {
57        let mut buflen = 0;
58        let mut bufs = Vec::with_capacity(self.buffers.len());
59        for vs in &self.buffers {
60            if buflen >= count {
61                break;
62            }
63
64            bufs.push(vs);
65
66            let rem = count - buflen;
67            if rem < vs.len() {
68                buflen += rem;
69            } else {
70                buflen += vs.len();
71            }
72        }
73
74        if bufs.is_empty() {
75            return Ok(0);
76        }
77
78        let bytes_consumed = f(&bufs)?;
79
80        // This can happen if a driver tricks a device into reading/writing more data than
81        // fits in a `usize`.
82        let total_bytes_consumed =
83            self.bytes_consumed
84                .checked_add(bytes_consumed)
85                .ok_or_else(|| {
86                    io::Error::new(io::ErrorKind::InvalidData, Error::DescriptorChainOverflow)
87                })?;
88
89        let mut rem = bytes_consumed;
90        while let Some(vs) = self.buffers.pop_front() {
91            if rem < vs.len() {
92                // Split the slice and push the remainder back into the buffer list. Safe because we
93                // know that `rem` is not out of bounds due to the check and we checked the bounds
94                // on `vs` when we added it to the buffer list.
95                self.buffers.push_front(vs.offset(rem).unwrap());
96                break;
97            }
98
99            // No need for checked math because we know that `vs.size() <= rem`.
100            rem -= vs.len();
101        }
102
103        self.bytes_consumed = total_bytes_consumed;
104
105        Ok(bytes_consumed)
106    }
107
108    fn split_at(&mut self, offset: usize) -> Result<DescriptorChainConsumer<'a, B>> {
109        let mut rem = offset;
110        let pos = self.buffers.iter().position(|vs| {
111            if rem < vs.len() {
112                true
113            } else {
114                rem -= vs.len();
115                false
116            }
117        });
118
119        if let Some(at) = pos {
120            let mut other = self.buffers.split_off(at);
121
122            if rem > 0 {
123                // There must be at least one element in `other` because we checked
124                // its `size` value in the call to `position` above.
125                let front = other.pop_front().expect("empty VecDeque after split");
126                self.buffers
127                    .push_back(front.subslice(0, rem).map_err(Error::VolatileMemoryError)?);
128                other.push_front(front.offset(rem).map_err(Error::VolatileMemoryError)?);
129            }
130
131            Ok(DescriptorChainConsumer {
132                buffers: other,
133                bytes_consumed: 0,
134            })
135        } else if rem == 0 {
136            Ok(DescriptorChainConsumer {
137                buffers: VecDeque::new(),
138                bytes_consumed: 0,
139            })
140        } else {
141            Err(Error::SplitOutOfBounds(offset))
142        }
143    }
144}
145
146/// Provides high-level interface over the sequence of memory regions
147/// defined by readable descriptors in the descriptor chain.
148///
149/// Note that virtio spec requires driver to place any device-writable
150/// descriptors after any device-readable descriptors (2.6.4.2 in Virtio Spec v1.1).
151/// Reader will skip iterating over descriptor chain when first writable
152/// descriptor is encountered.
153#[derive(Clone)]
154pub struct Reader<'a, B = ()> {
155    buffer: DescriptorChainConsumer<'a, B>,
156}
157
158impl<'a, B: BitmapSlice> Reader<'a, B> {
159    /// Construct a new Reader wrapper over `desc_chain`.
160    pub fn new<M, T>(mem: &'a M, desc_chain: DescriptorChain<T>) -> Result<Reader<'a, B>>
161    where
162        M: GuestMemory,
163        <<M as GuestMemory>::R as GuestMemoryRegion>::B: WithBitmapSlice<'a, S = B>,
164        T: Deref,
165        T::Target: GuestMemory + Sized,
166    {
167        let mut total_len: usize = 0;
168        let buffers = desc_chain
169            .readable()
170            .map(|desc| {
171                // Verify that summing the descriptor sizes does not overflow.
172                // This can happen if a driver tricks a device into reading more data than
173                // fits in a `usize`.
174                total_len = total_len
175                    .checked_add(desc.len() as usize)
176                    .ok_or(Error::DescriptorChainOverflow)?;
177
178                let region = mem
179                    .find_region(desc.addr())
180                    .ok_or(Error::FindMemoryRegion)?;
181                let offset = desc
182                    .addr()
183                    .checked_sub(region.start_addr().raw_value())
184                    .unwrap();
185                region
186                    .get_slice(MemoryRegionAddress(offset.raw_value()), desc.len() as usize)
187                    .map_err(Error::GuestMemoryError)
188            })
189            .collect::<Result<VecDeque<VolatileSlice<'a, B>>>>()?;
190        Ok(Reader {
191            buffer: DescriptorChainConsumer {
192                buffers,
193                bytes_consumed: 0,
194            },
195        })
196    }
197
198    /// Reads an object from the descriptor chain buffer.
199    pub fn read_obj<T: ByteValued>(&mut self) -> io::Result<T> {
200        let mut obj = MaybeUninit::<T>::uninit();
201
202        // SAFETY: `MaybeUninit` guarantees that the pointer is valid for
203        // `size_of::<T>()` bytes.
204        let buf = unsafe {
205            ::std::slice::from_raw_parts_mut(obj.as_mut_ptr() as *mut u8, size_of::<T>())
206        };
207
208        self.read_exact(buf)?;
209
210        // SAFETY: any type that implements `ByteValued` can be considered initialized
211        // even if it is filled with random data.
212        Ok(unsafe { obj.assume_init() })
213    }
214
215    /// Returns number of bytes available for reading.  May return an error if the combined
216    /// lengths of all the buffers in the DescriptorChain would cause an integer overflow.
217    pub fn available_bytes(&self) -> usize {
218        self.buffer.available_bytes()
219    }
220
221    /// Returns number of bytes already read from the descriptor chain buffer.
222    pub fn bytes_read(&self) -> usize {
223        self.buffer.bytes_consumed()
224    }
225
226    /// Splits this `Reader` into two at the given offset in the `DescriptorChain` buffer.
227    /// After the split, `self` will be able to read up to `offset` bytes while the returned
228    /// `Reader` can read up to `available_bytes() - offset` bytes.  Returns an error if
229    /// `offset > self.available_bytes()`.
230    pub fn split_at(&mut self, offset: usize) -> Result<Reader<'a, B>> {
231        self.buffer.split_at(offset).map(|buffer| Reader { buffer })
232    }
233}
234
235impl<'a, B: BitmapSlice> io::Read for Reader<'a, B> {
236    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
237        self.buffer.consume(buf.len(), |bufs| {
238            let mut rem = buf;
239            let mut total = 0;
240            for vs in bufs {
241                let copy_len = cmp::min(rem.len(), vs.len());
242
243                // SAFETY: Safe because we verify that we do not read outside
244                // of the slice's bound. The slice guard will only get dropped
245                // after the function returns. This will keep the pointer valid
246                // while reads are happening.
247                unsafe {
248                    copy_nonoverlapping(vs.ptr_guard().as_ptr(), rem.as_mut_ptr(), copy_len);
249                }
250                rem = &mut rem[copy_len..];
251                total += copy_len;
252            }
253            Ok(total)
254        })
255    }
256}
257
258/// Provides high-level interface over the sequence of memory regions
259/// defined by writable descriptors in the descriptor chain.
260///
261/// Note that virtio spec requires driver to place any device-writable
262/// descriptors after any device-readable descriptors (2.6.4.2 in Virtio Spec v1.1).
263/// Writer will start iterating the descriptors from the first writable one and will
264/// assume that all following descriptors are writable.
265#[derive(Clone)]
266pub struct Writer<'a, B = ()> {
267    buffer: DescriptorChainConsumer<'a, B>,
268}
269
270impl<'a, B: BitmapSlice> Writer<'a, B> {
271    /// Construct a new Writer wrapper over `desc_chain`.
272    pub fn new<M, T>(mem: &'a M, desc_chain: DescriptorChain<T>) -> Result<Writer<'a, B>>
273    where
274        M: GuestMemory,
275        <<M as GuestMemory>::R as GuestMemoryRegion>::B: WithBitmapSlice<'a, S = B>,
276        T: Deref,
277        T::Target: GuestMemory + Sized,
278    {
279        let mut total_len: usize = 0;
280        let buffers = desc_chain
281            .writable()
282            .map(|desc| {
283                // Verify that summing the descriptor sizes does not overflow.
284                // This can happen if a driver tricks a device into writing more data than
285                // fits in a `usize`.
286                total_len = total_len
287                    .checked_add(desc.len() as usize)
288                    .ok_or(Error::DescriptorChainOverflow)?;
289
290                let region = mem
291                    .find_region(desc.addr())
292                    .ok_or(Error::FindMemoryRegion)?;
293                let offset = desc
294                    .addr()
295                    .checked_sub(region.start_addr().raw_value())
296                    .unwrap();
297                region
298                    .get_slice(MemoryRegionAddress(offset.raw_value()), desc.len() as usize)
299                    .map_err(Error::GuestMemoryError)
300            })
301            .collect::<Result<VecDeque<VolatileSlice<'a, B>>>>()?;
302
303        Ok(Writer {
304            buffer: DescriptorChainConsumer {
305                buffers,
306                bytes_consumed: 0,
307            },
308        })
309    }
310
311    /// Writes an object to the descriptor chain buffer.
312    pub fn write_obj<T: ByteValued>(&mut self, val: T) -> io::Result<()> {
313        self.write_all(val.as_slice())
314    }
315
316    /// Returns number of bytes available for writing.  May return an error if the combined
317    /// lengths of all the buffers in the DescriptorChain would cause an overflow.
318    pub fn available_bytes(&self) -> usize {
319        self.buffer.available_bytes()
320    }
321
322    /// Returns number of bytes already written to the descriptor chain buffer.
323    pub fn bytes_written(&self) -> usize {
324        self.buffer.bytes_consumed()
325    }
326
327    /// Splits this `Writer` into two at the given offset in the `DescriptorChain` buffer.
328    /// After the split, `self` will be able to write up to `offset` bytes while the returned
329    /// `Writer` can write up to `available_bytes() - offset` bytes.  Returns an error if
330    /// `offset > self.available_bytes()`.
331    pub fn split_at(&mut self, offset: usize) -> Result<Writer<'a, B>> {
332        self.buffer.split_at(offset).map(|buffer| Writer { buffer })
333    }
334}
335
336impl<'a, B: BitmapSlice> io::Write for Writer<'a, B> {
337    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
338        self.buffer.consume(buf.len(), |bufs| {
339            let mut rem = buf;
340            let mut total = 0;
341            for vs in bufs {
342                let copy_len = cmp::min(rem.len(), vs.len());
343
344                // SAFETY: Safe because we ensure that we do not write over the
345                // slice's bounds. The slice guard will only get dropped after
346                // the function returns. This will keep the pointer valid while
347                // writes are happening.
348                unsafe {
349                    copy_nonoverlapping(rem.as_ptr(), vs.ptr_guard_mut().as_ptr(), copy_len);
350                }
351                vs.bitmap().mark_dirty(0, copy_len);
352                rem = &rem[copy_len..];
353                total += copy_len;
354            }
355            Ok(total)
356        })
357    }
358
359    fn flush(&mut self) -> io::Result<()> {
360        // Nothing to flush since the writes go straight into the buffer.
361        Ok(())
362    }
363}
364
365#[cfg(test)]
366mod tests {
367    use super::*;
368    use crate::{Descriptor, Queue, QueueOwnedT, QueueT};
369    use vm_memory::{GuestAddress, GuestMemoryMmap, Le32};
370
371    use crate::mock::MockSplitQueue;
372    use virtio_bindings::bindings::virtio_ring::{VRING_DESC_F_NEXT, VRING_DESC_F_WRITE};
373
374    const MAX_QUEUE_SIZE: u16 = 16;
375
376    #[derive(Copy, Clone, PartialEq, Eq)]
377    pub enum DescriptorType {
378        Readable,
379        Writable,
380    }
381
382    /// Test utility function to create a descriptor chain in guest memory.
383    pub fn create_descriptor_chain(
384        memory: &GuestMemoryMmap,
385        descriptor_array_addr: GuestAddress,
386        descriptors: Vec<(DescriptorType, u32)>,
387        spaces_between_regions: u32,
388    ) -> Result<DescriptorChain<&GuestMemoryMmap>> {
389        let descriptors_len = descriptors.len();
390        let mut descs = vec![];
391
392        let queue = MockSplitQueue::create(memory, descriptor_array_addr, MAX_QUEUE_SIZE);
393
394        let mut buffers_start_addr = queue.end();
395
396        for (index, (type_, size)) in descriptors.into_iter().enumerate() {
397            let mut flags = 0;
398            if let DescriptorType::Writable = type_ {
399                flags |= VRING_DESC_F_WRITE;
400            }
401            if index + 1 < descriptors_len {
402                flags |= VRING_DESC_F_NEXT;
403            }
404
405            descs.push(Descriptor::new(
406                buffers_start_addr.raw_value(),
407                size,
408                flags as u16,
409                (index + 1) as u16,
410            ));
411
412            let offset = size + spaces_between_regions;
413            buffers_start_addr = buffers_start_addr
414                .checked_add(u64::from(offset))
415                .ok_or(Error::InvalidChain)?;
416        }
417
418        queue.build_desc_chain(&descs).unwrap();
419
420        let avail_ring = queue.avail_addr();
421
422        let mut queue: Queue = Queue::new(MAX_QUEUE_SIZE).unwrap();
423        queue
424            .try_set_desc_table_address(descriptor_array_addr)
425            .unwrap();
426        queue.try_set_avail_ring_address(avail_ring).unwrap();
427        queue.set_ready(true);
428
429        let chain = queue.iter(memory).unwrap().next().unwrap();
430
431        Ok(chain.clone())
432    }
433
434    #[test]
435    fn reader_test_inv_desc_addr() {
436        let memory: GuestMemoryMmap =
437            GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), 0x1000)]).unwrap();
438
439        let queue = MockSplitQueue::create(&memory, GuestAddress(0x0), MAX_QUEUE_SIZE);
440
441        // set addr out of memory
442        let descriptor = Descriptor::new(0x1001, 1, 0, 1_u16);
443        queue.build_desc_chain(&[descriptor]).unwrap();
444
445        let avail_ring = queue.avail_addr();
446
447        let mut queue: Queue = Queue::new(MAX_QUEUE_SIZE).unwrap();
448        queue.try_set_desc_table_address(GuestAddress(0x0)).unwrap();
449        queue.try_set_avail_ring_address(avail_ring).unwrap();
450        queue.set_ready(true);
451
452        let chain = queue.iter(&memory).unwrap().next().unwrap();
453
454        assert!(Reader::new(&memory, chain).is_err());
455    }
456
457    #[test]
458    fn reader_test_simple_chain() {
459        use DescriptorType::*;
460
461        let memory_start_addr = GuestAddress(0x0);
462        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
463
464        let chain = create_descriptor_chain(
465            &memory,
466            GuestAddress(0x0),
467            vec![
468                (Readable, 8),
469                (Readable, 16),
470                (Readable, 18),
471                (Readable, 64),
472            ],
473            0,
474        )
475        .expect("create_descriptor_chain failed");
476        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
477        assert_eq!(reader.available_bytes(), 106);
478        assert_eq!(reader.bytes_read(), 0);
479
480        let mut buffer = [0_u8; 64];
481        if let Err(e) = reader.read_exact(&mut buffer) {
482            panic!("read_exact should not fail here: {:?}", e);
483        }
484
485        assert_eq!(reader.available_bytes(), 42);
486        assert_eq!(reader.bytes_read(), 64);
487
488        match reader.read(&mut buffer) {
489            Err(e) => panic!("read should not fail here: {:?}", e),
490            Ok(length) => assert_eq!(length, 42),
491        }
492
493        assert_eq!(reader.available_bytes(), 0);
494        assert_eq!(reader.bytes_read(), 106);
495    }
496
497    #[test]
498    fn writer_test_simple_chain() {
499        use DescriptorType::*;
500
501        let memory_start_addr = GuestAddress(0x0);
502        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
503
504        let chain = create_descriptor_chain(
505            &memory,
506            GuestAddress(0x0),
507            vec![
508                (Writable, 8),
509                (Writable, 16),
510                (Writable, 18),
511                (Writable, 64),
512            ],
513            0,
514        )
515        .expect("create_descriptor_chain failed");
516        let mut writer = Writer::new(&memory, chain).expect("failed to create Writer");
517        assert_eq!(writer.available_bytes(), 106);
518        assert_eq!(writer.bytes_written(), 0);
519
520        let buffer = [0_u8; 64];
521        if let Err(e) = writer.write_all(&buffer) {
522            panic!("write_all should not fail here: {:?}", e);
523        }
524
525        assert_eq!(writer.available_bytes(), 42);
526        assert_eq!(writer.bytes_written(), 64);
527
528        match writer.write(&buffer) {
529            Err(e) => panic!("write should not fail here {:?}", e),
530            Ok(length) => assert_eq!(length, 42),
531        }
532
533        assert_eq!(writer.available_bytes(), 0);
534        assert_eq!(writer.bytes_written(), 106);
535    }
536
537    #[test]
538    fn reader_test_incompatible_chain() {
539        use DescriptorType::*;
540
541        let memory_start_addr = GuestAddress(0x0);
542        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
543
544        let chain = create_descriptor_chain(&memory, GuestAddress(0x0), vec![(Writable, 8)], 0)
545            .expect("create_descriptor_chain failed");
546        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
547        assert_eq!(reader.available_bytes(), 0);
548        assert_eq!(reader.bytes_read(), 0);
549
550        assert!(reader.read_obj::<u8>().is_err());
551
552        assert_eq!(reader.available_bytes(), 0);
553        assert_eq!(reader.bytes_read(), 0);
554    }
555
556    #[test]
557    fn writer_test_incompatible_chain() {
558        use DescriptorType::*;
559
560        let memory_start_addr = GuestAddress(0x0);
561        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
562
563        let chain = create_descriptor_chain(&memory, GuestAddress(0x0), vec![(Readable, 8)], 0)
564            .expect("create_descriptor_chain failed");
565        let mut writer = Writer::new(&memory, chain).expect("failed to create Writer");
566        assert_eq!(writer.available_bytes(), 0);
567        assert_eq!(writer.bytes_written(), 0);
568
569        assert!(writer.write_obj(0u8).is_err());
570
571        assert_eq!(writer.available_bytes(), 0);
572        assert_eq!(writer.bytes_written(), 0);
573    }
574
575    #[test]
576    fn reader_writer_shared_chain() {
577        use DescriptorType::*;
578
579        let memory_start_addr = GuestAddress(0x0);
580        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
581
582        let chain = create_descriptor_chain(
583            &memory,
584            GuestAddress(0x0),
585            vec![
586                (Readable, 16),
587                (Readable, 16),
588                (Readable, 96),
589                (Writable, 64),
590                (Writable, 1),
591                (Writable, 3),
592            ],
593            0,
594        )
595        .expect("create_descriptor_chain failed");
596        let mut reader = Reader::new(&memory, chain.clone()).expect("failed to create Reader");
597        let mut writer = Writer::new(&memory, chain).expect("failed to create Writer");
598
599        assert_eq!(reader.bytes_read(), 0);
600        assert_eq!(writer.bytes_written(), 0);
601
602        let mut buffer = Vec::with_capacity(200);
603
604        assert_eq!(
605            reader
606                .read_to_end(&mut buffer)
607                .expect("read should not fail here"),
608            128
609        );
610
611        // The writable descriptors are only 68 bytes long.
612        writer
613            .write_all(&buffer[..68])
614            .expect("write should not fail here");
615
616        assert_eq!(reader.available_bytes(), 0);
617        assert_eq!(reader.bytes_read(), 128);
618        assert_eq!(writer.available_bytes(), 0);
619        assert_eq!(writer.bytes_written(), 68);
620    }
621
622    #[test]
623    fn reader_writer_shattered_object() {
624        use DescriptorType::*;
625
626        let memory_start_addr = GuestAddress(0x0);
627        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
628
629        let secret: Le32 = 0x1234_5678.into();
630
631        // Create a descriptor chain with memory regions that are properly separated.
632        let chain_writer = create_descriptor_chain(
633            &memory,
634            GuestAddress(0x0),
635            vec![(Writable, 1), (Writable, 1), (Writable, 1), (Writable, 1)],
636            123,
637        )
638        .expect("create_descriptor_chain failed");
639        let mut writer = Writer::new(&memory, chain_writer).expect("failed to create Writer");
640        if let Err(e) = writer.write_obj(secret) {
641            panic!("write_obj should not fail here: {:?}", e);
642        }
643
644        // Now create new descriptor chain pointing to the same memory and try to read it.
645        let chain_reader = create_descriptor_chain(
646            &memory,
647            GuestAddress(0x0),
648            vec![(Readable, 1), (Readable, 1), (Readable, 1), (Readable, 1)],
649            123,
650        )
651        .expect("create_descriptor_chain failed");
652        let mut reader = Reader::new(&memory, chain_reader).expect("failed to create Reader");
653        match reader.read_obj::<Le32>() {
654            Err(e) => panic!("read_obj should not fail here: {:?}", e),
655            Ok(read_secret) => assert_eq!(read_secret, secret),
656        }
657    }
658
659    #[test]
660    fn reader_unexpected_eof() {
661        use DescriptorType::*;
662
663        let memory_start_addr = GuestAddress(0x0);
664        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
665
666        let chain = create_descriptor_chain(
667            &memory,
668            GuestAddress(0x0),
669            vec![(Readable, 256), (Readable, 256)],
670            0,
671        )
672        .expect("create_descriptor_chain failed");
673
674        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
675
676        let mut buf = vec![0; 1024];
677
678        assert_eq!(
679            reader
680                .read_exact(&mut buf[..])
681                .expect_err("read more bytes than available")
682                .kind(),
683            io::ErrorKind::UnexpectedEof
684        );
685    }
686
687    #[test]
688    fn split_border() {
689        use DescriptorType::*;
690
691        let memory_start_addr = GuestAddress(0x0);
692        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
693
694        let chain = create_descriptor_chain(
695            &memory,
696            GuestAddress(0x0),
697            vec![
698                (Readable, 16),
699                (Readable, 16),
700                (Readable, 96),
701                (Writable, 64),
702                (Writable, 1),
703                (Writable, 3),
704            ],
705            0,
706        )
707        .expect("create_descriptor_chain failed");
708        let mut reader = Reader::new(&memory, chain.clone()).expect("failed to create Reader");
709
710        let other = reader.split_at(32).expect("failed to split Reader");
711        assert_eq!(reader.available_bytes(), 32);
712        assert_eq!(other.available_bytes(), 96);
713
714        let mut writer = Writer::new(&memory, chain.clone()).expect("failed to create Writer");
715        let other = writer.split_at(64).expect("failed to split Writer");
716        assert_eq!(writer.available_bytes(), 64);
717        assert_eq!(other.available_bytes(), 4);
718    }
719
720    #[test]
721    fn split_middle() {
722        use DescriptorType::*;
723
724        let memory_start_addr = GuestAddress(0x0);
725        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
726
727        let chain = create_descriptor_chain(
728            &memory,
729            GuestAddress(0x0),
730            vec![
731                (Readable, 16),
732                (Readable, 16),
733                (Readable, 96),
734                (Writable, 64),
735                (Writable, 1),
736                (Writable, 3),
737            ],
738            0,
739        )
740        .expect("create_descriptor_chain failed");
741        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
742
743        let other = reader.split_at(24).expect("failed to split Reader");
744        assert_eq!(reader.available_bytes(), 24);
745        assert_eq!(other.available_bytes(), 104);
746    }
747
748    #[test]
749    fn split_end() {
750        use DescriptorType::*;
751
752        let memory_start_addr = GuestAddress(0x0);
753        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
754
755        let chain = create_descriptor_chain(
756            &memory,
757            GuestAddress(0x0),
758            vec![
759                (Readable, 16),
760                (Readable, 16),
761                (Readable, 96),
762                (Writable, 64),
763                (Writable, 1),
764                (Writable, 3),
765            ],
766            0,
767        )
768        .expect("create_descriptor_chain failed");
769        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
770
771        let other = reader.split_at(128).expect("failed to split Reader");
772        assert_eq!(reader.available_bytes(), 128);
773        assert_eq!(other.available_bytes(), 0);
774    }
775
776    #[test]
777    fn split_beginning() {
778        use DescriptorType::*;
779
780        let memory_start_addr = GuestAddress(0x0);
781        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
782
783        let chain = create_descriptor_chain(
784            &memory,
785            GuestAddress(0x0),
786            vec![
787                (Readable, 16),
788                (Readable, 16),
789                (Readable, 96),
790                (Writable, 64),
791                (Writable, 1),
792                (Writable, 3),
793            ],
794            0,
795        )
796        .expect("create_descriptor_chain failed");
797        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
798
799        let other = reader.split_at(0).expect("failed to split Reader");
800        assert_eq!(reader.available_bytes(), 0);
801        assert_eq!(other.available_bytes(), 128);
802    }
803
804    #[test]
805    fn split_outofbounds() {
806        use DescriptorType::*;
807
808        let memory_start_addr = GuestAddress(0x0);
809        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
810
811        let chain = create_descriptor_chain(
812            &memory,
813            GuestAddress(0x0),
814            vec![
815                (Readable, 16),
816                (Readable, 16),
817                (Readable, 96),
818                (Writable, 64),
819                (Writable, 1),
820                (Writable, 3),
821            ],
822            0,
823        )
824        .expect("create_descriptor_chain failed");
825        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
826
827        if reader.split_at(256).is_ok() {
828            panic!("successfully split Reader with out of bounds offset");
829        }
830    }
831
832    #[test]
833    fn read_full() {
834        use DescriptorType::*;
835
836        let memory_start_addr = GuestAddress(0x0);
837        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
838
839        let chain = create_descriptor_chain(
840            &memory,
841            GuestAddress(0x0),
842            vec![(Readable, 16), (Readable, 16), (Readable, 16)],
843            0,
844        )
845        .expect("create_descriptor_chain failed");
846        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
847
848        let mut buf = [0u8; 64];
849        assert_eq!(
850            reader.read(&mut buf[..]).expect("failed to read to buffer"),
851            48
852        );
853    }
854
855    #[test]
856    fn write_full() {
857        use DescriptorType::*;
858
859        let memory_start_addr = GuestAddress(0x0);
860        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
861
862        let chain = create_descriptor_chain(
863            &memory,
864            GuestAddress(0x0),
865            vec![(Writable, 16), (Writable, 16), (Writable, 16)],
866            0,
867        )
868        .expect("create_descriptor_chain failed");
869        let mut writer = Writer::new(&memory, chain).expect("failed to create Writer");
870
871        let buf = [0xdeu8; 64];
872        assert_eq!(
873            writer.write(&buf[..]).expect("failed to write from buffer"),
874            48
875        );
876
877        assert!(writer.flush().is_ok());
878    }
879}