Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a46a8cdf authored by Adrian Hunter's avatar Adrian Hunter Committed by Greg Kroah-Hartman
Browse files

perf intel-pt: Fix overlap calculation for padding



commit 5a99d99e3310a565b0cf63f785b347be9ee0da45 upstream.

Auxtrace records might have up to 7 bytes of padding appended. Adjust
the overlap accordingly.

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: stable@vger.kernel.org
Link: http://lkml.kernel.org/r/20190206103947.15750-3-adrian.hunter@intel.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fa592fc0
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

#include "../cache.h"
#include "../util.h"
#include "../auxtrace.h"

#include "intel-pt-insn-decoder.h"
#include "intel-pt-pkt-decoder.h"
@@ -2558,6 +2559,34 @@ static int intel_pt_tsc_cmp(uint64_t tsc1, uint64_t tsc2)
	}
}

#define MAX_PADDING (PERF_AUXTRACE_RECORD_ALIGNMENT - 1)

/**
 * adj_for_padding - adjust overlap to account for padding.
 * @buf_b: second buffer
 * @buf_a: first buffer
 * @len_a: size of first buffer
 *
 * @buf_a might have up to 7 bytes of padding appended. Adjust the overlap
 * accordingly.
 *
 * Return: A pointer into @buf_b from where non-overlapped data starts
 */
static unsigned char *adj_for_padding(unsigned char *buf_b,
				      unsigned char *buf_a, size_t len_a)
{
	unsigned char *p = buf_b - MAX_PADDING;
	unsigned char *q = buf_a + len_a - MAX_PADDING;
	int i;

	for (i = MAX_PADDING; i; i--, p++, q++) {
		if (*p != *q)
			break;
	}

	return p;
}

/**
 * intel_pt_find_overlap_tsc - determine start of non-overlapped trace data
 *                             using TSC.
@@ -2608,8 +2637,11 @@ static unsigned char *intel_pt_find_overlap_tsc(unsigned char *buf_a,

			/* Same TSC, so buffers are consecutive */
			if (!cmp && rem_b >= rem_a) {
				unsigned char *start;

				*consecutive = true;
				return buf_b + len_b - (rem_b - rem_a);
				start = buf_b + len_b - (rem_b - rem_a);
				return adj_for_padding(start, buf_a, len_a);
			}
			if (cmp < 0)
				return buf_b; /* tsc_a < tsc_b => no overlap */
@@ -2672,7 +2704,7 @@ unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a,
		found = memmem(buf_a, len_a, buf_b, len_a);
		if (found) {
			*consecutive = true;
			return buf_b + len_a;
			return adj_for_padding(buf_b + len_a, buf_a, len_a);
		}

		/* Try again at next PSB in buffer 'a' */