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;
@@ -1225,9 +1235,12 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1225
1235
#[ cfg( target_os = "macos" ) ]
1226
1236
let ( sender, receiver) = unbounded ( ) ;
1227
1237
1238
+ let ( io_sender, receiver) = unbounded ( ) ;
1239
+
1228
1240
let _vmm = match vmm:: builder:: build_microvm (
1229
1241
& ctx_cfg. vmr ,
1230
1242
& mut event_manager,
1243
+ io_sender,
1231
1244
ctx_cfg. shutdown_efd ,
1232
1245
#[ cfg( target_os = "macos" ) ]
1233
1246
sender,
@@ -1242,6 +1255,61 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1242
1255
#[ cfg( target_os = "macos" ) ]
1243
1256
let mapper_vmm = _vmm. clone ( ) ;
1244
1257
1258
+ let vm = _vmm. lock ( ) . unwrap ( ) . kvm_vm ( ) . fd . clone ( ) ;
1259
+ let guest_mem = _vmm. lock ( ) . unwrap ( ) . guest_memory ( ) . clone ( ) ;
1260
+ let guest_memfd = _vmm. lock ( ) . unwrap ( ) . guest_memfd_vec . clone ( ) ;
1261
+
1262
+ std:: thread:: spawn ( move || loop {
1263
+ match receiver. recv ( ) {
1264
+ Err ( e) => error ! ( "Error in receiver: {:?}" , e) ,
1265
+ Ok ( m) => {
1266
+ let _ret = vm
1267
+ . lock ( )
1268
+ . unwrap ( )
1269
+ . set_memory_attributes ( kvm_memory_attributes {
1270
+ address : m. addr ,
1271
+ size : m. size ,
1272
+ attributes : m. attributes as u64 ,
1273
+ flags : 0 ,
1274
+ } ) ;
1275
+
1276
+ // from private to shared
1277
+ if m. attributes == 0 {
1278
+ for ( index, region) in guest_mem. iter ( ) . enumerate ( ) {
1279
+ // this supposes that m.addr + m.size < region.start + region.size
1280
+ // which may be false
1281
+ if ( region. start_addr ( ) . raw_value ( ) + region. size ( ) as u64 ) > m. addr {
1282
+ let offset = m. addr - region. start_addr ( ) . raw_value ( ) ;
1283
+ unsafe {
1284
+ let _ret = fallocate (
1285
+ * guest_memfd. get ( index) . unwrap ( ) ,
1286
+ FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE ,
1287
+ offset as i64 ,
1288
+ m. size as i64 ,
1289
+ ) ;
1290
+ }
1291
+ }
1292
+ }
1293
+ // from shared to private
1294
+ } else {
1295
+ for ( _index, region) in guest_mem. iter ( ) . enumerate ( ) {
1296
+ if ( region. start_addr ( ) . raw_value ( ) + region. size ( ) as u64 ) > m. addr {
1297
+ let offset = m. addr - region. start_addr ( ) . raw_value ( ) ;
1298
+ let host_startaddr = m. addr + offset;
1299
+ unsafe {
1300
+ let _ret = madvise (
1301
+ host_startaddr as * mut c_void ,
1302
+ m. size . try_into ( ) . unwrap ( ) ,
1303
+ MADV_DONTNEED ,
1304
+ ) ;
1305
+ }
1306
+ }
1307
+ }
1308
+ }
1309
+ }
1310
+ }
1311
+ } ) ;
1312
+
1245
1313
#[ cfg( target_os = "macos" ) ]
1246
1314
std:: thread:: Builder :: new ( )
1247
1315
. name ( "mapping worker" . into ( ) )
0 commit comments