| .. | .. |
|---|
| 2 | 2 | #include "builtin.h" |
|---|
| 3 | 3 | #include "perf.h" |
|---|
| 4 | 4 | |
|---|
| 5 | +#include "util/build-id.h" |
|---|
| 5 | 6 | #include "util/evsel.h" |
|---|
| 6 | 7 | #include "util/evlist.h" |
|---|
| 8 | +#include "util/mmap.h" |
|---|
| 7 | 9 | #include "util/term.h" |
|---|
| 8 | | -#include "util/util.h" |
|---|
| 9 | | -#include "util/cache.h" |
|---|
| 10 | 10 | #include "util/symbol.h" |
|---|
| 11 | 11 | #include "util/thread.h" |
|---|
| 12 | 12 | #include "util/header.h" |
|---|
| 13 | 13 | #include "util/session.h" |
|---|
| 14 | 14 | #include "util/intlist.h" |
|---|
| 15 | +#include <subcmd/pager.h> |
|---|
| 15 | 16 | #include <subcmd/parse-options.h> |
|---|
| 16 | 17 | #include "util/trace-event.h" |
|---|
| 17 | 18 | #include "util/debug.h" |
|---|
| 18 | 19 | #include "util/tool.h" |
|---|
| 19 | 20 | #include "util/stat.h" |
|---|
| 21 | +#include "util/synthetic-events.h" |
|---|
| 20 | 22 | #include "util/top.h" |
|---|
| 21 | 23 | #include "util/data.h" |
|---|
| 22 | 24 | #include "util/ordered-events.h" |
|---|
| 25 | +#include "util/kvm-stat.h" |
|---|
| 26 | +#include "ui/ui.h" |
|---|
| 23 | 27 | |
|---|
| 24 | 28 | #include <sys/prctl.h> |
|---|
| 25 | 29 | #ifdef HAVE_TIMERFD_SUPPORT |
|---|
| .. | .. |
|---|
| 30 | 34 | #include <sys/stat.h> |
|---|
| 31 | 35 | #include <fcntl.h> |
|---|
| 32 | 36 | |
|---|
| 37 | +#include <linux/err.h> |
|---|
| 33 | 38 | #include <linux/kernel.h> |
|---|
| 39 | +#include <linux/string.h> |
|---|
| 34 | 40 | #include <linux/time64.h> |
|---|
| 41 | +#include <linux/zalloc.h> |
|---|
| 35 | 42 | #include <errno.h> |
|---|
| 36 | 43 | #include <inttypes.h> |
|---|
| 37 | 44 | #include <poll.h> |
|---|
| .. | .. |
|---|
| 39 | 46 | #include <semaphore.h> |
|---|
| 40 | 47 | #include <signal.h> |
|---|
| 41 | 48 | #include <math.h> |
|---|
| 49 | +#include <perf/mmap.h> |
|---|
| 42 | 50 | |
|---|
| 43 | 51 | static const char *get_filename_for_perf_kvm(void) |
|---|
| 44 | 52 | { |
|---|
| .. | .. |
|---|
| 55 | 63 | } |
|---|
| 56 | 64 | |
|---|
| 57 | 65 | #ifdef HAVE_KVM_STAT_SUPPORT |
|---|
| 58 | | -#include "util/kvm-stat.h" |
|---|
| 59 | 66 | |
|---|
| 60 | | -void exit_event_get_key(struct perf_evsel *evsel, |
|---|
| 67 | +void exit_event_get_key(struct evsel *evsel, |
|---|
| 61 | 68 | struct perf_sample *sample, |
|---|
| 62 | 69 | struct event_key *key) |
|---|
| 63 | 70 | { |
|---|
| 64 | 71 | key->info = 0; |
|---|
| 65 | | - key->key = perf_evsel__intval(evsel, sample, kvm_exit_reason); |
|---|
| 72 | + key->key = evsel__intval(evsel, sample, kvm_exit_reason); |
|---|
| 66 | 73 | } |
|---|
| 67 | 74 | |
|---|
| 68 | | -bool kvm_exit_event(struct perf_evsel *evsel) |
|---|
| 75 | +bool kvm_exit_event(struct evsel *evsel) |
|---|
| 69 | 76 | { |
|---|
| 70 | 77 | return !strcmp(evsel->name, kvm_exit_trace); |
|---|
| 71 | 78 | } |
|---|
| 72 | 79 | |
|---|
| 73 | | -bool exit_event_begin(struct perf_evsel *evsel, |
|---|
| 80 | +bool exit_event_begin(struct evsel *evsel, |
|---|
| 74 | 81 | struct perf_sample *sample, struct event_key *key) |
|---|
| 75 | 82 | { |
|---|
| 76 | 83 | if (kvm_exit_event(evsel)) { |
|---|
| .. | .. |
|---|
| 81 | 88 | return false; |
|---|
| 82 | 89 | } |
|---|
| 83 | 90 | |
|---|
| 84 | | -bool kvm_entry_event(struct perf_evsel *evsel) |
|---|
| 91 | +bool kvm_entry_event(struct evsel *evsel) |
|---|
| 85 | 92 | { |
|---|
| 86 | 93 | return !strcmp(evsel->name, kvm_entry_trace); |
|---|
| 87 | 94 | } |
|---|
| 88 | 95 | |
|---|
| 89 | | -bool exit_event_end(struct perf_evsel *evsel, |
|---|
| 96 | +bool exit_event_end(struct evsel *evsel, |
|---|
| 90 | 97 | struct perf_sample *sample __maybe_unused, |
|---|
| 91 | 98 | struct event_key *key __maybe_unused) |
|---|
| 92 | 99 | { |
|---|
| .. | .. |
|---|
| 286 | 293 | } |
|---|
| 287 | 294 | |
|---|
| 288 | 295 | static bool is_child_event(struct perf_kvm_stat *kvm, |
|---|
| 289 | | - struct perf_evsel *evsel, |
|---|
| 296 | + struct evsel *evsel, |
|---|
| 290 | 297 | struct perf_sample *sample, |
|---|
| 291 | 298 | struct event_key *key) |
|---|
| 292 | 299 | { |
|---|
| .. | .. |
|---|
| 396 | 403 | |
|---|
| 397 | 404 | static |
|---|
| 398 | 405 | struct vcpu_event_record *per_vcpu_record(struct thread *thread, |
|---|
| 399 | | - struct perf_evsel *evsel, |
|---|
| 406 | + struct evsel *evsel, |
|---|
| 400 | 407 | struct perf_sample *sample) |
|---|
| 401 | 408 | { |
|---|
| 402 | 409 | /* Only kvm_entry records vcpu id. */ |
|---|
| .. | .. |
|---|
| 409 | 416 | return NULL; |
|---|
| 410 | 417 | } |
|---|
| 411 | 418 | |
|---|
| 412 | | - vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, |
|---|
| 413 | | - vcpu_id_str); |
|---|
| 419 | + vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str); |
|---|
| 414 | 420 | thread__set_priv(thread, vcpu_record); |
|---|
| 415 | 421 | } |
|---|
| 416 | 422 | |
|---|
| .. | .. |
|---|
| 419 | 425 | |
|---|
| 420 | 426 | static bool handle_kvm_event(struct perf_kvm_stat *kvm, |
|---|
| 421 | 427 | struct thread *thread, |
|---|
| 422 | | - struct perf_evsel *evsel, |
|---|
| 428 | + struct evsel *evsel, |
|---|
| 423 | 429 | struct perf_sample *sample) |
|---|
| 424 | 430 | { |
|---|
| 425 | 431 | struct vcpu_event_record *vcpu_record; |
|---|
| .. | .. |
|---|
| 672 | 678 | static int process_sample_event(struct perf_tool *tool, |
|---|
| 673 | 679 | union perf_event *event, |
|---|
| 674 | 680 | struct perf_sample *sample, |
|---|
| 675 | | - struct perf_evsel *evsel, |
|---|
| 681 | + struct evsel *evsel, |
|---|
| 676 | 682 | struct machine *machine) |
|---|
| 677 | 683 | { |
|---|
| 678 | 684 | int err = 0; |
|---|
| .. | .. |
|---|
| 744 | 750 | static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx, |
|---|
| 745 | 751 | u64 *mmap_time) |
|---|
| 746 | 752 | { |
|---|
| 747 | | - struct perf_evlist *evlist = kvm->evlist; |
|---|
| 753 | + struct evlist *evlist = kvm->evlist; |
|---|
| 748 | 754 | union perf_event *event; |
|---|
| 749 | | - struct perf_mmap *md; |
|---|
| 755 | + struct mmap *md; |
|---|
| 750 | 756 | u64 timestamp; |
|---|
| 751 | 757 | s64 n = 0; |
|---|
| 752 | 758 | int err; |
|---|
| 753 | 759 | |
|---|
| 754 | 760 | *mmap_time = ULLONG_MAX; |
|---|
| 755 | 761 | md = &evlist->mmap[idx]; |
|---|
| 756 | | - err = perf_mmap__read_init(md); |
|---|
| 762 | + err = perf_mmap__read_init(&md->core); |
|---|
| 757 | 763 | if (err < 0) |
|---|
| 758 | 764 | return (err == -EAGAIN) ? 0 : -1; |
|---|
| 759 | 765 | |
|---|
| 760 | | - while ((event = perf_mmap__read_event(md)) != NULL) { |
|---|
| 766 | + while ((event = perf_mmap__read_event(&md->core)) != NULL) { |
|---|
| 761 | 767 | err = perf_evlist__parse_sample_timestamp(evlist, event, ×tamp); |
|---|
| 762 | 768 | if (err) { |
|---|
| 763 | | - perf_mmap__consume(md); |
|---|
| 769 | + perf_mmap__consume(&md->core); |
|---|
| 764 | 770 | pr_err("Failed to parse sample\n"); |
|---|
| 765 | 771 | return -1; |
|---|
| 766 | 772 | } |
|---|
| .. | .. |
|---|
| 770 | 776 | * FIXME: Here we can't consume the event, as perf_session__queue_event will |
|---|
| 771 | 777 | * point to it, and it'll get possibly overwritten by the kernel. |
|---|
| 772 | 778 | */ |
|---|
| 773 | | - perf_mmap__consume(md); |
|---|
| 779 | + perf_mmap__consume(&md->core); |
|---|
| 774 | 780 | |
|---|
| 775 | 781 | if (err) { |
|---|
| 776 | 782 | pr_err("Failed to enqueue sample: %d\n", err); |
|---|
| .. | .. |
|---|
| 787 | 793 | break; |
|---|
| 788 | 794 | } |
|---|
| 789 | 795 | |
|---|
| 790 | | - perf_mmap__read_done(md); |
|---|
| 796 | + perf_mmap__read_done(&md->core); |
|---|
| 791 | 797 | return n; |
|---|
| 792 | 798 | } |
|---|
| 793 | 799 | |
|---|
| .. | .. |
|---|
| 797 | 803 | s64 n, ntotal = 0; |
|---|
| 798 | 804 | u64 flush_time = ULLONG_MAX, mmap_time; |
|---|
| 799 | 805 | |
|---|
| 800 | | - for (i = 0; i < kvm->evlist->nr_mmaps; i++) { |
|---|
| 806 | + for (i = 0; i < kvm->evlist->core.nr_mmaps; i++) { |
|---|
| 801 | 807 | n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time); |
|---|
| 802 | 808 | if (n < 0) |
|---|
| 803 | 809 | return -1; |
|---|
| .. | .. |
|---|
| 962 | 968 | goto out; |
|---|
| 963 | 969 | } |
|---|
| 964 | 970 | |
|---|
| 965 | | - if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0) |
|---|
| 971 | + if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0) |
|---|
| 966 | 972 | goto out; |
|---|
| 967 | 973 | |
|---|
| 968 | | - nr_stdin = perf_evlist__add_pollfd(kvm->evlist, fileno(stdin)); |
|---|
| 974 | + nr_stdin = evlist__add_pollfd(kvm->evlist, fileno(stdin)); |
|---|
| 969 | 975 | if (nr_stdin < 0) |
|---|
| 970 | 976 | goto out; |
|---|
| 971 | 977 | |
|---|
| .. | .. |
|---|
| 973 | 979 | goto out; |
|---|
| 974 | 980 | |
|---|
| 975 | 981 | /* everything is good - enable the events and process */ |
|---|
| 976 | | - perf_evlist__enable(kvm->evlist); |
|---|
| 982 | + evlist__enable(kvm->evlist); |
|---|
| 977 | 983 | |
|---|
| 978 | 984 | while (!done) { |
|---|
| 979 | | - struct fdarray *fda = &kvm->evlist->pollfd; |
|---|
| 985 | + struct fdarray *fda = &kvm->evlist->core.pollfd; |
|---|
| 980 | 986 | int rc; |
|---|
| 981 | 987 | |
|---|
| 982 | 988 | rc = perf_kvm__mmap_read(kvm); |
|---|
| .. | .. |
|---|
| 991 | 997 | done = perf_kvm__handle_stdin(); |
|---|
| 992 | 998 | |
|---|
| 993 | 999 | if (!rc && !done) |
|---|
| 994 | | - err = fdarray__poll(fda, 100); |
|---|
| 1000 | + err = evlist__poll(kvm->evlist, 100); |
|---|
| 995 | 1001 | } |
|---|
| 996 | 1002 | |
|---|
| 997 | | - perf_evlist__disable(kvm->evlist); |
|---|
| 1003 | + evlist__disable(kvm->evlist); |
|---|
| 998 | 1004 | |
|---|
| 999 | 1005 | if (err == 0) { |
|---|
| 1000 | 1006 | sort_result(kvm); |
|---|
| .. | .. |
|---|
| 1012 | 1018 | static int kvm_live_open_events(struct perf_kvm_stat *kvm) |
|---|
| 1013 | 1019 | { |
|---|
| 1014 | 1020 | int err, rc = -1; |
|---|
| 1015 | | - struct perf_evsel *pos; |
|---|
| 1016 | | - struct perf_evlist *evlist = kvm->evlist; |
|---|
| 1021 | + struct evsel *pos; |
|---|
| 1022 | + struct evlist *evlist = kvm->evlist; |
|---|
| 1017 | 1023 | char sbuf[STRERR_BUFSIZE]; |
|---|
| 1018 | 1024 | |
|---|
| 1019 | 1025 | perf_evlist__config(evlist, &kvm->opts, NULL); |
|---|
| .. | .. |
|---|
| 1023 | 1029 | * This command processes KVM tracepoints from host only |
|---|
| 1024 | 1030 | */ |
|---|
| 1025 | 1031 | evlist__for_each_entry(evlist, pos) { |
|---|
| 1026 | | - struct perf_event_attr *attr = &pos->attr; |
|---|
| 1032 | + struct perf_event_attr *attr = &pos->core.attr; |
|---|
| 1027 | 1033 | |
|---|
| 1028 | 1034 | /* make sure these *are* set */ |
|---|
| 1029 | | - perf_evsel__set_sample_bit(pos, TID); |
|---|
| 1030 | | - perf_evsel__set_sample_bit(pos, TIME); |
|---|
| 1031 | | - perf_evsel__set_sample_bit(pos, CPU); |
|---|
| 1032 | | - perf_evsel__set_sample_bit(pos, RAW); |
|---|
| 1035 | + evsel__set_sample_bit(pos, TID); |
|---|
| 1036 | + evsel__set_sample_bit(pos, TIME); |
|---|
| 1037 | + evsel__set_sample_bit(pos, CPU); |
|---|
| 1038 | + evsel__set_sample_bit(pos, RAW); |
|---|
| 1033 | 1039 | /* make sure these are *not*; want as small a sample as possible */ |
|---|
| 1034 | | - perf_evsel__reset_sample_bit(pos, PERIOD); |
|---|
| 1035 | | - perf_evsel__reset_sample_bit(pos, IP); |
|---|
| 1036 | | - perf_evsel__reset_sample_bit(pos, CALLCHAIN); |
|---|
| 1037 | | - perf_evsel__reset_sample_bit(pos, ADDR); |
|---|
| 1038 | | - perf_evsel__reset_sample_bit(pos, READ); |
|---|
| 1040 | + evsel__reset_sample_bit(pos, PERIOD); |
|---|
| 1041 | + evsel__reset_sample_bit(pos, IP); |
|---|
| 1042 | + evsel__reset_sample_bit(pos, CALLCHAIN); |
|---|
| 1043 | + evsel__reset_sample_bit(pos, ADDR); |
|---|
| 1044 | + evsel__reset_sample_bit(pos, READ); |
|---|
| 1039 | 1045 | attr->mmap = 0; |
|---|
| 1040 | 1046 | attr->comm = 0; |
|---|
| 1041 | 1047 | attr->task = 0; |
|---|
| .. | .. |
|---|
| 1049 | 1055 | attr->disabled = 1; |
|---|
| 1050 | 1056 | } |
|---|
| 1051 | 1057 | |
|---|
| 1052 | | - err = perf_evlist__open(evlist); |
|---|
| 1058 | + err = evlist__open(evlist); |
|---|
| 1053 | 1059 | if (err < 0) { |
|---|
| 1054 | 1060 | printf("Couldn't create the events: %s\n", |
|---|
| 1055 | 1061 | str_error_r(errno, sbuf, sizeof(sbuf))); |
|---|
| 1056 | 1062 | goto out; |
|---|
| 1057 | 1063 | } |
|---|
| 1058 | 1064 | |
|---|
| 1059 | | - if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { |
|---|
| 1065 | + if (evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { |
|---|
| 1060 | 1066 | ui__error("Failed to mmap the events: %s\n", |
|---|
| 1061 | 1067 | str_error_r(errno, sbuf, sizeof(sbuf))); |
|---|
| 1062 | | - perf_evlist__close(evlist); |
|---|
| 1068 | + evlist__close(evlist); |
|---|
| 1063 | 1069 | goto out; |
|---|
| 1064 | 1070 | } |
|---|
| 1065 | 1071 | |
|---|
| .. | .. |
|---|
| 1081 | 1087 | .ordered_events = true, |
|---|
| 1082 | 1088 | }; |
|---|
| 1083 | 1089 | struct perf_data file = { |
|---|
| 1084 | | - .file = { |
|---|
| 1085 | | - .path = kvm->file_name, |
|---|
| 1086 | | - }, |
|---|
| 1087 | | - .mode = PERF_DATA_MODE_READ, |
|---|
| 1088 | | - .force = kvm->force, |
|---|
| 1090 | + .path = kvm->file_name, |
|---|
| 1091 | + .mode = PERF_DATA_MODE_READ, |
|---|
| 1092 | + .force = kvm->force, |
|---|
| 1089 | 1093 | }; |
|---|
| 1090 | 1094 | |
|---|
| 1091 | 1095 | kvm->tool = eops; |
|---|
| 1092 | 1096 | kvm->session = perf_session__new(&file, false, &kvm->tool); |
|---|
| 1093 | | - if (!kvm->session) { |
|---|
| 1097 | + if (IS_ERR(kvm->session)) { |
|---|
| 1094 | 1098 | pr_err("Initializing perf session failed\n"); |
|---|
| 1095 | | - return -1; |
|---|
| 1099 | + return PTR_ERR(kvm->session); |
|---|
| 1096 | 1100 | } |
|---|
| 1097 | 1101 | |
|---|
| 1098 | 1102 | symbol__init(&kvm->session->header.env); |
|---|
| .. | .. |
|---|
| 1286 | 1290 | } |
|---|
| 1287 | 1291 | |
|---|
| 1288 | 1292 | #ifdef HAVE_TIMERFD_SUPPORT |
|---|
| 1289 | | -static struct perf_evlist *kvm_live_event_list(void) |
|---|
| 1293 | +static struct evlist *kvm_live_event_list(void) |
|---|
| 1290 | 1294 | { |
|---|
| 1291 | | - struct perf_evlist *evlist; |
|---|
| 1295 | + struct evlist *evlist; |
|---|
| 1292 | 1296 | char *tp, *name, *sys; |
|---|
| 1293 | 1297 | int err = -1; |
|---|
| 1294 | 1298 | const char * const *events_tp; |
|---|
| 1295 | 1299 | |
|---|
| 1296 | | - evlist = perf_evlist__new(); |
|---|
| 1300 | + evlist = evlist__new(); |
|---|
| 1297 | 1301 | if (evlist == NULL) |
|---|
| 1298 | 1302 | return NULL; |
|---|
| 1299 | 1303 | |
|---|
| .. | .. |
|---|
| 1315 | 1319 | *name = '\0'; |
|---|
| 1316 | 1320 | name++; |
|---|
| 1317 | 1321 | |
|---|
| 1318 | | - if (perf_evlist__add_newtp(evlist, sys, name, NULL)) { |
|---|
| 1322 | + if (evlist__add_newtp(evlist, sys, name, NULL)) { |
|---|
| 1319 | 1323 | pr_err("Failed to add %s tracepoint to the list\n", *events_tp); |
|---|
| 1320 | 1324 | free(tp); |
|---|
| 1321 | 1325 | goto out; |
|---|
| .. | .. |
|---|
| 1328 | 1332 | |
|---|
| 1329 | 1333 | out: |
|---|
| 1330 | 1334 | if (err) { |
|---|
| 1331 | | - perf_evlist__delete(evlist); |
|---|
| 1335 | + evlist__delete(evlist); |
|---|
| 1332 | 1336 | evlist = NULL; |
|---|
| 1333 | 1337 | } |
|---|
| 1334 | 1338 | |
|---|
| .. | .. |
|---|
| 1365 | 1369 | "show events other than" |
|---|
| 1366 | 1370 | " HLT (x86 only) or Wait state (s390 only)" |
|---|
| 1367 | 1371 | " that take longer than duration usecs"), |
|---|
| 1368 | | - OPT_UINTEGER(0, "proc-map-timeout", &kvm->opts.proc_map_timeout, |
|---|
| 1372 | + OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout, |
|---|
| 1369 | 1373 | "per thread proc mmap processing timeout in ms"), |
|---|
| 1370 | 1374 | OPT_END() |
|---|
| 1371 | 1375 | }; |
|---|
| .. | .. |
|---|
| 1395 | 1399 | kvm->opts.target.uses_mmap = false; |
|---|
| 1396 | 1400 | kvm->opts.target.uid_str = NULL; |
|---|
| 1397 | 1401 | kvm->opts.target.uid = UINT_MAX; |
|---|
| 1398 | | - kvm->opts.proc_map_timeout = 500; |
|---|
| 1399 | 1402 | |
|---|
| 1400 | 1403 | symbol__init(NULL); |
|---|
| 1401 | 1404 | disable_buildid_cache(); |
|---|
| .. | .. |
|---|
| 1446 | 1449 | * perf session |
|---|
| 1447 | 1450 | */ |
|---|
| 1448 | 1451 | kvm->session = perf_session__new(&data, false, &kvm->tool); |
|---|
| 1449 | | - if (kvm->session == NULL) { |
|---|
| 1450 | | - err = -1; |
|---|
| 1452 | + if (IS_ERR(kvm->session)) { |
|---|
| 1453 | + err = PTR_ERR(kvm->session); |
|---|
| 1451 | 1454 | goto out; |
|---|
| 1452 | 1455 | } |
|---|
| 1453 | 1456 | kvm->session->evlist = kvm->evlist; |
|---|
| 1454 | 1457 | perf_session__set_id_hdr_size(kvm->session); |
|---|
| 1455 | 1458 | ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); |
|---|
| 1456 | 1459 | machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, |
|---|
| 1457 | | - kvm->evlist->threads, false, |
|---|
| 1458 | | - kvm->opts.proc_map_timeout, 1); |
|---|
| 1460 | + kvm->evlist->core.threads, false, 1); |
|---|
| 1459 | 1461 | err = kvm_live_open_events(kvm); |
|---|
| 1460 | 1462 | if (err) |
|---|
| 1461 | 1463 | goto out; |
|---|
| .. | .. |
|---|
| 1465 | 1467 | out: |
|---|
| 1466 | 1468 | perf_session__delete(kvm->session); |
|---|
| 1467 | 1469 | kvm->session = NULL; |
|---|
| 1468 | | - perf_evlist__delete(kvm->evlist); |
|---|
| 1470 | + evlist__delete(kvm->evlist); |
|---|
| 1469 | 1471 | |
|---|
| 1470 | 1472 | return err; |
|---|
| 1471 | 1473 | } |
|---|
| .. | .. |
|---|
| 1515 | 1517 | } |
|---|
| 1516 | 1518 | #endif /* HAVE_KVM_STAT_SUPPORT */ |
|---|
| 1517 | 1519 | |
|---|
| 1520 | +int __weak kvm_add_default_arch_event(int *argc __maybe_unused, |
|---|
| 1521 | + const char **argv __maybe_unused) |
|---|
| 1522 | +{ |
|---|
| 1523 | + return 0; |
|---|
| 1524 | +} |
|---|
| 1525 | + |
|---|
| 1518 | 1526 | static int __cmd_record(const char *file_name, int argc, const char **argv) |
|---|
| 1519 | 1527 | { |
|---|
| 1520 | | - int rec_argc, i = 0, j; |
|---|
| 1528 | + int rec_argc, i = 0, j, ret; |
|---|
| 1521 | 1529 | const char **rec_argv; |
|---|
| 1522 | 1530 | |
|---|
| 1531 | + ret = kvm_add_default_arch_event(&argc, argv); |
|---|
| 1532 | + if (ret) |
|---|
| 1533 | + return -EINVAL; |
|---|
| 1534 | + |
|---|
| 1523 | 1535 | rec_argc = argc + 2; |
|---|
| 1524 | 1536 | rec_argv = calloc(rec_argc + 1, sizeof(char *)); |
|---|
| 1525 | 1537 | rec_argv[i++] = strdup("record"); |
|---|