1
1
#[ macro_use]
2
2
extern crate log;
3
3
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 ;
4
11
use std:: collections:: hash_map:: Entry ;
5
12
use std:: collections:: HashMap ;
6
13
use std:: convert:: TryInto ;
@@ -11,10 +18,13 @@ use std::ffi::CString;
11
18
#[ cfg( target_os = "linux" ) ]
12
19
use std:: os:: fd:: AsRawFd ;
13
20
use std:: os:: fd:: RawFd ;
21
+ use std:: os:: raw:: c_void;
14
22
use std:: path:: PathBuf ;
15
23
use std:: slice;
16
24
use std:: sync:: atomic:: { AtomicI32 , Ordering } ;
17
25
use std:: sync:: Mutex ;
26
+ use vm_memory:: GuestMemoryRegion ;
27
+ use vm_memory:: { Address , GuestMemory } ;
18
28
19
29
#[ cfg( target_os = "macos" ) ]
20
30
use crossbeam_channel:: unbounded;
@@ -1077,9 +1087,12 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1077
1087
#[ cfg( target_os = "macos" ) ]
1078
1088
let ( sender, receiver) = unbounded ( ) ;
1079
1089
1090
+ let ( io_sender, receiver) = unbounded ( ) ;
1091
+
1080
1092
let _vmm = match vmm:: builder:: build_microvm (
1081
1093
& ctx_cfg. vmr ,
1082
1094
& mut event_manager,
1095
+ io_sender,
1083
1096
ctx_cfg. shutdown_efd ,
1084
1097
#[ cfg( target_os = "macos" ) ]
1085
1098
sender,
@@ -1094,6 +1107,61 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1094
1107
#[ cfg( target_os = "macos" ) ]
1095
1108
let mapper_vmm = _vmm. clone ( ) ;
1096
1109
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
+
1097
1165
#[ cfg( target_os = "macos" ) ]
1098
1166
std:: thread:: spawn ( move || loop {
1099
1167
match receiver. recv ( ) {
0 commit comments