@@ -56,7 +56,7 @@ use crate::bitmap::MS;
56
56
use crate :: bytes:: { AtomicAccess , Bytes } ;
57
57
use crate :: io:: { ReadVolatile , WriteVolatile } ;
58
58
use crate :: volatile_memory:: { self , VolatileSlice } ;
59
- use crate :: GuestMemoryRegion ;
59
+ use crate :: { GuestMemoryRegion , IoMemory , Permissions } ;
60
60
61
61
/// Errors associated with handling guest memory accesses.
62
62
#[ allow( missing_docs) ]
@@ -552,13 +552,19 @@ impl<'a, M: GuestMemory + ?Sized> Iterator for GuestMemorySliceIterator<'a, M> {
552
552
/// returning `None`, ensuring that it will only return `None` from that point on.
553
553
impl < M : GuestMemory + ?Sized > FusedIterator for GuestMemorySliceIterator < ' _ , M > { }
554
554
555
- impl < T : GuestMemory + ?Sized > Bytes < GuestAddress > for T {
555
+ /// Allow accessing [`IoMemory`] (and [`GuestMemory`]) objects via [`Bytes`].
556
+ ///
557
+ /// Thanks to the [blanket implementation of `IoMemory` for all `GuestMemory`
558
+ /// types](../io_memory/trait.IoMemory.html#impl-IoMemory-for-M), this blanket implementation
559
+ /// extends to all [`GuestMemory`] types.
560
+ impl < T : IoMemory + ?Sized > Bytes < GuestAddress > for T {
556
561
type E = Error ;
557
562
558
563
fn write ( & self , buf : & [ u8 ] , addr : GuestAddress ) -> Result < usize > {
559
564
self . try_access (
560
565
buf. len ( ) ,
561
566
addr,
567
+ Permissions :: Write ,
562
568
|offset, count, caddr, region| -> Result < usize > {
563
569
region. write ( & buf[ offset..( offset + count) ] , caddr)
564
570
} ,
@@ -569,6 +575,7 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
569
575
self . try_access (
570
576
buf. len ( ) ,
571
577
addr,
578
+ Permissions :: Read ,
572
579
|offset, count, caddr, region| -> Result < usize > {
573
580
region. read ( & mut buf[ offset..( offset + count) ] , caddr)
574
581
} ,
@@ -636,9 +643,12 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
636
643
where
637
644
F : ReadVolatile ,
638
645
{
639
- self . try_access ( count, addr, |_, len, caddr, region| -> Result < usize > {
640
- region. read_volatile_from ( caddr, src, len)
641
- } )
646
+ self . try_access (
647
+ count,
648
+ addr,
649
+ Permissions :: Write ,
650
+ |_, len, caddr, region| -> Result < usize > { region. read_volatile_from ( caddr, src, len) } ,
651
+ )
642
652
}
643
653
644
654
fn read_exact_volatile_from < F > (
@@ -664,11 +674,16 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
664
674
where
665
675
F : WriteVolatile ,
666
676
{
667
- self . try_access ( count, addr, |_, len, caddr, region| -> Result < usize > {
668
- // For a non-RAM region, reading could have side effects, so we
669
- // must use write_all().
670
- region. write_all_volatile_to ( caddr, dst, len) . map ( |( ) | len)
671
- } )
677
+ self . try_access (
678
+ count,
679
+ addr,
680
+ Permissions :: Read ,
681
+ |_, len, caddr, region| -> Result < usize > {
682
+ // For a non-RAM region, reading could have side effects, so we
683
+ // must use write_all().
684
+ region. write_all_volatile_to ( caddr, dst, len) . map ( |( ) | len)
685
+ } ,
686
+ )
672
687
}
673
688
674
689
fn write_all_volatile_to < F > ( & self , addr : GuestAddress , dst : & mut F , count : usize ) -> Result < ( ) >
@@ -688,7 +703,7 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
688
703
fn store < O : AtomicAccess > ( & self , val : O , addr : GuestAddress , order : Ordering ) -> Result < ( ) > {
689
704
// No need to check past the first iterator item: It either has the size of `O`, then there
690
705
// can be no further items; or it does not, and then `VolatileSlice::store()` will fail.
691
- self . get_slices ( addr, size_of :: < O > ( ) )
706
+ self . get_slices ( addr, size_of :: < O > ( ) , Permissions :: Write ) ?
692
707
. next ( )
693
708
. unwrap ( ) ? // count > 0 never produces an empty iterator
694
709
. store ( val, 0 , order)
@@ -698,7 +713,7 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
698
713
fn load < O : AtomicAccess > ( & self , addr : GuestAddress , order : Ordering ) -> Result < O > {
699
714
// No need to check past the first iterator item: It either has the size of `O`, then there
700
715
// can be no further items; or it does not, and then `VolatileSlice::store()` will fail.
701
- self . get_slices ( addr, size_of :: < O > ( ) )
716
+ self . get_slices ( addr, size_of :: < O > ( ) , Permissions :: Read ) ?
702
717
. next ( )
703
718
. unwrap ( ) ? // count > 0 never produces an empty iterator
704
719
. load ( 0 , order)
0 commit comments