9
9
10
10
use bitflags:: bitflags;
11
11
use libc:: { c_int, c_void, MAP_SHARED , _SC_PAGESIZE} ;
12
+ use std:: sync:: Arc ;
12
13
use std:: { io, mem:: size_of, os:: raw:: c_ulong, os:: unix:: io:: AsRawFd , ptr:: null_mut, result} ;
13
-
14
14
use vmm_sys_util:: {
15
15
fam:: { Error as FamError , FamStruct , FamStructWrapper } ,
16
16
generate_fam_struct_impl,
@@ -26,28 +26,23 @@ use tests::ioctl_with_ref;
26
26
27
27
use crate :: bitmap:: { Bitmap , NewBitmap , BS } ;
28
28
use crate :: guest_memory:: { FileOffset , GuestAddress } ;
29
+ use crate :: mmap:: unix:: MmapRegion as MmapUnix ;
29
30
use crate :: volatile_memory:: { self , VolatileMemory , VolatileSlice } ;
30
31
use crate :: {
31
32
guest_memory, Address , GuestMemoryRegion , GuestMemoryRegionBytes , GuestRegionCollection ,
32
- GuestUsize , MemoryRegionAddress ,
33
+ GuestUsize , MemoryRegionAddress , MmapRegionBuilder ,
33
34
} ;
34
35
35
36
/// Error conditions that may arise when creating a new `MmapRegion` object.
36
37
#[ derive( Debug , thiserror:: Error ) ]
37
38
pub enum Error {
38
- /// The specified file offset and length cause overflow when added.
39
- #[ error( "The specified file offset and length cause overflow when added" ) ]
40
- InvalidOffsetLength ,
41
39
/// The forbidden `MAP_FIXED` flag was specified.
42
40
#[ error( "The forbidden `MAP_FIXED` flag was specified" ) ]
43
41
MapFixed ,
44
- /// A mapping with offset + length > EOF was attempted.
45
- #[ error( "The specified file offset and length is greater then file length" ) ]
46
- MappingPastEof ,
47
42
/// The `mmap` call returned an error.
48
43
#[ error( "{0}" ) ]
49
44
Mmap ( io:: Error ) ,
50
- /// Invalid file offset.
45
+ /// Invalid file offset (non-zero of missing altogether) .
51
46
#[ error( "Invalid file offset" ) ]
52
47
InvalidFileOffset ,
53
48
/// Memory mapped in advance.
@@ -62,6 +57,9 @@ pub enum Error {
62
57
/// Unexpected error.
63
58
#[ error( "Unexpected error" ) ]
64
59
Unexpected ,
60
+ /// Error establishing normal unix mapping
61
+ #[ error[ "{0}" ] ]
62
+ Unix ( #[ from] crate :: mmap:: unix:: Error ) ,
65
63
}
66
64
67
65
type Result < T > = result:: Result < T , Error > ;
@@ -427,45 +425,6 @@ impl<B: Bitmap> VolatileMemory for MmapRegion<B> {
427
425
}
428
426
}
429
427
430
- #[ derive( Clone , Debug , PartialEq ) ]
431
- struct MmapUnix {
432
- addr : * mut u8 ,
433
- size : usize ,
434
- }
435
-
436
- impl MmapUnix {
437
- fn new ( size : usize , prot : i32 , flags : i32 , fd : i32 , f_offset : u64 ) -> Result < Self > {
438
- let addr =
439
- // SAFETY: This is safe because we're not allowing MAP_FIXED, and invalid parameters
440
- // cannot break Rust safety guarantees (things may change if we're mapping /dev/mem or
441
- // some wacky file).
442
- unsafe { libc:: mmap ( null_mut ( ) , size, prot, flags, fd, f_offset as libc:: off_t ) } ;
443
-
444
- if addr == libc:: MAP_FAILED {
445
- return Err ( Error :: Mmap ( io:: Error :: last_os_error ( ) ) ) ;
446
- }
447
-
448
- Ok ( Self {
449
- addr : addr as * mut u8 ,
450
- size,
451
- } )
452
- }
453
-
454
- fn addr ( & self ) -> * mut u8 {
455
- self . addr
456
- }
457
- }
458
-
459
- impl Drop for MmapUnix {
460
- fn drop ( & mut self ) {
461
- // SAFETY: This is safe because we mmap the area at addr ourselves, and nobody
462
- // else is holding a reference to it.
463
- unsafe {
464
- libc:: munmap ( self . addr as * mut libc:: c_void , self . size ) ;
465
- }
466
- }
467
- }
468
-
469
428
// Bit mask for the vhost-user xen mmap message.
470
429
bitflags ! {
471
430
/// Flags for the Xen mmap message.
@@ -531,21 +490,18 @@ fn pages(size: usize) -> (usize, usize) {
531
490
( num, page_size * num)
532
491
}
533
492
534
- fn validate_file ( file_offset : & Option < FileOffset > ) -> Result < ( i32 , u64 ) > {
493
+ fn validate_file ( file_offset : Option < FileOffset > ) -> Result < FileOffset > {
535
494
let file_offset = match file_offset {
536
495
Some ( f) => f,
537
496
None => return Err ( Error :: InvalidFileOffset ) ,
538
497
} ;
539
498
540
- let fd = file_offset. file ( ) . as_raw_fd ( ) ;
541
- let f_offset = file_offset. start ( ) ;
542
-
543
499
// We don't allow file offsets with Xen foreign mappings.
544
- if f_offset != 0 {
545
- return Err ( Error :: InvalidOffsetLength ) ;
500
+ if file_offset . start ( ) != 0 {
501
+ return Err ( Error :: InvalidFileOffset ) ;
546
502
}
547
503
548
- Ok ( ( fd , f_offset ) )
504
+ Ok ( file_offset )
549
505
}
550
506
551
507
// Xen Foreign memory mapping interface.
@@ -556,27 +512,22 @@ trait MmapXenTrait: std::fmt::Debug {
556
512
}
557
513
558
514
// Standard Unix memory mapping for testing other crates.
559
- #[ derive( Clone , Debug , PartialEq ) ]
515
+ #[ derive( Clone , Debug ) ]
560
516
struct MmapXenUnix ( MmapUnix , GuestAddress ) ;
561
517
562
518
impl MmapXenUnix {
563
519
fn new ( range : & MmapRange ) -> Result < Self > {
564
- let ( fd, offset) = if let Some ( ref f_off) = range. file_offset {
565
- ( f_off. file ( ) . as_raw_fd ( ) , f_off. start ( ) )
566
- } else {
567
- ( -1 , 0 )
568
- } ;
520
+ let mut builder = MmapRegionBuilder :: new ( range. size )
521
+ . with_mmap_prot ( range. prot . ok_or ( Error :: Unexpected ) ?)
522
+ . with_mmap_flags ( range. flags . ok_or ( Error :: Unexpected ) ?) ;
569
523
570
- Ok ( Self (
571
- MmapUnix :: new (
572
- range. size ,
573
- range. prot . ok_or ( Error :: Unexpected ) ?,
574
- range. flags . ok_or ( Error :: Unexpected ) ?,
575
- fd,
576
- offset,
577
- ) ?,
578
- range. addr ,
579
- ) )
524
+ if let Some ( ref file_offset) = range. file_offset {
525
+ builder = builder. with_file_offset ( file_offset. clone ( ) ) ;
526
+ }
527
+
528
+ let mmap_unix = builder. build ( ) ?;
529
+
530
+ Ok ( MmapXenUnix ( mmap_unix, range. addr ) )
580
531
}
581
532
}
582
533
@@ -587,7 +538,7 @@ impl MmapXenTrait for MmapXenUnix {
587
538
}
588
539
589
540
fn addr ( & self ) -> * mut u8 {
590
- self . 0 . addr ( )
541
+ self . 0 . as_ptr ( )
591
542
}
592
543
593
544
fn guest_base ( & self ) -> GuestAddress {
@@ -626,7 +577,7 @@ fn ioctl_privcmd_mmapbatch_v2() -> c_ulong {
626
577
}
627
578
628
579
// Xen foreign memory specific implementation.
629
- #[ derive( Clone , Debug , PartialEq ) ]
580
+ #[ derive( Clone , Debug ) ]
630
581
struct MmapXenForeign {
631
582
domid : u32 ,
632
583
guest_base : GuestAddress ,
@@ -642,16 +593,15 @@ impl AsRawFd for MmapXenForeign {
642
593
643
594
impl MmapXenForeign {
644
595
fn new ( range : & MmapRange ) -> Result < Self > {
645
- let ( fd, f_offset) = validate_file ( & range. file_offset ) ?;
646
596
let ( count, size) = pages ( range. size ) ;
597
+ let file_offset = validate_file ( range. file_offset . clone ( ) ) ?;
598
+ let fd = file_offset. file ( ) . as_raw_fd ( ) ;
647
599
648
- let unix_mmap = MmapUnix :: new (
649
- size,
650
- range. prot . ok_or ( Error :: Unexpected ) ?,
651
- range. flags . ok_or ( Error :: Unexpected ) ? | MAP_SHARED ,
652
- fd,
653
- f_offset,
654
- ) ?;
600
+ let unix_mmap = MmapRegionBuilder :: new ( size)
601
+ . with_mmap_prot ( range. prot . ok_or ( Error :: Unexpected ) ?)
602
+ . with_mmap_flags ( range. flags . ok_or ( Error :: Unexpected ) ? | MAP_SHARED )
603
+ . with_file_offset ( file_offset)
604
+ . build ( ) ?;
655
605
656
606
let foreign = Self {
657
607
domid : range. mmap_data ,
@@ -701,7 +651,7 @@ impl MmapXenTrait for MmapXenForeign {
701
651
}
702
652
703
653
fn addr ( & self ) -> * mut u8 {
704
- self . unix_mmap . addr ( )
654
+ self . unix_mmap . as_ptr ( )
705
655
}
706
656
707
657
fn guest_base ( & self ) -> GuestAddress {
@@ -855,12 +805,12 @@ impl AsRawFd for MmapXenGrant {
855
805
856
806
impl MmapXenGrant {
857
807
fn new ( range : & MmapRange , mmap_flags : MmapXenFlags ) -> Result < Self > {
858
- validate_file ( & range. file_offset ) ?;
808
+ let file_offset = validate_file ( range. file_offset . clone ( ) ) ?;
859
809
860
810
let mut grant = Self {
861
811
guest_base : range. addr ,
862
812
unix_mmap : None ,
863
- file_offset : range . file_offset . as_ref ( ) . unwrap ( ) . clone ( ) ,
813
+ file_offset,
864
814
flags : range. flags . ok_or ( Error :: Unexpected ) ?,
865
815
size : 0 ,
866
816
index : 0 ,
@@ -884,7 +834,15 @@ impl MmapXenGrant {
884
834
fn mmap_range ( & self , addr : GuestAddress , size : usize , prot : i32 ) -> Result < ( MmapUnix , u64 ) > {
885
835
let ( count, size) = pages ( size) ;
886
836
let index = self . mmap_ioctl ( addr, count) ?;
887
- let unix_mmap = MmapUnix :: new ( size, prot, self . flags , self . as_raw_fd ( ) , index) ?;
837
+
838
+ let unix_mmap = MmapRegionBuilder :: new ( size)
839
+ . with_mmap_prot ( prot)
840
+ . with_mmap_flags ( self . flags )
841
+ . with_file_offset ( FileOffset :: from_arc (
842
+ Arc :: clone ( self . file_offset . arc ( ) ) ,
843
+ index,
844
+ ) )
845
+ . build ( ) ?;
888
846
889
847
Ok ( ( unix_mmap, index) )
890
848
}
@@ -934,7 +892,7 @@ impl MmapXenTrait for MmapXenGrant {
934
892
935
893
fn addr ( & self ) -> * mut u8 {
936
894
if let Some ( ref unix_mmap) = self . unix_mmap {
937
- unix_mmap. addr ( )
895
+ unix_mmap. as_ptr ( )
938
896
} else {
939
897
null_mut ( )
940
898
}
@@ -983,7 +941,7 @@ impl MmapXenSlice {
983
941
let ( unix_mmap, index) = grant. mmap_range ( GuestAddress ( addr) , size, prot) ?;
984
942
985
943
// SAFETY: We have already mapped the range including offset.
986
- let addr = unsafe { unix_mmap. addr ( ) . add ( offset) } ;
944
+ let addr = unsafe { unix_mmap. as_ptr ( ) . add ( offset) } ;
987
945
988
946
Ok ( Self {
989
947
grant : Some ( grant) ,
0 commit comments