Skip to content

Commit 5ebe19d

Browse files
roypatbonzini
authored andcommitted
fix: remove superfluous calls to .subslice in io.rs
The call to `.subslice()` ensures that the range `[0, total]` is a valid subslice of the `buf: VolatileSlice` passed in. But `total = min(buf.len(), self.len()) <= buf.len()`, and thus `[0, total]` is definitely a valid subslice of `buf`. The `copy_{from,to}_volatile_slice` functions do not actually care about the length of the `VolatileSlice` passed in - it relies on the safety invariant to ensure that the passed slice has length at least `total`. Thus it doesn't matter if we pass a slice of length `total`, or of a length greater than `total`. It will simply access the first `total` bytes in the slice. Also clarify the safety comment, as some slightly mistakes seemingly snuck in when copying them. Signed-off-by: Patrick Roy <roypat@amazon.co.uk>
1 parent 9fbb4e8 commit 5ebe19d

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

src/io.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,16 @@ impl WriteVolatile for &mut [u8] {
220220
buf: &VolatileSlice<B>,
221221
) -> Result<usize, VolatileMemoryError> {
222222
let total = buf.len().min(self.len());
223-
let src = buf.subslice(0, total)?;
224223

225224
// SAFETY:
226-
// We check above that `src` is contiguously allocated memory of length `total <= self.len())`.
227-
// Furthermore, both src and dst of the call to
228-
// copy_from_volatile_slice are valid for reads and writes respectively of length `total`
229-
// since total is the minimum of lengths of the memory areas pointed to. The areas do not
230-
// overlap, since `dst` is inside guest memory, and buf is a slice (no slices to guest
231-
// memory are possible without violating rust's aliasing rules).
232-
let written = unsafe { copy_from_volatile_slice(self.as_mut_ptr(), &src, total) };
225+
// `buf` is contiguously allocated memory of length `total <= buf.len())` by the invariants
226+
// of `VolatileSlice`.
227+
// Furthermore, both source and destination of the call to copy_from_volatile_slice are valid
228+
// for reads and writes respectively of length `total` since total is the minimum of lengths
229+
// of the memory areas pointed to. The areas do not overlap, since the source is inside guest
230+
// memory, and the destination is a pointer derived from a slice (no slices to guest memory
231+
// are possible without violating rust's aliasing rules).
232+
let written = unsafe { copy_from_volatile_slice(self.as_mut_ptr(), buf, total) };
233233

234234
// Advance the slice, just like the stdlib: https://doc.rust-lang.org/src/std/io/impls.rs.html#335
235235
*self = std::mem::take(self).split_at_mut(written).1;
@@ -259,15 +259,16 @@ impl ReadVolatile for &[u8] {
259259
buf: &mut VolatileSlice<B>,
260260
) -> Result<usize, VolatileMemoryError> {
261261
let total = buf.len().min(self.len());
262-
let dst = buf.subslice(0, total)?;
263262

264263
// SAFETY:
265-
// We check above that `dst` is contiguously allocated memory of length `total <= self.len())`.
266-
// Furthermore, both src and dst of the call to copy_to_volatile_slice are valid for reads
267-
// and writes respectively of length `total` since total is the minimum of lengths of the
268-
// memory areas pointed to. The areas do not overlap, since `dst` is inside guest memory,
269-
// and buf is a slice (no slices to guest memory are possible without violating rust's aliasing rules).
270-
let read = unsafe { copy_to_volatile_slice(&dst, self.as_ptr(), total) };
264+
// `buf` is contiguously allocated memory of length `total <= buf.len())` by the invariants
265+
// of `VolatileSlice`.
266+
// Furthermore, both source and destination of the call to copy_to_volatile_slice are valid
267+
// for reads and writes respectively of length `total` since total is the minimum of lengths
268+
// of the memory areas pointed to. The areas do not overlap, since the destination is inside
269+
// guest memory, and the source is a pointer derived from a slice (no slices to guest memory
270+
// are possible without violating rust's aliasing rules).
271+
let read = unsafe { copy_to_volatile_slice(buf, self.as_ptr(), total) };
271272

272273
// Advance the slice, just like the stdlib: https://doc.rust-lang.org/src/std/io/impls.rs.html#232-310
273274
*self = self.split_at(read).1;

0 commit comments

Comments
 (0)