Author: tychon
Date: Fri Apr 13 17:23:05 2018
New Revision: 332479
URL: https://svnweb.freebsd.org/changeset/base/332479

Log:
  Add SDT probes to vmexit on Intel.
  
  Submitted by: domagoj.stolfa_gmail.com
  Reviewed by:  grehan, tychon
  Sponsored by: DARPA/AFRL
  Differential Revision:        https://reviews.freebsd.org/D14656

Modified:
  head/sys/amd64/include/vmm.h
  head/sys/amd64/vmm/intel/vmx.c
  head/sys/amd64/vmm/vmm.c

Modified: head/sys/amd64/include/vmm.h
==============================================================================
--- head/sys/amd64/include/vmm.h        Fri Apr 13 16:54:49 2018        
(r332478)
+++ head/sys/amd64/include/vmm.h        Fri Apr 13 17:23:05 2018        
(r332479)
@@ -31,7 +31,12 @@
 #ifndef _VMM_H_
 #define        _VMM_H_
 
+#include <sys/sdt.h>
 #include <x86/segments.h>
+
+#ifdef _KERNEL
+SDT_PROVIDER_DECLARE(vmm);
+#endif
 
 enum vm_suspend_how {
        VM_SUSPEND_NONE,

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c      Fri Apr 13 16:54:49 2018        
(r332478)
+++ head/sys/amd64/vmm/intel/vmx.c      Fri Apr 13 17:23:05 2018        
(r332479)
@@ -188,6 +188,82 @@ SYSCTL_UINT(_hw_vmm_vmx, OID_AUTO, vpid_alloc_failed, 
            &vpid_alloc_failed, 0, NULL);
 
 /*
+ * The definitions of SDT probes for VMX.
+ */
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, entry,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE4(vmm, vmx, exit, taskswitch,
+    "struct vmx *", "int", "struct vm_exit *", "struct vm_task_switch *");
+
+SDT_PROBE_DEFINE4(vmm, vmx, exit, craccess,
+    "struct vmx *", "int", "struct vm_exit *", "uint64_t");
+
+SDT_PROBE_DEFINE4(vmm, vmx, exit, rdmsr,
+    "struct vmx *", "int", "struct vm_exit *", "uint32_t");
+
+SDT_PROBE_DEFINE5(vmm, vmx, exit, wrmsr,
+    "struct vmx *", "int", "struct vm_exit *", "uint32_t", "uint64_t");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, halt,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, mtrap,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, pause,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, intrwindow,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE4(vmm, vmx, exit, interrupt,
+    "struct vmx *", "int", "struct vm_exit *", "uint32_t");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, nmiwindow,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, inout,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, cpuid,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE5(vmm, vmx, exit, exception,
+    "struct vmx *", "int", "struct vm_exit *", "uint32_t", "int");
+
+SDT_PROBE_DEFINE5(vmm, vmx, exit, nestedfault,
+    "struct vmx *", "int", "struct vm_exit *", "uint64_t", "uint64_t");
+
+SDT_PROBE_DEFINE4(vmm, vmx, exit, mmiofault,
+    "struct vmx *", "int", "struct vm_exit *", "uint64_t");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, eoi,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, apicaccess,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE4(vmm, vmx, exit, apicwrite,
+    "struct vmx *", "int", "struct vm_exit *", "struct vlapic *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, xsetbv,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, monitor,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE3(vmm, vmx, exit, mwait,
+    "struct vmx *", "int", "struct vm_exit *");
+
+SDT_PROBE_DEFINE4(vmm, vmx, exit, unknown,
+    "struct vmx *", "int", "struct vm_exit *", "uint32_t");
+
+SDT_PROBE_DEFINE4(vmm, vmx, exit, return,
+    "struct vmx *", "int", "struct vm_exit *", "int");
+
+/*
  * Use the last page below 4GB as the APIC access address. This address is
  * occupied by the boot firmware so it is guaranteed that it will not conflict
  * with a page in system memory.
@@ -2118,6 +2194,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
        vmexit->exitcode = VM_EXITCODE_BOGUS;
 
        vmm_stat_incr(vmx->vm, vcpu, VMEXIT_COUNT, 1);
+       SDT_PROBE3(vmm, vmx, exit, entry, vmx, vcpu, vmexit);
 
        /*
         * VM-entry failures during or after loading guest state.
@@ -2220,6 +2297,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                        }
                }
                vmexit->exitcode = VM_EXITCODE_TASK_SWITCH;
+               SDT_PROBE4(vmm, vmx, exit, taskswitch, vmx, vcpu, vmexit, ts);
                VCPU_CTR4(vmx->vm, vcpu, "task switch reason %d, tss 0x%04x, "
                    "%s errcode 0x%016lx", ts->reason, ts->tsssel,
                    ts->ext ? "external" : "internal",
@@ -2227,6 +2305,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                break;
        case EXIT_REASON_CR_ACCESS:
                vmm_stat_incr(vmx->vm, vcpu, VMEXIT_CR_ACCESS, 1);
+               SDT_PROBE4(vmm, vmx, exit, craccess, vmx, vcpu, vmexit, qual);
                switch (qual & 0xf) {
                case 0:
                        handled = vmx_emulate_cr0_access(vmx, vcpu, qual);
@@ -2244,6 +2323,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                retu = false;
                ecx = vmxctx->guest_rcx;
                VCPU_CTR1(vmx->vm, vcpu, "rdmsr 0x%08x", ecx);
+               SDT_PROBE4(vmm, vmx, exit, rdmsr, vmx, vcpu, vmexit, ecx);
                error = emulate_rdmsr(vmx, vcpu, ecx, &retu);
                if (error) {
                        vmexit->exitcode = VM_EXITCODE_RDMSR;
@@ -2264,6 +2344,8 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                edx = vmxctx->guest_rdx;
                VCPU_CTR2(vmx->vm, vcpu, "wrmsr 0x%08x value 0x%016lx",
                    ecx, (uint64_t)edx << 32 | eax);
+               SDT_PROBE5(vmm, vmx, exit, wrmsr, vmx, vmexit, vcpu, ecx,
+                   (uint64_t)edx << 32 | eax);
                error = emulate_wrmsr(vmx, vcpu, ecx,
                    (uint64_t)edx << 32 | eax, &retu);
                if (error) {
@@ -2280,6 +2362,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                break;
        case EXIT_REASON_HLT:
                vmm_stat_incr(vmx->vm, vcpu, VMEXIT_HLT, 1);
+               SDT_PROBE3(vmm, vmx, exit, halt, vmx, vcpu, vmexit);
                vmexit->exitcode = VM_EXITCODE_HLT;
                vmexit->u.hlt.rflags = vmcs_read(VMCS_GUEST_RFLAGS);
                if (virtual_interrupt_delivery)
@@ -2290,15 +2373,18 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                break;
        case EXIT_REASON_MTF:
                vmm_stat_incr(vmx->vm, vcpu, VMEXIT_MTRAP, 1);
+               SDT_PROBE3(vmm, vmx, exit, mtrap, vmx, vcpu, vmexit);
                vmexit->exitcode = VM_EXITCODE_MTRAP;
                vmexit->inst_length = 0;
                break;
        case EXIT_REASON_PAUSE:
                vmm_stat_incr(vmx->vm, vcpu, VMEXIT_PAUSE, 1);
+               SDT_PROBE3(vmm, vmx, exit, pause, vmx, vcpu, vmexit);
                vmexit->exitcode = VM_EXITCODE_PAUSE;
                break;
        case EXIT_REASON_INTR_WINDOW:
                vmm_stat_incr(vmx->vm, vcpu, VMEXIT_INTR_WINDOW, 1);
+               SDT_PROBE3(vmm, vmx, exit, intrwindow, vmx, vcpu, vmexit);
                vmx_clear_int_window_exiting(vmx, vcpu);
                return (1);
        case EXIT_REASON_EXT_INTR:
@@ -2312,6 +2398,8 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                 * this virtual interrupt during the subsequent VM enter.
                 */
                intr_info = vmcs_read(VMCS_EXIT_INTR_INFO);
+               SDT_PROBE4(vmm, vmx, exit, interrupt,
+                   vmx, vcpu, vmexit, intr_info);
 
                /*
                 * XXX: Ignore this exit if VMCS_INTR_VALID is not set.
@@ -2331,6 +2419,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EXTINT, 1);
                return (1);
        case EXIT_REASON_NMI_WINDOW:
+               SDT_PROBE3(vmm, vmx, exit, nmiwindow, vmx, vcpu, vmexit);
                /* Exit to allow the pending virtual NMI to be injected */
                if (vm_nmi_pending(vmx->vm, vcpu))
                        vmx_inject_nmi(vmx, vcpu);
@@ -2358,9 +2447,11 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                        vis->addrsize = inout_str_addrsize(inst_info);
                        inout_str_seginfo(vmx, vcpu, inst_info, in, vis);
                }
