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