DF-3829 / vctest5.c
#include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/mman.h> #include <dev/virtual/nvmm/nvmm.h> #include <dev/virtual/nvmm/nvmm_ioctl.h> int main(void) { struct nvmm_ioc_capability c; struct nvmm_ioc_machine_create mc; struct nvmm_ioc_hva_map hm; struct nvmm_ioc_gpa_map gm; struct nvmm_ioc_vcpu_create vc; struct nvmm_ioc_vcpu_setstate ss; struct nvmm_comm_page *comm; int fd = open("/dev/nvmm", O_RDONLY|O_CLOEXEC); if (fd < 0) { perror("open"); return 1; } memset(&c, 0, sizeof(c)); if (ioctl(fd, NVMM_IOC_CAPABILITY, &c)) { perror("cap"); return 1; } printf("cap ok v%u\n", c.cap.version); memset(&mc, 0, sizeof(mc)); if (ioctl(fd, NVMM_IOC_MACHINE_CREATE, &mc)) { perror("machcreate"); return 1; } memset(&hm, 0, sizeof(hm)); hm.machid = mc.machid; hm.hva = 0x10000000UL; hm.size = 0x200000; if (ioctl(fd, NVMM_IOC_HVA_MAP, &hm)) { perror("hvamap"); return 1; } memset(&gm, 0, sizeof(gm)); gm.machid = mc.machid; gm.hva = 0x10000000UL; gm.gpa = 0; gm.size = 0x200000; gm.prot = PROT_READ|PROT_WRITE|PROT_EXEC; if (ioctl(fd, NVMM_IOC_GPA_MAP, &gm)) { perror("gpamap"); return 1; } memset(&vc, 0, sizeof(vc)); vc.machid = mc.machid; vc.cpuid = 0; vc.comm = (void *)0x30000000UL; if (ioctl(fd, NVMM_IOC_VCPU_CREATE, &vc)) { perror("vcpucreate"); return 1; } comm = (struct nvmm_comm_page *)vc.comm; printf("vcpu ok comm=%p\n", comm); memcpy((void *)0x10000000UL + 0x1000, (uint8_t[]){0xEB,0xFE}, 2); struct nvmm_x64_state *st = &comm->state; memset(st, 0, sizeof(*st)); for (int i = 0; i < NVMM_X64_NSEG; i++) { st->segs[i].limit = 0xFFFF; st->segs[i].attrib.type = 3; st->segs[i].attrib.p = 1; } st->segs[NVMM_X64_SEG_GDT].attrib.type = 2; st->segs[NVMM_X64_SEG_IDT].attrib.type = 2; st->segs[NVMM_X64_SEG_TR].attrib.type = 3; st->segs[NVMM_X64_SEG_TR].attrib.s = 0; st->segs[NVMM_X64_SEG_LDT].attrib.s = 0; st->gprs[NVMM_X64_GPR_RFLAGS] = 2; st->gprs[NVMM_X64_GPR_RIP] = 0x1000; st->gprs[NVMM_X64_GPR_RSP] = 0x7000; st->crs[NVMM_X64_CR_CR0] = 0x10; st->crs[NVMM_X64_CR_XCR0] = 1; st->drs[NVMM_X64_DR_DR6] = 0xFFFF0FF0; st->drs[NVMM_X64_DR_DR7] = 0x400; comm->state_wanted = NVMM_X64_STATE_ALL; memset(&ss, 0, sizeof(ss)); ss.machid = mc.machid; ss.cpuid = 0; if (ioctl(fd, NVMM_IOC_VCPU_SETSTATE, &ss)) { perror("setstate"); return 1; } printf("setstate ok\n"); return 0; } |