+               SDT_PROBE3(vmm, vmx, exit, inout, vmx, vcpu, vmexit);
                break;
        case EXIT_REASON_CPUID:
                vmm_stat_incr(vmx->vm, vcpu, VMEXIT_CPUID, 1);
+               SDT_PROBE3(vmm, vmx, exit, cpuid, vmx, vcpu, vmexit);
                handled = vmx_handle_cpuid(vmx->vm, vcpu, vmxctx);
                break;
        case EXIT_REASON_EXCEPTION:
@@ -2425,6 +2516,8 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                }
                VCPU_CTR2(vmx->vm, vcpu, "Reflecting exception %d/%#x into "
                    "the guest", intr_vec, errcode);
+               SDT_PROBE5(vmm, vmx, exit, exception,
+                   vmx, vcpu, vmexit, intr_vec, errcode);
                error = vm_inject_exception(vmx->vm, vcpu, intr_vec,
                    errcode_valid, errcode, 0);
                KASSERT(error == 0, ("%s: vm_inject_exception error %d",
@@ -2445,9 +2538,13 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                        vmexit->u.paging.gpa = gpa;
                        vmexit->u.paging.fault_type = ept_fault_type(qual);
                        vmm_stat_incr(vmx->vm, vcpu, VMEXIT_NESTED_FAULT, 1);
+                       SDT_PROBE5(vmm, vmx, exit, nestedfault,
+                           vmx, vcpu, vmexit, gpa, qual);
                } else if (ept_emulation_fault(qual)) {
                        vmexit_inst_emul(vmexit, gpa, vmcs_gla());
                        vmm_stat_incr(vmx->vm, vcpu, VMEXIT_INST_EMUL, 1);
+                       SDT_PROBE4(vmm, vmx, exit, mmiofault,
+                           vmx, vcpu, vmexit, gpa);
                }
                /*
                 * If Virtual NMIs control is 1 and the VM-exit is due to an
@@ -2464,9 +2561,11 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
        case EXIT_REASON_VIRTUALIZED_EOI:
                vmexit->exitcode = VM_EXITCODE_IOAPIC_EOI;
                vmexit->u.ioapic_eoi.vector = qual & 0xFF;
+               SDT_PROBE3(vmm, vmx, exit, eoi, vmx, vcpu, vmexit);
                vmexit->inst_length = 0;        /* trap-like */
                break;
        case EXIT_REASON_APIC_ACCESS:
+               SDT_PROBE3(vmm, vmx, exit, apicaccess, vmx, vcpu, vmexit);
                handled = vmx_handle_apic_access(vmx, vcpu, vmexit);
                break;
        case EXIT_REASON_APIC_WRITE:
@@ -2476,18 +2575,25 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                 */
                vmexit->inst_length = 0;
                vlapic = vm_lapic(vmx->vm, vcpu);
+               SDT_PROBE4(vmm, vmx, exit, apicwrite,
+                   vmx, vcpu, vmexit, vlapic);
                handled = vmx_handle_apic_write(vmx, vcpu, vlapic, qual);
                break;
        case EXIT_REASON_XSETBV:
+               SDT_PROBE3(vmm, vmx, exit, xsetbv, vmx, vcpu, vmexit);
                handled = vmx_emulate_xsetbv(vmx, vcpu, vmexit);
                break;
        case EXIT_REASON_MONITOR:
+               SDT_PROBE3(vmm, vmx, exit, monitor, vmx, vcpu, vmexit);
                vmexit->exitcode = VM_EXITCODE_MONITOR;
                break;
        case EXIT_REASON_MWAIT:
+               SDT_PROBE3(vmm, vmx, exit, mwait, vmx, vcpu, vmexit);
                vmexit->exitcode = VM_EXITCODE_MWAIT;
                break;
        default:
+               SDT_PROBE4(vmm, vmx, exit, unknown,
+                   vmx, vcpu, vmexit, reason);
                vmm_stat_incr(vmx->vm, vcpu, VMEXIT_UNKNOWN, 1);
                break;
        }
@@ -2523,6 +2629,9 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_
                         */
                }
        }
+
+       SDT_PROBE4(vmm, vmx, exit, return,
+           vmx, vcpu, vmexit, handled);
        return (handled);
 }
 

Modified: head/sys/amd64/vmm/vmm.c
==============================================================================
--- head/sys/amd64/vmm/vmm.c    Fri Apr 13 16:54:49 2018        (r332478)
+++ head/sys/amd64/vmm/vmm.c    Fri Apr 13 17:23:05 2018        (r332479)
@@ -208,6 +208,8 @@ static struct vmm_ops *ops;
 #define        fpu_start_emulating()   load_cr0(rcr0() | CR0_TS)
 #define        fpu_stop_emulating()    clts()
 
+SDT_PROVIDER_DEFINE(vmm);
+
 static MALLOC_DEFINE(M_VM, "vm", "vm");
 
 /* statistics */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to