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>
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
_______________________________________________
freebsd-virtualization@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-virtualization
To unsubscribe, send any mail to 
"freebsd-virtualization-unsubscr...@freebsd.org"

Reply via email to