11#[ macro_use]
22extern crate log;
33
4+ use crossbeam_channel:: unbounded;
5+ use kvm_bindings:: kvm_memory_attributes;
6+ use libc:: fallocate;
7+ use libc:: madvise;
8+ use libc:: FALLOC_FL_KEEP_SIZE ;
9+ use libc:: FALLOC_FL_PUNCH_HOLE ;
10+ use libc:: MADV_DONTNEED ;
411use std:: collections:: hash_map:: Entry ;
512use std:: collections:: HashMap ;
613use std:: convert:: TryInto ;
@@ -11,10 +18,13 @@ use std::ffi::CString;
1118#[ cfg( target_os = "linux" ) ]
1219use std:: os:: fd:: AsRawFd ;
1320use std:: os:: fd:: RawFd ;
21+ use std:: os:: raw:: c_void;
1422use std:: path:: PathBuf ;
1523use std:: slice;
1624use std:: sync:: atomic:: { AtomicI32 , Ordering } ;
1725use std:: sync:: Mutex ;
26+ use vm_memory:: GuestMemoryRegion ;
27+ use vm_memory:: { Address , GuestMemory } ;
1828
1929#[ cfg( target_os = "macos" ) ]
2030use crossbeam_channel:: unbounded;
@@ -1077,9 +1087,12 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
10771087 #[ cfg( target_os = "macos" ) ]
10781088 let ( sender, receiver) = unbounded ( ) ;
10791089
1090+ let ( io_sender, receiver) = unbounded ( ) ;
1091+
10801092 let _vmm = match vmm:: builder:: build_microvm (
10811093 & ctx_cfg. vmr ,
10821094 & mut event_manager,
1095+ io_sender,
10831096 ctx_cfg. shutdown_efd ,
10841097 #[ cfg( target_os = "macos" ) ]
10851098 sender,
@@ -1094,6 +1107,61 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
10941107 #[ cfg( target_os = "macos" ) ]
10951108 let mapper_vmm = _vmm. clone ( ) ;
10961109
1110+ let vm = _vmm. lock ( ) . unwrap ( ) . kvm_vm ( ) . fd . clone ( ) ;
1111+ let guest_mem = _vmm. lock ( ) . unwrap ( ) . guest_memory ( ) . clone ( ) ;
1112+ let guest_memfd = _vmm. lock ( ) . unwrap ( ) . guest_memfd_vec . clone ( ) ;
1113+
1114+ std:: thread:: spawn ( move || loop {
1115+ match receiver. recv ( ) {
1116+ Err ( e) => error ! ( "Error in receiver: {:?}" , e) ,
1117+ Ok ( m) => {
1118+ let _ret = vm
1119+ . lock ( )
1120+ . unwrap ( )
1121+ . set_memory_attributes ( kvm_memory_attributes {
1122+ address : m. addr ,
1123+ size : m. size ,
1124+ attributes : m. attributes as u64 ,
1125+ flags : 0 ,
1126+ } ) ;
1127+
1128+ // from private to shared
1129+ if m. attributes == 0 {
1130+ for ( index, region) in guest_mem. iter ( ) . enumerate ( ) {
1131+ // this supposes that m.addr + m.size < region.start + region.size
1132+ // which may be false
1133+ if ( region. start_addr ( ) . raw_value ( ) + region. size ( ) as u64 ) > m. addr {
1134+ let offset = m. addr - region. start_addr ( ) . raw_value ( ) ;
1135+ unsafe {
1136+ let _ret = fallocate (
1137+ * guest_memfd. get ( index) . unwrap ( ) ,
1138+ FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE ,
1139+ offset as i64 ,
1140+ m. size as i64 ,
1141+ ) ;
1142+ }
1143+ }
1144+ }
1145+ // from shared to private
1146+ } else {
1147+ for ( _index, region) in guest_mem. iter ( ) . enumerate ( ) {
1148+ if ( region. start_addr ( ) . raw_value ( ) + region. size ( ) as u64 ) > m. addr {
1149+ let offset = m. addr - region. start_addr ( ) . raw_value ( ) ;
1150+ let host_startaddr = m. addr + offset;
1151+ unsafe {
1152+ let _ret = madvise (
1153+ host_startaddr as * mut c_void ,
1154+ m. size . try_into ( ) . unwrap ( ) ,
1155+ MADV_DONTNEED ,
1156+ ) ;
1157+ }
1158+ }
1159+ }
1160+ }
1161+ }
1162+ }
1163+ } ) ;
1164+
10971165 #[ cfg( target_os = "macos" ) ]
10981166 std:: thread:: spawn ( move || loop {
10991167 match receiver. recv ( ) {
0 commit comments