Skip to content

Commit a6722a2

Browse files
committed
refactor(queue): safer write_used_ring method
Now `write_used_ring` makes sure the index is in correct bounds. This removes a need for the caller to make sure the index is in bounds. It will be used in the later commits to discard used descriptors. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent bb8394a commit a6722a2

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

src/vmm/src/devices/virtio/queue.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -448,12 +448,11 @@ impl Queue {
448448
) -> Result<(), QueueError> {
449449
debug_assert!(self.is_layout_valid(mem));
450450

451-
let next_used = self.next_used.0 % self.actual_size();
452451
let used_element = UsedElement {
453452
id: u32::from(desc_index),
454453
len,
455454
};
456-
self.write_used_ring(mem, next_used, used_element)?;
455+
self.write_used_ring(mem, self.next_used.0, used_element)?;
457456
self.advance_used_ring(mem, 1);
458457
Ok(())
459458
}
@@ -493,11 +492,17 @@ impl Queue {
493492
// We calculate offset into `ring` field.
494493
let used_ring_offset = std::mem::size_of::<u16>()
495494
+ std::mem::size_of::<u16>()
496-
+ std::mem::size_of::<UsedElement>() * usize::from(index);
495+
+ std::mem::size_of::<UsedElement>() * usize::from(index % self.actual_size());
497496
let used_element_address = self.used_ring.unchecked_add(usize_to_u64(used_ring_offset));
498497

499-
mem.write_obj(used_element, used_element_address)
500-
.map_err(QueueError::UsedRing)
498+
// SAFETY:
499+
// `used_element_address` param is bounded by size of the queue as `index` is
500+
// modded by `actual_size()`.
501+
// `self.is_valid()` already performed all the bound checks on the descriptor table
502+
// and virtq rings, so it's safe to unwrap guest memory reads and to use unchecked
503+
// offsets.
504+
mem.write_obj(used_element, used_element_address).unwrap();
505+
Ok(())
501506
}
502507

503508
/// Fetch the available ring index (`virtq_avail->idx`) from guest memory.

0 commit comments

Comments
 (0)