vmm_stat.c revision 248935
1221828Sgrehan/*- 2221828Sgrehan * Copyright (c) 2011 NetApp, Inc. 3221828Sgrehan * All rights reserved. 4221828Sgrehan * 5221828Sgrehan * Redistribution and use in source and binary forms, with or without 6221828Sgrehan * modification, are permitted provided that the following conditions 7221828Sgrehan * are met: 8221828Sgrehan * 1. Redistributions of source code must retain the above copyright 9221828Sgrehan * notice, this list of conditions and the following disclaimer. 10221828Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 11221828Sgrehan * notice, this list of conditions and the following disclaimer in the 12221828Sgrehan * documentation and/or other materials provided with the distribution. 13221828Sgrehan * 14221828Sgrehan * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15221828Sgrehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16221828Sgrehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17221828Sgrehan * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18221828Sgrehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19221828Sgrehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20221828Sgrehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21221828Sgrehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22221828Sgrehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23221828Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24221828Sgrehan * SUCH DAMAGE. 25221828Sgrehan * 26221828Sgrehan * $FreeBSD: head/sys/amd64/vmm/vmm_stat.c 248935 2013-03-30 17:46:03Z neel $ 27221828Sgrehan */ 28221828Sgrehan 29221828Sgrehan#include <sys/cdefs.h> 30221828Sgrehan__FBSDID("$FreeBSD: head/sys/amd64/vmm/vmm_stat.c 248935 2013-03-30 17:46:03Z neel $"); 31221828Sgrehan 32221828Sgrehan#include <sys/param.h> 33221828Sgrehan#include <sys/kernel.h> 34221828Sgrehan#include <sys/systm.h> 35221828Sgrehan#include <sys/malloc.h> 36223621Sgrehan#include <sys/smp.h> 37221828Sgrehan 38221828Sgrehan#include <machine/vmm.h> 39248389Sneel#include "vmm_util.h" 40221828Sgrehan#include "vmm_stat.h" 41221828Sgrehan 42221828Sgrehanstatic int vstnum; 43221828Sgrehanstatic struct vmm_stat_type *vsttab[MAX_VMM_STAT_TYPES]; 44221828Sgrehan 45221828Sgrehanstatic MALLOC_DEFINE(M_VMM_STAT, "vmm stat", "vmm stat"); 46221828Sgrehan 47221828Sgrehanvoid 48221828Sgrehanvmm_stat_init(void *arg) 49221828Sgrehan{ 50221828Sgrehan struct vmm_stat_type *vst = arg; 51221828Sgrehan 52221828Sgrehan /* We require all stats to identify themselves with a description */ 53221828Sgrehan if (vst->desc == NULL) 54221828Sgrehan return; 55221828Sgrehan 56248389Sneel if (vst->scope == VMM_STAT_SCOPE_INTEL && !vmm_is_intel()) 57248389Sneel return; 58248389Sneel 59248389Sneel if (vst->scope == VMM_STAT_SCOPE_AMD && !vmm_is_amd()) 60248389Sneel return; 61248389Sneel 62221828Sgrehan if (vstnum >= MAX_VMM_STAT_TYPES) { 63221828Sgrehan printf("Cannot accomodate vmm stat type \"%s\"!\n", vst->desc); 64221828Sgrehan return; 65221828Sgrehan } 66221828Sgrehan 67221828Sgrehan vst->index = vstnum; 68221828Sgrehan vsttab[vstnum++] = vst; 69221828Sgrehan} 70221828Sgrehan 71221828Sgrehanint 72221828Sgrehanvmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf) 73221828Sgrehan{ 74221828Sgrehan int i; 75221828Sgrehan uint64_t *stats; 76221828Sgrehan 77221828Sgrehan if (vcpu < 0 || vcpu >= VM_MAXCPU) 78221828Sgrehan return (EINVAL); 79221828Sgrehan 80221828Sgrehan stats = vcpu_stats(vm, vcpu); 81221828Sgrehan for (i = 0; i < vstnum; i++) 82221828Sgrehan buf[i] = stats[i]; 83221828Sgrehan *num_stats = vstnum; 84221828Sgrehan return (0); 85221828Sgrehan} 86221828Sgrehan 87221828Sgrehanvoid * 88221828Sgrehanvmm_stat_alloc(void) 89221828Sgrehan{ 90221828Sgrehan u_long size; 91221828Sgrehan 92221828Sgrehan size = vstnum * sizeof(uint64_t); 93221828Sgrehan 94221828Sgrehan return (malloc(size, M_VMM_STAT, M_ZERO | M_WAITOK)); 95221828Sgrehan} 96221828Sgrehan 97221828Sgrehanvoid 98221828Sgrehanvmm_stat_free(void *vp) 99221828Sgrehan{ 100221828Sgrehan free(vp, M_VMM_STAT); 101221828Sgrehan} 102221828Sgrehan 103221828Sgrehanconst char * 104221828Sgrehanvmm_stat_desc(int index) 105221828Sgrehan{ 106221828Sgrehan 107221828Sgrehan if (index >= 0 && index < vstnum) 108221828Sgrehan return (vsttab[index]->desc); 109221828Sgrehan else 110221828Sgrehan return (NULL); 111221828Sgrehan} 112248389Sneel 113248389Sneel/* global statistics */ 114248389SneelVMM_STAT(VCPU_MIGRATIONS, "vcpu migration across host cpus"); 115248389SneelVMM_STAT(VMEXIT_COUNT, "total number of vm exits"); 116248389SneelVMM_STAT(VMEXIT_EXTINT, "vm exits due to external interrupt"); 117248389SneelVMM_STAT(VMEXIT_HLT, "number of times hlt was intercepted"); 118248935SneelVMM_STAT(VMEXIT_CR_ACCESS, "number of times %cr access was intercepted"); 119248935SneelVMM_STAT(VMEXIT_RDMSR, "number of times rdmsr was intercepted"); 120248935SneelVMM_STAT(VMEXIT_WRMSR, "number of times wrmsr was intercepted"); 121248935SneelVMM_STAT(VMEXIT_MTRAP, "number of monitor trap exits"); 122248935SneelVMM_STAT(VMEXIT_PAUSE, "number of times pause was intercepted"); 123248935SneelVMM_STAT(VMEXIT_INTR_WINDOW, "vm exits due to interrupt window opening"); 124248935SneelVMM_STAT(VMEXIT_NMI_WINDOW, "vm exits due to nmi window opening"); 125248935SneelVMM_STAT(VMEXIT_INOUT, "number of times in/out was intercepted"); 126248935SneelVMM_STAT(VMEXIT_CPUID, "number of times cpuid was intercepted"); 127248935SneelVMM_STAT(VMEXIT_EPT_FAULT, "vm exits due to nested page fault"); 128248935SneelVMM_STAT(VMEXIT_UNKNOWN, "number of vm exits for unknown reason"); 129248935SneelVMM_STAT(VMEXIT_ASTPENDING, "number of times astpending at exit"); 130248935SneelVMM_STAT(VMEXIT_USERSPACE, "number of vm exits handled in userspace"); 131