@@ -32,7 +32,6 @@ use std::mem::{align_of, size_of};
32
32
use std:: ptr:: copy;
33
33
use std:: ptr:: { read_volatile, write_volatile} ;
34
34
use std:: result;
35
- use std:: slice:: { from_raw_parts, from_raw_parts_mut} ;
36
35
use std:: sync:: atomic:: Ordering ;
37
36
use std:: usize;
38
37
@@ -352,15 +351,13 @@ impl<'a, B: BitmapSlice> VolatileSlice<'a, B> {
352
351
/// The returned subslice is a copy of this slice with the address increased by `offset` bytes
353
352
/// and the size set to `count` bytes.
354
353
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
+
359
356
// SAFETY: This is safe because the pointer is range-checked by compute_end_offset, and
360
357
// the lifetime is the same as the original slice.
361
358
unsafe {
362
359
Ok ( VolatileSlice :: with_bitmap (
363
- ( self . as_ptr ( ) as usize + offset) as * mut u8 ,
360
+ self . as_ptr ( ) . add ( offset) ,
364
361
count,
365
362
self . bitmap . slice_at ( offset) ,
366
363
) )
@@ -531,30 +528,6 @@ impl<'a, B: BitmapSlice> VolatileSlice<'a, B> {
531
528
} ;
532
529
}
533
530
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
-
558
531
/// Checks if the current slice is aligned at `alignment` bytes.
559
532
fn check_alignment ( & self , alignment : usize ) -> Result < ( ) > {
560
533
// Check that the desired alignment is a power of two.
@@ -741,20 +714,30 @@ impl<B: BitmapSlice> Bytes<usize> for VolatileSlice<'_, B> {
741
714
where
742
715
F : Read ,
743
716
{
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
+
750
721
let bytes_read = loop {
751
- match src. read ( dst) {
722
+ match src. read ( & mut dst) {
752
723
Ok ( n) => break n,
753
724
Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: Interrupted => continue ,
754
725
Err ( e) => return Err ( Error :: IOError ( e) ) ,
755
726
}
756
727
} ;
757
728
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
+
758
741
self . bitmap . mark_dirty ( addr, bytes_read) ;
759
742
Ok ( bytes_read)
760
743
}
@@ -787,16 +770,22 @@ impl<B: BitmapSlice> Bytes<usize> for VolatileSlice<'_, B> {
787
770
where
788
771
F : Read ,
789
772
{
790
- let end = self . compute_end_offset ( addr, count) ?;
773
+ let _ = self . compute_end_offset ( addr, count) ?;
791
774
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
+ }
796
786
797
- let result = src. read_exact ( dst) . map_err ( Error :: IOError ) ;
798
787
self . bitmap . mark_dirty ( addr, count) ;
799
- result
788
+ Ok ( ( ) )
800
789
}
801
790
802
791
/// # Examples
@@ -826,14 +815,21 @@ impl<B: BitmapSlice> Bytes<usize> for VolatileSlice<'_, B> {
826
815
where
827
816
F : Write ,
828
817
{
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) ;
830
820
// 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
+
835
831
loop {
836
- match dst. write ( src) {
832
+ match dst. write ( & src) {
837
833
Ok ( n) => break Ok ( n) ,
838
834
Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: Interrupted => continue ,
839
835
Err ( e) => break Err ( Error :: IOError ( e) ) ,
@@ -868,14 +864,22 @@ impl<B: BitmapSlice> Bytes<usize> for VolatileSlice<'_, B> {
868
864
where
869
865
F : Write ,
870
866
{
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`
875
876
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 ) ;
878
879
}
880
+
881
+ dst. write_all ( & src) . map_err ( Error :: IOError ) ?;
882
+
879
883
Ok ( ( ) )
880
884
}
881
885
@@ -906,7 +910,7 @@ impl<B: BitmapSlice> VolatileMemory for VolatileSlice<'_, B> {
906
910
// the lifetime is the same as self.
907
911
unsafe {
908
912
VolatileSlice :: with_bitmap (
909
- ( self . addr as usize + offset) as * mut u8 ,
913
+ self . addr . add ( offset) ,
910
914
count,
911
915
self . bitmap . slice_at ( offset) ,
912
916
)
0 commit comments