Date: Tue, 12 Aug 2014 11:24:07 +0200 From: Martin Steegmanns <martin@unix-users.de> To: freebsd-virtualization@freebsd.org Subject: Problem with vmexit on mtrap Message-ID: <20140812092407.GC11403@mail.demonism.de>
next in thread | raw e-mail | index | archive | help
--zYM0uCDKw75PZbzx Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hello list! I modified bhyve to toggle the MTF bit on an UD2 instruction. In a guest system, a program does: __asm__ __volatile__( "UD2" "NOP" "xor %rax,%rax" "NOP" "UD2" ); On the first UD2, MTF bit is correctly set, but the second UD2 is never reached (waited some hours). If I manually reset the MTF bit via bhyvectl --setcap, guest executione reaches the second UD2 instruction. A diff of my modifications is attached to this mail. Am I missing something on vmenter that makes the guest loop forever? Regards, Martin <snippet of ktr dump> /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1074 vm vm1[0]: unhandled mtf vmexit at 0xffffffff804dde70 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1063 vm vm1[0]: Resume execution at 0xffffffff804dde41 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:2652 vm vm1[0]: returning from vmx_run: exitcode 6 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1074 vm vm1[0]: unhandled mtf vmexit at 0xffffffff804dde41 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1063 vm vm1[0]: Resume execution at 0xffffffff804dde39 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:2652 vm vm1[0]: returning from vmx_run: exitcode 6 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1074 vm vm1[0]: unhandled mtf vmexit at 0xffffffff804dde39 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1063 vm vm1[0]: Resume execution at 0xffffffff804dde30 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:2652 vm vm1[0]: returning from vmx_run: exitcode 6 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1074 vm vm1[0]: unhandled mtf vmexit at 0xffffffff804dde30 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1063 vm vm1[0]: Resume execution at 0xffffffff804dde27 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:2652 vm vm1[0]: returning from vmx_run: exitcode 6 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1074 vm vm1[0]: unhandled mtf vmexit at 0xffffffff804dde27 /usr/src/sys/modules/vmm/../../amd64/vmm/intel/vmx.c:1063 vm vm1[0]: Resume execution at 0xffffffff804dde1f </snippet> --zYM0uCDKw75PZbzx Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="mtrap_r269497.diff" Index: sys/amd64/vmm/intel/vmcs.c =================================================================== --- sys/amd64/vmm/intel/vmcs.c (revision 269497) +++ sys/amd64/vmm/intel/vmcs.c (working copy) @@ -418,7 +418,7 @@ goto done; /* exception bitmap */ - exc_bitmap = 1 << IDT_MC; + exc_bitmap = 1 << IDT_MC | 1 << IDT_UD; if ((error = vmwrite(VMCS_EXCEPTION_BITMAP, exc_bitmap)) != 0) goto done; Index: sys/amd64/vmm/intel/vmx.c =================================================================== --- sys/amd64/vmm/intel/vmx.c (revision 269497) +++ sys/amd64/vmm/intel/vmx.c (working copy) @@ -1024,6 +1024,20 @@ } static int +vmx_handle_exception(struct vmx *vmx, int vcpu, struct vm_exit *vme) +{ + + return (HANDLED); +} + +static int +vmx_handle_ud_exception(struct vmx *vmx, int vcpu, struct vm_exit *vme) +{ + + return (UNHANDLED); +} + +static int vmx_handle_cpuid(struct vm *vm, int vcpu, struct vmxctx *vmxctx) { int handled, func; @@ -2256,6 +2270,8 @@ break; case EXIT_REASON_MTF: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_MTRAP, 1); + vmexit_inst_emul(vmexit, vmcs_gpa(), vmcs_gla()); + vmexit->inst_length = vmexit_instruction_length(); vmexit->exitcode = VM_EXITCODE_MTRAP; break; case EXIT_REASON_PAUSE: @@ -2334,6 +2350,14 @@ KASSERT((intr_info & VMCS_INTR_VALID) != 0, ("VM exit interruption info invalid: %#x", intr_info)); + if (intr_info & IDT_UD) { + vmexit->exitcode = VM_EXITCODE_UD; + handled = vmx_handle_ud_exception(vmx, vcpu, vmexit); + } else { + vmexit->exitcode = VM_EXITCODE_EXCEPTION; + handled = vmx_handle_exception(vmx, vcpu, vmexit); + } + /* * If Virtual NMIs control is 1 and the VM-exit is due to a * fault encountered during the execution of IRET then we must Index: sys/amd64/vmm/vmm.c =================================================================== --- sys/amd64/vmm/vmm.c (revision 269497) +++ sys/amd64/vmm/vmm.c (working copy) @@ -1153,6 +1153,14 @@ } static int +vm_handle_mtf(struct vm *vm, int vcpuid, bool *retu) +{ + *retu = true; + + return (0); +} + +static int vm_handle_paging(struct vm *vm, int vcpuid, bool *retu) { int rv, ftype; @@ -1380,6 +1388,7 @@ bool retu, intr_disabled; pmap_t pmap; void *rptr, *sptr; + int val; vcpuid = vmrun->cpuid; @@ -1441,6 +1450,9 @@ intr_disabled = ((vme->u.hlt.rflags & PSL_I) == 0); error = vm_handle_hlt(vm, vcpuid, intr_disabled, &retu); break; + case VM_EXITCODE_MTRAP: + error = vm_handle_mtf(vm, vcpuid, &retu); + break; case VM_EXITCODE_PAGING: error = vm_handle_paging(vm, vcpuid, &retu); break; @@ -1451,6 +1463,12 @@ case VM_EXITCODE_INOUT_STR: error = vm_handle_inout(vm, vcpuid, vme, &retu); break; + case VM_EXITCODE_UD: + val = 1; + VMGETCAP(vm->cookie, vcpuid, VM_CAP_MTRAP_EXIT, &val); + val = (val == 1)? 0 : 1; + VMSETCAP(vm->cookie, vcpuid, VM_CAP_MTRAP_EXIT, val); + break; default: retu = true; /* handled in userland */ break; Index: sys/modules/vmm/Makefile =================================================================== --- sys/modules/vmm/Makefile (revision 269497) +++ sys/modules/vmm/Makefile (working copy) @@ -4,7 +4,7 @@ SRCS= opt_acpi.h opt_ddb.h device_if.h bus_if.h pci_if.h -CFLAGS+= -DVMM_KEEP_STATS -DSMP +CFLAGS+= -DVMM_KEEP_STATS -DSMP -DKTR CFLAGS+= -I${.CURDIR}/../../amd64/vmm CFLAGS+= -I${.CURDIR}/../../amd64/vmm/io CFLAGS+= -I${.CURDIR}/../../amd64/vmm/intel --zYM0uCDKw75PZbzx--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140812092407.GC11403>