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