Skip to content

Commit def6cb5

Browse files
executor: sys/linux: implement SYZOS_API_NESTED_LOAD_CODE
The new command loads an instruction blob into the specified L2 VM.
1 parent efb7cc2 commit def6cb5

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

executor/common_kvm_amd64_syzos.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
4956
struct 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);
8592
GUEST_CODE static void guest_handle_set_irq_handler(struct api_call_2* cmd);
8693
GUEST_CODE static void guest_handle_enable_nested(struct api_call_1* cmd, uint64 cpu_id);
8794
GUEST_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

8997
typedef 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;
@@ -534,6 +545,14 @@ GUEST_CODE static void guest_memset(void* s, uint8 c, int size)
534545
p[i] = c;
535546
}
536547

548+
GUEST_CODE static void guest_memcpy(void* dst, void* src, int size)
549+
{
550+
volatile uint8* d = (volatile uint8*)dst;
551+
volatile uint8* s = (volatile uint8*)src;
552+
for (int i = 0; i < size; i++)
553+
d[i] = s[i];
554+
}
555+
537556
GUEST_CODE static noinline void
538557
nested_enable_vmx_intel(uint64 cpu_id)
539558
{
@@ -928,4 +947,26 @@ guest_handle_nested_create_vm(struct api_call_1* cmd, uint64 cpu_id)
928947
}
929948
}
930949

950+
GUEST_CODE static noinline void
951+
guest_handle_nested_load_code(struct api_call_nested_load_code* cmd, uint64 cpu_id)
952+
{
953+
uint64 vm_id = cmd->vm_id;
954+
uint64 l2_code_addr = X86_SYZOS_ADDR_VM_CODE(cpu_id, vm_id);
955+
uint64 l2_stack_addr = X86_SYZOS_ADDR_VM_STACK(cpu_id, vm_id);
956+
// Code size = command size - header size - vm_id size.
957+
uint64 l2_code_size = cmd->header.size - sizeof(struct api_call_header) - sizeof(uint64);
958+
if (l2_code_size > KVM_PAGE_SIZE)
959+
l2_code_size = KVM_PAGE_SIZE;
960+
guest_memcpy((void*)l2_code_addr, (void*)cmd->insns,
961+
l2_code_size);
962+
if (get_cpu_vendor() == CPU_VENDOR_INTEL) {
963+
nested_vmptrld(cpu_id, vm_id);
964+
vmwrite(VMCS_GUEST_RIP, l2_code_addr);
965+
vmwrite(VMCS_GUEST_RSP, l2_stack_addr + KVM_PAGE_SIZE - 8);
966+
} else {
967+
vmcb_write64(X86_SYZOS_ADDR_VMCS_VMCB(cpu_id, vm_id), VMCB_GUEST_RIP, l2_code_addr);
968+
vmcb_write64(X86_SYZOS_ADDR_VMCS_VMCB(cpu_id, vm_id), VMCB_GUEST_RSP, l2_stack_addr + KVM_PAGE_SIZE - 8);
969+
}
970+
}
971+
931972
#endif // EXECUTOR_COMMON_KVM_AMD64_SYZOS_H

sys/linux/dev_kvm_amd64.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ syzos_api_set_irq_handler {
9696

9797
type syzos_api_vm_id int64[0:3]
9898

99+
syzos_api_nested_load_code {
100+
vm_id syzos_api_vm_id
101+
insns text[x86_64]
102+
} [packed]
103+
99104
# IDs here must match those in executor/common_kvm_amd64_syzos.h.
100105
syzos_api_call$x86 [
101106
uexit syzos_api$x86[0, intptr]
@@ -110,6 +115,7 @@ syzos_api_call$x86 [
110115
set_irq_handler syzos_api$x86[200, syzos_api_set_irq_handler]
111116
enable_nested syzos_api$x86[300, const[0, intptr]]
112117
nested_create_vm syzos_api$x86[301, syzos_api_vm_id]
118+
nested_load_code syzos_api$x86[302, syzos_api_nested_load_code]
113119
] [varlen]
114120

115121
kvm_text_x86 [

0 commit comments

Comments
 (0)