@@ -398,33 +398,23 @@ impl Queue {
398398 // In a naive notation, that would be:
399399 // `descriptor_table[avail_ring[next_avail]]`.
400400 //
401- // First, we compute the byte-offset (into `self.avail_ring`) of the index of the next
402- // available descriptor. `self.avail_ring` stores the address of a `struct
403- // virtq_avail`, as defined by the VirtIO spec:
404- //
405- // ```C
406- // struct virtq_avail {
407- // le16 flags;
408- // le16 idx;
409- // le16 ring[QUEUE_SIZE];
410- // le16 used_event
401+ // Avail ring has layout:
402+ // struct AvailRing {
403+ // flags: u16,
404+ // idx: u16,
405+ // ring: [u16; <queue size>],
406+ // used_event: u16,
411407 // }
412- // ```
413- //
414- // We use `self.next_avail` to store the position, in `ring`, of the next available
415- // descriptor index, with a twist: we always only increment `self.next_avail`, so the
416- // actual position will be `self.next_avail % self.actual_size()`.
417- // We are now looking for the offset of `ring[self.next_avail % self.actual_size()]`.
418- // `ring` starts after `flags` and `idx` (4 bytes into `struct virtq_avail`), and holds
419- // 2-byte items, so the offset will be:
420- let index_offset = 4 + 2 * ( self . next_avail . 0 % self . actual_size ( ) ) ;
408+ // We calculate offset into `ring` field.
409+ let desc_index_offset = std:: mem:: size_of :: < u16 > ( )
410+ + std:: mem:: size_of :: < u16 > ( )
411+ + std:: mem:: size_of :: < u16 > ( ) * usize:: from ( self . next_avail . 0 % self . actual_size ( ) ) ;
412+ let desc_index_address = self . avail_ring . unchecked_add ( usize_to_u64 ( desc_index_offset) ) ;
421413
422414 // `self.is_valid()` already performed all the bound checks on the descriptor table
423415 // and virtq rings, so it's safe to unwrap guest memory reads and to use unchecked
424416 // offsets.
425- let desc_index: u16 = mem
426- . read_obj ( self . avail_ring . unchecked_add ( u64:: from ( index_offset) ) )
427- . unwrap ( ) ;
417+ let desc_index: u16 = mem. read_obj ( desc_index_address) . unwrap ( ) ;
428418
429419 DescriptorChain :: checked_new ( mem, self . desc_table , self . actual_size ( ) , desc_index) . map (
430420 |dc| {
0 commit comments