@@ -28,6 +28,7 @@ typedef enum {
2828 SYZOS_API_SET_IRQ_HANDLER = 200 ,
2929 SYZOS_API_ENABLE_NESTED = 300 ,
3030 SYZOS_API_NESTED_CREATE_VM = 301 ,
31+ SYZOS_API_NESTED_LOAD_CODE = 302 ,
3132 SYZOS_API_STOP , // Must be the last one
3233} syzos_api_id ;
3334
@@ -46,6 +47,12 @@ struct api_call_code {
4647 uint8 insns [];
4748};
4849
50+ struct api_call_nested_load_code {
51+ struct api_call_header header ;
52+ uint64 vm_id ;
53+ uint8 insns [];
54+ };
55+
4956struct api_call_cpuid {
5057 struct api_call_header header ;
5158 uint32 eax ;
@@ -85,6 +92,7 @@ GUEST_CODE static void guest_handle_out_dx(struct api_call_3* cmd);
8592GUEST_CODE static void guest_handle_set_irq_handler (struct api_call_2 * cmd );
8693GUEST_CODE static void guest_handle_enable_nested (struct api_call_1 * cmd , uint64 cpu_id );
8794GUEST_CODE static void guest_handle_nested_create_vm (struct api_call_1 * cmd , uint64 cpu_id );
95+ GUEST_CODE static void guest_handle_nested_load_code (struct api_call_nested_load_code * cmd , uint64 cpu_id );
8896
8997typedef enum {
9098 UEXIT_END = (uint64 )- 1 ,
@@ -185,6 +193,9 @@ guest_main(uint64 size, uint64 cpu)
185193 } else if (call == SYZOS_API_NESTED_CREATE_VM ) {
186194 // Create a nested VM.
187195 guest_handle_nested_create_vm ((struct api_call_1 * )cmd , cpu );
196+ } else if (call == SYZOS_API_NESTED_LOAD_CODE ) {
197+ // Load code into the nested VM.
198+ guest_handle_nested_load_code ((struct api_call_nested_load_code * )cmd , cpu );
188199 }
189200 addr += cmd -> size ;
190201 size -= cmd -> size ;
@@ -535,6 +546,15 @@ GUEST_CODE static void guest_memset(void* s, uint8 c, int size)
535546 }
536547}
537548
549+ GUEST_CODE static void guest_memcpy (void * dst , void * src , int size )
550+ {
551+ volatile uint8 * d = (volatile uint8 * )dst ;
552+ volatile uint8 * s = (volatile uint8 * )src ;
553+ for (int i = 0 ; i < size ; i ++ ) {
554+ d [i ] = s [i ];
555+ }
556+ }
557+
538558GUEST_CODE static noinline void
539559nested_enable_vmx_intel (uint64 cpu_id )
540560{
@@ -933,4 +953,26 @@ guest_handle_nested_create_vm(struct api_call_1* cmd, uint64 cpu_id)
933953 }
934954}
935955
956+ GUEST_CODE static noinline void
957+ guest_handle_nested_load_code (struct api_call_nested_load_code * cmd , uint64 cpu_id )
958+ {
959+ uint64 vm_id = cmd -> vm_id ;
960+ uint64 l2_code_addr = X86_SYZOS_ADDR_VM_CODE (cpu_id , vm_id );
961+ uint64 l2_stack_addr = X86_SYZOS_ADDR_VM_STACK (cpu_id , vm_id );
962+ // Code size = command size - header size - vm_id size.
963+ uint64 l2_code_size = cmd -> header .size - sizeof (struct api_call_header ) - sizeof (uint64 );
964+ if (l2_code_size > KVM_PAGE_SIZE )
965+ l2_code_size = KVM_PAGE_SIZE ;
966+ guest_memcpy ((void * )l2_code_addr , (void * )cmd -> insns ,
967+ l2_code_size );
968+ if (get_cpu_vendor () == CPU_VENDOR_INTEL ) {
969+ nested_vmptrld (cpu_id , vm_id );
970+ vmwrite (VMCS_GUEST_RIP , l2_code_addr );
971+ vmwrite (VMCS_GUEST_RSP , l2_stack_addr + KVM_PAGE_SIZE - 8 );
972+ } else {
973+ vmcb_write64 (X86_SYZOS_ADDR_VMCS_VMCB (cpu_id , vm_id ), VMCB_GUEST_RIP , l2_code_addr );
974+ vmcb_write64 (X86_SYZOS_ADDR_VMCS_VMCB (cpu_id , vm_id ), VMCB_GUEST_RSP , l2_stack_addr + KVM_PAGE_SIZE - 8 );
975+ }
976+ }
977+
936978#endif // EXECUTOR_COMMON_KVM_AMD64_SYZOS_H
0 commit comments