aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-kvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-kvm.c')
-rw-r--r--tools/perf/builtin-kvm.c157
1 files changed, 93 insertions, 64 deletions
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 260abc535b5b..37a769d7f9fe 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -22,9 +22,10 @@
22#include <pthread.h> 22#include <pthread.h>
23#include <math.h> 23#include <math.h>
24 24
25#include "../../arch/x86/include/asm/svm.h" 25#if defined(__i386__) || defined(__x86_64__)
26#include "../../arch/x86/include/asm/vmx.h" 26#include <asm/svm.h>
27#include "../../arch/x86/include/asm/kvm.h" 27#include <asm/vmx.h>
28#include <asm/kvm.h>
28 29
29struct event_key { 30struct event_key {
30 #define INVALID_KEY (~0ULL) 31 #define INVALID_KEY (~0ULL)
@@ -58,7 +59,7 @@ struct kvm_event_key {
58}; 59};
59 60
60 61
61struct perf_kvm; 62struct perf_kvm_stat;
62 63
63struct kvm_events_ops { 64struct kvm_events_ops {
64 bool (*is_begin_event)(struct perf_evsel *evsel, 65 bool (*is_begin_event)(struct perf_evsel *evsel,
@@ -66,7 +67,7 @@ struct kvm_events_ops {
66 struct event_key *key); 67 struct event_key *key);
67 bool (*is_end_event)(struct perf_evsel *evsel, 68 bool (*is_end_event)(struct perf_evsel *evsel,
68 struct perf_sample *sample, struct event_key *key); 69 struct perf_sample *sample, struct event_key *key);
69 void (*decode_key)(struct perf_kvm *kvm, struct event_key *key, 70 void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key,
70 char decode[20]); 71 char decode[20]);
71 const char *name; 72 const char *name;
72}; 73};
@@ -79,7 +80,7 @@ struct exit_reasons_table {
79#define EVENTS_BITS 12 80#define EVENTS_BITS 12
80#define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS) 81#define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS)
81 82
82struct perf_kvm { 83struct perf_kvm_stat {
83 struct perf_tool tool; 84 struct perf_tool tool;
84 struct perf_session *session; 85 struct perf_session *session;
85 86
@@ -146,7 +147,7 @@ static struct exit_reasons_table svm_exit_reasons[] = {
146 SVM_EXIT_REASONS 147 SVM_EXIT_REASONS
147}; 148};
148 149
149static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code) 150static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code)
150{ 151{
151 int i = kvm->exit_reasons_size; 152 int i = kvm->exit_reasons_size;
152 struct exit_reasons_table *tbl = kvm->exit_reasons; 153 struct exit_reasons_table *tbl = kvm->exit_reasons;
@@ -162,7 +163,7 @@ static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code)
162 return "UNKNOWN"; 163 return "UNKNOWN";
163} 164}
164 165
165static void exit_event_decode_key(struct perf_kvm *kvm, 166static void exit_event_decode_key(struct perf_kvm_stat *kvm,
166 struct event_key *key, 167 struct event_key *key,
167 char decode[20]) 168 char decode[20])
168{ 169{
@@ -228,7 +229,7 @@ static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample,
228 return false; 229 return false;
229} 230}
230 231
231static void mmio_event_decode_key(struct perf_kvm *kvm __maybe_unused, 232static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
232 struct event_key *key, 233 struct event_key *key,
233 char decode[20]) 234 char decode[20])
234{ 235{
@@ -271,7 +272,7 @@ static bool ioport_event_end(struct perf_evsel *evsel,
271 return kvm_entry_event(evsel); 272 return kvm_entry_event(evsel);
272} 273}
273 274
274static void ioport_event_decode_key(struct perf_kvm *kvm __maybe_unused, 275static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
275 struct event_key *key, 276 struct event_key *key,
276 char decode[20]) 277 char decode[20])
277{ 278{
@@ -286,7 +287,7 @@ static struct kvm_events_ops ioport_events = {
286 .name = "IO Port Access" 287 .name = "IO Port Access"
287}; 288};
288 289
289static bool register_kvm_events_ops(struct perf_kvm *kvm) 290static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
290{ 291{
291 bool ret = true; 292 bool ret = true;
292 293
@@ -311,11 +312,11 @@ struct vcpu_event_record {
311}; 312};
312 313
313 314
314static void init_kvm_event_record(struct perf_kvm *kvm) 315static void init_kvm_event_record(struct perf_kvm_stat *kvm)
315{ 316{
316 int i; 317 unsigned int i;
317 318
318 for (i = 0; i < (int)EVENTS_CACHE_SIZE; i++) 319 for (i = 0; i < EVENTS_CACHE_SIZE; i++)
319 INIT_LIST_HEAD(&kvm->kvm_events_cache[i]); 320 INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
320} 321}
321 322
@@ -360,7 +361,7 @@ static struct kvm_event *kvm_alloc_init_event(struct event_key *key)
360 return event; 361 return event;
361} 362}
362 363
363static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm, 364static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm,
364 struct event_key *key) 365 struct event_key *key)
365{ 366{
366 struct kvm_event *event; 367 struct kvm_event *event;
@@ -369,9 +370,10 @@ static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm,
369 BUG_ON(key->key == INVALID_KEY); 370 BUG_ON(key->key == INVALID_KEY);
370 371
371 head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)]; 372 head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)];
372 list_for_each_entry(event, head, hash_entry) 373 list_for_each_entry(event, head, hash_entry) {
373 if (event->key.key == key->key && event->key.info == key->info) 374 if (event->key.key == key->key && event->key.info == key->info)
374 return event; 375 return event;
376 }
375 377
376 event = kvm_alloc_init_event(key); 378 event = kvm_alloc_init_event(key);
377 if (!event) 379 if (!event)
@@ -381,7 +383,7 @@ static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm,
381 return event; 383 return event;
382} 384}
383 385
384static bool handle_begin_event(struct perf_kvm *kvm, 386static bool handle_begin_event(struct perf_kvm_stat *kvm,
385 struct vcpu_event_record *vcpu_record, 387 struct vcpu_event_record *vcpu_record,
386 struct event_key *key, u64 timestamp) 388 struct event_key *key, u64 timestamp)
387{ 389{
@@ -416,7 +418,10 @@ static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event)
416static bool update_kvm_event(struct kvm_event *event, int vcpu_id, 418static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
417 u64 time_diff) 419 u64 time_diff)
418{ 420{
419 kvm_update_event_stats(&event->total, time_diff); 421 if (vcpu_id == -1) {
422 kvm_update_event_stats(&event->total, time_diff);
423 return true;
424 }
420 425
421 if (!kvm_event_expand(event, vcpu_id)) 426 if (!kvm_event_expand(event, vcpu_id))
422 return false; 427 return false;
@@ -425,13 +430,19 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
425 return true; 430 return true;
426} 431}
427 432
428static bool handle_end_event(struct perf_kvm *kvm, 433static bool handle_end_event(struct perf_kvm_stat *kvm,
429 struct vcpu_event_record *vcpu_record, 434 struct vcpu_event_record *vcpu_record,
430 struct event_key *key, 435 struct event_key *key,
431 u64 timestamp) 436 u64 timestamp)
432{ 437{
433 struct kvm_event *event; 438 struct kvm_event *event;
434 u64 time_begin, time_diff; 439 u64 time_begin, time_diff;
440 int vcpu;
441
442 if (kvm->trace_vcpu == -1)
443 vcpu = -1;
444 else
445 vcpu = vcpu_record->vcpu_id;
435 446
436 event = vcpu_record->last_event; 447 event = vcpu_record->last_event;
437 time_begin = vcpu_record->start_time; 448 time_begin = vcpu_record->start_time;
@@ -461,7 +472,7 @@ static bool handle_end_event(struct perf_kvm *kvm,
461 BUG_ON(timestamp < time_begin); 472 BUG_ON(timestamp < time_begin);
462 473
463 time_diff = timestamp - time_begin; 474 time_diff = timestamp - time_begin;
464 return update_kvm_event(event, vcpu_record->vcpu_id, time_diff); 475 return update_kvm_event(event, vcpu, time_diff);
465} 476}
466 477
467static 478static
@@ -486,7 +497,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
486 return thread->priv; 497 return thread->priv;
487} 498}
488 499
489static bool handle_kvm_event(struct perf_kvm *kvm, 500static bool handle_kvm_event(struct perf_kvm_stat *kvm,
490 struct thread *thread, 501 struct thread *thread,
491 struct perf_evsel *evsel, 502 struct perf_evsel *evsel,
492 struct perf_sample *sample) 503 struct perf_sample *sample)
@@ -498,6 +509,11 @@ static bool handle_kvm_event(struct perf_kvm *kvm,
498 if (!vcpu_record) 509 if (!vcpu_record)
499 return true; 510 return true;
500 511
512 /* only process events for vcpus user cares about */
513 if ((kvm->trace_vcpu != -1) &&
514 (kvm->trace_vcpu != vcpu_record->vcpu_id))
515 return true;
516
501 if (kvm->events_ops->is_begin_event(evsel, sample, &key)) 517 if (kvm->events_ops->is_begin_event(evsel, sample, &key))
502 return handle_begin_event(kvm, vcpu_record, &key, sample->time); 518 return handle_begin_event(kvm, vcpu_record, &key, sample->time);
503 519
@@ -541,7 +557,7 @@ static struct kvm_event_key keys[] = {
541 { NULL, NULL } 557 { NULL, NULL }
542}; 558};
543 559
544static bool select_key(struct perf_kvm *kvm) 560static bool select_key(struct perf_kvm_stat *kvm)
545{ 561{
546 int i; 562 int i;
547 563
@@ -577,7 +593,8 @@ static void insert_to_result(struct rb_root *result, struct kvm_event *event,
577 rb_insert_color(&event->rb, result); 593 rb_insert_color(&event->rb, result);
578} 594}
579 595
580static void update_total_count(struct perf_kvm *kvm, struct kvm_event *event) 596static void
597update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event)
581{ 598{
582 int vcpu = kvm->trace_vcpu; 599 int vcpu = kvm->trace_vcpu;
583 600
@@ -590,19 +607,21 @@ static bool event_is_valid(struct kvm_event *event, int vcpu)
590 return !!get_event_count(event, vcpu); 607 return !!get_event_count(event, vcpu);
591} 608}
592 609
593static void sort_result(struct perf_kvm *kvm) 610static void sort_result(struct perf_kvm_stat *kvm)
594{ 611{
595 unsigned int i; 612 unsigned int i;
596 int vcpu = kvm->trace_vcpu; 613 int vcpu = kvm->trace_vcpu;
597 struct kvm_event *event; 614 struct kvm_event *event;
598 615
599 for (i = 0; i < EVENTS_CACHE_SIZE; i++) 616 for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
600 list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) 617 list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) {
601 if (event_is_valid(event, vcpu)) { 618 if (event_is_valid(event, vcpu)) {
602 update_total_count(kvm, event); 619 update_total_count(kvm, event);
603 insert_to_result(&kvm->result, event, 620 insert_to_result(&kvm->result, event,
604 kvm->compare, vcpu); 621 kvm->compare, vcpu);
605 } 622 }
623 }
624 }
606} 625}
607 626
608/* returns left most element of result, and erase it */ 627/* returns left most element of result, and erase it */
@@ -627,7 +646,7 @@ static void print_vcpu_info(int vcpu)
627 pr_info("VCPU %d:\n\n", vcpu); 646 pr_info("VCPU %d:\n\n", vcpu);
628} 647}
629 648
630static void print_result(struct perf_kvm *kvm) 649static void print_result(struct perf_kvm_stat *kvm)
631{ 650{
632 char decode[20]; 651 char decode[20];
633 struct kvm_event *event; 652 struct kvm_event *event;
@@ -659,8 +678,8 @@ static void print_result(struct perf_kvm *kvm)
659 pr_info("\n"); 678 pr_info("\n");
660 } 679 }
661 680
662 pr_info("\nTotal Samples:%lld, Total events handled time:%.2fus.\n\n", 681 pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n",
663 (unsigned long long)kvm->total_count, kvm->total_time / 1e3); 682 kvm->total_count, kvm->total_time / 1e3);
664} 683}
665 684
666static int process_sample_event(struct perf_tool *tool, 685static int process_sample_event(struct perf_tool *tool,
@@ -670,7 +689,8 @@ static int process_sample_event(struct perf_tool *tool,
670 struct machine *machine) 689 struct machine *machine)
671{ 690{
672 struct thread *thread = machine__findnew_thread(machine, sample->tid); 691 struct thread *thread = machine__findnew_thread(machine, sample->tid);
673 struct perf_kvm *kvm = container_of(tool, struct perf_kvm, tool); 692 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat,
693 tool);
674 694
675 if (thread == NULL) { 695 if (thread == NULL) {
676 pr_debug("problem processing %d event, skipping it.\n", 696 pr_debug("problem processing %d event, skipping it.\n",
@@ -701,7 +721,7 @@ static int get_cpu_isa(struct perf_session *session)
701 return isa; 721 return isa;
702} 722}
703 723
704static int read_events(struct perf_kvm *kvm) 724static int read_events(struct perf_kvm_stat *kvm)
705{ 725{
706 int ret; 726 int ret;
707 727
@@ -750,7 +770,7 @@ static bool verify_vcpu(int vcpu)
750 return true; 770 return true;
751} 771}
752 772
753static int kvm_events_report_vcpu(struct perf_kvm *kvm) 773static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
754{ 774{
755 int ret = -EINVAL; 775 int ret = -EINVAL;
756 int vcpu = kvm->trace_vcpu; 776 int vcpu = kvm->trace_vcpu;
@@ -798,7 +818,8 @@ static const char * const record_args[] = {
798 _p; \ 818 _p; \
799 }) 819 })
800 820
801static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv) 821static int
822kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
802{ 823{
803 unsigned int rec_argc, i, j; 824 unsigned int rec_argc, i, j;
804 const char **rec_argv; 825 const char **rec_argv;
@@ -821,7 +842,8 @@ static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv)
821 return cmd_record(i, rec_argv, NULL); 842 return cmd_record(i, rec_argv, NULL);
822} 843}
823 844
824static int kvm_events_report(struct perf_kvm *kvm, int argc, const char **argv) 845static int
846kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
825{ 847{
826 const struct option kvm_events_report_options[] = { 848 const struct option kvm_events_report_options[] = {
827 OPT_STRING(0, "event", &kvm->report_event, "report event", 849 OPT_STRING(0, "event", &kvm->report_event, "report event",
@@ -864,24 +886,37 @@ static void print_kvm_stat_usage(void)
864 printf("\nOtherwise, it is the alias of 'perf stat':\n"); 886 printf("\nOtherwise, it is the alias of 'perf stat':\n");
865} 887}
866 888
867static int kvm_cmd_stat(struct perf_kvm *kvm, int argc, const char **argv) 889static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
868{ 890{
891 struct perf_kvm_stat kvm = {
892 .file_name = file_name,
893
894 .trace_vcpu = -1,
895 .report_event = "vmexit",
896 .sort_key = "sample",
897
898 .exit_reasons = svm_exit_reasons,
899 .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
900 .exit_reasons_isa = "SVM",
901 };
902
869 if (argc == 1) { 903 if (argc == 1) {
870 print_kvm_stat_usage(); 904 print_kvm_stat_usage();
871 goto perf_stat; 905 goto perf_stat;
872 } 906 }
873 907
874 if (!strncmp(argv[1], "rec", 3)) 908 if (!strncmp(argv[1], "rec", 3))
875 return kvm_events_record(kvm, argc - 1, argv + 1); 909 return kvm_events_record(&kvm, argc - 1, argv + 1);
876 910
877 if (!strncmp(argv[1], "rep", 3)) 911 if (!strncmp(argv[1], "rep", 3))
878 return kvm_events_report(kvm, argc - 1 , argv + 1); 912 return kvm_events_report(&kvm, argc - 1 , argv + 1);
879 913
880perf_stat: 914perf_stat:
881 return cmd_stat(argc, argv, NULL); 915 return cmd_stat(argc, argv, NULL);
882} 916}
917#endif
883 918
884static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv) 919static int __cmd_record(const char *file_name, int argc, const char **argv)
885{ 920{
886 int rec_argc, i = 0, j; 921 int rec_argc, i = 0, j;
887 const char **rec_argv; 922 const char **rec_argv;
@@ -890,7 +925,7 @@ static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
890 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 925 rec_argv = calloc(rec_argc + 1, sizeof(char *));
891 rec_argv[i++] = strdup("record"); 926 rec_argv[i++] = strdup("record");
892 rec_argv[i++] = strdup("-o"); 927 rec_argv[i++] = strdup("-o");
893 rec_argv[i++] = strdup(kvm->file_name); 928 rec_argv[i++] = strdup(file_name);
894 for (j = 1; j < argc; j++, i++) 929 for (j = 1; j < argc; j++, i++)
895 rec_argv[i] = argv[j]; 930 rec_argv[i] = argv[j];
896 931
@@ -899,7 +934,7 @@ static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
899 return cmd_record(i, rec_argv, NULL); 934 return cmd_record(i, rec_argv, NULL);
900} 935}
901 936
902static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv) 937static int __cmd_report(const char *file_name, int argc, const char **argv)
903{ 938{
904 int rec_argc, i = 0, j; 939 int rec_argc, i = 0, j;
905 const char **rec_argv; 940 const char **rec_argv;
@@ -908,7 +943,7 @@ static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
908 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 943 rec_argv = calloc(rec_argc + 1, sizeof(char *));
909 rec_argv[i++] = strdup("report"); 944 rec_argv[i++] = strdup("report");
910 rec_argv[i++] = strdup("-i"); 945 rec_argv[i++] = strdup("-i");
911 rec_argv[i++] = strdup(kvm->file_name); 946 rec_argv[i++] = strdup(file_name);
912 for (j = 1; j < argc; j++, i++) 947 for (j = 1; j < argc; j++, i++)
913 rec_argv[i] = argv[j]; 948 rec_argv[i] = argv[j];
914 949
@@ -917,7 +952,8 @@ static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
917 return cmd_report(i, rec_argv, NULL); 952 return cmd_report(i, rec_argv, NULL);
918} 953}
919 954
920static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv) 955static int
956__cmd_buildid_list(const char *file_name, int argc, const char **argv)
921{ 957{
922 int rec_argc, i = 0, j; 958 int rec_argc, i = 0, j;
923 const char **rec_argv; 959 const char **rec_argv;
@@ -926,7 +962,7 @@ static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
926 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 962 rec_argv = calloc(rec_argc + 1, sizeof(char *));
927 rec_argv[i++] = strdup("buildid-list"); 963 rec_argv[i++] = strdup("buildid-list");
928 rec_argv[i++] = strdup("-i"); 964 rec_argv[i++] = strdup("-i");
929 rec_argv[i++] = strdup(kvm->file_name); 965 rec_argv[i++] = strdup(file_name);
930 for (j = 1; j < argc; j++, i++) 966 for (j = 1; j < argc; j++, i++)
931 rec_argv[i] = argv[j]; 967 rec_argv[i] = argv[j];
932 968
@@ -937,20 +973,11 @@ static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
937 973
938int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused) 974int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
939{ 975{
940 struct perf_kvm kvm = { 976 const char *file_name = NULL;
941 .trace_vcpu = -1,
942 .report_event = "vmexit",
943 .sort_key = "sample",
944
945 .exit_reasons = svm_exit_reasons,
946 .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
947 .exit_reasons_isa = "SVM",
948 };
949
950 const struct option kvm_options[] = { 977 const struct option kvm_options[] = {
951 OPT_STRING('i', "input", &kvm.file_name, "file", 978 OPT_STRING('i', "input", &file_name, "file",
952 "Input file name"), 979 "Input file name"),
953 OPT_STRING('o', "output", &kvm.file_name, "file", 980 OPT_STRING('o', "output", &file_name, "file",
954 "Output file name"), 981 "Output file name"),
955 OPT_BOOLEAN(0, "guest", &perf_guest, 982 OPT_BOOLEAN(0, "guest", &perf_guest,
956 "Collect guest os data"), 983 "Collect guest os data"),
@@ -985,32 +1012,34 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
985 if (!perf_host) 1012 if (!perf_host)
986 perf_guest = 1; 1013 perf_guest = 1;
987 1014
988 if (!kvm.file_name) { 1015 if (!file_name) {
989 if (perf_host && !perf_guest) 1016 if (perf_host && !perf_guest)
990 kvm.file_name = strdup("perf.data.host"); 1017 file_name = strdup("perf.data.host");
991 else if (!perf_host && perf_guest) 1018 else if (!perf_host && perf_guest)
992 kvm.file_name = strdup("perf.data.guest"); 1019 file_name = strdup("perf.data.guest");
993 else 1020 else
994 kvm.file_name = strdup("perf.data.kvm"); 1021 file_name = strdup("perf.data.kvm");
995 1022
996 if (!kvm.file_name) { 1023 if (!file_name) {
997 pr_err("Failed to allocate memory for filename\n"); 1024 pr_err("Failed to allocate memory for filename\n");
998 return -ENOMEM; 1025 return -ENOMEM;
999 } 1026 }
1000 } 1027 }
1001 1028
1002 if (!strncmp(argv[0], "rec", 3)) 1029 if (!strncmp(argv[0], "rec", 3))
1003 return __cmd_record(&kvm, argc, argv); 1030 return __cmd_record(file_name, argc, argv);
1004 else if (!strncmp(argv[0], "rep", 3)) 1031 else if (!strncmp(argv[0], "rep", 3))
1005 return __cmd_report(&kvm, argc, argv); 1032 return __cmd_report(file_name, argc, argv);
1006 else if (!strncmp(argv[0], "diff", 4)) 1033 else if (!strncmp(argv[0], "diff", 4))
1007 return cmd_diff(argc, argv, NULL); 1034 return cmd_diff(argc, argv, NULL);
1008 else if (!strncmp(argv[0], "top", 3)) 1035 else if (!strncmp(argv[0], "top", 3))
1009 return cmd_top(argc, argv, NULL); 1036 return cmd_top(argc, argv, NULL);
1010 else if (!strncmp(argv[0], "buildid-list", 12)) 1037 else if (!strncmp(argv[0], "buildid-list", 12))
1011 return __cmd_buildid_list(&kvm, argc, argv); 1038 return __cmd_buildid_list(file_name, argc, argv);
1039#if defined(__i386__) || defined(__x86_64__)
1012 else if (!strncmp(argv[0], "stat", 4)) 1040 else if (!strncmp(argv[0], "stat", 4))
1013 return kvm_cmd_stat(&kvm, argc, argv); 1041 return kvm_cmd_stat(file_name, argc, argv);
1042#endif
1014 else 1043 else
1015 usage_with_options(kvm_usage, kvm_options); 1044 usage_with_options(kvm_usage, kvm_options);
1016 1045