88use std:: fs:: File ;
99use std:: io:: { Read , Seek , SeekFrom } ;
1010use std:: mem:: ManuallyDrop ;
11+ use std:: os:: fd:: AsRawFd ;
1112use std:: sync:: Arc ;
1213
13- 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 } ;
1415use serde:: { Deserialize , Serialize } ;
1516pub use vm_memory:: bitmap:: { AtomicBitmap , BS , Bitmap , BitmapSlice } ;
1617pub use vm_memory:: mmap:: MmapRegionBuilder ;
@@ -106,7 +107,7 @@ impl<S: Seek> Seek for Bounce<S> {
106107/// A memory region, described in terms of `kvm_userspace_memory_region`
107108#[ derive( Debug ) ]
108109pub struct KvmRegion {
109- region : kvm_userspace_memory_region ,
110+ region : kvm_userspace_memory_region2 ,
110111 bitmap : Option < AtomicBitmap > ,
111112 file_offset : Option < FileOffset > ,
112113}
@@ -120,7 +121,7 @@ impl KvmRegion {
120121 /// `kvm_region.userspace_addr as *mut u8` is valid for reads and writes of length
121122 /// `kvm_region.memory_size`.
122123 pub unsafe fn new (
123- region : kvm_userspace_memory_region ,
124+ region : kvm_userspace_memory_region2 ,
124125 bitmap : Option < AtomicBitmap > ,
125126 file_offset : Option < FileOffset > ,
126127 ) -> Self {
@@ -131,34 +132,46 @@ impl KvmRegion {
131132 }
132133 }
133134
134- pub ( crate ) fn from_mmap_region ( region : GuestRegionMmap , slot : u32 ) -> Self {
135+ pub ( crate ) fn from_mmap_region (
136+ region : GuestRegionMmap ,
137+ slot : u32 ,
138+ guest_memfd : Option < & FileOffset > ,
139+ ) -> Self {
135140 let region = ManuallyDrop :: new ( region) ;
136141 let flags = if region. bitmap ( ) . is_some ( ) {
137142 KVM_MEM_LOG_DIRTY_PAGES
138143 } else {
139144 0
140145 } ;
141146
147+ #[ allow( clippy:: cast_sign_loss) ]
148+ let ( guest_memfd, guest_memfd_offset) = guest_memfd
149+ . map ( |fo| ( fo. file ( ) . as_raw_fd ( ) as u32 , fo. start ( ) ) )
150+ . unwrap_or ( ( 0 , 0 ) ) ;
151+
142152 // SAFETY: `GuestRegionMmap` is essentially a fat pointer, and ensures that
143153 // region.as_ptr() is valid for reads and writes of length region.len(),
144154 // and by placing our region into a `ManuallyDrop` we ensure that its `Drop`
145155 // impl won't run and free the memory away from underneath us.
146156 unsafe {
147157 Self :: new (
148- kvm_userspace_memory_region {
158+ kvm_userspace_memory_region2 {
149159 slot,
150160 flags,
151161 guest_phys_addr : region. start_addr ( ) . 0 ,
152162 memory_size : region. len ( ) ,
153163 userspace_addr : region. as_ptr ( ) as u64 ,
164+ guest_memfd,
165+ guest_memfd_offset,
166+ ..Default :: default ( )
154167 } ,
155168 region. bitmap ( ) . clone ( ) ,
156169 region. file_offset ( ) . cloned ( ) ,
157170 )
158171 }
159172 }
160173
161- pub ( crate ) fn inner ( & self ) -> & kvm_userspace_memory_region {
174+ pub ( crate ) fn inner ( & self ) -> & kvm_userspace_memory_region2 {
162175 & self . region
163176 }
164177}
@@ -536,7 +549,7 @@ mod tests {
536549 regions
537550 . into_iter ( )
538551 . zip ( 0u32 ..) // assign dummy slots
539- . map ( |( region, slot) | KvmRegion :: from_mmap_region ( region, slot) )
552+ . map ( |( region, slot) | KvmRegion :: from_mmap_region ( region, slot, None ) )
540553 . collect ( ) ,
541554 )
542555 . unwrap ( )
0 commit comments