@@ -389,266 +389,12 @@ impl Queue {
389
389
390
390
#[ cfg( test) ]
391
391
pub ( crate ) mod tests {
392
- use std:: marker:: PhantomData ;
393
- use std:: mem;
394
392
395
393
pub use super :: * ;
396
- use crate :: virtio:: QueueError :: { DescIndexOutOfBounds , UsedRing } ;
397
- use vm_memory:: { Bytes , GuestAddress , GuestMemoryMmap } ;
398
-
399
- // Represents a location in GuestMemoryMmap which holds a given type.
400
- pub struct SomeplaceInMemory < ' a , T > {
401
- pub location : GuestAddress ,
402
- mem : & ' a GuestMemoryMmap ,
403
- phantom : PhantomData < * const T > ,
404
- }
405
-
406
- // The ByteValued trait is required to use mem.read_obj_from_addr and write_obj_at_addr.
407
- impl < ' a , T > SomeplaceInMemory < ' a , T >
408
- where
409
- T : vm_memory:: ByteValued ,
410
- {
411
- fn new ( location : GuestAddress , mem : & ' a GuestMemoryMmap ) -> Self {
412
- SomeplaceInMemory {
413
- location,
414
- mem,
415
- phantom : PhantomData ,
416
- }
417
- }
418
-
419
- // Reads from the actual memory location.
420
- pub fn get ( & self ) -> T {
421
- self . mem . read_obj ( self . location ) . unwrap ( )
422
- }
423
-
424
- // Writes to the actual memory location.
425
- pub fn set ( & self , val : T ) {
426
- self . mem . write_obj ( val, self . location ) . unwrap ( )
427
- }
428
-
429
- // This function returns a place in memory which holds a value of type U, and starts
430
- // offset bytes after the current location.
431
- fn map_offset < U > ( & self , offset : usize ) -> SomeplaceInMemory < ' a , U > {
432
- SomeplaceInMemory {
433
- location : self . location . checked_add ( offset as u64 ) . unwrap ( ) ,
434
- mem : self . mem ,
435
- phantom : PhantomData ,
436
- }
437
- }
438
-
439
- // This function returns a place in memory which holds a value of type U, and starts
440
- // immediately after the end of self (which is location + sizeof(T)).
441
- fn next_place < U > ( & self ) -> SomeplaceInMemory < ' a , U > {
442
- self . map_offset :: < U > ( mem:: size_of :: < T > ( ) )
443
- }
444
-
445
- fn end ( & self ) -> GuestAddress {
446
- self . location
447
- . checked_add ( mem:: size_of :: < T > ( ) as u64 )
448
- . unwrap ( )
449
- }
450
- }
451
-
452
- // Represents a virtio descriptor in guest memory.
453
- pub struct VirtqDesc < ' a > {
454
- pub addr : SomeplaceInMemory < ' a , u64 > ,
455
- pub len : SomeplaceInMemory < ' a , u32 > ,
456
- pub flags : SomeplaceInMemory < ' a , u16 > ,
457
- pub next : SomeplaceInMemory < ' a , u16 > ,
458
- }
459
-
460
- impl < ' a > VirtqDesc < ' a > {
461
- pub const ALIGNMENT : u64 = 16 ;
462
-
463
- fn new ( start : GuestAddress , mem : & ' a GuestMemoryMmap ) -> Self {
464
- assert_eq ! ( start. 0 & ( Self :: ALIGNMENT - 1 ) , 0 ) ;
465
-
466
- let addr = SomeplaceInMemory :: new ( start, mem) ;
467
- let len = addr. next_place ( ) ;
468
- let flags = len. next_place ( ) ;
469
- let next = flags. next_place ( ) ;
470
-
471
- VirtqDesc {
472
- addr,
473
- len,
474
- flags,
475
- next,
476
- }
477
- }
478
-
479
- fn start ( & self ) -> GuestAddress {
480
- self . addr . location
481
- }
482
-
483
- fn end ( & self ) -> GuestAddress {
484
- self . next . end ( )
485
- }
486
-
487
- pub fn set ( & self , addr : u64 , len : u32 , flags : u16 , next : u16 ) {
488
- self . addr . set ( addr) ;
489
- self . len . set ( len) ;
490
- self . flags . set ( flags) ;
491
- self . next . set ( next) ;
492
- }
493
-
494
- pub fn check_data ( & self , expected_data : & [ u8 ] ) {
495
- assert ! ( self . len. get( ) as usize >= expected_data. len( ) ) ;
496
- let mem = self . addr . mem ;
497
- let mut buf = vec ! [ 0 ; expected_data. len( ) as usize ] ;
498
- assert ! ( mem
499
- . read_slice( & mut buf, GuestAddress :: new( self . addr. get( ) ) )
500
- . is_ok( ) ) ;
501
- assert_eq ! ( buf. as_slice( ) , expected_data) ;
502
- }
503
- }
504
-
505
- // Represents a virtio queue ring. The only difference between the used and available rings,
506
- // is the ring element type.
507
- pub struct VirtqRing < ' a , T > {
508
- pub flags : SomeplaceInMemory < ' a , u16 > ,
509
- pub idx : SomeplaceInMemory < ' a , u16 > ,
510
- pub ring : Vec < SomeplaceInMemory < ' a , T > > ,
511
- pub event : SomeplaceInMemory < ' a , u16 > ,
512
- }
513
-
514
- impl < ' a , T > VirtqRing < ' a , T >
515
- where
516
- T : vm_memory:: ByteValued ,
517
- {
518
- fn new (
519
- start : GuestAddress ,
520
- mem : & ' a GuestMemoryMmap ,
521
- qsize : u16 ,
522
- alignment : usize ,
523
- ) -> Self {
524
- assert_eq ! ( start. 0 & ( alignment as u64 - 1 ) , 0 ) ;
525
-
526
- let flags = SomeplaceInMemory :: new ( start, mem) ;
527
- let idx = flags. next_place ( ) ;
528
-
529
- let mut ring = Vec :: with_capacity ( qsize as usize ) ;
530
-
531
- ring. push ( idx. next_place ( ) ) ;
532
-
533
- for _ in 1 ..qsize as usize {
534
- let x = ring. last ( ) . unwrap ( ) . next_place ( ) ;
535
- ring. push ( x)
536
- }
537
-
538
- let event = ring. last ( ) . unwrap ( ) . next_place ( ) ;
539
-
540
- flags. set ( 0 ) ;
541
- idx. set ( 0 ) ;
542
- event. set ( 0 ) ;
543
394
544
- VirtqRing {
545
- flags,
546
- idx,
547
- ring,
548
- event,
549
- }
550
- }
551
-
552
- pub fn end ( & self ) -> GuestAddress {
553
- self . event . end ( )
554
- }
555
- }
556
-
557
- #[ repr( C ) ]
558
- #[ derive( Clone , Copy , Default ) ]
559
- pub struct VirtqUsedElem {
560
- pub id : u32 ,
561
- pub len : u32 ,
562
- }
563
-
564
- unsafe impl vm_memory:: ByteValued for VirtqUsedElem { }
565
-
566
- pub type VirtqAvail < ' a > = VirtqRing < ' a , u16 > ;
567
- pub type VirtqUsed < ' a > = VirtqRing < ' a , VirtqUsedElem > ;
568
-
569
- pub struct VirtQueue < ' a > {
570
- pub dtable : Vec < VirtqDesc < ' a > > ,
571
- pub avail : VirtqAvail < ' a > ,
572
- pub used : VirtqUsed < ' a > ,
573
- }
574
-
575
- impl < ' a > VirtQueue < ' a > {
576
- // We try to make sure things are aligned properly :-s
577
- pub fn new ( start : GuestAddress , mem : & ' a GuestMemoryMmap , qsize : u16 ) -> Self {
578
- // power of 2?
579
- assert ! ( qsize > 0 && qsize & ( qsize - 1 ) == 0 ) ;
580
-
581
- let mut dtable = Vec :: with_capacity ( qsize as usize ) ;
582
-
583
- let mut end = start;
584
-
585
- for _ in 0 ..qsize {
586
- let d = VirtqDesc :: new ( end, mem) ;
587
- end = d. end ( ) ;
588
- dtable. push ( d) ;
589
- }
590
-
591
- const AVAIL_ALIGN : usize = 2 ;
592
-
593
- let avail = VirtqAvail :: new ( end, mem, qsize, AVAIL_ALIGN ) ;
594
-
595
- const USED_ALIGN : u64 = 4 ;
596
-
597
- let mut x = avail. end ( ) . 0 ;
598
- x = ( x + USED_ALIGN - 1 ) & !( USED_ALIGN - 1 ) ;
599
-
600
- let used = VirtqUsed :: new ( GuestAddress ( x) , mem, qsize, USED_ALIGN as usize ) ;
601
-
602
- VirtQueue {
603
- dtable,
604
- avail,
605
- used,
606
- }
607
- }
608
-
609
- pub fn size ( & self ) -> u16 {
610
- self . dtable . len ( ) as u16
611
- }
612
-
613
- fn dtable_start ( & self ) -> GuestAddress {
614
- self . dtable . first ( ) . unwrap ( ) . start ( )
615
- }
616
-
617
- fn avail_start ( & self ) -> GuestAddress {
618
- self . avail . flags . location
619
- }
620
-
621
- fn used_start ( & self ) -> GuestAddress {
622
- self . used . flags . location
623
- }
624
-
625
- // Creates a new Queue, using the underlying memory regions represented by the VirtQueue.
626
- pub fn create_queue ( & self ) -> Queue {
627
- let mut q = Queue :: new ( self . size ( ) ) ;
628
-
629
- q. size = self . size ( ) ;
630
- q. ready = true ;
631
- q. desc_table = self . dtable_start ( ) ;
632
- q. avail_ring = self . avail_start ( ) ;
633
- q. used_ring = self . used_start ( ) ;
634
-
635
- q
636
- }
637
-
638
- pub fn start ( & self ) -> GuestAddress {
639
- self . dtable_start ( )
640
- }
641
-
642
- pub fn end ( & self ) -> GuestAddress {
643
- self . used . end ( )
644
- }
645
-
646
- pub fn check_used_elem ( & self , used_index : u16 , expected_id : u16 , expected_len : u32 ) {
647
- let used_elem = self . used . ring [ used_index as usize ] . get ( ) ;
648
- assert_eq ! ( used_elem. id, expected_id as u32 ) ;
649
- assert_eq ! ( used_elem. len, expected_len) ;
650
- }
651
- }
395
+ use crate :: virtio:: test_utils:: VirtQueue ;
396
+ use crate :: virtio:: QueueError :: { DescIndexOutOfBounds , UsedRing } ;
397
+ use vm_memory:: { GuestAddress , GuestMemoryMmap } ;
652
398
653
399
#[ test]
654
400
fn test_checked_new_descriptor_chain ( ) {
0 commit comments