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 ;
@@ -107,7 +108,7 @@ impl<S: Seek> Seek for Bounce<S> {
107108/// A memory region, described in terms of `kvm_userspace_memory_region`
108109#[ derive( Debug ) ]
109110pub struct KvmRegion {
110- region : kvm_userspace_memory_region ,
111+ region : kvm_userspace_memory_region2 ,
111112 bitmap : Option < AtomicBitmap > ,
112113 file_offset : Option < FileOffset > ,
113114}
@@ -121,7 +122,7 @@ impl KvmRegion {
121122 /// `kvm_region.userspace_addr as *mut u8` is valid for reads and writes of length
122123 /// `kvm_region.memory_size`.
123124 pub unsafe fn new (
124- region : kvm_userspace_memory_region ,
125+ region : kvm_userspace_memory_region2 ,
125126 bitmap : Option < AtomicBitmap > ,
126127 file_offset : Option < FileOffset > ,
127128 ) -> Self {
@@ -132,34 +133,46 @@ impl KvmRegion {
132133 }
133134 }
134135
135- pub ( crate ) fn from_mmap_region ( region : GuestRegionMmap , slot : u32 ) -> Self {
136+ pub ( crate ) fn from_mmap_region (
137+ region : GuestRegionMmap ,
138+ slot : u32 ,
139+ guest_memfd : Option < & FileOffset > ,
140+ ) -> Self {
136141 let region = ManuallyDrop :: new ( region) ;
137142 let flags = if region. bitmap ( ) . is_some ( ) {
138143 KVM_MEM_LOG_DIRTY_PAGES
139144 } else {
140145 0
141146 } ;
142147
148+ #[ allow( clippy:: cast_sign_loss) ]
149+ let ( guest_memfd, guest_memfd_offset) = guest_memfd
150+ . map ( |fo| ( fo. file ( ) . as_raw_fd ( ) as u32 , fo. start ( ) ) )
151+ . unwrap_or ( ( 0 , 0 ) ) ;
152+
143153 // SAFETY: `GuestRegionMmap` is essentially a fat pointer, and ensures that
144154 // region.as_ptr() is valid for reads and writes of length region.len(),
145155 // and by placing our region into a `ManuallyDrop` we ensure that its `Drop`
146156 // impl won't run and free the memory away from underneath us.
147157 unsafe {
148158 Self :: new (
149- kvm_userspace_memory_region {
159+ kvm_userspace_memory_region2 {
150160 slot,
151161 flags,
152162 guest_phys_addr : region. start_addr ( ) . 0 ,
153163 memory_size : region. len ( ) ,
154164 userspace_addr : region. as_ptr ( ) as u64 ,
165+ guest_memfd,
166+ guest_memfd_offset,
167+ ..Default :: default ( )
155168 } ,
156169 region. bitmap ( ) . clone ( ) ,
157170 region. file_offset ( ) . cloned ( ) ,
158171 )
159172 }
160173 }
161174
162- pub ( crate ) fn inner ( & self ) -> & kvm_userspace_memory_region {
175+ pub ( crate ) fn inner ( & self ) -> & kvm_userspace_memory_region2 {
163176 & self . region
164177 }
165178}
@@ -539,7 +552,7 @@ mod tests {
539552 regions
540553 . into_iter ( )
541554 . zip ( 0u32 ..) // assign dummy slots
542- . map ( |( region, slot) | KvmRegion :: from_mmap_region ( region, slot) )
555+ . map ( |( region, slot) | KvmRegion :: from_mmap_region ( region, slot, None ) )
543556 . collect ( ) ,
544557 )
545558 . unwrap ( )
0 commit comments