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<B: BitmapSlice> io::Read for Reader<'_, 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<B: BitmapSlice> io::Write for Writer<'_, 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::{
369        desc::{split::Descriptor as SplitDescriptor, RawDescriptor},
370        Queue, QueueOwnedT, QueueT,
371    };
372    use vm_memory::{GuestAddress, GuestMemoryMmap, Le32};
373
374    use crate::mock::MockSplitQueue;
375    use virtio_bindings::bindings::virtio_ring::{VRING_DESC_F_NEXT, VRING_DESC_F_WRITE};
376
377    const MAX_QUEUE_SIZE: u16 = 16;
378
379    #[derive(Copy, Clone, PartialEq, Eq)]
380    pub enum DescriptorType {
381        Readable,
382        Writable,
383    }
384
385    /// Test utility function to create a descriptor chain in guest memory.
386    pub fn create_descriptor_chain(
387        memory: &GuestMemoryMmap,
388        descriptor_array_addr: GuestAddress,
389        descriptors: Vec<(DescriptorType, u32)>,
390        spaces_between_regions: u32,
391    ) -> Result<DescriptorChain<&GuestMemoryMmap>> {
392        let descriptors_len = descriptors.len();
393        let mut descs = vec![];
394
395        let queue = MockSplitQueue::create(memory, descriptor_array_addr, MAX_QUEUE_SIZE);
396
397        let mut buffers_start_addr = queue.end();
398
399        for (index, (type_, size)) in descriptors.into_iter().enumerate() {
400            let mut flags = 0;
401            if let DescriptorType::Writable = type_ {
402                flags |= VRING_DESC_F_WRITE;
403            }
404            if index + 1 < descriptors_len {
405                flags |= VRING_DESC_F_NEXT;
406            }
407
408            descs.push(RawDescriptor::from(SplitDescriptor::new(
409                buffers_start_addr.raw_value(),
410                size,
411                flags as u16,
412                (index + 1) as u16,
413            )));
414
415            let offset = size + spaces_between_regions;
416            buffers_start_addr = buffers_start_addr
417                .checked_add(u64::from(offset))
418                .ok_or(Error::InvalidChain)?;
419        }
420
421        queue.build_desc_chain(&descs).unwrap();
422
423        let avail_ring = queue.avail_addr();
424
425        let mut queue: Queue = Queue::new(MAX_QUEUE_SIZE).unwrap();
426        queue
427            .try_set_desc_table_address(descriptor_array_addr)
428            .unwrap();
429        queue.try_set_avail_ring_address(avail_ring).unwrap();
430        queue.set_ready(true);
431
432        let chain = queue.iter(memory).unwrap().next().unwrap();
433
434        Ok(chain.clone())
435    }
436
437    #[test]
438    fn reader_test_inv_desc_addr() {
439        let memory: GuestMemoryMmap =
440            GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), 0x1000)]).unwrap();
441
442        let queue = MockSplitQueue::create(&memory, GuestAddress(0x0), MAX_QUEUE_SIZE);
443
444        // set addr out of memory
445        let descriptor = RawDescriptor::from(SplitDescriptor::new(0x1001, 1, 0, 1_u16));
446        queue.build_desc_chain(&[descriptor]).unwrap();
447
448        let avail_ring = queue.avail_addr();
449
450        let mut queue: Queue = Queue::new(MAX_QUEUE_SIZE).unwrap();
451        queue.try_set_desc_table_address(GuestAddress(0x0)).unwrap();
452        queue.try_set_avail_ring_address(avail_ring).unwrap();
453        queue.set_ready(true);
454
455        let chain = queue.iter(&memory).unwrap().next().unwrap();
456
457        assert!(Reader::new(&memory, chain).is_err());
458    }
459
460    #[test]
461    fn reader_test_simple_chain() {
462        use DescriptorType::*;
463
464        let memory_start_addr = GuestAddress(0x0);
465        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
466
467        let chain = create_descriptor_chain(
468            &memory,
469            GuestAddress(0x0),
470            vec![
471                (Readable, 8),
472                (Readable, 16),
473                (Readable, 18),
474                (Readable, 64),
475            ],
476            0,
477        )
478        .expect("create_descriptor_chain failed");
479        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
480        assert_eq!(reader.available_bytes(), 106);
481        assert_eq!(reader.bytes_read(), 0);
482
483        let mut buffer = [0_u8; 64];
484        if let Err(e) = reader.read_exact(&mut buffer) {
485            panic!("read_exact should not fail here: {:?}", e);
486        }
487
488        assert_eq!(reader.available_bytes(), 42);
489        assert_eq!(reader.bytes_read(), 64);
490
491        match reader.read(&mut buffer) {
492            Err(e) => panic!("read should not fail here: {:?}", e),
493            Ok(length) => assert_eq!(length, 42),
494        }
495
496        assert_eq!(reader.available_bytes(), 0);
497        assert_eq!(reader.bytes_read(), 106);
498    }
499
500    #[test]
501    fn writer_test_simple_chain() {
502        use DescriptorType::*;
503
504        let memory_start_addr = GuestAddress(0x0);
505        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
506
507        let chain = create_descriptor_chain(
508            &memory,
509            GuestAddress(0x0),
510            vec![
511                (Writable, 8),
512                (Writable, 16),
513                (Writable, 18),
514                (Writable, 64),
515            ],
516            0,
517        )
518        .expect("create_descriptor_chain failed");
519        let mut writer = Writer::new(&memory, chain).expect("failed to create Writer");
520        assert_eq!(writer.available_bytes(), 106);
521        assert_eq!(writer.bytes_written(), 0);
522
523        let buffer = [0_u8; 64];
524        if let Err(e) = writer.write_all(&buffer) {
525            panic!("write_all should not fail here: {:?}", e);
526        }
527
528        assert_eq!(writer.available_bytes(), 42);
529        assert_eq!(writer.bytes_written(), 64);
530
531        match writer.write(&buffer) {
532            Err(e) => panic!("write should not fail here {:?}", e),
533            Ok(length) => assert_eq!(length, 42),
534        }
535
536        assert_eq!(writer.available_bytes(), 0);
537        assert_eq!(writer.bytes_written(), 106);
538    }
539
540    #[test]
541    fn reader_test_incompatible_chain() {
542        use DescriptorType::*;
543
544        let memory_start_addr = GuestAddress(0x0);
545        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
546
547        let chain = create_descriptor_chain(&memory, GuestAddress(0x0), vec![(Writable, 8)], 0)
548            .expect("create_descriptor_chain failed");
549        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
550        assert_eq!(reader.available_bytes(), 0);
551        assert_eq!(reader.bytes_read(), 0);
552
553        assert!(reader.read_obj::<u8>().is_err());
554
555        assert_eq!(reader.available_bytes(), 0);
556        assert_eq!(reader.bytes_read(), 0);
557    }
558
559    #[test]
560    fn writer_test_incompatible_chain() {
561        use DescriptorType::*;
562
563        let memory_start_addr = GuestAddress(0x0);
564        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
565
566        let chain = create_descriptor_chain(&memory, GuestAddress(0x0), vec![(Readable, 8)], 0)
567            .expect("create_descriptor_chain failed");
568        let mut writer = Writer::new(&memory, chain).expect("failed to create Writer");
569        assert_eq!(writer.available_bytes(), 0);
570        assert_eq!(writer.bytes_written(), 0);
571
572        assert!(writer.write_obj(0u8).is_err());
573
574        assert_eq!(writer.available_bytes(), 0);
575        assert_eq!(writer.bytes_written(), 0);
576    }
577
578    #[test]
579    fn reader_writer_shared_chain() {
580        use DescriptorType::*;
581
582        let memory_start_addr = GuestAddress(0x0);
583        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
584
585        let chain = create_descriptor_chain(
586            &memory,
587            GuestAddress(0x0),
588            vec![
589                (Readable, 16),
590                (Readable, 16),
591                (Readable, 96),
592                (Writable, 64),
593                (Writable, 1),
594                (Writable, 3),
595            ],
596            0,
597        )
598        .expect("create_descriptor_chain failed");
599        let mut reader = Reader::new(&memory, chain.clone()).expect("failed to create Reader");
600        let mut writer = Writer::new(&memory, chain).expect("failed to create Writer");
601
602        assert_eq!(reader.bytes_read(), 0);
603        assert_eq!(writer.bytes_written(), 0);
604
605        let mut buffer = Vec::with_capacity(200);
606
607        assert_eq!(
608            reader
609                .read_to_end(&mut buffer)
610                .expect("read should not fail here"),
611            128
612        );
613
614        // The writable descriptors are only 68 bytes long.
615        writer
616            .write_all(&buffer[..68])
617            .expect("write should not fail here");
618
619        assert_eq!(reader.available_bytes(), 0);
620        assert_eq!(reader.bytes_read(), 128);
621        assert_eq!(writer.available_bytes(), 0);
622        assert_eq!(writer.bytes_written(), 68);
623    }
624
625    #[test]
626    fn reader_writer_shattered_object() {
627        use DescriptorType::*;
628
629        let memory_start_addr = GuestAddress(0x0);
630        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
631
632        let secret: Le32 = 0x1234_5678.into();
633
634        // Create a descriptor chain with memory regions that are properly separated.
635        let chain_writer = create_descriptor_chain(
636            &memory,
637            GuestAddress(0x0),
638            vec![(Writable, 1), (Writable, 1), (Writable, 1), (Writable, 1)],
639            123,
640        )
641        .expect("create_descriptor_chain failed");
642        let mut writer = Writer::new(&memory, chain_writer).expect("failed to create Writer");
643        if let Err(e) = writer.write_obj(secret) {
644            panic!("write_obj should not fail here: {:?}", e);
645        }
646
647        // Now create new descriptor chain pointing to the same memory and try to read it.
648        let chain_reader = create_descriptor_chain(
649            &memory,
650            GuestAddress(0x0),
651            vec![(Readable, 1), (Readable, 1), (Readable, 1), (Readable, 1)],
652            123,
653        )
654        .expect("create_descriptor_chain failed");
655        let mut reader = Reader::new(&memory, chain_reader).expect("failed to create Reader");
656        match reader.read_obj::<Le32>() {
657            Err(e) => panic!("read_obj should not fail here: {:?}", e),
658            Ok(read_secret) => assert_eq!(read_secret, secret),
659        }
660    }
661
662    #[test]
663    fn reader_unexpected_eof() {
664        use DescriptorType::*;
665
666        let memory_start_addr = GuestAddress(0x0);
667        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
668
669        let chain = create_descriptor_chain(
670            &memory,
671            GuestAddress(0x0),
672            vec![(Readable, 256), (Readable, 256)],
673            0,
674        )
675        .expect("create_descriptor_chain failed");
676
677        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
678
679        let mut buf = vec![0; 1024];
680
681        assert_eq!(
682            reader
683                .read_exact(&mut buf[..])
684                .expect_err("read more bytes than available")
685                .kind(),
686            io::ErrorKind::UnexpectedEof
687        );
688    }
689
690    #[test]
691    fn split_border() {
692        use DescriptorType::*;
693
694        let memory_start_addr = GuestAddress(0x0);
695        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
696
697        let chain = create_descriptor_chain(
698            &memory,
699            GuestAddress(0x0),
700            vec![
701                (Readable, 16),
702                (Readable, 16),
703                (Readable, 96),
704                (Writable, 64),
705                (Writable, 1),
706                (Writable, 3),
707            ],
708            0,
709        )
710        .expect("create_descriptor_chain failed");
711        let mut reader = Reader::new(&memory, chain.clone()).expect("failed to create Reader");
712
713        let other = reader.split_at(32).expect("failed to split Reader");
714        assert_eq!(reader.available_bytes(), 32);
715        assert_eq!(other.available_bytes(), 96);
716
717        let mut writer = Writer::new(&memory, chain.clone()).expect("failed to create Writer");
718        let other = writer.split_at(64).expect("failed to split Writer");
719        assert_eq!(writer.available_bytes(), 64);
720        assert_eq!(other.available_bytes(), 4);
721    }
722
723    #[test]
724    fn split_middle() {
725        use DescriptorType::*;
726
727        let memory_start_addr = GuestAddress(0x0);
728        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
729
730        let chain = create_descriptor_chain(
731            &memory,
732            GuestAddress(0x0),
733            vec![
734                (Readable, 16),
735                (Readable, 16),
736                (Readable, 96),
737                (Writable, 64),
738                (Writable, 1),
739                (Writable, 3),
740            ],
741            0,
742        )
743        .expect("create_descriptor_chain failed");
744        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
745
746        let other = reader.split_at(24).expect("failed to split Reader");
747        assert_eq!(reader.available_bytes(), 24);
748        assert_eq!(other.available_bytes(), 104);
749    }
750
751    #[test]
752    fn split_end() {
753        use DescriptorType::*;
754
755        let memory_start_addr = GuestAddress(0x0);
756        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
757
758        let chain = create_descriptor_chain(
759            &memory,
760            GuestAddress(0x0),
761            vec![
762                (Readable, 16),
763                (Readable, 16),
764                (Readable, 96),
765                (Writable, 64),
766                (Writable, 1),
767                (Writable, 3),
768            ],
769            0,
770        )
771        .expect("create_descriptor_chain failed");
772        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
773
774        let other = reader.split_at(128).expect("failed to split Reader");
775        assert_eq!(reader.available_bytes(), 128);
776        assert_eq!(other.available_bytes(), 0);
777    }
778
779    #[test]
780    fn split_beginning() {
781        use DescriptorType::*;
782
783        let memory_start_addr = GuestAddress(0x0);
784        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
785
786        let chain = create_descriptor_chain(
787            &memory,
788            GuestAddress(0x0),
789            vec![
790                (Readable, 16),
791                (Readable, 16),
792                (Readable, 96),
793                (Writable, 64),
794                (Writable, 1),
795                (Writable, 3),
796            ],
797            0,
798        )
799        .expect("create_descriptor_chain failed");
800        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
801
802        let other = reader.split_at(0).expect("failed to split Reader");
803        assert_eq!(reader.available_bytes(), 0);
804        assert_eq!(other.available_bytes(), 128);
805    }
806
807    #[test]
808    fn split_outofbounds() {
809        use DescriptorType::*;
810
811        let memory_start_addr = GuestAddress(0x0);
812        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
813
814        let chain = create_descriptor_chain(
815            &memory,
816            GuestAddress(0x0),
817            vec![
818                (Readable, 16),
819                (Readable, 16),
820                (Readable, 96),
821                (Writable, 64),
822                (Writable, 1),
823                (Writable, 3),
824            ],
825            0,
826        )
827        .expect("create_descriptor_chain failed");
828        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
829
830        if reader.split_at(256).is_ok() {
831            panic!("successfully split Reader with out of bounds offset");
832        }
833    }
834
835    #[test]
836    fn read_full() {
837        use DescriptorType::*;
838
839        let memory_start_addr = GuestAddress(0x0);
840        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
841
842        let chain = create_descriptor_chain(
843            &memory,
844            GuestAddress(0x0),
845            vec![(Readable, 16), (Readable, 16), (Readable, 16)],
846            0,
847        )
848        .expect("create_descriptor_chain failed");
849        let mut reader = Reader::new(&memory, chain).expect("failed to create Reader");
850
851        let mut buf = [0u8; 64];
852        assert_eq!(
853            reader.read(&mut buf[..]).expect("failed to read to buffer"),
854            48
855        );
856    }
857
858    #[test]
859    fn write_full() {
860        use DescriptorType::*;
861
862        let memory_start_addr = GuestAddress(0x0);
863        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 0x10000)]).unwrap();
864
865        let chain = create_descriptor_chain(
866            &memory,
867            GuestAddress(0x0),
868            vec![(Writable, 16), (Writable, 16), (Writable, 16)],
869            0,
870        )
871        .expect("create_descriptor_chain failed");
872        let mut writer = Writer::new(&memory, chain).expect("failed to create Writer");
873
874        let buf = [0xdeu8; 64];
875        assert_eq!(
876            writer.write(&buf[..]).expect("failed to write from buffer"),
877            48
878        );
879
880        assert!(writer.flush().is_ok());
881    }
882}