Skip to content

Commit 3443660

Browse files
committed
Add packed descriptor and MockPackedQueue
Signed-off-by: Wenyu Huang <[email protected]>
1 parent a318603 commit 3443660

File tree

8 files changed

+668
-56
lines changed

8 files changed

+668
-56
lines changed

virtio-queue/src/chain.rs

+63-22
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ where
253253
#[cfg(test)]
254254
mod tests {
255255
use super::*;
256+
use crate::desc::{split::Descriptor as SplitDescriptor, Descriptor};
256257
use crate::mock::{DescriptorTable, MockSplitQueue};
257258
use virtio_bindings::bindings::virtio_ring::{VRING_DESC_F_INDIRECT, VRING_DESC_F_NEXT};
258259
use vm_memory::GuestMemoryMmap;
@@ -281,7 +282,12 @@ mod tests {
281282
{
282283
// the first desc has a normal len, and the next_descriptor flag is set
283284
// but the the index of the next descriptor is too large
284-
let desc = Descriptor::new(0x1000, 0x1000, VRING_DESC_F_NEXT as u16, 16);
285+
let desc = Descriptor::from(SplitDescriptor::new(
286+
0x1000,
287+
0x1000,
288+
VRING_DESC_F_NEXT as u16,
289+
16,
290+
));
285291
vq.desc_table().store(0, desc).unwrap();
286292

287293
let mut c = DescriptorChain::<&GuestMemoryMmap>::new(m, vq.start(), 16, 0);
@@ -291,10 +297,15 @@ mod tests {
291297

292298
// finally, let's test an ok chain
293299
{
294-
let desc = Descriptor::new(0x1000, 0x1000, VRING_DESC_F_NEXT as u16, 1);
300+
let desc = Descriptor::from(SplitDescriptor::new(
301+
0x1000,
302+
0x1000,
303+
VRING_DESC_F_NEXT as u16,
304+
1,
305+
));
295306
vq.desc_table().store(0, desc).unwrap();
296307

297-
let desc = Descriptor::new(0x2000, 0x1000, 0, 0);
308+
let desc = Descriptor::from(SplitDescriptor::new(0x2000, 0x1000, 0, 0));
298309
vq.desc_table().store(1, desc).unwrap();
299310

300311
let mut c = DescriptorChain::<&GuestMemoryMmap>::new(m, vq.start(), 16, 0);
@@ -333,15 +344,15 @@ mod tests {
333344
// Populate the entire descriptor table with entries. Only the last one should not have the
334345
// VIRTQ_DESC_F_NEXT set.
335346
for i in 0..QUEUE_SIZE - 1 {
336-
let desc = Descriptor::new(
347+
let desc = Descriptor::from(SplitDescriptor::new(
337348
0x1000 * (i + 1) as u64,
338349
0x1000,
339350
VRING_DESC_F_NEXT as u16,
340351
i + 1,
341-
);
352+
));
342353
vq.desc_table().store(i, desc).unwrap();
343354
}
344-
let desc = Descriptor::new((0x1000 * 16) as u64, 0x1000, 0, 0);
355+
let desc = Descriptor::from(SplitDescriptor::new((0x1000 * 16) as u64, 0x1000, 0, 0));
345356
vq.desc_table().store(QUEUE_SIZE - 1, desc).unwrap();
346357

347358
let mut c = DescriptorChain::<&GuestMemoryMmap>::new(m, vq.start(), QUEUE_SIZE, 0);
@@ -366,18 +377,23 @@ mod tests {
366377
let dtable = vq.desc_table();
367378

368379
// Create a chain with one normal descriptor and one pointing to an indirect table.
369-
let desc = Descriptor::new(0x6000, 0x1000, VRING_DESC_F_NEXT as u16, 1);
380+
let desc = Descriptor::from(SplitDescriptor::new(
381+
0x6000,
382+
0x1000,
383+
VRING_DESC_F_NEXT as u16,
384+
1,
385+
));
370386
dtable.store(0, desc).unwrap();
371387
// The spec forbids setting both VIRTQ_DESC_F_INDIRECT and VIRTQ_DESC_F_NEXT in flags. We do
372388
// not currently enforce this rule, we just ignore the VIRTQ_DESC_F_NEXT flag.
373-
let desc = Descriptor::new(
389+
let desc = Descriptor::from(SplitDescriptor::new(
374390
0x7000,
375391
0x1000,
376392
(VRING_DESC_F_INDIRECT | VRING_DESC_F_NEXT) as u16,
377393
2,
378-
);
394+
));
379395
dtable.store(1, desc).unwrap();
380-
let desc = Descriptor::new(0x8000, 0x1000, 0, 0);
396+
let desc = Descriptor::from(SplitDescriptor::new(0x8000, 0x1000, 0, 0));
381397
dtable.store(2, desc).unwrap();
382398

383399
let mut c: DescriptorChain<&GuestMemoryMmap> = DescriptorChain::new(m, vq.start(), 16, 0);
@@ -386,9 +402,14 @@ mod tests {
386402
let idtable = DescriptorTable::new(m, GuestAddress(0x7000), 4);
387403
for i in 0..4u16 {
388404
let desc: Descriptor = if i < 3 {
389-
Descriptor::new(0x1000 * i as u64, 0x1000, VRING_DESC_F_NEXT as u16, i + 1)
405+
Descriptor::from(SplitDescriptor::new(
406+
0x1000 * i as u64,
407+
0x1000,
408+
VRING_DESC_F_NEXT as u16,
409+
i + 1,
410+
))
390411
} else {
391-
Descriptor::new(0x1000 * i as u64, 0x1000, 0, 0)
412+
Descriptor::from(SplitDescriptor::new(0x1000 * i as u64, 0x1000, 0, 0))
392413
};
393414
idtable.store(i, desc).unwrap();
394415
}
@@ -423,12 +444,12 @@ mod tests {
423444
let dtable = vq.desc_table();
424445

425446
// Create a chain with a descriptor pointing to an indirect table with unaligned address.
426-
let desc = Descriptor::new(
447+
let desc = Descriptor::from(SplitDescriptor::new(
427448
0x7001,
428449
0x1000,
429450
(VRING_DESC_F_INDIRECT | VRING_DESC_F_NEXT) as u16,
430451
2,
431-
);
452+
));
432453
dtable.store(0, desc).unwrap();
433454

434455
let mut c: DescriptorChain<&GuestMemoryMmap> = DescriptorChain::new(m, vq.start(), 16, 0);
@@ -437,9 +458,14 @@ mod tests {
437458
let idtable = DescriptorTable::new(m, GuestAddress(0x7001), 4);
438459
for i in 0..4u16 {
439460
let desc: Descriptor = if i < 3 {
440-
Descriptor::new(0x1000 * i as u64, 0x1000, VRING_DESC_F_NEXT as u16, i + 1)
461+
Descriptor::from(SplitDescriptor::new(
462+
0x1000 * i as u64,
463+
0x1000,
464+
VRING_DESC_F_NEXT as u16,
465+
i + 1,
466+
))
441467
} else {
442-
Descriptor::new(0x1000 * i as u64, 0x1000, 0, 0)
468+
Descriptor::from(SplitDescriptor::new(0x1000 * i as u64, 0x1000, 0, 0))
443469
};
444470
idtable.store(i, desc).unwrap();
445471
}
@@ -465,7 +491,12 @@ mod tests {
465491

466492
// Create a chain with a descriptor pointing to an invalid indirect table: len not a
467493
// multiple of descriptor size.
468-
let desc = Descriptor::new(0x1000, 0x1001, VRING_DESC_F_INDIRECT as u16, 0);
494+
let desc = Descriptor::from(SplitDescriptor::new(
495+
0x1000,
496+
0x1001,
497+
VRING_DESC_F_INDIRECT as u16,
498+
0,
499+
));
469500
vq.desc_table().store(0, desc).unwrap();
470501

471502
let mut c: DescriptorChain<&GuestMemoryMmap> =
@@ -480,12 +511,12 @@ mod tests {
480511

481512
// Create a chain with a descriptor pointing to an invalid indirect table: table len >
482513
// u16::MAX.
483-
let desc = Descriptor::new(
514+
let desc = Descriptor::from(SplitDescriptor::new(
484515
0x1000,
485516
(u16::MAX as u32 + 1) * VRING_DESC_ALIGN_SIZE,
486517
VRING_DESC_F_INDIRECT as u16,
487518
0,
488-
);
519+
));
489520
vq.desc_table().store(0, desc).unwrap();
490521

491522
let mut c: DescriptorChain<&GuestMemoryMmap> =
@@ -499,10 +530,15 @@ mod tests {
499530
let vq = MockSplitQueue::new(m, 16);
500531

501532
// Create a chain with a descriptor pointing to an indirect table.
502-
let desc = Descriptor::new(0x1000, 0x1000, VRING_DESC_F_INDIRECT as u16, 0);
533+
let desc = Descriptor::from(SplitDescriptor::new(
534+
0x1000,
535+
0x1000,
536+
VRING_DESC_F_INDIRECT as u16,
537+
0,
538+
));
503539
vq.desc_table().store(0, desc).unwrap();
504540
// It's ok for an indirect descriptor to have flags = 0.
505-
let desc = Descriptor::new(0x3000, 0x1000, 0, 0);
541+
let desc = Descriptor::from(SplitDescriptor::new(0x3000, 0x1000, 0, 0));
506542
m.write_obj(desc, GuestAddress(0x1000)).unwrap();
507543

508544
let mut c: DescriptorChain<&GuestMemoryMmap> =
@@ -511,7 +547,12 @@ mod tests {
511547

512548
// But it's not allowed to have an indirect descriptor that points to another indirect
513549
// table.
514-
let desc = Descriptor::new(0x3000, 0x1000, VRING_DESC_F_INDIRECT as u16, 0);
550+
let desc = Descriptor::from(SplitDescriptor::new(
551+
0x3000,
552+
0x1000,
553+
VRING_DESC_F_INDIRECT as u16,
554+
0,
555+
));
515556
m.write_obj(desc, GuestAddress(0x1000)).unwrap();
516557

517558
let mut c: DescriptorChain<&GuestMemoryMmap> =

virtio-queue/src/desc/mod.rs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//! Descriptor types for virtio queue.
2+
use vm_memory::{ByteValued, Le16, Le32, Le64};
3+
4+
pub mod packed;
5+
pub mod split;
6+
7+
/// A virtio descriptor constraints with C representation.
8+
#[repr(C)]
9+
#[derive(Clone, Copy, Debug, Default)]
10+
pub struct Descriptor(Le64, Le32, Le16, Le16);
11+
12+
unsafe impl ByteValued for Descriptor {}
13+
14+
impl From<split::Descriptor> for Descriptor {
15+
fn from(desc: split::Descriptor) -> Self {
16+
Descriptor(
17+
Le64::from(desc.addr().0),
18+
Le32::from(desc.len()),
19+
Le16::from(desc.flags()),
20+
Le16::from(desc.next()),
21+
)
22+
}
23+
}
24+
25+
impl From<packed::Descriptor> for Descriptor {
26+
fn from(desc: packed::Descriptor) -> Self {
27+
Descriptor(
28+
Le64::from(desc.addr().0),
29+
Le32::from(desc.len()),
30+
Le16::from(desc.id()),
31+
Le16::from(desc.flags()),
32+
)
33+
}
34+
}
35+
36+
impl From<Descriptor> for split::Descriptor {
37+
fn from(desc: Descriptor) -> split::Descriptor {
38+
split::Descriptor::new(desc.0.into(), desc.1.into(), desc.2.into(), desc.3.into())
39+
}
40+
}
41+
42+
impl From<Descriptor> for packed::Descriptor {
43+
fn from(desc: Descriptor) -> packed::Descriptor {
44+
packed::Descriptor::new(desc.0.into(), desc.1.into(), desc.2.into(), desc.3.into())
45+
}
46+
}

0 commit comments

Comments
 (0)