Skip to content

Commit b61f394

Browse files
committed
TEST: manual desc read
Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent 70bce30 commit b61f394

File tree

2 files changed

+78
-15
lines changed

2 files changed

+78
-15
lines changed

src/vmm/src/devices/virtio/iovec.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ impl IoVecBuffer {
218218
#[derive(Debug, Default, Clone)]
219219
pub struct IoVecBufferMut {
220220
// Index of the head desciptor
221-
head_index: u16,
221+
pub head_index: u16,
222222
// container of the memory regions included in this IO vector
223-
vecs: IoVecVec,
223+
pub vecs: IoVecVec,
224224
// Total length of the IoVecBufferMut
225-
len: u32,
225+
pub len: u32,
226226
}
227227

228228
impl IoVecBufferMut {

src/vmm/src/devices/virtio/net/device.rs

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use utils::eventfd::EventFd;
1818
use utils::net::mac::MacAddr;
1919
use utils::ring_buffer::RingBuffer;
2020
use utils::{u64_to_usize, usize_to_u64};
21-
use vm_memory::VolatileMemoryError;
21+
use vm_memory::{GuestAddress, GuestMemory, VolatileMemoryError};
2222

2323
use crate::devices::virtio::device::{DeviceState, IrqTrigger, IrqType, VirtioDevice};
2424
use crate::devices::virtio::gen::virtio_blk::VIRTIO_F_VERSION_1;
@@ -156,23 +156,86 @@ impl AvailableDescriptors {
156156

157157
/// Read new descriptor chains from the queue.
158158
pub fn read_new_desc_chains(&mut self, queue: &mut Queue, mem: &GuestMemoryMmap) {
159-
for _ in 0..queue.len(mem) {
159+
#[repr(C)]
160+
struct AvailRing {
161+
flags: u16,
162+
idx: u16,
163+
ring: [u16; 256],
164+
used_event: u16,
165+
}
166+
#[repr(C)]
167+
#[derive(Default, Clone, Copy)]
168+
struct Descriptor {
169+
addr: u64,
170+
len: u32,
171+
flags: u16,
172+
next: u16,
173+
}
174+
175+
// SAFETY:
176+
// avail_ring in the queue is a valid guest address
177+
let avail_ring: &AvailRing =
178+
unsafe { std::mem::transmute(mem.get_host_address(queue.avail_ring).unwrap()) };
179+
180+
// SAFETY:
181+
// desc_table in the queue is a valid guest address
182+
let desc_table: &[Descriptor; 256] =
183+
unsafe { std::mem::transmute(mem.get_host_address(queue.desc_table).unwrap()) };
184+
185+
let avail_idx = queue.avail_idx(mem);
186+
let actual_size = queue.actual_size();
187+
188+
while queue.next_avail.0 != avail_idx.0 {
160189
let Some(next_iovec_buf) = self.iov_ring.next_available() else {
161190
break;
162191
};
163192

164-
match queue.do_pop_unchecked(mem) {
165-
Some(desc_chain) => {
166-
// SAFETY:
167-
// This descriptor chain is only processed once.
168-
let valid = unsafe { next_iovec_buf.load_descriptor_chain(desc_chain).is_ok() };
169-
self.valid_ring.push(valid);
170-
}
171-
None => {
172-
self.valid_ring.push(false);
173-
}
193+
let avail_index = queue.next_avail.0 % actual_size;
194+
queue.next_avail += Wrapping(1);
195+
196+
let desc_index = avail_ring.ring[avail_index as usize];
197+
let mut desc = &desc_table[desc_index as usize];
198+
199+
next_iovec_buf.clear();
200+
next_iovec_buf.head_index = desc_index;
201+
202+
let iov = libc::iovec {
203+
iov_base: mem.get_host_address(GuestAddress(desc.addr)).unwrap().cast(),
204+
iov_len: desc.len as usize,
205+
};
206+
next_iovec_buf.vecs.push(iov);
207+
next_iovec_buf.len += desc.len;
208+
self.valid_ring.push(true);
209+
210+
while desc.flags & crate::devices::virtio::queue::VIRTQ_DESC_F_NEXT != 0 {
211+
desc = &desc_table[desc.next as usize];
212+
let iov = libc::iovec {
213+
iov_base: mem.get_host_address(GuestAddress(desc.addr)).unwrap().cast(),
214+
iov_len: desc.len as usize,
215+
};
216+
next_iovec_buf.vecs.push(iov);
217+
next_iovec_buf.len += desc.len;
218+
self.valid_ring.push(true);
174219
}
175220
}
221+
222+
// for _ in 0..queue.len(mem) {
223+
// let Some(next_iovec_buf) = self.iov_ring.next_available() else {
224+
// break;
225+
// };
226+
//
227+
// match queue.do_pop_unchecked(mem) {
228+
// Some(desc_chain) => {
229+
// // SAFETY:
230+
// // This descriptor chain is only processed once.
231+
// let valid = unsafe { next_iovec_buf.load_descriptor_chain(desc_chain).is_ok() };
232+
// self.valid_ring.push(valid);
233+
// }
234+
// None => {
235+
// self.valid_ring.push(false);
236+
// }
237+
// }
238+
// }
176239
}
177240

178241
/// Pop first descriptor chain.

0 commit comments

Comments
 (0)