And what about this version: static int vmx_run() { u32 ret = 0; asm volatile( "mov %%rsp, %%rsi\n\t" "mov %2, %%edi\n\t" "call vmcs_write\n\t" "0: " LOAD_GPR_C "cmpl $0, %1\n\t" "jne 1f\n\t" "vmlaunch;seta %1\n\t" /* vmlaunch error, return VMX_TEST_LAUNCH_ERR */ "movl %3, %0\n\t" SAVE_GPR_C "jmp 2f\n\t" "1: " "vmresume;seta %1\n\t" /* vmresume error, return VMX_TEST_RESUME_ERR */ "movl %4, %0\n\t" SAVE_GPR_C "jmp 2f\n\t" "vmx_return:\n\t" SAVE_GPR_C "call exit_handler\n\t" /* set launched = 1 */ "movl $0x1, %1\n\t" /* jump to resume when VMX_TEST_RESUME */ "cmp %5, %%eax\n\t" "je 0b\n\t" "mov %%eax, %0\n\t" "2: " : "=m"(ret), "=m"(launched) : "i"(HOST_RSP), "i"(VMX_TEST_LAUNCH_ERR), "i"(VMX_TEST_RESUME_ERR), "i"(VMX_TEST_RESUME) : "rax", "rbx", "rdi", "rsi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "memory", "cc" ); switch (ret) { case VMX_TEST_VMEXIT: launched = 0; return 0; case VMX_TEST_LAUNCH_ERR: printf("%s : vmlaunch failed.\n", __func__); if (launched != 0) printf("\tvmlaunch set flags error\n"); report("test vmlaunch", 0); break; case VMX_TEST_RESUME_ERR: printf("%s : vmresume failed.\n", __func__); if (launched != 0) printf("\tvmlaunch set flags error\n"); report("test vmresume", 0); break; default: launched = 0; printf("%s : unhandled ret from exit_handler, ret=%d.\n", __func__, ret); break; } return 1; } On Wed, Jul 24, 2013 at 6:24 PM, Jan Kiszka <jan.kiszka@xxxxxx> wrote: > On 2013-07-24 12:16, Arthur Chunqi Li wrote: >> On Wed, Jul 24, 2013 at 6:03 PM, Jan Kiszka <jan.kiszka@xxxxxx> wrote: >>> On 2013-07-24 11:56, Arthur Chunqi Li wrote: >>>> So what about this one. I merged all the exit reason to "ret" and >>>> remove the flag detection after vmlaunch/vmresume (because I think >>>> this detection is useless). Currently we support only one guest, so >>>> variant "launched" is located in vmx_run(). If we want to support >>>> multiple guest, we could move it to some structures (e.g. >>>> environment_ctxt). Now I just put it here. >>>> >>>> static int vmx_run() >>>> { >>>> u32 ret = 0; >>>> bool launched = 0; >>>> >>>> asm volatile( >>>> "mov %%rsp, %%rsi\n\t" >>>> "mov %2, %%edi\n\t" >>>> "call vmcs_write\n\t" >>>> >>>> "0: " >>>> LOAD_GPR_C >>>> "cmp $0, %1\n\t" >>>> "jne 1f\n\t" >>>> "vmlaunch\n\t" >>>> SAVE_GPR_C >>>> /* vmlaunch error, return VMX_TEST_LAUNCH_ERR */ >>>> "mov %3, %0\n\t" >>>> "jmp 2f\n\t" >>>> "1: " >>>> "vmresume\n\t" >>>> SAVE_GPR_C >>>> /* vmresume error, return VMX_TEST_RESUME_ERR */ >>>> "mov %4, %0\n\t" >>>> "jmp 2f\n\t" >>> >>> Where do you store the flags now? You may want to differentiate / test >>> if ZF of CF is set. >> I store the flags as a global variant. You mean I need to detect ZF/CF >> after vmlaunch/vmresume? > > Yes - if you want to check correct emulation of those instructions > completely. > > Jan > > -- Arthur Chunqi Li Department of Computer Science School of EECS Peking University Beijing, China -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html