@@ -32,7 +32,6 @@ use std::mem::{align_of, size_of};
3232use std:: ptr:: copy;
3333use std:: ptr:: { read_volatile, write_volatile} ;
3434use std:: result;
35- use std:: slice:: { from_raw_parts, from_raw_parts_mut} ;
3635use std:: sync:: atomic:: Ordering ;
3736use std:: usize;
3837
@@ -352,15 +351,13 @@ impl<'a, B: BitmapSlice> VolatileSlice<'a, B> {
352351 /// The returned subslice is a copy of this slice with the address increased by `offset` bytes
353352 /// and the size set to `count` bytes.
354353 pub fn subslice ( & self , offset : usize , count : usize ) -> Result < Self > {
355- let mem_end = compute_offset ( offset, count) ?;
356- if mem_end > self . len ( ) {
357- return Err ( Error :: OutOfBounds { addr : mem_end } ) ;
358- }
354+ let _ = self . compute_end_offset ( offset, count) ?;
355+
359356 // SAFETY: This is safe because the pointer is range-checked by compute_end_offset, and
360357 // the lifetime is the same as the original slice.
361358 unsafe {
362359 Ok ( VolatileSlice :: with_bitmap (
363- ( self . as_ptr ( ) as usize + offset) as * mut u8 ,
360+ self . as_ptr ( ) . add ( offset) ,
364361 count,
365362 self . bitmap . slice_at ( offset) ,
366363 ) )
@@ -531,30 +528,6 @@ impl<'a, B: BitmapSlice> VolatileSlice<'a, B> {
531528 } ;
532529 }
533530
534- /// Returns a slice corresponding to the data in the underlying memory.
535- ///
536- /// # Safety
537- ///
538- /// This function is private and only used for the read/write functions. It is not valid in
539- /// general to take slices of volatile memory.
540- unsafe fn as_slice ( & self ) -> & [ u8 ] {
541- from_raw_parts ( self . addr , self . size )
542- }
543-
544- /// Returns a mutable slice corresponding to the data in the underlying memory. Writes to the
545- /// slice have to be tracked manually using the handle returned by `VolatileSlice::bitmap`.
546- ///
547- /// # Safety
548- ///
549- /// This function is private and only used for the read/write functions. It is not valid in
550- /// general to take slices of volatile memory. Mutable accesses performed through the returned
551- /// slice are not visible to the dirty bitmap tracking functionality, and must be manually
552- /// recorded using the associated bitmap object.
553- #[ allow( clippy:: mut_from_ref) ]
554- unsafe fn as_mut_slice ( & self ) -> & mut [ u8 ] {
555- from_raw_parts_mut ( self . addr , self . size )
556- }
557-
558531 /// Checks if the current slice is aligned at `alignment` bytes.
559532 fn check_alignment ( & self , alignment : usize ) -> Result < ( ) > {
560533 // Check that the desired alignment is a power of two.
@@ -741,20 +714,30 @@ impl<B: BitmapSlice> Bytes<usize> for VolatileSlice<'_, B> {
741714 where
742715 F : Read ,
743716 {
744- let end = self . compute_end_offset ( addr, count) ?;
745- // SAFETY: We checked the addr and count so accessing the slice is safe.
746- // Also, it is safe to overwrite the volatile memory. Accessing the guest
747- // memory as a mutable slice is OK because nothing assumes another
748- // thread won't change what is loaded.
749- let dst = unsafe { & mut self . as_mut_slice ( ) [ addr..end] } ;
717+ let _ = self . compute_end_offset ( addr, count) ?;
718+
719+ let mut dst = vec ! [ 0 ; count] ;
720+
750721 let bytes_read = loop {
751- match src. read ( dst) {
722+ match src. read ( & mut dst) {
752723 Ok ( n) => break n,
753724 Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: Interrupted => continue ,
754725 Err ( e) => return Err ( Error :: IOError ( e) ) ,
755726 }
756727 } ;
757728
729+ // There is no guarantee that the read implementation is well-behaved, see the docs for
730+ // Read::read.
731+ assert ! ( bytes_read <= count) ;
732+
733+ // SAFETY: We have checked via compute_end_offset that accessing the specified
734+ // region of guest memory is valid. We asserted that the value returned by `read` is between
735+ // 0 and count (the length of the buffer passed to it), and that the
736+ // regions don't overlap because we allocated the Vec outside of guest memory.
737+ unsafe {
738+ copy_slice ( self . as_ptr ( ) . add ( addr) , dst. as_ptr ( ) , bytes_read) ;
739+ }
740+
758741 self . bitmap . mark_dirty ( addr, bytes_read) ;
759742 Ok ( bytes_read)
760743 }
@@ -787,16 +770,22 @@ impl<B: BitmapSlice> Bytes<usize> for VolatileSlice<'_, B> {
787770 where
788771 F : Read ,
789772 {
790- let end = self . compute_end_offset ( addr, count) ?;
773+ let _ = self . compute_end_offset ( addr, count) ?;
791774
792- // SAFETY: It is safe to overwrite the volatile memory. Accessing the guest memory as a
793- // mutable slice is OK because nothing assumes another thread won't change what is loaded.
794- // We also manually update the dirty bitmap below.
795- let dst = unsafe { & mut self . as_mut_slice ( ) [ addr..end] } ;
775+ let mut dst = vec ! [ 0 ; count] ;
776+
777+ // Read into buffer that can be copied into guest memory
778+ src. read_exact ( & mut dst) . map_err ( Error :: IOError ) ?;
779+
780+ // SAFETY: We have checked via compute_end_offset that accessing the specified
781+ // region of guest memory is valid. We know that `dst` has len `count`, and that the
782+ // regions don't overlap because we allocated the Vec outside of guest memory
783+ unsafe {
784+ copy_slice ( self . as_ptr ( ) . add ( addr) , dst. as_ptr ( ) , count) ;
785+ }
796786
797- let result = src. read_exact ( dst) . map_err ( Error :: IOError ) ;
798787 self . bitmap . mark_dirty ( addr, count) ;
799- result
788+ Ok ( ( ) )
800789 }
801790
802791 /// # Examples
@@ -826,14 +815,21 @@ impl<B: BitmapSlice> Bytes<usize> for VolatileSlice<'_, B> {
826815 where
827816 F : Write ,
828817 {
829- let end = self . compute_end_offset ( addr, count) ?;
818+ let _ = self . compute_end_offset ( addr, count) ?;
819+ let mut src = Vec :: with_capacity ( count) ;
830820 // SAFETY: We checked the addr and count so accessing the slice is safe.
831- // It is safe to read from volatile memory. Accessing the guest
832- // memory as a slice is OK because nothing assumes another thread
833- // won't change what is loaded.
834- let src = unsafe { & self . as_slice ( ) [ addr..end] } ;
821+ // It is safe to read from volatile memory. The Vec has capacity for exactly `count`
822+ // many bytes, and the memory regions pointed to definitely do not overlap, as we
823+ // allocated src outside of guest memory.
824+ // The call to set_len is safe because the bytes between 0 and count have been initialized
825+ // via copying from guest memory, and the Vec's capacity is `count`
826+ unsafe {
827+ copy_slice ( src. as_mut_ptr ( ) , self . as_ptr ( ) . add ( addr) , count) ;
828+ src. set_len ( count) ;
829+ }
830+
835831 loop {
836- match dst. write ( src) {
832+ match dst. write ( & src) {
837833 Ok ( n) => break Ok ( n) ,
838834 Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: Interrupted => continue ,
839835 Err ( e) => break Err ( Error :: IOError ( e) ) ,
@@ -868,14 +864,22 @@ impl<B: BitmapSlice> Bytes<usize> for VolatileSlice<'_, B> {
868864 where
869865 F : Write ,
870866 {
871- let end = self . compute_end_offset ( addr, count) ?;
872- // SAFETY: It is safe to read from volatile memory. Accessing the guest
873- // memory as a slice is OK because nothing assumes another thread
874- // won't change what is loaded.
867+ let _ = self . compute_end_offset ( addr, count) ?;
868+ let mut src = Vec :: with_capacity ( count) ;
869+
870+ // SAFETY: We checked the addr and count so accessing the slice is safe.
871+ // It is safe to read from volatile memory. The Vec has capacity for exactly `count`
872+ // many bytes, and the memory regions pointed to definitely do not overlap, as we
873+ // allocated src outside of guest memory.
874+ // The call to set_len is safe because the bytes between 0 and count have been initialized
875+ // via copying from guest memory, and the Vec's capacity is `count`
875876 unsafe {
876- let src = & self . as_slice ( ) [ addr..end ] ;
877- dst . write_all ( src) . map_err ( Error :: IOError ) ? ;
877+ copy_slice ( src. as_mut_ptr ( ) , self . as_ptr ( ) . add ( addr ) , count ) ;
878+ src. set_len ( count ) ;
878879 }
880+
881+ dst. write_all ( & src) . map_err ( Error :: IOError ) ?;
882+
879883 Ok ( ( ) )
880884 }
881885
@@ -906,7 +910,7 @@ impl<B: BitmapSlice> VolatileMemory for VolatileSlice<'_, B> {
906910 // the lifetime is the same as self.
907911 unsafe {
908912 VolatileSlice :: with_bitmap (
909- ( self . addr as usize + offset) as * mut u8 ,
913+ self . addr . add ( offset) ,
910914 count,
911915 self . bitmap . slice_at ( offset) ,
912916 )
0 commit comments