-
Notifications
You must be signed in to change notification settings - Fork 19
/
hv_demo.m
62 lines (53 loc) · 2.19 KB
/
hv_demo.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
@import Darwin;
#include <Hypervisor/Hypervisor.h>
const char kVMCode[] = {
// Compute ((2 + 2) - 1)
0x40, 0x00, 0x80, 0xD2, // mov x0, #2
0x00, 0x08, 0x00, 0x91, // add x0, x0, #2
0x00, 0x04, 0x00, 0xD1, // sub x0, x0, #1
// Write it to memory pointed by x1
0x20, 0x00, 0x00, 0xF9, // str x0, [x1]
// Reboot the computer with PSCI/SMCCC
// 0x84000009 is PSCI SYSTEM_RESET using SMC32 calling convention
0x20, 0x01, 0x80, 0xd2, // mov x0, 0x0009
0x00, 0x80, 0xb0, 0xf2, // movk x0, 0x8400, lsl #16
0x02, 0x00, 0x00, 0xD4, // hvc #0
// Infinite loop
0x00, 0x00, 0x00, 0x14, // b .
};
int main() {
// https://github.com/zhuowei/FakeHVF/blob/main/simplevm.c
// https://gist.github.com/imbushuo/51b09e61ecd7b7ac063853ad65cedf34
// allocate 1MB of RAM, aligned to page size, for the VM
const uint64_t kMemSize = 0x100000;
const uint64_t kMemStart = 0x69420000;
const uint64_t kMemResultOutOffset = 0x100;
const uint64_t kMemGuestResultOut = kMemStart + kMemResultOutOffset;
char* vm_ram = mmap(NULL, kMemSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (vm_ram == MAP_FAILED) {
abort();
}
// copy our code into the VM's RAM
memcpy(vm_ram, kVMCode, sizeof(kVMCode));
hv_return_t err = hv_vm_create(nil);
printf("vm create %x\n", err);
err = hv_vm_map(vm_ram, kMemStart, kMemSize, HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
printf("hv_vm_map %x\n", err);
hv_vcpu_t vcpu = 0;
hv_vcpu_exit_t* exit = nil;
err = hv_vcpu_create(&vcpu, &exit, nil);
printf("vcpu create %x\n", err);
// Set the CPU's PC to execute code from our RAM
err = hv_vcpu_set_reg(vcpu, HV_REG_PC, kMemStart);
printf("vcpu set reg pc %x\n", err);
// Set CPU's x1 register to point to where we want to read the result
err = hv_vcpu_set_reg(vcpu, HV_REG_X1, kMemGuestResultOut);
printf("vcpu set reg x1 %x\n", err);
// Set CPU's CPSR to EL1
err = hv_vcpu_set_reg(vcpu, HV_REG_CPSR, 0x3c4);
printf("vcpu set reg cpsr %x\n", err);
err = hv_vcpu_run(vcpu);
printf("run %x\n", err);
uint64_t result_out = *((uint64_t*)(vm_ram + kMemResultOutOffset));
printf("The result of (2 + 2) - 1 is %d\n", (int)result_out);
}