@@ -5,6 +5,8 @@ use std::collections::hash_map::Entry;
5
5
use std:: collections:: HashMap ;
6
6
use std:: convert:: TryInto ;
7
7
use std:: env;
8
+ #[ cfg( feature = "tee" ) ]
9
+ use std:: ffi:: c_void;
8
10
use std:: ffi:: CStr ;
9
11
#[ cfg( target_os = "linux" ) ]
10
12
use std:: ffi:: CString ;
@@ -20,7 +22,7 @@ use std::sync::atomic::{AtomicI32, Ordering};
20
22
use std:: sync:: LazyLock ;
21
23
use std:: sync:: Mutex ;
22
24
23
- #[ cfg( target_os = "macos" ) ]
25
+ #[ cfg( any ( target_os = "macos" , feature = "tee" ) ) ]
24
26
use crossbeam_channel:: unbounded;
25
27
#[ cfg( feature = "blk" ) ]
26
28
use devices:: virtio:: block:: ImageType ;
@@ -54,6 +56,15 @@ use vmm::vmm_config::machine_config::VmConfig;
54
56
use vmm:: vmm_config:: net:: NetworkInterfaceConfig ;
55
57
use vmm:: vmm_config:: vsock:: VsockDeviceConfig ;
56
58
59
+ #[ cfg( feature = "tee" ) ]
60
+ use kvm_bindings:: kvm_memory_attributes;
61
+
62
+ #[ cfg( feature = "tee" ) ]
63
+ use vm_memory:: { guest_memory:: GuestMemory , GuestAddress , GuestMemoryRegion , MemoryRegionAddress } ;
64
+
65
+ #[ cfg( feature = "tee" ) ]
66
+ use libc:: { fallocate, madvise, FALLOC_FL_KEEP_SIZE , FALLOC_FL_PUNCH_HOLE , MADV_DONTNEED } ;
67
+
57
68
// Value returned on success. We use libc's errors otherwise.
58
69
const KRUN_SUCCESS : i32 = 0 ;
59
70
// Maximum number of arguments/environment variables we allow
@@ -1454,12 +1465,19 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1454
1465
#[ cfg( target_os = "macos" ) ]
1455
1466
let ( sender, receiver) = unbounded ( ) ;
1456
1467
1468
+ #[ cfg( feature = "tee" ) ]
1469
+ let ( pm_sender, pm_receiver) = unbounded ( ) ;
1470
+ #[ cfg( feature = "tee" ) ]
1471
+ let pm_efd = EventFd :: new ( libc:: EFD_SEMAPHORE ) . unwrap ( ) ;
1472
+
1457
1473
let _vmm = match vmm:: builder:: build_microvm (
1458
1474
& ctx_cfg. vmr ,
1459
1475
& mut event_manager,
1460
1476
ctx_cfg. shutdown_efd ,
1461
1477
#[ cfg( target_os = "macos" ) ]
1462
1478
sender,
1479
+ #[ cfg( feature = "tee" ) ]
1480
+ ( pm_sender, pm_efd. try_clone ( ) . unwrap ( ) ) ,
1463
1481
) {
1464
1482
Ok ( vmm) => vmm,
1465
1483
Err ( e) => {
@@ -1468,7 +1486,7 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1468
1486
}
1469
1487
} ;
1470
1488
1471
- #[ cfg( target_os = "macos" ) ]
1489
+ #[ cfg( any ( target_os = "macos" , feature = "tee" ) ) ]
1472
1490
let mapper_vmm = _vmm. clone ( ) ;
1473
1491
1474
1492
#[ cfg( target_os = "macos" ) ]
@@ -1491,6 +1509,91 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1491
1509
. unwrap ( ) ;
1492
1510
}
1493
1511
1512
+ #[ cfg( feature = "tee" ) ]
1513
+ let guest_mem = _vmm. lock ( ) . unwrap ( ) . guest_memory ( ) . clone ( ) ;
1514
+
1515
+ #[ cfg( feature = "tee" ) ]
1516
+ std:: thread:: Builder :: new ( )
1517
+ . name ( "TEE memory properties worker" . into ( ) )
1518
+ . spawn ( move || loop {
1519
+ match pm_receiver. recv ( ) {
1520
+ Err ( e) => error ! ( "Error in pm receiver: {:?}" , e) ,
1521
+ Ok ( m) => {
1522
+ let ( guest_memfd, region_start) = mapper_vmm
1523
+ . lock ( )
1524
+ . unwrap ( )
1525
+ . kvm_vm ( )
1526
+ . guest_memfd_get ( m. gpa )
1527
+ . unwrap ( ) ;
1528
+
1529
+ let attributes: u64 = if m. private {
1530
+ 1 << 3 /* KVM_MEMORY_ATTRIBUTE_PRIVATE */
1531
+ } else {
1532
+ 0
1533
+ } ;
1534
+
1535
+ let attr = kvm_memory_attributes {
1536
+ address : m. gpa ,
1537
+ size : m. size ,
1538
+ attributes,
1539
+ flags : 0 ,
1540
+ } ;
1541
+
1542
+ mapper_vmm
1543
+ . lock ( )
1544
+ . unwrap ( )
1545
+ . kvm_vm ( )
1546
+ . fd ( )
1547
+ . set_memory_attributes ( attr)
1548
+ . unwrap ( ) ;
1549
+
1550
+ let region = guest_mem. find_region ( GuestAddress ( m. gpa ) ) ;
1551
+ if region. is_none ( ) {
1552
+ error ! ( "Region not found" ) ;
1553
+ pm_efd. write ( 1 ) . unwrap ( ) ;
1554
+ continue ;
1555
+ }
1556
+
1557
+ let offset = m. gpa - region_start;
1558
+
1559
+ if m. private {
1560
+ let host_startaddr = region
1561
+ . unwrap ( )
1562
+ . get_host_address ( MemoryRegionAddress ( offset) )
1563
+ . unwrap ( ) ;
1564
+
1565
+ let ret = unsafe {
1566
+ madvise (
1567
+ host_startaddr as * mut c_void ,
1568
+ m. size . try_into ( ) . unwrap ( ) ,
1569
+ MADV_DONTNEED ,
1570
+ )
1571
+ } ;
1572
+
1573
+ if ret < 0 {
1574
+ error ! ( "madvise has failed" ) ;
1575
+ }
1576
+ } else {
1577
+ let ret = unsafe {
1578
+ fallocate (
1579
+ guest_memfd,
1580
+ FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE ,
1581
+ offset as i64 ,
1582
+ m. size as i64 ,
1583
+ )
1584
+ } ;
1585
+
1586
+ if ret < 0 {
1587
+ error ! ( "fallocate has failed" ) ;
1588
+ }
1589
+ }
1590
+
1591
+ pm_efd. write ( 1 ) . unwrap ( ) ;
1592
+ }
1593
+ }
1594
+ } )
1595
+ . unwrap ( ) ;
1596
+
1494
1597
loop {
1495
1598
match event_manager. run ( ) {
1496
1599
Ok ( _) => { }
0 commit comments