diff options
| author | Mao Han <han_mao@c-sky.com> | 2019-04-10 04:16:43 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-04-16 10:27:53 -0400 |
| commit | 3a5b64f05d7fe36dea0dde26423e3044fbacd482 (patch) | |
| tree | 2544042bb5009ace4a8887975f436b0f9632b106 /tools | |
| parent | f32c2877bcb068a718bb70094cd59ccc29d4d082 (diff) | |
perf evsel: Use hweight64() instead of hweight_long(attr.sample_regs_user)
On 32-bits platform with more than 32 registers, the 64 bits mask is
truncate to the lower 32 bits and the return value of hweight_long will
always smaller than 32. When kernel outputs more than 32 registers, but
the user perf program only counts 32, there will be a data mismatch
result to overflow check fail.
Signed-off-by: Mao Han <han_mao@c-sky.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Fixes: 6a21c0b5c2ab ("perf tools: Add core support for sampling intr machine state regs")
Fixes: d03f2170546d ("perf tools: Expand perf_event__synthesize_sample()")
Fixes: 0f6a30150ca2 ("perf tools: Support user regs and stack in sample parsing")
Link: http://lkml.kernel.org/r/29ad7947dc8fd1ff0abd2093a72cc27a2446be9f.1554883878.git.han_mao@c-sky.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/perf/util/evsel.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 66d066f18b5b..966360844fff 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -2368,7 +2368,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, | |||
| 2368 | if (data->user_regs.abi) { | 2368 | if (data->user_regs.abi) { |
| 2369 | u64 mask = evsel->attr.sample_regs_user; | 2369 | u64 mask = evsel->attr.sample_regs_user; |
| 2370 | 2370 | ||
| 2371 | sz = hweight_long(mask) * sizeof(u64); | 2371 | sz = hweight64(mask) * sizeof(u64); |
| 2372 | OVERFLOW_CHECK(array, sz, max_size); | 2372 | OVERFLOW_CHECK(array, sz, max_size); |
| 2373 | data->user_regs.mask = mask; | 2373 | data->user_regs.mask = mask; |
| 2374 | data->user_regs.regs = (u64 *)array; | 2374 | data->user_regs.regs = (u64 *)array; |
| @@ -2424,7 +2424,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, | |||
| 2424 | if (data->intr_regs.abi != PERF_SAMPLE_REGS_ABI_NONE) { | 2424 | if (data->intr_regs.abi != PERF_SAMPLE_REGS_ABI_NONE) { |
| 2425 | u64 mask = evsel->attr.sample_regs_intr; | 2425 | u64 mask = evsel->attr.sample_regs_intr; |
| 2426 | 2426 | ||
| 2427 | sz = hweight_long(mask) * sizeof(u64); | 2427 | sz = hweight64(mask) * sizeof(u64); |
| 2428 | OVERFLOW_CHECK(array, sz, max_size); | 2428 | OVERFLOW_CHECK(array, sz, max_size); |
| 2429 | data->intr_regs.mask = mask; | 2429 | data->intr_regs.mask = mask; |
| 2430 | data->intr_regs.regs = (u64 *)array; | 2430 | data->intr_regs.regs = (u64 *)array; |
| @@ -2552,7 +2552,7 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, | |||
| 2552 | if (type & PERF_SAMPLE_REGS_USER) { | 2552 | if (type & PERF_SAMPLE_REGS_USER) { |
| 2553 | if (sample->user_regs.abi) { | 2553 | if (sample->user_regs.abi) { |
| 2554 | result += sizeof(u64); | 2554 | result += sizeof(u64); |
| 2555 | sz = hweight_long(sample->user_regs.mask) * sizeof(u64); | 2555 | sz = hweight64(sample->user_regs.mask) * sizeof(u64); |
| 2556 | result += sz; | 2556 | result += sz; |
| 2557 | } else { | 2557 | } else { |
| 2558 | result += sizeof(u64); | 2558 | result += sizeof(u64); |
| @@ -2580,7 +2580,7 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, | |||
| 2580 | if (type & PERF_SAMPLE_REGS_INTR) { | 2580 | if (type & PERF_SAMPLE_REGS_INTR) { |
| 2581 | if (sample->intr_regs.abi) { | 2581 | if (sample->intr_regs.abi) { |
| 2582 | result += sizeof(u64); | 2582 | result += sizeof(u64); |
| 2583 | sz = hweight_long(sample->intr_regs.mask) * sizeof(u64); | 2583 | sz = hweight64(sample->intr_regs.mask) * sizeof(u64); |
| 2584 | result += sz; | 2584 | result += sz; |
| 2585 | } else { | 2585 | } else { |
| 2586 | result += sizeof(u64); | 2586 | result += sizeof(u64); |
| @@ -2710,7 +2710,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, | |||
| 2710 | if (type & PERF_SAMPLE_REGS_USER) { | 2710 | if (type & PERF_SAMPLE_REGS_USER) { |
| 2711 | if (sample->user_regs.abi) { | 2711 | if (sample->user_regs.abi) { |
| 2712 | *array++ = sample->user_regs.abi; | 2712 | *array++ = sample->user_regs.abi; |
| 2713 | sz = hweight_long(sample->user_regs.mask) * sizeof(u64); | 2713 | sz = hweight64(sample->user_regs.mask) * sizeof(u64); |
| 2714 | memcpy(array, sample->user_regs.regs, sz); | 2714 | memcpy(array, sample->user_regs.regs, sz); |
| 2715 | array = (void *)array + sz; | 2715 | array = (void *)array + sz; |
| 2716 | } else { | 2716 | } else { |
| @@ -2746,7 +2746,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, | |||
| 2746 | if (type & PERF_SAMPLE_REGS_INTR) { | 2746 | if (type & PERF_SAMPLE_REGS_INTR) { |
| 2747 | if (sample->intr_regs.abi) { | 2747 | if (sample->intr_regs.abi) { |
| 2748 | *array++ = sample->intr_regs.abi; | 2748 | *array++ = sample->intr_regs.abi; |
| 2749 | sz = hweight_long(sample->intr_regs.mask) * sizeof(u64); | 2749 | sz = hweight64(sample->intr_regs.mask) * sizeof(u64); |
| 2750 | memcpy(array, sample->intr_regs.regs, sz); | 2750 | memcpy(array, sample->intr_regs.regs, sz); |
| 2751 | array = (void *)array + sz; | 2751 | array = (void *)array + sz; |
| 2752 | } else { | 2752 | } else { |
