88use std:: fs:: File ;
99use std:: io:: { Read , Seek , SeekFrom } ;
1010use std:: mem:: ManuallyDrop ;
11- use std:: os:: fd:: AsFd ;
11+ use std:: os:: fd:: { AsFd , AsRawFd } ;
1212use std:: sync:: Arc ;
1313
14- use kvm_bindings:: { KVM_MEM_LOG_DIRTY_PAGES , kvm_userspace_memory_region } ;
14+ use kvm_bindings:: { KVM_MEM_LOG_DIRTY_PAGES , kvm_userspace_memory_region2 } ;
1515use serde:: { Deserialize , Serialize } ;
1616pub use vm_memory:: bitmap:: { AtomicBitmap , BS , Bitmap , BitmapSlice } ;
1717pub use vm_memory:: mmap:: MmapRegionBuilder ;
@@ -98,7 +98,7 @@ impl<S: Seek> Seek for Bounce<S> {
9898/// A memory region, described in terms of `kvm_userspace_memory_region`
9999#[ derive( Debug ) ]
100100pub struct KvmRegion {
101- region : kvm_userspace_memory_region ,
101+ region : kvm_userspace_memory_region2 ,
102102 bitmap : Option < AtomicBitmap > ,
103103 file_offset : Option < FileOffset > ,
104104}
@@ -112,7 +112,7 @@ impl KvmRegion {
112112 /// `kvm_region.userspace_addr as *mut u8` is valid for reads and writes of length
113113 /// `kvm_region.memory_size`.
114114 pub unsafe fn new (
115- region : kvm_userspace_memory_region ,
115+ region : kvm_userspace_memory_region2 ,
116116 bitmap : Option < AtomicBitmap > ,
117117 file_offset : Option < FileOffset > ,
118118 ) -> Self {
@@ -123,34 +123,46 @@ impl KvmRegion {
123123 }
124124 }
125125
126- pub ( crate ) fn from_mmap_region ( region : GuestRegionMmap , slot : u32 ) -> Self {
126+ pub ( crate ) fn from_mmap_region (
127+ region : GuestRegionMmap ,
128+ slot : u32 ,
129+ guest_memfd : Option < & FileOffset > ,
130+ ) -> Self {
127131 let region = ManuallyDrop :: new ( region) ;
128132 let flags = if region. bitmap ( ) . is_some ( ) {
129133 KVM_MEM_LOG_DIRTY_PAGES
130134 } else {
131135 0
132136 } ;
133137
138+ #[ allow( clippy:: cast_sign_loss) ]
139+ let ( guest_memfd, guest_memfd_offset) = guest_memfd
140+ . map ( |fo| ( fo. file ( ) . as_raw_fd ( ) as u32 , fo. start ( ) ) )
141+ . unwrap_or ( ( 0 , 0 ) ) ;
142+
134143 // SAFETY: `GuestRegionMmap` is essentially a fat pointer, and ensures that
135144 // region.as_ptr() is valid for reads and writes of length region.len(),
136145 // and by placing our region into a `ManuallyDrop` we ensure that its `Drop`
137146 // impl won't run and free the memory away from underneath us.
138147 unsafe {
139148 Self :: new (
140- kvm_userspace_memory_region {
149+ kvm_userspace_memory_region2 {
141150 slot,
142151 flags,
143152 guest_phys_addr : region. start_addr ( ) . 0 ,
144153 memory_size : region. len ( ) ,
145154 userspace_addr : region. as_ptr ( ) as u64 ,
155+ guest_memfd,
156+ guest_memfd_offset,
157+ ..Default :: default ( )
146158 } ,
147159 region. bitmap ( ) . clone ( ) ,
148160 region. file_offset ( ) . cloned ( ) ,
149161 )
150162 }
151163 }
152164
153- pub ( crate ) fn inner ( & self ) -> & kvm_userspace_memory_region {
165+ pub ( crate ) fn inner ( & self ) -> & kvm_userspace_memory_region2 {
154166 & self . region
155167 }
156168}
@@ -528,7 +540,7 @@ mod tests {
528540 regions
529541 . into_iter ( )
530542 . zip ( 0u32 ..) // assign dummy slots
531- . map ( |( region, slot) | KvmRegion :: from_mmap_region ( region, slot) )
543+ . map ( |( region, slot) | KvmRegion :: from_mmap_region ( region, slot, None ) )
532544 . collect ( ) ,
533545 )
534546 . unwrap ( )
0 commit comments