aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/uapi/asm/Kbuild1
-rw-r--r--arch/x86/include/uapi/asm/kvm_perf.h16
-rw-r--r--tools/perf/MANIFEST1
-rw-r--r--tools/perf/builtin-kvm.c34
4 files changed, 34 insertions, 18 deletions
diff --git a/arch/x86/include/uapi/asm/Kbuild b/arch/x86/include/uapi/asm/Kbuild
index 09409c44f9a5..3dec769cadf7 100644
--- a/arch/x86/include/uapi/asm/Kbuild
+++ b/arch/x86/include/uapi/asm/Kbuild
@@ -22,6 +22,7 @@ header-y += ipcbuf.h
22header-y += ist.h 22header-y += ist.h
23header-y += kvm.h 23header-y += kvm.h
24header-y += kvm_para.h 24header-y += kvm_para.h
25header-y += kvm_perf.h
25header-y += ldt.h 26header-y += ldt.h
26header-y += mce.h 27header-y += mce.h
27header-y += mman.h 28header-y += mman.h
diff --git a/arch/x86/include/uapi/asm/kvm_perf.h b/arch/x86/include/uapi/asm/kvm_perf.h
new file mode 100644
index 000000000000..3bb964f88aa1
--- /dev/null
+++ b/arch/x86/include/uapi/asm/kvm_perf.h
@@ -0,0 +1,16 @@
1#ifndef _ASM_X86_KVM_PERF_H
2#define _ASM_X86_KVM_PERF_H
3
4#include <asm/svm.h>
5#include <asm/vmx.h>
6#include <asm/kvm.h>
7
8#define DECODE_STR_LEN 20
9
10#define VCPU_ID "vcpu_id"
11
12#define KVM_ENTRY_TRACE "kvm:kvm_entry"
13#define KVM_EXIT_TRACE "kvm:kvm_exit"
14#define KVM_EXIT_REASON "exit_reason"
15
16#endif /* _ASM_X86_KVM_PERF_H */
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 45da209b6ed3..02b485d619cd 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -37,3 +37,4 @@ arch/x86/include/asm/kvm_host.h
37arch/x86/include/uapi/asm/svm.h 37arch/x86/include/uapi/asm/svm.h
38arch/x86/include/uapi/asm/vmx.h 38arch/x86/include/uapi/asm/vmx.h
39arch/x86/include/uapi/asm/kvm.h 39arch/x86/include/uapi/asm/kvm.h
40arch/x86/include/uapi/asm/kvm_perf.h
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 41dbeaf8cc11..6d73346ef2a6 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -30,9 +30,7 @@
30#include <math.h> 30#include <math.h>
31 31
32#ifdef HAVE_KVM_STAT_SUPPORT 32#ifdef HAVE_KVM_STAT_SUPPORT
33#include <asm/svm.h> 33#include <asm/kvm_perf.h>
34#include <asm/vmx.h>
35#include <asm/kvm.h>
36 34
37struct event_key { 35struct event_key {
38 #define INVALID_KEY (~0ULL) 36 #define INVALID_KEY (~0ULL)
@@ -75,7 +73,7 @@ struct kvm_events_ops {
75 bool (*is_end_event)(struct perf_evsel *evsel, 73 bool (*is_end_event)(struct perf_evsel *evsel,
76 struct perf_sample *sample, struct event_key *key); 74 struct perf_sample *sample, struct event_key *key);
77 void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, 75 void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key,
78 char decode[20]); 76 char *decode);
79 const char *name; 77 const char *name;
80}; 78};
81 79
@@ -126,12 +124,12 @@ static void exit_event_get_key(struct perf_evsel *evsel,
126 struct event_key *key) 124 struct event_key *key)
127{ 125{
128 key->info = 0; 126 key->info = 0;
129 key->key = perf_evsel__intval(evsel, sample, "exit_reason"); 127 key->key = perf_evsel__intval(evsel, sample, KVM_EXIT_REASON);
130} 128}
131 129
132static bool kvm_exit_event(struct perf_evsel *evsel) 130static bool kvm_exit_event(struct perf_evsel *evsel)
133{ 131{
134 return !strcmp(evsel->name, "kvm:kvm_exit"); 132 return !strcmp(evsel->name, KVM_EXIT_TRACE);
135} 133}
136 134
137static bool exit_event_begin(struct perf_evsel *evsel, 135static bool exit_event_begin(struct perf_evsel *evsel,
@@ -147,7 +145,7 @@ static bool exit_event_begin(struct perf_evsel *evsel,
147 145
148static bool kvm_entry_event(struct perf_evsel *evsel) 146static bool kvm_entry_event(struct perf_evsel *evsel)
149{ 147{
150 return !strcmp(evsel->name, "kvm:kvm_entry"); 148 return !strcmp(evsel->name, KVM_ENTRY_TRACE);
151} 149}
152 150
153static bool exit_event_end(struct perf_evsel *evsel, 151static bool exit_event_end(struct perf_evsel *evsel,
@@ -182,12 +180,12 @@ static const char *get_exit_reason(struct perf_kvm_stat *kvm,
182 180
183static void exit_event_decode_key(struct perf_kvm_stat *kvm, 181static void exit_event_decode_key(struct perf_kvm_stat *kvm,
184 struct event_key *key, 182 struct event_key *key,
185 char decode[20]) 183 char *decode)
186{ 184{
187 const char *exit_reason = get_exit_reason(kvm, kvm->exit_reasons, 185 const char *exit_reason = get_exit_reason(kvm, kvm->exit_reasons,
188 key->key); 186 key->key);
189 187
190 scnprintf(decode, 20, "%s", exit_reason); 188 scnprintf(decode, DECODE_STR_LEN, "%s", exit_reason);
191} 189}
192 190
193static struct kvm_events_ops exit_events = { 191static struct kvm_events_ops exit_events = {
@@ -249,9 +247,9 @@ static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample,
249 247
250static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, 248static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
251 struct event_key *key, 249 struct event_key *key,
252 char decode[20]) 250 char *decode)
253{ 251{
254 scnprintf(decode, 20, "%#lx:%s", (unsigned long)key->key, 252 scnprintf(decode, DECODE_STR_LEN, "%#lx:%s", (unsigned long)key->key,
255 key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R"); 253 key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R");
256} 254}
257 255
@@ -292,9 +290,9 @@ static bool ioport_event_end(struct perf_evsel *evsel,
292 290
293static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, 291static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
294 struct event_key *key, 292 struct event_key *key,
295 char decode[20]) 293 char *decode)
296{ 294{
297 scnprintf(decode, 20, "%#llx:%s", (unsigned long long)key->key, 295 scnprintf(decode, DECODE_STR_LEN, "%#llx:%s", (unsigned long long)key->key,
298 key->info ? "POUT" : "PIN"); 296 key->info ? "POUT" : "PIN");
299} 297}
300 298
@@ -524,7 +522,7 @@ static bool handle_end_event(struct perf_kvm_stat *kvm,
524 time_diff = sample->time - time_begin; 522 time_diff = sample->time - time_begin;
525 523
526 if (kvm->duration && time_diff > kvm->duration) { 524 if (kvm->duration && time_diff > kvm->duration) {
527 char decode[32]; 525 char decode[DECODE_STR_LEN];
528 526
529 kvm->events_ops->decode_key(kvm, &event->key, decode); 527 kvm->events_ops->decode_key(kvm, &event->key, decode);
530 if (strcmp(decode, "HLT")) { 528 if (strcmp(decode, "HLT")) {
@@ -552,7 +550,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
552 return NULL; 550 return NULL;
553 } 551 }
554 552
555 vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, "vcpu_id"); 553 vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID);
556 thread->priv = vcpu_record; 554 thread->priv = vcpu_record;
557 } 555 }
558 556
@@ -739,7 +737,7 @@ static void show_timeofday(void)
739 737
740static void print_result(struct perf_kvm_stat *kvm) 738static void print_result(struct perf_kvm_stat *kvm)
741{ 739{
742 char decode[20]; 740 char decode[DECODE_STR_LEN];
743 struct kvm_event *event; 741 struct kvm_event *event;
744 int vcpu = kvm->trace_vcpu; 742 int vcpu = kvm->trace_vcpu;
745 743
@@ -750,7 +748,7 @@ static void print_result(struct perf_kvm_stat *kvm)
750 748
751 pr_info("\n\n"); 749 pr_info("\n\n");
752 print_vcpu_info(kvm); 750 print_vcpu_info(kvm);
753 pr_info("%20s ", kvm->events_ops->name); 751 pr_info("%*s ", DECODE_STR_LEN, kvm->events_ops->name);
754 pr_info("%10s ", "Samples"); 752 pr_info("%10s ", "Samples");
755 pr_info("%9s ", "Samples%"); 753 pr_info("%9s ", "Samples%");
756 754
@@ -769,7 +767,7 @@ static void print_result(struct perf_kvm_stat *kvm)
769 min = get_event_min(event, vcpu); 767 min = get_event_min(event, vcpu);
770 768
771 kvm->events_ops->decode_key(kvm, &event->key, decode); 769 kvm->events_ops->decode_key(kvm, &event->key, decode);
772 pr_info("%20s ", decode); 770 pr_info("%*s ", DECODE_STR_LEN, decode);
773 pr_info("%10llu ", (unsigned long long)ecount); 771 pr_info("%10llu ", (unsigned long long)ecount);
774 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100); 772 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
775 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100); 773 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);