88use std:: fs:: File ;
99use std:: io:: { Read , Seek , SeekFrom , Write } ;
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 ;
@@ -115,7 +115,7 @@ impl<S: Seek> Seek for Bounce<S> {
115115/// A memory region, described in terms of `kvm_userspace_memory_region`
116116#[ derive( Debug ) ]
117117pub struct KvmRegion {
118- region : kvm_userspace_memory_region ,
118+ region : kvm_userspace_memory_region2 ,
119119 bitmap : Option < AtomicBitmap > ,
120120 file_offset : Option < FileOffset > ,
121121}
@@ -129,7 +129,7 @@ impl KvmRegion {
129129 /// `kvm_region.userspace_addr as *mut u8` is valid for reads and writes of length
130130 /// `kvm_region.memory_size`.
131131 pub unsafe fn new (
132- region : kvm_userspace_memory_region ,
132+ region : kvm_userspace_memory_region2 ,
133133 bitmap : Option < AtomicBitmap > ,
134134 file_offset : Option < FileOffset > ,
135135 ) -> Self {
@@ -140,34 +140,46 @@ impl KvmRegion {
140140 }
141141 }
142142
143- pub ( crate ) fn from_mmap_region ( region : GuestRegionMmap , slot : u32 ) -> Self {
143+ pub ( crate ) fn from_mmap_region (
144+ region : GuestRegionMmap ,
145+ slot : u32 ,
146+ guest_memfd : Option < & FileOffset > ,
147+ ) -> Self {
144148 let region = ManuallyDrop :: new ( region) ;
145149 let flags = if region. bitmap ( ) . is_some ( ) {
146150 KVM_MEM_LOG_DIRTY_PAGES
147151 } else {
148152 0
149153 } ;
150154
155+ #[ allow( clippy:: cast_sign_loss) ]
156+ let ( guest_memfd, guest_memfd_offset) = guest_memfd
157+ . map ( |fo| ( fo. file ( ) . as_raw_fd ( ) as u32 , fo. start ( ) ) )
158+ . unwrap_or ( ( 0 , 0 ) ) ;
159+
151160 // SAFETY: `GuestRegionMmap` is essentially a fat pointer, and ensures that
152161 // region.as_ptr() is valid for reads and writes of length region.len(),
153162 // and by placing our region into a `ManuallyDrop` we ensure that its `Drop`
154163 // impl won't run and free the memory away from underneath us.
155164 unsafe {
156165 Self :: new (
157- kvm_userspace_memory_region {
166+ kvm_userspace_memory_region2 {
158167 slot,
159168 flags,
160169 guest_phys_addr : region. start_addr ( ) . 0 ,
161170 memory_size : region. len ( ) ,
162171 userspace_addr : region. as_ptr ( ) as u64 ,
172+ guest_memfd,
173+ guest_memfd_offset,
174+ ..Default :: default ( )
163175 } ,
164176 region. bitmap ( ) . clone ( ) ,
165177 region. file_offset ( ) . cloned ( ) ,
166178 )
167179 }
168180 }
169181
170- pub ( crate ) fn inner ( & self ) -> & kvm_userspace_memory_region {
182+ pub ( crate ) fn inner ( & self ) -> & kvm_userspace_memory_region2 {
171183 & self . region
172184 }
173185}
@@ -546,7 +558,7 @@ mod tests {
546558 regions
547559 . into_iter ( )
548560 . zip ( 0u32 ..) // assign dummy slots
549- . map ( |( region, slot) | KvmRegion :: from_mmap_region ( region, slot) )
561+ . map ( |( region, slot) | KvmRegion :: from_mmap_region ( region, slot, None ) )
550562 . collect ( ) ,
551563 )
552564 . unwrap ( )
0 commit comments