vmm_stat.c revision 248935
1200581Srdivacky/*- 2200581Srdivacky * Copyright (c) 2011 NetApp, Inc. 3200581Srdivacky * All rights reserved. 4200581Srdivacky * 5200581Srdivacky * Redistribution and use in source and binary forms, with or without 6200581Srdivacky * modification, are permitted provided that the following conditions 7200581Srdivacky * are met: 8200581Srdivacky * 1. Redistributions of source code must retain the above copyright 9200581Srdivacky * notice, this list of conditions and the following disclaimer. 10200581Srdivacky * 2. Redistributions in binary form must reproduce the above copyright 11200581Srdivacky * notice, this list of conditions and the following disclaimer in the 12200581Srdivacky * documentation and/or other materials provided with the distribution. 13200581Srdivacky * 14200581Srdivacky * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15200581Srdivacky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16200581Srdivacky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17200581Srdivacky * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18200581Srdivacky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19200581Srdivacky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20200581Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21200581Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22200581Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23203954Srdivacky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24207618Srdivacky * SUCH DAMAGE. 25207618Srdivacky * 26200581Srdivacky * $FreeBSD: head/sys/amd64/vmm/vmm_stat.c 248935 2013-03-30 17:46:03Z neel $ 27200581Srdivacky */ 28200581Srdivacky 29200581Srdivacky#include <sys/cdefs.h> 30200581Srdivacky__FBSDID("$FreeBSD: head/sys/amd64/vmm/vmm_stat.c 248935 2013-03-30 17:46:03Z neel $"); 31207618Srdivacky 32207618Srdivacky#include <sys/param.h> 33207618Srdivacky#include <sys/kernel.h> 34207618Srdivacky#include <sys/systm.h> 35207618Srdivacky#include <sys/malloc.h> 36207618Srdivacky#include <sys/smp.h> 37207618Srdivacky 38207618Srdivacky#include <machine/vmm.h> 39207618Srdivacky#include "vmm_util.h" 40207618Srdivacky#include "vmm_stat.h" 41207618Srdivacky 42207618Srdivackystatic int vstnum; 43207618Srdivackystatic struct vmm_stat_type *vsttab[MAX_VMM_STAT_TYPES]; 44207618Srdivacky 45207618Srdivackystatic MALLOC_DEFINE(M_VMM_STAT, "vmm stat", "vmm stat"); 46207618Srdivacky 47207618Srdivackyvoid 48207618Srdivackyvmm_stat_init(void *arg) 49207618Srdivacky{ 50200581Srdivacky struct vmm_stat_type *vst = arg; 51200581Srdivacky 52200581Srdivacky /* We require all stats to identify themselves with a description */ 53200581Srdivacky if (vst->desc == NULL) 54200581Srdivacky return; 55207618Srdivacky 56207618Srdivacky if (vst->scope == VMM_STAT_SCOPE_INTEL && !vmm_is_intel()) 57200581Srdivacky return; 58200581Srdivacky 59200581Srdivacky if (vst->scope == VMM_STAT_SCOPE_AMD && !vmm_is_amd()) 60200581Srdivacky return; 61207618Srdivacky 62200581Srdivacky if (vstnum >= MAX_VMM_STAT_TYPES) { 63200581Srdivacky printf("Cannot accomodate vmm stat type \"%s\"!\n", vst->desc); 64200581Srdivacky return; 65200581Srdivacky } 66200581Srdivacky 67200581Srdivacky vst->index = vstnum; 68200581Srdivacky vsttab[vstnum++] = vst; 69200581Srdivacky} 70200581Srdivacky 71200581Srdivackyint 72200581Srdivackyvmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf) 73200581Srdivacky{ 74200581Srdivacky int i; 75200581Srdivacky uint64_t *stats; 76200581Srdivacky 77200581Srdivacky if (vcpu < 0 || vcpu >= VM_MAXCPU) 78200581Srdivacky return (EINVAL); 79200581Srdivacky 80200581Srdivacky stats = vcpu_stats(vm, vcpu); 81200581Srdivacky for (i = 0; i < vstnum; i++) 82200581Srdivacky buf[i] = stats[i]; 83200581Srdivacky *num_stats = vstnum; 84200581Srdivacky return (0); 85200581Srdivacky} 86200581Srdivacky 87200581Srdivackyvoid * 88200581Srdivackyvmm_stat_alloc(void) 89200581Srdivacky{ 90200581Srdivacky u_long size; 91200581Srdivacky 92200581Srdivacky size = vstnum * sizeof(uint64_t); 93200581Srdivacky 94200581Srdivacky return (malloc(size, M_VMM_STAT, M_ZERO | M_WAITOK)); 95200581Srdivacky} 96200581Srdivacky 97200581Srdivackyvoid 98200581Srdivackyvmm_stat_free(void *vp) 99200581Srdivacky{ 100200581Srdivacky free(vp, M_VMM_STAT); 101200581Srdivacky} 102200581Srdivacky 103200581Srdivackyconst char * 104200581Srdivackyvmm_stat_desc(int index) 105200581Srdivacky{ 106200581Srdivacky 107203954Srdivacky if (index >= 0 && index < vstnum) 108200581Srdivacky return (vsttab[index]->desc); 109200581Srdivacky else 110200581Srdivacky return (NULL); 111200581Srdivacky} 112200581Srdivacky 113203954Srdivacky/* global statistics */ 114200581SrdivackyVMM_STAT(VCPU_MIGRATIONS, "vcpu migration across host cpus"); 115200581SrdivackyVMM_STAT(VMEXIT_COUNT, "total number of vm exits"); 116200581SrdivackyVMM_STAT(VMEXIT_EXTINT, "vm exits due to external interrupt"); 117200581SrdivackyVMM_STAT(VMEXIT_HLT, "number of times hlt was intercepted"); 118200581SrdivackyVMM_STAT(VMEXIT_CR_ACCESS, "number of times %cr access was intercepted"); 119200581SrdivackyVMM_STAT(VMEXIT_RDMSR, "number of times rdmsr was intercepted"); 120200581SrdivackyVMM_STAT(VMEXIT_WRMSR, "number of times wrmsr was intercepted"); 121200581SrdivackyVMM_STAT(VMEXIT_MTRAP, "number of monitor trap exits"); 122200581SrdivackyVMM_STAT(VMEXIT_PAUSE, "number of times pause was intercepted"); 123200581SrdivackyVMM_STAT(VMEXIT_INTR_WINDOW, "vm exits due to interrupt window opening"); 124200581SrdivackyVMM_STAT(VMEXIT_NMI_WINDOW, "vm exits due to nmi window opening"); 125200581SrdivackyVMM_STAT(VMEXIT_INOUT, "number of times in/out was intercepted"); 126200581SrdivackyVMM_STAT(VMEXIT_CPUID, "number of times cpuid was intercepted"); 127200581SrdivackyVMM_STAT(VMEXIT_EPT_FAULT, "vm exits due to nested page fault"); 128200581SrdivackyVMM_STAT(VMEXIT_UNKNOWN, "number of vm exits for unknown reason"); 129200581SrdivackyVMM_STAT(VMEXIT_ASTPENDING, "number of times astpending at exit"); 130200581SrdivackyVMM_STAT(VMEXIT_USERSPACE, "number of vm exits handled in userspace"); 131200581Srdivacky