@@ -875,6 +875,158 @@ fn get_memory_access_violation<'a>(
875875 None
876876}
877877
878+ #[ cfg( test) ]
879+ mod tests {
880+ use super :: * ;
881+ use crate :: is_hypervisor_present;
882+ use crate :: mem:: layout:: SandboxMemoryLayout ;
883+ use crate :: mem:: mgr:: SandboxMemoryManager ;
884+ use crate :: mem:: ptr:: RawPtr ;
885+ use crate :: mem:: ptr_offset:: Offset ;
886+ use crate :: mem:: shared_mem:: { ExclusiveSharedMemory , SharedMemory } ;
887+ use crate :: sandbox:: SandboxConfiguration ;
888+ use crate :: sandbox:: host_funcs:: FunctionRegistry ;
889+ #[ cfg( feature = "mem_profile" ) ]
890+ use crate :: sandbox:: trace:: DummyUnwindInfo ;
891+ #[ cfg( feature = "mem_profile" ) ]
892+ use crate :: sandbox:: trace:: MemTraceInfo ;
893+ #[ cfg( crashdump) ]
894+ use crate :: sandbox:: uninitialized:: SandboxRuntimeConfig ;
895+ use std:: sync:: { Arc , Mutex } ;
896+
897+ #[ test]
898+ fn test_reset_vcpu ( ) -> Result < ( ) > {
899+ if !is_hypervisor_present ( ) {
900+ return Ok ( ( ) ) ;
901+ }
902+
903+ #[ cfg( target_os = "windows" ) ]
904+ return Ok ( ( ) ) ;
905+
906+ #[ cfg( not( target_os = "windows" ) ) ]
907+ {
908+ let mut code = Vec :: new ( ) ;
909+ // mov rax, 0x1111111111111111
910+ code. extend_from_slice ( & [ 0x48 , 0xb8 , 0x11 , 0x11 , 0x11 , 0x11 , 0x11 , 0x11 , 0x11 , 0x11 ] ) ;
911+ // mov rbx, 0x2222222222222222
912+ code. extend_from_slice ( & [ 0x48 , 0xbb , 0x22 , 0x22 , 0x22 , 0x22 , 0x22 , 0x22 , 0x22 , 0x22 ] ) ;
913+ // mov rcx, 0x3333333333333333
914+ code. extend_from_slice ( & [ 0x48 , 0xb9 , 0x33 , 0x33 , 0x33 , 0x33 , 0x33 , 0x33 , 0x33 , 0x33 ] ) ;
915+
916+ // hlt
917+ code. extend_from_slice ( & [ 0xf4 ] ) ;
918+
919+ let config: SandboxConfiguration = Default :: default ( ) ;
920+ #[ cfg( crashdump) ]
921+ let rt_cfg: SandboxRuntimeConfig = Default :: default ( ) ;
922+ #[ cfg( feature = "mem_profile" ) ]
923+ let trace_info = MemTraceInfo :: new ( Arc :: new ( DummyUnwindInfo { } ) ) . unwrap ( ) ;
924+
925+ let layout = SandboxMemoryLayout :: new (
926+ config. clone ( ) ,
927+ code. len ( ) , // code size
928+ 0 , // stack
929+ 0 , // heap
930+ 0 , // init data
931+ None ,
932+ ) ?;
933+
934+ let mem_size = layout. get_memory_size ( ) ?;
935+ let eshm = ExclusiveSharedMemory :: new ( mem_size) ?;
936+
937+ let stack_cookie = [ 0u8 ; 16 ] ;
938+ let mem_mgr = SandboxMemoryManager :: new (
939+ layout. clone ( ) ,
940+ eshm,
941+ RawPtr :: from ( 0 ) ,
942+ Offset :: from ( 0 ) ,
943+ stack_cookie,
944+ ) ;
945+
946+ let ( mut mem_mgr_hshm, mut mem_mgr_gshm) = mem_mgr. build ( ) ;
947+
948+ // Set up shared memory (page tables)
949+ #[ cfg( feature = "init-paging" ) ]
950+ let rsp = {
951+ let mut regions = layout. get_memory_regions ( & mem_mgr_gshm. shared_mem ) ?;
952+ let mem_size = mem_mgr_gshm. shared_mem . mem_size ( ) as u64 ;
953+ mem_mgr_gshm. set_up_shared_memory ( mem_size, & mut regions) ?
954+ } ;
955+ #[ cfg( not( feature = "init-paging" ) ) ]
956+ let rsp = 0 ;
957+
958+ // Write code
959+ let code_offset = layout. get_guest_code_offset ( ) ;
960+ mem_mgr_hshm
961+ . shared_mem
962+ . copy_from_slice ( & code, code_offset) ?;
963+
964+ // Get regions for VM
965+ let regions = layout
966+ . get_memory_regions ( & mem_mgr_gshm. shared_mem ) ?
967+ . into_iter ( )
968+ . filter ( |r| r. guest_region . len ( ) > 0 )
969+ . collect ( ) ;
970+
971+ // Calculate pml4_addr
972+ #[ cfg( feature = "init-paging" ) ]
973+ let pml4_addr = SandboxMemoryLayout :: PML4_OFFSET as u64 ;
974+ #[ cfg( not( feature = "init-paging" ) ) ]
975+ let pml4_addr = 0 ;
976+
977+ // Entrypoint
978+ let entrypoint = layout. get_guest_code_address ( ) as u64 ;
979+
980+ let mut vm = HyperlightVm :: new (
981+ regions,
982+ pml4_addr,
983+ entrypoint,
984+ rsp,
985+ & config,
986+ #[ cfg( gdb) ]
987+ None ,
988+ #[ cfg( crashdump) ]
989+ rt_cfg,
990+ #[ cfg( feature = "mem_profile" ) ]
991+ trace_info,
992+ ) ?;
993+
994+ let host_funcs = Arc :: new ( Mutex :: new ( FunctionRegistry :: default ( ) ) ) ;
995+ #[ cfg( gdb) ]
996+ let dbg_mem_access_fn = Arc :: new ( Mutex :: new ( mem_mgr_hshm. clone ( ) ) ) ;
997+
998+ // Run the VM
999+ vm. initialise (
1000+ RawPtr :: from ( 0 ) , // peb_addr
1001+ 0 , // seed
1002+ 4096 , // page_size
1003+ & mut mem_mgr_hshm,
1004+ & host_funcs,
1005+ None ,
1006+ #[ cfg( gdb) ]
1007+ dbg_mem_access_fn. clone ( ) ,
1008+ ) ?;
1009+
1010+ // After run, check registers
1011+ let regs = vm. vm . regs ( ) ?;
1012+ assert_eq ! ( regs. rax, 0x1111111111111111 ) ;
1013+ assert_eq ! ( regs. rbx, 0x2222222222222222 ) ;
1014+ assert_eq ! ( regs. rcx, 0x3333333333333333 ) ;
1015+
1016+ // Reset vcpu
1017+ vm. reset_vcpu ( ) ?;
1018+
1019+ // Check registers again
1020+ let regs = vm. vm . regs ( ) ?;
1021+ assert_eq ! ( regs. rax, 0 ) ;
1022+ assert_eq ! ( regs. rbx, 0 ) ;
1023+ assert_eq ! ( regs. rcx, 0 ) ;
1024+ }
1025+
1026+ Ok ( ( ) )
1027+ }
1028+ }
1029+
8781030#[ cfg( gdb) ]
8791031mod debug {
8801032 use hyperlight_common:: mem:: PAGE_SIZE ;
0 commit comments