X-Git-Url: https://rtime.felk.cvut.cz/gitweb/l4.git/blobdiff_plain/f4122e6e085938b6d216a9ec724b974a603f6992..983fe7c4ac262f56d38a143b1efab1e4afb77a52:/l4/pkg/examples/sys/vmtest/main.c diff --git a/l4/pkg/examples/sys/vmtest/main.c b/l4/pkg/examples/sys/vmtest/main.c index 8418c8bcb..881970070 100644 --- a/l4/pkg/examples/sys/vmtest/main.c +++ b/l4/pkg/examples/sys/vmtest/main.c @@ -14,6 +14,8 @@ #include #include +#include + #include #include #include @@ -24,419 +26,477 @@ #include #include +#include + #define STACKSIZE (8<<10) static char stack[STACKSIZE]; +static char hdl_stack[STACKSIZE]; static unsigned long idt[32 * 2] __attribute__((aligned(4096))); static unsigned long gdt[32 * 2] __attribute__((aligned(4096))); -static void init_vmcb(l4_vm_svm_vmcb_t *vmcb_s) -{ - - vmcb_s->control_area.np_enable = 1; - vmcb_s->control_area.guest_asid_tlb_ctl = 1; - - vmcb_s->state_save_area.es.selector = 0; - vmcb_s->state_save_area.es.attrib = 0; - vmcb_s->state_save_area.es.limit = 0; - vmcb_s->state_save_area.es.base = 0ULL; +void vm_resume(void); +void handle_vmexit(void); +l4_vcpu_state_t *vcpu; +l4_vm_svm_vmcb_t *vmcb_s; + +static void init_vmcb(l4_vm_svm_vmcb_t *vmcb_s) { + + vmcb_s->control_area.np_enable = 1; + vmcb_s->control_area.guest_asid_tlb_ctl = 1; + + vmcb_s->state_save_area.es.selector = 0; + vmcb_s->state_save_area.es.attrib = 0; + vmcb_s->state_save_area.es.limit = 0; + vmcb_s->state_save_area.es.base = 0ULL; + + // vmcb[256 + 0] = 0; // es; attrib sel + + vmcb_s->state_save_area.cs.selector = 0x8; + vmcb_s->state_save_area.cs.attrib = 0xc9b; + vmcb_s->state_save_area.cs.limit = 0xffffffff; + vmcb_s->state_save_area.cs.base = 0ULL; + + vmcb_s->state_save_area.ss.selector = 0x10; + vmcb_s->state_save_area.ss.attrib = 0xc93; + vmcb_s->state_save_area.ss.limit = 0xffffffff; + vmcb_s->state_save_area.ss.base = 0ULL; + + vmcb_s->state_save_area.ds.selector = 0x23; + vmcb_s->state_save_area.ds.attrib = 0xcf3; + vmcb_s->state_save_area.ds.limit = 0xffffffff; + vmcb_s->state_save_area.ds.base = 0ULL; + + vmcb_s->state_save_area.fs.selector = 0; + vmcb_s->state_save_area.fs.attrib = 0xcf3; + vmcb_s->state_save_area.fs.limit = 0xffffffff; + vmcb_s->state_save_area.fs.base = 0ULL; + + vmcb_s->state_save_area.gs.selector = 0; + vmcb_s->state_save_area.gs.attrib = 0xcf3; + vmcb_s->state_save_area.gs.limit = 0xffffffff; + vmcb_s->state_save_area.gs.base = 0ULL; + + vmcb_s->state_save_area.gdtr.selector = 0; + vmcb_s->state_save_area.gdtr.attrib = 0; + vmcb_s->state_save_area.gdtr.limit = 0x3f; + vmcb_s->state_save_area.gdtr.base = (unsigned long) gdt; + + vmcb_s->state_save_area.ldtr.selector = 0; + vmcb_s->state_save_area.ldtr.attrib = 0; + vmcb_s->state_save_area.ldtr.limit = 0; + vmcb_s->state_save_area.ldtr.base = 0; + + vmcb_s->state_save_area.idtr.selector = 0; + vmcb_s->state_save_area.idtr.attrib = 0; + vmcb_s->state_save_area.idtr.limit = 0xff; + vmcb_s->state_save_area.idtr.base = (unsigned long) idt; + + vmcb_s->state_save_area.tr.selector = 0x28; + vmcb_s->state_save_area.tr.attrib = 0x8b; + vmcb_s->state_save_area.tr.limit = 0x67; + vmcb_s->state_save_area.tr.base = 0; + + vmcb_s->state_save_area.g_pat = 0x7040600010406ULL; +} +static int check_svm(void) { + l4_umword_t ax, bx, cx, dx; -// vmcb[256 + 0] = 0; // es; attrib sel + if (!l4util_cpu_has_cpuid()) + return 1; - vmcb_s->state_save_area.cs.selector = 0x8; - vmcb_s->state_save_area.cs.attrib = 0xc9b; - vmcb_s->state_save_area.cs.limit = 0xffffffff; - vmcb_s->state_save_area.cs.base = 0ULL; + l4util_cpu_cpuid(0x80000001, &ax, &bx, &cx, &dx); - vmcb_s->state_save_area.ss.selector = 0x10; - vmcb_s->state_save_area.ss.attrib = 0xc93; - vmcb_s->state_save_area.ss.limit = 0xffffffff; - vmcb_s->state_save_area.ss.base = 0ULL; + if (!(cx & 4)) { + printf("CPU does not support SVM.\n"); + return 1; + } + l4util_cpu_cpuid(0x8000000a, &ax, &bx, &cx, &dx); - vmcb_s->state_save_area.ds.selector = 0x23; - vmcb_s->state_save_area.ds.attrib = 0xcf3; - vmcb_s->state_save_area.ds.limit = 0xffffffff; - vmcb_s->state_save_area.ds.base = 0ULL; + printf("SVM revision: %lx\n", ax & 0xf); + printf("Number of ASIDs: %lx\n", bx); - vmcb_s->state_save_area.fs.selector = 0; - vmcb_s->state_save_area.fs.attrib = 0xcf3; - vmcb_s->state_save_area.fs.limit = 0xffffffff; - vmcb_s->state_save_area.fs.base = 0ULL; + return 0; +} - vmcb_s->state_save_area.gs.selector = 0; - vmcb_s->state_save_area.gs.attrib = 0xcf3; - vmcb_s->state_save_area.gs.limit = 0xffffffff; - vmcb_s->state_save_area.gs.base = 0ULL; +static int check_svm_npt(void) { + l4_umword_t ax, bx, cx, dx; - vmcb_s->state_save_area.gdtr.selector = 0; - vmcb_s->state_save_area.gdtr.attrib = 0; - vmcb_s->state_save_area.gdtr.limit = 0x3f; - vmcb_s->state_save_area.gdtr.base = (unsigned long) gdt; + l4util_cpu_cpuid(0x8000000a, &ax, &bx, &cx, &dx); - vmcb_s->state_save_area.ldtr.selector = 0; - vmcb_s->state_save_area.ldtr.attrib = 0; - vmcb_s->state_save_area.ldtr.limit = 0; - vmcb_s->state_save_area.ldtr.base = 0; + printf("NPT available: %s\n", dx & 1 ? "yes" : "no"); - vmcb_s->state_save_area.idtr.selector = 0; - vmcb_s->state_save_area.idtr.attrib = 0; - vmcb_s->state_save_area.idtr.limit = 0xff; - vmcb_s->state_save_area.idtr.base = (unsigned long) idt; + return (!(dx & 1)); +} - vmcb_s->state_save_area.tr.selector = 0x28; - vmcb_s->state_save_area.tr.attrib = 0x8b; - vmcb_s->state_save_area.tr.limit = 0x67; - vmcb_s->state_save_area.tr.base = 0; +int vmexit = 0; + +static int cnt_triggered, cnt_received; + +static void handler(void) { + //if(vmexit){ + //vmexit = 0; + //handle_vmexit(); + //} else { + // exception and ipc handling here + cnt_received++; + printf("received interrupt %d | %d %d\n", (int)vcpu->i.label, + cnt_triggered, cnt_received); + //} + vm_resume(); +} - vmcb_s->state_save_area.g_pat = 0x7040600010406ULL; +void vm_resume(void) { + unsigned long long old_rip; + l4_msgtag_t tag; + +// if ((vmcb_s->state_save_area.rip >= marker)) { +// //printf("set tf for rip=%llx\n", vmcb_s->state_save_area.rip); +// vmcb_s->state_save_area.rflags |= 0x100; // set tf +// } + + vmcb_s->control_area.intercept_exceptions |= 0xa; // intercept #1 & #3 + vmcb_s->control_area.intercept_exceptions |= 0xffffffff; + vmcb_s->control_area.intercept_instruction1 |= 0x20; // intercept int1 + + //vmcb_s->control_area.exitcode = 0x100 << i; + vmcb_s->control_area.exitcode = 0; + + old_rip = vmcb_s->state_save_area.rip; + + tag = l4_thread_vcpu_resume_commit(L4_INVALID_CAP, + l4_thread_vcpu_resume_start()); + if (l4_error(tag)) + printf("vm-resume failed: %s (%ld)\n", l4sys_errtostr(l4_error(tag)), + l4_error(tag)); + + // if l4_thread_vcpu_resume_commit returns without error + // tell the handler that a vmexit occurred + vmexit = 1; + // and rewind the stack before we return into the handler + // simulating an upcall + handle_vmexit(); + vm_resume(); +#if 0 + asm volatile ( + "movl %0, %%esp\n" + "pushl %1\n" + "ret\n" + : : "r"(vcpu->entry_sp), "r"(handler) ); +#endif } -static int check_svm(void) -{ - l4_umword_t ax, bx, cx, dx; +void handle_vmexit(void) { + static unsigned int i = 0; + ++i; + printf("iteration=%d, exit code=%llx", i, + vmcb_s->control_area.exitcode); - if (!l4util_cpu_has_cpuid()) - return 1; + if (vmcb_s->control_area.exitcode == 0x43) + // int3 is treated as fault, not trap + vmcb_s->state_save_area.rip += 1; - l4util_cpu_cpuid(0x80000001, &ax, &bx, &cx, &dx); + if (vmcb_s->control_area.exitcode == 0x46) { +// if (vmcb_s->state_save_area.rip >= test_end) +// break; + vmcb_s->state_save_area.rip += 2; + } - if (!(cx & 4)) - { - printf("CPU does not support SVM.\n"); - return 1; + if (vmcb_s->control_area.exitcode == 0x400) { + printf("host-level page fault; error code=%llx, gpa=%llx\n", + vmcb_s->control_area.exitinfo1, vmcb_s->control_area.exitinfo2); } - l4util_cpu_cpuid(0x8000000a, &ax, &bx, &cx, &dx); + if (vmcb_s->control_area.exitcode == 0x4e) { + printf("page fault; error code=%llx, pfa=%llx\n", + vmcb_s->control_area.exitinfo1, vmcb_s->control_area.exitinfo2); + } - printf("SVM revision: %lx\n", ax & 0xf); - printf("Number of ASIDs: %lx\n", bx); + if (vmcb_s->control_area.exitcode == 0x81) { + printf("VMMCALL\n"); + vmcb_s->state_save_area.rip += 3; + } - return 0; + if (vmcb_s->control_area.exitcode == 0x4d) { + printf("cs=%08x attrib=%x, limit=%x, base=%llx\n", + vmcb_s->state_save_area.cs.selector, + vmcb_s->state_save_area.cs.attrib, + vmcb_s->state_save_area.cs.limit, + vmcb_s->state_save_area.cs.base); + printf("ss=%08x attrib=%x, limit=%x, base=%llx\n", + vmcb_s->state_save_area.ss.selector, + vmcb_s->state_save_area.ss.attrib, + vmcb_s->state_save_area.ss.limit, + vmcb_s->state_save_area.ss.base); + printf("np_enabled=%lld\n", vmcb_s->control_area.np_enable); + printf("cr0=%llx cr4=%llx\n", vmcb_s->state_save_area.cr0, + vmcb_s->state_save_area.cr4); + printf("interrupt_ctl=%llx\n", vmcb_s->control_area.interrupt_ctl); + printf("rip=%llx, rsp=%llx, cpl=%d\n", vmcb_s->state_save_area.rip, + vmcb_s->state_save_area.rsp, vmcb_s->state_save_area.cpl); + printf("exitinfo1=%llx\n", vmcb_s->control_area.exitinfo1); + } } -static int check_svm_npt(void) -{ - l4_umword_t ax, bx, cx, dx; - - l4util_cpu_cpuid(0x8000000a, &ax, &bx, &cx, &dx); - - printf("NPT available: %s\n", dx & 1 ? "yes" : "no"); - - return (!(dx & 1)); -} +static l4_vcpu_state_t *get_state_mem(l4_addr_t *extstate) { + static int done; + long r; + l4_msgtag_t tag; + static l4_addr_t ext_state; -static l4_vcpu_state_t *get_state_mem(l4_addr_t *extstate) -{ - static int done; - long r; - l4_msgtag_t tag; - static l4_vcpu_state_t *vcpu; - static l4_addr_t ext_state; - - if (done) - { - *extstate = ext_state; - return vcpu; + if (done) { + *extstate = ext_state; + return vcpu; } - if ((r = l4vcpu_ext_alloc(&vcpu, &ext_state, - L4_BASE_TASK_CAP, l4re_env()->rm))) - { - printf("Adding state mem failed: %ld\n", r); - exit(1); + if ((r = l4vcpu_ext_alloc(&vcpu, &ext_state, L4_BASE_TASK_CAP, + l4re_env()->rm))) { + printf("Adding state mem failed: %ld\n", r); + exit(1); } - vcpu->state = L4_VCPU_F_FPU_ENABLED; - vcpu->saved_state = L4_VCPU_F_USER_MODE | L4_VCPU_F_FPU_ENABLED; + vcpu->state = L4_VCPU_F_FPU_ENABLED; + vcpu->saved_state = L4_VCPU_F_USER_MODE | L4_VCPU_F_FPU_ENABLED | L4_VCPU_F_IRQ; + + vcpu->entry_ip = (l4_umword_t)handler; + l4_umword_t * stack = (l4_umword_t*)(hdl_stack + STACKSIZE); + --stack; + *stack = 0; + vcpu->entry_sp = (l4_umword_t)stack; + - tag = l4_thread_vcpu_control_ext(L4_INVALID_CAP, (l4_addr_t)vcpu); - if (l4_error(tag)) - { - printf("Could not enable ext vCPU\n"); - exit(1); + tag = l4_thread_vcpu_control_ext(L4_INVALID_CAP, (l4_addr_t) vcpu); + if (l4_error(tag)) { + printf("Could not enable ext vCPU\n"); + exit(1); } - done = 1; - *extstate = ext_state; + done = 1; + *extstate = ext_state; - return vcpu; + return vcpu; } -static void run_test(int np_available) -{ - l4_umword_t eflags; - l4_msgtag_t tag; - l4_cap_idx_t vm_task = l4re_util_cap_alloc(); - int i; - l4_umword_t ip, marker, test_end; - l4_addr_t vmcx; - l4_vcpu_state_t *vcpu = get_state_mem(&vmcx); - - printf("run test, np_available=%d\n", np_available); - - if (l4_is_invalid_cap(vm_task)) - { - printf("No more caps.\n"); - return; + +static void run_test(int np_available) { + l4_umword_t eflags; + l4_msgtag_t tag; + l4_cap_idx_t vm_task = l4re_util_cap_alloc(); +// int i; + l4_umword_t ip; //, marker, test_end; + l4_addr_t vmcx; + get_state_mem(&vmcx); + + printf("run test, np_available=%d\n", np_available); + + if (l4_is_invalid_cap(vm_task)) { + printf("No more caps.\n"); + return; } - tag = l4_factory_create_vm(l4re_env()->factory, vm_task); - if (l4_error(tag)) - { - printf("Failed to create new task\n"); - exit(1); + tag = l4_factory_create_vm(l4re_env()->factory, vm_task); + if (l4_error(tag)) { + printf("Failed to create new task\n"); + exit(1); } - l4_vm_svm_vmcb_t *vmcb_s = (l4_vm_svm_vmcb_t *)vmcx; - - vcpu->user_task = vm_task; - - vcpu->r.dx = 1; - vcpu->r.cx = 2; - vcpu->r.bx = 3; - vcpu->r.bp = 4; - vcpu->r.si = 5; - vcpu->r.di = 6; - - printf("clearing exit codes\n"); - - asm volatile(" jmp 1f; \n" - "2: nop \n" - " nop \n" - " ud2 \n" - " int3 \n" - "3: nop \n" - " nop \n" - " int3 \n" - //"3: nop \n" - //" int3 \n" - " nop \n" - " nop \n" - " movl %%eax, %%ecx \n" - " addl %%edx, %%ecx \n" - " vmmcall \n" - "4: \n" - " ud2 \n" - "1: movl $2b, %0 \n" - " movl $3b, %1 \n" - " movl $4b, %2 \n" - : "=r" (ip), "=r" (marker), "=r" (test_end)); - - - init_vmcb(vmcb_s); - - vmcb_s->state_save_area.cpl = 0; - vmcb_s->state_save_area.efer = 0x1000; // svme set - - vmcb_s->state_save_area.cr4 = 0x690; - vmcb_s->state_save_area.cr3 = 0; - // PG[31] = 0, WP[16] = 1, NE[5] = 1, ET[4] = 1 - // TS[3] = 1, MP[1] = 1, PE[0] = 1 - vmcb_s->state_save_area.cr0 = 0x1003b; - - if (!np_available) - { - vmcb_s->state_save_area.cr0 |= 0x80000000; // PG = 1 - vmcb_s->control_area.np_enable &= ~1; + vmcb_s = (l4_vm_svm_vmcb_t *) vmcx; + + vcpu->user_task = vm_task; + + vcpu->r.dx = 1; + vcpu->r.cx = 2; + vcpu->r.bx = 3; + vcpu->r.bp = 4; + vcpu->r.si = 5; + vcpu->r.di = 6; + + printf("clearing exit codes\n"); + + // asm volatile(" jmp 1f; \n" + // "2: nop \n" + // " nop \n" + // " ud2 \n" + // " int3 \n" + // "3: nop \n" + // " nop \n" + // " int3 \n" + // //"3: nop \n" + // //" int3 \n" + // " nop \n" + // " nop \n" + // " movl %%eax, %%ecx \n" + // " addl %%edx, %%ecx \n" + // " vmmcall \n" + // "4: \n" + // " ud2 \n" + // "1: movl $2b, %0 \n" + // " movl $3b, %1 \n" + // " movl $4b, %2 \n" + // : "=r" (ip), "=r" (marker), "=r" (test_end)); + + asm volatile(" jmp 1f; \n" + "2: nop \n" + " nop \n" + " nop \n" + " jmp 2b \n" + "1: movl $2b, %0 \n" + : "=r" (ip)); + + init_vmcb(vmcb_s); + + vmcb_s->state_save_area.cpl = 0; + vmcb_s->state_save_area.efer = 0x1000; // svme set + + vmcb_s->state_save_area.cr4 = 0x690; + vmcb_s->state_save_area.cr3 = 0; + // PG[31] = 0, WP[16] = 1, NE[5] = 1, ET[4] = 1 + // TS[3] = 1, MP[1] = 1, PE[0] = 1 + vmcb_s->state_save_area.cr0 = 0x1003b; + + if (!np_available) { + vmcb_s->state_save_area.cr0 |= 0x80000000; // PG = 1 + vmcb_s->control_area.np_enable &= ~1; } - vmcb_s->state_save_area.dr7 = 0x300; - vmcb_s->state_save_area.dr6 = 0; + vmcb_s->state_save_area.dr7 = 0x300; + vmcb_s->state_save_area.dr6 = 0; - asm volatile("pushf \n" - "popl %0 \n" - : "=r" (eflags)); + asm volatile("pushf \n" + "popl %0 \n" + : "=r" (eflags)); - vmcb_s->state_save_area.rflags = eflags; - vmcb_s->state_save_area.rip = ip; - vmcb_s->state_save_area.rsp = (l4_umword_t)stack + STACKSIZE; + vmcb_s->state_save_area.rflags = eflags; + vmcb_s->state_save_area.rip = ip; + vmcb_s->state_save_area.rsp = (l4_umword_t) stack + STACKSIZE; - unsigned ofs; - for (ofs = 0; ofs < STACKSIZE; ofs += L4_PAGESIZE) - { - stack[ofs] = 0; - unsigned char c = stack[ofs]; - unsigned dummy; + unsigned ofs; + for (ofs = 0; ofs < STACKSIZE; ofs += L4_PAGESIZE) { + stack[ofs] = 0; + unsigned char c = stack[ofs]; + unsigned dummy; - asm volatile("nop" : "=a"(dummy) : "0" (c)); + asm volatile("nop" : "=a"(dummy) : "0" (c)); - tag = l4_task_map(vm_task, L4RE_THIS_TASK_CAP, - l4_fpage((((l4_umword_t)(stack)) + ofs) & L4_PAGEMASK, - L4_PAGESHIFT, L4_FPAGE_RW), - l4_map_control(((l4_umword_t)stack) + ofs, 0, - L4_MAP_ITEM_MAP)); - printf("msgtag raw=%08x, ofs=%08x\n", (unsigned) tag.raw, ofs); + tag = l4_task_map(vm_task, L4RE_THIS_TASK_CAP, l4_fpage( + (((l4_umword_t)(stack)) + ofs) & L4_PAGEMASK, L4_PAGESHIFT, + L4_FPAGE_RW), l4_map_control(((l4_umword_t) stack) + ofs, 0, + L4_MAP_ITEM_MAP)); + printf("msgtag raw=%08x, ofs=%08x\n", (unsigned) tag.raw, ofs); } - tag = l4_task_map(vm_task, L4RE_THIS_TASK_CAP, - l4_fpage(ip & L4_PAGEMASK, L4_PAGESHIFT, L4_FPAGE_RW), - l4_map_control(ip, 0, L4_MAP_ITEM_MAP)); - - printf("msgtag raw=%08lx, ip=%08lx\n", tag.raw, ip); - - idt[26] = 0x80000; // #13 general protection fault - idt[27] = 0x8e00; + tag = l4_task_map(vm_task, L4RE_THIS_TASK_CAP, l4_fpage(ip & L4_PAGEMASK, + L4_PAGESHIFT, L4_FPAGE_RW), l4_map_control(ip, 0, L4_MAP_ITEM_MAP)); - idt[28] = 0x80000; // #14 page fault - idt[29] = 0x8e00; + printf("msgtag raw=%08lx, ip=%08lx\n", tag.raw, ip); - // code segment 0x08 - gdt[2] = 0xffff; - gdt[3] = 0xcf9b00; + idt[26] = 0x80000; // #13 general protection fault + idt[27] = 0x8e00; - // stack segment 0x10 - gdt[4] = 0xffff; - gdt[5] = 0xcf9300; + idt[28] = 0x80000; // #14 page fault + idt[29] = 0x8e00; - // data segment 0x20 - gdt[8] = 0xffff; - gdt[9] = 0xcff300; + // code segment 0x08 + gdt[2] = 0xffff; + gdt[3] = 0xcf9b00; - // tss 0x28 - gdt[10] = 0x67; - gdt[11] = 0x8b00; + // stack segment 0x10 + gdt[4] = 0xffff; + gdt[5] = 0xcf9300; - unsigned idt0 = (unsigned) idt; - tag = l4_task_map(vm_task, L4RE_THIS_TASK_CAP, - l4_fpage(idt0 & L4_PAGEMASK, L4_PAGESHIFT, L4_FPAGE_RW), - l4_map_control(idt0, 0, L4_MAP_ITEM_MAP)); - printf("msgtag raw=%08x, idt=%08x\n", (unsigned) tag.raw, idt0); + // data segment 0x20 + gdt[8] = 0xffff; + gdt[9] = 0xcff300; - unsigned gdt0 = (unsigned) gdt; - tag = l4_task_map(vm_task, L4RE_THIS_TASK_CAP, - l4_fpage(gdt0 & L4_PAGEMASK, L4_PAGESHIFT, L4_FPAGE_RW), - l4_map_control(gdt0, 0, L4_MAP_ITEM_MAP)); - printf("msgtag raw=%08x, gdt=%08x\n", (unsigned) tag.raw, gdt0); + // tss 0x28 + gdt[10] = 0x67; + gdt[11] = 0x8b00; + unsigned idt0 = (unsigned) idt; + tag = l4_task_map(vm_task, L4RE_THIS_TASK_CAP, l4_fpage(idt0 & L4_PAGEMASK, + L4_PAGESHIFT, L4_FPAGE_RW), + l4_map_control(idt0, 0, L4_MAP_ITEM_MAP)); + printf("msgtag raw=%08x, idt=%08x\n", (unsigned) tag.raw, idt0); -// printf("sizes vmcb=%x, control=%x, state=%x\n", -// sizeof(*vmcb_s), -// sizeof(vmcb_s->control_area), sizeof(vmcb_s->sitate_save_area)); + unsigned gdt0 = (unsigned) gdt; + tag = l4_task_map(vm_task, L4RE_THIS_TASK_CAP, l4_fpage(gdt0 & L4_PAGEMASK, + L4_PAGESHIFT, L4_FPAGE_RW), + l4_map_control(gdt0, 0, L4_MAP_ITEM_MAP)); + printf("msgtag raw=%08x, gdt=%08x\n", (unsigned) tag.raw, gdt0); - printf("start rip=%llx\n", vmcb_s->state_save_area.rip); + // printf("sizes vmcb=%x, control=%x, state=%x\n", + // sizeof(*vmcb_s), + // sizeof(vmcb_s->control_area), sizeof(vmcb_s->sitate_save_area)); - vmcb_s->state_save_area.rax = 8; + printf("start rip=%llx\n", vmcb_s->state_save_area.rip); - for (i = 0; i < 16; i++) - { - unsigned long long old_rip; + vmcb_s->state_save_area.rax = 8; - if ((vmcb_s->state_save_area.rip >= marker)) - { - //printf("set tf for rip=%llx\n", vmcb_s->state_save_area.rip); - vmcb_s->state_save_area.rflags |= 0x100; // set tf - } + vm_resume(); - vmcb_s->control_area.intercept_exceptions |= 0xa; // intercept #1 & #3 - vmcb_s->control_area.intercept_exceptions |= 0xffffffff; - vmcb_s->control_area.intercept_instruction1 |= 0x20; // intercept int1 - - //vmcb_s->control_area.exitcode = 0x100 << i; - vmcb_s->control_area.exitcode = 0; +} - old_rip = vmcb_s->state_save_area.rip; +// printf("rip=%08llx, rax=%llx, edx=%lx, ecx=%lx\n", +// vmcb_s->state_save_area.rip, +// vmcb_s->state_save_area.rax, +// vcpu->r.dx, vcpu->r.cx); +// +// printf("run vm stop, status=%s\n", vcpu->r.cx == 9 ? "success" : "failure"); +// +// l4_task_unmap(L4RE_THIS_TASK_CAP, +// l4_obj_fpage(vm_task, 0, L4_FPAGE_RWX), +// L4_FP_ALL_SPACES); +//} + +#include +l4_cap_idx_t timer_irq; +void * timer_thread(void * ); +void * timer_thread(void * data) { + (void)data; + l4_sleep(1000); + fiasco_tbuf_log("FIRST"); + while(1){ + l4_sleep(200); + fiasco_tbuf_log("Trig"); + printf("trigger\n"); + cnt_triggered++; + l4_irq_trigger(timer_irq); + } +} - tag = l4_thread_vcpu_resume_commit(L4_INVALID_CAP, - l4_thread_vcpu_resume_start()); - if (l4_error(tag)) - printf("vm-resume failed: %s (%ld)\n", - l4sys_errtostr(l4_error(tag)), l4_error(tag)); +#include - printf("iteration=%d, exit code=%llx, rip=%llx -> %llx\n", - i, vmcb_s->control_area.exitcode, - old_rip, vmcb_s->state_save_area.rip); +int main(void) +{ + timer_irq = l4re_util_cap_alloc(); + if (l4_error(l4_factory_create_irq(l4re_env()->factory, timer_irq))) + printf("irq creation failed\n"); + if (l4_error(l4_irq_attach(timer_irq, 0x120, L4_INVALID_CAP))) + printf("irq attach failed\n"); - if (vmcb_s->control_area.exitcode == 0x43) - // int3 is treated as fault, not trap - vmcb_s->state_save_area.rip += 1; + printf("VM testing\n"); - if (vmcb_s->control_area.exitcode == 0x46) - { - if (vmcb_s->state_save_area.rip >= test_end) - break; - vmcb_s->state_save_area.rip += 2; - } - - if (vmcb_s->control_area.exitcode == 0x400) - { - printf("host-level page fault; error code=%llx, gpa=%llx\n", - vmcb_s->control_area.exitinfo1, - vmcb_s->control_area.exitinfo2); - } - - if (vmcb_s->control_area.exitcode == 0x4e) - { - printf("page fault; error code=%llx, pfa=%llx\n", - vmcb_s->control_area.exitinfo1, - vmcb_s->control_area.exitinfo2); - } - - if (vmcb_s->control_area.exitcode == 0x81) - { - printf("VMMCALL\n"); - vmcb_s->state_save_area.rip += 3; - } - - if (vmcb_s->control_area.exitcode == 0x4d) - { - printf("cs=%08x attrib=%x, limit=%x, base=%llx\n", - vmcb_s->state_save_area.cs.selector, - vmcb_s->state_save_area.cs.attrib, - vmcb_s->state_save_area.cs.limit, - vmcb_s->state_save_area.cs.base); - printf("ss=%08x attrib=%x, limit=%x, base=%llx\n", - vmcb_s->state_save_area.ss.selector, - vmcb_s->state_save_area.ss.attrib, - vmcb_s->state_save_area.ss.limit, - vmcb_s->state_save_area.ss.base); - printf("np_enabled=%lld\n", - vmcb_s->control_area.np_enable); - printf("cr0=%llx cr4=%llx\n", - vmcb_s->state_save_area.cr0, - vmcb_s->state_save_area.cr4); - printf("interrupt_ctl=%llx\n", - vmcb_s->control_area.interrupt_ctl); - printf("rip=%llx, rsp=%llx, cpl=%d\n", - vmcb_s->state_save_area.rip, - vmcb_s->state_save_area.rsp, - vmcb_s->state_save_area.cpl); - printf("exitinfo1=%llx\n", vmcb_s->control_area.exitinfo1); - break; - } - } - - printf("rip=%08llx, rax=%llx, edx=%lx, ecx=%lx\n", - vmcb_s->state_save_area.rip, - vmcb_s->state_save_area.rax, - vcpu->r.dx, vcpu->r.cx); - - printf("run vm stop, status=%s\n", vcpu->r.cx == 9 ? "success" : "failure"); - - l4_task_unmap(L4RE_THIS_TASK_CAP, - l4_obj_fpage(vm_task, 0, L4_FPAGE_RWX), - L4_FP_ALL_SPACES); -} + if (check_svm()) + { + printf("No SVM CPU. Bye.\n"); + return 1; + } -int main(void) -{ - printf("VM testing\n"); + l4_touch_rw(stack, sizeof(stack)); + l4_touch_rw(hdl_stack, sizeof(hdl_stack)); - if (check_svm()) - { - printf("No SVM CPU. Bye.\n"); - return 1; - } + pthread_t pthread_timer_thread; - l4_touch_rw(stack, sizeof(stack)); + pthread_create(&pthread_timer_thread, NULL, timer_thread, NULL); - run_test(0); + run_test(0); - if (!check_svm_npt()) - run_test(1); + if (!check_svm_npt()) + run_test(1); - return 0; + return 0; }